esp32/ble: enable the BLE interrupt during a SPI flash operation

This commit sets the BLE's interrupt as a IRAM-enabled interrupt,
which enables it to run during a SPI flash operation. This enables
us to create a cache to off-load semaphores and message queues
operations and treat them when the SPI flash operation is finished.
By doing that, we avoid packet losses during a SPI flash operation.
This commit is contained in:
Tiago Medicci Serrano 2023-10-11 16:10:07 -03:00 committed by Xiang Xiao
parent f94daf09b2
commit 18718316dc
9 changed files with 672 additions and 40 deletions

View File

@ -198,6 +198,15 @@ config ESP32_RUN_IRAM
This loads all of NuttX inside IRAM. Used to test somewhat small
images that can fit entirely in IRAM.
config ESP32_EXCEPTION_ENABLE_CACHE
bool
default y
depends on ESP32_SPIFLASH
---help---
When an exception triggers, the panic function reenables the SPI Flash
cache to allow functions that are located in SPI Flash to run.
Disable this option to save IRAM space.
menu "ESP32 Peripheral Selection"
config ESP32_UART

View File

@ -50,12 +50,15 @@
#include <irq/irq.h>
#include "hardware/esp32_dport.h"
#include "hardware/wdev_reg.h"
#include "espidf_wifi.h"
#include "xtensa.h"
#include "xtensa_attr.h"
#include "esp32_rt_timer.h"
#include "esp32_ble_adapter.h"
#include "esp32_wireless.h"
#include "esp32_irq.h"
#include "esp32_spicache.h"
#ifdef CONFIG_ESP32_WIFI_BT_COEXIST
# include "esp_coexist_internal.h"
@ -104,6 +107,11 @@ do {\
#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20200622
#ifdef CONFIG_ESP32_SPIFLASH
# define BLE_TASK_EVENT_QUEUE_ITEM_SIZE 8
# define BLE_TASK_EVENT_QUEUE_LEN 8
#endif
#ifdef CONFIG_ESP32_BLE_INTERRUPT_SAVE_STATUS
# define NR_IRQSTATE_FLAGS CONFIG_ESP32_BLE_INTERRUPT_SAVE_STATUS
#else
@ -176,6 +184,16 @@ typedef enum
} btdm_wakeup_src_t;
#endif
/* Superseded semaphore definition */
struct bt_sem_s
{
sem_t sem;
#ifdef CONFIG_ESP32_SPIFLASH
struct esp_semcache_s sc;
#endif
};
typedef enum
{
PERIPH_LEDC_MODULE = 0,
@ -521,6 +539,13 @@ static sq_queue_t g_int_flags_used;
static struct irqstate_list_s g_int_flags[NR_IRQSTATE_FLAGS];
/* Cached queue control variables */
#ifdef CONFIG_ESP32_SPIFLASH
static struct esp_queuecache_s g_esp_queuecache[BLE_TASK_EVENT_QUEUE_LEN];
static uint8_t g_esp_queuecache_buffer[BLE_TASK_EVENT_QUEUE_ITEM_SIZE];
#endif
/****************************************************************************
* Public Data
****************************************************************************/
@ -860,7 +885,7 @@ static xt_handler esp_ble_set_isr(int n, xt_handler f, void *arg)
int ret;
uint32_t tmp;
struct irq_adpt_s *adapter;
int irq = n + XTENSA_IRQ_FIRSTPERIPH;
int irq = esp32_getirq(0, n);
wlinfo("n=%d f=%p arg=%p irq=%d\n", n, f, arg, irq);
@ -877,7 +902,7 @@ static xt_handler esp_ble_set_isr(int n, xt_handler f, void *arg)
if (!adapter)
{
wlerr("Failed to alloc %d memory\n", tmp);
assert(0);
DEBUGPANIC();
return NULL;
}
@ -888,7 +913,7 @@ static xt_handler esp_ble_set_isr(int n, xt_handler f, void *arg)
if (ret)
{
wlerr("Failed to attach IRQ %d\n", irq);
assert(0);
DEBUGPANIC();
return NULL;
}
@ -912,17 +937,21 @@ static xt_handler esp_ble_set_isr(int n, xt_handler f, void *arg)
static void esp32_ints_on(uint32_t mask)
{
uint32_t bit;
int irq;
for (int i = 0; i < 32; i++)
{
bit = 1 << i;
if (bit & mask)
{
int irq = i + XTENSA_IRQ_FIRSTPERIPH;
wlinfo("Enabled bit %d\n", irq);
irq = esp32_getirq(0, i);
DEBUGVERIFY(esp32_irq_set_iram_isr(irq));
up_enable_irq(irq);
wlinfo("Enabled bit %d\n", irq);
}
}
UNUSED(irq);
}
/****************************************************************************
@ -1081,7 +1110,7 @@ static void bt_periph_module_enable(periph_module_e periph)
*
****************************************************************************/
static int esp_int_adpt_cb(int irq, void *context, void *arg)
static int IRAM_ATTR esp_int_adpt_cb(int irq, void *context, void *arg)
{
struct irq_adpt_s *adapter = (struct irq_adpt_s *)arg;
@ -1182,26 +1211,32 @@ 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);
if (!sem)
tmp = sizeof(struct bt_sem_s);
bt_sem = kmm_malloc(tmp);
DEBUGASSERT(bt_sem);
if (!bt_sem)
{
wlerr("ERROR: Failed to alloc %d memory\n", tmp);
return NULL;
}
ret = nxsem_init(sem, 0, init);
ret = nxsem_init(&bt_sem->sem, 0, init);
DEBUGASSERT(ret == OK);
if (ret)
{
wlerr("ERROR: Failed to initialize sem error=%d\n", ret);
kmm_free(sem);
kmm_free(bt_sem);
return NULL;
}
return sem;
#ifdef CONFIG_ESP32_SPIFLASH
esp_init_semcache(&bt_sem->sc, &bt_sem->sem);
#endif
return bt_sem;
}
/****************************************************************************
@ -1220,9 +1255,9 @@ static void *semphr_create_wrapper(uint32_t max, uint32_t init)
static void semphr_delete_wrapper(void *semphr)
{
sem_t *sem = (sem_t *)semphr;
nxsem_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);
}
/****************************************************************************
@ -1244,7 +1279,8 @@ static int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw)
{
*(int *)hptw = 0;
return esp_errno_trans(nxsem_trywait(semphr));
DEBUGPANIC();
return 0;
}
/****************************************************************************
@ -1263,7 +1299,24 @@ 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_ESP32_SPIFLASH
if (spi_flash_cache_enabled())
{
ret = semphr_give_wrapper(bt_sem);
}
else
{
esp_post_semcache(&bt_sem->sc);
ret = 0;
}
#else
ret = semphr_give_wrapper(bt_sem);
#endif
return esp_errno_trans(ret);
}
/****************************************************************************
@ -1314,21 +1367,21 @@ static void esp_update_time(struct timespec *timespec, uint32_t ticks)
static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms)
{
int ret;
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 = nxsem_wait(sem);
ret = nxsem_wait(&bt_sem->sem);
}
else
{
if (block_time_ms > 0)
{
ret = nxsem_tickwait(sem, MSEC2TICK(block_time_ms));
ret = nxsem_tickwait(&bt_sem->sem, MSEC2TICK(block_time_ms));
}
else
{
ret = nxsem_trywait(sem);
ret = nxsem_trywait(&bt_sem->sem);
}
}
@ -1358,9 +1411,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 = nxsem_post(sem);
ret = nxsem_post(&bt_sem->sem);
if (ret)
{
wlerr("Failed to post sem error=%d\n", ret);
@ -1495,13 +1548,21 @@ static int mutex_unlock_wrapper(void *mutex)
*
****************************************************************************/
static int32_t esp_queue_send_generic(void *queue, void *item,
uint32_t ticks, int prio)
static IRAM_ATTR int32_t esp_queue_send_generic(void *queue, void *item,
uint32_t ticks, int prio)
{
int ret;
struct timespec timeout;
struct mq_adpt_s *mq_adpt = (struct mq_adpt_s *)queue;
#ifdef CONFIG_ESP32_SPIFLASH
if (!spi_flash_cache_enabled())
{
esp_send_queuecache(queue, item, mq_adpt->msgsize);
return esp_errno_trans(OK);
}
#endif
if (ticks == OSI_FUNCS_TIME_BLOCKING || ticks == 0)
{
/**
@ -1587,6 +1648,7 @@ static int IRAM_ATTR queue_recv_from_isr_wrapper(void *queue,
void *item,
void *hptw)
{
DEBUGPANIC();
return 0;
}
@ -1803,7 +1865,7 @@ static void IRAM_ATTR srand_wrapper(unsigned int seed)
static int IRAM_ATTR rand_wrapper(void)
{
return random();
return getreg32(WDEV_RND_REG);
}
/****************************************************************************
@ -2234,6 +2296,26 @@ static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size)
}
mq_adpt->msgsize = item_size;
#ifdef CONFIG_ESP32_SPIFLASH
if (queue_len <= BLE_TASK_EVENT_QUEUE_LEN &&
item_size == BLE_TASK_EVENT_QUEUE_ITEM_SIZE)
{
esp_init_queuecache(g_esp_queuecache,
&mq_adpt->mq,
g_esp_queuecache_buffer,
BLE_TASK_EVENT_QUEUE_LEN,
BLE_TASK_EVENT_QUEUE_ITEM_SIZE);
}
else
{
wlerr("Failed to create queue cache."
" Please incresase BLE_TASK_EVENT_QUEUE_LEN to, at least, %d",
queue_len);
return NULL;
}
#endif
return (void *)mq_adpt;
}
@ -2420,6 +2502,13 @@ int esp32_bt_controller_init(void)
return ERROR;
}
#ifdef CONFIG_ESP32_SPIFLASH
if (esp_wireless_init() != OK)
{
return -EIO;
}
#endif
if (btdm_osi_funcs_register(&g_osi_funcs) != 0)
{
wlerr("Error, probably invalid OSI Functions\n");
@ -2915,7 +3004,7 @@ int esp32_vhci_register_callback(const esp_vhci_host_callback_t *callback)
return ret;
}
int coex_bt_request_wrapper(uint32_t event,
int IRAM_ATTR coex_bt_request_wrapper(uint32_t event,
uint32_t latency,
uint32_t duration)
{
@ -2926,7 +3015,7 @@ int coex_bt_request_wrapper(uint32_t event,
#endif
}
int coex_bt_release_wrapper(uint32_t event)
int IRAM_ATTR coex_bt_release_wrapper(uint32_t event)
{
#if defined(CONFIG_ESP32_WIFI_BT_COEXIST)
return coex_bt_release(event);
@ -2935,7 +3024,7 @@ int coex_bt_release_wrapper(uint32_t event)
#endif
}
uint32_t coex_bb_reset_lock_wrapper(void)
uint32_t IRAM_ATTR coex_bb_reset_lock_wrapper(void)
{
#if defined(CONFIG_ESP32_WIFI_BT_COEXIST)
return coex_bb_reset_lock();
@ -2944,7 +3033,7 @@ uint32_t coex_bb_reset_lock_wrapper(void)
#endif
}
void coex_bb_reset_unlock_wrapper(uint32_t restore)
void IRAM_ATTR coex_bb_reset_unlock_wrapper(uint32_t restore)
{
#if defined(CONFIG_ESP32_WIFI_BT_COEXIST)
coex_bb_reset_unlock(restore);

View File

@ -147,4 +147,31 @@ void IRAM_ATTR spi_enable_cache(int cpu)
putreg32(regval, ctrl1reg);
}
/****************************************************************************
* Name: spi_flash_cache_enabled
*
* Description:
* Check at runtime if flash cache is enabled on both CPUs.
*
* Returned Value:
* True if both CPUs have flash cache enabled, false otherwise.
*
****************************************************************************/
bool spi_flash_cache_enabled(void)
{
bool result = false;
if (((getreg32(DPORT_PRO_CACHE_CTRL_REG) & DPORT_PRO_CACHE_ENABLE) != 0)
#ifdef CONFIG_SMP
&& ((getreg32(DPORT_APP_CACHE_CTRL_REG) & DPORT_APP_CACHE_ENABLE) != 0)
#endif
)
{
result = true;
}
return result;
}
#endif /* CONFIG_ESP32_SPICACHE */

View File

@ -81,6 +81,19 @@ void spi_disable_cache(int cpu);
void spi_enable_cache(int cpu);
/****************************************************************************
* Name: spi_flash_cache_enabled
*
* Description:
* Check at runtime if flash cache is enabled on both CPUs.
*
* Returned Value:
* True if both CPUs have flash cache enabled, false otherwise.
*
****************************************************************************/
bool spi_flash_cache_enabled(void);
#ifdef __cplusplus
}
#endif

View File

@ -33,6 +33,7 @@
#include <debug.h>
#include "xtensa.h"
#include "esp32_spicache.h"
/****************************************************************************
* Public Data
@ -323,6 +324,17 @@ static void advance_pc(uint32_t *regs, int diff)
uint32_t *xtensa_user(int exccause, uint32_t *regs)
{
#ifdef CONFIG_ESP32_EXCEPTION_ENABLE_CACHE
if (!spi_flash_cache_enabled())
{
spi_enable_cache(0);
#ifdef CONFIG_SMP
spi_enable_cache(1);
#endif
_err("\nERROR: Cache was disabled and re-enabled\n");
}
#endif
#ifdef CONFIG_ARCH_USE_TEXT_HEAP
/* Emulate byte access for module text.
*

View File

@ -24,20 +24,25 @@
#include <nuttx/config.h>
#include <nuttx/kmalloc.h>
#include <nuttx/mqueue.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <debug.h>
#include <assert.h>
#include "xtensa.h"
#include "hardware/esp32_soc.h"
#include "hardware/esp32_dport.h"
#include "hardware/esp32_emac.h"
#include "esp32_wireless.h"
#include "hardware/esp32_soc.h"
#include "esp32_irq.h"
#include "esp32_partition.h"
#include "esp_phy_init.h"
#include "phy_init_data.h"
#include "esp32_wireless.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -48,6 +53,28 @@
# define MAC_ADDR_UNIVERSE_BT_OFFSET 1
#endif
/* Software Interrupt */
#define SWI_IRQ ESP32_IRQ_CPU_CPU2
#define SWI_PERIPH ESP32_PERIPH_CPU_CPU2
/****************************************************************************
* Private Types
****************************************************************************/
/* Wireless Private Data */
struct esp_wireless_priv_s
{
volatile int ref; /* Reference count */
int cpuint; /* CPU interrupt assigned to SWI */
struct list_node sc_list; /* Semaphore cache list */
struct list_node qc_list; /* Queue cache list */
struct list_node qc_freelist; /* List of free queue cache structures */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -165,6 +192,10 @@ static phy_country_to_bin_type_t g_country_code_map_type_table[] =
#endif
/* Private data of the wireless common interface */
static struct esp_wireless_priv_s g_esp_wireless_priv;
/****************************************************************************
* Private Functions
****************************************************************************/
@ -206,6 +237,68 @@ static inline void phy_digital_regs_load(void)
}
}
/****************************************************************************
* Name: esp_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 esp_swi_irq(int irq, void *context, void *arg)
{
int i;
int ret;
struct esp_semcache_s *sc;
struct esp_semcache_s *sc_tmp;
struct esp_queuecache_s *qc_entry;
struct esp_queuecache_s *qc_tmp;
struct esp_wireless_priv_s *priv = &g_esp_wireless_priv;
modifyreg32(DPORT_CPU_INTR_FROM_CPU_2_REG, DPORT_CPU_INTR_FROM_CPU_2, 0);
list_for_every_entry_safe(&priv->sc_list, sc, sc_tmp,
struct esp_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);
}
list_for_every_entry_safe(&priv->qc_list, qc_entry, qc_tmp,
struct esp_queuecache_s, node)
{
ret = file_mq_send(qc_entry->mq_ptr, (const char *)qc_entry->buffer,
qc_entry->size, 0);
if (ret < 0)
{
wlerr("ERROR: Failed to send queue ret=%d\n", ret);
}
list_delete(&qc_entry->node);
list_add_tail(&priv->qc_freelist, &qc_entry->node);
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -754,7 +847,7 @@ const esp_phy_init_data_t *esp_phy_get_init_data(void)
kmm_free(init_data_store);
return NULL;
}
#else /* CONFIG_ESP32_PHY_DEFAULT_INIT_IF_INVALID */
#else /* CONFIG_ESP32_PHY_DEFAULT_INIT_IF_INVALID */
wlerr("ERROR: Failed to validate PHY data partition\n");
kmm_free(init_data_store);
return NULL;
@ -797,7 +890,7 @@ void esp_phy_release_init_data(const esp_phy_init_data_t *init_data)
kmm_free((uint8_t *)init_data - sizeof(phy_init_magic_pre));
}
#else /* CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION */
#else /* CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION */
/****************************************************************************
* Name: esp_phy_get_init_data
@ -1067,3 +1160,240 @@ void esp32_phy_enable(void)
leave_critical_section(flags);
kmm_free(cal_data);
}
/****************************************************************************
* Name: esp_init_semcache
*
* Description:
* Initialize semaphore cache.
*
* Parameters:
* sc - Semaphore cache data pointer
* sem - Semaphore data pointer
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_init_semcache(struct esp_semcache_s *sc, sem_t *sem)
{
sc->sem = sem;
sc->count = 0;
list_initialize(&sc->node);
}
/****************************************************************************
* Name: esp_post_semcache
*
* Description:
* Store posting semaphore action into semaphore cache.
*
* Parameters:
* sc - Semaphore cache data pointer
*
* Returned Value:
* None.
*
****************************************************************************/
IRAM_ATTR void esp_post_semcache(struct esp_semcache_s *sc)
{
struct esp_wireless_priv_s *priv = &g_esp_wireless_priv;
if (!sc->count)
{
list_add_tail(&priv->sc_list, &sc->node);
}
sc->count++;
/* Enable CPU 2 interrupt. This will generate an IRQ as soon as non-IRAM
* are (re)enabled.
*/
modifyreg32(DPORT_CPU_INTR_FROM_CPU_2_REG, 0, DPORT_CPU_INTR_FROM_CPU_2);
}
/****************************************************************************
* Name: esp_init_queuecache
*
* Description:
* Initialize queue cache.
*
* Parameters:
* qc - Queue cache data pointer
* mq_ptr - Queue data pointer
* buffer - Queue cache buffer pointer
* len - Queue cache max length
* size - Queue cache buffer size
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_init_queuecache(struct esp_queuecache_s *qc,
struct file *mq_ptr,
uint8_t *buffer,
size_t len,
size_t size)
{
struct esp_wireless_priv_s *priv = &g_esp_wireless_priv;
int i;
for (i = 0; i < len; i++)
{
qc[i].mq_ptr = mq_ptr;
qc[i].size = size;
qc[i].buffer = buffer;
list_initialize(&qc[i].node);
list_add_tail(&priv->qc_freelist, &qc[i].node);
}
}
/****************************************************************************
* Name: esp_send_queuecache
*
* Description:
* Store posting queue action and data into queue cache.
*
* Parameters:
* qc - Queue cache data pointer
* buffer - Data buffer
* size - Buffer size
*
* Returned Value:
* None.
*
****************************************************************************/
IRAM_ATTR void esp_send_queuecache(void *queue, uint8_t *buffer, int size)
{
struct esp_wireless_priv_s *priv = &g_esp_wireless_priv;
struct esp_queuecache_s *msg;
irqstate_t flags;
flags = enter_critical_section();
msg = (struct esp_queuecache_s *)list_remove_head(&priv->qc_freelist);
DEBUGASSERT(msg != NULL);
DEBUGASSERT(msg->size == size);
DEBUGASSERT(msg->mq_ptr == queue);
memcpy(msg->buffer, buffer, size);
list_add_tail(&priv->qc_list, &msg->node);
leave_critical_section(flags);
/* Enable CPU 2 interrupt. This will generate an IRQ as soon as non-IRAM
* are (re)enabled.
*/
modifyreg32(DPORT_CPU_INTR_FROM_CPU_2_REG, 0, DPORT_CPU_INTR_FROM_CPU_2);
}
/****************************************************************************
* Name: esp_wireless_init
*
* Description:
* Initialize ESP32 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 esp_wireless_init(void)
{
int ret;
irqstate_t flags;
struct esp_wireless_priv_s *priv = &g_esp_wireless_priv;
flags = enter_critical_section();
if (priv->ref != 0)
{
priv->ref++;
leave_critical_section(flags);
return OK;
}
priv->cpuint = esp32_setup_irq(0, SWI_PERIPH, 1, ESP32_CPUINT_LEVEL);
if (priv->cpuint < 0)
{
/* Failed to allocate a CPU interrupt of this type. */
wlerr("ERROR: Failed to attach IRQ ret=%d\n", ret);
ret = priv->cpuint;
leave_critical_section(flags);
return ret;
}
ret = irq_attach(SWI_IRQ, esp_swi_irq, NULL);
if (ret < 0)
{
esp32_teardown_irq(0, SWI_PERIPH, priv->cpuint);
leave_critical_section(flags);
wlerr("ERROR: Failed to attach IRQ ret=%d\n", ret);
return ret;
}
list_initialize(&priv->sc_list);
list_initialize(&priv->qc_list);
list_initialize(&priv->qc_freelist);
up_enable_irq(SWI_IRQ);
priv->ref++;
leave_critical_section(flags);
return OK;
}
/****************************************************************************
* Name: esp_wireless_deinit
*
* Description:
* De-initialize ESP32 wireless common components.
*
* Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success. A negated errno value is returned on
* failure.
*
****************************************************************************/
int esp_wireless_deinit(void)
{
irqstate_t flags;
struct esp_wireless_priv_s *priv = &g_esp_wireless_priv;
flags = enter_critical_section();
if (priv->ref > 0)
{
priv->ref--;
if (priv->ref == 0)
{
up_disable_irq(SWI_IRQ);
irq_detach(SWI_IRQ);
esp32_teardown_irq(0, SWI_PERIPH, priv->cpuint);
}
}
leave_critical_section(flags);
return OK;
}

View File

@ -24,8 +24,12 @@
/****************************************************************************
* Included Files
****************************************************************************/
#include <semaphore.h>
#include <stdbool.h>
#include <stdint.h>
#include <nuttx/config.h>
#include <nuttx/list.h>
#include "xtensa_attr.h"
@ -48,6 +52,31 @@
#define MAC_LEN (6)
/****************************************************************************
* Public Types
****************************************************************************/
/* Semaphore Cache Data */
struct esp_semcache_s
{
struct list_node node;
sem_t *sem;
uint32_t count;
};
/* Queue Cache Data */
struct esp_queuecache_s
{
struct list_node node;
struct file *mq_ptr;
size_t size;
uint8_t *buffer;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@ -217,4 +246,113 @@ int phy_printf(const char *format, ...) printf_like(1, 2);
int esp32_phy_update_country_info(const char *country);
/****************************************************************************
* Name: esp_init_semcache
*
* Description:
* Initialize semaphore cache.
*
* Parameters:
* sc - Semaphore cache data pointer
* sem - Semaphore data pointer
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_init_semcache(struct esp_semcache_s *sc, sem_t *sem);
/****************************************************************************
* Name: esp_post_semcache
*
* Description:
* Store posting semaphore action into semaphore cache.
*
* Parameters:
* sc - Semaphore cache data pointer
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_post_semcache(struct esp_semcache_s *sc);
/****************************************************************************
* Name: esp_init_queuecache
*
* Description:
* Initialize queue cache.
*
* Parameters:
* qc - Queue cache data pointer
* mq_ptr - Queue data pointer
* buffer - Queue cache buffer pointer
* len - Queue cache max length
* size - Queue cache buffer size
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_init_queuecache(struct esp_queuecache_s *qc,
struct file *mq_ptr,
uint8_t *buffer,
size_t len,
size_t size);
/****************************************************************************
* Name: esp32_wl_send_queuecache
*
* Description:
* Store posting queue action and data into queue cache.
*
* Parameters:
* queue - Pointer to the queue
* buffer - Data buffer
* size - Buffer size
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_send_queuecache(void *queue, uint8_t *buffer, int size);
/****************************************************************************
* Name: esp_wireless_init
*
* Description:
* Initialize ESP32 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 esp_wireless_init(void);
/****************************************************************************
* Name: esp_wireless_deinit
*
* Description:
* De-initialize ESP32 wireless common components.
*
* Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success. A negated errno value is returned on
* failure.
*
****************************************************************************/
int esp_wireless_deinit(void);
#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_WIRELESS_H */

View File

@ -80,22 +80,34 @@ SECTIONS
*libarch.a:esp32_irq.*(.literal .text .literal.* .text.*)
*libarch.a:esp32_spicache.*(.literal .text .literal.* .text.*)
*libarch.a:esp32_spiflash.*(.literal .text .literal.* .text.*)
*libarch.a:esp32_user.*(.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_irqdispatch.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_modifyreg32.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_saveusercontext.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_testset.*(.literal .text .literal.* .text.*)
*libc.a:lib_assert.*(.literal .text .literal.* .text.*)
*libc.a:lib_utsname.*(.literal .text .literal.* .text.*)
#ifdef CONFIG_ESP32_BLE
*libc.a:sq_remlast.*(.literal .text .literal.* .text.*)
#endif
*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:panic_notifier.*(.literal.panic_notifier_call_chain .text.panic_notifier_call_chain)
*libsched.a:sched_gettcb.*(.literal .text .literal.* .text.*)
*libsched.a:sched_lock.*(.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:sched_unlock.*(.literal .text .literal.* .text.*)
*libsched.a:spinlock.*(.literal .text .literal.* .text.*)
*(.wifirxiram .wifirxiram.*)
@ -204,11 +216,13 @@ SECTIONS
*libc.a:lib_stackchk.*(.rodata .rodata.*)
#endif
*libarch.a:esp32_spiflash.*(.rodata .rodata.*)
*libarch.a:xtensa_cpupause.*(.rodata .rodata.*)
*libarch.a:xtensa_context.*(.rodata .rodata.*)
*libarch.a:xtensa_copystate.*(.rodata .rodata.*)
*libarch.a:xtensa_interruptcontext.*(.rodata .rodata.*)
*libarch.a:xtensa_cpupause.*(.rodata .rodata.*)
*libarch.a:xtensa_testset.*(.rodata .rodata.*)
*libdrivers.a:syslog_channel.*(.rodata .rodata.*)
*libsched.a:sched_suspendscheduler.*(.rodata .rodata.*)
*libsched.a:sched_thistask.*(.rodata .rodata.*)
*libsched.a:sched_note.*(.rodata .rodata.*)

View File

@ -6,6 +6,7 @@
# 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
@ -23,8 +24,6 @@ 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
@ -49,7 +48,8 @@ CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_MQ_MSGS=32
CONFIG_PREALLOC_MQ_IRQ_MSGS=1024
CONFIG_PREALLOC_MQ_MSGS=256
CONFIG_PREALLOC_TIMERS=4
CONFIG_PTHREAD_MUTEX_TYPES=y
CONFIG_RAM_SIZE=114688