mirror of
https://github.com/apache/nuttx.git
synced 2026-05-22 22:20:01 +08:00
esp32s3/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:
committed by
Xiang Xiao
parent
0ddb64555a
commit
a71a3258b7
@@ -60,7 +60,6 @@
|
||||
#include "esp32s3_rtc.h"
|
||||
#include "esp32s3_spiflash.h"
|
||||
#include "esp32s3_wireless.h"
|
||||
#include "esp32s3_wireless.h"
|
||||
|
||||
#include "esp32s3_ble_adapter.h"
|
||||
|
||||
@@ -90,6 +89,11 @@
|
||||
#define BTDM_LPCLK_SEL_RTC_SLOW (2)
|
||||
#define BTDM_LPCLK_SEL_8M (3)
|
||||
|
||||
#ifdef CONFIG_ESP32S3_SPIFLASH
|
||||
# define BLE_TASK_EVENT_QUEUE_ITEM_SIZE 8
|
||||
# define BLE_TASK_EVENT_QUEUE_LEN 1
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@@ -159,6 +163,16 @@ enum btdm_wakeup_src_e
|
||||
BTDM_ASYNC_WAKEUP_SRC_MAX,
|
||||
};
|
||||
|
||||
/* Superseded semaphore definition */
|
||||
|
||||
struct bt_sem_s
|
||||
{
|
||||
sem_t sem;
|
||||
#ifdef CONFIG_ESP32S3_SPIFLASH
|
||||
struct esp_semcache_s sc;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* prototype of function to handle vendor dependent signals */
|
||||
|
||||
typedef void (*btdm_vnd_ol_task_func_t)(void *param);
|
||||
@@ -424,6 +438,13 @@ static DRAM_ATTR void * g_light_sleep_pm_lock;
|
||||
|
||||
static irqstate_t g_inter_flags;
|
||||
|
||||
/* Cached queue control variables */
|
||||
|
||||
#ifdef CONFIG_ESP32S3_SPIFLASH
|
||||
static struct esp_queuecache_s g_esp_queuecache;
|
||||
static uint8_t g_esp_queuecache_buffer[BLE_TASK_EVENT_QUEUE_ITEM_SIZE];
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@@ -704,7 +725,6 @@ static int IRAM_ATTR esp_int_adpt_cb(int irq, void *context, void *arg)
|
||||
|
||||
static void interrupt_handler_set_wrapper(int intr_num, void *fn, void *arg)
|
||||
{
|
||||
int ret;
|
||||
struct irq_adpt_s *adapter;
|
||||
int irq = esp32s3_getirq(0, intr_num);
|
||||
|
||||
@@ -716,8 +736,7 @@ static void interrupt_handler_set_wrapper(int intr_num, void *fn, void *arg)
|
||||
adapter->func = fn;
|
||||
adapter->arg = arg;
|
||||
|
||||
ret = irq_attach(irq, esp_int_adpt_cb, adapter);
|
||||
DEBUGASSERT(ret == OK);
|
||||
DEBUGVERIFY(irq_attach(irq, esp_int_adpt_cb, adapter));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -727,7 +746,7 @@ static void interrupt_handler_set_wrapper(int intr_num, void *fn, void *arg)
|
||||
* Enable Wi-Fi interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* intr_num - No mean
|
||||
* intr_num - The interrupt CPU number.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
@@ -736,7 +755,12 @@ static void interrupt_handler_set_wrapper(int intr_num, void *fn, void *arg)
|
||||
|
||||
static void interrupt_on_wrapper(int intr_num)
|
||||
{
|
||||
up_enable_irq(intr_num + XTENSA_IRQ_FIRSTPERIPH);
|
||||
int cpuint = intr_num;
|
||||
int irq = esp32s3_getirq(0, cpuint);
|
||||
|
||||
DEBUGVERIFY(esp32s3_irq_set_iram_isr(irq));
|
||||
|
||||
up_enable_irq(irq);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -834,26 +858,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_ESP32S3_SPIFLASH
|
||||
esp_init_semcache(&bt_sem->sc, &bt_sem->sem);
|
||||
#endif
|
||||
|
||||
return bt_sem;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -872,9 +902,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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -896,7 +926,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;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -916,9 +947,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)
|
||||
{
|
||||
sem_t *sem = (sem_t *)semphr;
|
||||
int ret;
|
||||
struct bt_sem_s *bt_sem = (struct bt_sem_s *)semphr;
|
||||
|
||||
return esp_errno_trans(semphr_give_wrapper(sem));
|
||||
#ifdef CONFIG_ESP32S3_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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -969,21 +1015,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1013,9 +1059,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);
|
||||
@@ -1150,13 +1196,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_ESP32S3_SPIFLASH
|
||||
if (!spi_flash_cache_enabled())
|
||||
{
|
||||
esp_send_queuecache(&g_esp_queuecache, item, mq_adpt->msgsize);
|
||||
return esp_errno_trans(OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ticks == OSI_FUNCS_TIME_BLOCKING || ticks == 0)
|
||||
{
|
||||
/**
|
||||
@@ -1239,6 +1293,18 @@ static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size)
|
||||
}
|
||||
|
||||
mq_adpt->msgsize = item_size;
|
||||
|
||||
#ifdef CONFIG_ESP32S3_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_ITEM_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (void *)mq_adpt;
|
||||
}
|
||||
|
||||
@@ -1392,28 +1458,8 @@ static int IRAM_ATTR queue_recv_from_isr_wrapper(void *queue,
|
||||
void *item,
|
||||
void *hptw)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct timespec timeout;
|
||||
unsigned int prio;
|
||||
struct mq_adpt_s *mq_adpt = (struct mq_adpt_s *)queue;
|
||||
|
||||
ret = clock_gettime(CLOCK_REALTIME, &timeout);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("Failed to get time %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = file_mq_timedreceive(&mq_adpt->mq, (char *)item,
|
||||
mq_adpt->msgsize, &prio, &timeout);
|
||||
|
||||
if (ret < 0 && ret != -ETIMEDOUT)
|
||||
{
|
||||
wlerr("Failed to timedreceive from mqueue error=%d\n", ret);
|
||||
}
|
||||
|
||||
return ret > 0 ? true : false;
|
||||
DEBUGPANIC();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2391,6 +2437,13 @@ int esp32s3_bt_controller_init(void)
|
||||
|
||||
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
|
||||
|
||||
#ifdef CONFIG_ESP32S3_SPIFLASH
|
||||
if (esp_wireless_init() != OK)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
|
||||
error:
|
||||
|
||||
@@ -24,15 +24,18 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/mqueue.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "xtensa.h"
|
||||
#include "hardware/esp32s3_efuse.h"
|
||||
#include "hardware/esp32s3_rtccntl.h"
|
||||
#include "hardware/esp32s3_soc.h"
|
||||
#include "hardware/esp32s3_syscon.h"
|
||||
#include "hardware/esp32s3_efuse.h"
|
||||
#include "hardware/esp32s3_system.h"
|
||||
#include "esp32s3_irq.h"
|
||||
#include "esp32s3_periph.h"
|
||||
|
||||
#include "esp_phy_init.h"
|
||||
@@ -47,6 +50,27 @@
|
||||
#define MAC_ADDR0_REG EFUSE_RD_MAC_SPI_SYS_0_REG
|
||||
#define MAC_ADDR1_REG EFUSE_RD_MAC_SPI_SYS_1_REG
|
||||
|
||||
/* Software Interrupt */
|
||||
|
||||
#define SWI_IRQ ESP32S3_IRQ_INT_FROM_CPU2
|
||||
#define SWI_PERIPH ESP32S3_PERIPH_INT_FROM_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 */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@@ -91,6 +115,10 @@ static bool g_is_phy_calibrated = false;
|
||||
|
||||
static uint8_t g_wifi_bt_pd_controller;
|
||||
|
||||
/* Private data of the wireless common interface */
|
||||
|
||||
static struct esp_wireless_priv_s g_esp_wireless_priv;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@@ -132,6 +160,66 @@ 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;
|
||||
struct esp_queuecache_s *qc_tmp;
|
||||
struct esp_wireless_priv_s *priv = &g_esp_wireless_priv;
|
||||
|
||||
modifyreg32(SYSTEM_CPU_INTR_FROM_CPU_2_REG, SYSTEM_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, qc_tmp,
|
||||
struct esp_queuecache_s, node)
|
||||
{
|
||||
ret = file_mq_send(qc->mq_ptr, (const char *)qc->buffer, qc->size, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("ERROR: Failed to send queue ret=%d\n", ret);
|
||||
}
|
||||
|
||||
list_delete(&qc->node);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -605,3 +693,220 @@ int32_t esp_timer_delete(esp_timer_handle_t timer)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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 0 interrupt. This will generate an IRQ as soon as non-IRAM
|
||||
* are (re)enabled.
|
||||
*/
|
||||
|
||||
modifyreg32(SYSTEM_CPU_INTR_FROM_CPU_2_REG, 0, SYSTEM_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
|
||||
* 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 size)
|
||||
{
|
||||
qc->mq_ptr = mq_ptr;
|
||||
qc->size = size;
|
||||
qc->buffer = buffer;
|
||||
list_initialize(&qc->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(struct esp_queuecache_s *qc,
|
||||
uint8_t *buffer,
|
||||
int size)
|
||||
{
|
||||
struct esp_wireless_priv_s *priv = &g_esp_wireless_priv;
|
||||
|
||||
DEBUGASSERT(qc->size == size);
|
||||
|
||||
list_add_tail(&priv->qc_list, &qc->node);
|
||||
memcpy(qc->buffer, buffer, size);
|
||||
|
||||
/* Enable CPU 0 interrupt. This will generate an IRQ as soon as non-IRAM
|
||||
* are (re)enabled.
|
||||
*/
|
||||
|
||||
modifyreg32(SYSTEM_CPU_INTR_FROM_CPU_2_REG, 0, SYSTEM_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 = esp32s3_setup_irq(0, SWI_PERIPH, ESP32S3_INT_PRIO_DEF, 0);
|
||||
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)
|
||||
{
|
||||
esp32s3_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);
|
||||
|
||||
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);
|
||||
esp32s3_teardown_irq(0, SWI_PERIPH, priv->cpuint);
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
#include "esp32s3_rt_timer.h"
|
||||
@@ -45,6 +49,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
|
||||
****************************************************************************/
|
||||
@@ -266,4 +295,113 @@ int32_t esp_timer_stop(esp_timer_handle_t timer);
|
||||
|
||||
int32_t esp_timer_delete(esp_timer_handle_t timer);
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
* 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 size);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_wl_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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp_send_queuecache(struct esp_queuecache_s *qc,
|
||||
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_ESP32S3_ESP32S3_WIRELESS_H */
|
||||
|
||||
@@ -78,6 +78,7 @@ SECTIONS
|
||||
|
||||
*libarch.a:esp32s3_cpuindex.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:esp32s3_irq.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:esp32s3_user.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:esp32s3_spiflash.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_assert.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_cpuint.*(.literal .text .literal.* .text.*)
|
||||
@@ -86,6 +87,10 @@ SECTIONS
|
||||
*libarch.a:xtensa_modifyreg32.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_testset.*(.literal .text .literal.* .text.*)
|
||||
|
||||
#ifdef CONFIG_ESP32S3_BLE
|
||||
*libc.a:bin/sq_remlast.*(.literal .text .literal.* .text.*)
|
||||
#endif
|
||||
|
||||
*libdrivers.a:syslog_flush.*(.literal .text .literal.* .text.*)
|
||||
|
||||
*libsched.a:assert.*(.literal .text .literal.* .text.*)
|
||||
|
||||
Reference in New Issue
Block a user