This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 57b8fc99543c2de7b249bdc2c8eab419c7be6e0e Author: Tiago Medicci Serrano <[email protected]> AuthorDate: Tue Oct 10 10:38:38 2023 -0300 esp32/irq: Allow IRAM ISRs to run during SPI flash operation This commit provides an interface to register ISRs that run from IRAM and keeps track of the non-IRAM interrupts. It enables, for instance, to avoid disabling all the interrupts during a SPI flash operation: IRAM-enabled ISRs are, then, able to run during these operations. It also makes the code look more similar to the ESP32-S3 SPI flash implementation by creating a common `esp32_spiflash_init` that is responsible to create the SPI flash operation tasks. The function intended to initialize the SPI flash partions was, then, renamed to `board_spiflash_init`. --- arch/xtensa/include/esp32/irq.h | 10 + arch/xtensa/src/esp32/Kconfig | 24 ++ arch/xtensa/src/esp32/esp32_irq.c | 364 ++++++++++++++++++++- arch/xtensa/src/esp32/esp32_irq.h | 150 ++++++++- arch/xtensa/src/esp32/esp32_spiflash.c | 234 ++++++++++++- arch/xtensa/src/esp32/esp32_spiflash.h | 13 + arch/xtensa/src/esp32/hardware/esp32_soc.h | 19 ++ .../esp32/common/include/esp32_board_spiflash.h | 4 +- .../xtensa/esp32/common/scripts/legacy_sections.ld | 18 +- .../xtensa/esp32/common/src/esp32_board_spiflash.c | 10 +- .../esp32/esp32-audio-kit/src/esp32_bringup.c | 2 +- .../esp32/esp32-devkitc/configs/ble/defconfig | 7 +- .../xtensa/esp32/esp32-devkitc/src/esp32_bringup.c | 2 +- .../esp32/esp32-ethernet-kit/src/esp32_bringup.c | 2 +- .../xtensa/esp32/esp32-lyrat/src/esp32_bringup.c | 2 +- .../esp32/esp32-pico-kit/src/esp32_bringup.c | 2 +- .../esp32/esp32-sparrow-kit/src/esp32_bringup.c | 2 +- .../esp32/esp32-wrover-kit/src/esp32_bringup.c | 2 +- .../lilygo_tbeam_lora_gps/src/esp32_bringup.c | 2 +- .../xtensa/esp32/ttgo_eink5_v2/src/esp32_bringup.c | 2 +- .../esp32/ttgo_lora_esp32/src/esp32_bringup.c | 2 +- .../esp32/ttgo_t_display_esp32/src/esp32_bringup.c | 2 +- 22 files changed, 831 insertions(+), 44 deletions(-) diff --git a/arch/xtensa/include/esp32/irq.h b/arch/xtensa/include/esp32/irq.h index 1b71bfac9b..05b273468f 100644 --- a/arch/xtensa/include/esp32/irq.h +++ b/arch/xtensa/include/esp32/irq.h @@ -35,6 +35,16 @@ * Pre-processor Definitions ****************************************************************************/ +/* CPU interrupt flags: + * These flags can be used to specify which interrupt qualities the + * code calling esp32_setup_irq needs. + */ + +#define ESP32_CPUINT_FLAG_LEVEL (1 << 0) /* Level-triggered interrupt */ +#define ESP32_CPUINT_FLAG_EDGE (1 << 1) /* Edge-triggered interrupt */ +#define ESP32_CPUINT_FLAG_SHARED (1 << 2) /* Interrupt can be shared between ISRs */ +#define ESP32_CPUINT_FLAG_IRAM (1 << 3) /* ISR can be called if cache is disabled */ + /* Interrupt Matrix * * The Interrupt Matrix embedded in the ESP32 independently allocates diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index bb273a1686..996ac5f50f 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -758,6 +758,19 @@ config ESP32_WIFI_BT_COEXIST default n depends on ESP32_WIFI && ESP32_BLE +menu "Interrupt Configuration" + +config ESP32_IRAM_ISR_DEBUG + bool "Enable debugging of the IRAM-enabled interrupts" + default n + ---help--- + This option enables keeping track of the IRAM-enabled interrupts by + registering its execution when non-IRAM interrupts are disabled. It + keeps track of the IRQ executed and register how many times since + boot it was executed. + +endmenu # Interrupt Configuration + menu "Memory Configuration" config ESP32_BT_RESERVE_DRAM @@ -1858,6 +1871,17 @@ config ESP32_PARTITION_MOUNTPT endif # ESP32_PARTITION_TABLE +config ESP32_SPIFLASH_OP_TASK_STACKSIZE + int "The SPI flash operation task stack size" + default 768 + depends on SMP + ---help--- + When SMP is enabled, it is needed to create two tasks (one for each + core) to be able to run IRAM-enabled interrupts. These tasks ensures + that the core that isn't performing the SPI flash operation is able + to disable non-IRAM interrupts and wait for the SPI flash operation + to be finished. + endif # ESP32_SPIFLASH endmenu # SPI Flash configuration diff --git a/arch/xtensa/src/esp32/esp32_irq.c b/arch/xtensa/src/esp32/esp32_irq.c index 56938edffb..9dae25e495 100644 --- a/arch/xtensa/src/esp32/esp32_irq.c +++ b/arch/xtensa/src/esp32/esp32_irq.c @@ -35,6 +35,7 @@ #include <nuttx/board.h> #include <arch/irq.h> #include <arch/board/board.h> +#include <irq/irq.h> #include "xtensa.h" @@ -154,6 +155,24 @@ static volatile uint8_t g_irqmap[NR_IRQS]; static uint32_t g_intenable[CONFIG_SMP_NCPUS]; +/* g_non_iram_int_mask[] is a bitmask of the interrupts that should be + * disabled during a SPI flash operation. Non-IRAM interrupts should always + * be disabled, but interrupts place on IRAM are able to run during a SPI + * flash operation. + */ + +static uint32_t g_non_iram_int_mask[CONFIG_SMP_NCPUS]; + +/* g_non_iram_int_disabled[] keeps track of the interrupts disabled during + * a SPI flash operation. + */ + +static uint32_t g_non_iram_int_disabled[CONFIG_SMP_NCPUS]; + +/* Per-CPU flag to indicate that non-IRAM interrupts were disabled */ + +static bool g_non_iram_int_disabled_flag[CONFIG_SMP_NCPUS]; + /* Bitsets for free, unallocated CPU interrupts available to peripheral * devices. */ @@ -176,6 +195,14 @@ static const uint32_t g_priority[5] = ESP32_INTPRI5_MASK }; +#ifdef CONFIG_ESP32_IRAM_ISR_DEBUG +/* The g_iram_count keeps track of how many times such an IRQ ran when the + * non-IRAM interrupts were disabled. + */ + +static uint64_t g_iram_count[NR_IRQS]; +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -368,7 +395,13 @@ static int esp32_alloc_cpuint(int cpu, int priority, int type) DEBUGASSERT(type == ESP32_CPUINT_LEVEL || type == ESP32_CPUINT_EDGE); - if (type == ESP32_CPUINT_LEVEL) + if ((type & (ESP32_CPUINT_LEVEL | ESP32_CPUINT_EDGE)) == 0) + { + irqerr("Either the level or edege-triggered flag must be selected"); + return -EINVAL; + } + + if ((type & ESP32_CPUINT_LEVEL) != 0) { /* Check if there are any level CPU interrupts available at the * requested interrupt priority. @@ -428,6 +461,33 @@ static void esp32_free_cpuint(int cpuint) *freeints |= bitmask; } +#ifdef CONFIG_ESP32_IRAM_ISR_DEBUG + +/**************************************************************************** + * Name: esp32_iram_interrupt_record + * + * Description: + * This function keeps track of the IRQs that ran when non-IRAM interrupts + * are disabled and enables debugging of the IRAM-enabled interrupts. + * + * Input Parameters: + * irq - The IRQ associated with a CPU interrupt + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32_irq_iram_interrupt_record(int irq) +{ + irqstate_t flags = enter_critical_section(); + + g_iram_count[irq]++; + + leave_critical_section(flags); +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -440,6 +500,15 @@ void up_irqinitialize(void) { int i; + /* All CPU ints are non-IRAM interrupts at the beginning and should be + * disabled during a SPI flash operation + */ + + for (i = 0; i < CONFIG_SMP_NCPUS; i++) + { + g_non_iram_int_mask[i] = UINT32_MAX; + } + for (i = 0; i < NR_IRQS; i++) { g_irqmap[i] = IRQ_UNMAPPED; @@ -625,6 +694,21 @@ void up_enable_irq(int irq) int cpu = IRQ_GETCPU(g_irqmap[irq]); + /* Check if the registered ISR for this IRQ is intended to be run from + * IRAM. If so, check if its interrupt handler is located in IRAM. + */ + + bool isr_in_iram = !((g_non_iram_int_mask[cpu] & (1 << cpuint)) > 0); + + xcpt_t handler = g_irqvector[irq].handler; + + if (isr_in_iram && handler && !esp32_ptr_iram(handler)) + { + irqerr("Interrupt handler isn't in IRAM (%08" PRIx32 ")", + (intptr_t)handler); + PANIC(); + } + DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS); /* Attach the interrupt to the peripheral; the CPU interrupt was @@ -780,14 +864,16 @@ int esp32_cpuint_initialize(void) * * Description: * This function sets up the IRQ. It allocates a CPU interrupt of the given - * priority and type and attaches it to the given peripheral. + * priority and associated flags and attaches it to the given peripheral. * * Input Parameters: * cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU * periphid - The peripheral number from irq.h to be assigned to * a CPU interrupt. * priority - Interrupt's priority (1 - 5). - * type - Interrupt's type (level or edge). + * flags - An ORred mask of the ESP32_CPUINT_FLAG_* defines. These + * restrict the choice of interrupts that this routine can + * choose from. * * Returned Value: * The allocated CPU interrupt on success, a negated errno value on @@ -795,7 +881,7 @@ int esp32_cpuint_initialize(void) * ****************************************************************************/ -int esp32_setup_irq(int cpu, int periphid, int priority, int type) +int esp32_setup_irq(int cpu, int periphid, int priority, int flags) { irqstate_t irqstate; uintptr_t regaddr; @@ -809,13 +895,14 @@ int esp32_setup_irq(int cpu, int periphid, int priority, int type) * 1. Allocate a CPU interrupt. * 2. Attach that CPU interrupt to the peripheral. * 3. Map the CPU interrupt to the IRQ to ease searching later. + * 4. Check if its ISR is intended to run from IRAM. */ - cpuint = esp32_alloc_cpuint(cpu, priority, type); + cpuint = esp32_alloc_cpuint(cpu, priority, flags); if (cpuint < 0) { - irqerr("Unable to allocate CPU interrupt for priority=%d and type=%d", - priority, type); + irqerr("Unable to allocate CPU interrupt for priority=%d and flags=%d", + priority, flags); leave_critical_section(irqstate); return cpuint; @@ -842,6 +929,15 @@ int esp32_setup_irq(int cpu, int periphid, int priority, int type) intmap[cpuint] = CPUINT_ASSIGN(periphid + XTENSA_IRQ_FIRSTPERIPH); g_irqmap[irq] = IRQ_MKMAP(cpu, cpuint); + if ((flags & ESP32_CPUINT_FLAG_IRAM) != 0) + { + esp32_irq_set_iram_isr(irq); + } + else + { + esp32_irq_unset_iram_isr(irq); + } + putreg32(cpuint, regaddr); leave_critical_section(irqstate); @@ -901,6 +997,65 @@ void esp32_teardown_irq(int cpu, int periphid, int cpuint) leave_critical_section(irqstate); } +/**************************************************************************** + * Name: esp32_getirq + * + * Description: + * This function returns the IRQ associated with a CPU interrupt + * + * Input Parameters: + * cpu - The CPU core of the IRQ being queried + * cpuint - The CPU interrupt associated to the IRQ + * + * Returned Value: + * The IRQ associated with such CPU interrupt or CPUINT_UNASSIGNED if + * IRQ is not yet assigned to a CPU interrupt. + * + ****************************************************************************/ + +int esp32_getirq(int cpu, int cpuint) +{ + uint8_t *intmap; + +#ifdef CONFIG_SMP + /* Select PRO or APP CPU interrupt mapping table */ + + if (cpu != 0) + { + intmap = g_cpu1_intmap; + } + else +#endif + { + intmap = g_cpu0_intmap; + } + + return CPUINT_GETIRQ(intmap[cpuint]); +} + +/**************************************************************************** + * Name: esp32_getcpuint_from_irq + * + * Description: + * This function returns the CPU interrupt associated with an IRQ + * + * Input Parameters: + * irq - The IRQ associated with a CPU interrupt + * cpu - Pointer to store the CPU core of the CPU interrupt + * + * Returned Value: + * The CPU interrupt associated with such IRQ or IRQ_UNMAPPED if + * CPU interrupt is not mapped to an IRQ. + * + ****************************************************************************/ + +int esp32_getcpuint_from_irq(int irq, int *cpu) +{ + (*cpu) = (int)IRQ_GETCPU(g_irqmap[irq]); + + return IRQ_GETCPUINT(g_irqmap[irq]); +} + /**************************************************************************** * Name: xtensa_int_decode * @@ -924,18 +1079,17 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs) uint8_t *intmap; uint32_t mask; int bit; -#ifdef CONFIG_SMP int cpu; -#endif #ifdef CONFIG_ARCH_LEDS_CPU_ACTIVITY board_autoled_on(LED_CPU); #endif -#ifdef CONFIG_SMP /* Select PRO or APP CPU interrupt mapping table */ cpu = up_cpu_index(); + +#ifdef CONFIG_SMP if (cpu != 0) { intmap = g_cpu1_intmap; @@ -966,6 +1120,17 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs) DEBUGASSERT(CPUINT_GETEN(intmap[bit])); DEBUGASSERT(irq != CPUINT_UNASSIGNED); +#ifdef CONFIG_ESP32_IRAM_ISR_DEBUG + /* Check if non-IRAM interrupts are disabled */ + + if (esp32_irq_noniram_status(cpu) == 0) + { + /* Sum-up the IRAM-enabled counter associated with the IRQ */ + + esp32_irq_iram_interrupt_record(irq); + } +#endif + /* Clear software or edge-triggered interrupt */ xtensa_intclear(mask); @@ -986,6 +1151,185 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs) } } + UNUSED(cpu); + return regs; } +/**************************************************************************** + * Name: esp32_irq_noniram_disable + * + * Description: + * Disable interrupts that aren't specifically marked as running from IRAM + * + * Input Parameters: + * None + * + * Input Parameters: + * None + * + ****************************************************************************/ + +void esp32_irq_noniram_disable(void) +{ + irqstate_t irqstate; + int cpu; + uint32_t oldint; + uint32_t non_iram_ints; + + irqstate = enter_critical_section(); + cpu = up_cpu_index(); + non_iram_ints = g_non_iram_int_mask[cpu]; + + ASSERT(!g_non_iram_int_disabled_flag[cpu]); + + g_non_iram_int_disabled_flag[cpu] = true; + oldint = g_intenable[cpu]; + + xtensa_disable_cpuint(&g_intenable[cpu], non_iram_ints); + + g_non_iram_int_disabled[cpu] = oldint & non_iram_ints; + + leave_critical_section(irqstate); +} + +/**************************************************************************** + * Name: esp32_irq_noniram_enable + * + * Description: + * Re-enable interrupts disabled by esp32_irq_noniram_disable + * + * Input Parameters: + * None + * + * Input Parameters: + * None + * + ****************************************************************************/ + +void esp32_irq_noniram_enable(void) +{ + irqstate_t irqstate; + int cpu; + uint32_t non_iram_ints; + + irqstate = enter_critical_section(); + cpu = up_cpu_index(); + non_iram_ints = g_non_iram_int_disabled[cpu]; + + ASSERT(g_non_iram_int_disabled_flag[cpu]); + + g_non_iram_int_disabled_flag[cpu] = false; + + xtensa_enable_cpuint(&g_intenable[cpu], non_iram_ints); + + leave_critical_section(irqstate); +} + +/**************************************************************************** + * Name: esp32_irq_noniram_status + * + * Description: + * Get the current status of non-IRAM interrupts on a specific CPU core + * + * Input Parameters: + * cpu - The CPU to check the non-IRAM interrupts state + * + * Returned Value: + * true if non-IRAM interrupts are enabled, false otherwise. + * + ****************************************************************************/ + +bool esp32_irq_noniram_status(int cpu) +{ + DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS); + + return !g_non_iram_int_disabled_flag[cpu]; +} + +/**************************************************************************** + * Name: esp32_irq_set_iram_isr + * + * Description: + * Set the ISR associated to an IRQ as a IRAM-enabled ISR. + * + * Input Parameters: + * irq - The associated IRQ to set + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +int esp32_irq_set_iram_isr(int irq) +{ + int cpu; + int cpuint = esp32_getcpuint_from_irq(irq, &cpu); + + if (cpuint == IRQ_UNMAPPED) + { + return -EINVAL; + } + + g_non_iram_int_mask[cpu] &= ~(1 << cpuint); + + return OK; +} + +/**************************************************************************** + * Name: esp32_irq_unset_iram_isr + * + * Description: + * Set the ISR associated to an IRQ as a non-IRAM ISR. + * + * Input Parameters: + * irq - The associated IRQ to set + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +int esp32_irq_unset_iram_isr(int irq) +{ + int cpu; + int cpuint = esp32_getcpuint_from_irq(irq, &cpu); + + if (cpuint == IRQ_UNMAPPED) + { + return -EINVAL; + } + + g_non_iram_int_mask[cpu] |= (1 << cpuint); + + return OK; +} + +#ifdef CONFIG_ESP32_IRAM_ISR_DEBUG + +/**************************************************************************** + * Name: esp32_get_iram_interrupt_records + * + * Description: + * This function copies the vector that keeps track of the IRQs that ran + * when non-IRAM interrupts were disabled. + * + * Input Parameters: + * + * irq_count - A previously allocated pointer to store the counter of the + * interrupts that ran when non-IRAM interrupts were disabled. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp32_get_iram_interrupt_records(uint64_t *irq_count) +{ + irqstate_t flags = enter_critical_section(); + + memcpy(irq_count, &g_iram_count, sizeof(uint64_t) * NR_IRQS); + + leave_critical_section(flags); +} +#endif diff --git a/arch/xtensa/src/esp32/esp32_irq.h b/arch/xtensa/src/esp32/esp32_irq.h index f1141a95c4..ba29477924 100644 --- a/arch/xtensa/src/esp32/esp32_irq.h +++ b/arch/xtensa/src/esp32/esp32_irq.h @@ -46,8 +46,8 @@ extern "C" /* CPU interrupt types. */ -#define ESP32_CPUINT_LEVEL 0 -#define ESP32_CPUINT_EDGE 1 +#define ESP32_CPUINT_LEVEL ESP32_CPUINT_FLAG_LEVEL +#define ESP32_CPUINT_EDGE ESP32_CPUINT_FLAG_EDGE /**************************************************************************** * Public Functions Prototypes @@ -75,14 +75,16 @@ int esp32_cpuint_initialize(void); * * Description: * This function sets up the IRQ. It allocates a CPU interrupt of the given - * priority and type and attaches it to the given peripheral. + * priority and associated flags and attaches it to the given peripheral. * * Input Parameters: * cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU * periphid - The peripheral number from irq.h to be assigned to * a CPU interrupt. * priority - Interrupt's priority (1 - 5). - * type - Interrupt's type (level or edge). + * flags - An ORred mask of the ESP32_CPUINT_FLAG_* defines. These + * restrict the choice of interrupts that this routine can + * choose from. * * Returned Value: * The allocated CPU interrupt on success, a negated errno value on @@ -90,7 +92,7 @@ int esp32_cpuint_initialize(void); * ****************************************************************************/ -int esp32_setup_irq(int cpu, int periphid, int priority, int type); +int esp32_setup_irq(int cpu, int periphid, int priority, int flags); /**************************************************************************** * Name: esp32_teardown_irq @@ -114,6 +116,144 @@ int esp32_setup_irq(int cpu, int periphid, int priority, int type); void esp32_teardown_irq(int cpu, int periphid, int cpuint); +/**************************************************************************** + * Name: esp32_getirq + * + * Description: + * This function returns the IRQ associated with a CPU interrupt + * + * Input Parameters: + * cpu - The CPU core of the IRQ being queried + * cpuint - The CPU interrupt associated to the IRQ + * + * Returned Value: + * The IRQ associated with such CPU interrupt or CPUINT_UNASSIGNED if + * IRQ is not yet assigned to a CPU interrupt. + * + ****************************************************************************/ + +int esp32_getirq(int cpu, int cpuint); + +/**************************************************************************** + * Name: esp32_getcpuint_from_irq + * + * Description: + * This function returns the CPU interrupt associated with an IRQ + * + * Input Parameters: + * irq - The IRQ associated with a CPU interrupt + * cpu - Pointer to store the CPU core of the CPU interrupt + * + * Returned Value: + * The CPU interrupt associated with such IRQ or IRQ_UNMAPPED if + * CPU interrupt is not mapped to an IRQ. + * + ****************************************************************************/ + +int esp32_getcpuint_from_irq(int irq, int *cpu); + +/**************************************************************************** + * Name: esp32_irq_noniram_disable + * + * Description: + * Disable interrupts that aren't specifically marked as running from IRAM + * + * Input Parameters: + * None + * + * Input Parameters: + * None + * + ****************************************************************************/ + +void esp32_irq_noniram_disable(void); + +/**************************************************************************** + * Name: esp32_irq_noniram_enable + * + * Description: + * Re-enable interrupts disabled by esp32_irq_noniram_disable + * + * Input Parameters: + * None + * + * Input Parameters: + * None + * + ****************************************************************************/ + +void esp32_irq_noniram_enable(void); + +/**************************************************************************** + * Name: esp32_irq_noniram_status + * + * Description: + * Get the current status of non-IRAM interrupts on a specific CPU core + * + * Input Parameters: + * cpu - The CPU to check the non-IRAM interrupts state + * + * Returned Value: + * true if non-IRAM interrupts are enabled, false otherwise. + * + ****************************************************************************/ + +bool esp32_irq_noniram_status(int cpu); + +/**************************************************************************** + * Name: esp32_irq_set_iram_isr + * + * Description: + * Set the ISR associated to an IRQ as a IRAM-enabled ISR. + * + * Input Parameters: + * irq - The associated IRQ to set + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +int esp32_irq_set_iram_isr(int irq); + +/**************************************************************************** + * Name: esp32_irq_unset_iram_isr + * + * Description: + * Set the ISR associated to an IRQ as a non-IRAM ISR. + * + * Input Parameters: + * irq - The associated IRQ to set + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +int esp32_irq_unset_iram_isr(int irq); + +#ifdef CONFIG_ESP32_IRAM_ISR_DEBUG + +/**************************************************************************** + * Name: esp32_get_iram_interrupt_records + * + * Description: + * This function copies the vector that keeps track of the IRQs that ran + * when non-IRAM interrupts were disabled. + * + * Input Parameters: + * + * irq_count - A previously allocated pointer to store the counter of the + * interrupts that ran when non-IRAM interrupts were disabled. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp32_get_iram_interrupt_records(uint64_t *irq_count); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/xtensa/src/esp32/esp32_spiflash.c b/arch/xtensa/src/esp32/esp32_spiflash.c index c788fdf3d3..5b5d5533af 100644 --- a/arch/xtensa/src/esp32/esp32_spiflash.c +++ b/arch/xtensa/src/esp32/esp32_spiflash.c @@ -37,9 +37,12 @@ #include <nuttx/arch.h> #include <nuttx/init.h> +#include <nuttx/kthread.h> #include <nuttx/mutex.h> #include <nuttx/mtd/mtd.h> +#include "sched/sched.h" + #include "xtensa.h" #include "xtensa_attr.h" @@ -50,11 +53,12 @@ #include "hardware/esp32_dport.h" #include "hardware/efuse_reg.h" +#include "esp32_spicache.h" #ifdef CONFIG_ESP32_SPIRAM #include "esp32_spiram.h" #endif +#include "esp32_irq.h" -#include "esp32_spicache.h" #include "esp32_spiflash.h" /**************************************************************************** @@ -181,6 +185,7 @@ struct spiflash_cachestate_s #endif irqstate_t flags; uint32_t val[CONFIG_SMP_NCPUS]; + bool sched_suspended[CONFIG_SMP_NCPUS]; }; #ifdef CONFIG_ESP32_SPI_FLASH_SUPPORT_PSRAM_STACK @@ -230,7 +235,7 @@ static inline void spi_reset_regbits(struct esp32_spiflash_s *priv, static inline void IRAM_ATTR esp32_spiflash_opstart(struct spiflash_cachestate_s *state); static inline void IRAM_ATTR -esp32_spiflash_opdone(const struct spiflash_cachestate_s *state); +esp32_spiflash_opdone(struct spiflash_cachestate_s *state); static bool IRAM_ATTR spiflash_pagecached(uint32_t phypage); static void IRAM_ATTR spiflash_flushmapped(size_t start, size_t size); @@ -346,13 +351,19 @@ static struct esp32_spiflash_s g_esp32_spiflash1_encrypt = .dummies = g_rom_spiflash_dummy_len_plus }; -/* Enxusre exculisve access to the driver */ +/* Ensure exclusive access to the driver */ static mutex_t g_lock = NXMUTEX_INITIALIZER; #ifdef CONFIG_ESP32_SPI_FLASH_SUPPORT_PSRAM_STACK static struct work_s g_work; #endif +static volatile bool g_flash_op_can_start = false; +static volatile bool g_flash_op_complete = false; +#ifdef CONFIG_SMP +static sem_t g_disable_non_iram_isr_on_core[CONFIG_SMP_NCPUS]; +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -459,7 +470,12 @@ static inline void spi_reset_regbits(struct esp32_spiflash_s *priv, static inline void IRAM_ATTR esp32_spiflash_opstart(struct spiflash_cachestate_s *state) { - state->flags = enter_critical_section(); + struct tcb_s *tcb = this_task(); + int saved_priority = tcb->sched_priority; + + /* Temporary raise schedule priority */ + + nxsched_set_priority(tcb, SCHED_PRIORITY_MAX); state->cpu = up_cpu_index(); #ifdef CONFIG_SMP @@ -467,12 +483,33 @@ esp32_spiflash_opstart(struct spiflash_cachestate_s *state) #endif DEBUGASSERT(state->cpu == 0 || state->cpu == 1); + #ifdef CONFIG_SMP DEBUGASSERT(state->other == 0 || state->other == 1); DEBUGASSERT(state->other != state->cpu); - up_cpu_pause(state->other); + if (OSINIT_OS_READY()) + { + g_flash_op_can_start = false; + + nxsem_post(&g_disable_non_iram_isr_on_core[state->other]); + + while (!g_flash_op_can_start) + { + /* Busy loop and wait for spi_flash_op_block_task to disable cache + * on the other CPU + */ + } + } #endif + state->sched_suspended[state->cpu] = true; + + sched_lock(); + + nxsched_set_priority(tcb, saved_priority); + + esp32_irq_noniram_disable(); + spi_disable_cache(state->cpu, &state->val[state->cpu]); #ifdef CONFIG_SMP spi_disable_cache(state->other, &state->val[state->other]); @@ -488,7 +525,7 @@ esp32_spiflash_opstart(struct spiflash_cachestate_s *state) ****************************************************************************/ static inline void IRAM_ATTR - esp32_spiflash_opdone(const struct spiflash_cachestate_s *state) + esp32_spiflash_opdone(struct spiflash_cachestate_s *state) { DEBUGASSERT(state->cpu == 0 || state->cpu == 1); #ifdef CONFIG_SMP @@ -499,10 +536,26 @@ static inline void IRAM_ATTR spi_enable_cache(state->cpu, state->val[state->cpu]); #ifdef CONFIG_SMP spi_enable_cache(state->other, state->val[state->other]); - up_cpu_resume(state->other); #endif - leave_critical_section(state->flags); + /* Signal to spi_flash_op_block_task that flash operation is complete */ + + g_flash_op_complete = true; + + esp32_irq_noniram_enable(); + + sched_unlock(); + + state->sched_suspended[state->cpu] = false; + +#ifdef CONFIG_SMP + while (state->sched_suspended[state->other]) + { + /* Busy loop and wait for spi_flash_op_block_task to properly finish + * and resume scheduler + */ + } +#endif } /**************************************************************************** @@ -2300,10 +2353,175 @@ static int esp32_ioctl_encrypt(struct mtd_dev_s *dev, int cmd, return ret; } +#ifdef CONFIG_SMP + +/**************************************************************************** + * Name: spi_flash_op_block_task + * + * Description: + * Disable the non-IRAM interrupts on the other core (the one that isn't + * handling the SPI flash operation) and notify that the SPI flash + * operation can start. Wait on a busy loop until it's finished and then + * reenable the non-IRAM interrups. + * + * Input Parameters: + * argc - Not used. + * argv - Not used. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned to + * indicate the nature of any failure. + * + ****************************************************************************/ + +static int spi_flash_op_block_task(int argc, char *argv[]) +{ + struct tcb_s *tcb = this_task(); + int cpu = up_cpu_index(); + + for (; ; ) + { + DEBUGASSERT((1 << cpu) & tcb->affinity); + /* Wait for a SPI flash operation to take place and this (the other + * core) being asked to disable its non-IRAM interrupts. + */ + + nxsem_wait(&g_disable_non_iram_isr_on_core[cpu]); + + sched_lock(); + + esp32_irq_noniram_disable(); + + /* g_flash_op_complete flag is cleared on *this* CPU, otherwise the + * other CPU may reset the flag back to false before this task has a + * chance to check it (if it's preempted by an ISR taking non-trivial + * amount of time). + */ + + g_flash_op_complete = false; + g_flash_op_can_start = true; + while (!g_flash_op_complete) + { + /* Busy loop here and wait for the other CPU to finish the SPI + * flash operation. + */ + } + + /* Flash operation is complete, re-enable cache */ + +#if 0 + spi_enable_cache(cpu); +#endif + + /* Restore interrupts that aren't located in IRAM */ + + esp32_irq_noniram_enable(); + + sched_unlock(); + } + + return OK; +} + +/**************************************************************************** + * Name: spiflash_init_spi_flash_op_block_task + * + * Description: + * Starts a kernel thread that waits for a semaphore indicating that a SPI + * flash operation is going to take place in the other CPU. It disables + * non-IRAM interrupts, indicates to the other core that the SPI flash + * operation can start and waits for it to be finished in a busy loop. + * + * Input Parameters: + * cpu - The CPU core that will run the created task to wait on a busy + * loop while the SPI flash operation finishes + * + * Returned Value: + * 0 (OK) on success; A negated errno value on failure. + * + ****************************************************************************/ + +int spiflash_init_spi_flash_op_block_task(int cpu) +{ + int pid; + int ret = OK; + char *argv[2]; + char arg1[32]; + cpu_set_t cpuset; + + snprintf(arg1, sizeof(arg1), "%p", &cpu); + argv[0] = arg1; + argv[1] = NULL; + + pid = kthread_create("spiflash_op", + SCHED_PRIORITY_MAX, + CONFIG_ESP32_SPIFLASH_OP_TASK_STACKSIZE, + spi_flash_op_block_task, + argv); + if (pid > 0) + { + if (cpu < CONFIG_SMP_NCPUS) + { + CPU_ZERO(&cpuset); + CPU_SET(cpu, &cpuset); + ret = nxsched_set_affinity(pid, sizeof(cpuset), &cpuset); + if (ret < 0) + { + return ret; + } + } + } + else + { + return -EPERM; + } + + return ret; +} +#endif /* CONFIG_SMP */ + /**************************************************************************** * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: esp32_spiflash_init + * + * Description: + * Initialize ESP32 SPI flash driver. + * + * Returned Value: + * OK if success or a negative value if fail. + * + ****************************************************************************/ + +int esp32_spiflash_init(void) +{ + int cpu; + int ret = OK; + +#ifdef CONFIG_SMP + sched_lock(); + + for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++) + { + nxsem_init(&g_disable_non_iram_isr_on_core[cpu], 0, 0); + + ret = spiflash_init_spi_flash_op_block_task(cpu); + if (ret != OK) + { + return ret; + } + } + + sched_unlock(); +#else + UNUSED(cpu); +#endif + + return ret; +} + /**************************************************************************** * Name: esp32_spiflash_alloc_mtdpart * diff --git a/arch/xtensa/src/esp32/esp32_spiflash.h b/arch/xtensa/src/esp32/esp32_spiflash.h index a2eb5f5ffa..be8c452639 100644 --- a/arch/xtensa/src/esp32/esp32_spiflash.h +++ b/arch/xtensa/src/esp32/esp32_spiflash.h @@ -48,6 +48,19 @@ extern "C" * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: esp32_spiflash_init + * + * Description: + * Initialize ESP32 SPI flash driver. + * + * Returned Value: + * OK if success or a negative value if fail. + * + ****************************************************************************/ + +int esp32_spiflash_init(void); + /**************************************************************************** * Name: esp32_spiflash_alloc_mtdpart * diff --git a/arch/xtensa/src/esp32/hardware/esp32_soc.h b/arch/xtensa/src/esp32/hardware/esp32_soc.h index ff4f9da8a0..1128e4a49c 100644 --- a/arch/xtensa/src/esp32/hardware/esp32_soc.h +++ b/arch/xtensa/src/esp32/hardware/esp32_soc.h @@ -840,6 +840,25 @@ static inline bool IRAM_ATTR esp32_ptr_extram(const void *p) (intptr_t)p < SOC_EXTRAM_DATA_HIGH); } +/**************************************************************************** + * Name: esp32_ptr_iram + * + * Description: + * Check if the pointer is in IRAM + * + * Parameters: + * p - Pointer to the address being checked. + * + * Return Value: + * True if the address is a member of the internal memory. False if not. + * + ****************************************************************************/ + +static inline bool IRAM_ATTR esp32_ptr_iram(const void *p) +{ + return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH); +} + /**************************************************************************** * Name: esp32_ptr_exec * diff --git a/boards/xtensa/esp32/common/include/esp32_board_spiflash.h b/boards/xtensa/esp32/common/include/esp32_board_spiflash.h index 0dd4257572..273cfe8230 100644 --- a/boards/xtensa/esp32/common/include/esp32_board_spiflash.h +++ b/boards/xtensa/esp32/common/include/esp32_board_spiflash.h @@ -43,7 +43,7 @@ extern "C" ****************************************************************************/ /**************************************************************************** - * Name: esp32_spiflash_init + * Name: board_spiflash_init * * Description: * Initialize the SPI Flash and register the MTD. @@ -57,7 +57,7 @@ extern "C" * ****************************************************************************/ -int esp32_spiflash_init(void); +int board_spiflash_init(void); #undef EXTERN #if defined(__cplusplus) diff --git a/boards/xtensa/esp32/common/scripts/legacy_sections.ld b/boards/xtensa/esp32/common/scripts/legacy_sections.ld index 49d99a7222..80eefe19b8 100644 --- a/boards/xtensa/esp32/common/scripts/legacy_sections.ld +++ b/boards/xtensa/esp32/common/scripts/legacy_sections.ld @@ -76,18 +76,26 @@ SECTIONS #ifdef CONFIG_STACK_CANARIES *libc.a:lib_stackchk.*(.literal .text .literal.* .text.*) #endif + *libarch.a:esp32_cpuindex.*(.literal .text .literal.* .text.*) + *libarch.a:esp32_irq.*(.literal .text .literal.* .text.*) *libarch.a:esp32_spiflash.*(.literal .text .literal.* .text.*) + *libarch.a:xtensa_assert.*(.literal .text .literal.* .text.*) + *libarch.a:xtensa_cpuint.*(.literal .text .literal.* .text.*) *libarch.a:xtensa_cpupause.*(.literal .text .literal.* .text.*) - *libarch.a:xtensa_copystate.*(.literal .text .literal.* .text.*) - *libarch.a:xtensa_interruptcontext.*(.literal .text .literal.* .text.*) + *libarch.a:xtensa_irqdispatch.*(.literal .text .literal.* .text.*) + *libarch.a:xtensa_modifyreg32.*(.literal .text .literal.* .text.*) *libarch.a:xtensa_testset.*(.literal .text .literal.* .text.*) - *libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*) + *libdrivers.a:syslog_flush.*(.literal .text .literal.* .text.*) + + *libsched.a:assert.*(.literal .text .literal.* .text.*) + *libsched.a:irq_csection.*(.literal .text .literal.* .text.*) + *libsched.a:irq_dispatch.*(.literal .text .literal.* .text.*) + *libsched.a:irq_spinlock.*(.literal .text .literal.* .text.*) *libsched.a:sched_note.*(.literal .text .literal.* .text.*) + *libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*) *libsched.a:sched_thistask.*(.literal .text .literal.* .text.*) *libsched.a:spinlock.*(.literal .text .literal.* .text.*) - *libsched.a:irq_csection.*(.literal .text .literal.* .text.*) - *libsched.a:irq_dispatch.*(.literal .text .literal.* .text.*) *(.wifirxiram .wifirxiram.*) *(.wifi0iram .wifi0iram.*) diff --git a/boards/xtensa/esp32/common/src/esp32_board_spiflash.c b/boards/xtensa/esp32/common/src/esp32_board_spiflash.c index 56717bf1d2..026733b444 100644 --- a/boards/xtensa/esp32/common/src/esp32_board_spiflash.c +++ b/boards/xtensa/esp32/common/src/esp32_board_spiflash.c @@ -427,7 +427,7 @@ static int init_storage_partition(void) ****************************************************************************/ /**************************************************************************** - * Name: esp32_spiflash_init + * Name: board_spiflash_init * * Description: * Initialize the SPI Flash and register the MTD. @@ -441,10 +441,16 @@ static int init_storage_partition(void) * ****************************************************************************/ -int esp32_spiflash_init(void) +int board_spiflash_init(void) { int ret = OK; + ret = esp32_spiflash_init(); + if (ret < 0) + { + return ret; + } + #ifdef CONFIG_ESP32_HAVE_OTA_PARTITION ret = init_ota_partitions(); if (ret < 0) diff --git a/boards/xtensa/esp32/esp32-audio-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-audio-kit/src/esp32_bringup.c index 049c3e5bda..d876870d83 100644 --- a/boards/xtensa/esp32/esp32-audio-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-audio-kit/src/esp32_bringup.c @@ -184,7 +184,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/ble/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/ble/defconfig index b09264fa44..1db421a79a 100644 --- a/boards/xtensa/esp32/esp32-devkitc/configs/ble/defconfig +++ b/boards/xtensa/esp32/esp32-devkitc/configs/ble/defconfig @@ -6,7 +6,6 @@ # modifications. # # CONFIG_ARCH_LEDS is not set -# CONFIG_NDEBUG is not set # CONFIG_NSH_ARGCAT is not set # CONFIG_NSH_CMDOPT_HEXDUMP is not set CONFIG_ALLOW_BSD_COMPONENTS=y @@ -20,13 +19,18 @@ CONFIG_ARCH_CHIP_ESP32WROVER=y CONFIG_ARCH_INTERRUPTSTACK=2048 CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_XTENSA=y +CONFIG_BCH=y CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BTSAK=y CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_FEATURES=y CONFIG_DRIVERS_BLUETOOTH=y CONFIG_DRIVERS_IEEE80211=y CONFIG_DRIVERS_WIRELESS=y CONFIG_ESP32_BLE=y +CONFIG_ESP32_IRAM_ISR_DEBUG=y +CONFIG_ESP32_SPIFLASH=y CONFIG_ESP32_UART0=y CONFIG_FS_PROCFS=y CONFIG_HAVE_CXX=y @@ -35,6 +39,7 @@ CONFIG_IDLETHREAD_STACKSIZE=3072 CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INTELHEX_BINARY=y CONFIG_MM_REGIONS=3 +CONFIG_MTD_PARTITION_NAMES=y CONFIG_NETDEV_LATEINIT=y CONFIG_NET_BLUETOOTH=y CONFIG_NET_SOCKOPTS=y diff --git a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c index 22e9a2327c..ec2f5b24f2 100644 --- a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c @@ -255,7 +255,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c index ea3b76f084..10fba05b17 100644 --- a/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c @@ -144,7 +144,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/esp32-lyrat/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-lyrat/src/esp32_bringup.c index bb64a15644..eeb39598fa 100644 --- a/boards/xtensa/esp32/esp32-lyrat/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-lyrat/src/esp32_bringup.c @@ -184,7 +184,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/esp32-pico-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-pico-kit/src/esp32_bringup.c index 9e72264bfb..95974cdf28 100644 --- a/boards/xtensa/esp32/esp32-pico-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-pico-kit/src/esp32_bringup.c @@ -185,7 +185,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/esp32-sparrow-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-sparrow-kit/src/esp32_bringup.c index 35a21fdb90..3665696ccb 100644 --- a/boards/xtensa/esp32/esp32-sparrow-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-sparrow-kit/src/esp32_bringup.c @@ -190,7 +190,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c index a8dfc1dbd5..b5261dc59c 100644 --- a/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c @@ -178,7 +178,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_bringup.c b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_bringup.c index d1b197c142..14903d2dfe 100644 --- a/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_bringup.c +++ b/boards/xtensa/esp32/lilygo_tbeam_lora_gps/src/esp32_bringup.c @@ -174,7 +174,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/ttgo_eink5_v2/src/esp32_bringup.c b/boards/xtensa/esp32/ttgo_eink5_v2/src/esp32_bringup.c index 4b79f7a291..845cfd103c 100644 --- a/boards/xtensa/esp32/ttgo_eink5_v2/src/esp32_bringup.c +++ b/boards/xtensa/esp32/ttgo_eink5_v2/src/esp32_bringup.c @@ -231,7 +231,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/ttgo_lora_esp32/src/esp32_bringup.c b/boards/xtensa/esp32/ttgo_lora_esp32/src/esp32_bringup.c index 99cbd4e6d9..f571529062 100644 --- a/boards/xtensa/esp32/ttgo_lora_esp32/src/esp32_bringup.c +++ b/boards/xtensa/esp32/ttgo_lora_esp32/src/esp32_bringup.c @@ -174,7 +174,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); diff --git a/boards/xtensa/esp32/ttgo_t_display_esp32/src/esp32_bringup.c b/boards/xtensa/esp32/ttgo_t_display_esp32/src/esp32_bringup.c index b002b928f7..9e054b7682 100644 --- a/boards/xtensa/esp32/ttgo_t_display_esp32/src/esp32_bringup.c +++ b/boards/xtensa/esp32/ttgo_t_display_esp32/src/esp32_bringup.c @@ -234,7 +234,7 @@ int esp32_bringup(void) #endif #ifdef CONFIG_ESP32_SPIFLASH - ret = esp32_spiflash_init(); + ret = board_spiflash_init(); if (ret) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n");
