esp32[c3]: Add BLE support

This commit is contained in:
Eren Terzioglu 2024-07-19 16:10:15 +02:00 committed by Xiang Xiao
parent 68d6b18f9a
commit 05ba822c41
16 changed files with 4781 additions and 13 deletions

View file

@ -53,6 +53,74 @@ All of the configurations presented below can be tested by running the following
Where <config_name> is the name of board configuration you want to use, i.e.: nsh, buttons, wifi...
Then use a serial console terminal like ``picocom`` configured to 115200 8N1.
ble
---
This configuration is used to enable the Bluetooth Low Energy (BLE) of
ESP32-C3 chip.
To test it, just run the following commands below.
Confirm that bnep interface exist::
nsh> ifconfig
bnep0 Link encap:UNSPEC at DOWN
inet addr:0.0.0.0 DRaddr:0.0.0.0 Mask:0.0.0.0
Get basic information from it::
nsh> bt bnep0 info
Device: bnep0
BDAddr: 86:f7:03:09:41:4d
Flags: 0000
Free: 20
ACL: 20
SCO: 0
Max:
ACL: 24
SCO: 0
MTU:
ACL: 70
SCO: 70
Policy: 0
Type: 0
Start the scanning process::
nsh> bt bnep0 scan start
Wait a little bit before stopping it.
Then after some minutes stop it::
nsh> bt bnep0 scan stop
Get the list of BLE devices found around you::
nsh> bt bnep0 scan get
Scan result:
1. addr: d7:c4:e6:xx:xx:xx type: 0
rssi: -62
response type: 4
advertiser data: 10 09 4d 69 20 XX XX XX XX XX XX XX XX XX XX 20 e
2. addr: cb:23:18:xx:xx:xx type: 0
rssi: -60
response type: 0
advertiser data: 02 01 06 1b ff XX XX XX ff ff ff ff ff ff ff ff 8
3. addr: cb:23:18:xx:xx:xx type: 0
rssi: -60
response type: 4
advertiser data: 10 09 4d 69 20 XX XX XX XX XX XX XX XX XX XX 20 e
4. addr: d7:c4:e6:xx:xx:xx type: 0
rssi: -62
response type: 0
advertiser data: 02 01 06 1b ff XX XX XX ff ff ff ff ff ff ff ff e
5. addr: d7:c4:e6:xx:xx:xx type: 0
rssi: -62
response type: 4
advertiser data: 10 09 4d 69 20 XX XX XX XX XX XX XX XX XX XX 20 e
nsh>
bmp180
------

View file

@ -465,6 +465,14 @@ config ESPRESSIF_WIFI
---help---
Enable Wi-Fi support
config ESPRESSIF_BLE
bool "BLE"
depends on ESPRESSIF_ESP32C3
default n
select ESP_WIRELESS
---help---
Enable BLE support
config ESP_COEX_SW_COEXIST_ENABLE
bool "Software WiFi/Bluetooth/IEEE 802.15.4 coexistence"
depends on (ESPRESSIF_WIFI && ESPRESSIF_BLE) || \
@ -478,6 +486,13 @@ config ESP_COEX_SW_COEXIST_ENABLE
If only Bluetooth is used, it is recommended to disable this option to reduce binary file
size.
menuconfig ESPRESSIF_WIFI_BT_COEXIST
bool "Wi-Fi and BT coexist"
default y if ESPRESSIF_WIFI && ESPRESSIF_BLE
default n
depends on ESPRESSIF_WIFI && ESPRESSIF_BLE
select ESPRESSIF_WIFI_STA_DISCONNECT_PM
config ESP_MCPWM
bool "Motor Control PWM (MCPWM)"
default n
@ -933,6 +948,30 @@ endchoice # ESP_POWER_SAVE_MODE
endmenu # ESPRESSIF_WIFI
menu "BLE Configuration"
depends on ESPRESSIF_BLE
config ESPRESSIF_BLE_TTY_NAME
string "BLE TTY device name"
default "/dev/ttyHCI0"
depends on UART_BTH4
config ESPRESSIF_BLE_TASK_STACK_SIZE
int "Controller task stack size"
default 4096
config ESPRESSIF_BLE_TASK_PRIORITY
int "Controller task priority"
default 253
config ESPRESSIF_BLE_INTERRUPT_SAVE_STATUS
int "Number of interrupt save status"
default 3
---help---
Number of interrupt save status variables to keep track. Increase it if any related bug is found.
endmenu # BLE Configuration
menu "UART Configuration"
depends on ESPRESSIF_UART

View file

@ -120,8 +120,8 @@ ifeq ($(CONFIG_ESP_WIRELESS),y)
ifeq ($(CONFIG_ESPRESSIF_WIFI),y)
CHIP_CSRCS += esp_wifi_init.c
CHIP_CSRCS += esp_wlan.c
CHIP_CSRCS += esp_wifi_utils.c
endif
CHIP_CSRCS += esp_wifi_utils.c
endif
ifeq ($(CONFIG_ESP_MCPWM),y)
@ -136,7 +136,7 @@ endif
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION
ESP_HAL_3RDPARTY_VERSION = b4c723a119344b4b71d69819019d55637fb570fd
ESP_HAL_3RDPARTY_VERSION = ca869dd97ed2c01187b85b759c0d6edb27c12c21
endif
ifndef ESP_HAL_3RDPARTY_URL
@ -168,7 +168,7 @@ chip/$(ESP_HAL_3RDPARTY_REPO):
$(Q) git -C chip/$(ESP_HAL_3RDPARTY_REPO) checkout --quiet $(ESP_HAL_3RDPARTY_VERSION)
ifeq ($(CONFIG_ESP_WIRELESS),y)
$(Q) echo "Espressif HAL for 3rd Party Platforms: initializing submodules..."
$(Q) git -C chip/$(ESP_HAL_3RDPARTY_REPO) submodule --quiet update --init $(GIT_DEPTH_PARAMETER) components/mbedtls/mbedtls components/esp_phy/lib components/esp_wifi/lib components/esp_coex/lib
$(Q) git -C chip/$(ESP_HAL_3RDPARTY_REPO) submodule --quiet update --init $(GIT_DEPTH_PARAMETER) components/mbedtls/mbedtls components/esp_phy/lib components/esp_wifi/lib components/bt/controller/lib_esp32c3_family components/esp_coex/lib
$(Q) git -C chip/$(ESP_HAL_3RDPARTY_REPO)/components/mbedtls/mbedtls reset --quiet --hard
$(Q) echo "Applying patches..."
$(Q) cd chip/$(ESP_HAL_3RDPARTY_REPO)/components/mbedtls/mbedtls && git apply ../../../nuttx/patches/components/mbedtls/mbedtls/*.patch

View file

@ -24,6 +24,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)$(CHIP_SERIES)$(DELIM)include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)include$(DELIM)esp_wifi
EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bt$(DELIM)controller$(DELIM)lib_esp32c3_family$(DELIM)$(CHIP_SERIES)
EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_coex$(DELIM)lib$(DELIM)$(CHIP_SERIES)
EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_phy$(DELIM)lib$(DELIM)$(CHIP_SERIES)
EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_wifi$(DELIM)lib$(DELIM)$(CHIP_SERIES)

View file

@ -33,6 +33,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/wireless/wireless.h>
#ifdef CONFIG_ESPRESSIF_WIFI
#include "esp_wifi_adapter.h"
#include "esp_log.h"
@ -44,7 +45,9 @@
#include "esp_wpa.h"
#include "rom/ets_sys.h"
#include "soc/soc_caps.h"
#endif /* CONFIG_ESPRESSIF_WIFI */
#include "esp_err.h"
#include "esp_wifi_utils.h"
/****************************************************************************
@ -104,6 +107,8 @@ static uint8_t g_channel_list[CHANNEL_MAX_NUM];
* Public Functions
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_WIFI
/****************************************************************************
* Name: esp_wifi_start_scan
*
@ -573,6 +578,7 @@ scan_result_full:
priv->scan_status = ESP_SCAN_DONE;
nxsem_post(&priv->scan_signal);
}
#endif /* CONFIG_ESPRESSIF_WIFI */
/****************************************************************************
* Name: esp_wifi_to_errno

View file

@ -45,6 +45,8 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_WIFI
/****************************************************************************
* Name: esp_wifi_start_scan
*
@ -95,6 +97,8 @@ int esp_wifi_get_scan_results(struct iwreq *iwr);
void esp_wifi_scan_event_parse(void);
#endif
/****************************************************************************
* Name: esp_wifi_to_errno
*

View file

@ -28,4 +28,9 @@ CHIP_CSRCS += esp_coex_adapter.c esp_wifi_adapter.c
EXTRA_LIBS += -lcore -lnet80211 -lpp
endif
ifeq ($(CONFIG_ESPRESSIF_BLE),y)
CHIP_CSRCS += esp_ble.c esp_ble_adapter.c esp_wireless.c
EXTRA_LIBS += -lbtbb -lbtdm_app
endif
CFLAGS += ${DEFINE_PREFIX}_RETARGETABLE_LOCKING

View file

@ -0,0 +1,328 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp_ble.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/nuttx.h>
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <nuttx/net/bluetooth.h>
#include <nuttx/wireless/bluetooth/bt_driver.h>
#include <nuttx/wireless/bluetooth/bt_uart.h>
#if defined(CONFIG_UART_BTH4)
# include <nuttx/serial/uart_bth4.h>
#endif
#include "esp_ble_adapter.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* BLE packet buffer max size */
#define BLE_BUF_SIZE 1024
/****************************************************************************
* Private Types
****************************************************************************/
struct esp_ble_priv_s
{
struct bt_driver_s drv; /* NuttX BT/BLE driver data */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int esp_ble_open(struct bt_driver_s *drv);
static int esp_ble_send(struct bt_driver_s *drv,
enum bt_buf_type_e type,
void *data, size_t len);
static void esp_ble_close(struct bt_driver_s *drv);
static void esp_ble_send_ready(void);
static int esp_ble_recv_cb(uint8_t *data, uint16_t len);
/****************************************************************************
* Private Data
****************************************************************************/
static struct esp_ble_priv_s g_ble_priv =
{
.drv =
{
.head_reserve = H4_HEADER_SIZE,
.open = esp_ble_open,
.send = esp_ble_send,
.close = esp_ble_close
}
};
static esp_vhci_host_callback_t vhci_host_cb =
{
.notify_host_send_available = esp_ble_send_ready,
.notify_host_recv = esp_ble_recv_cb
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: esp_ble_send_ready
*
* Description:
* If the controller could send HCI comand will callback this function.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void esp_ble_send_ready(void)
{
}
/****************************************************************************
* Name: esp_ble_recv_cb
*
* Description:
* BLE receive callback function when BLE hardware receive packet
*
* Input Parameters:
* data - BLE packet data pointer
* len - BLE packet length
*
* Returned Value:
* 0 on success or a negated value on failure.
*
****************************************************************************/
static int esp_ble_recv_cb(uint8_t *data, uint16_t len)
{
int ret;
bool valid;
enum bt_buf_type_e type;
struct esp_ble_priv_s *priv = &g_ble_priv;
switch (data[0])
{
case H4_EVT:
type = BT_EVT;
valid = true;
break;
case H4_ACL:
type = BT_ACL_IN;
valid = true;
break;
case H4_ISO:
type = BT_ISO_IN;
valid = true;
break;
default:
valid = false;
break;
}
if (!valid)
{
ret = ERROR;
}
else
{
/* send packet to host */
ret = bt_netdev_receive(&priv->drv, type,
&data[H4_HEADER_SIZE],
len - H4_HEADER_SIZE);
if (ret < 0)
{
wlerr("Failed to receive ret=%d\n", ret);
}
}
return ret;
}
/****************************************************************************
* Name: esp_ble_send
*
* Description:
* ESP32-C3 BLE send callback function for BT driver.
*
* Input Parameters:
* drv - BT driver pointer
* type - BT packet type
* data - BT packet data buffer pointer
* len - BT packet length
*
* Returned Value:
* Sent bytes on success or a negated value on failure.
*
****************************************************************************/
static int esp_ble_send(struct bt_driver_s *drv,
enum bt_buf_type_e type,
void *data, size_t len)
{
uint8_t *hdr = (uint8_t *)data - drv->head_reserve;
if ((len + H4_HEADER_SIZE) > BLE_BUF_SIZE)
{
return -EINVAL;
}
if (type == BT_CMD)
{
*hdr = H4_CMD;
}
else if (type == BT_ACL_OUT)
{
*hdr = H4_ACL;
}
else if (type == BT_ISO_OUT)
{
*hdr = H4_ISO;
}
else
{
return -EINVAL;
}
if (esp_vhci_host_check_send_available())
{
esp_vhci_host_send_packet(hdr, len + drv->head_reserve);
}
return len;
}
/****************************************************************************
* Name: esp_ble_close
*
* Description:
* ESP32-C3 BLE close callback function for BT driver.
*
* Input Parameters:
* drv - BT driver pointer
*
* Returned Value:
* None
*
****************************************************************************/
static void esp_ble_close(struct bt_driver_s *drv)
{
}
/****************************************************************************
* Name: esp_ble_open
*
* Description:
* ESP32-C3 BLE open callback function for BT driver.
*
* Input Parameters:
* drv - BT driver pointer
*
* Returned Value:
* OK on success or a negated value on failure.
*
****************************************************************************/
static int esp_ble_open(struct bt_driver_s *drv)
{
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: esp_ble_initialize
*
* Description:
* Init BT controller
*
* Input Parameters:
* None
*
* Returned Value:
* success or fail
*
****************************************************************************/
int esp_ble_initialize(void)
{
int ret;
ret = esp_bt_controller_init();
if (ret)
{
wlerr("Failed to initialize BLE ret=%d\n", ret);
return ERROR;
}
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
if (ret)
{
wlerr("Failed to Enable BLE ret=%d\n", ret);
return ERROR;
}
ret = esp_vhci_register_callback(&vhci_host_cb);
if (ret)
{
esp_bt_controller_disable();
wlerr("Failed to register BLE callback ret=%d\n", ret);
return ERROR;
}
#if defined(CONFIG_UART_BTH4)
ret = uart_bth4_register(CONFIG_ESPRESSIF_BLE_TTY_NAME, &g_ble_priv.drv);
#else
ret = bt_netdev_register(&g_ble_priv.drv);
#endif
if (ret < 0)
{
wlerr("bt_netdev_register error: %d\n", ret);
return ret;
}
return OK;
}

View file

@ -0,0 +1,50 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp_ble.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP_BLE_H
#define __ARCH_RISCV_SRC_ESP32C3_ESP_BLE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp_ble_initialize
*
* Description:
* Init BT controller
*
* Input Parameters:
* None
*
* Returned Value:
* success or fail
*
****************************************************************************/
int esp_ble_initialize(void);
#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP_BLE_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,175 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp_ble_adapter.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP_BLE_ADAPTER_H
#define __ARCH_RISCV_SRC_ESP32C3_ESP_BLE_ADAPTER_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_bt.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp_bt_controller_init
*
* Description:
* Init BT controller.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success. A negated errno value is returned
* on failure.
*
****************************************************************************/
int esp_bt_controller_init(void);
/****************************************************************************
* Name: esp_bt_controller_deinit
*
* Description:
* Deinit BT controller.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success. Otherwise, -1 (ERROR) is returned.
*
****************************************************************************/
int esp_bt_controller_deinit(void);
/****************************************************************************
* Name: esp_bt_controller_enable
*
* Description:
* Enable BT controller.
*
* Input Parameters:
* mode - the mode(BLE/BT/BTDM) to enable. For compatible of API, retain
* this argument. This mode must be equal as the mode in "cfg" of
* esp_bt_controller_init().
*
* Returned Value:
* Zero (OK) is returned on success. A negated errno value is returned
* on failure.
*
****************************************************************************/
int esp_bt_controller_enable(esp_bt_mode_t mode);
/****************************************************************************
* Name: esp_bt_controller_disable
*
* Description:
* Disable BT controller.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success. A negated errno value is returned
* on failure.
*
****************************************************************************/
int esp_bt_controller_disable(void);
/****************************************************************************
* Name: esp_bt_controller_get_status
*
* Description:
* Enable BT controller.
*
* Input Parameters:
* mode - the mode(BLE/BT/BTDM) to enable. For compatible of API, retain
* this argument. This mode must be equal as the mode in "cfg" of
* esp_bt_controller_init().
*
* Returned Value:
* Zero (OK) is returned on success. A negated errno value is returned
* on failure.
*
****************************************************************************/
esp_bt_controller_status_t esp_bt_controller_get_status(void);
/****************************************************************************
* Name: esp_vhci_host_check_send_available
*
* Description:
* Check if the host can send packet to controller or not.
*
* Input Parameters:
* None
*
* Returned Value:
* True if returned on success. Otherwise, false is returned.
*
****************************************************************************/
bool esp_vhci_host_check_send_available(void);
/****************************************************************************
* Name: esp_vhci_host_send_packet
*
* Description:
* Host send packet to controller.
*
* Input Parameters:
* data - the packet pointer
* len - the packet length
*
* Returned Value:
* None
*
****************************************************************************/
void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
/****************************************************************************
* Name: esp_vhci_register_callback
*
* Description:
* Register the vhci reference callback.
*
* Input Parameters:
* callback - struct defined by vhci_host_callback structure.
*
* Returned Value:
* status - success or fail
*
****************************************************************************/
int esp_vhci_register_callback(const esp_vhci_host_callback_t *callback);
#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP_BLE_ADAPTER_H */

View file

@ -0,0 +1,370 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp_wireless.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/kmalloc.h>
#include <nuttx/mqueue.h>
#include <debug.h>
#include <assert.h>
#include <netinet/in.h>
#include <sys/param.h>
#include "soc/system_reg.h"
#include "espressif/esp_irq.h"
#include "riscv_internal.h"
#include "esp_private/phy.h"
#include "espressif/esp_hr_timer.h"
#include "esp_private/phy.h"
#include "periph_ctrl.h"
#include "esp_phy_init.h"
#include "phy_init_data.h"
#include "esp_wireless.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Software Interrupt */
#define SWI_IRQ ESP_IRQ_FROM_CPU_INTR0
#define SWI_PERIPH FROM_CPU_INTR0_SOURCE
/****************************************************************************
* 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
****************************************************************************/
static int esp_swi_irq(int irq, void *context, void *arg);
/****************************************************************************
* Private Data
****************************************************************************/
/* Private data of the wireless common interface */
static struct esp_wireless_priv_s g_esp_wireless_priv;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* 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;
putreg32(0, SYSTEM_CPU_INTR_FROM_CPU_0_REG);
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
****************************************************************************/
/****************************************************************************
* 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 interrupt. This will generate an IRQ as soon as non-IRAM
* are (re)enabled.
*/
putreg32(SYSTEM_CPU_INTR_FROM_CPU_0_M, SYSTEM_CPU_INTR_FROM_CPU_0_REG);
}
/****************************************************************************
* 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.
*/
putreg32(SYSTEM_CPU_INTR_FROM_CPU_0_M, SYSTEM_CPU_INTR_FROM_CPU_0_REG);
}
/****************************************************************************
* Name: esp_wireless_init
*
* Description:
* Initialize ESP32-C3 wireless common components for both BT and Wi-Fi.
*
* Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success. A negated errno value is returned on
* failure.
*
****************************************************************************/
int 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 = esp_setup_irq(SWI_PERIPH, ESP_IRQ_PRIORITY_DEFAULT, 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)
{
esp_teardown_irq(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-C3 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);
esp_teardown_irq(SWI_PERIPH, priv->cpuint);
}
}
leave_critical_section(flags);
return OK;
}

View file

@ -0,0 +1,198 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp_wireless.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_XTENSA_SRC_ESP32C3_ESP_WIRELESS_H
#define __ARCH_XTENSA_SRC_ESP32C3_ESP_WIRELESS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <semaphore.h>
#include <stdbool.h>
#include <stdint.h>
#include <nuttx/config.h>
#include <nuttx/list.h>
#include "esp_attr.h"
#include "esp_log.h"
#include "esp_mac.h"
#include "esp_private/phy.h"
#include "esp_private/wifi.h"
#include "esp_random.h"
#include "esp_timer.h"
#include "rom/ets_sys.h"
#include "soc/soc_caps.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Note: Don't remove these definitions, they are needed by the 3rdparty IDF
* headers
*/
#define CONFIG_MAC_BB_PD (0)
#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
****************************************************************************/
/****************************************************************************
* Functions needed by libphy.a
****************************************************************************/
/****************************************************************************
* 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_ESP32C3_ESP_WIRELESS_H */

View file

@ -30,6 +30,7 @@
****************************************************************************/
#include "common.ld"
#include "esp32c3_aliases.ld"
#define SRAM_IRAM_START 0x4037c000
#define SRAM_DRAM_START 0x3fc7c000

View file

@ -0,0 +1,67 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ALLOW_BSD_COMPONENTS=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32c3-generic"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32C3_GENERIC=y
CONFIG_ARCH_CHIP="esp32c3"
CONFIG_ARCH_CHIP_ESP32C3_GENERIC=y
CONFIG_ARCH_INTERRUPTSTACK=1536
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BTSAK=y
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_DRIVERS_BLUETOOTH=y
CONFIG_DRIVERS_IEEE80211=y
CONFIG_DRIVERS_WIRELESS=y
CONFIG_ESPRESSIF_BLE=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NAME_MAX=48
CONFIG_NETDEV_LATEINIT=y
CONFIG_NET_BLUETOOTH=y
CONFIG_NET_SOCKOPTS=y
CONFIG_NET_TCP=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_DATE=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_MQ_MSGS=32
CONFIG_PREALLOC_TIMERS=0
CONFIG_PTHREAD_MUTEX_TYPES=y
CONFIG_RR_INTERVAL=200
CONFIG_RTC_ALARM=y
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_SIG_DEFAULT=y
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_WIRELESS=y
CONFIG_WIRELESS_BLUETOOTH=y

View file

@ -84,6 +84,10 @@
# include "esp_board_wlan.h"
#endif
#ifdef CONFIG_ESPRESSIF_BLE
# include "esp_ble.h"
#endif
#ifdef CONFIG_SPI_SLAVE_DRIVER
# include "espressif/esp_spi.h"
# include "esp_board_spislavedev.h"
@ -232,6 +236,25 @@ int esp_bringup(void)
}
#endif
#ifdef CONFIG_RTC_DRIVER
/* Initialize the RTC driver */
ret = esp_rtc_driverinit();
if (ret < 0)
{
_err("Failed to initialize the RTC driver: %d\n", ret);
}
#endif
#ifdef CONFIG_ESPRESSIF_BLE
ret = esp_ble_initialize();
if (ret)
{
syslog(LOG_ERR, "ERROR: Failed to initialize BLE\n");
return ret;
}
#endif
#if defined(CONFIG_SPI_SLAVE_DRIVER) && defined(CONFIG_ESPRESSIF_SPI2)
ret = board_spislavedev_initialize(ESPRESSIF_SPI2);
if (ret < 0)
@ -263,16 +286,6 @@ int esp_bringup(void)
}
#endif
#ifdef CONFIG_RTC_DRIVER
/* Initialize the RTC driver */
ret = esp_rtc_driverinit();
if (ret < 0)
{
_err("Failed to initialize the RTC driver: %d\n", ret);
}
#endif
#if defined(CONFIG_I2C_DRIVER)
/* Configure I2C peripheral interfaces */