risc-v/espressif: Add SPI Flash support

This commit is contained in:
Eren Terzioglu 2023-12-15 15:16:24 +03:00 committed by Xiang Xiao
parent 7b37dd1224
commit aa0dccb7bc
31 changed files with 3408 additions and 1 deletions

View File

@ -43,6 +43,12 @@ config ESPRESSIF_FLASH_2M
config ESPRESSIF_FLASH_4M config ESPRESSIF_FLASH_4M
bool "4 MB" bool "4 MB"
config ESPRESSIF_FLASH_8M
bool "8 MB"
config ESPRESSIF_FLASH_16M
bool "16 MB"
endchoice # ESPRESSIF_FLASH endchoice # ESPRESSIF_FLASH
config ESPRESSIF_FLASH_DETECT config ESPRESSIF_FLASH_DETECT
@ -281,6 +287,10 @@ config ESPRESSIF_LEDC
select PWM select PWM
select ARCH_HAVE_PWM_MULTICHAN select ARCH_HAVE_PWM_MULTICHAN
config ESPRESSIF_SPIFLASH
bool "SPI Flash"
default n
config ESPRESSIF_HR_TIMER config ESPRESSIF_HR_TIMER
bool bool
default RTC_DRIVER default RTC_DRIVER
@ -408,6 +418,35 @@ config ESPRESSIF_FLASH_MODE_QOUT
endchoice # ESPRESSIF_FLASH_MODE endchoice # ESPRESSIF_FLASH_MODE
if ESPRESSIF_SPIFLASH
comment "General storage MTD configuration"
config ESPRESSIF_MTD
bool "MTD driver"
default y
select MTD
select MTD_BYTE_WRITE
select MTD_PARTITION
---help---
Initialize an MTD driver for the SPI Flash, which will
add an entry at /dev for application access from userspace.
config ESPRESSIF_SPIFLASH_MTD_BLKSIZE
int "Storage MTD block size"
default 64
depends on ESPRESSIF_MTD
---help---
Block size for MTD driver in kB. This size must be divisible by 2
config ESPRESSIF_STORAGE_MTD_DEBUG
bool "Storage MTD Debug"
default n
depends on ESPRESSIF_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).
endif # ESPRESSIF_SPIFLASH
choice ESPRESSIF_FLASH_FREQ choice ESPRESSIF_FLASH_FREQ
prompt "SPI Flash frequency" prompt "SPI Flash frequency"
default ESPRESSIF_FLASH_FREQ_80M if ESPRESSIF_ESP32C3 || ESPRESSIF_ESP32C6 default ESPRESSIF_FLASH_FREQ_80M if ESPRESSIF_ESP32C3 || ESPRESSIF_ESP32C6
@ -437,6 +476,29 @@ config ESPRESSIF_FLASH_FREQ_20M
endchoice # ESPRESSIF_FLASH_FREQ endchoice # ESPRESSIF_FLASH_FREQ
config ESPRESSIF_SPI_FLASH_USE_32BIT_ADDRESS
bool "SPI flash uses 32-bit address"
default n
---help---
SPI flash driver in ROM only support 24-bit address access,
if select the option, it will force to use source code instead
of functions in ROM, so that SPI flash driver can access full
32-bit address.
config ESPRESSIF_STORAGE_MTD_OFFSET
hex "Storage MTD base address in SPI Flash"
default 0x180000
depends on ESPRESSIF_MTD
---help---
MTD base address in SPI Flash.
config ESPRESSIF_STORAGE_MTD_SIZE
hex "Storage MTD size in SPI Flash"
default 0x100000
depends on ESPRESSIF_MTD
---help---
MTD size in SPI Flash.
endmenu # SPI Flash Configuration endmenu # SPI Flash Configuration
menu "LEDC configuration" menu "LEDC configuration"

View File

@ -80,6 +80,13 @@ ifeq ($(CONFIG_ESP_RMT),y)
endif endif
endif endif
ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
CHIP_CSRCS += esp_spiflash.c
ifeq ($(CONFIG_ESPRESSIF_MTD),y)
CHIP_CSRCS += esp_spiflash_mtd.c
endif
endif
############################################################################# #############################################################################
# Espressif HAL for 3rd Party Platforms # Espressif HAL for 3rd Party Platforms
############################################################################# #############################################################################
@ -88,7 +95,7 @@ endif
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION ifndef ESP_HAL_3RDPARTY_VERSION
ESP_HAL_3RDPARTY_VERSION = b6a943764f5e5a12d12edd8a6d71bdecc505428c ESP_HAL_3RDPARTY_VERSION = 7951b5b282384ec43858a28ddfabbef7b6b326cb
endif endif
ifndef ESP_HAL_3RDPARTY_URL ifndef ESP_HAL_3RDPARTY_URL

View File

@ -115,6 +115,19 @@ static volatile uint8_t g_irq_map[NR_IRQS];
static uint32_t g_cpuint_freelist = ESP_CPUINT_PERIPHSET; static uint32_t g_cpuint_freelist = ESP_CPUINT_PERIPHSET;
/* This bitmask has an 1 if the int should be disabled
* when the flash is disabled.
*/
static uint32_t non_iram_int_mask[CONFIG_ESPRESSIF_NUM_CPUS];
/* This bitmask has 1 in it if the int was disabled
* using esp_intr_noniram_disable.
*/
static uint32_t non_iram_int_disabled[CONFIG_ESPRESSIF_NUM_CPUS];
static bool non_iram_int_disabled_flag[CONFIG_ESPRESSIF_NUM_CPUS];
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -280,6 +293,15 @@ static void esp_cpuint_initialize(void)
void up_irqinitialize(void) void up_irqinitialize(void)
{ {
/* All CPU ints are non-IRAM interrupts at the beginning and should be
* disabled during a SPI flash operation
*/
for (int i = 0; i < CONFIG_SMP_NCPUS; i++)
{
non_iram_int_mask[i] = UINT32_MAX;
}
/* Indicate that no interrupt sources are assigned to CPU interrupts */ /* Indicate that no interrupt sources are assigned to CPU interrupts */
for (int i = 0; i < NR_IRQS; i++) for (int i = 0; i < NR_IRQS; i++)
@ -584,3 +606,77 @@ irqstate_t up_irq_enable(void)
flags = READ_AND_SET_CSR(mstatus, MSTATUS_MIE); flags = READ_AND_SET_CSR(mstatus, MSTATUS_MIE);
return flags; return flags;
} }
/****************************************************************************
* Name: esp_intr_noniram_disable
*
* Description:
* Disable interrupts that aren't specifically marked as running from IRAM.
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
void IRAM_ATTR esp_intr_noniram_disable(void)
{
uint32_t oldint;
irqstate_t irqstate;
uint32_t cpu;
uint32_t non_iram_ints;
irqstate = enter_critical_section();
cpu = esp_cpu_get_core_id();
non_iram_ints = non_iram_int_mask[cpu];
if (non_iram_int_disabled_flag[cpu])
{
abort();
}
non_iram_int_disabled_flag[cpu] = true;
oldint = esp_cpu_intr_get_enabled_mask();
esp_cpu_intr_disable(non_iram_ints);
/* Save disabled ints */
non_iram_int_disabled[cpu] = oldint & non_iram_ints;
leave_critical_section(irqstate);
}
/****************************************************************************
* Name: esp_intr_noniram_enable
*
* Description:
* Enable interrupts that aren't specifically marked as running from IRAM.
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
void IRAM_ATTR esp_intr_noniram_enable(void)
{
irqstate_t irqstate;
uint32_t cpu;
int non_iram_ints;
irqstate = enter_critical_section();
cpu = esp_cpu_get_core_id();
non_iram_ints = non_iram_int_disabled[cpu];
if (!non_iram_int_disabled_flag[cpu])
{
abort();
}
non_iram_int_disabled_flag[cpu] = false;
esp_cpu_intr_enable(non_iram_ints);
leave_critical_section(irqstate);
}

View File

@ -142,6 +142,38 @@ int esp_setup_irq(int source, irq_priority_t priority, irq_trigger_t type);
void esp_teardown_irq(int source, int cpuint); void esp_teardown_irq(int source, int cpuint);
/****************************************************************************
* Name: esp_intr_noniram_disable
*
* Description:
* Disable interrupts that aren't specifically marked as running from IRAM.
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_intr_noniram_disable(void);
/****************************************************************************
* Name: esp_intr_noniram_enable
*
* Description:
* Enable interrupts that aren't specifically marked as running from IRAM.
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_intr_noniram_enable(void);
#undef EXTERN #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)
} }

View File

@ -0,0 +1,594 @@
/****************************************************************************
* arch/risc-v/src/common/espressif/esp_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 <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <string.h>
#include <sys/types.h>
#include <inttypes.h>
#include <errno.h>
#include "riscv_internal.h"
#include "riscv/rv_utils.h"
#include <nuttx/arch.h>
#include <nuttx/init.h>
#include "esp_spiflash.h"
#include "esp_attr.h"
#include "memspi_host_driver.h"
#include "spi_flash_defs.h"
#include "hal/spimem_flash_ll.h"
#include "hal/spi_flash_ll.h"
#include "esp_rom_spiflash.h"
#include "esp_irq.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* SPI buffer size */
# define SPI_BUFFER_WORDS (16)
# define SPI_BUFFER_BYTES (SPI_BUFFER_WORDS * 4)
/* SPI flash hardware definition */
# define FLASH_SECTOR_SIZE (4096)
/* SPI flash SR1 bits */
# define FLASH_SR1_BUSY ESP_ROM_SPIFLASH_BUSY_FLAG
# define FLASH_SR1_WREN ESP_ROM_SPIFLASH_WRENABLE_FLAG
/* SPI flash operation */
# define FLASH_CMD_WRDI CMD_WRDI
# define FLASH_CMD_WREN CMD_WREN
# define FLASH_CMD_RDSR CMD_RDSR
#ifdef CONFIG_ESPRESSIF_SPI_FLASH_USE_32BIT_ADDRESS
# define ADDR_BITS(addr) (((addr) & 0xff000000) ? 32 : 24)
# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? \
CMD_FASTRD_4B : CMD_FASTRD)
# define WRITE_CMD(addr) (ADDR_BITS(addr) == 32 ? CMD_PROGRAM_PAGE_4B : \
CMD_PROGRAM_PAGE)
# define ERASE_CMD(addr) (ADDR_BITS(addr) == 32 ? CMD_SECTOR_ERASE_4B : \
CMD_SECTOR_ERASE)
# define READ_DUMMY(addr) (8)
#else
# define ADDR_BITS(addr) (24)
# define READ_CMD(addr) CMD_FASTRD
# define WRITE_CMD(addr) CMD_PROGRAM_PAGE
# define ERASE_CMD(addr) CMD_SECTOR_ERASE
# define READ_DUMMY(addr) (8)
#endif
# define SEND_CMD8_TO_FLASH(cmd) \
esp_spi_trans((cmd), 8, \
0, 0, \
NULL, 0, \
NULL, 0, \
0)
# define READ_SR1_FROM_FLASH(cmd, status) \
esp_spi_trans((cmd), 8, \
0, 0, \
NULL, 0, \
(status), 1, \
0)
# define ERASE_FLASH_SECTOR(addr) \
esp_spi_trans(ERASE_CMD(addr), 8, \
(addr), ADDR_BITS(addr), \
NULL, 0, \
NULL, 0, \
0)
# define WRITE_DATA_TO_FLASH(addr, buffer, size) \
esp_spi_trans(WRITE_CMD(addr), 8, \
(addr), ADDR_BITS(addr), \
buffer, size, \
NULL, 0, \
0)
# define READ_DATA_FROM_FLASH(addr, buffer, size) \
esp_spi_trans(READ_CMD(addr), 8, \
(addr), ADDR_BITS(addr), \
NULL, 0, \
buffer, size, \
READ_DUMMY(addr))
/****************************************************************************
* Private Types
****************************************************************************/
spi_mem_dev_t *dev;
/****************************************************************************
* Private Functions Declaration
****************************************************************************/
static void spiflash_start(void);
static void spiflash_end(void);
/****************************************************************************
* Private Data
****************************************************************************/
static struct spiflash_guard_funcs g_spi_flash_guard_funcs =
{
.start = spiflash_start,
.end = spiflash_end,
.op_lock = NULL,
.op_unlock = NULL,
.address_is_safe = NULL,
.yield = NULL,
};
static mutex_t s_flash_op_mutex;
static uint32_t s_flash_op_cache_state[CONFIG_ESPRESSIF_NUM_CPUS];
static volatile bool s_sched_suspended[CONFIG_ESPRESSIF_NUM_CPUS];
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: spiflash_opstart
*
* Description:
* Prepare for an SPIFLASH operation.
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
static IRAM_ATTR void spiflash_start(void)
{
extern uint32_t cache_suspend_icache(void);
int cpu;
irqstate_t flags;
uint32_t regval;
nxmutex_lock(&s_flash_op_mutex);
flags = enter_critical_section();
cpu = up_cpu_index();
s_sched_suspended[cpu] = true;
esp_intr_noniram_disable();
s_flash_op_cache_state[cpu] = cache_suspend_icache() << 16;
leave_critical_section(flags);
}
/****************************************************************************
* Name: spiflash_opdone
*
* Description:
* Undo all the steps of opstart.
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
static IRAM_ATTR void spiflash_end(void)
{
extern void cache_resume_icache(uint32_t);
int cpu;
irqstate_t flags;
flags = enter_critical_section();
cpu = up_cpu_index();
cache_resume_icache(s_flash_op_cache_state[cpu] >> 16);
esp_intr_noniram_enable();
s_sched_suspended[cpu] = false;
leave_critical_section(flags);
nxmutex_unlock(&s_flash_op_mutex);
}
/****************************************************************************
* Name: esp_spi_trans
*
* Description:
* Transmit given command, address and data.
*
* Input Parameters:
* command - command value
* command_bits - command bits
* address - address value
* address_bits - address bits
* tx_buffer - write buffer
* tx_bytes - write buffer size
* rx_buffer - read buffer
* rx_bytes - read buffer size
* dummy_bits - dummy bits
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
static IRAM_ATTR void esp_spi_trans(uint32_t command,
uint32_t command_bits,
uint32_t address,
uint32_t address_bits,
uint32_t *tx_buffer,
uint32_t tx_bytes,
uint32_t *rx_buffer,
uint32_t rx_bytes,
uint32_t dummy_bits)
{
/* Initiliaze SPI user register */
spi_flash_ll_reset(dev);
while (!spi_flash_ll_host_idle(dev));
/* Set command bits and value, and command is always needed */
spi_flash_ll_set_command(dev, command, command_bits);
/* Set address bits and value */
if (address_bits)
{
spi_flash_ll_set_addr_bitlen(dev, address_bits);
spi_flash_ll_set_address(dev, address);
}
/* Set dummy */
if (dummy_bits)
{
spi_flash_ll_set_dummy(dev, dummy_bits);
}
/* Set TX data */
if (tx_bytes)
{
spi_flash_ll_set_mosi_bitlen(dev, tx_bytes * 8);
spi_flash_ll_set_buffer_data(dev, tx_buffer, tx_bytes);
}
/* Set RX data */
if (rx_bytes)
{
spi_flash_ll_set_miso_bitlen(dev, rx_bytes * 8);
}
/* Set I/O mode */
spi_flash_ll_set_read_mode(dev, SPI_FLASH_FASTRD);
/* Set clock and delay */
spimem_flash_ll_suspend_cmd_setup(dev, 0);
/* Start transmision */
spi_flash_ll_user_start(dev);
/* Wait until transmission is done */
while (!spi_flash_ll_cmd_is_done(dev));
/* Get read data */
if (rx_bytes)
{
spi_flash_ll_get_buffer_data(dev, rx_buffer, rx_bytes);
}
}
/****************************************************************************
* Name: wait_flash_idle
*
* Description:
* Wait until flash enters idle state
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
static IRAM_ATTR void wait_flash_idle(void)
{
while (!spi_flash_ll_host_idle(dev));
}
/****************************************************************************
* Name: enable_flash_write
*
* Description:
* Enable Flash write mode
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
static IRAM_ATTR void enable_flash_write(void)
{
uint32_t status;
do
{
SEND_CMD8_TO_FLASH(FLASH_CMD_WREN);
READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status);
if ((status & FLASH_SR1_WREN) != 0)
{
break;
}
}
while (1);
}
/****************************************************************************
* Name: disable_flash_write
*
* Description:
* Disable Flash write mode
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
static IRAM_ATTR void disable_flash_write(void)
{
uint32_t status;
do
{
SEND_CMD8_TO_FLASH(FLASH_CMD_WRDI);
READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status);
if ((status & FLASH_SR1_WREN) == 0)
{
break;
}
}
while (1);
}
/****************************************************************************
* Name: spi_flash_read
*
* Description:
* Read data from Flash.
*
* Parameters:
* address - source address of the data in Flash.
* buffer - pointer to the destination buffer
* length - length of data
*
* Returned Values:
* Zero (OK) is returned or a negative error.
*
****************************************************************************/
IRAM_ATTR int spi_flash_read(uint32_t address, void *buffer, uint32_t length)
{
int ret = OK;
uint8_t *rx_buf = (uint8_t *)buffer;
uint32_t rx_bytes = length;
uint32_t rx_addr = address;
spiflash_start();
for (uint32_t i = 0; i < length; i += SPI_BUFFER_BYTES)
{
uint32_t spi_buffer[SPI_BUFFER_WORDS];
uint32_t n = MIN(rx_bytes, SPI_BUFFER_BYTES);
READ_DATA_FROM_FLASH(rx_addr, spi_buffer, n);
memcpy(rx_buf, spi_buffer, n);
rx_bytes -= n;
rx_buf += n;
rx_addr += n;
}
spiflash_end();
return ret;
}
/****************************************************************************
* 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.
*
****************************************************************************/
IRAM_ATTR int spi_flash_erase_sector(uint32_t sector)
{
int ret = OK;
uint32_t addr = sector * FLASH_SECTOR_SIZE;
spiflash_start();
wait_flash_idle();
enable_flash_write();
ERASE_FLASH_SECTOR(addr);
wait_flash_idle();
disable_flash_write();
spiflash_end();
return ret;
}
/****************************************************************************
* 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.
*
****************************************************************************/
IRAM_ATTR int spi_flash_erase_range(uint32_t start_address, uint32_t size)
{
int ret = OK;
uint32_t addr = start_address;
spiflash_start();
for (uint32_t i = 0; i < size; i += FLASH_SECTOR_SIZE)
{
wait_flash_idle();
enable_flash_write();
ERASE_FLASH_SECTOR(addr);
addr += FLASH_SECTOR_SIZE;
}
wait_flash_idle();
disable_flash_write();
spiflash_end();
return ret;
}
/****************************************************************************
* Name: spi_flash_write
*
* Description:
* Write data to Flash.
*
* Parameters:
* dest_addr - Destination address in Flash.
* buffer - Pointer to the source buffer.
* size - Length of data, in bytes.
*
* Returned Values:
* Zero (OK) is returned or a negative error.
*
****************************************************************************/
IRAM_ATTR int spi_flash_write(uint32_t dest_addr,
const void *buffer,
uint32_t size)
{
int ret = OK;
const uint8_t *tx_buf = (const uint8_t *)buffer;
uint32_t tx_bytes = size;
uint32_t tx_addr = dest_addr;
spiflash_start();
for (int i = 0; i < size; i += SPI_BUFFER_BYTES)
{
uint32_t spi_buffer[SPI_BUFFER_WORDS];
uint32_t n = MIN(tx_bytes, SPI_BUFFER_BYTES);
memcpy(spi_buffer, tx_buf, n);
wait_flash_idle();
enable_flash_write();
WRITE_DATA_TO_FLASH(tx_addr, spi_buffer, n);
tx_bytes -= n;
tx_buf += n;
tx_addr += n;
}
wait_flash_idle();
disable_flash_write();
spiflash_end();
return ret;
}
/****************************************************************************
* Name: esp_spiflash_init
*
* Description:
* Initialize ESP SPI flash driver.
*
* Input Parameters:
* None.
*
* Returned Value:
* OK if success or a negative value if fail.
*
****************************************************************************/
int esp_spiflash_init(void)
{
extern void spi_flash_guard_set(const struct spiflash_guard_funcs *);
nxmutex_init(&s_flash_op_mutex);
spi_flash_guard_set(&g_spi_flash_guard_funcs);
dev = spimem_flash_ll_get_hw(SPI1_HOST);
return OK;
}

View File

@ -0,0 +1,188 @@
/****************************************************************************
* arch/risc-v/src/common/espressif/esp_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_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPIFLASH_H
#define __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPIFLASH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <nuttx/mtd/mtd.h>
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/**
* 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 (spi_flash_write, spi_flash_read,
* spi_flash_erase_sector and spi_flash_erase_range):
* - '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".
* - '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".
* 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.
*
* 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: spi_flash_read
*
* Description:
* Read data from Flash.
*
* Parameters:
* address - source address of the data in Flash.
* buffer - pointer to the destination buffer
* length - length of data
*
* Returned Values:
* Zero (OK) is returned or a negative error.
*
****************************************************************************/
int spi_flash_read(uint32_t address, void *buffer, uint32_t length);
/****************************************************************************
* 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_write
*
* Description:
* Write data to Flash.
*
* 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 *buffer, uint32_t size);
/****************************************************************************
* Name: esp_spiflash_init
*
* Description:
* Initialize ESP SPI flash driver.
*
* Input Parameters:
* None.
*
* Returned Value:
* OK if success or a negative value if fail.
*
****************************************************************************/
int esp_spiflash_init(void);
#ifdef __cplusplus
}
#endif
#undef EXTERN
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPIFLASH_H */

View File

@ -0,0 +1,540 @@
/****************************************************************************
* arch/risc-v/src/common/espressif/esp_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 <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <inttypes.h>
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/init.h>
#include <nuttx/mutex.h>
#include <nuttx/mtd/mtd.h>
#include "esp_attr.h"
#include "esp_spiflash.h"
#include "esp_rom_spiflash.h"
#include "esp_rom_spiflash_defs.h"
#include "esp_spiflash_mtd.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MTD_BLK_SIZE CONFIG_ESPRESSIF_SPIFLASH_MTD_BLKSIZE
#define MTD_ERASE_SIZE 4096
#define MTD_ERASED_STATE (0xff)
#define MTD2PRIV(_dev) ((struct esp_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
****************************************************************************/
/* ESP SPI Flash device private data */
struct esp_mtd_dev_s
{
struct mtd_dev_s mtd;
/* SPI Flash data */
const esp_rom_spiflash_legacy_data_t **data;
};
/****************************************************************************
* Private Functions Prototypes
****************************************************************************/
/* MTD driver methods */
static int esp_erase(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks);
static ssize_t esp_read(struct mtd_dev_s *dev, off_t offset,
size_t nbytes, uint8_t *buffer);
static ssize_t esp_bread(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, uint8_t *buffer);
static ssize_t esp_write(struct mtd_dev_s *dev, off_t offset,
size_t nbytes, const uint8_t *buffer);
static ssize_t esp_bwrite(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, const uint8_t *buffer);
static int esp_ioctl(struct mtd_dev_s *dev, int cmd,
unsigned long arg);
/****************************************************************************
* Private Data
****************************************************************************/
static const struct esp_mtd_dev_s g_esp_spiflash =
{
.mtd =
{
.erase = esp_erase,
.bread = esp_bread,
.bwrite = esp_bwrite,
.read = esp_read,
.ioctl = esp_ioctl,
#ifdef CONFIG_MTD_BYTE_WRITE
.write = esp_write,
#endif
.name = "esp_spiflash"
},
.data = (const esp_rom_spiflash_legacy_data_t **)&rom_spiflash_legacy_data,
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: esp_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 esp_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 esp_mtd_dev_s *priv = (struct esp_mtd_dev_s *)dev;
irqstate_t flags;
if ((offset > MTD_SIZE(priv)) || ((offset + nbytes) > MTD_SIZE(priv)))
{
return -EINVAL;
}
#ifdef CONFIG_ESPRESSIF_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
flags = enter_critical_section();
ret = spi_flash_erase_range(offset, nbytes);
leave_critical_section(flags);
if (ret == OK)
{
ret = nblocks;
}
else
{
#ifdef CONFIG_ESPRESSIF_STORAGE_MTD_DEBUG
finfo("Failed to erase the flash range!\n");
#endif
ret = -1;
}
#ifdef CONFIG_ESPRESSIF_STORAGE_MTD_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp_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 esp_read(struct mtd_dev_s *dev, off_t offset,
size_t nbytes, uint8_t *buffer)
{
ssize_t ret;
irqstate_t flags;
#ifdef CONFIG_ESPRESSIF_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
flags = enter_critical_section();
ret = spi_flash_read(offset, (uint32_t *)buffer, nbytes);
leave_critical_section(flags);
if (ret == OK)
{
ret = nbytes;
}
#ifdef CONFIG_ESPRESSIF_STORAGE_MTD_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp_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 esp_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;
irqstate_t flags;
#ifdef CONFIG_ESPRESSIF_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
flags = enter_critical_section();
ret = spi_flash_read(addr, (uint32_t *)buffer, size);
leave_critical_section(flags);
if (ret == OK)
{
ret = nblocks;
}
#ifdef CONFIG_ESPRESSIF_STORAGE_MTD_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp_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 esp_write(struct mtd_dev_s *dev, off_t offset,
size_t nbytes, const uint8_t *buffer)
{
ssize_t ret;
struct esp_mtd_dev_s *priv = (struct esp_mtd_dev_s *)dev;
irqstate_t flags;
ASSERT(buffer);
if ((offset > MTD_SIZE(priv)) || ((offset + nbytes) > MTD_SIZE(priv)))
{
return -EINVAL;
}
#ifdef CONFIG_ESPRESSIF_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
flags = enter_critical_section();
ret = spi_flash_write(offset, (uint32_t *)buffer, nbytes);
leave_critical_section(flags);
if (ret == OK)
{
ret = nbytes;
}
#ifdef CONFIG_ESPRESSIF_STORAGE_MTD_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp_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 esp_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;
irqstate_t flags;
#ifdef CONFIG_ESPRESSIF_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
flags = enter_critical_section();
ret = spi_flash_write(addr, (uint32_t *)buffer, size);
leave_critical_section(flags);
if (ret == OK)
{
ret = nblocks;
}
#ifdef CONFIG_ESPRESSIF_STORAGE_MTD_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp_ioctl
*
* Description:
* Set/Get option to/from ESP SPI Flash MTD device data.
*
* Input Parameters:
* dev - ESP MTD device data
* cmd - operation command
* arg - operation argument
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
static int esp_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 esp_mtd_dev_s *priv = (struct esp_mtd_dev_s *)dev;
struct mtd_geometry_s *geo = (struct mtd_geometry_s *)arg;
if (geo)
{
memset(geo, 0, sizeof(*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 esp_mtd_dev_s *priv = (struct esp_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: esp_spiflash_alloc_mtdpart
*
* Description:
* Allocate an MTD partition from the ESP 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:
* ESP SPI Flash MTD data pointer if success or NULL if fail.
*
****************************************************************************/
struct mtd_dev_s *esp_spiflash_alloc_mtdpart(uint32_t mtd_offset,
uint32_t mtd_size)
{
const struct esp_mtd_dev_s *priv;
const esp_rom_spiflash_chip_t *chip;
struct mtd_dev_s *mtd_part;
uint32_t blocks;
uint32_t startblock;
uint32_t size;
priv = &g_esp_spiflash;
chip = &(*priv->data)->chip;
finfo("ESP 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: esp_spiflash_mtd
*
* Description:
* Get SPI Flash MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* ESP SPI Flash MTD pointer.
*
****************************************************************************/
struct mtd_dev_s *esp_spiflash_mtd(void)
{
struct esp_mtd_dev_s *priv =
(struct esp_mtd_dev_s *)&g_esp_spiflash;
return &priv->mtd;
}

View File

@ -0,0 +1,89 @@
/****************************************************************************
* arch/risc-v/src/common/espressif/esp_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_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPIFLASH_MTD_H
#define __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPIFLASH_MTD_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <nuttx/mtd/mtd.h>
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp_spiflash_mtd
*
* Description:
* Get SPI Flash MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* SPI Flash MTD pointer.
*
****************************************************************************/
struct mtd_dev_s *esp_spiflash_mtd(void);
/****************************************************************************
* Name: esp_spiflash_alloc_mtdpart
*
* Description:
* Allocate an MTD partition from the 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:
* SPI Flash MTD data pointer if success or NULL if fail.
*
****************************************************************************/
struct mtd_dev_s *esp_spiflash_alloc_mtdpart(uint32_t mtd_offset,
uint32_t mtd_size);
#ifdef __cplusplus
}
#endif
#undef EXTERN
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_SPIFLASH_MTD_H */

View File

@ -49,6 +49,8 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/compone
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/riscv/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/riscv/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y) ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/bootloader_support/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/bootloader_support/include

View File

@ -49,6 +49,8 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/compone
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/riscv/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/riscv/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash
# Linker scripts # Linker scripts

View File

@ -49,6 +49,8 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/compone
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/riscv/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/riscv/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash
# Linker scripts # Linker scripts

View File

@ -11,3 +11,40 @@ config ESPRESSIF_MERGE_BINS
device. device.
This is only useful when the path to binary files (e.g. bootloader) This is only useful when the path to binary files (e.g. bootloader)
is provided via the ESPTOOL_BINDIR variable. is provided via the ESPTOOL_BINDIR variable.
choice ESPRESSIF_SPIFLASH_FS
prompt "Mount SPI Flash MTD on bring-up"
default ESPRESSIF_SPIFLASH_SMARTFS
depends on ESPRESSIF_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 ESPRESSIF_SPIFLASH_SMARTFS
bool "SmartFS"
select FS_SMARTFS
select MTD_SMART
config ESPRESSIF_SPIFLASH_NXFFS
bool "NXFFS"
select FS_NXFFS
config ESPRESSIF_SPIFLASH_SPIFFS
bool "SPIFFS"
select FS_SPIFFS
config ESPRESSIF_SPIFLASH_LITTLEFS
bool "LittleFS"
select FS_LITTLEFS
config ESPRESSIF_SPIFLASH_MTD_CONFIG
bool "Non-volatile storage"
endchoice # ESPRESSIF_SPIFLASH_FS
config ESPRESSIF_SPIFLASH_FS_MOUNT_PT
string "File-system Mount Point"
depends on ESPRESSIF_SPIFLASH_LITTLEFS
default "/data"

View File

@ -0,0 +1,74 @@
/****************************************************************************
* boards/risc-v/esp32c3/common/include/esp_board_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 __BOARDS_RISCV_ESP32C3_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H
#define __BOARDS_RISCV_ESP32C3_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: board_spiflash_init
*
* Description:
* Initialize the SPIFLASH and register the MTD device.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned
* to indicate the nature of any failure.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_SPIFLASH
int board_spiflash_init(void);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_RISCV_ESP32C3_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H */

View File

@ -28,6 +28,10 @@ ifeq ($(CONFIG_ESP_RMT),y)
CSRCS += esp_board_rmt.c CSRCS += esp_board_rmt.c
endif endif
ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
CSRCS += esp_board_spiflash.c
endif
DEPPATH += --dep-path src DEPPATH += --dep-path src
VPATH += :src VPATH += :src
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src

View File

@ -0,0 +1,417 @@
/****************************************************************************
* boards/risc-v/esp32c3/common/src/esp_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 <nuttx/config.h>
#include <sys/mount.h>
#include "inttypes.h"
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <sys/param.h>
#include <nuttx/kmalloc.h>
#include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/mtd/configdata.h>
#include <nuttx/fs/nxffs.h>
#ifdef CONFIG_BCH
#include <nuttx/drivers/drivers.h>
#endif
#include "espressif/esp_spiflash.h"
#include "espressif/esp_spiflash_mtd.h"
#include "esp_board_spiflash.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* 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_ESPRESSIF_SPIFLASH_SMARTFS)
static int setup_smartfs(int smartn, struct mtd_dev_s *mtd,
const char *mnt_pt)
{
int ret = OK;
char path[22];
ret = smart_initialize(smartn, mtd, NULL);
if (ret < 0)
{
syslog(LOG_INFO, "smart_initialize failed, "
"Trying to erase first...\n");
ret = mtd->ioctl(mtd, MTDIOC_BULKERASE, 0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: ioctl(BULKERASE) failed: %d\n", ret);
return ret;
}
syslog(LOG_INFO, "Erase successful, initializing it again.\n");
ret = smart_initialize(smartn, mtd, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "ERROR: Failed to mount the FS volume: %d\n", ret);
if (ret == -ENODEV)
{
syslog(LOG_WARNING, "Smartfs seems unformatted. "
"Did you run 'mksmartfs /dev/smart%d'?\n", smartn);
}
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_ESPRESSIF_SPIFLASH_LITTLEFS)
static int setup_littlefs(const char *path, struct mtd_dev_s *mtd,
const char *mnt_pt, int priv)
{
int ret = OK;
ret = register_mtddriver(path, mtd, priv, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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_ESPRESSIF_SPIFLASH_SPIFFS)
static int setup_spiffs(const char *path, struct mtd_dev_s *mtd,
const char *mnt_pt, int priv)
{
int ret = OK;
ret = register_mtddriver(path, mtd, priv, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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 NXFFS 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_ESPRESSIF_SPIFLASH_NXFFS)
static int setup_nxffs(struct mtd_dev_s *mtd, const char *mnt_pt)
{
int ret = OK;
ret = nxffs_initialize(mtd);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int init_storage_partition(void)
{
int ret = OK;
struct mtd_dev_s *mtd;
mtd = esp_spiflash_alloc_mtdpart(CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET,
CONFIG_ESPRESSIF_STORAGE_MTD_SIZE);
if (!mtd)
{
syslog(LOG_ERR, "ERROR: Failed to alloc MTD partition of SPI Flash\n");
return ERROR;
}
#if defined (CONFIG_ESPRESSIF_SPIFLASH_SMARTFS)
ret = setup_smartfs(0, mtd, "/data");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup smartfs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_NXFFS)
ret = setup_nxffs(mtd, "/data");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup nxffs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_LITTLEFS)
const char *path = "/dev/espflash";
ret = setup_littlefs(path, mtd, "/data", 0755);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup littlefs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_SPIFFS)
const char *path = "/dev/espflash";
ret = setup_spiffs(path, mtd, "/data", 0755);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup spiffs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_MTD_CONFIG)
# if defined (CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE)
/* To test power-loss resilient kv system,
* we write possible power-loss flash layout into flash
* then start kv system to see if it recovers.
* To do so, we need a mtd driver so that test code can
* write into flash.
*/
const char *path = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME;
ret = register_mtddriver(path, mtd, 0777, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to register MTD: %d\n", ret);
return ret;
}
# else
ret = mtdconfig_register(mtd);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup mtd config\n");
return ret;
}
# endif
#else
ret = register_mtddriver("/dev/espflash", mtd, 0755, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to register MTD: %d\n", ret);
return ret;
}
#endif
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_spiflash_init
*
* Description:
* Initialize the SPI Flash and register the MTD device.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned
* to indicate the nature of any failure.
*
****************************************************************************/
int board_spiflash_init(void)
{
int ret = OK;
esp_spiflash_init();
ret = init_storage_partition();
if (ret < 0)
{
return ret;
}
return ret;
}

View File

@ -0,0 +1,54 @@
#
# 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_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32c3-generic"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32C3_GENERIC=y
CONFIG_ARCH_CHIP="esp32c3"
CONFIG_ARCH_CHIP_ESP32C3_GENERIC=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_SPIFLASH=y
CONFIG_ESPRESSIF_SPIFLASH_SMARTFS=y
CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET=0x110000
CONFIG_ESPRESSIF_STORAGE_MTD_SIZE=0xf0000
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NAME_MAX=48
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_LOSMART=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_SMARTFS_MAXNAMLEN=48
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_FLASH_ERASEALL=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_FSTEST=y
CONFIG_TESTING_FSTEST_MOUNTPT="/mnt"
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -35,6 +35,7 @@
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include "esp_board_ledc.h" #include "esp_board_ledc.h"
#include "esp_board_spiflash.h"
#ifdef CONFIG_WATCHDOG #ifdef CONFIG_WATCHDOG
# include "espressif/esp_wdt.h" # include "espressif/esp_wdt.h"
@ -143,6 +144,14 @@ int esp_bringup(void)
#endif #endif
#endif #endif
#ifdef CONFIG_ESPRESSIF_SPIFLASH
ret = board_spiflash_init();
if (ret)
{
syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n");
}
#endif
#ifdef CONFIG_ONESHOT #ifdef CONFIG_ONESHOT
ret = esp_oneshot_initialize(); ret = esp_oneshot_initialize();
if (ret < 0) if (ret < 0)

View File

@ -11,3 +11,40 @@ config ESPRESSIF_MERGE_BINS
device. device.
This is only useful when the path to binary files (e.g. bootloader) This is only useful when the path to binary files (e.g. bootloader)
is provided via the ESPTOOL_BINDIR variable. is provided via the ESPTOOL_BINDIR variable.
choice ESPRESSIF_SPIFLASH_FS
prompt "Mount SPI Flash MTD on bring-up"
default ESPRESSIF_SPIFLASH_SMARTFS
depends on ESPRESSIF_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 ESPRESSIF_SPIFLASH_SMARTFS
bool "SmartFS"
select FS_SMARTFS
select MTD_SMART
config ESPRESSIF_SPIFLASH_NXFFS
bool "NXFFS"
select FS_NXFFS
config ESPRESSIF_SPIFLASH_SPIFFS
bool "SPIFFS"
select FS_SPIFFS
config ESPRESSIF_SPIFLASH_LITTLEFS
bool "LittleFS"
select FS_LITTLEFS
config ESPRESSIF_SPIFLASH_MTD_CONFIG
bool "Non-volatile storage"
endchoice # ESPRESSIF_SPIFLASH_FS
config ESPRESSIF_SPIFLASH_FS_MOUNT_PT
string "File-system Mount Point"
depends on ESPRESSIF_SPIFLASH_LITTLEFS
default "/data"

View File

@ -0,0 +1,74 @@
/****************************************************************************
* boards/risc-v/esp32c6/common/include/esp_board_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 __BOARDS_RISCV_ESP32C6_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H
#define __BOARDS_RISCV_ESP32C6_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: board_spiflash_init
*
* Description:
* Initialize the SPIFLASH and register the MTD device.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned
* to indicate the nature of any failure.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_SPIFLASH
int board_spiflash_init(void);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_RISCV_ESP32C6_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H */

View File

@ -18,6 +18,9 @@
* *
****************************************************************************/ ****************************************************************************/
cache_resume_icache = Cache_Resume_ICache;
cache_suspend_icache = Cache_Suspend_ICache;
#ifdef CONFIG_ESPRESSIF_BLE #ifdef CONFIG_ESPRESSIF_BLE
/* Lower-case aliases for BLE library symbols not compliant to nxstyle */ /* Lower-case aliases for BLE library symbols not compliant to nxstyle */

View File

@ -28,6 +28,10 @@ ifeq ($(CONFIG_ESP_RMT),y)
CSRCS += esp_board_rmt.c CSRCS += esp_board_rmt.c
endif endif
ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
CSRCS += esp_board_spiflash.c
endif
DEPPATH += --dep-path src DEPPATH += --dep-path src
VPATH += :src VPATH += :src
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src

View File

@ -0,0 +1,417 @@
/****************************************************************************
* boards/risc-v/esp32c6/common/src/esp_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 <nuttx/config.h>
#include <sys/mount.h>
#include "inttypes.h"
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <sys/param.h>
#include <nuttx/kmalloc.h>
#include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/mtd/configdata.h>
#include <nuttx/fs/nxffs.h>
#ifdef CONFIG_BCH
#include <nuttx/drivers/drivers.h>
#endif
#include "espressif/esp_spiflash.h"
#include "espressif/esp_spiflash_mtd.h"
#include "esp_board_spiflash.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* 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_ESPRESSIF_SPIFLASH_SMARTFS)
static int setup_smartfs(int smartn, struct mtd_dev_s *mtd,
const char *mnt_pt)
{
int ret = OK;
char path[22];
ret = smart_initialize(smartn, mtd, NULL);
if (ret < 0)
{
syslog(LOG_INFO, "smart_initialize failed, "
"Trying to erase first...\n");
ret = mtd->ioctl(mtd, MTDIOC_BULKERASE, 0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: ioctl(BULKERASE) failed: %d\n", ret);
return ret;
}
syslog(LOG_INFO, "Erase successful, initializing it again.\n");
ret = smart_initialize(smartn, mtd, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "ERROR: Failed to mount the FS volume: %d\n", ret);
if (ret == -ENODEV)
{
syslog(LOG_WARNING, "Smartfs seems unformatted. "
"Did you run 'mksmartfs /dev/smart%d'?\n", smartn);
}
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_ESPRESSIF_SPIFLASH_LITTLEFS)
static int setup_littlefs(const char *path, struct mtd_dev_s *mtd,
const char *mnt_pt, int priv)
{
int ret = OK;
ret = register_mtddriver(path, mtd, priv, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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_ESPRESSIF_SPIFLASH_SPIFFS)
static int setup_spiffs(const char *path, struct mtd_dev_s *mtd,
const char *mnt_pt, int priv)
{
int ret = OK;
ret = register_mtddriver(path, mtd, priv, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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 NXFFS 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_ESPRESSIF_SPIFLASH_NXFFS)
static int setup_nxffs(struct mtd_dev_s *mtd, const char *mnt_pt)
{
int ret = OK;
ret = nxffs_initialize(mtd);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int init_storage_partition(void)
{
int ret = OK;
struct mtd_dev_s *mtd;
mtd = esp_spiflash_alloc_mtdpart(CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET,
CONFIG_ESPRESSIF_STORAGE_MTD_SIZE);
if (!mtd)
{
syslog(LOG_ERR, "ERROR: Failed to alloc MTD partition of SPI Flash\n");
return ERROR;
}
#if defined (CONFIG_ESPRESSIF_SPIFLASH_SMARTFS)
ret = setup_smartfs(0, mtd, "/data");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup smartfs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_NXFFS)
ret = setup_nxffs(mtd, "/data");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup nxffs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_LITTLEFS)
const char *path = "/dev/espflash";
ret = setup_littlefs(path, mtd, "/data", 0755);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup littlefs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_SPIFFS)
const char *path = "/dev/espflash";
ret = setup_spiffs(path, mtd, "/data", 0755);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup spiffs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_MTD_CONFIG)
# if defined (CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE)
/* To test power-loss resilient kv system,
* we write possible power-loss flash layout into flash
* then start kv system to see if it recovers.
* To do so, we need a mtd driver so that test code can
* write into flash.
*/
const char *path = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME;
ret = register_mtddriver(path, mtd, 0777, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to register MTD: %d\n", ret);
return ret;
}
# else
ret = mtdconfig_register(mtd);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup mtd config\n");
return ret;
}
# endif
#else
ret = register_mtddriver("/dev/espflash", mtd, 0755, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to register MTD: %d\n", ret);
return ret;
}
#endif
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_spiflash_init
*
* Description:
* Initialize the SPI Flash and register the MTD device.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned
* to indicate the nature of any failure.
*
****************************************************************************/
int board_spiflash_init(void)
{
int ret = OK;
esp_spiflash_init();
ret = init_storage_partition();
if (ret < 0)
{
return ret;
}
return ret;
}

View File

@ -0,0 +1,55 @@
#
# 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_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32c6-devkit"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32C6_DEVKIT=y
CONFIG_ARCH_CHIP="esp32c6"
CONFIG_ARCH_CHIP_ESP32C6=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_ESP32C6=y
CONFIG_ESPRESSIF_SPIFLASH=y
CONFIG_ESPRESSIF_SPIFLASH_SMARTFS=y
CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET=0x110000
CONFIG_ESPRESSIF_STORAGE_MTD_SIZE=0xf0000
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NAME_MAX=48
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_LOSMART=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_SMARTFS_MAXNAMLEN=48
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_FLASH_ERASEALL=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_FSTEST=y
CONFIG_TESTING_FSTEST_MOUNTPT="/mnt"
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -35,6 +35,7 @@
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include "esp_board_ledc.h" #include "esp_board_ledc.h"
#include "esp_board_spiflash.h"
#ifdef CONFIG_WATCHDOG #ifdef CONFIG_WATCHDOG
# include "espressif/esp_wdt.h" # include "espressif/esp_wdt.h"
@ -175,6 +176,14 @@ int esp_bringup(void)
} }
#endif #endif
#ifdef CONFIG_ESPRESSIF_SPIFLASH
ret = board_spiflash_init();
if (ret)
{
syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n");
}
#endif
#ifdef CONFIG_DEV_GPIO #ifdef CONFIG_DEV_GPIO
ret = esp_gpio_init(); ret = esp_gpio_init();
if (ret < 0) if (ret < 0)

View File

@ -11,3 +11,40 @@ config ESPRESSIF_MERGE_BINS
device. device.
This is only useful when the path to binary files (e.g. bootloader) This is only useful when the path to binary files (e.g. bootloader)
is provided via the ESPTOOL_BINDIR variable. is provided via the ESPTOOL_BINDIR variable.
choice ESPRESSIF_SPIFLASH_FS
prompt "Mount SPI Flash MTD on bring-up"
default ESPRESSIF_SPIFLASH_SMARTFS
depends on ESPRESSIF_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 ESPRESSIF_SPIFLASH_SMARTFS
bool "SmartFS"
select FS_SMARTFS
select MTD_SMART
config ESPRESSIF_SPIFLASH_NXFFS
bool "NXFFS"
select FS_NXFFS
config ESPRESSIF_SPIFLASH_SPIFFS
bool "SPIFFS"
select FS_SPIFFS
config ESPRESSIF_SPIFLASH_LITTLEFS
bool "LittleFS"
select FS_LITTLEFS
config ESPRESSIF_SPIFLASH_MTD_CONFIG
bool "Non-volatile storage"
endchoice # ESPRESSIF_SPIFLASH_FS
config ESPRESSIF_SPIFLASH_FS_MOUNT_PT
string "File-system Mount Point"
depends on ESPRESSIF_SPIFLASH_LITTLEFS
default "/data"

View File

@ -0,0 +1,74 @@
/****************************************************************************
* boards/risc-v/esp32h2/common/include/esp_board_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 __BOARDS_RISCV_ESP32H2_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H
#define __BOARDS_RISCV_ESP32H2_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: board_spiflash_init
*
* Description:
* Initialize the SPIFLASH and register the MTD device.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned
* to indicate the nature of any failure.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_SPIFLASH
int board_spiflash_init(void);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_RISCV_ESP32H2_COMMON_INCLUDE_ESP_BOARD_SPIFLASH_H */

View File

@ -18,6 +18,9 @@
* *
****************************************************************************/ ****************************************************************************/
cache_resume_icache = Cache_Resume_ICache;
cache_suspend_icache = Cache_Suspend_ICache;
#ifdef CONFIG_ESPRESSIF_BLE #ifdef CONFIG_ESPRESSIF_BLE
/* Lower-case aliases for BLE library symbols not compliant to nxstyle */ /* Lower-case aliases for BLE library symbols not compliant to nxstyle */

View File

@ -28,6 +28,10 @@ ifeq ($(CONFIG_ESP_RMT),y)
CSRCS += esp_board_rmt.c CSRCS += esp_board_rmt.c
endif endif
ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
CSRCS += esp_board_spiflash.c
endif
DEPPATH += --dep-path src DEPPATH += --dep-path src
VPATH += :src VPATH += :src
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src

View File

@ -0,0 +1,417 @@
/****************************************************************************
* boards/risc-v/esp32h2/common/src/esp_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 <nuttx/config.h>
#include <sys/mount.h>
#include "inttypes.h"
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <sys/param.h>
#include <nuttx/kmalloc.h>
#include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/mtd/configdata.h>
#include <nuttx/fs/nxffs.h>
#ifdef CONFIG_BCH
#include <nuttx/drivers/drivers.h>
#endif
#include "espressif/esp_spiflash.h"
#include "espressif/esp_spiflash_mtd.h"
#include "esp_board_spiflash.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* 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_ESPRESSIF_SPIFLASH_SMARTFS)
static int setup_smartfs(int smartn, struct mtd_dev_s *mtd,
const char *mnt_pt)
{
int ret = OK;
char path[22];
ret = smart_initialize(smartn, mtd, NULL);
if (ret < 0)
{
syslog(LOG_INFO, "smart_initialize failed, "
"Trying to erase first...\n");
ret = mtd->ioctl(mtd, MTDIOC_BULKERASE, 0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: ioctl(BULKERASE) failed: %d\n", ret);
return ret;
}
syslog(LOG_INFO, "Erase successful, initializing it again.\n");
ret = smart_initialize(smartn, mtd, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "ERROR: Failed to mount the FS volume: %d\n", ret);
if (ret == -ENODEV)
{
syslog(LOG_WARNING, "Smartfs seems unformatted. "
"Did you run 'mksmartfs /dev/smart%d'?\n", smartn);
}
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_ESPRESSIF_SPIFLASH_LITTLEFS)
static int setup_littlefs(const char *path, struct mtd_dev_s *mtd,
const char *mnt_pt, int priv)
{
int ret = OK;
ret = register_mtddriver(path, mtd, priv, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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_ESPRESSIF_SPIFLASH_SPIFFS)
static int setup_spiffs(const char *path, struct mtd_dev_s *mtd,
const char *mnt_pt, int priv)
{
int ret = OK;
ret = register_mtddriver(path, mtd, priv, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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 NXFFS 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_ESPRESSIF_SPIFLASH_NXFFS)
static int setup_nxffs(struct mtd_dev_s *mtd, const char *mnt_pt)
{
int ret = OK;
ret = nxffs_initialize(mtd);
if (ret < 0)
{
syslog(LOG_ERR, "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)
{
syslog(LOG_ERR, "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.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int init_storage_partition(void)
{
int ret = OK;
struct mtd_dev_s *mtd;
mtd = esp_spiflash_alloc_mtdpart(CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET,
CONFIG_ESPRESSIF_STORAGE_MTD_SIZE);
if (!mtd)
{
syslog(LOG_ERR, "ERROR: Failed to alloc MTD partition of SPI Flash\n");
return ERROR;
}
#if defined (CONFIG_ESPRESSIF_SPIFLASH_SMARTFS)
ret = setup_smartfs(0, mtd, "/data");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup smartfs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_NXFFS)
ret = setup_nxffs(mtd, "/data");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup nxffs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_LITTLEFS)
const char *path = "/dev/espflash";
ret = setup_littlefs(path, mtd, "/data", 0755);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup littlefs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_SPIFFS)
const char *path = "/dev/espflash";
ret = setup_spiffs(path, mtd, "/data", 0755);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup spiffs\n");
return ret;
}
#elif defined (CONFIG_ESPRESSIF_SPIFLASH_MTD_CONFIG)
# if defined (CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE)
/* To test power-loss resilient kv system,
* we write possible power-loss flash layout into flash
* then start kv system to see if it recovers.
* To do so, we need a mtd driver so that test code can
* write into flash.
*/
const char *path = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME;
ret = register_mtddriver(path, mtd, 0777, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to register MTD: %d\n", ret);
return ret;
}
# else
ret = mtdconfig_register(mtd);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to setup mtd config\n");
return ret;
}
# endif
#else
ret = register_mtddriver("/dev/espflash", mtd, 0755, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to register MTD: %d\n", ret);
return ret;
}
#endif
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_spiflash_init
*
* Description:
* Initialize the SPI Flash and register the MTD device.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned
* to indicate the nature of any failure.
*
****************************************************************************/
int board_spiflash_init(void)
{
int ret = OK;
esp_spiflash_init();
ret = init_storage_partition();
if (ret < 0)
{
return ret;
}
return ret;
}

View File

@ -0,0 +1,55 @@
#
# 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_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32h2-devkit"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32H2_DEVKIT=y
CONFIG_ARCH_CHIP="esp32h2"
CONFIG_ARCH_CHIP_ESP32H2=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_ESP32H2=y
CONFIG_ESPRESSIF_SPIFLASH=y
CONFIG_ESPRESSIF_SPIFLASH_SMARTFS=y
CONFIG_ESPRESSIF_STORAGE_MTD_OFFSET=0x110000
CONFIG_ESPRESSIF_STORAGE_MTD_SIZE=0xf0000
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NAME_MAX=48
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_LOSMART=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_SMARTFS_MAXNAMLEN=48
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_FLASH_ERASEALL=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_FSTEST=y
CONFIG_TESTING_FSTEST_MOUNTPT="/mnt"
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -35,6 +35,7 @@
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include "esp_board_ledc.h" #include "esp_board_ledc.h"
#include "esp_board_spiflash.h"
#ifdef CONFIG_WATCHDOG #ifdef CONFIG_WATCHDOG
# include "espressif/esp_wdt.h" # include "espressif/esp_wdt.h"
@ -175,6 +176,14 @@ int esp_bringup(void)
} }
#endif #endif
#ifdef CONFIG_ESPRESSIF_SPIFLASH
ret = board_spiflash_init();
if (ret)
{
syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n");
}
#endif
#ifdef CONFIG_DEV_GPIO #ifdef CONFIG_DEV_GPIO
ret = esp_gpio_init(); ret = esp_gpio_init();
if (ret < 0) if (ret < 0)