risc-v/espressif: Add SPI Flash support
This commit is contained in:
parent
7b37dd1224
commit
aa0dccb7bc
@ -43,6 +43,12 @@ config ESPRESSIF_FLASH_2M
|
||||
config ESPRESSIF_FLASH_4M
|
||||
bool "4 MB"
|
||||
|
||||
config ESPRESSIF_FLASH_8M
|
||||
bool "8 MB"
|
||||
|
||||
config ESPRESSIF_FLASH_16M
|
||||
bool "16 MB"
|
||||
|
||||
endchoice # ESPRESSIF_FLASH
|
||||
|
||||
config ESPRESSIF_FLASH_DETECT
|
||||
@ -281,6 +287,10 @@ config ESPRESSIF_LEDC
|
||||
select PWM
|
||||
select ARCH_HAVE_PWM_MULTICHAN
|
||||
|
||||
config ESPRESSIF_SPIFLASH
|
||||
bool "SPI Flash"
|
||||
default n
|
||||
|
||||
config ESPRESSIF_HR_TIMER
|
||||
bool
|
||||
default RTC_DRIVER
|
||||
@ -408,6 +418,35 @@ config ESPRESSIF_FLASH_MODE_QOUT
|
||||
|
||||
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
|
||||
prompt "SPI Flash frequency"
|
||||
default ESPRESSIF_FLASH_FREQ_80M if ESPRESSIF_ESP32C3 || ESPRESSIF_ESP32C6
|
||||
@ -437,6 +476,29 @@ config ESPRESSIF_FLASH_FREQ_20M
|
||||
|
||||
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
|
||||
|
||||
menu "LEDC configuration"
|
||||
|
@ -80,6 +80,13 @@ ifeq ($(CONFIG_ESP_RMT),y)
|
||||
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
|
||||
#############################################################################
|
||||
@ -88,7 +95,7 @@ endif
|
||||
|
||||
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
|
||||
ifndef ESP_HAL_3RDPARTY_VERSION
|
||||
ESP_HAL_3RDPARTY_VERSION = b6a943764f5e5a12d12edd8a6d71bdecc505428c
|
||||
ESP_HAL_3RDPARTY_VERSION = 7951b5b282384ec43858a28ddfabbef7b6b326cb
|
||||
endif
|
||||
|
||||
ifndef ESP_HAL_3RDPARTY_URL
|
||||
|
@ -115,6 +115,19 @@ static volatile uint8_t g_irq_map[NR_IRQS];
|
||||
|
||||
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
|
||||
****************************************************************************/
|
||||
@ -280,6 +293,15 @@ static void esp_cpuint_initialize(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 */
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
594
arch/risc-v/src/common/espressif/esp_spiflash.c
Normal file
594
arch/risc-v/src/common/espressif/esp_spiflash.c
Normal 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;
|
||||
}
|
188
arch/risc-v/src/common/espressif/esp_spiflash.h
Normal file
188
arch/risc-v/src/common/espressif/esp_spiflash.h
Normal 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 */
|
540
arch/risc-v/src/common/espressif/esp_spiflash_mtd.c
Normal file
540
arch/risc-v/src/common/espressif/esp_spiflash_mtd.c
Normal 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;
|
||||
}
|
89
arch/risc-v/src/common/espressif/esp_spiflash_mtd.h
Normal file
89
arch/risc-v/src/common/espressif/esp_spiflash_mtd.h
Normal 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 */
|
@ -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/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/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)
|
||||
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/bootloader_support/include
|
||||
|
@ -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/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/spi_flash/include
|
||||
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash
|
||||
|
||||
# Linker scripts
|
||||
|
||||
|
@ -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/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/spi_flash/include
|
||||
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash
|
||||
|
||||
# Linker scripts
|
||||
|
||||
|
@ -11,3 +11,40 @@ config ESPRESSIF_MERGE_BINS
|
||||
device.
|
||||
This is only useful when the path to binary files (e.g. bootloader)
|
||||
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"
|
||||
|
74
boards/risc-v/esp32c3/common/include/esp_board_spiflash.h
Normal file
74
boards/risc-v/esp32c3/common/include/esp_board_spiflash.h
Normal 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 */
|
@ -28,6 +28,10 @@ ifeq ($(CONFIG_ESP_RMT),y)
|
||||
CSRCS += esp_board_rmt.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
|
||||
CSRCS += esp_board_spiflash.c
|
||||
endif
|
||||
|
||||
DEPPATH += --dep-path src
|
||||
VPATH += :src
|
||||
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src
|
||||
|
417
boards/risc-v/esp32c3/common/src/esp_board_spiflash.c
Normal file
417
boards/risc-v/esp32c3/common/src/esp_board_spiflash.c
Normal 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;
|
||||
}
|
||||
|
@ -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
|
@ -35,6 +35,7 @@
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "esp_board_ledc.h"
|
||||
#include "esp_board_spiflash.h"
|
||||
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
# include "espressif/esp_wdt.h"
|
||||
@ -143,6 +144,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_ONESHOT
|
||||
ret = esp_oneshot_initialize();
|
||||
if (ret < 0)
|
||||
|
@ -11,3 +11,40 @@ config ESPRESSIF_MERGE_BINS
|
||||
device.
|
||||
This is only useful when the path to binary files (e.g. bootloader)
|
||||
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"
|
||||
|
74
boards/risc-v/esp32c6/common/include/esp_board_spiflash.h
Normal file
74
boards/risc-v/esp32c6/common/include/esp_board_spiflash.h
Normal 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 */
|
@ -18,6 +18,9 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
cache_resume_icache = Cache_Resume_ICache;
|
||||
cache_suspend_icache = Cache_Suspend_ICache;
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_BLE
|
||||
|
||||
/* Lower-case aliases for BLE library symbols not compliant to nxstyle */
|
||||
|
@ -28,6 +28,10 @@ ifeq ($(CONFIG_ESP_RMT),y)
|
||||
CSRCS += esp_board_rmt.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
|
||||
CSRCS += esp_board_spiflash.c
|
||||
endif
|
||||
|
||||
DEPPATH += --dep-path src
|
||||
VPATH += :src
|
||||
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src
|
||||
|
417
boards/risc-v/esp32c6/common/src/esp_board_spiflash.c
Normal file
417
boards/risc-v/esp32c6/common/src/esp_board_spiflash.c
Normal 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;
|
||||
}
|
||||
|
@ -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
|
@ -35,6 +35,7 @@
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "esp_board_ledc.h"
|
||||
#include "esp_board_spiflash.h"
|
||||
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
# include "espressif/esp_wdt.h"
|
||||
@ -175,6 +176,14 @@ int esp_bringup(void)
|
||||
}
|
||||
#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
|
||||
ret = esp_gpio_init();
|
||||
if (ret < 0)
|
||||
|
@ -11,3 +11,40 @@ config ESPRESSIF_MERGE_BINS
|
||||
device.
|
||||
This is only useful when the path to binary files (e.g. bootloader)
|
||||
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"
|
||||
|
74
boards/risc-v/esp32h2/common/include/esp_board_spiflash.h
Normal file
74
boards/risc-v/esp32h2/common/include/esp_board_spiflash.h
Normal 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 */
|
@ -18,6 +18,9 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
cache_resume_icache = Cache_Resume_ICache;
|
||||
cache_suspend_icache = Cache_Suspend_ICache;
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_BLE
|
||||
|
||||
/* Lower-case aliases for BLE library symbols not compliant to nxstyle */
|
||||
|
@ -28,6 +28,10 @@ ifeq ($(CONFIG_ESP_RMT),y)
|
||||
CSRCS += esp_board_rmt.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
|
||||
CSRCS += esp_board_spiflash.c
|
||||
endif
|
||||
|
||||
DEPPATH += --dep-path src
|
||||
VPATH += :src
|
||||
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src
|
||||
|
417
boards/risc-v/esp32h2/common/src/esp_board_spiflash.c
Normal file
417
boards/risc-v/esp32h2/common/src/esp_board_spiflash.c
Normal 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;
|
||||
}
|
||||
|
@ -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
|
@ -35,6 +35,7 @@
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "esp_board_ledc.h"
|
||||
#include "esp_board_spiflash.h"
|
||||
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
# include "espressif/esp_wdt.h"
|
||||
@ -175,6 +176,14 @@ int esp_bringup(void)
|
||||
}
|
||||
#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
|
||||
ret = esp_gpio_init();
|
||||
if (ret < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user