diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig index a620ed3d755..e955ee65571 100644 --- a/arch/risc-v/src/esp32c3/Kconfig +++ b/arch/risc-v/src/esp32c3/Kconfig @@ -169,6 +169,14 @@ config ESP32C3_WIRELESS default n select ESP32C3_RT_TIMER +config ESP32C3_EXCEPTION_ENABLE_CACHE + bool + default y + depends on ESP32C3_SPIFLASH + ---help--- + When exception triggers, panic function enables SPI Flash cache to + let functions be able to call functions which locate in SPI Flash. + menu "ESP32-C3 Peripheral Support" config ESP32C3_ADC @@ -264,9 +272,6 @@ config ESP32C3_TIMER1 config ESP32C3_SPIFLASH bool "SPI Flash" default n - select MTD - select MTD_BYTE_WRITE - select MTD_PARTITION config ESP32C3_SPI2 bool "SPI 2" @@ -856,10 +861,6 @@ endmenu # Wi-Fi configuration menu "BLE Configuration" depends on ESP32C3_BLE -config ESP32C3_BLE_PKTBUF_NUM - int "BLE netcard packet buffer number per netcard" - default 16 - config ESP32C3_BLE_TTY_NAME string "BLE TTY device name" default "/dev/ttyHCI0" @@ -871,7 +872,7 @@ config ESP32C3_BLE_TASK_STACK_SIZE config ESP32C3_BLE_TASK_PRIORITY int "Controller task priority" - default 110 + default 253 endmenu # BLE Configuration @@ -918,25 +919,42 @@ endif comment "General storage MTD configuration" +config ESP32C3_MTD + bool "MTD driver" + default y + select MTD + select MTD_BYTE_WRITE + select MTD_PARTITION + ---help--- + Initialize an MTD driver for the ESP32-C3 SPI Flash, which will + add an entry at /dev for application access from userspace. + +config ESP32C3_STORAGE_MTD_BLKSIZE + int "Storage MTD block size" + default 64 + depends on ESP32C3_MTD + config ESP32C3_STORAGE_MTD_OFFSET hex "Storage MTD base address in SPI Flash" default 0x180000 if !ESP32C3_HAVE_OTA_PARTITION default 0x250000 if ESP32C3_HAVE_OTA_PARTITION + depends on ESP32C3_MTD ---help--- MTD base address in SPI Flash. config ESP32C3_STORAGE_MTD_SIZE hex "Storage MTD size in SPI Flash" default 0x100000 + depends on ESP32C3_MTD ---help--- MTD size in SPI Flash. -config ESP32C3_SPIFLASH_DEBUG - bool "Debug SPI Flash" +config ESP32C3_STORAGE_MTD_DEBUG + bool "Storage MTD Debug" default n - depends on DEBUG_FS_INFO + depends on ESP32C3_MTD && DEBUG_FS_INFO ---help--- - If this option is enabled, SPI Flash driver read and write functions + If this option is enabled, Storage MTD driver read and write functions will output input parameters and return values (if applicable). if ESP32C3_APP_FORMAT_LEGACY diff --git a/arch/risc-v/src/esp32c3/Make.defs b/arch/risc-v/src/esp32c3/Make.defs index 085e48676db..513852d9873 100644 --- a/arch/risc-v/src/esp32c3/Make.defs +++ b/arch/risc-v/src/esp32c3/Make.defs @@ -81,6 +81,9 @@ endif ifeq ($(CONFIG_ESP32C3_SPIFLASH),y) CHIP_CSRCS += esp32c3_spiflash.c + ifeq ($(CONFIG_ESP32C3_MTD),y) + CHIP_CSRCS += esp32c3_spiflash_mtd.c + endif endif ifeq ($(CONFIG_ESP32C3_PARTITION_TABLE),y) diff --git a/arch/risc-v/src/esp32c3/esp32c3_ble.c b/arch/risc-v/src/esp32c3/esp32c3_ble.c index 47bab8b21f2..1df5dc1b218 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_ble.c +++ b/arch/risc-v/src/esp32c3/esp32c3_ble.c @@ -51,18 +51,10 @@ * Pre-processor Definitions ****************************************************************************/ -/* BLE packet buffer max number */ - -#define BLE_BUF_NUM CONFIG_ESP32C3_BLE_PKTBUF_NUM - /* BLE packet buffer max size */ #define BLE_BUF_SIZE 1024 -/* Low-priority work queue process RX/TX */ - -#define BLE_WORK LPWORK - /**************************************************************************** * Private Types ****************************************************************************/ diff --git a/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c index 5be6cc56b35..366b3a4a87c 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c +++ b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -49,11 +48,15 @@ #include #include "hardware/esp32c3_syscon.h" +#include "hardware/wdev_reg.h" +#include "rom/esp32c3_spiflash.h" #include "espidf_wifi.h" #include "esp32c3.h" #include "esp32c3_attr.h" #include "esp32c3_irq.h" #include "esp32c3_rt_timer.h" +#include "esp32c3_spiflash.h" +#include "esp32c3_wireless.h" #include "esp32c3_ble_adapter.h" #include "esp32c3_wireless.h" @@ -132,6 +135,14 @@ typedef struct btdm_lpstat_s bool wakeup_timer_started; /* whether wakeup timer is started */ } btdm_lpstat_t; +struct bt_sem_s +{ + sem_t sem; +#ifdef CONFIG_ESP32C3_SPIFLASH + struct esp32c3_wl_semcache_s sc; +#endif +}; + #ifdef CONFIG_PM /* wakeup request sources */ @@ -238,37 +249,37 @@ static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio); static void interrupt_clear_wrapper(int intr_source, int intr_num); static void interrupt_handler_set_wrapper(int n, void *fn, void *arg); -static void IRAM_ATTR interrupt_disable(void); -static void IRAM_ATTR interrupt_restore(void); -static void IRAM_ATTR task_yield_from_isr(void); +static void interrupt_disable(void); +static void interrupt_restore(void); +static void task_yield_from_isr(void); static void *semphr_create_wrapper(uint32_t max, uint32_t init); static void semphr_delete_wrapper(void *semphr); -static int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw); -static int IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw); -static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms); -static int semphr_give_wrapper(void *semphr); +static int semphr_take_from_isr_wrapper(void *semphr, void *hptw); +static int semphr_give_from_isr_wrapper(void *semphr, void *hptw); +static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms); +static int semphr_give_wrapper(void *semphr); static void *mutex_create_wrapper(void); static void mutex_delete_wrapper(void *mutex); static int mutex_lock_wrapper(void *mutex); static int mutex_unlock_wrapper(void *mutex); -static int IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, - void *hptw); -static int IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, +static int queue_send_from_isr_wrapper(void *queue, void *item, void *hptw); +static int queue_recv_from_isr_wrapper(void *queue, void *item, + void *hptw); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -static bool IRAM_ATTR is_in_isr_wrapper(void); +static bool is_in_isr_wrapper(void); static void *malloc_wrapper(size_t size); static void *malloc_internal_wrapper(size_t size); -static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6]); -static void IRAM_ATTR srand_wrapper(unsigned int seed); -static int IRAM_ATTR rand_wrapper(void); -static uint32_t IRAM_ATTR btdm_lpcycles_2_hus(uint32_t cycles, +static int read_mac_wrapper(uint8_t mac[6]); +static void srand_wrapper(unsigned int seed); +static int rand_wrapper(void); +static uint32_t btdm_lpcycles_2_hus(uint32_t cycles, uint32_t *error_corr); -static uint32_t IRAM_ATTR btdm_hus_2_lpcycles(uint32_t us); +static uint32_t btdm_hus_2_lpcycles(uint32_t us); static void coex_wifi_sleep_set_hook(bool sleep); static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status); static void coex_schm_status_bit_clear_wrapper(uint32_t type, @@ -283,7 +294,7 @@ static int queue_recv_wrapper(void *queue, void *item, static void queue_delete_wrapper(void *queue); #ifdef CONFIG_PM -static bool IRAM_ATTR btdm_sleep_check_duration(int32_t *half_slot_cnt); +static bool btdm_sleep_check_duration(int32_t *half_slot_cnt); static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles); static void btdm_sleep_enter_phase2_wrapper(void); static void btdm_sleep_exit_phase3_wrapper(void); @@ -570,6 +581,9 @@ static void interrupt_set_wrapper(int cpu_no, wlinfo("cpu_no=%d , intr_source=%d , intr_num=%d, intr_prio=%d\n", cpu_no, intr_source, intr_num, intr_prio); esp32c3_bind_irq(intr_num, intr_source, intr_prio, ESP32C3_INT_LEVEL); +#ifdef CONFIG_ESP32C3_SPIFLASH + esp32c3_spiflash_unmask_cpuint(intr_num); +#endif } /**************************************************************************** @@ -580,7 +594,7 @@ static void interrupt_set_wrapper(int cpu_no, * ****************************************************************************/ -static void interrupt_clear_wrapper(int intr_source, int intr_num) +static void IRAM_ATTR interrupt_clear_wrapper(int intr_source, int intr_num) { } @@ -598,7 +612,7 @@ static void interrupt_clear_wrapper(int intr_source, int intr_num) * ****************************************************************************/ -static int esp_int_adpt_cb(int irq, void *context, void *arg) +static int IRAM_ATTR esp_int_adpt_cb(int irq, void *context, FAR void *arg) { struct irq_adpt_s *adapter = (struct irq_adpt_s *)arg; @@ -628,10 +642,10 @@ static void interrupt_handler_set_wrapper(int n, void *fn, void *arg) int ret; struct irq_adpt_s *adapter; - if (g_ble_irq_bind) - { - return; - } + if (g_ble_irq_bind) + { + return; + } adapter = kmm_malloc(sizeof(struct irq_adpt_s)); DEBUGASSERT(adapter); @@ -700,7 +714,7 @@ static void interrupt_off_wrapper(int intr_num) static void IRAM_ATTR interrupt_disable(void) { - enter_critical_section(); + g_inter_flags = enter_critical_section(); } /**************************************************************************** @@ -737,7 +751,7 @@ static void IRAM_ATTR interrupt_restore(void) * ****************************************************************************/ -static void IRAM_ATTR task_yield_from_isr(void) +static void task_yield_from_isr(void) { } @@ -759,17 +773,21 @@ static void IRAM_ATTR task_yield_from_isr(void) static void *semphr_create_wrapper(uint32_t max, uint32_t init) { int ret; - sem_t *sem; + struct bt_sem_s *bt_sem; int tmp; - tmp = sizeof(sem_t); - sem = kmm_malloc(tmp); - DEBUGASSERT(sem); + tmp = sizeof(struct bt_sem_s); + bt_sem = kmm_malloc(tmp); + DEBUGASSERT(bt_sem); - ret = sem_init(sem, 0, init); + ret = sem_init(&bt_sem->sem, 0, init); DEBUGASSERT(ret == OK); - return sem; +#ifdef CONFIG_ESP32C3_SPIFLASH + esp32c3_wl_init_semcache(&bt_sem->sc, &bt_sem->sem); +#endif + + return bt_sem; } /**************************************************************************** @@ -788,16 +806,16 @@ static void *semphr_create_wrapper(uint32_t max, uint32_t init) static void semphr_delete_wrapper(void *semphr) { - sem_t *sem = (sem_t *)semphr; - sem_destroy(sem); - kmm_free(sem); + struct bt_sem_s *bt_sem = (struct bt_sem_s *)semphr; + sem_destroy(&bt_sem->sem); + kmm_free(bt_sem); } /**************************************************************************** * Name: semphr_take_from_isr_wrapper * * Description: - * take a semaphore from an ISR + * Take a semaphore from an ISR. * * Input Parameters: * semphr - Semaphore data pointer @@ -807,9 +825,10 @@ static void semphr_delete_wrapper(void *semphr) * ****************************************************************************/ -static int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw) +static int semphr_take_from_isr_wrapper(void *semphr, void *hptw) { - return semphr_take_wrapper(semphr, 0); + DEBUGASSERT(0); + return false; } /**************************************************************************** @@ -828,7 +847,26 @@ static int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw) static int IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw) { - return semphr_give_wrapper(semphr); + int ret; + struct bt_sem_s *bt_sem = (struct bt_sem_s *)semphr; + +#ifdef CONFIG_ESP32C3_SPIFLASH + if (spi_flash_cache_enabled()) + { + ret = semphr_give_wrapper(&bt_sem->sem); + ret = esp_errno_trans(ret); + } + else + { + esp32c3_wl_post_semcache(&bt_sem->sc); + ret = true; + } +#else + ret = semphr_give_wrapper(&bt_sem->sem); + ret = esp_errno_trans(ret); +#endif + + return ret; } /**************************************************************************** @@ -878,11 +916,11 @@ static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms) { int ret; struct timespec timeout; - sem_t *sem = (sem_t *)semphr; + struct bt_sem_s *bt_sem = (struct bt_sem_s *)semphr; if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) { - ret = sem_wait(sem); + ret = sem_wait(&bt_sem->sem); if (ret) { wlerr("Failed to wait sem\n"); @@ -890,19 +928,21 @@ static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms) } else { - ret = clock_gettime(CLOCK_REALTIME, &timeout); - if (ret < 0) - { - wlerr("Failed to get time\n"); - return false; - } - - if (block_time_ms) + if (block_time_ms > 0) { + ret = clock_gettime(CLOCK_REALTIME, &timeout); + if (ret < 0) + { + wlerr("Failed to get time\n"); + return false; + } esp_update_time(&timeout, MSEC2TICK(block_time_ms)); + ret = sem_timedwait(&bt_sem->sem, &timeout); + } + else + { + ret = sem_trywait(&bt_sem->sem); } - - ret = sem_timedwait(sem, &timeout); } return esp_errno_trans(ret); @@ -925,9 +965,9 @@ static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms) static int semphr_give_wrapper(void *semphr) { int ret; - sem_t *sem = (sem_t *)semphr; + struct bt_sem_s *bt_sem = (struct bt_sem_s *)semphr; - ret = sem_post(sem); + ret = sem_post(&bt_sem->sem); if (ret) { wlerr("Failed to post sem error=%d\n", ret); @@ -1149,11 +1189,10 @@ static int IRAM_ATTR queue_send_from_isr_wrapper(void *queue, * ****************************************************************************/ -static int IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, - void *item, - void *hptw) +static int queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw) { - return 0; + DEBUGASSERT(0); + return false; } /**************************************************************************** @@ -1287,7 +1326,7 @@ static void *malloc_internal_wrapper(size_t size) * ****************************************************************************/ -static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6]) +static int read_mac_wrapper(uint8_t mac[6]) { return 0; } @@ -1305,7 +1344,7 @@ static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6]) * ****************************************************************************/ -static void IRAM_ATTR srand_wrapper(unsigned int seed) +static void srand_wrapper(unsigned int seed) { /* empty function */ } @@ -1323,9 +1362,9 @@ static void IRAM_ATTR srand_wrapper(unsigned int seed) * ****************************************************************************/ -static int IRAM_ATTR rand_wrapper(void) +static IRAM_ATTR int rand_wrapper(void) { - return random(); + return getreg32(WDEV_RND_REG); } /**************************************************************************** @@ -2054,6 +2093,13 @@ int esp32c3_bt_controller_init(void) btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; +#ifdef CONFIG_ESP32C3_SPIFLASH + if (esp32c3_wl_init() < 0) + { + return -EIO; + } +#endif + return 0; #ifdef CONFIG_PM diff --git a/arch/risc-v/src/esp32c3/esp32c3_irq.c b/arch/risc-v/src/esp32c3/esp32c3_irq.c index 23e57c7062c..aa96948939b 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_irq.c +++ b/arch/risc-v/src/esp32c3/esp32c3_irq.c @@ -38,6 +38,7 @@ #include "riscv_internal.h" #include "hardware/esp32c3_interrupt.h" +#include "rom/esp32c3_spiflash.h" #include "esp32c3.h" #include "esp32c3_attr.h" @@ -376,7 +377,24 @@ IRAM_ATTR uint32_t *esp32c3_dispatch_irq(uint32_t mcause, uint32_t *regs) { int irq; - DEBUGASSERT(g_current_regs == NULL); + if (((MCAUSE_INTERRUPT & mcause) == 0) && + (mcause != MCAUSE_ECALL_M)) + { +#ifdef CONFIG_ESP32C3_EXCEPTION_ENABLE_CACHE + if (!spi_flash_cache_enabled()) + { + spi_flash_enable_cache(0); + _err("ERROR: Cache was disabled and re-enabled\n"); + } +#endif + } + else + { + /* Check "g_current_regs" only in interrupt or ecall */ + + DEBUGASSERT(g_current_regs == NULL); + } + g_current_regs = regs; irqinfo("INFO: mcause=%08" PRIX32 "\n", mcause); @@ -404,7 +422,7 @@ IRAM_ATTR uint32_t *esp32c3_dispatch_irq(uint32_t mcause, uint32_t *regs) /* Toggle the bit back to zero. */ - resetbits(1 << cpuint, INTERRUPT_CPU_INT_CLEAR_REG); + putreg32(0, INTERRUPT_CPU_INT_CLEAR_REG); } else { diff --git a/arch/risc-v/src/esp32c3/esp32c3_partition.c b/arch/risc-v/src/esp32c3/esp32c3_partition.c index 0e0e400cd48..56bc02e3475 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_partition.c +++ b/arch/risc-v/src/esp32c3/esp32c3_partition.c @@ -31,7 +31,7 @@ #include -#include "esp32c3_spiflash.h" +#include "esp32c3_spiflash_mtd.h" /**************************************************************************** * Pre-processor Definitions diff --git a/arch/risc-v/src/esp32c3/esp32c3_spiflash.c b/arch/risc-v/src/esp32c3/esp32c3_spiflash.c index 8003f3db10e..9cccbe02e35 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_spiflash.c +++ b/arch/risc-v/src/esp32c3/esp32c3_spiflash.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -35,13 +34,14 @@ #include #include -#include -#include -#include "esp32c3_attr.h" +#include "esp32c3.h" #include "esp32c3_spiflash.h" +#include "esp32c3_irq.h" #include "rom/esp32c3_spiflash.h" #include "hardware/esp32c3_soc.h" +#include "hardware/esp32c3_interrupt.h" +#include "hardware/extmem_reg.h" /**************************************************************************** * Pre-processor Definitions @@ -64,6 +64,11 @@ #define VADDR0_START_ADDR (0x3c020000) +/* Ibus virtual address */ + +#define IBUS_VADDR_START (0x42000000) +#define IBUS_VADDR_END (0x44000000) + /* Flash MMU table for CPU */ #define MMU_TABLE ((volatile uint32_t *)DR_REG_MMU_TABLE) @@ -73,33 +78,10 @@ #define MMU_BYTES2PAGES(_n) (((_n) + SPI_FLASH_MMU_PAGE_SIZE - 1) / \ SPI_FLASH_MMU_PAGE_SIZE) -#define SPI_FLASH_BLK_SIZE 256 -#define SPI_FLASH_ERASE_SIZE 4096 -#define SPI_FLASH_ERASED_STATE (0xff) -#define SPI_FLASH_SIZE (4 * 1024 * 1024) - -#define MTD2PRIV(_dev) ((struct esp32c3_spiflash_s *)_dev) -#define MTD_SIZE(_priv) ((*(_priv)->data)->chip.chip_size) -#define MTD_BLKSIZE(_priv) ((*(_priv)->data)->chip.page_size) -#define MTD_ERASESIZE(_priv) ((*(_priv)->data)->chip.sector_size) -#define MTD_BLK2SIZE(_priv, _b) (MTD_BLKSIZE(_priv) * (_b)) -#define MTD_SIZE2BLK(_priv, _s) ((_s) / MTD_BLKSIZE(_priv)) - /**************************************************************************** * Private Types ****************************************************************************/ -/* ESP32-C3 SPI Flash device private data */ - -struct esp32c3_spiflash_s -{ - struct mtd_dev_s mtd; - - /* SPI Flash data */ - - const struct spiflash_legacy_data_s **data; -}; - /* SPI Flash map request data */ struct spiflash_map_req_s @@ -125,42 +107,12 @@ struct spiflash_map_req_s uint32_t page_cnt; }; -struct spiflash_cachestate_s -{ - irqstate_t flags; - uint32_t val; -}; - /**************************************************************************** - * Private Functions Prototypes + * Private Functions Declaration ****************************************************************************/ -/* MTD driver methods */ - -static int esp32c3_erase(struct mtd_dev_s *dev, off_t startblock, - size_t nblocks); -static ssize_t esp32c3_read(struct mtd_dev_s *dev, off_t offset, - size_t nbytes, uint8_t *buffer); -static ssize_t esp32c3_read_decrypt(struct mtd_dev_s *dev, - off_t offset, - size_t nbytes, - uint8_t *buffer); -static ssize_t esp32c3_bread(struct mtd_dev_s *dev, off_t startblock, - size_t nblocks, uint8_t *buffer); -static ssize_t esp32c3_bread_decrypt(struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks, - uint8_t *buffer); -static ssize_t esp32c3_write(struct mtd_dev_s *dev, off_t offset, - size_t nbytes, const uint8_t *buffer); -static ssize_t esp32c3_bwrite(struct mtd_dev_s *dev, off_t startblock, - size_t nblocks, const uint8_t *buffer); -static ssize_t esp32c3_bwrite_encrypt(struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks, - const uint8_t *buffer); -static int esp32c3_ioctl(struct mtd_dev_s *dev, int cmd, - unsigned long arg); +static void spiflash_start(void); +static void spiflash_end(void); /**************************************************************************** * Public Functions Declaration @@ -170,57 +122,43 @@ extern int cache_invalidate_addr(uint32_t addr, uint32_t size); extern uint32_t cache_suspend_icache(void); extern void cache_resume_icache(uint32_t val); -/**************************************************************************** - * Public Data - ****************************************************************************/ - -extern const struct spiflash_legacy_data_s *rom_spiflash_legacy_data; - /**************************************************************************** * Private Data ****************************************************************************/ -static struct esp32c3_spiflash_s g_esp32c3_spiflash = +static struct spiflash_guard_funcs g_spi_flash_guard_funcs = { - .mtd = - { - .erase = esp32c3_erase, - .bread = esp32c3_bread, - .bwrite = esp32c3_bwrite, - .read = esp32c3_read, - .ioctl = esp32c3_ioctl, -#ifdef CONFIG_MTD_BYTE_WRITE - .write = esp32c3_write, -#endif - .name = "esp32c3_spiflash" - }, - .data = &rom_spiflash_legacy_data, + .start = spiflash_start, + .end = spiflash_end, + .op_lock = NULL, + .op_unlock = NULL, + .address_is_safe = NULL, + .yield = NULL, }; -static struct esp32c3_spiflash_s g_esp32c3_spiflash_encrypt = -{ - .mtd = - { - .erase = esp32c3_erase, - .bread = esp32c3_bread_decrypt, - .bwrite = esp32c3_bwrite_encrypt, - .read = esp32c3_read_decrypt, - .ioctl = esp32c3_ioctl, -#ifdef CONFIG_MTD_BYTE_WRITE - .write = NULL, -#endif - .name = "esp32c3_spiflash_encrypt" - } -}; - -/* Ensure exclusive access to the driver */ - -static sem_t g_exclsem = SEM_INITIALIZER(1); +static uint32_t g_icache_value; +static uint32_t g_int_regval; +static uint32_t g_int_unmask; /**************************************************************************** * Private Functions ****************************************************************************/ +static IRAM_ATTR void disable_mask_int(void) +{ + uint32_t regval; + + g_int_regval = getreg32(INTERRUPT_CPU_INT_ENABLE_REG); + regval = g_int_regval & g_int_unmask; + + putreg32(regval, INTERRUPT_CPU_INT_ENABLE_REG); +} + +static IRAM_ATTR void enable_mask_int(void) +{ + putreg32(g_int_regval, INTERRUPT_CPU_INT_ENABLE_REG); +} + /**************************************************************************** * Name: spiflash_opstart * @@ -229,10 +167,17 @@ static sem_t g_exclsem = SEM_INITIALIZER(1); * ****************************************************************************/ -static inline void spiflash_opstart(struct spiflash_cachestate_s *state) +static IRAM_ATTR void spiflash_start(void) { - state->flags = enter_critical_section(); - state->val = cache_suspend_icache() << 16; + irqstate_t flags; + + flags = enter_critical_section(); + + disable_mask_int(); + + g_icache_value = cache_suspend_icache() << 16; + + leave_critical_section(flags); } /**************************************************************************** @@ -243,10 +188,17 @@ static inline void spiflash_opstart(struct spiflash_cachestate_s *state) * ****************************************************************************/ -static inline void spiflash_opdone(const struct spiflash_cachestate_s *state) +static IRAM_ATTR void spiflash_end(void) { - cache_resume_icache(state->val >> 16); - leave_critical_section(state->flags); + irqstate_t flags; + + flags = enter_critical_section(); + + cache_resume_icache(g_icache_value >> 16); + + enable_mask_int(); + + leave_critical_section(flags); } /**************************************************************************** @@ -267,7 +219,7 @@ static inline void spiflash_opdone(const struct spiflash_cachestate_s *state) * ****************************************************************************/ -static int IRAM_ATTR esp32c3_mmap(struct spiflash_map_req_s *req) +static IRAM_ATTR int esp32c3_mmap(struct spiflash_map_req_s *req) { int ret; int i; @@ -275,9 +227,8 @@ static int IRAM_ATTR esp32c3_mmap(struct spiflash_map_req_s *req) int flash_page; int page_cnt; uint32_t mapped_addr; - struct spiflash_cachestate_s state; - spiflash_opstart(&state); + spiflash_start(); for (start_page = DROM0_PAGES_START; start_page < DROM0_PAGES_END; @@ -315,7 +266,7 @@ static int IRAM_ATTR esp32c3_mmap(struct spiflash_map_req_s *req) ret = -ENOBUFS; } - spiflash_opdone(&state); + spiflash_end(); return ret; } @@ -334,23 +285,22 @@ static int IRAM_ATTR esp32c3_mmap(struct spiflash_map_req_s *req) * ****************************************************************************/ -static void IRAM_ATTR esp32c3_ummap(const struct spiflash_map_req_s *req) +static IRAM_ATTR void esp32c3_ummap(const struct spiflash_map_req_s *req) { int i; - struct spiflash_cachestate_s state; - spiflash_opstart(&state); + spiflash_start(); for (i = req->start_page; i < req->start_page + req->page_cnt; ++i) { MMU_TABLE[i] = INVALID_MMU_VAL; } - spiflash_opdone(&state); + spiflash_end(); } /**************************************************************************** - * Name: esp32c3_readdata_encrypted + * Name: spi_flash_read_encrypted * * Description: * Read decrypted data from SPI Flash at designated address when @@ -366,9 +316,7 @@ static void IRAM_ATTR esp32c3_ummap(const struct spiflash_map_req_s *req) * ****************************************************************************/ -static IRAM_ATTR int esp32c3_readdata_encrypted(uint32_t addr, - uint8_t *buffer, - uint32_t size) +int spi_flash_read_encrypted(uint32_t addr, void *buffer, uint32_t size) { int ret; struct spiflash_map_req_s req = @@ -391,623 +339,91 @@ static IRAM_ATTR int esp32c3_readdata_encrypted(uint32_t addr, } /**************************************************************************** - * Name: esp32c3_erase + * Name: esp32c3_icache2phys * * Description: - * Erase SPI Flash designated sectors. + * Get Absolute address in SPI Flash by input function pointer. * * Input Parameters: - * dev - MTD device data - * startblock - start block number, it is not equal to SPI Flash's block - * nblocks - Number of blocks + * func - Function pointer * * Returned Value: - * Erased blocks if success or a negative value if fail. + * Absolute address if success or negtive value if failed. * ****************************************************************************/ -static int esp32c3_erase(struct mtd_dev_s *dev, off_t startblock, - size_t nblocks) +int32_t esp32c3_icache2phys(const void *func) { - ssize_t ret; - uint32_t offset = startblock * SPI_FLASH_ERASE_SIZE; - uint32_t nbytes = nblocks * SPI_FLASH_ERASE_SIZE; + intptr_t pages; + intptr_t off; + intptr_t c = (intptr_t)func; - if ((offset > SPI_FLASH_SIZE) || ((offset + nbytes) > SPI_FLASH_SIZE)) - { - return -EINVAL; - } + off = (c - IBUS_VADDR_START) % SPI_FLASH_MMU_PAGE_SIZE; + pages = (c - IBUS_VADDR_START) / SPI_FLASH_MMU_PAGE_SIZE; -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("(%p, %d, %d)\n", dev, startblock, nblocks); -#endif + pages += MMU_TABLE[pages]; - ret = nxsem_wait(&g_exclsem); - if (ret < 0) - { - return ret; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("spi_flash_erase_range(%p, 0x%x, %d)\n", dev, offset, nbytes); -#endif - - ret = spi_flash_erase_range(offset, nbytes); - - nxsem_post(&g_exclsem); - - if (ret == OK) - { - ret = nblocks; - } - else - { -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("Failed to erase the flash range!\n"); -#endif - ret = -1; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s()=%d\n", __func__, ret); -#endif - - return ret; + return pages * SPI_FLASH_MMU_PAGE_SIZE + off; } /**************************************************************************** - * Name: esp32c3_read + * Name: esp32c3_spiflash_unmask_cpuint * * Description: - * Read data from SPI Flash at designated address. + * Unmask CPU interrupt and keep this interrupt work when read, write, + * erase SPI Flash. + * + * By default, all CPU interrupts are masked. * * Input Parameters: - * dev - MTD device data - * offset - target address offset - * nbytes - data number - * buffer - data buffer pointer + * cpuint - CPU interrupt ID * * Returned Value: - * Read data bytes if success or a negative value if fail. + * None. * ****************************************************************************/ -static ssize_t esp32c3_read(struct mtd_dev_s *dev, off_t offset, - size_t nbytes, uint8_t *buffer) +void esp32c3_spiflash_unmask_cpuint(int cpuint) { - ssize_t ret; - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer); -#endif - - /* Acquire the semaphore. */ - - ret = nxsem_wait(&g_exclsem); - if (ret < 0) - { - goto error_with_buffer; - } - - ret = spi_flash_read(offset, buffer, nbytes); - - nxsem_post(&g_exclsem); - - if (ret == OK) - { - ret = nbytes; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s()=%d\n", __func__, ret); -#endif - -error_with_buffer: - - return ret; + g_int_unmask |= 1 << cpuint; } /**************************************************************************** - * Name: esp32c3_bread + * Name: esp32c3_spiflash_unmask_cpuint * * Description: - * Read data from designated blocks. + * Mask CPU interrupt and disable this interrupt when read, write, + * erase SPI Flash. + * + * By default, all CPU interrupts are masked. * * 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 + * cpuint - CPU interrupt ID * * Returned Value: - * Read block number if success or a negative value if fail. + * None. * ****************************************************************************/ -static ssize_t esp32c3_bread(struct mtd_dev_s *dev, off_t startblock, - size_t nblocks, uint8_t *buffer) +void esp32c3_spiflash_mask_cpuint(int cpuint) { - ssize_t ret; - uint32_t addr = startblock * SPI_FLASH_BLK_SIZE; - uint32_t size = nblocks * SPI_FLASH_BLK_SIZE; - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, nblocks, - buffer); -#endif - - ret = nxsem_wait(&g_exclsem); - if (ret < 0) - { - return ret; - } - - ret = spi_flash_read(addr, buffer, size); - - nxsem_post(&g_exclsem); - - if (ret == OK) - { - ret = nblocks; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s()=%d\n", __func__, ret); -#endif - - return ret; + g_int_unmask &= ~(1 << cpuint); } /**************************************************************************** - * Name: esp32c3_read_decrypt + * Name: esp32c3_spiflash_init * * Description: - * Read encrypted data and decrypt automatically from SPI Flash - * at designated address. - * - * Input Parameters: - * dev - MTD device data - * offset - target address offset - * nbytes - data number - * buffer - data buffer pointer + * Initialize ESP32-C3 SPI flash driver. * * Returned Value: - * Read data bytes if success or a negative value if fail. + * OK if success or a negative value if fail. * ****************************************************************************/ -static ssize_t esp32c3_read_decrypt(struct mtd_dev_s *dev, - off_t offset, - size_t nbytes, - uint8_t *buffer) +int esp32c3_spiflash_init(void) { - ssize_t ret; + spi_flash_guard_set(&g_spi_flash_guard_funcs); -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer); -#endif - - /* Acquire the semaphore. */ - - ret = nxsem_wait(&g_exclsem); - if (ret < 0) - { - return ret; - } - - ret = esp32c3_readdata_encrypted(offset, buffer, nbytes); - - nxsem_post(&g_exclsem); - - if (ret == OK) - { - ret = nbytes; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s()=%d\n", __func__, ret); -#endif - - return ret; -} - -/**************************************************************************** - * Name: esp32c3_bread_decrypt - * - * Description: - * Read encrypted data and decrypt automatically 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 esp32c3_bread_decrypt(struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks, - uint8_t *buffer) -{ - ssize_t ret; - uint32_t addr = startblock * SPI_FLASH_BLK_SIZE; - uint32_t size = nblocks * SPI_FLASH_BLK_SIZE; - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, nblocks, - buffer); -#endif - - ret = nxsem_wait(&g_exclsem); - if (ret < 0) - { - return ret; - } - - ret = esp32c3_readdata_encrypted(addr, buffer, size); - - nxsem_post(&g_exclsem); - - if (ret == OK) - { - ret = nblocks; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s()=%d\n", __func__, ret); -#endif - - return ret; -} - -/**************************************************************************** - * Name: esp32c3_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 esp32c3_write(struct mtd_dev_s *dev, off_t offset, - size_t nbytes, const uint8_t *buffer) -{ - int ret; - - ASSERT(buffer); - - if ((offset > SPI_FLASH_SIZE) || ((offset + nbytes) > SPI_FLASH_SIZE)) - { - return -EINVAL; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer); -#endif - - /* Acquire the semaphore. */ - - ret = nxsem_wait(&g_exclsem); - if (ret < 0) - { - goto error_with_buffer; - } - - ret = spi_flash_write(offset, buffer, nbytes); - - nxsem_post(&g_exclsem); - - if (ret == OK) - { - ret = nbytes; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s()=%d\n", __func__, ret); -#endif - -error_with_buffer: - - return (ssize_t)ret; -} - -/**************************************************************************** - * Name: esp32c3_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 esp32c3_bwrite(struct mtd_dev_s *dev, off_t startblock, - size_t nblocks, const uint8_t *buffer) -{ - ssize_t ret; - uint32_t addr = startblock * SPI_FLASH_BLK_SIZE; - uint32_t size = nblocks * SPI_FLASH_BLK_SIZE; - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, - nblocks, buffer); -#endif - - ret = nxsem_wait(&g_exclsem); - if (ret < 0) - { - return ret; - } - - ret = spi_flash_write(addr, buffer, size); - - nxsem_post(&g_exclsem); - - if (ret == OK) - { - ret = nblocks; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s()=%d\n", __func__, ret); -#endif - - return ret; -} - -/**************************************************************************** - * Name: esp32c3_bwrite_encrypt - * - * Description: - * Write data to designated blocks by SPI Flash hardware encryption. - * - * 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 esp32c3_bwrite_encrypt(struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks, - const uint8_t *buffer) -{ - ssize_t ret; - uint32_t addr = startblock * SPI_FLASH_BLK_SIZE; - uint32_t size = nblocks * SPI_FLASH_BLK_SIZE; - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, - nblocks, buffer); -#endif - - ret = nxsem_wait(&g_exclsem); - if (ret < 0) - { - goto error_with_buffer; - } - - ret = spi_flash_write_encrypted(addr, buffer, size); - - nxsem_post(&g_exclsem); - - if (ret == OK) - { - ret = nblocks; - } - -#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG - finfo("%s()=%d\n", __func__, ret); -#endif - -error_with_buffer: - - return ret; -} - -/**************************************************************************** - * Name: esp32c3_ioctl - * - * Description: - * Set/Get option to/from ESP32-C3 SPI Flash MTD device data. - * - * Input Parameters: - * dev - ESP32-C3 MTD device data - * cmd - operation command - * arg - operation argument - * - * Returned Value: - * 0 if success or a negative value if fail. - * - ****************************************************************************/ - -static int esp32c3_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 mtd_geometry_s *geo = (struct mtd_geometry_s *)arg; - if (geo) - { - geo->blocksize = SPI_FLASH_BLK_SIZE; - geo->erasesize = SPI_FLASH_ERASE_SIZE; - geo->neraseblocks = SPI_FLASH_SIZE / SPI_FLASH_ERASE_SIZE; - ret = OK; - - finfo("blocksize: %" PRId32 " erasesize: %" PRId32 \ - " neraseblocks: %" PRId32 "\n", - geo->blocksize, geo->erasesize, geo->neraseblocks); - } - } - break; - - case BIOC_PARTINFO: - { - struct partition_info_s *info = (struct partition_info_s *)arg; - if (info != NULL) - { - info->numsectors = SPI_FLASH_SIZE / SPI_FLASH_BLK_SIZE; - info->sectorsize = SPI_FLASH_BLK_SIZE; - info->startsector = 0; - info->parent[0] = '\0'; - } - } - break; - - case MTDIOC_ERASESTATE: - { - uint8_t *result = (uint8_t *)arg; - *result = SPI_FLASH_ERASED_STATE; - - ret = OK; - } - break; - - default: - ret = -ENOTTY; - break; - } - - finfo("return %d\n", ret); - return ret; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: esp32c3_spiflash_alloc_mtdpart - * - * Description: - * Allocate an MTD partition from the ESP32-C3 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 *esp32c3_spiflash_alloc_mtdpart(uint32_t mtd_offset, - uint32_t mtd_size) -{ - struct esp32c3_spiflash_s *priv = &g_esp32c3_spiflash; - const esp32c3_spiflash_chip_t *chip = &(*priv->data)->chip; - struct mtd_dev_s *mtd_part; - uint32_t blocks; - uint32_t startblock; - uint32_t size; - - ASSERT((mtd_offset + mtd_size) <= chip->chip_size); - ASSERT((mtd_offset % chip->sector_size) == 0); - ASSERT((mtd_size % chip->sector_size) == 0); - - finfo("ESP32-C3 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); - - 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(&priv->mtd, startblock, blocks); - if (!mtd_part) - { - ferr("ERROR: Failed to create MTD partition\n"); - return NULL; - } - - return mtd_part; -} - -/**************************************************************************** - * Name: esp32c3_spiflash_mtd - * - * Description: - * Get SPI Flash MTD. - * - * Input Parameters: - * None - * - * Returned Value: - * ESP32-C3 SPI Flash MTD pointer. - * - ****************************************************************************/ - -struct mtd_dev_s *esp32c3_spiflash_mtd(void) -{ - struct esp32c3_spiflash_s *priv = &g_esp32c3_spiflash; - - return &priv->mtd; -} - -/**************************************************************************** - * Name: esp32c3_spiflash_encrypt_mtd - * - * Description: - * Get SPI Flash encryption MTD. - * - * Input Parameters: - * None - * - * Returned Value: - * SPI Flash encryption MTD pointer. - * - ****************************************************************************/ - -struct mtd_dev_s *esp32c3_spiflash_encrypt_mtd(void) -{ - struct esp32c3_spiflash_s *priv = &g_esp32c3_spiflash_encrypt; - - return &priv->mtd; + return OK; } diff --git a/arch/risc-v/src/esp32c3/esp32c3_spiflash.h b/arch/risc-v/src/esp32c3/esp32c3_spiflash.h index 76c7812f80f..85125b8c14d 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_spiflash.h +++ b/arch/risc-v/src/esp32c3/esp32c3_spiflash.h @@ -46,114 +46,6 @@ extern "C" * Public Function Prototypes ****************************************************************************/ -/**************************************************************************** - * Name: esp32c3_spiflash_mtd - * - * Description: - * Get ESP32-C3 SPI Flash MTD. - * - * Input Parameters: - * None - * - * Returned Value: - * ESP32-C3 SPI Flash MTD pointer. - * - ****************************************************************************/ - -struct mtd_dev_s *esp32c3_spiflash_mtd(void); - -/**************************************************************************** - * Name: esp32c3_spiflash_alloc_mtdpart - * - * Description: - * Allocate an MTD partition from the ESP32-C3 SPI Flash. - * - * Input Parameters: - * mtd_offset - MTD Partition offset from the base address in SPI Flash. - * mtd_size - Size for the MTD partition. - * - * Returned Value: - * ESP32-C3 SPI Flash MTD data pointer if success or NULL if fail - * - ****************************************************************************/ - -struct mtd_dev_s *esp32c3_spiflash_alloc_mtdpart(uint32_t mtd_offset, - uint32_t mtd_size); - -/**************************************************************************** - * Name: esp32c3_spiflash_encrypt_mtd - * - * Description: - * Get ESP32-C3 SPI Flash encryption MTD. - * - * Input Parameters: - * None - * - * Returned Value: - * ESP32-C3 SPI Flash encryption MTD pointer. - * - ****************************************************************************/ - -struct mtd_dev_s *esp32c3_spiflash_encrypt_mtd(void); - -/**************************************************************************** - * Name: spi_flash_write_encrypted - * - * Description: - * Write data encrypted to Flash. - * - * Flash encryption must be enabled for this function to work. - * - * Flash encryption must be enabled when calling this function. - * If flash encryption is disabled, the function returns - * ESP_ERR_INVALID_STATE. Use esp_flash_encryption_enabled() - * function to determine if flash encryption is enabled. - * - * Both dest_addr and size must be multiples of 16 bytes. For - * absolute best performance, both dest_addr and size arguments should - * be multiples of 32 bytes. - * - * Input Parameters: - * dest_addr - Destination address in Flash. Must be a multiple of 16 - * bytes. - * src - Pointer to the source buffer. - * size - Length of data, in bytes. Must be a multiple of 16 bytes. - * - * Returned Values: - * Zero (OK) is returned or a negative error. - * - ****************************************************************************/ - -int spi_flash_write_encrypted(uint32_t dest_addr, const void *src, - uint32_t size); - -/**************************************************************************** - * Name: spi_flash_write - * - * Description: - * - * Write data to Flash. - * - * Note: For fastest write performance, write a 4 byte aligned size at a - * 4 byte aligned offset in flash from a source buffer in DRAM. Varying - * any of these parameters will still work, but will be slower due to - * buffering. - * - * Writing more than 8KB at a time will be split into multiple - * write operations to avoid disrupting other tasks in the system. - * - * Parameters: - * dest_addr - Destination address in Flash. - * src - Pointer to the source buffer. - * size - Length of data, in bytes. - * - * Returned Values: - * Zero (OK) is returned or a negative error. - * - ****************************************************************************/ - -int spi_flash_write(uint32_t dest_addr, const void *src, uint32_t size); - /**************************************************************************** * Name: spi_flash_read_encrypted * @@ -170,79 +62,66 @@ int spi_flash_write(uint32_t dest_addr, const void *src, uint32_t size); * encryption is enabled. * * Parameters: - * src - source address of the data in Flash. - * dest - pointer to the destination buffer - * size - length of data + * addr - source address of the data in Flash. + * buffer - pointer to the destination buffer + * size - length of data * * Returned Values: esp_err_t * ****************************************************************************/ -int spi_flash_read_encrypted(uint32_t src, void *dest, uint32_t size); +int spi_flash_read_encrypted(uint32_t addr, void *buffer, uint32_t size); /**************************************************************************** - * Name: spi_flash_read + * Name: esp32c3_spiflash_unmask_cpuint * * Description: - * Read data from Flash. + * Unmask CPU interrupt and keep this interrupt work when read, write, + * erase SPI Flash. * - * Note: For fastest read performance, all parameters should be - * 4 byte aligned. If source address and read size are not 4 byte - * aligned, read may be split into multiple flash operations. If - * destination buffer is not 4 byte aligned, a temporary buffer will - * be allocated on the stack. + * By default, all CPU interrupts are masked. * - * Reading more than 16KB of data at a time will be split - * into multiple reads to avoid disruption to other tasks in the - * system. Consider using spi_flash_mmap() to read large amounts - * of data. + * Input Parameters: + * cpuint - CPU interrupt ID * - * Parameters: - * src_addr - source address of the data in Flash. - * dest - pointer to the destination buffer - * size - length of data - * - * Returned Values: - * Zero (OK) is returned or a negative error. + * Returned Value: + * None. * ****************************************************************************/ -int spi_flash_read(uint32_t src_addr, void *dest, uint32_t size); +void esp32c3_spiflash_unmask_cpuint(int cpuint); /**************************************************************************** - * Name: spi_flash_erase_sector + * Name: esp32c3_spiflash_unmask_cpuint * * Description: - * Erase the Flash sector. + * Mask CPU interrupt and disable this interrupt when read, write, + * erase SPI Flash. * - * Parameters: - * sector - Sector number, the count starts at sector 0, 4KB per sector. + * By default, all CPU interrupts are masked. * - * Returned Values: esp_err_t - * Zero (OK) is returned or a negative error. + * Input Parameters: + * cpuint - CPU interrupt ID + * + * Returned Value: + * None. * ****************************************************************************/ -int spi_flash_erase_sector(uint32_t sector); +void esp32c3_spiflash_mask_cpuint(int cpuint); /**************************************************************************** - * Name: spi_flash_erase_range + * Name: esp32c3_spiflash_init * * Description: - * Erase a range of flash sectors + * Initialize ESP32-C3 SPI flash driver. * - * 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. + * Returned Value: + * OK if success or a negative value if fail. * ****************************************************************************/ -int spi_flash_erase_range(uint32_t start_address, uint32_t size); +int esp32c3_spiflash_init(void); #ifdef __cplusplus } diff --git a/arch/risc-v/src/esp32c3/esp32c3_spiflash_mtd.c b/arch/risc-v/src/esp32c3/esp32c3_spiflash_mtd.c new file mode 100644 index 00000000000..a031ee97be5 --- /dev/null +++ b/arch/risc-v/src/esp32c3/esp32c3_spiflash_mtd.c @@ -0,0 +1,795 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp32c3_spiflash_mtd.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "esp32c3_attr.h" +#include "esp32c3_spiflash.h" +#include "rom/esp32c3_spiflash.h" +#include "hardware/esp32c3_soc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MTD_BLK_SIZE CONFIG_ESP32C3_STORAGE_MTD_BLKSIZE +#define MTD_ERASE_SIZE 4096 +#define MTD_ERASED_STATE (0xff) + +#define MTD_PART_OFFSET CONFIG_ESP32C3_STORAGE_MTD_OFFSET +#define MTD_PART_SIZE CONFIG_ESP32C3_STORAGE_MTD_SIZE + +#define MTD2PRIV(_dev) ((struct esp32c3_mtd_dev_s *)_dev) +#define MTD_SIZE(_priv) ((*(_priv)->data)->chip.chip_size) +#define MTD_BLK2SIZE(_priv, _b) (MTD_BLK_SIZE * (_b)) +#define MTD_SIZE2BLK(_priv, _s) ((_s) / MTD_BLK_SIZE) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* ESP32-C3 SPI Flash device private data */ + +struct esp32c3_mtd_dev_s +{ + struct mtd_dev_s mtd; + + /* SPI Flash data */ + + const struct spiflash_legacy_data_s **data; +}; + +/**************************************************************************** + * Private Functions Prototypes + ****************************************************************************/ + +/* MTD driver methods */ + +static int esp32c3_erase(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks); +static ssize_t esp32c3_read(struct mtd_dev_s *dev, off_t offset, + size_t nbytes, uint8_t *buffer); +static ssize_t esp32c3_read_decrypt(struct mtd_dev_s *dev, + off_t offset, + size_t nbytes, + uint8_t *buffer); +static ssize_t esp32c3_bread(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, uint8_t *buffer); +static ssize_t esp32c3_bread_decrypt(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + uint8_t *buffer); +static ssize_t esp32c3_write(struct mtd_dev_s *dev, off_t offset, + size_t nbytes, const uint8_t *buffer); +static ssize_t esp32c3_bwrite(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, const uint8_t *buffer); +static ssize_t esp32c3_bwrite_encrypt(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + const uint8_t *buffer); +static int esp32c3_ioctl(struct mtd_dev_s *dev, int cmd, + unsigned long arg); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct spiflash_legacy_data_s *rom_spiflash_legacy_data; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct esp32c3_mtd_dev_s g_esp32c3_spiflash = +{ + .mtd = + { + .erase = esp32c3_erase, + .bread = esp32c3_bread, + .bwrite = esp32c3_bwrite, + .read = esp32c3_read, + .ioctl = esp32c3_ioctl, +#ifdef CONFIG_MTD_BYTE_WRITE + .write = esp32c3_write, +#endif + .name = "esp32c3_spiflash" + }, + .data = &rom_spiflash_legacy_data, +}; + +static const struct esp32c3_mtd_dev_s g_esp32c3_spiflash_encrypt = +{ + .mtd = + { + .erase = esp32c3_erase, + .bread = esp32c3_bread_decrypt, + .bwrite = esp32c3_bwrite_encrypt, + .read = esp32c3_read_decrypt, + .ioctl = esp32c3_ioctl, +#ifdef CONFIG_MTD_BYTE_WRITE + .write = NULL, +#endif + .name = "esp32c3_spiflash_encrypt" + } +}; + +/* Ensure exclusive access to the driver */ + +static sem_t g_exclsem = SEM_INITIALIZER(1); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32c3_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 esp32c3_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 esp32c3_mtd_dev_s *priv = (struct esp32c3_mtd_dev_s *)dev; + + if ((offset > MTD_SIZE(priv)) || ((offset + nbytes) > MTD_SIZE(priv))) + { + return -EINVAL; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d)\n", __func__, dev, startblock, nblocks); + + finfo("spi_flash_erase_range(0x%x, %d)\n", offset, nbytes); +#endif + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + return ret; + } + + ret = spi_flash_erase_range(offset, nbytes); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nblocks; + } + else + { +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("Failed to erase the flash range!\n"); +#endif + ret = -1; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + + return ret; +} + +/**************************************************************************** + * Name: esp32c3_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 esp32c3_read(struct mtd_dev_s *dev, off_t offset, + size_t nbytes, uint8_t *buffer) +{ + ssize_t ret; + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer); + + finfo("spi_flash_read(0x%x, %p, %d)\n", offset, buffer, nbytes); +#endif + + /* Acquire the semaphore. */ + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + goto error_with_buffer; + } + + ret = spi_flash_read(offset, buffer, nbytes); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nbytes; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + +error_with_buffer: + + return ret; +} + +/**************************************************************************** + * Name: esp32c3_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 esp32c3_bread(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, uint8_t *buffer) +{ + ssize_t ret; + uint32_t addr = startblock * MTD_BLK_SIZE; + uint32_t size = nblocks * MTD_BLK_SIZE; + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, nblocks, + buffer); + + finfo("spi_flash_read(0x%x, %p, %d)\n", addr, buffer, size); +#endif + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + return ret; + } + + ret = spi_flash_read(addr, buffer, size); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nblocks; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + + return ret; +} + +/**************************************************************************** + * Name: esp32c3_read_decrypt + * + * Description: + * Read encrypted data and decrypt automatically 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 esp32c3_read_decrypt(struct mtd_dev_s *dev, + off_t offset, + size_t nbytes, + uint8_t *buffer) +{ + ssize_t ret; + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer); + + finfo("spi_flash_read_encrypted(0x%x, %p, %d)\n", offset, buffer, + nbytes); +#endif + + /* Acquire the semaphore. */ + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + return ret; + } + + ret = spi_flash_read_encrypted(offset, buffer, nbytes); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nbytes; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + + return ret; +} + +/**************************************************************************** + * Name: esp32c3_bread_decrypt + * + * Description: + * Read encrypted data and decrypt automatically 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 esp32c3_bread_decrypt(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + uint8_t *buffer) +{ + ssize_t ret; + uint32_t addr = startblock * MTD_BLK_SIZE; + uint32_t size = nblocks * MTD_BLK_SIZE; + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, nblocks, + buffer); + + finfo("spi_flash_read_encrypted(0x%x, %p, %d)\n", addr, buffer, size); +#endif + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + return ret; + } + + ret = spi_flash_read_encrypted(addr, buffer, size); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nblocks; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + + return ret; +} + +/**************************************************************************** + * Name: esp32c3_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 esp32c3_write(struct mtd_dev_s *dev, off_t offset, + size_t nbytes, const uint8_t *buffer) +{ + int ret; + struct esp32c3_mtd_dev_s *priv = (struct esp32c3_mtd_dev_s *)dev; + + ASSERT(buffer); + + if ((offset > MTD_SIZE(priv)) || ((offset + nbytes) > MTD_SIZE(priv))) + { + return -EINVAL; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer); + + finfo("spi_flash_write(0x%x, %p, %d)\n", offset, buffer, nbytes); +#endif + + /* Acquire the semaphore. */ + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + goto error_with_buffer; + } + + ret = spi_flash_write(offset, buffer, nbytes); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nbytes; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + +error_with_buffer: + + return (ssize_t)ret; +} + +/**************************************************************************** + * Name: esp32c3_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 esp32c3_bwrite(struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, const uint8_t *buffer) +{ + ssize_t ret; + uint32_t addr = startblock * MTD_BLK_SIZE; + uint32_t size = nblocks * MTD_BLK_SIZE; + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, + nblocks, buffer); + + finfo("spi_flash_write(0x%x, %p, %d)\n", addr, buffer, size); +#endif + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + return ret; + } + + ret = spi_flash_write(addr, buffer, size); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nblocks; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + + return ret; +} + +/**************************************************************************** + * Name: esp32c3_bwrite_encrypt + * + * Description: + * Write data to designated blocks by SPI Flash hardware encryption. + * + * 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 esp32c3_bwrite_encrypt(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + const uint8_t *buffer) +{ + ssize_t ret; + uint32_t addr = startblock * MTD_BLK_SIZE; + uint32_t size = nblocks * MTD_BLK_SIZE; + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, + nblocks, buffer); + + finfo("spi_flash_write_encrypted(0x%x, %p, %d)\n", addr, buffer, size); +#endif + + ret = nxsem_wait(&g_exclsem); + if (ret < 0) + { + goto error_with_buffer; + } + + ret = spi_flash_write_encrypted(addr, buffer, size); + + nxsem_post(&g_exclsem); + + if (ret == OK) + { + ret = nblocks; + } + +#ifdef CONFIG_ESP32C3_STORAGE_MTD_DEBUG + finfo("%s()=%d\n", __func__, ret); +#endif + +error_with_buffer: + + return ret; +} + +/**************************************************************************** + * Name: esp32c3_ioctl + * + * Description: + * Set/Get option to/from ESP32-C3 SPI Flash MTD device data. + * + * Input Parameters: + * dev - ESP32-C3 MTD device data + * cmd - operation command + * arg - operation argument + * + * Returned Value: + * 0 if success or a negative value if fail. + * + ****************************************************************************/ + +static int esp32c3_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 mtd_geometry_s *geo = (struct mtd_geometry_s *)arg; + if (geo) + { + geo->blocksize = MTD_BLK_SIZE; + geo->erasesize = MTD_ERASE_SIZE; + geo->neraseblocks = MTD_PART_SIZE / MTD_ERASE_SIZE; + ret = OK; + + finfo("blocksize: %" PRId32 " erasesize: %" PRId32 \ + " neraseblocks: %" PRId32 "\n", + geo->blocksize, geo->erasesize, geo->neraseblocks); + } + } + break; + + case BIOC_PARTINFO: + { + struct partition_info_s *info = (struct partition_info_s *)arg; + if (info != NULL) + { + info->numsectors = MTD_PART_SIZE / 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: esp32c3_spiflash_alloc_mtdpart + * + * Description: + * Allocate SPI Flash MTD. + * + * Input Parameters: + * None + * + * Returned Value: + * SPI Flash MTD data pointer if success or NULL if fail. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32c3_spiflash_alloc_mtdpart(uint32_t mtd_offset, + uint32_t mtd_size) +{ + struct esp32c3_mtd_dev_s *priv = + (struct esp32c3_mtd_dev_s *)&g_esp32c3_spiflash; + const esp32c3_spiflash_chip_t *chip = &(*priv->data)->chip; + struct mtd_dev_s *mtd_part; + uint32_t blocks; + uint32_t startblock; + uint32_t size; + + ASSERT((mtd_offset + mtd_size) <= chip->chip_size); + ASSERT((mtd_offset % chip->sector_size) == 0); + ASSERT((mtd_size % chip->sector_size) == 0); + + finfo("ESP32-C3 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); + + 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(&priv->mtd, startblock, blocks); + if (!mtd_part) + { + ferr("ERROR: Failed to create MTD partition\n"); + return NULL; + } + + return mtd_part; +} + +/**************************************************************************** + * Name: esp32c3_spiflash_mtd + * + * Description: + * Get SPI Flash MTD. + * + * Input Parameters: + * None + * + * Returned Value: + * ESP32-C3 SPI Flash MTD pointer. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32c3_spiflash_mtd(void) +{ + struct esp32c3_mtd_dev_s *priv = + (struct esp32c3_mtd_dev_s *)&g_esp32c3_spiflash; + + return &priv->mtd; +} + +/**************************************************************************** + * Name: esp32c3_spiflash_encrypt_mtd + * + * Description: + * Get SPI Flash encryption MTD. + * + * Input Parameters: + * None + * + * Returned Value: + * SPI Flash encryption MTD pointer. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32c3_spiflash_encrypt_mtd(void) +{ + struct esp32c3_mtd_dev_s *priv = + (struct esp32c3_mtd_dev_s *)&g_esp32c3_spiflash_encrypt; + + return &priv->mtd; +} diff --git a/arch/risc-v/src/esp32c3/esp32c3_spiflash_mtd.h b/arch/risc-v/src/esp32c3/esp32c3_spiflash_mtd.h new file mode 100644 index 00000000000..3c3a261307b --- /dev/null +++ b/arch/risc-v/src/esp32c3/esp32c3_spiflash_mtd.h @@ -0,0 +1,105 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp32c3_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_ESP32C3_ESP32C3_SPIFLASH_MTD_H +#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_SPIFLASH_MTD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32c3_spiflash_mtd + * + * Description: + * Get SPI Flash MTD. + * + * Input Parameters: + * None + * + * Returned Value: + * ESP32-C3 SPI Flash MTD pointer. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32c3_spiflash_mtd(void); + +/**************************************************************************** + * Name: esp32c3_spiflash_encrypt_mtd + * + * Description: + * Get SPI Flash encryption MTD. + * + * Input Parameters: + * None + * + * Returned Value: + * SPI Flash encryption MTD pointer. + * + ****************************************************************************/ + +struct mtd_dev_s *esp32c3_spiflash_encrypt_mtd(void); + +/**************************************************************************** + * Name: esp32c3_spiflash_alloc_mtdpart + * + * Description: + * Allocate an MTD partition from the ESP32-C3 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 *esp32c3_spiflash_alloc_mtdpart(uint32_t mtd_offset, + uint32_t mtd_size); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_SPIFLASH_MTD_H */ diff --git a/arch/risc-v/src/esp32c3/esp32c3_wireless.c b/arch/risc-v/src/esp32c3/esp32c3_wireless.c index 8abf11882fa..1e085041dd1 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_wireless.c +++ b/arch/risc-v/src/esp32c3/esp32c3_wireless.c @@ -25,13 +25,45 @@ #include #include +#include #include +#include "riscv_internal.h" + +#include "hardware/esp32c3_system.h" #include "hardware/esp32c3_soc.h" #include "hardware/esp32c3_syscon.h" #include "esp32c3.h" +#include "esp32c3_irq.h" +#include "esp32c3_attr.h" +#include "esp32c3_wireless.h" + #include "espidf_wifi.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Software Interrupt */ + +#define SWI_IRQ ESP32C3_IRQ_FROM_CPU_INT0 +#define SWI_PERIPH ESP32C3_PERIPH_FROM_CPU_INT0 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* ESP32-C3 Wireless Private Data */ + +struct esp32c3_wl_priv_s +{ + volatile int ref; /* Reference count */ + + int cpuint; /* CPU interrupt assigned to SWI */ + + struct list_node sc_list; /* Semaphore cache list */ +}; + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -69,6 +101,8 @@ static uint32_t *g_phy_digital_regs_mem = NULL; static bool g_is_phy_calibrated = false; +static struct esp32c3_wl_priv_s g_esp32c3_wl_priv; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -175,6 +209,52 @@ static void esp32c3_phy_disable_clock(void) leave_critical_section(flags); } +/**************************************************************************** + * Name: esp32c3_wl_swi_irq + * + * Description: + * Wireless software interrupt callback function. + * + * Parameters: + * cpuint - CPU interrupt index + * context - Context data from the ISR + * arg - NULL + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int esp32c3_wl_swi_irq(int irq, void *context, FAR void *arg) +{ + int i; + int ret; + struct esp32c3_wl_semcache_s *sc; + struct esp32c3_wl_semcache_s *tmp; + struct esp32c3_wl_priv_s *priv = &g_esp32c3_wl_priv; + + putreg32(0, SYSTEM_CPU_INTR_FROM_CPU_0_REG); + + list_for_every_entry_safe(&priv->sc_list, sc, tmp, + struct esp32c3_wl_semcache_s, node) + { + for (i = 0; i < sc->count; i++) + { + ret = nxsem_post(sc->sem); + if (ret < 0) + { + wlerr("ERROR: Failed to post sem ret=%d\n", ret); + } + } + + sc->count = 0; + list_delete(&sc->node); + } + + return OK; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -280,3 +360,147 @@ void esp32c3_phy_enable(void) leave_critical_section(flags); kmm_free(cal_data); } + +/**************************************************************************** + * Name: esp32c3_wl_init_semcache + * + * Description: + * Initialize semaphore cache. + * + * Parameters: + * sc - Semaphore cache data pointer + * sem - Semaphore data pointer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32c3_wl_init_semcache(struct esp32c3_wl_semcache_s *sc, + sem_t *sem) +{ + sc->sem = sem; + sc->count = 0; + list_initialize(&sc->node); +} + +/**************************************************************************** + * Name: esp32c3_wl_post_semcache + * + * Description: + * Store posting semaphore action into semaphore cache. + * + * Parameters: + * sc - Semaphore cache data pointer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void IRAM_ATTR esp32c3_wl_post_semcache( + struct esp32c3_wl_semcache_s *sc) +{ + struct esp32c3_wl_priv_s *priv = &g_esp32c3_wl_priv; + + if (!sc->count) + { + list_add_tail(&priv->sc_list, &sc->node); + } + + sc->count++; + + putreg32(SYSTEM_CPU_INTR_FROM_CPU_0_M, SYSTEM_CPU_INTR_FROM_CPU_0_REG); +} + +/**************************************************************************** + * Name: esp32c3_wl_init + * + * Description: + * Initialize ESP32-C3 wireless common components for both BT and Wi-Fi. + * + * Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int esp32c3_wl_init(void) +{ + int ret; + irqstate_t flags; + struct esp32c3_wl_priv_s *priv = &g_esp32c3_wl_priv; + + flags = enter_critical_section(); + if (priv->ref != 0) + { + priv->ref++; + leave_critical_section(flags); + return OK; + } + + priv->cpuint = esp32c3_request_irq(SWI_PERIPH, + ESP32C3_INT_PRIO_DEF, + ESP32C3_INT_LEVEL); + + ret = irq_attach(SWI_IRQ, esp32c3_wl_swi_irq, NULL); + if (ret < 0) + { + esp32c3_free_cpuint(SWI_PERIPH); + leave_critical_section(flags); + wlerr("ERROR: Failed to attach IRQ ret=%d\n", ret); + + return ret; + } + + list_initialize(&priv->sc_list); + + up_enable_irq(priv->cpuint); + + priv->ref++; + + leave_critical_section(flags); + + return OK; +} + +/**************************************************************************** + * Name: esp32c3_wl_deinit + * + * Description: + * De-initialize ESP32-C3 wireless common components. + * + * Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int esp32c3_wl_deinit(void) +{ + irqstate_t flags; + struct esp32c3_wl_priv_s *priv = &g_esp32c3_wl_priv; + + flags = enter_critical_section(); + if (priv->ref == 0) + { + leave_critical_section(flags); + return OK; + } + + up_disable_irq(priv->cpuint); + irq_detach(SWI_IRQ); + esp32c3_free_cpuint(SWI_PERIPH); + + priv->ref--; + + leave_critical_section(flags); + + return OK; +} diff --git a/arch/risc-v/src/esp32c3/esp32c3_wireless.h b/arch/risc-v/src/esp32c3/esp32c3_wireless.h index 02d8d60530b..8fe156498c7 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_wireless.h +++ b/arch/risc-v/src/esp32c3/esp32c3_wireless.h @@ -26,6 +26,35 @@ ****************************************************************************/ #include +#include +#include +#include +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* Semaphore Cache Data */ + +struct esp32c3_wl_semcache_s +{ + struct list_node node; + + sem_t *sem; + uint32_t count; +}; /**************************************************************************** * Public Function Prototypes @@ -63,4 +92,78 @@ void esp32c3_phy_enable(void); void esp32c3_phy_disable(void); +/**************************************************************************** + * Name: esp32c3_wl_init_semcache + * + * Description: + * Initialize semaphore cache. + * + * Parameters: + * sc - Semaphore cache data pointer + * sem - Semaphore data pointer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32c3_wl_init_semcache(struct esp32c3_wl_semcache_s *sc, + sem_t *sem); + +/**************************************************************************** + * Name: esp32c3_wl_post_semcache + * + * Description: + * Store posting semaphore action into semaphore cache. + * + * Parameters: + * sc - Semaphore cache data pointer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32c3_wl_post_semcache(struct esp32c3_wl_semcache_s *sc); + +/**************************************************************************** + * Name: esp32c3_wl_init + * + * Description: + * Initialize ESP32-C3 wireless common components for both BT and Wi-Fi. + * + * Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int esp32c3_wl_init(void); + +/**************************************************************************** + * Name: esp32c3_wl_deinit + * + * Description: + * De-initialize ESP32-C3 wireless common components. + * + * Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int esp32c3_wl_deinit(void); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ #endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WIRELESS_H */ diff --git a/arch/risc-v/src/esp32c3/hardware/extmem_reg.h b/arch/risc-v/src/esp32c3/hardware/extmem_reg.h index d44cdcb75b4..3706b3a905e 100644 --- a/arch/risc-v/src/esp32c3/hardware/extmem_reg.h +++ b/arch/risc-v/src/esp32c3/hardware/extmem_reg.h @@ -31,7 +31,19 @@ * Pre-processor Definitions ****************************************************************************/ +#define EXTMEM_ICACHE_CTRL_REG (DR_REG_EXTMEM_BASE + 0x000) + +/* EXTMEM_ICACHE_ENABLE : R/W ;bitpos:[0] ;default: 1'b0. + * The bit is used to activate the data cache. 0: disable 1: enable + */ + +#define EXTMEM_ICACHE_ENABLE (BIT(0)) +#define EXTMEM_ICACHE_ENABLE_M (BIT(0)) +#define EXTMEM_ICACHE_ENABLE_V 0x1 +#define EXTMEM_ICACHE_ENABLE_S 0 + #define EXTMEM_ICACHE_CTRL1_REG (DR_REG_EXTMEM_BASE + 0x004) + #define EXTMEM_ICACHE_TAG_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x008) #define EXTMEM_CACHE_MMU_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x0ac) diff --git a/arch/risc-v/src/esp32c3/rom/esp32c3_spiflash.h b/arch/risc-v/src/esp32c3/rom/esp32c3_spiflash.h index 62e32714b0e..ca6bfe0cc7c 100644 --- a/arch/risc-v/src/esp32c3/rom/esp32c3_spiflash.h +++ b/arch/risc-v/src/esp32c3/rom/esp32c3_spiflash.h @@ -154,6 +154,57 @@ struct spiflash_legacy_data_s uint8_t sig_matrix; }; +/** + * Structure holding SPI flash access critical sections management functions. + * + * Flash API uses two types of functions for flash access management: + * 1) Functions which prepare/restore flash cache and interrupts before + * calling appropriate ROM functions (SPIWrite, SPIRead and + * SPIEraseBlock): + * - 'start' function should disable flash cache and non-IRAM interrupts + * and is invoked before the call to one of ROM functions from + * "struct spiflash_guard_funcs_s". + * - 'end' function should restore state of flash cache and non-IRAM + * interrupts and is invoked after the call to one of ROM + * functions from "struct spiflash_guard_funcs_s". + * These two functions are not reentrant. + * 2) Functions which synchronizes access to internal data used by flash API. + * These functions are mostly intended to synchronize access to flash API + * internal data in multithreaded environment and use OS primitives: + * - 'op_lock' locks access to flash API internal data. + * - 'op_unlock' unlocks access to flash API internal data. + * These two functions are reentrant and can be used around the outside of + * multiple calls to 'start' & 'end', in order to create atomic multi-part + * flash operations. + * + * Different versions of the guarding functions should be used depending on + * the context of execution (with or without functional OS). In normal + * conditions when flash API is called from task the functions use OS + * primitives. + * When there is no OS at all or when it is not guaranteed that OS is + * functional (accessing flash from exception handler) these functions cannot + * use OS primitives or even does not need them (multithreaded access is + * not possible). + * + * @note Structure and corresponding guard functions should not reside + * in flash. For example structure can be placed in DRAM and functions + * in IRAM sections. + */ + +struct spiflash_guard_funcs +{ + void (*start)(void); /* critical section start function */ + void (*end)(void); /* critical section end function */ + void (*op_lock)(void); /* flash access API lock function */ + void (*op_unlock)(void); /* flash access API unlock function */ + + /* checks flash write addresses */ + + bool (*address_is_safe)(size_t addr, size_t size); + + void (*yield)(void); /* yield to the OS during flash erase */ +}; + /***************************************************************************** * Public Function Prototypes *****************************************************************************/ @@ -792,6 +843,168 @@ esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp32c3_spiflash_chip_t void esp_rom_spiflash_select_qio_pins(uint8_t wp_gpio_num, uint32_t spiconfig); +/***************************************************************************** + * Name: spi_flash_guard_set + * + * Description: + * Sets guard functions to access flash. + * + * Input Parameters: + * funcs - funcs pointer to structure holding flash access guard functions + * + * Returned Value: + * None + * + *****************************************************************************/ + +void spi_flash_guard_set(const struct spiflash_guard_funcs *funcs); + +/***************************************************************************** + * Name: spi_flash_write_encrypted + * + * Description: + * Write data encrypted to Flash. + * + * Flash encryption must be enabled for this function to work. + * + * Flash encryption must be enabled when calling this function. + * If flash encryption is disabled, the function returns + * ESP_ERR_INVALID_STATE. Use esp_flash_encryption_enabled() + * function to determine if flash encryption is enabled. + * + * Both dest_addr and size must be multiples of 16 bytes. For + * absolute best performance, both dest_addr and size arguments should + * be multiples of 32 bytes. + * + * Input Parameters: + * dest_addr - Destination address in Flash. Must be a multiple of 16 + * bytes. + * src - Pointer to the source buffer. + * size - Length of data, in bytes. Must be a multiple of 16 bytes. + * + * Returned Values: + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_write_encrypted(uint32_t dest_addr, const void *src, + uint32_t size); + +/***************************************************************************** + * Name: spi_flash_write + * + * Description: + * + * Write data to Flash. + * + * Note: For fastest write performance, write a 4 byte aligned size at a + * 4 byte aligned offset in flash from a source buffer in DRAM. Varying + * any of these parameters will still work, but will be slower due to + * buffering. + * + * Writing more than 8KB at a time will be split into multiple + * write operations to avoid disrupting other tasks in the system. + * + * Parameters: + * dest_addr - Destination address in Flash. + * src - Pointer to the source buffer. + * size - Length of data, in bytes. + * + * Returned Values: + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_write(uint32_t dest_addr, const void *src, uint32_t size); + +/***************************************************************************** + * Name: spi_flash_read + * + * Description: + * Read data from Flash. + * + * Note: For fastest read performance, all parameters should be + * 4 byte aligned. If source address and read size are not 4 byte + * aligned, read may be split into multiple flash operations. If + * destination buffer is not 4 byte aligned, a temporary buffer will + * be allocated on the stack. + * + * Reading more than 16KB of data at a time will be split + * into multiple reads to avoid disruption to other tasks in the + * system. Consider using spi_flash_mmap() to read large amounts + * of data. + * + * Parameters: + * src_addr - source address of the data in Flash. + * dest - pointer to the destination buffer + * size - length of data + * + * Returned Values: + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_read(uint32_t src_addr, void *dest, uint32_t size); + +/***************************************************************************** + * Name: spi_flash_erase_sector + * + * Description: + * Erase the Flash sector. + * + * Parameters: + * sector - Sector number, the count starts at sector 0, 4KB per sector. + * + * Returned Values: esp_err_t + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_erase_sector(uint32_t sector); + +/***************************************************************************** + * Name: spi_flash_erase_range + * + * Description: + * Erase a range of flash sectors + * + * Parameters: + * start_address - Address where erase operation has to start. + * Must be 4kB-aligned + * size - Size of erased range, in bytes. Must be divisible by + * 4kB. + * + * Returned Values: + * Zero (OK) is returned or a negative error. + * + *****************************************************************************/ + +int spi_flash_erase_range(uint32_t start_address, uint32_t size); + +/***************************************************************************** + * Name: spi_flash_cache_enabled + * + * Description: + * Check at runtime if flash cache is enabled on both CPUs. + * + * Returned Values: + * Return true if both CPUs have flash cache enabled, false otherwise. + */ + +bool spi_flash_cache_enabled(void); + +/***************************************************************************** + * Name: spi_flash_enable_cache + * + * Description: + * Re-enable cache for the core defined as cpuid parameter. + * + * Parameters: + * cpuid - core number to enable instruction cache for. + */ + +void spi_flash_enable_cache(uint32_t cpuid); + /* Global esp32c3_spiflash_chip_t structure used by ROM functions */ extern esp32c3_spiflash_chip_t g_rom_flashchip; diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.ld b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.ld index fddd0dd3019..8910d4c5dc7 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.ld +++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.ld @@ -36,6 +36,8 @@ SECTIONS *(.iram1) *(.iram1.*) + *libsched.a:irq_dispatch.*(.text .text.* .literal .literal.*) + *(.wifi0iram .wifi0iram.*) *(.wifirxiram .wifirxiram.*) *(.wifislpiram .wifislpiram.*) diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3-devkit.h b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3-devkit.h index baa8835d574..a58b8e4e26d 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3-devkit.h +++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3-devkit.h @@ -205,7 +205,7 @@ int board_wlan_init(void); #endif /**************************************************************************** - * Name: esp32c3_spiflash_init + * Name: board_spiflash_init * * Description: * Initialize the SPIFLASH and register the MTD device. @@ -213,7 +213,7 @@ int board_wlan_init(void); ****************************************************************************/ #ifdef CONFIG_ESP32C3_SPIFLASH -int esp32c3_spiflash_init(void); +int board_spiflash_init(void); #endif /**************************************************************************** diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c index 34b8e26a66b..0ecca7b81ae 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c +++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c @@ -145,7 +145,7 @@ int esp32c3_bringup(void) #endif #ifdef CONFIG_ESP32C3_SPIFLASH - ret = esp32c3_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c index 334c9956ee2..d49236e3bd9 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c +++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c @@ -43,6 +43,7 @@ #endif #include "esp32c3_spiflash.h" +#include "esp32c3_spiflash_mtd.h" #include "esp32c3-devkit.h" /**************************************************************************** @@ -497,16 +498,18 @@ static int init_storage_partition(void) ****************************************************************************/ /**************************************************************************** - * Name: esp32c3_spiflash_init + * Name: board_spiflash_init * * Description: * Initialize the SPIFLASH and register the MTD device. ****************************************************************************/ -int esp32c3_spiflash_init(void) +int board_spiflash_init(void) { int ret = OK; + esp32c3_spiflash_init(); + #ifdef CONFIG_ESP32C3_HAVE_OTA_PARTITION ret = init_ota_partitions(); if (ret < 0)