mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 11:03:11 +00:00
feat(ble): added ble support for esp32h4 eco1
This commit is contained in:
@@ -166,6 +166,7 @@
|
||||
- "components/heap/tlsf"
|
||||
- "components/bt/controller/lib_esp32c6/esp32c6-bt-lib"
|
||||
- "components/bt/controller/lib_esp32c5/esp32c5-bt-lib"
|
||||
- "components/bt/controller/lib_esp32h4/esp32h4-bt-lib"
|
||||
- "components/bt/esp_ble_mesh/lib/lib"
|
||||
- ".gitmodules"
|
||||
|
||||
|
||||
@@ -116,6 +116,11 @@
|
||||
url = ../../espressif/esp32h2-bt-lib.git
|
||||
shallow = true
|
||||
|
||||
[submodule "components/bt/controller/lib_esp32h4/esp32h4-bt-lib"]
|
||||
path = components/bt/controller/lib_esp32h4/esp32h4-bt-lib
|
||||
url = ../../espressif/esp32h4-bt-lib.git
|
||||
shallow = true
|
||||
|
||||
[submodule "components/bt/controller/lib_esp32c2/esp32c2-bt-lib"]
|
||||
path = components/bt/controller/lib_esp32c2/esp32c2-bt-lib
|
||||
url = ../../espressif/esp32c2-bt-lib.git
|
||||
|
||||
@@ -105,9 +105,15 @@ if(CONFIG_BT_ENABLED)
|
||||
list(APPEND priv_include_dirs
|
||||
common/btc/include
|
||||
common/include
|
||||
)
|
||||
|
||||
if(NOT CONFIG_BT_DUAL_MODE_ARCH)
|
||||
list(APPEND priv_include_dirs
|
||||
porting/mem/
|
||||
porting/include
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND include_dirs ${common_include_dirs})
|
||||
|
||||
list(APPEND srcs "common/btc/core/btc_alarm.c"
|
||||
@@ -672,7 +678,22 @@ if(CONFIG_BT_ENABLED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT)
|
||||
if(CONFIG_BT_DUAL_MODE_ARCH)
|
||||
add_subdirectory(porting_btdm)
|
||||
list(APPEND srcs
|
||||
${porting_btdm_srcs}
|
||||
)
|
||||
|
||||
if(CONFIG_BT_NIMBLE_ENABLED)
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/nimble/transport/esp_ipc_btdm/src/hci_esp_ipc.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND include_dirs
|
||||
${porting_btdm_include_dirs}
|
||||
)
|
||||
elseif(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT)
|
||||
list(APPEND srcs
|
||||
"porting/npl/freertos/src/npl_os_freertos.c"
|
||||
"porting/mem/os_msys_init.c"
|
||||
@@ -867,9 +888,21 @@ if(CONFIG_BT_ENABLED)
|
||||
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/nimble/src/nimble_port.c"
|
||||
"host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c"
|
||||
"host/nimble/port/src/nvs_port.c"
|
||||
"host/nimble/port/src/esp_nimble_mem.c"
|
||||
)
|
||||
if(CONFIG_BT_DUAL_MODE_ARCH)
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/npl/esp-idf/src/nimble_port_freertos.c"
|
||||
)
|
||||
list(APPEND include_dirs
|
||||
"host/nimble/nimble/porting/npl/esp-idf/include"
|
||||
)
|
||||
else()
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND include_dirs
|
||||
host/nimble/nimble/porting/nimble/include
|
||||
@@ -884,7 +917,7 @@ if(CONFIG_BT_ENABLED)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT)
|
||||
if((NOT CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT) AND (NOT CONFIG_BT_DUAL_MODE_ARCH))
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/nimble/src/endian.c"
|
||||
"porting/mem/os_mempool.c"
|
||||
@@ -1087,6 +1120,12 @@ if(CONFIG_BT_ENABLED)
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
|
||||
|
||||
if(CONFIG_BT_DUAL_MODE_ARCH)
|
||||
add_prebuilt_library(libbtdm_common
|
||||
"controller/lib_${target_name}/${target_name}-bt-lib/libbtdm_common.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE libbtdm_common)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set_source_files_properties(
|
||||
|
||||
@@ -0,0 +1,739 @@
|
||||
|
||||
menuconfig BT_LE_50_FEATURE_SUPPORT
|
||||
bool "Enable BLE 5 feature"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable BLE 5 feature
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_2M_PHY
|
||||
bool "Enable 2M Phy"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable 2M-PHY
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
bool "Enable coded Phy"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable coded-PHY
|
||||
|
||||
config BT_LE_EXT_ADV
|
||||
bool "Enable extended advertising"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable this option to do extended advertising. Extended advertising
|
||||
will be supported from BLE 5.0 onwards.
|
||||
|
||||
if BT_LE_EXT_ADV
|
||||
config BT_LE_MAX_EXT_ADV_INSTANCES
|
||||
int "Maximum number of extended advertising instances."
|
||||
range 0 4
|
||||
default 1
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Change this option to set maximum number of extended advertising
|
||||
instances. Minimum there is always one instance of
|
||||
advertising. Enter how many more advertising instances you
|
||||
want.
|
||||
Each extended advertising instance will take about 0.5k DRAM.
|
||||
|
||||
config BT_LE_EXT_ADV_MAX_SIZE
|
||||
int "Maximum length of the advertising data."
|
||||
range 0 1650
|
||||
default 1650
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Defines the length of the extended adv data. The value should not
|
||||
exceed 1650.
|
||||
|
||||
config BT_LE_ENABLE_PERIODIC_ADV
|
||||
bool "Enable periodic advertisement."
|
||||
default y
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Enable this option to start periodic advertisement.
|
||||
|
||||
config BT_LE_PERIODIC_ADV_SYNC_TRANSFER
|
||||
bool "Enable Transfer Sync Events"
|
||||
depends on BT_LE_ENABLE_PERIODIC_ADV
|
||||
default y
|
||||
help
|
||||
This enables controller transfer periodic sync events to host
|
||||
|
||||
endif
|
||||
|
||||
config BT_LE_MAX_PERIODIC_SYNCS
|
||||
int "Maximum number of periodic advertising syncs"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
|
||||
range 0 8
|
||||
default 1 if BT_LE_ENABLE_PERIODIC_ADV
|
||||
default 0
|
||||
help
|
||||
Set this option to set the upper limit for number of periodic sync
|
||||
connections. This should be less than maximum connections allowed by
|
||||
controller.
|
||||
|
||||
config BT_LE_MAX_PERIODIC_ADVERTISER_LIST
|
||||
int "Maximum number of periodic advertiser list"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
range 1 5
|
||||
default 5
|
||||
help
|
||||
Set this option to set the upper limit for number of periodic advertiser list.
|
||||
|
||||
config BT_LE_POWER_CONTROL_ENABLED
|
||||
bool "Enable controller support for BLE Power Control"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
default n
|
||||
help
|
||||
Set this option to enable the Power Control feature on controller
|
||||
|
||||
menuconfig BT_LE_ISO_SUPPORT
|
||||
bool "Enable BLE ISO feature"
|
||||
default n
|
||||
help
|
||||
Support BLE 5.2 ISO feature
|
||||
|
||||
config BT_LE_ISO_FRA_UNSEG
|
||||
bool "Enable Unsegmented mode for Framed PDU"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
help
|
||||
Enable this to support the Framed Unsegmented mode.
|
||||
|
||||
config BT_LE_ISO_NSFC_EN
|
||||
bool "Enable Non-standard Flow Control (NSFC) mode"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable this to support ISO non-standard flow control.
|
||||
Note:
|
||||
If non-standard flow control mode is used, no Number of
|
||||
Completed Packets event will be posted from Controller.
|
||||
Instead before transmitting an ISO packet, Host needs to
|
||||
invoke an API provided by Controller to make sure that
|
||||
the ISO packet could be accommodated by Controller.
|
||||
|
||||
config BT_LE_ISO_NSFC_NUM
|
||||
int "Maximum number of ISO packets for NSFC mode"
|
||||
depends on BT_LE_ISO_SUPPORT && BT_LE_ISO_NSFC_EN
|
||||
range 1 255
|
||||
default 12
|
||||
help
|
||||
Maximum number of ISO packets could be accommodated by
|
||||
Controller while using non-standard flow control mode.
|
||||
|
||||
config BT_LE_ISO_BUF_COUNT
|
||||
int "Number of allocated ISO buffers"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
range 1 255
|
||||
default 12
|
||||
help
|
||||
Number of ISO buffers allocated in Controller.
|
||||
|
||||
config BT_LE_ISO_BUF_SIZE
|
||||
int "Size of each allocated ISO buffer"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
range 1 65535
|
||||
default 251
|
||||
help
|
||||
Size of each allocated ISO buffer in Controller.
|
||||
And the allocated ISO buffers will be used to hold
|
||||
ISO Data PDUs for transmission.
|
||||
Currently a larger value is meaningless, which only
|
||||
increase memory consumption.
|
||||
|
||||
config BT_LE_ISO_BIG
|
||||
int "Maximum number of BIGs"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
range 1 2
|
||||
default 1
|
||||
help
|
||||
Maximum number of BIGs.
|
||||
|
||||
config BT_LE_ISO_BIS
|
||||
int "Maximum number of BISes"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
range 1 6
|
||||
default 2
|
||||
help
|
||||
Maximum number of BISes.
|
||||
|
||||
config BT_LE_ISO_BIS_PER_BIG
|
||||
int "Maximum number of BISes per BIG"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
range 1 BT_LE_ISO_BIS
|
||||
default BT_LE_ISO_BIS
|
||||
help
|
||||
Maximum number of BISes per BIG.
|
||||
|
||||
config BT_LE_ISO_CIG
|
||||
int "Maximum number of CIGs"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
range 1 2
|
||||
default 1
|
||||
help
|
||||
Maximum number of CIGs.
|
||||
|
||||
config BT_LE_ISO_CIS
|
||||
int "Maximum number of CISes"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
range 1 6
|
||||
default 2
|
||||
help
|
||||
Maximum number of CISes.
|
||||
|
||||
config BT_LE_ISO_CIS_PER_CIG
|
||||
int "Maximum number of CISes per CIG"
|
||||
depends on BT_LE_ISO_SUPPORT
|
||||
range 1 BT_LE_ISO_CIS
|
||||
default BT_LE_ISO_CIS
|
||||
help
|
||||
Maximum number of CISes per CIG.
|
||||
|
||||
menu "Memory Settings"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
||||
config BT_LE_MSYS_1_BLOCK_COUNT
|
||||
int "MSYS_1 Block Count"
|
||||
default 12
|
||||
help
|
||||
MSYS is a system level mbuf registry. For prepare write & prepare
|
||||
responses MBUFs are allocated out of msys_1 pool. For NIMBLE_MESH
|
||||
enabled cases, this block count is increased by 8 than user defined
|
||||
count.
|
||||
|
||||
config BT_LE_MSYS_1_BLOCK_SIZE
|
||||
int "MSYS_1 Block Size"
|
||||
default 256
|
||||
help
|
||||
Dynamic memory size of block 1
|
||||
|
||||
config BT_LE_MSYS_2_BLOCK_COUNT
|
||||
int "MSYS_2 Block Count"
|
||||
default 24
|
||||
help
|
||||
Dynamic memory count
|
||||
|
||||
config BT_LE_MSYS_2_BLOCK_SIZE
|
||||
int "MSYS_2 Block Size"
|
||||
default 320
|
||||
help
|
||||
Dynamic memory size of block 2
|
||||
|
||||
config BT_LE_MSYS_BUF_FROM_HEAP
|
||||
bool "Get Msys Mbuf from heap"
|
||||
default y
|
||||
depends on BT_LE_MSYS_INIT_IN_CONTROLLER
|
||||
help
|
||||
This option sets the source of the shared msys mbuf memory between
|
||||
the Host and the Controller. Allocate the memory from the heap if
|
||||
this option is sets, from the mempool otherwise.
|
||||
|
||||
config BT_LE_ACL_BUF_COUNT
|
||||
int "ACL Buffer count"
|
||||
default 10
|
||||
help
|
||||
The number of ACL data buffers.
|
||||
|
||||
config BT_LE_ACL_BUF_SIZE
|
||||
int "ACL Buffer size"
|
||||
default 517
|
||||
help
|
||||
This is the maximum size of the data portion of HCI ACL data packets.
|
||||
It does not include the HCI data header (of 4 bytes)
|
||||
|
||||
config BT_LE_HCI_EVT_BUF_SIZE
|
||||
int "HCI Event Buffer size"
|
||||
default 257 if BT_LE_EXT_ADV
|
||||
default 70
|
||||
help
|
||||
This is the size of each HCI event buffer in bytes. In case of
|
||||
extended advertising, packets can be fragmented. 257 bytes is the
|
||||
maximum size of a packet.
|
||||
|
||||
config BT_LE_HCI_EVT_HI_BUF_COUNT
|
||||
int "High Priority HCI Event Buffer count"
|
||||
default 30
|
||||
help
|
||||
This is the high priority HCI events' buffer size. High-priority
|
||||
event buffers are for everything except advertising reports. If there
|
||||
are no free high-priority event buffers then host will try to allocate a
|
||||
low-priority buffer instead
|
||||
|
||||
config BT_LE_HCI_EVT_LO_BUF_COUNT
|
||||
int "Low Priority HCI Event Buffer count"
|
||||
default 8
|
||||
help
|
||||
This is the low priority HCI events' buffer size. Low-priority event
|
||||
buffers are only used for advertising reports. If there are no free
|
||||
low-priority event buffers, then an incoming advertising report will
|
||||
get dropped
|
||||
endmenu
|
||||
|
||||
menu "Controller debug features"
|
||||
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
|
||||
bool "Controller log enable"
|
||||
default n
|
||||
help
|
||||
Enable controller log
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
|
||||
bool "Utilize BLE Log v2 for controller log"
|
||||
depends on BLE_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Utilize BLE Log v2 for controller log
|
||||
|
||||
if !BT_LE_CONTROLLER_LOG_MODE_BLE_LOG_V2
|
||||
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
|
||||
bool "enable controller log module"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable controller log module
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
|
||||
bool "enable HCI log module"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable hci log module
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
|
||||
bool "Controller log dump mode only"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Only operate in dump mode
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
|
||||
bool "Output ble controller logs to SPI bus (Experimental)"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
|
||||
select BT_BLE_LOG_SPI_OUT_ENABLED
|
||||
default n
|
||||
help
|
||||
Output ble controller logs to SPI bus
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_UHCI_OUT_ENABLED
|
||||
bool "Output ble controller logs via UART DMA (Experimental)"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
|
||||
depends on !BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED
|
||||
select BT_BLE_LOG_UHCI_OUT_ENABLED
|
||||
default y
|
||||
help
|
||||
Output ble controller logs via UART DMA
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
|
||||
bool "Store ble controller logs to flash(Experimental)"
|
||||
depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default n
|
||||
help
|
||||
Store ble controller logs to flash memory.
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_PARTITION_SIZE
|
||||
int "size of ble controller log partition(Multiples of 4K)"
|
||||
depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE
|
||||
default 65536
|
||||
help
|
||||
The size of ble controller log partition shall be a multiples of 4K.
|
||||
The name of log partition shall be "bt_ctrl_log".
|
||||
The partition type shall be ESP_PARTITION_TYPE_DATA.
|
||||
The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY.
|
||||
|
||||
config BT_LE_LOG_CTRL_BUF1_SIZE
|
||||
int "size of the first BLE controller LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 4096
|
||||
help
|
||||
Configure the size of the first BLE controller LOG buffer.
|
||||
|
||||
config BT_LE_LOG_CTRL_BUF2_SIZE
|
||||
int "size of the second BLE controller LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 1024
|
||||
help
|
||||
Configure the size of the second BLE controller LOG buffer.
|
||||
|
||||
config BT_LE_LOG_HCI_BUF_SIZE
|
||||
int "size of the BLE HCI LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 4096
|
||||
help
|
||||
Configure the size of the BLE HCI LOG buffer.
|
||||
endif
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE
|
||||
bool "Enable wrap panic handler"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default n
|
||||
help
|
||||
Wrap esp_panic_handler to get controller logs when PC pointer exception crashes.
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE
|
||||
bool "Enable esp_task_wdt_isr_user_handler implementation"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default n
|
||||
help
|
||||
Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered.
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL
|
||||
int "The output level of controller log"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
range 0 5
|
||||
default 1
|
||||
help
|
||||
The output level of controller log.
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH
|
||||
hex "The switch of module log output"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
range 0 0xFFFFFFFF
|
||||
default 0xFFFFFFFF
|
||||
help
|
||||
The switch of module log output, this is an unsigned 32-bit hexadecimal value.
|
||||
|
||||
config BT_LE_ERROR_SIM_ENABLED
|
||||
bool "Enable controller features for internal testing"
|
||||
default n
|
||||
|
||||
config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED
|
||||
bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)"
|
||||
default n
|
||||
|
||||
config BT_LE_DEBUG_REMAIN_SCENE_ENABLED
|
||||
bool "Remain scene with GDB to capture relevant status info(Experimental)"
|
||||
default n
|
||||
help
|
||||
Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN).
|
||||
|
||||
config BT_LE_PTR_CHECK_ENABLED
|
||||
bool "Enable boundary check for internal memory"
|
||||
default n
|
||||
|
||||
config BT_LE_MEM_CHECK_ENABLED
|
||||
bool "Enable memory allocation check"
|
||||
default n
|
||||
help
|
||||
Used in internal tests only. Enable the memory allocation check.
|
||||
endmenu
|
||||
|
||||
config BT_LE_LL_RESOLV_LIST_SIZE
|
||||
int "BLE LL Resolving list size"
|
||||
range 1 5
|
||||
default 4
|
||||
help
|
||||
Configure the size of resolving list used in link layer.
|
||||
|
||||
menuconfig BT_LE_SECURITY_ENABLE
|
||||
bool "Enable BLE SM feature"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable BLE sm feature
|
||||
|
||||
config BT_LE_SM_LEGACY
|
||||
bool "Security manager legacy pairing"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable security manager legacy pairing
|
||||
|
||||
config BT_LE_SM_SC
|
||||
bool "Security manager secure connections (4.2)"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable security manager secure connections
|
||||
|
||||
config BT_LE_SM_SC_DEBUG_KEYS
|
||||
bool "Use predefined public-private key pair"
|
||||
default n
|
||||
depends on BT_LE_SECURITY_ENABLE && BT_LE_SM_SC
|
||||
help
|
||||
If this option is enabled, SM uses predefined DH key pair as described
|
||||
in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to
|
||||
decrypt air traffic easily and thus should only be used for debugging.
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_ENCRYPTION
|
||||
bool "Enable LE encryption"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable encryption connection
|
||||
|
||||
config BT_LE_CRYPTO_STACK_MBEDTLS
|
||||
bool "Override TinyCrypt with mbedTLS for crypto computations"
|
||||
default n
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
select MBEDTLS_CMAC_C
|
||||
help
|
||||
Enable this option to choose mbedTLS instead of TinyCrypt for crypto
|
||||
computations.
|
||||
|
||||
config BT_LE_WHITELIST_SIZE
|
||||
int "BLE white list size"
|
||||
range 1 15
|
||||
default 12
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
||||
help
|
||||
BLE list size
|
||||
|
||||
config BT_LE_LL_DUP_SCAN_LIST_COUNT
|
||||
int "BLE duplicate scan list count"
|
||||
range 1 100
|
||||
default 20
|
||||
help
|
||||
config the max count of duplicate scan list
|
||||
|
||||
config BT_LE_LL_SCA
|
||||
int "BLE Sleep clock accuracy"
|
||||
range 0 500
|
||||
default 60
|
||||
help
|
||||
Sleep clock accuracy of our device (in ppm)
|
||||
|
||||
config BT_LE_MAX_CONNECTIONS
|
||||
int "Maximum number of concurrent connections"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
range 1 70
|
||||
default 3
|
||||
help
|
||||
Defines maximum number of concurrent BLE connections.
|
||||
Each connection will take about 1k DRAM.
|
||||
|
||||
choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM
|
||||
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection"
|
||||
default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
help
|
||||
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to
|
||||
better avoid dramatic performance deterioration of Wi-Fi.
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
bool "Force Enable"
|
||||
help
|
||||
Always enable the limitation on max tx/rx time for Coded-PHY connection
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
bool "Force Disable"
|
||||
help
|
||||
Disable the limitation on max tx/rx time for Coded-PHY connection
|
||||
endchoice
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
int
|
||||
default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
|
||||
choice BT_LE_LP_CLK_SRC
|
||||
prompt "BLE low power clock source"
|
||||
default BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
depends on BT_CTRL_SLEEP_ENABLE
|
||||
config BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
bool "Use main XTAL as RTC clock source"
|
||||
help
|
||||
User main XTAL as RTC clock source.
|
||||
This option is recommended if external 32.768k XTAL is not available.
|
||||
Using the external 32.768 kHz XTAL will have lower current consumption
|
||||
in light sleep compared to using the main XTAL.
|
||||
|
||||
config BT_LE_LP_CLK_SRC_DEFAULT
|
||||
bool "Use system RTC slow clock source"
|
||||
help
|
||||
Use the same slow clock source as system RTC
|
||||
Using any clock source other than external 32.768 kHz XTAL supports only
|
||||
legacy ADV and SCAN due to low clock accuracy.
|
||||
|
||||
endchoice
|
||||
|
||||
config BT_LE_USE_ESP_TIMER
|
||||
bool "Enable Esp Timer for Callout"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Set this option to use Esp Timer which has higher priority timer
|
||||
instead of FreeRTOS timer
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
bool "BLE adv report flow control supported"
|
||||
default y
|
||||
help
|
||||
The function is mainly used to enable flow control for advertising reports. When it is enabled,
|
||||
advertising reports will be discarded by the controller if the number of unprocessed advertising
|
||||
reports exceeds the size of BLE adv report flow control.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM
|
||||
int "BLE adv report flow control number"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 50 1000
|
||||
default 100
|
||||
help
|
||||
The number of unprocessed advertising report that bluetooth host can save.If you set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a
|
||||
lot of adv packets and this may cause system memory run out. For example, if you set
|
||||
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv
|
||||
packets as fast as possible, otherwise it will cause adv packets lost.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
int "BLE adv lost event threshold value"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 1 1000
|
||||
default 20
|
||||
help
|
||||
When adv report flow control is enabled, The ADV lost event will be generated when the number
|
||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
config BT_LE_SCAN_DUPL
|
||||
bool "BLE Scan Duplicate Options"
|
||||
default y
|
||||
help
|
||||
This select enables parameters setting of BLE scan duplicate.
|
||||
|
||||
choice BT_LE_SCAN_DUPL_TYPE
|
||||
prompt "Scan Duplicate Type"
|
||||
default BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
help
|
||||
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use
|
||||
advertiser address filtering. The adv packet of the same address is only allowed to be reported once.
|
||||
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising
|
||||
data and device address filtering. All different adv packets with the same address are allowed to be
|
||||
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data
|
||||
filtering. All same advertising data only allow to be reported once even though they are from
|
||||
different devices.
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
bool "Scan Duplicate By Device Address"
|
||||
help
|
||||
This way is to use advertiser address filtering. The adv packet of the same address is only
|
||||
allowed to be reported once
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DATA
|
||||
bool "Scan Duplicate By Advertising Data"
|
||||
help
|
||||
This way is to use advertising data filtering. All same advertising data only allow to be reported
|
||||
once even though they are from different devices.
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
bool "Scan Duplicate By Device Address And Advertising Data"
|
||||
help
|
||||
This way is to use advertising data and device address filtering. All different adv packets with
|
||||
the same address are allowed to be reported.
|
||||
endchoice
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE
|
||||
int
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
default 0 if BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
default 1 if BT_LE_SCAN_DUPL_TYPE_DATA
|
||||
default 2 if BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
default 0
|
||||
|
||||
|
||||
config BT_LE_SCAN_DUPL_CACHE_SIZE
|
||||
int "Maximum number of devices in scan duplicate filter"
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
range 10 1000
|
||||
default 100
|
||||
help
|
||||
Maximum number of devices which can be recorded in scan duplicate filter.
|
||||
When the maximum amount of device in the filter is reached, the cache will be refreshed.
|
||||
|
||||
config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD
|
||||
int "Duplicate scan list refresh period (seconds)"
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
range 0 1000
|
||||
default 0
|
||||
help
|
||||
If the period value is non-zero, the controller will periodically clear the device information
|
||||
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared
|
||||
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the
|
||||
Host in advertising report events.
|
||||
There are two scenarios where the ADV packet will be repeatedly reported:
|
||||
1. The duplicate scan cache is full, the controller will delete the oldest device information and
|
||||
add new device information.
|
||||
2. When the refresh period is up, the controller will clear all device information and start filtering
|
||||
again.
|
||||
|
||||
config BT_LE_MSYS_INIT_IN_CONTROLLER
|
||||
bool "Msys Mbuf Init in Controller"
|
||||
default y
|
||||
|
||||
config BT_LE_TX_CCA_ENABLED
|
||||
bool "Enable TX CCA feature"
|
||||
default n
|
||||
help
|
||||
Enable CCA feature to cancel sending the packet if the signal power is stronger than CCA threshold.
|
||||
|
||||
config BT_LE_CCA_RSSI_THRESH
|
||||
int "CCA RSSI threshold value"
|
||||
depends on BT_LE_TX_CCA_ENABLED
|
||||
range 20 100
|
||||
default 20
|
||||
help
|
||||
Power threshold of CCA in unit of -1 dBm.
|
||||
|
||||
choice BT_LE_DFT_TX_POWER_LEVEL_DBM
|
||||
prompt "BLE default Tx power level(dBm)"
|
||||
default BT_LE_DFT_TX_POWER_LEVEL_P9
|
||||
help
|
||||
Specify default Tx power level(dBm).
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_N15
|
||||
bool "-15dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_N12
|
||||
bool "-12dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_N9
|
||||
bool "-9dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_N6
|
||||
bool "-6dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_N3
|
||||
bool "-3dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_N0
|
||||
bool "0dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_P3
|
||||
bool "+3dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_P6
|
||||
bool "+6dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_P9
|
||||
bool "+9dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_P12
|
||||
bool "+12dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_P15
|
||||
bool "+15dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_P18
|
||||
bool "+18dBm"
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_P20
|
||||
bool "+20dBm"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF
|
||||
int
|
||||
default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15
|
||||
default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12
|
||||
default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9
|
||||
default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6
|
||||
default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3
|
||||
default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0
|
||||
default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3
|
||||
default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6
|
||||
default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9
|
||||
default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12
|
||||
default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15
|
||||
default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18
|
||||
default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20
|
||||
default 0
|
||||
|
||||
config BT_LE_ERROR_SIM_ENABLED
|
||||
bool "Enable controller features for internal testing"
|
||||
default n
|
||||
@@ -0,0 +1,191 @@
|
||||
choice
|
||||
prompt "Bluetooth controller mode (BR/EDR/BLE/DUALMODE)"
|
||||
help
|
||||
Specify the bluetooth controller mode (BR/EDR, BLE or dual mode).
|
||||
|
||||
config BTDM_CTRL_MODE_BLE_ONLY
|
||||
bool "BLE Only"
|
||||
depends on SOC_BLE_SUPPORTED
|
||||
|
||||
config BTDM_CTRL_MODE_BR_EDR_ONLY
|
||||
bool "BR/EDR Only"
|
||||
depends on SOC_BT_CLASSIC_SUPPORTED
|
||||
|
||||
config BTDM_CTRL_MODE_BTDM
|
||||
bool "Bluetooth Dual Mode"
|
||||
depends on SOC_BLE_SUPPORTED && SOC_BT_CLASSIC_SUPPORTED
|
||||
endchoice
|
||||
|
||||
choice BT_CTRL_PINNED_TO_CORE_CHOICE
|
||||
prompt "The cpu core which bluetooth controller run"
|
||||
depends on !FREERTOS_UNICORE
|
||||
help
|
||||
Specify the cpu core to run bluetooth controller.
|
||||
Can not specify no-affinity.
|
||||
|
||||
config BT_CTRL_PINNED_TO_CORE_CHOICE_0
|
||||
bool "Core 0 (PRO CPU)"
|
||||
config BT_CTRL_PINNED_TO_CORE_CHOICE_1
|
||||
bool "Core 1 (APP CPU)"
|
||||
depends on !FREERTOS_UNICORE
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_PINNED_TO_CORE
|
||||
int
|
||||
default 0 if BT_CTRL_PINNED_TO_CORE_CHOICE_0
|
||||
default 1 if BT_CTRL_PINNED_TO_CORE_CHOICE_1
|
||||
default 0
|
||||
|
||||
config BT_CTRL_TASK_STACK_SIZE
|
||||
int "Controller task stack size"
|
||||
default 5120 if BLE_MESH
|
||||
default 4096
|
||||
help
|
||||
This configures stack size of NimBLE controller task
|
||||
|
||||
config BT_CTRL_SLEEP_ENABLE
|
||||
bool "Enable Bluetooth Controller sleep"
|
||||
default n
|
||||
help
|
||||
Enable Bluetooth Controller sleep
|
||||
|
||||
menu "Bluetooth controller HCI"
|
||||
config BT_CTRL_HCI_CMD_NUM
|
||||
int "HCI CMD buffer number"
|
||||
range 1 255
|
||||
default 5
|
||||
|
||||
choice BT_CTRL_HCI_INTERFACE
|
||||
prompt "HCI mode"
|
||||
default BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
|
||||
config BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
bool "VHCI"
|
||||
help
|
||||
Use RAM as HCI interface
|
||||
config BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
bool "UART(H4)"
|
||||
help
|
||||
Use UART as HCI interface
|
||||
endchoice
|
||||
|
||||
choice BT_CTRL_UART_HCI_MODE_CHOICE
|
||||
prompt "UART HCI mode"
|
||||
depends on BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
default BT_CTRL_UART_HCI_NO_DMA_MODE
|
||||
help
|
||||
Specify UART HCI mode: DMA or No DMA
|
||||
|
||||
config BT_CTRL_UART_HCI_DMA_MODE
|
||||
bool "UHCI(UART with DMA)(EXPERIMENTAL)"
|
||||
help
|
||||
UART HCI Mode with DMA functionality.
|
||||
|
||||
config BT_CTRL_UART_HCI_NO_DMA_MODE
|
||||
bool "UART(NO DMA)"
|
||||
help
|
||||
UART HCI Mode without DMA functionality.
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_HCI_UART_PORT
|
||||
int "HCI UART port"
|
||||
depends on BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
default 1
|
||||
help
|
||||
Set the port number of HCI UART
|
||||
|
||||
config BT_CTRL_HCI_UART_FLOWCTRL
|
||||
bool "HCI uart Hardware Flow ctrl"
|
||||
depends on BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
default n
|
||||
|
||||
config BT_CTRL_HCI_UART_TX_PIN
|
||||
int "HCI uart Tx gpio"
|
||||
depends on BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
default 19
|
||||
|
||||
config BT_CTRL_HCI_UART_RX_PIN
|
||||
int "HCI uart Rx gpio"
|
||||
depends on BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
default 10
|
||||
|
||||
config BT_CTRL_HCI_UART_RTS_PIN
|
||||
int "HCI uart RTS gpio"
|
||||
depends on BT_CTRL_HCI_UART_FLOWCTRL
|
||||
default 4
|
||||
|
||||
config BT_CTRL_HCI_UART_CTS_PIN
|
||||
int "HCI uart CTS gpio"
|
||||
depends on BT_CTRL_HCI_UART_FLOWCTRL
|
||||
default 5
|
||||
|
||||
config BT_CTRL_HCI_UART_BAUD
|
||||
int "HCI uart baudrate"
|
||||
depends on BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
default 921600
|
||||
help
|
||||
HCI uart baud rate 115200 ~ 1000000
|
||||
|
||||
choice BT_CTRL_HCI_UART_PARITY
|
||||
prompt "select uart parity"
|
||||
depends on BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
default BT_CTRL_HCI_UART_UART_PARITY_DISABLE
|
||||
|
||||
config BT_CTRL_HCI_UART_UART_PARITY_DISABLE
|
||||
bool "PARITY_DISABLE"
|
||||
help
|
||||
UART_PARITY_DISABLE
|
||||
config BT_CTRL_HCI_UART_UART_PARITY_EVEN
|
||||
bool "PARITY_EVEN"
|
||||
help
|
||||
UART_PARITY_EVEN
|
||||
config BT_CTRL_HCI_UART_UART_PARITY_ODD
|
||||
bool "PARITY_ODD"
|
||||
help
|
||||
UART_PARITY_ODD
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_HCI_UART_RX_BUFFER_SIZE
|
||||
int "The size of rx ring buffer memory"
|
||||
depends on BT_CTRL_UART_HCI_NO_DMA_MODE
|
||||
default 512
|
||||
help
|
||||
The size of rx ring buffer memory
|
||||
|
||||
config BT_CTRL_HCI_UART_TX_BUFFER_SIZE
|
||||
int "The size of tx ring buffer memory"
|
||||
depends on BT_CTRL_UART_HCI_NO_DMA_MODE
|
||||
default 256
|
||||
help
|
||||
The size of tx ring buffer memory
|
||||
|
||||
config BT_CTRL_HCI_TRANS_TASK_STACK_SIZE
|
||||
int "HCI transport task stack size"
|
||||
depends on !BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
default 1024
|
||||
help
|
||||
This configures stack size of hci transport task
|
||||
|
||||
config BT_CTRL_HCI_TRANS_RX_MEM_NUM
|
||||
int "The amount of rx memory received at the same time"
|
||||
depends on BT_CTRL_UART_HCI_DMA_MODE
|
||||
default 3
|
||||
help
|
||||
The amount of rx memory received at the same time
|
||||
|
||||
config BT_CTRL_HCI_LLDESCS_POOL_NUM
|
||||
int "The amount of lldecs memory for driver dma mode"
|
||||
depends on BT_CTRL_UART_HCI_DMA_MODE
|
||||
default 20
|
||||
help
|
||||
The amount of lldecs memory for driver dma mode
|
||||
endmenu
|
||||
|
||||
menu "BLE Controller Settings"
|
||||
depends on BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.ble.in"
|
||||
endmenu
|
||||
|
||||
config BT_DUAL_MODE_ARCH
|
||||
bool
|
||||
default y
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* From ESP Bluetooth */
|
||||
#include "esp_bt.h"
|
||||
#include "esp_hci_transport.h"
|
||||
#include "ble_priv.h"
|
||||
#include "btdm_coex.h"
|
||||
#include "btdm_lp.h"
|
||||
#include "btdm_log.h"
|
||||
#include "btdm_external.h"
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Local Defined Macros
|
||||
***************************************************************************************************
|
||||
*/
|
||||
#define BTDM_LOG_TAG "BTDM_INIT"
|
||||
|
||||
#if UC_BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_VHCI
|
||||
#elif UC_BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_UART_NO_DMA
|
||||
#if UC_BT_CTRL_UART_HCI_DMA_MODE
|
||||
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_UART_UHCI
|
||||
#endif // UC_BT_CTRL_UART_HCI_DMA_MODE
|
||||
#endif // UC_BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* External Functions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
extern const char *r_btdm_get_compile_version(void);
|
||||
extern int r_btdm_hci_fc_env_init();
|
||||
extern void r_btdm_hci_fc_env_deinit(void);
|
||||
extern int r_btdm_hci_fc_enable(void);
|
||||
extern void r_btdm_hci_fc_disable(void);
|
||||
|
||||
extern int r_btdm_task_init(esp_btdm_controller_config_t *cfg);
|
||||
extern void r_btdm_task_deinit(void);
|
||||
extern int r_btdm_task_enable(void);
|
||||
extern void r_btdm_task_disable(void);
|
||||
extern void r_btdm_task_shutdown(void);
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Local Variables
|
||||
***************************************************************************************************
|
||||
*/
|
||||
esp_bt_controller_status_t s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Static Function Definitions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
static void
|
||||
bt_shutdown(void)
|
||||
{
|
||||
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
r_btdm_task_shutdown();
|
||||
btdm_lp_shutdown();
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Public Function Definitions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
esp_err_t
|
||||
esp_bt_mem_release(esp_bt_mode_t mode)
|
||||
{
|
||||
ESP_LOGW(BTDM_LOG_TAG, "esp_bt_mem_release not implement yet!");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
esp_bt_controller_mem_release(esp_bt_mode_t mode)
|
||||
{
|
||||
|
||||
ESP_LOGW(BTDM_LOG_TAG, "esp_bt_controller_mem_release not implement yet!");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
int ret;
|
||||
// TODO: Delete workaround
|
||||
btdm_osal_elem_num_t elem = {
|
||||
.evt_count = 3 + 100,
|
||||
.evtq_count = 1 + 2,
|
||||
.co_count = 0 + 10,
|
||||
.sem_count = 0,
|
||||
.mutex_count = 1,
|
||||
};
|
||||
|
||||
ESP_LOGI(BTDM_LOG_TAG, "BTDM version [%s]", r_btdm_get_compile_version());
|
||||
|
||||
if (cfg->btdm.bluetooth_mode == ESP_BT_MODE_IDLE) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "bluetooth_mode in cfg is IDLE");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
|
||||
|
||||
ret = ESP_FAIL;
|
||||
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
ble_osal_elem_calc(cfg, &elem);
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
bredr_osal_elem_calc(cfg, &elem);
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
ret = btdm_osal_elem_mempool_init(&elem);
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "btdm_osal_elem_mempool_init failed: %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
ret = btdm_log_init();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "btdm_log_init failed: %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
ret = btdm_external_init();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "btdm_external_init failed: %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
ret = btdm_coex_init();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "btdm_coex_init failed: %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
btdm_lp_enable_clock(&cfg->btdm);
|
||||
|
||||
ret = r_btdm_task_init(&cfg->btdm);
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "r_btdm_task_init failed: %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
ret = btdm_lp_init();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "btdm_lp_init failed %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
#if UC_BT_CTRL_CONN_FC_ENABLE
|
||||
ret = r_btdm_hci_fc_env_init();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "r_btdm_hci_fc_env_init failed: %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
#endif // UC_BT_CTRL_CONN_FC_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
ret = ble_stack_init(cfg);
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "ble_stack_init failed: %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
ret = bredr_stack_init(cfg);
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "bredr_stack_init failed: %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
ret = hci_transport_init(BT_HCI_TRANSPORT_MODE);
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "hci_transport_init failed %d", ret);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
ESP_LOGI(BTDM_LOG_TAG, "BTDM controller init OK");
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
init_failed:
|
||||
esp_bt_controller_deinit();
|
||||
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
esp_bt_controller_deinit(void)
|
||||
{
|
||||
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
|
||||
|
||||
hci_transport_deinit();
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
bredr_stack_deinit();
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
ble_stack_deinit();
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_CONN_FC_ENABLE
|
||||
r_btdm_hci_fc_env_deinit();
|
||||
#endif // UC_BT_CTRL_CONN_FC_ENABLE
|
||||
|
||||
btdm_lp_deinit();
|
||||
r_btdm_task_deinit();
|
||||
btdm_lp_disable_clock();
|
||||
btdm_coex_deinit();
|
||||
btdm_log_deinit();
|
||||
btdm_external_deinit();
|
||||
btdm_osal_elem_mempool_deinit();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
esp_bt_controller_enable(esp_bt_mode_t mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
|
||||
|
||||
btdm_lp_reset(true);
|
||||
|
||||
ret = btdm_coex_enable();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "btdm_coex_enable failed %d", ret);
|
||||
goto enable_failed;
|
||||
}
|
||||
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
ret = ble_stack_enable();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "ble_stack_enable failed %d", ret);
|
||||
goto enable_failed;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
ret = bredr_stack_enable();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "bredr_stack_enable failed %d", ret);
|
||||
goto enable_failed;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_CONN_FC_ENABLE
|
||||
ret = r_btdm_hci_fc_enable();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "r_btdm_hci_fc_enable failed %d", ret);
|
||||
goto enable_failed;
|
||||
}
|
||||
#endif // UC_BT_CTRL_CONN_FC_ENABLE
|
||||
|
||||
ret = r_btdm_task_enable();
|
||||
if (ret) {
|
||||
ESP_LOGE(BTDM_LOG_TAG, "r_btdm_task_enable failed %d", ret);
|
||||
goto enable_failed;
|
||||
}
|
||||
|
||||
ret = esp_register_shutdown_handler(bt_shutdown);
|
||||
if (ret) {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "Register shutdown handler failed, ret = 0x%x", ret);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
enable_failed:
|
||||
esp_bt_controller_disable();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
esp_bt_controller_disable(void)
|
||||
{
|
||||
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
|
||||
|
||||
esp_unregister_shutdown_handler(bt_shutdown);
|
||||
|
||||
r_btdm_task_disable();
|
||||
|
||||
#if UC_BT_CTRL_CONN_FC_ENABLE
|
||||
r_btdm_hci_fc_disable();
|
||||
#endif // UC_BT_CTRL_CONN_FC_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
bredr_stack_disable();
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
ble_stack_disable();
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
|
||||
btdm_coex_disable();
|
||||
btdm_lp_reset(false);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_bt_controller_status_t
|
||||
esp_bt_controller_get_status(void)
|
||||
{
|
||||
return s_btdm_controller_status;
|
||||
}
|
||||
+1
Submodule components/bt/controller/lib_esp32h4/esp32h4-bt-lib added at 9a0df711be
@@ -24,9 +24,7 @@
|
||||
#include "common/bt_target.h"
|
||||
#include "osi/pkt_queue.h"
|
||||
#include "stack/bt_types.h"
|
||||
#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER)
|
||||
#include "os/os_mbuf.h"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
DATA_TYPE_COMMAND = 1,
|
||||
DATA_TYPE_ACL = 2,
|
||||
@@ -87,11 +85,6 @@ typedef struct hci_hal_t {
|
||||
|
||||
// Gets the correct hal implementation, as compiled for.
|
||||
const hci_hal_t *hci_hal_h4_get_interface(void);
|
||||
#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER)
|
||||
int ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg);
|
||||
|
||||
int ble_hs_rx_data(struct os_mbuf *om, void *arg);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _HCI_HAL_H */
|
||||
|
||||
@@ -569,7 +569,7 @@ menu "Memory Settings"
|
||||
|
||||
config BT_NIMBLE_MEMPOOL_RUNTIME_ALLOC
|
||||
bool "Support on-demand runtime memory allocation for mempool"
|
||||
depends on BT_NIMBLE_ENABLED && BT_NIMBLE_STATIC_TO_DYNAMIC
|
||||
depends on BT_NIMBLE_ENABLED && BT_NIMBLE_STATIC_TO_DYNAMIC && !BT_DUAL_MODE_ARCH
|
||||
default n
|
||||
help
|
||||
When this option is enabled, mempool does not require pre-allocating memory.
|
||||
|
||||
Submodule components/bt/host/nimble/nimble updated: 23bfcada3e...2d0d4de008
@@ -13,9 +13,95 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// #pragma message "This file should be replaced with bt_osi_mem.h, used here for compatibility"
|
||||
void *bt_osi_mem_malloc(size_t size);
|
||||
|
||||
void *bt_osi_mem_calloc(size_t n, size_t size);
|
||||
|
||||
void bt_osi_mem_free(void *ptr);
|
||||
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
size_t bt_osi_mem_used_size_get(void);
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
|
||||
#if CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
/**
|
||||
* @brief Initialize NimBLE memory debug module
|
||||
*/
|
||||
void nimble_mem_dbg_init(void);
|
||||
|
||||
/**
|
||||
* @brief Record memory allocation information
|
||||
*
|
||||
* @param p Pointer to allocated memory
|
||||
* @param size Size of allocation
|
||||
* @param func Function name where allocation occurred
|
||||
* @param line Line number where allocation occurred
|
||||
*/
|
||||
void nimble_mem_dbg_record(void *p, int size, const char *func, int line);
|
||||
|
||||
/**
|
||||
* @brief Clean up memory allocation record
|
||||
*
|
||||
* @param p Pointer to memory being freed
|
||||
* @param func Function name where free occurred
|
||||
* @param line Line number where free occurred
|
||||
*/
|
||||
void nimble_mem_dbg_clean(void *p, const char *func, int line);
|
||||
|
||||
/**
|
||||
* @brief Display all memory debug information
|
||||
*/
|
||||
void nimble_mem_dbg_show(void);
|
||||
|
||||
/**
|
||||
* @brief Get maximum memory size used
|
||||
*
|
||||
* @return Maximum memory size in bytes
|
||||
*/
|
||||
uint32_t nimble_mem_dbg_get_max_size(void);
|
||||
|
||||
/**
|
||||
* @brief Get current memory size in use
|
||||
*
|
||||
* @return Current memory size in bytes
|
||||
*/
|
||||
uint32_t nimble_mem_dbg_get_current_size(void);
|
||||
|
||||
/**
|
||||
* @brief Start tracking memory usage for a specific section
|
||||
*
|
||||
* @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1)
|
||||
*/
|
||||
void nimble_mem_dbg_set_section_start(uint8_t index);
|
||||
|
||||
/**
|
||||
* @brief Stop tracking memory usage for a specific section
|
||||
*
|
||||
* @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1)
|
||||
*/
|
||||
void nimble_mem_dbg_set_section_end(uint8_t index);
|
||||
|
||||
/**
|
||||
* @brief Get maximum memory size used in a specific section
|
||||
*
|
||||
* @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1)
|
||||
* @return Maximum memory size in bytes for this section
|
||||
*/
|
||||
uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index);
|
||||
|
||||
/**
|
||||
* @brief Reallocate memory with debug tracking
|
||||
*
|
||||
* @param ptr Pointer to memory to reallocate
|
||||
* @param new_size New size of allocation
|
||||
* @param func Function name where realloc occurred
|
||||
* @param line Line number where realloc occurred
|
||||
* @return Pointer to reallocated memory
|
||||
*/
|
||||
void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line);
|
||||
|
||||
#endif // CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
|
||||
#include "bt_osi_mem.h"
|
||||
|
||||
#if CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include <assert.h>
|
||||
|
||||
static uint8_t log_count;
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
static size_t host_mem_used_size = 0;
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
|
||||
#if CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
|
||||
#define NIMBLE_MEM_DBG_INFO_MAX 1024*3
|
||||
typedef struct {
|
||||
void *p;
|
||||
int size;
|
||||
const char *func;
|
||||
int line;
|
||||
} nimble_mem_dbg_info_t;
|
||||
|
||||
static uint32_t nimble_mem_dbg_count = 0;
|
||||
static nimble_mem_dbg_info_t nimble_mem_dbg_info[NIMBLE_MEM_DBG_INFO_MAX];
|
||||
static uint32_t nimble_mem_dbg_current_size = 0;
|
||||
static uint32_t nimble_mem_dbg_max_size = 0;
|
||||
|
||||
#define NIMBLE_MEM_DBG_MAX_SECTION_NUM 5
|
||||
typedef struct {
|
||||
bool used;
|
||||
uint32_t max_size;
|
||||
} nimble_mem_dbg_max_size_section_t;
|
||||
static nimble_mem_dbg_max_size_section_t nimble_mem_dbg_max_size_section[NIMBLE_MEM_DBG_MAX_SECTION_NUM];
|
||||
|
||||
void nimble_mem_dbg_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
nimble_mem_dbg_info[i].p = NULL;
|
||||
nimble_mem_dbg_info[i].size = 0;
|
||||
nimble_mem_dbg_info[i].func = NULL;
|
||||
nimble_mem_dbg_info[i].line = 0;
|
||||
}
|
||||
nimble_mem_dbg_count = 0;
|
||||
nimble_mem_dbg_current_size = 0;
|
||||
nimble_mem_dbg_max_size = 0;
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++){
|
||||
nimble_mem_dbg_max_size_section[i].used = false;
|
||||
nimble_mem_dbg_max_size_section[i].max_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_record(void *p, int size, const char *func, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!p || size == 0) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s invalid !!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p == NULL) {
|
||||
nimble_mem_dbg_info[i].p = p;
|
||||
nimble_mem_dbg_info[i].size = size;
|
||||
nimble_mem_dbg_info[i].func = func;
|
||||
nimble_mem_dbg_info[i].line = line;
|
||||
nimble_mem_dbg_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= NIMBLE_MEM_DBG_INFO_MAX) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
|
||||
nimble_mem_dbg_current_size += size;
|
||||
if(nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) {
|
||||
nimble_mem_dbg_max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++){
|
||||
if (nimble_mem_dbg_max_size_section[i].used) {
|
||||
if(nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) {
|
||||
nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_clean(void *p, const char *func, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!p) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s %d free->%p invalid\n", func, line, p);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p == p) {
|
||||
nimble_mem_dbg_current_size -= nimble_mem_dbg_info[i].size;
|
||||
nimble_mem_dbg_info[i].p = NULL;
|
||||
nimble_mem_dbg_info[i].size = 0;
|
||||
nimble_mem_dbg_info[i].func = NULL;
|
||||
nimble_mem_dbg_info[i].line = 0;
|
||||
nimble_mem_dbg_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= NIMBLE_MEM_DBG_INFO_MAX) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_show(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p || nimble_mem_dbg_info[i].size != 0 ) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "--> p %p, s %d, f %s, l %d\n",
|
||||
nimble_mem_dbg_info[i].p, nimble_mem_dbg_info[i].size,
|
||||
nimble_mem_dbg_info[i].func, nimble_mem_dbg_info[i].line);
|
||||
}
|
||||
}
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "--> count %ld\n", nimble_mem_dbg_count);
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "--> size %ldB\n--> max size %ldB\n",
|
||||
nimble_mem_dbg_current_size, nimble_mem_dbg_max_size);
|
||||
}
|
||||
|
||||
uint32_t nimble_mem_dbg_get_max_size(void)
|
||||
{
|
||||
return nimble_mem_dbg_max_size;
|
||||
}
|
||||
|
||||
uint32_t nimble_mem_dbg_get_current_size(void)
|
||||
{
|
||||
return nimble_mem_dbg_current_size;
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_set_section_start(uint8_t index)
|
||||
{
|
||||
if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nimble_mem_dbg_max_size_section[index].used) {
|
||||
ESP_LOGW("BT_NIMBLE_MEM", "This index(%d) has been started, restart it.\n", index);
|
||||
}
|
||||
|
||||
nimble_mem_dbg_max_size_section[index].used = true;
|
||||
nimble_mem_dbg_max_size_section[index].max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_set_section_end(uint8_t index)
|
||||
{
|
||||
if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nimble_mem_dbg_max_size_section[index].used) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "This index(%d) has not been started.\n", index);
|
||||
return;
|
||||
}
|
||||
|
||||
nimble_mem_dbg_max_size_section[index].used = false;
|
||||
}
|
||||
|
||||
uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index)
|
||||
{
|
||||
if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM){
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nimble_mem_dbg_max_size_section[index].max_size;
|
||||
}
|
||||
|
||||
void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line)
|
||||
{
|
||||
size_t old_size = 0;
|
||||
int i;
|
||||
|
||||
void *new_ptr = realloc(ptr, new_size);
|
||||
if (new_ptr == NULL && new_size > 0) {
|
||||
// realloc failed, keep old ptr record
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Find and clean old record if ptr is not NULL
|
||||
if (ptr != NULL) {
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p == ptr) {
|
||||
old_size = nimble_mem_dbg_info[i].size;
|
||||
nimble_mem_dbg_current_size -= old_size;
|
||||
|
||||
nimble_mem_dbg_info[i].p = NULL;
|
||||
nimble_mem_dbg_info[i].size = 0;
|
||||
nimble_mem_dbg_info[i].func = NULL;
|
||||
nimble_mem_dbg_info[i].line = 0;
|
||||
nimble_mem_dbg_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Record the new allocation if new_size > 0
|
||||
if (new_ptr != NULL && new_size > 0) {
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p == NULL) {
|
||||
nimble_mem_dbg_info[i].p = new_ptr;
|
||||
nimble_mem_dbg_info[i].size = new_size;
|
||||
nimble_mem_dbg_info[i].func = func;
|
||||
nimble_mem_dbg_info[i].line = line;
|
||||
nimble_mem_dbg_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= NIMBLE_MEM_DBG_INFO_MAX) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
|
||||
nimble_mem_dbg_current_size += new_size;
|
||||
if (nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) {
|
||||
nimble_mem_dbg_max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++) {
|
||||
if (nimble_mem_dbg_max_size_section[i].used &&
|
||||
nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) {
|
||||
nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
#endif // CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void *bt_osi_mem_malloc(size_t size)
|
||||
{
|
||||
void *mem = NULL;
|
||||
#ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL
|
||||
mem = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL
|
||||
mem = heap_caps_malloc(size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT
|
||||
mem = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#else
|
||||
mem = malloc(size);
|
||||
#endif
|
||||
if (!mem) {
|
||||
log_count ++;
|
||||
if ((log_count % 100) == 0) {
|
||||
ESP_EARLY_LOGI("ESP_LOG_INFO","malloc failed (size %zu)",size);
|
||||
log_count = 0;
|
||||
}
|
||||
assert(mem != NULL);
|
||||
}
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if(mem) {
|
||||
host_mem_used_size += heap_caps_get_allocated_size(mem);
|
||||
}
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
return mem;
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void *bt_osi_mem_calloc(size_t n, size_t size)
|
||||
{
|
||||
void *mem = NULL;
|
||||
#ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL
|
||||
mem = heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL
|
||||
mem = heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT
|
||||
mem = heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#else
|
||||
mem = calloc(n, size);
|
||||
#endif
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if(mem) {
|
||||
host_mem_used_size += heap_caps_get_allocated_size(mem);
|
||||
}
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
return mem;
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void bt_osi_mem_free(void *ptr)
|
||||
{
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if (ptr) {
|
||||
size_t alloc_size = heap_caps_get_allocated_size(ptr);
|
||||
// assert(host_mem_used_size >= alloc_size);
|
||||
host_mem_used_size -= alloc_size;
|
||||
}
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if (ptr) {
|
||||
heap_caps_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
size_t
|
||||
bt_osi_mem_used_size_get(void)
|
||||
{
|
||||
return host_mem_used_size;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
uint32_t esp_host_used_heap_size_get(void)
|
||||
{
|
||||
return bt_osi_mem_used_size_get();
|
||||
}
|
||||
#endif // CONFIG_BT_NIMBLE_ENABLED
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -12,23 +12,75 @@
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_task.h"
|
||||
#include "esp_assert.h"
|
||||
|
||||
#include "nimble/nimble_npl.h"
|
||||
#include "esp_bt_cfg.h"
|
||||
#include "btdm_user_cfg.h"
|
||||
|
||||
#if CONFIG_BTDM_CTRL_MODE_BLE_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
// #include "nimble/nimble_npl.h"
|
||||
#include "ble_user_cfg.h"
|
||||
#endif /* CONFIG_BTDM_CTRL_MODE_BLE_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM */
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#include "driver/uart.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_BT_HCI_TL_MAGIC_VALUE 0xfadebead
|
||||
#define ESP_BT_HCI_TL_VERSION 0x00010000
|
||||
|
||||
/**
|
||||
* @brief Bluetooth audio data transport path
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_SCO_DATA_PATH_HCI = 0, /*!< data over HCI transport */
|
||||
ESP_SCO_DATA_PATH_PCM = 1, /*!< data over PCM interface */
|
||||
} esp_sco_data_path_t;
|
||||
|
||||
/**
|
||||
* @brief Type of controller HCI transport layer
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BT_CTRL_HCI_TL_UART = 0, /*!< HCI UART h4 transport layer */
|
||||
ESP_BT_CTRL_HCI_TL_VHCI = 1, /*!< VHCI interface */
|
||||
} esp_bt_ctrl_hci_tl_t;
|
||||
|
||||
#define ESP_BT_HCI_TL_STATUS_OK (0) /*!< HCI_TL Tx/Rx operation status OK */
|
||||
|
||||
/**
|
||||
* @brief callback function for HCI Transport Layer send/receive operations
|
||||
*/
|
||||
typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status);
|
||||
|
||||
#if CONFIG_BT_CTRL_HCI_MODE_CHOICE_VHCI
|
||||
#define CFG_HCI_TL_TYPE 1
|
||||
#else
|
||||
#define CFG_HCI_TL_TYPE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Controller HCI transport layer function structure
|
||||
* This structure shall be registered when HCI transport layer is UART
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t _magic; /* Magic number */
|
||||
uint32_t _version; /* version number of the defined structure */
|
||||
uint32_t _reserved; /* reserved for future use */
|
||||
int (* _open)(void); /* hci tl open */
|
||||
void (* _close)(void); /* hci tl close */
|
||||
void (* _finish_transfers)(void); /* hci tl finish transfers */
|
||||
void (* _recv)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl recv */
|
||||
void (* _send)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl send */
|
||||
bool (* _flow_off)(void); /* hci tl flow off */
|
||||
void (* _flow_on)(void); /* hci tl flow on */
|
||||
} esp_bt_hci_tl_t;
|
||||
|
||||
/**
|
||||
* @brief Bluetooth mode for controller enable/disable
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */
|
||||
ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */
|
||||
@@ -37,9 +89,8 @@ typedef enum {
|
||||
} esp_bt_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Bluetooth controller enable/disable/initialised/de-initialised status
|
||||
* @brief Bluetooth controller enable/disable/initialised/de-initialised status.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ESP_BT_CONTROLLER_STATUS_IDLE = 0, /*!< Controller is in idle state */
|
||||
ESP_BT_CONTROLLER_STATUS_INITED, /*!< Controller is in initialising state */
|
||||
@@ -77,25 +128,31 @@ typedef enum {
|
||||
* @brief Bluetooth TX power level(index), it's just a index corresponding to power(dbm).
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_PWR_LVL_N27 = 0, /*!< Corresponding to -27dbm */
|
||||
ESP_PWR_LVL_N24 = 1, /*!< Corresponding to -24dbm */
|
||||
ESP_PWR_LVL_N21 = 2, /*!< Corresponding to -21dbm */
|
||||
ESP_PWR_LVL_N18 = 3, /*!< Corresponding to -18dbm */
|
||||
ESP_PWR_LVL_N15 = 4, /*!< Corresponding to -15dbm */
|
||||
ESP_PWR_LVL_N12 = 5, /*!< Corresponding to -12dbm */
|
||||
ESP_PWR_LVL_N9 = 6, /*!< Corresponding to -9dbm */
|
||||
ESP_PWR_LVL_N6 = 7, /*!< Corresponding to -6dbm */
|
||||
ESP_PWR_LVL_N3 = 8, /*!< Corresponding to -3dbm */
|
||||
ESP_PWR_LVL_N0 = 9, /*!< Corresponding to 0dbm */
|
||||
ESP_PWR_LVL_P3 = 10, /*!< Corresponding to +3dbm */
|
||||
ESP_PWR_LVL_P6 = 11, /*!< Corresponding to +6dbm */
|
||||
ESP_PWR_LVL_P9 = 12, /*!< Corresponding to +9dbm */
|
||||
ESP_PWR_LVL_P12 = 13, /*!< Corresponding to +12dbm */
|
||||
ESP_PWR_LVL_P15 = 14, /*!< Corresponding to +15dbm */
|
||||
ESP_PWR_LVL_P18 = 15, /*!< Corresponding to +18dbm */
|
||||
ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */
|
||||
ESP_PWR_LVL_N24 = 0, /*!< Corresponding to -24dbm */
|
||||
ESP_PWR_LVL_N21 = 1, /*!< Corresponding to -21dbm */
|
||||
ESP_PWR_LVL_N18 = 2, /*!< Corresponding to -18dbm */
|
||||
ESP_PWR_LVL_N15 = 3, /*!< Corresponding to -15dbm */
|
||||
ESP_PWR_LVL_N12 = 4, /*!< Corresponding to -12dbm */
|
||||
ESP_PWR_LVL_N9 = 5, /*!< Corresponding to -9dbm */
|
||||
ESP_PWR_LVL_N6 = 6, /*!< Corresponding to -6dbm */
|
||||
ESP_PWR_LVL_N3 = 7, /*!< Corresponding to -3dbm */
|
||||
ESP_PWR_LVL_N0 = 8, /*!< Corresponding to 0dbm */
|
||||
ESP_PWR_LVL_P3 = 9, /*!< Corresponding to +3dbm */
|
||||
ESP_PWR_LVL_P6 = 10, /*!< Corresponding to +6dbm */
|
||||
ESP_PWR_LVL_P9 = 11, /*!< Corresponding to +9dbm */
|
||||
ESP_PWR_LVL_P12 = 12, /*!< Corresponding to +12dbm */
|
||||
ESP_PWR_LVL_P15 = 13, /*!< Corresponding to +15dbm */
|
||||
ESP_PWR_LVL_P16 = 14, /*!< Corresponding to +16dbm */
|
||||
ESP_PWR_LVL_P17 = 15, /*!< Corresponding to +17dbm */
|
||||
ESP_PWR_LVL_P18 = 16, /*!< Corresponding to +18dbm */
|
||||
ESP_PWR_LVL_P19 = 17, /*!< Corresponding to +19dbm */
|
||||
ESP_PWR_LVL_P20 = 18, /*!< Corresponding to +20dbm */
|
||||
ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */
|
||||
} esp_power_level_t;
|
||||
|
||||
/**
|
||||
* @brief The enhanced type of which tx power, could set Advertising/Connection/Default and etc.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT = 0,
|
||||
ESP_BLE_ENHANCED_PWR_TYPE_ADV,
|
||||
@@ -105,11 +162,22 @@ typedef enum {
|
||||
ESP_BLE_ENHANCED_PWR_TYPE_MAX,
|
||||
} esp_ble_enhanced_power_type_t;
|
||||
|
||||
/**
|
||||
* @brief Address type and address value.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t val[6];
|
||||
uint8_t type; /*!< Type of the Bluetooth address (public, random, etc.) */
|
||||
uint8_t val[6]; /*!< Array containing the 6-byte Bluetooth address value */
|
||||
} esp_ble_addr_t;
|
||||
|
||||
/**
|
||||
* @brief Select buffers
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BLE_LOG_BUF_HCI = 0x02,
|
||||
ESP_BLE_LOG_BUF_CONTROLLER = 0x05,
|
||||
} esp_ble_log_buf_t;
|
||||
|
||||
/**
|
||||
* @brief Set BLE TX power
|
||||
* Connection Tx power should only be set after connection created.
|
||||
@@ -127,7 +195,6 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_
|
||||
*/
|
||||
esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type);
|
||||
|
||||
|
||||
/**
|
||||
* @brief ENHANCED API for Setting BLE TX power
|
||||
* Connection Tx power should only be set after connection created.
|
||||
@@ -147,119 +214,250 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type
|
||||
*/
|
||||
esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle);
|
||||
|
||||
#define CONFIG_VERSION 0x20220824
|
||||
#define CONFIG_MAGIC 0x5A5AA5A5
|
||||
#define BLE_CONFIG_VERSION 0x20241029
|
||||
#define BLE_CONFIG_MAGIC 0x5A5AA5A5
|
||||
|
||||
#define BTDM_CONFIG_VERSION 0x20260127
|
||||
#define BTDM_CONFIG_MAGIC_VALUE 0x5a5aa5a5
|
||||
|
||||
/* Types definition
|
||||
************************************************************************
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
uint16_t task_stack_size; /*!< Size of Bluetooth controller task stack */
|
||||
uint8_t task_prio; /*!< Priority of the Bluetooth controller task */
|
||||
uint8_t task_run_cpu; /*!< CPU number on which the Bluetooth controller task runs */
|
||||
uint8_t hci_cmd_num; /*!< HCI command buffer number */
|
||||
uint8_t hci_conn_num; /*!< HCI level connection number */
|
||||
uint8_t sleep_en;
|
||||
uint8_t version_num;
|
||||
uint8_t bluetooth_mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */
|
||||
uint32_t magic;
|
||||
}esp_btdm_controller_config_t;
|
||||
|
||||
/**
|
||||
* @brief Controller config options, depend on config mask.
|
||||
* Config mask indicate which functions enabled, this means
|
||||
* some options or parameters of some functions enabled by config mask.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t config_version;
|
||||
uint16_t ble_ll_resolv_list_size;
|
||||
uint16_t ble_hci_evt_hi_buf_count;
|
||||
uint16_t ble_hci_evt_lo_buf_count;
|
||||
uint8_t ble_ll_sync_list_cnt;
|
||||
uint8_t ble_ll_sync_cnt;
|
||||
uint16_t ble_ll_rsp_dup_list_count;
|
||||
uint16_t ble_ll_adv_dup_list_count;
|
||||
uint8_t ble_ll_tx_pwr_dbm;
|
||||
uint64_t rtc_freq;
|
||||
uint16_t ble_ll_sca;
|
||||
uint8_t ble_ll_scan_phy_number;
|
||||
uint16_t ble_ll_conn_def_auth_pyld_tmo;
|
||||
uint8_t ble_ll_jitter_usecs;
|
||||
uint16_t ble_ll_sched_max_adv_pdu_usecs;
|
||||
uint16_t ble_ll_sched_direct_adv_max_usecs;
|
||||
uint16_t ble_ll_sched_adv_max_usecs;
|
||||
uint16_t ble_scan_rsp_data_max_len;
|
||||
uint8_t ble_ll_cfg_num_hci_cmd_pkts;
|
||||
uint32_t ble_ll_ctrl_proc_timeout_ms;
|
||||
uint16_t nimble_max_connections;
|
||||
uint8_t ble_whitelist_size;
|
||||
uint16_t ble_acl_buf_size;
|
||||
uint16_t ble_acl_buf_count;
|
||||
uint16_t ble_hci_evt_buf_size;
|
||||
uint16_t ble_multi_adv_instances;
|
||||
uint16_t ble_ext_adv_max_size;
|
||||
uint16_t controller_task_stack_size;
|
||||
uint8_t controller_task_prio;
|
||||
uint8_t controller_run_cpu;
|
||||
uint8_t enable_qa_test;
|
||||
uint8_t enable_bqb_test;
|
||||
uint8_t enable_uart_hci;
|
||||
uint8_t ble_hci_uart_port;
|
||||
uint32_t ble_hci_uart_baud;
|
||||
uint8_t ble_hci_uart_data_bits;
|
||||
uint8_t ble_hci_uart_stop_bits;
|
||||
uint8_t ble_hci_uart_flow_ctrl;
|
||||
uint8_t ble_hci_uart_uart_parity;
|
||||
uint8_t enable_tx_cca;
|
||||
uint8_t cca_rssi_thresh;
|
||||
uint8_t sleep_en;
|
||||
uint8_t coex_phy_coded_tx_rx_time_limit;
|
||||
uint8_t dis_scan_backoff;
|
||||
uint8_t ble_scan_classify_filter_enable;
|
||||
uint8_t cca_drop_mode;
|
||||
int8_t cca_low_tx_pwr;
|
||||
uint8_t main_xtal_freq;
|
||||
uint32_t config_magic;
|
||||
struct {
|
||||
uint32_t config_version; /*!< Version number of the defined structure */
|
||||
uint16_t ble_ll_resolv_list_size; /*!< Size of the resolvable private address list */
|
||||
uint16_t ble_hci_evt_hi_buf_count; /*!< Count of high buffers for HCI events */
|
||||
uint16_t ble_hci_evt_lo_buf_count; /*!< Count of low buffers for HCI events */
|
||||
uint8_t ble_ll_sync_list_cnt; /*!< Number of synchronization lists */
|
||||
uint8_t ble_ll_sync_cnt; /*!< Number of synchronizations */
|
||||
uint16_t ble_ll_rsp_dup_list_count; /*!< Count of duplicated lists for scan response packets */
|
||||
uint16_t ble_ll_adv_dup_list_count; /*!< Count of duplicated lists for advertising packets */
|
||||
uint8_t ble_ll_tx_pwr_dbm; /*!< Tx power (transmit power) in dBm */
|
||||
uint64_t rtc_freq; /*!< Frequency of RTC (Real-Time Clock) */
|
||||
uint16_t ble_ll_sca; /*!< Sleep Clock Accuracy (SCA) parameter */
|
||||
uint8_t ble_ll_scan_phy_number; /*!< Number of PHYs supported for scanning */
|
||||
uint16_t ble_ll_conn_def_auth_pyld_tmo; /*!< Connection default authentication payload timeout */
|
||||
uint8_t ble_ll_jitter_usecs; /*!< Jitter time in microseconds */
|
||||
uint16_t ble_ll_sched_max_adv_pdu_usecs; /*!< Maximum time in microseconds for advertising PDU scheduling */
|
||||
uint16_t ble_ll_sched_direct_adv_max_usecs; /*!< Maximum time in microseconds for directed advertising scheduling */
|
||||
uint16_t ble_ll_sched_adv_max_usecs; /*!< Maximum time in microseconds for advertising scheduling */
|
||||
uint16_t ble_scan_rsp_data_max_len; /*!< Maximum length of scan response data */
|
||||
uint8_t ble_ll_cfg_num_hci_cmd_pkts; /*!< Number of HCI command packets that can be queued */
|
||||
uint32_t ble_ll_ctrl_proc_timeout_ms; /*!< Control processing timeout in milliseconds */
|
||||
uint16_t nimble_max_connections; /*!< Maximum number of connections supported */
|
||||
uint8_t ble_whitelist_size; /*!< Size of the white list */
|
||||
uint16_t ble_acl_buf_size; /*!< Buffer size of ACL (Asynchronous Connection-Less) data */
|
||||
uint16_t ble_acl_buf_count; /*!< Buffer count of ACL data */
|
||||
uint16_t ble_hci_evt_buf_size; /*!< Buffer size for HCI event data */
|
||||
uint16_t ble_multi_adv_instances; /*!< Number of advertising instances */
|
||||
uint16_t ble_ext_adv_max_size; /*!< Maximum size of extended advertising data */
|
||||
uint16_t controller_task_stack_size; /*!< Size of Bluetooth controller task stack, to be removed */
|
||||
uint8_t controller_task_prio; /*!< Priority of the Bluetooth task, to be removed */
|
||||
uint8_t controller_run_cpu; /*!< CPU number on which the Bluetooth controller task runs, to be removed */
|
||||
uint8_t enable_qa_test; /*!< Enable for QA test */
|
||||
uint8_t enable_bqb_test; /*!< Enable for BQB test */
|
||||
uint8_t enable_tx_cca; /*!< Enable Clear Channel Assessment (CCA) when transmitting */
|
||||
uint8_t cca_rssi_thresh; /*!< RSSI threshold for CCA */
|
||||
uint8_t sleep_en; /*!< Enable sleep functionality */
|
||||
uint8_t coex_phy_coded_tx_rx_time_limit; /*!< Coexistence PHY coded TX and RX time limit */
|
||||
uint8_t dis_scan_backoff; /*!< Disable scan backoff */
|
||||
uint8_t ble_scan_classify_filter_enable; /*!< Enable classification filter for BLE scan */
|
||||
uint8_t cca_drop_mode; /*!< CCA drop mode */
|
||||
int8_t cca_low_tx_pwr; /*!< Low TX power setting for CCA */
|
||||
uint8_t main_xtal_freq; /*!< Main crystal frequency */
|
||||
uint8_t ignore_wl_for_direct_adv; /*!< Ignore the white list for directed advertising */
|
||||
uint8_t enable_pcl; /*!< Enable power control */
|
||||
uint8_t csa2_select;
|
||||
uint8_t enable_csr;
|
||||
int8_t backoff_rssi;
|
||||
bool iso_enabled;
|
||||
bool iso_bqb_test;
|
||||
bool iso_fra_unseg;
|
||||
bool iso_nsfc_en;
|
||||
uint8_t iso_nsfc_num;
|
||||
uint8_t iso_buf_count;
|
||||
uint16_t iso_buf_size;
|
||||
uint8_t iso_big_count;
|
||||
uint16_t iso_bis_count;
|
||||
uint8_t iso_bis_per_big;
|
||||
uint8_t iso_cig_count;
|
||||
uint16_t iso_cis_count;
|
||||
uint8_t iso_cis_per_cig;
|
||||
uint32_t config_magic; /*!< Configuration magic value */
|
||||
} ble; /* Bluetooth LE controller configuration options */
|
||||
|
||||
esp_btdm_controller_config_t btdm; /*!< BTDM controller common configuration options */ /*!< BTDM controller common configuration options */
|
||||
} esp_bt_controller_config_t;
|
||||
|
||||
#if defined(CONFIG_BTDM_CTRL_MODE_BLE_ONLY)
|
||||
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BLE
|
||||
#elif defined(CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY)
|
||||
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_CLASSIC_BT
|
||||
#else
|
||||
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BTDM
|
||||
#endif
|
||||
|
||||
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
|
||||
.config_version = CONFIG_VERSION, \
|
||||
.ble_ll_resolv_list_size = CONFIG_BT_LE_LL_RESOLV_LIST_SIZE, \
|
||||
.ble_hci_evt_hi_buf_count = DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT, \
|
||||
.ble_hci_evt_lo_buf_count = DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT, \
|
||||
.ble_ll_sync_list_cnt = DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST, \
|
||||
.ble_ll_sync_cnt = DEFAULT_BT_LE_MAX_PERIODIC_SYNCS, \
|
||||
.ble_ll_rsp_dup_list_count = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT, \
|
||||
.ble_ll_adv_dup_list_count = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT, \
|
||||
.ble_ll_tx_pwr_dbm = BLE_LL_TX_PWR_DBM_N, \
|
||||
.rtc_freq = RTC_FREQ_N, \
|
||||
.ble_ll_sca = CONFIG_BT_LE_LL_SCA, \
|
||||
.ble_ll_scan_phy_number = BLE_LL_SCAN_PHY_NUMBER_N, \
|
||||
.ble_ll_conn_def_auth_pyld_tmo = BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N, \
|
||||
.ble_ll_jitter_usecs = BLE_LL_JITTER_USECS_N, \
|
||||
.ble_ll_sched_max_adv_pdu_usecs = BLE_LL_SCHED_MAX_ADV_PDU_USECS_N, \
|
||||
.ble_ll_sched_direct_adv_max_usecs = BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N, \
|
||||
.ble_ll_sched_adv_max_usecs = BLE_LL_SCHED_ADV_MAX_USECS_N, \
|
||||
.ble_scan_rsp_data_max_len = DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N, \
|
||||
.ble_ll_cfg_num_hci_cmd_pkts = BLE_LL_CFG_NUM_HCI_CMD_PKTS_N, \
|
||||
.ble_ll_ctrl_proc_timeout_ms = BLE_LL_CTRL_PROC_TIMEOUT_MS_N, \
|
||||
.nimble_max_connections = DEFAULT_BT_LE_MAX_CONNECTIONS, \
|
||||
.ble_whitelist_size = DEFAULT_BT_NIMBLE_WHITELIST_SIZE, \
|
||||
.ble_acl_buf_size = DEFAULT_BT_LE_ACL_BUF_SIZE, \
|
||||
.ble_acl_buf_count = DEFAULT_BT_LE_ACL_BUF_COUNT, \
|
||||
.ble_hci_evt_buf_size = DEFAULT_BT_LE_HCI_EVT_BUF_SIZE, \
|
||||
.ble_multi_adv_instances = DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES, \
|
||||
.ble_ext_adv_max_size = DEFAULT_BT_LE_EXT_ADV_MAX_SIZE, \
|
||||
.controller_task_stack_size = NIMBLE_LL_STACK_SIZE, \
|
||||
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
|
||||
.controller_run_cpu = 0, \
|
||||
.enable_qa_test = RUN_QA_TEST, \
|
||||
.enable_bqb_test = RUN_BQB_TEST, \
|
||||
.enable_uart_hci = HCI_UART_EN, \
|
||||
.ble_hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \
|
||||
.ble_hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \
|
||||
.ble_hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \
|
||||
.ble_hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \
|
||||
.ble_hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \
|
||||
.ble_hci_uart_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \
|
||||
.enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \
|
||||
.cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \
|
||||
.cca_drop_mode = 0, \
|
||||
.cca_low_tx_pwr = 0, \
|
||||
.sleep_en = NIMBLE_SLEEP_ENABLE, \
|
||||
.coex_phy_coded_tx_rx_time_limit = DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF, \
|
||||
.ble_scan_classify_filter_enable = 0, \
|
||||
.main_xtal_freq = CONFIG_XTAL_FREQ, \
|
||||
.config_magic = CONFIG_MAGIC, \
|
||||
#if defined(CONFIG_BT_CTRL_BR_EDR_TEST_MODE_EN)
|
||||
#define BT_CTRL_BR_EDR_TEST_MODE_EN 1
|
||||
#else
|
||||
#define BT_CTRL_BR_EDR_TEST_MODE_EN 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_BT_CTRL_BR_EDR_DTM_EN_EFF
|
||||
#define CONFIG_BT_CTRL_BR_EDR_DTM_EN_EFF false
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_CTRL_BR_EDR_TX_CCA_ENABLED)
|
||||
#define BT_CTRL_BR_EDR_TX_CCA_ENABLED (CONFIG_BT_CTRL_BR_EDR_TX_CCA_ENABLED)
|
||||
#else
|
||||
#define BT_CTRL_BR_EDR_TX_CCA_ENABLED (0)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_CTRL_BR_EDR_CCA_RSSI_THRESH)
|
||||
#define BT_CTRL_BR_EDR_CCA_RSSI_THRESH (CONFIG_BT_CTRL_BR_EDR_CCA_RSSI_THRESH)
|
||||
#else
|
||||
#define BT_CTRL_BR_EDR_CCA_RSSI_THRESH (50)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_ISO_SUPPORT)
|
||||
#define DEFAULT_BT_LE_ISO_ENABLED 1
|
||||
#if defined(CONFIG_BT_LE_ISO_FRA_UNSEG)
|
||||
#define DEFAULT_BT_LE_ISO_FRA_UNSEG CONFIG_BT_LE_ISO_FRA_UNSEG
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ISO_FRA_UNSEG (0)
|
||||
#endif
|
||||
#if defined(CONFIG_BT_LE_ISO_NSFC_EN)
|
||||
#define DEFAULT_BT_LE_ISO_NSFC_EN CONFIG_BT_LE_ISO_NSFC_EN
|
||||
#define DEFAULT_BT_LE_ISO_NSFC_NUM CONFIG_BT_LE_ISO_NSFC_NUM
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ISO_NSFC_EN (0)
|
||||
#define DEFAULT_BT_LE_ISO_NSFC_NUM (0)
|
||||
#endif
|
||||
#define DEFAULT_BT_LE_ISO_BUF_COUNT CONFIG_BT_LE_ISO_BUF_COUNT
|
||||
#define DEFAULT_BT_LE_ISO_BUF_SIZE CONFIG_BT_LE_ISO_BUF_SIZE
|
||||
#define DEFAULT_BT_LE_ISO_BIG CONFIG_BT_LE_ISO_BIG
|
||||
#define DEFAULT_BT_LE_ISO_BIS CONFIG_BT_LE_ISO_BIS
|
||||
#define DEFAULT_BT_LE_ISO_BIS_PER_BIG CONFIG_BT_LE_ISO_BIS_PER_BIG
|
||||
#define DEFAULT_BT_LE_ISO_CIG CONFIG_BT_LE_ISO_CIG
|
||||
#define DEFAULT_BT_LE_ISO_CIS CONFIG_BT_LE_ISO_CIS
|
||||
#define DEFAULT_BT_LE_ISO_CIS_PER_CIG CONFIG_BT_LE_ISO_CIS_PER_CIG
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ISO_ENABLED 0
|
||||
#define DEFAULT_BT_LE_ISO_FRA_UNSEG 0
|
||||
#define DEFAULT_BT_LE_ISO_NSFC_EN 0
|
||||
#define DEFAULT_BT_LE_ISO_NSFC_NUM 0
|
||||
#define DEFAULT_BT_LE_ISO_BUF_COUNT 0
|
||||
#define DEFAULT_BT_LE_ISO_BUF_SIZE 0
|
||||
#define DEFAULT_BT_LE_ISO_BIG 0
|
||||
#define DEFAULT_BT_LE_ISO_BIS 0
|
||||
#define DEFAULT_BT_LE_ISO_BIS_PER_BIG 0
|
||||
#define DEFAULT_BT_LE_ISO_CIG 0
|
||||
#define DEFAULT_BT_LE_ISO_CIS 0
|
||||
#define DEFAULT_BT_LE_ISO_CIS_PER_CIG 0
|
||||
#endif
|
||||
|
||||
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
|
||||
.ble = { \
|
||||
.config_version = BLE_CONFIG_VERSION, \
|
||||
.ble_ll_resolv_list_size = CONFIG_BT_LE_LL_RESOLV_LIST_SIZE, \
|
||||
.ble_hci_evt_hi_buf_count = DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT, \
|
||||
.ble_hci_evt_lo_buf_count = DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT, \
|
||||
.ble_ll_sync_list_cnt = DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST, \
|
||||
.ble_ll_sync_cnt = DEFAULT_BT_LE_MAX_PERIODIC_SYNCS, \
|
||||
.ble_ll_rsp_dup_list_count = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT, \
|
||||
.ble_ll_adv_dup_list_count = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT, \
|
||||
.ble_ll_tx_pwr_dbm = 0, \
|
||||
.rtc_freq = 32000, \
|
||||
.ble_ll_sca = CONFIG_BT_LE_LL_SCA, \
|
||||
.ble_ll_scan_phy_number = BLE_LL_SCAN_PHY_NUMBER_N, \
|
||||
.ble_ll_conn_def_auth_pyld_tmo = BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N, \
|
||||
.ble_ll_jitter_usecs = BLE_LL_JITTER_USECS_N, \
|
||||
.ble_ll_sched_max_adv_pdu_usecs = BLE_LL_SCHED_MAX_ADV_PDU_USECS_N, \
|
||||
.ble_ll_sched_direct_adv_max_usecs = BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N, \
|
||||
.ble_ll_sched_adv_max_usecs = BLE_LL_SCHED_ADV_MAX_USECS_N, \
|
||||
.ble_scan_rsp_data_max_len = DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N, \
|
||||
.ble_ll_cfg_num_hci_cmd_pkts = BLE_LL_CFG_NUM_HCI_CMD_PKTS_N, \
|
||||
.ble_ll_ctrl_proc_timeout_ms = BLE_LL_CTRL_PROC_TIMEOUT_MS_N, \
|
||||
.nimble_max_connections = DEFAULT_BT_LE_MAX_CONNECTIONS, \
|
||||
.ble_whitelist_size = DEFAULT_BT_NIMBLE_WHITELIST_SIZE, \
|
||||
.ble_acl_buf_size = DEFAULT_BT_LE_ACL_BUF_SIZE, \
|
||||
.ble_acl_buf_count = DEFAULT_BT_LE_ACL_BUF_COUNT, \
|
||||
.ble_hci_evt_buf_size = DEFAULT_BT_LE_HCI_EVT_BUF_SIZE, \
|
||||
.ble_multi_adv_instances = DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES, \
|
||||
.ble_ext_adv_max_size = DEFAULT_BT_LE_EXT_ADV_MAX_SIZE, \
|
||||
.controller_task_stack_size = UC_BT_CTRL_TASK_STACK_SIZE, \
|
||||
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
|
||||
.controller_run_cpu = 0, \
|
||||
.enable_qa_test = RUN_QA_TEST, \
|
||||
.enable_bqb_test = RUN_BQB_TEST, \
|
||||
.enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \
|
||||
.cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \
|
||||
.sleep_en = UC_BT_CTRL_SLEEP_ENABLE, \
|
||||
.coex_phy_coded_tx_rx_time_limit = DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF, \
|
||||
.dis_scan_backoff = NIMBLE_DISABLE_SCAN_BACKOFF, \
|
||||
.ble_scan_classify_filter_enable = 1, \
|
||||
.main_xtal_freq = CONFIG_XTAL_FREQ, \
|
||||
.ignore_wl_for_direct_adv = 0, \
|
||||
.enable_pcl = 0, \
|
||||
.csa2_select = 1, \
|
||||
.enable_csr = 0, \
|
||||
.backoff_rssi = -100, \
|
||||
.iso_enabled = DEFAULT_BT_LE_ISO_ENABLED, \
|
||||
.iso_bqb_test = false, \
|
||||
.iso_fra_unseg = DEFAULT_BT_LE_ISO_FRA_UNSEG, \
|
||||
.iso_nsfc_en = DEFAULT_BT_LE_ISO_NSFC_EN, \
|
||||
.iso_nsfc_num = DEFAULT_BT_LE_ISO_NSFC_NUM, \
|
||||
.iso_buf_count = DEFAULT_BT_LE_ISO_BUF_COUNT, \
|
||||
.iso_buf_size = DEFAULT_BT_LE_ISO_BUF_SIZE, \
|
||||
.iso_big_count = DEFAULT_BT_LE_ISO_BIG, \
|
||||
.iso_bis_count = DEFAULT_BT_LE_ISO_BIS, \
|
||||
.iso_bis_per_big = DEFAULT_BT_LE_ISO_BIS_PER_BIG, \
|
||||
.iso_cig_count = DEFAULT_BT_LE_ISO_CIG, \
|
||||
.iso_cis_count = DEFAULT_BT_LE_ISO_CIS, \
|
||||
.iso_cis_per_cig = DEFAULT_BT_LE_ISO_CIS_PER_CIG, \
|
||||
.config_magic = BLE_CONFIG_MAGIC, \
|
||||
}, \
|
||||
.btdm = { \
|
||||
.version = BTDM_CONFIG_VERSION, \
|
||||
.task_stack_size = UC_BT_CTRL_TASK_STACK_SIZE, \
|
||||
.task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
|
||||
.task_run_cpu = CONFIG_BT_CTRL_PINNED_TO_CORE, \
|
||||
.hci_cmd_num = CONFIG_BT_CTRL_HCI_CMD_NUM, \
|
||||
.hci_conn_num = DEFAULT_BT_LE_MAX_CONNECTIONS + DEFAULT_BT_LE_ISO_CIS + DEFAULT_BT_LE_ISO_BIS, \
|
||||
.sleep_en = UC_BT_CTRL_SLEEP_ENABLE, \
|
||||
.version_num = 0, \
|
||||
.bluetooth_mode = BTDM_CONTROLLER_MODE_EFF, \
|
||||
.magic = BTDM_CONFIG_MAGIC_VALUE, \
|
||||
}, \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize BT controller to allocate task and other resource.
|
||||
* This function should be called only once, before any other BT functions are called.
|
||||
* @param cfg: Initial configuration of BT controller. Different from previous version, there's a mode and some
|
||||
* connection configuration in "cfg" to configure controller work mode and allocate the resource which is needed.
|
||||
* @return ESP_OK - success, other - failed
|
||||
*/
|
||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg);
|
||||
|
||||
/**
|
||||
@@ -267,11 +465,53 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg);
|
||||
* @return status value
|
||||
*/
|
||||
esp_bt_controller_status_t esp_bt_controller_get_status(void);
|
||||
|
||||
/**
|
||||
* @brief Get BLE TX power
|
||||
* Connection Tx power should only be get after connection created.
|
||||
* @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc
|
||||
* @return >= 0 - Power level, < 0 - Invalid
|
||||
*/
|
||||
esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type);
|
||||
|
||||
/**
|
||||
* @brief De-initialize BT controller to free resource and delete task.
|
||||
* You should stop advertising and scanning, as well as
|
||||
* disconnect all existing connections before de-initializing BT controller.
|
||||
*
|
||||
* This function should be called only once, after any other BT functions are called.
|
||||
* This function is not whole completed, esp_bt_controller_init cannot called after this function.
|
||||
* @return ESP_OK - success, other - failed
|
||||
*/
|
||||
esp_err_t esp_bt_controller_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Enable BT controller.
|
||||
* Due to a known issue, you cannot call esp_bt_controller_enable() a second time
|
||||
* to change the controller mode dynamically. To change controller mode, call
|
||||
* esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode.
|
||||
* @param 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().
|
||||
* @return ESP_OK - success, other - failed
|
||||
*/
|
||||
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Disable BT controller
|
||||
* @return ESP_OK - success, other - failed
|
||||
*/
|
||||
esp_err_t esp_bt_controller_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Get BT controller is initialised/de-initialised/enabled/disabled
|
||||
* @return status value
|
||||
*/
|
||||
esp_bt_controller_status_t esp_bt_controller_get_status(void);
|
||||
|
||||
|
||||
/** @brief esp_vhci_host_callback
|
||||
* used for vhci call host function to notify what host need to do
|
||||
*/
|
||||
typedef struct esp_vhci_host_callback {
|
||||
void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */
|
||||
int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/
|
||||
@@ -359,9 +599,20 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode);
|
||||
*/
|
||||
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode);
|
||||
|
||||
/* Returns random static address or -1 if not present */
|
||||
/**
|
||||
* @brief Returns random static address or -1 if not present.
|
||||
* @return ESP_OK - success, other - failed
|
||||
*/
|
||||
extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr);
|
||||
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
/**
|
||||
* @brief dump all log information cached in buffers.
|
||||
* @param output : true for log dump, false will take no effect
|
||||
*/
|
||||
void esp_ble_controller_log_dump_all(bool output);
|
||||
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// @brief HCI VS Commands for Espressif's Bluetooth Host
|
||||
//
|
||||
// @note The following vendor-specific HCI commands are exclusively for Espressif's Bluetooth Host (ESP-Bluedroid Host or ESP-NimBLE Host).
|
||||
// If you are using a non-ESP host or HCI UART, these commands will remain disabled unless the initialization function is explicitly called from the application.
|
||||
// Note, these init functions as well as these additional HCI VS commands are intended for Espressif's Bluetooth Host use only.
|
||||
// Application developers **should not** call the init functions in their applications.
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief Config scanning duplicate exceptional list (OCF: 0x0108)
|
||||
*
|
||||
* @note The init function is `advFilter_stack_eanbleDupExcListCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_CONFIG_DUP_EXC_LIST_OCF (0x0108)
|
||||
/**
|
||||
* @brief Update exception list cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_update_exc_list {
|
||||
uint8_t subcode; /*!< Add, remove or clear exception list */
|
||||
uint32_t type; /*!< device type */
|
||||
uint8_t device_info[6]; /*!< device information */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enable/disable advertising report flow control (OCF: 0x0109)
|
||||
*
|
||||
* @note The init function is `scan_stack_enableAdvFlowCtrlVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_SET_ADV_REPORT_FLOW_CTRL_OCF (0x0109)
|
||||
/**
|
||||
* @brief Init ADV flow control cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_init_adv_flow_ctrl {
|
||||
uint8_t enable; /*!< Enable ADV flow control */
|
||||
uint16_t num; /*!< ADV buffer maximum value */
|
||||
uint16_t adv_lost_threshold; /*!< ADV lost event triggered threshold */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Update the number of advertising report in ADV flow control (OCF: 0x010A)
|
||||
*
|
||||
* @note The init function is `scan_stack_enableAdvFlowCtrlVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_UPD_ADV_REPORT_FLOW_CTRL_NUM_OCF (0x010a)
|
||||
/**
|
||||
* @brief Update ADV flow control cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_update_adv_flow_ctrl {
|
||||
uint16_t num; /*!< The number of ADV report processed */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Clear legacy advertising (same as HCI_LE_Clear_Advertising_Sets) (OCF: 0x010C)
|
||||
*
|
||||
* @note The init function is `adv_stack_enableClearLegacyAdvVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_CLR_LEGACY_ADV_OCF (0x010c)
|
||||
/**
|
||||
* @brief Clear legacy ADV cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_clr_legacy_adv {
|
||||
// no parameters
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set parameters of duplicate list (OCF: 0x010D)
|
||||
*
|
||||
* @note The init function is `advFilter_stack_eanbleDupExcListCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_SET_DUP_LIST_PARAMS_OCF (0x010d)
|
||||
/**
|
||||
* @brief Set duplicate list cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_set_dup_params {
|
||||
uint8_t dup_mode; /*!< Duplicate mode */
|
||||
uint8_t dup_ad_type; /*!< Duplicate data type */
|
||||
uint16_t ring_list_max_num; /*!< Duplicate list size */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enable/disable duplicate and exception list (OCF: 0x010E)
|
||||
*
|
||||
* @note The init function is `advFilter_stack_eanbleDupExcListCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_ENABLE_DUP_EXC_LIST_OCF (0x010e)
|
||||
/**
|
||||
* @brief Enable duplicate and exception list cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_enable_dup_exc {
|
||||
uint8_t enable; /*!< Enable or disable */
|
||||
uint8_t ring_list_reset; /*!< Reset list */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enable optimization of multiple connections (OCF: 0x010F)
|
||||
*
|
||||
* @note The init function is `arr_stack_enableMultiConnVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_ENABLE_ARRANGEMENT_OCF (0x010f)
|
||||
/**
|
||||
* @brief Multiple connections optimization cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_enable_arrangement {
|
||||
uint32_t common_factor; /*!< The greatest common factor of connection interval */
|
||||
uint8_t enable; /*!< Enable or disable */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set scheduling length for a certain role (OCF: 0x0110)
|
||||
*
|
||||
* @note The init function is `arr_stack_enableMultiConnVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_SET_SCHED_ROLE_LEN_OCF (0x0110)
|
||||
/**
|
||||
* @brief Scheduling length cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_set_sched_role_len {
|
||||
uint8_t role; /*!< BLE role; 0: central; 1: peripheral */
|
||||
uint32_t len; /*!< Length is us */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set RSSI threshold for automatic power control (OCF: 0x0111)
|
||||
*
|
||||
* @note The init function is `pcl_stack_enableSetRssiThreshVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_SET_PCL_RSSI_THRESH_OCF (0x0111)
|
||||
/**
|
||||
* @brief PCL RSSI threshold cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_set_pcl_rssi_thresh {
|
||||
uint16_t conn_handle; /*!< Connection handle */
|
||||
uint8_t rssi_thresh_min_1M; /*!< Lower limit for 1M */
|
||||
uint8_t rssi_thresh_max_1M; /*!< Upper limit for 1M */
|
||||
uint8_t rssi_thresh_min_2M; /*!< Lower limit for 2M */
|
||||
uint8_t rssi_thresh_max_2M; /*!< Upper limit for 2M */
|
||||
uint8_t rssi_thresh_min_s2coded; /*!< Lower limit for s2 coded */
|
||||
uint8_t rssi_thresh_max_s2coded; /*!< Upper limit for s2 coded */
|
||||
uint8_t rssi_thresh_min_s8coded; /*!< Lower limit for s8 coded */
|
||||
uint8_t rssi_thresh_max_s8coded; /*!< Upper limit for s8 coded */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enable/disable channel selection algorithm #2 (OCF: 0x0112)
|
||||
*
|
||||
* @note The init function is `chanSel_stack_enableSetCsaVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_ENABLE_CSA2_OCF (0x0112)
|
||||
/**
|
||||
* @brief Enable/disable channel selection algorithm #2 cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_csa_enable {
|
||||
uint8_t csa2_select; /*!< Select CSA2 */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set parameters of controller logs (OCF: 0x0114)
|
||||
*
|
||||
* @note The init function is `log_stack_enableLogsRelatedVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_SET_LOG_PARAMS_OCF (0x0114)
|
||||
/**
|
||||
* @brief Controller logs cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_log_params {
|
||||
uint8_t type; /*!< Operation type */
|
||||
uint32_t output_enable; /*!< Enable/disable output */
|
||||
uint8_t buffer_optoin /*!< Select log buffers */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set BLE vendor events mask (OCF: 0x0116)
|
||||
*
|
||||
* @note The init function is `hci_stack_enableSetVsEvtMaskVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_SET_LE_VENDOR_EVTS_MASK_OCF (0x0116)
|
||||
/**
|
||||
* @brief Set BLE vendor events mask cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_set_vs_evts_mask {
|
||||
uint32_t evt_masks; /*!< BLE vendor events Mask */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set peer sleep clock accuracy to a constant value (OCF: 0x0118)
|
||||
*
|
||||
* @note The init function is `winWiden_stack_enableSetConstPeerScaVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_SET_CONST_PEER_SCA_OCF (0x0118)
|
||||
/**
|
||||
* @brief Peer constant SCA cmd parameters
|
||||
*/
|
||||
struct bt_hci_vs_ble_set_const_peer_sca {
|
||||
uint16_t peer_sca; /*!< Peer SCA */
|
||||
};
|
||||
|
||||
// @brief HCI VS Events for Espressif's Bluetooth Host
|
||||
//
|
||||
// @note The following HCI VS events are exclusively for Espressif's Bluetooth Host (ESP-Bluedroid Host or ESP-NimBLE Host).
|
||||
// If you are using a non-ESP host or HCI UART, these events will remain disabled unless the initialization function is explicitly called from the application.
|
||||
// Note, these init functions as well as these additional HCI VS events are intended for Espressif's Bluetooth Host use only.
|
||||
// Application developers **should not** call the init functions in their applications.
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief BLE Scan/Connect Request, Aux Connect Response received event (EVTCODE: 0xFF, SUBCODE: 0xC0)
|
||||
*
|
||||
* @note The init function is `adv_stack_enableScanReqRxdVsEvent(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_LE_CONN_SCAN_REQ_RXED_EVT_SUBCODE (0xC0)
|
||||
/**
|
||||
* @brief BLE Scan/Connect Request, Aux Connect Response received event parameters
|
||||
*/
|
||||
struct bt_hci_vs_le_conn_scan_req_rxed_evt {
|
||||
uint8_t evt_type; /*!< Event type; 0: SCAN_REQ; 1: CONN_IND */
|
||||
uint8_t handle; /*!< Advertisement handle */
|
||||
uint8_t peer_addr_type; /*!< Peer address type */
|
||||
uint8_t peer_addr[6]; /*!< Peer address */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief BLE Channel Map Update Completion event (EVTCODE: 0xFF, SUBCODE: 0xC1)
|
||||
*
|
||||
* @note The init function is `conn_stack_enableChanMapUpdCompVsEvent(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_LE_CHAN_UPDATE_COMP_EVT_SUBCODE (0xC1)
|
||||
/**
|
||||
* @brief BLE Channel Map Update Completion event parameters
|
||||
*/
|
||||
struct bt_hci_vs_le_chan_update_comp_evt {
|
||||
uint8_t status; /*!< Controller error code */
|
||||
uint16_t handle; /*!< Connection handle */
|
||||
uint8_t ch_map[5]; /*!< Updated channel map */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief BLE Wakeup From Sleep event (EVTCODE: 0xFF, SUBCODE: 0xC3)
|
||||
*
|
||||
* @note The init function is `sleep_stack_enableWakeupVsEvent(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_LE_SLEEP_WAKEUP_EVT_SUBCODE (0xC3)
|
||||
/**
|
||||
* @brief BLE wakeup event parameters
|
||||
*/
|
||||
struct bt_hci_vs_le_sleep_wakeup_evt {
|
||||
// no parameters
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief BLE advertising report lost event for flow control (EVTCODE: 0x3E, SUBCODE: 0xF0)
|
||||
*
|
||||
* @note The init function is `scan_stack_enableAdvFlowCtrlVsCmd(true)`
|
||||
*/
|
||||
#define ESP_BT_VS_LE_ADV_LOST_EVT_SUBCODE (0xF0)
|
||||
/**
|
||||
* @brief ADV lost event parameters
|
||||
*/
|
||||
struct bt_hci_vs_le_adv_lost_evt {
|
||||
uint32_t nb_lost; /*!< The number of ADV report discarded */
|
||||
};
|
||||
|
||||
//
|
||||
// @brief HCI VS Commands for Espressif's Internal-Use Debugging
|
||||
//
|
||||
// @note The following HCI VS debugging commands are implemented in Bluetooth controller pre-compiled libraries.
|
||||
// These commands are not linked into the application binary, unless the function `esp_ble_internalTestFeaturesEnable(true)`is called from the application.
|
||||
// They are intended for Espressif's internal use only. Application developers **should not** call `esp_ble_internalTestFeaturesEnable(true)` in their applications.
|
||||
//
|
||||
|
||||
#define ESP_BT_VS_CFG_TEST_RELATED_OCF (0x0113)
|
||||
#define ESP_BT_VS_CFG_TEST_ENABLE_SUBCMD (0X00)
|
||||
#define ESP_BT_VS_CFG_TEST_ENABLE_ADV_DELAY_SUBCMD (0X01)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_PREF_CODED_SUBCMD (0X02)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_DEFAULT_PRIV_MODE_SUBCMD (0X03)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_SCAN_FOREVER_SUBCMD (0X04)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_EXPECTED_PEER_SUBCMD (0X05)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_ADV_TXED_CNT_SUBCMD (0X06)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_SCAN_RXED_CNT_SUBCMD (0X07)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_TXPWR_LVL_SUBCMD (0X08)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_TXPWR_LVL_SUBCMD (0X09)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_TXPWR_LVL_ENH_SUBCMD (0X0a)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_TXPWR_LVL_ENH_SUBCMD (0X0b)
|
||||
#define ESP_BT_VS_CFG_TEST_IGNORE_WL_FOR_DIR_ADV_SUBCMD (0X0c)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_ADV_RXED_RSSI_SUBCMD (0X0d)
|
||||
#define ESP_BT_VS_CFG_TEST_ENABLE_CCA_SUBCMD (0X0e)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_CCA_WIN_SUBCMD (0X0f)
|
||||
#define ESP_BT_VS_CFG_TEST_READ_CCA_DATA_SUBCM (0X10)
|
||||
#define ESP_BT_VS_CFG_TEST_CLEAR_RAND_ADDR_SUBCMD (0X11)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_MAX_TXPWR_SUBCMD (0X12)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_TXPWR_RANGE_SUBCMD (0X13)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_SCAN_AA_SUBCMD (0X14)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_ADV_AA_SUBCMD (0X15)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_SCAN_CHAN_SUBCMD (0X16)
|
||||
#define ESP_BT_VS_CFG_TEST_SKIP_LIGHT_SLEEP_CHECK_SUBCMD (0X17)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_WAKEUP_OVERHEAD_SUBCMD (0X18)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_ADV_MIN_ITVL_SUBCMD (0X19)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_CTRL_STATUS_SUBCMD (0X1a)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_CONN_PHY_TXPWR_SUBCMD (0X1b)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_CONN_PHY_TXPWR_SUBCMD (0X1c)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_RXBUF_EMPTY_CNT_SUBCMD (0X1d)
|
||||
#define ESP_BT_VS_CFG_TEST_RESTART_SUBCMD (0X1e)
|
||||
#define ESP_BT_VS_CFG_TEST_ENABLE_RECODE_RX_STATE_SUBCMD (0X1f)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_RECODE_CNT_SUBCMD (0X20)
|
||||
#define ESP_BT_VS_CFG_TEST_CLR_RECODE_CNT_SUBCMD (0X21)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_CTRL_COMPILE_VER_SUBCMD (0X24)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_AUX_ADV_OFFSET_SUBCMD (0X25)
|
||||
#define ESP_BT_VS_CFG_TEST_INIT_FLEXIBLE_MODE_SUBCMD (0X26)
|
||||
#define ESP_BT_VS_CFG_TEST_ENABLE_FLEXIBLE_MODE_SUBCMD (0X27)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_FLEXIBLE_CONN_ERR_SUBCMD (0X28)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_FLEXIBLE_ADV_ERR_SUBCMD (0X29)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_FLEXIBLE_SCAN_ERR_SUBCMD (0X2a)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_TXED_CRCERR_SUBCMD (0X2c)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_BACKOFF_UPLIMIT_SUBCMD (0X2d)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_RXED_ADV_ADI_SUBCMD (0X2f)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_SCH_RAND_MODE_SUBCMD (0X30)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_RX_SENS_THRESH_SUBCMD (0X31)
|
||||
#define ESP_BT_VS_CFG_TEST_CHECK_MSYS_BUF_SUBCMD (0X32)
|
||||
#define ESP_BT_VS_CFG_TEST_UPDATE_BLE_TIMER_SUBCMD (0X33)
|
||||
#define ESP_BT_VS_CFG_TEST_UPDATE_BLE_RTC_SUBCMD (0X34)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_LOCKED_MEM_NUM_SUBCMD (0X35)
|
||||
#define ESP_BT_VS_CFG_TEST_ALLOW_MEM_ALLOC_SUBCMD (0X36)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_SCH_RAND_INFO_PTR_SUBCMD (0X37)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_DIAG_IO_SUBCMD (0X38)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_AGC_MAX_GAIN_SUBCMD (0X39)
|
||||
#define ESP_BT_VS_CFG_TEST_ENABLE_CHAN_ASSESS_SUBCMD (0X40)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_BACKOFF_UPLIMIT_SUBCMD (0X41)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_CONN_TOP_PRIO_RESV_THRESH_SUBCMD (0X42)
|
||||
#define ESP_BT_VS_CFG_TEST_SET_TEST_EVT_MSK_SUBCMD (0X43)
|
||||
#define ESP_BT_VS_CFG_TEST_GET_WAKEUP_TIMEOUT_SUBCMD (0X45)
|
||||
#define ESP_BT_VS_CFG_TEST_RELATED_SUBCMD_MAX (0Xff)
|
||||
|
||||
//
|
||||
// @brief HCI VS Events for Espressif's Internal-Use Debugging
|
||||
//
|
||||
// @note The following HCI VS debugging events are implemented in Bluetooth controller pre-compiled libraries.
|
||||
// These events are not linked into the application binary, unless the function `esp_ble_internalTestFeaturesEnable(true)`is called from the application.
|
||||
// Application developers **should not** call `esp_ble_internalTestFeaturesEnable(true)` in their applications.
|
||||
//
|
||||
|
||||
#define ESP_BT_VS_LE_RUNNING_STATUS_EVT_SUBCODE (0xC3)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -10,101 +10,19 @@
|
||||
#include "esp_attr.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
void *bt_osi_mem_malloc(size_t size);
|
||||
|
||||
void *bt_osi_mem_calloc(size_t n, size_t size);
|
||||
|
||||
void *bt_osi_mem_malloc_internal(size_t size);
|
||||
|
||||
void *bt_osi_mem_calloc_internal(size_t n, size_t size);
|
||||
|
||||
void bt_osi_mem_free(void *ptr);
|
||||
|
||||
void bt_osi_mem_free_internal(void *ptr);
|
||||
|
||||
#if CONFIG_BT_LE_MEM_CHECK_ENABLED
|
||||
void bt_osi_mem_count_limit_set(uint16_t count_limit);
|
||||
#endif // CONFIG_BT_LE_MEM_CHECK_ENABLED
|
||||
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
size_t bt_osi_mem_internal_used_size_get(void);
|
||||
// TODO: Remove it. bt_osi_mem_used_size_get has been defined in esp_nimble_mem.h.
|
||||
size_t bt_osi_mem_used_size_get(void);
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
|
||||
#if CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
/**
|
||||
* @brief Initialize NimBLE memory debug module
|
||||
*/
|
||||
void nimble_mem_dbg_init(void);
|
||||
|
||||
/**
|
||||
* @brief Record memory allocation information
|
||||
*
|
||||
* @param p Pointer to allocated memory
|
||||
* @param size Size of allocation
|
||||
* @param func Function name where allocation occurred
|
||||
* @param line Line number where allocation occurred
|
||||
*/
|
||||
void nimble_mem_dbg_record(void *p, int size, const char *func, int line);
|
||||
|
||||
/**
|
||||
* @brief Clean up memory allocation record
|
||||
*
|
||||
* @param p Pointer to memory being freed
|
||||
* @param func Function name where free occurred
|
||||
* @param line Line number where free occurred
|
||||
*/
|
||||
void nimble_mem_dbg_clean(void *p, const char *func, int line);
|
||||
|
||||
/**
|
||||
* @brief Display all memory debug information
|
||||
*/
|
||||
void nimble_mem_dbg_show(void);
|
||||
|
||||
/**
|
||||
* @brief Get maximum memory size used
|
||||
*
|
||||
* @return Maximum memory size in bytes
|
||||
*/
|
||||
uint32_t nimble_mem_dbg_get_max_size(void);
|
||||
|
||||
/**
|
||||
* @brief Get current memory size in use
|
||||
*
|
||||
* @return Current memory size in bytes
|
||||
*/
|
||||
uint32_t nimble_mem_dbg_get_current_size(void);
|
||||
|
||||
/**
|
||||
* @brief Start tracking memory usage for a specific section
|
||||
*
|
||||
* @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1)
|
||||
*/
|
||||
void nimble_mem_dbg_set_section_start(uint8_t index);
|
||||
|
||||
/**
|
||||
* @brief Stop tracking memory usage for a specific section
|
||||
*
|
||||
* @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1)
|
||||
*/
|
||||
void nimble_mem_dbg_set_section_end(uint8_t index);
|
||||
|
||||
/**
|
||||
* @brief Get maximum memory size used in a specific section
|
||||
*
|
||||
* @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1)
|
||||
* @return Maximum memory size in bytes for this section
|
||||
*/
|
||||
uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index);
|
||||
|
||||
/**
|
||||
* @brief Reallocate memory with debug tracking
|
||||
*
|
||||
* @param ptr Pointer to memory to reallocate
|
||||
* @param new_size New size of allocation
|
||||
* @param func Function name where realloc occurred
|
||||
* @param line Line number where realloc occurred
|
||||
* @return Pointer to reallocated memory
|
||||
*/
|
||||
void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line);
|
||||
|
||||
#endif // CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
|
||||
@@ -10,311 +10,17 @@
|
||||
#include "esp_log.h"
|
||||
#include <assert.h>
|
||||
|
||||
static uint8_t log_count;
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
static size_t controller_mem_used_size = 0;
|
||||
static size_t host_mem_used_size = 0;
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
|
||||
#if CONFIG_BT_LE_MEM_CHECK_ENABLED
|
||||
static uint16_t mem_count_limit = 0;
|
||||
static uint16_t curr_mem_count;
|
||||
#endif // CONFIG_BT_LE_MEM_CHECK_ENABLED
|
||||
|
||||
#if CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
|
||||
#define NIMBLE_MEM_DBG_INFO_MAX 1024*3
|
||||
typedef struct {
|
||||
void *p;
|
||||
int size;
|
||||
const char *func;
|
||||
int line;
|
||||
} nimble_mem_dbg_info_t;
|
||||
|
||||
static uint32_t nimble_mem_dbg_count = 0;
|
||||
static nimble_mem_dbg_info_t nimble_mem_dbg_info[NIMBLE_MEM_DBG_INFO_MAX];
|
||||
static uint32_t nimble_mem_dbg_current_size = 0;
|
||||
static uint32_t nimble_mem_dbg_max_size = 0;
|
||||
|
||||
#define NIMBLE_MEM_DBG_MAX_SECTION_NUM 5
|
||||
typedef struct {
|
||||
bool used;
|
||||
uint32_t max_size;
|
||||
} nimble_mem_dbg_max_size_section_t;
|
||||
static nimble_mem_dbg_max_size_section_t nimble_mem_dbg_max_size_section[NIMBLE_MEM_DBG_MAX_SECTION_NUM];
|
||||
|
||||
void nimble_mem_dbg_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
nimble_mem_dbg_info[i].p = NULL;
|
||||
nimble_mem_dbg_info[i].size = 0;
|
||||
nimble_mem_dbg_info[i].func = NULL;
|
||||
nimble_mem_dbg_info[i].line = 0;
|
||||
}
|
||||
nimble_mem_dbg_count = 0;
|
||||
nimble_mem_dbg_current_size = 0;
|
||||
nimble_mem_dbg_max_size = 0;
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++){
|
||||
nimble_mem_dbg_max_size_section[i].used = false;
|
||||
nimble_mem_dbg_max_size_section[i].max_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_record(void *p, int size, const char *func, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!p || size == 0) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s invalid !!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p == NULL) {
|
||||
nimble_mem_dbg_info[i].p = p;
|
||||
nimble_mem_dbg_info[i].size = size;
|
||||
nimble_mem_dbg_info[i].func = func;
|
||||
nimble_mem_dbg_info[i].line = line;
|
||||
nimble_mem_dbg_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= NIMBLE_MEM_DBG_INFO_MAX) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
|
||||
nimble_mem_dbg_current_size += size;
|
||||
if(nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) {
|
||||
nimble_mem_dbg_max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++){
|
||||
if (nimble_mem_dbg_max_size_section[i].used) {
|
||||
if(nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) {
|
||||
nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_clean(void *p, const char *func, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!p) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s %d free->%p invalid\n", func, line, p);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p == p) {
|
||||
nimble_mem_dbg_current_size -= nimble_mem_dbg_info[i].size;
|
||||
nimble_mem_dbg_info[i].p = NULL;
|
||||
nimble_mem_dbg_info[i].size = 0;
|
||||
nimble_mem_dbg_info[i].func = NULL;
|
||||
nimble_mem_dbg_info[i].line = 0;
|
||||
nimble_mem_dbg_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= NIMBLE_MEM_DBG_INFO_MAX) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_show(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p || nimble_mem_dbg_info[i].size != 0 ) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "--> p %p, s %d, f %s, l %d\n",
|
||||
nimble_mem_dbg_info[i].p, nimble_mem_dbg_info[i].size,
|
||||
nimble_mem_dbg_info[i].func, nimble_mem_dbg_info[i].line);
|
||||
}
|
||||
}
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "--> count %ld\n", nimble_mem_dbg_count);
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "--> size %ldB\n--> max size %ldB\n",
|
||||
nimble_mem_dbg_current_size, nimble_mem_dbg_max_size);
|
||||
}
|
||||
|
||||
uint32_t nimble_mem_dbg_get_max_size(void)
|
||||
{
|
||||
return nimble_mem_dbg_max_size;
|
||||
}
|
||||
|
||||
uint32_t nimble_mem_dbg_get_current_size(void)
|
||||
{
|
||||
return nimble_mem_dbg_current_size;
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_set_section_start(uint8_t index)
|
||||
{
|
||||
if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nimble_mem_dbg_max_size_section[index].used) {
|
||||
ESP_LOGW("BT_NIMBLE_MEM", "This index(%d) has been started, restart it.\n", index);
|
||||
}
|
||||
|
||||
nimble_mem_dbg_max_size_section[index].used = true;
|
||||
nimble_mem_dbg_max_size_section[index].max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
|
||||
void nimble_mem_dbg_set_section_end(uint8_t index)
|
||||
{
|
||||
if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nimble_mem_dbg_max_size_section[index].used) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "This index(%d) has not been started.\n", index);
|
||||
return;
|
||||
}
|
||||
|
||||
nimble_mem_dbg_max_size_section[index].used = false;
|
||||
}
|
||||
|
||||
uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index)
|
||||
{
|
||||
if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM){
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nimble_mem_dbg_max_size_section[index].max_size;
|
||||
}
|
||||
|
||||
void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line)
|
||||
{
|
||||
size_t old_size = 0;
|
||||
int i;
|
||||
|
||||
void *new_ptr = realloc(ptr, new_size);
|
||||
if (new_ptr == NULL && new_size > 0) {
|
||||
// realloc failed, keep old ptr record
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Find and clean old record if ptr is not NULL
|
||||
if (ptr != NULL) {
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p == ptr) {
|
||||
old_size = nimble_mem_dbg_info[i].size;
|
||||
nimble_mem_dbg_current_size -= old_size;
|
||||
|
||||
nimble_mem_dbg_info[i].p = NULL;
|
||||
nimble_mem_dbg_info[i].size = 0;
|
||||
nimble_mem_dbg_info[i].func = NULL;
|
||||
nimble_mem_dbg_info[i].line = 0;
|
||||
nimble_mem_dbg_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Record the new allocation if new_size > 0
|
||||
if (new_ptr != NULL && new_size > 0) {
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
|
||||
if (nimble_mem_dbg_info[i].p == NULL) {
|
||||
nimble_mem_dbg_info[i].p = new_ptr;
|
||||
nimble_mem_dbg_info[i].size = new_size;
|
||||
nimble_mem_dbg_info[i].func = func;
|
||||
nimble_mem_dbg_info[i].line = line;
|
||||
nimble_mem_dbg_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= NIMBLE_MEM_DBG_INFO_MAX) {
|
||||
ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
|
||||
nimble_mem_dbg_current_size += new_size;
|
||||
if (nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) {
|
||||
nimble_mem_dbg_max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
|
||||
for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++) {
|
||||
if (nimble_mem_dbg_max_size_section[i].used &&
|
||||
nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) {
|
||||
nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
#endif // CONFIG_BT_NIMBLE_MEM_DEBUG
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void *bt_osi_mem_malloc(size_t size)
|
||||
{
|
||||
void *mem = NULL;
|
||||
#ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL
|
||||
mem = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL
|
||||
mem = heap_caps_malloc(size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT
|
||||
mem = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#else
|
||||
mem = malloc(size);
|
||||
#endif
|
||||
if (!mem) {
|
||||
log_count ++;
|
||||
if ((log_count % 100) == 0) {
|
||||
ESP_EARLY_LOGI("ESP_LOG_INFO","malloc failed (size %zu)",size);
|
||||
log_count = 0;
|
||||
}
|
||||
assert(mem != NULL);
|
||||
}
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if(mem) {
|
||||
host_mem_used_size += heap_caps_get_allocated_size(mem);
|
||||
}
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
return mem;
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void *bt_osi_mem_calloc(size_t n, size_t size)
|
||||
{
|
||||
void *mem = NULL;
|
||||
#ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL
|
||||
mem = heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL
|
||||
mem = heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
|
||||
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT
|
||||
mem = heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
#else
|
||||
mem = calloc(n, size);
|
||||
#endif
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if(mem) {
|
||||
host_mem_used_size += heap_caps_get_allocated_size(mem);
|
||||
}
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
return mem;
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void *bt_osi_mem_malloc_internal(size_t size)
|
||||
void *
|
||||
bt_osi_mem_malloc_internal(size_t size)
|
||||
{
|
||||
void *mem_ptr;
|
||||
#if CONFIG_BT_LE_MEM_CHECK_ENABLED
|
||||
@@ -334,10 +40,9 @@ void *bt_osi_mem_malloc_internal(size_t size)
|
||||
return mem_ptr;
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void *bt_osi_mem_calloc_internal(size_t n, size_t size)
|
||||
|
||||
void *
|
||||
bt_osi_mem_calloc_internal(size_t n, size_t size)
|
||||
{
|
||||
void *mem_ptr;
|
||||
#if CONFIG_BT_LE_MEM_CHECK_ENABLED
|
||||
@@ -357,10 +62,8 @@ void *bt_osi_mem_calloc_internal(size_t n, size_t size)
|
||||
return mem_ptr;
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void bt_osi_mem_free_internal(void *ptr)
|
||||
void
|
||||
bt_osi_mem_free_internal(void *ptr)
|
||||
{
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if (ptr) {
|
||||
@@ -374,23 +77,6 @@ void bt_osi_mem_free_internal(void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
|
||||
IRAM_ATTR
|
||||
#endif
|
||||
void bt_osi_mem_free(void *ptr)
|
||||
{
|
||||
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if (ptr) {
|
||||
size_t alloc_size = heap_caps_get_allocated_size(ptr);
|
||||
// assert(host_mem_used_size >= alloc_size);
|
||||
host_mem_used_size -= alloc_size;
|
||||
}
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
if (ptr) {
|
||||
heap_caps_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_BT_LE_MEM_CHECK_ENABLED
|
||||
void bt_osi_mem_count_limit_set(uint16_t count_limit)
|
||||
{
|
||||
@@ -406,21 +92,8 @@ bt_osi_mem_internal_used_size_get(void)
|
||||
return controller_mem_used_size;
|
||||
}
|
||||
|
||||
size_t
|
||||
bt_osi_mem_used_size_get(void)
|
||||
{
|
||||
return host_mem_used_size;
|
||||
}
|
||||
|
||||
uint32_t esp_ble_controller_used_heap_size_get(void)
|
||||
{
|
||||
return bt_osi_mem_internal_used_size_get();
|
||||
}
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
uint32_t esp_host_used_heap_size_get(void)
|
||||
{
|
||||
return bt_osi_mem_used_size_get();
|
||||
}
|
||||
#endif // CONFIG_BT_NIMBLE_ENABLED
|
||||
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
set(porting_btdm_srcs "")
|
||||
set(porting_btdm_include_dirs "")
|
||||
|
||||
# btdm_common
|
||||
file(GLOB_RECURSE BTDM_COMMON_SRCS "controller/btdm_common/src/*.c")
|
||||
list(APPEND porting_btdm_srcs ${BTDM_COMMON_SRCS})
|
||||
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/controller/btdm_common/include")
|
||||
|
||||
# ble
|
||||
if(CONFIG_BTDM_CTRL_MODE_BLE_ONLY OR CONFIG_BTDM_CTRL_MODE_BTDM)
|
||||
file(GLOB_RECURSE BLE_SRCS "controller/ble/src/*.c")
|
||||
list(APPEND porting_btdm_srcs ${BLE_SRCS})
|
||||
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/controller/ble/include")
|
||||
endif()
|
||||
|
||||
# bredr
|
||||
if(CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY OR CONFIG_BTDM_CTRL_MODE_BTDM)
|
||||
file(GLOB_RECURSE BREDR_SRCS "controller/bredr/src/*.c")
|
||||
list(APPEND porting_btdm_srcs ${BREDR_SRCS})
|
||||
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/controller/bredr/include")
|
||||
endif()
|
||||
|
||||
# transport
|
||||
file(GLOB_RECURSE TRANSPORT_SRCS "transport/src/*.c")
|
||||
list(APPEND porting_btdm_srcs ${TRANSPORT_SRCS})
|
||||
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/transport/include")
|
||||
if(CONFIG_BT_CTRL_HCI_INTERFACE_USE_RAM)
|
||||
if(CONFIG_BT_NIMBLE_ENABLED)
|
||||
list(APPEND porting_btdm_srcs
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/transport/driver/vhci/hci_driver_nimble.c"
|
||||
)
|
||||
else()
|
||||
list(APPEND porting_btdm_srcs
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/transport/driver/vhci/hci_driver_standard.c"
|
||||
)
|
||||
endif()
|
||||
elseif(CONFIG_BT_CTRL_HCI_INTERFACE_USE_UART)
|
||||
list(APPEND porting_btdm_srcs
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/transport/driver/common/hci_driver_util.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/transport/driver/common/hci_driver_h4.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/transport/driver/common/hci_driver_mem.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/transport/driver/uart/hci_driver_uart_config.c"
|
||||
)
|
||||
if(CONFIG_BT_CTRL_UART_HCI_NO_DMA_MODE)
|
||||
list(APPEND porting_btdm_srcs
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/transport/driver/uart/hci_driver_uart.c"
|
||||
)
|
||||
else()
|
||||
list(APPEND porting_btdm_srcs
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/transport/driver/uart/hci_driver_uart_dma.c"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(porting_btdm_srcs ${porting_btdm_srcs} PARENT_SCOPE)
|
||||
set(porting_btdm_include_dirs ${porting_btdm_include_dirs} PARENT_SCOPE)
|
||||
@@ -0,0 +1,721 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _BLE_MBUF_H
|
||||
#define _BLE_MBUF_H
|
||||
|
||||
#include "btdm_mempool.h"
|
||||
#include "queue.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A mbuf pool from which to allocate mbufs. This contains a pointer to the os
|
||||
* mempool to allocate mbufs out of, the total number of elements in the pool,
|
||||
* and the amount of "user" data in a non-packet header mbuf. The total pool
|
||||
* size, in bytes, should be:
|
||||
* ble_mbuf_count * (omp_databuf_len + sizeof(struct ble_mbuf))
|
||||
*/
|
||||
struct ble_mbuf_pool {
|
||||
/**
|
||||
* Total length of the databuf in each mbuf. This is the size of the
|
||||
* mempool block, minus the mbuf header
|
||||
*/
|
||||
uint16_t omp_databuf_len;
|
||||
/**
|
||||
* The memory pool which to allocate mbufs out of
|
||||
*/
|
||||
struct btdm_mempool *omp_pool;
|
||||
|
||||
STAILQ_ENTRY(ble_mbuf_pool) omp_next;
|
||||
};
|
||||
|
||||
/**
|
||||
* A packet header structure that precedes the mbuf packet headers.
|
||||
*/
|
||||
struct ble_mbuf_pkthdr {
|
||||
/**
|
||||
* Overall length of the packet.
|
||||
*/
|
||||
uint16_t omp_len;
|
||||
/**
|
||||
* Flags
|
||||
*/
|
||||
uint16_t omp_flags;
|
||||
|
||||
STAILQ_ENTRY(ble_mbuf_pkthdr) omp_next;
|
||||
};
|
||||
|
||||
/**
|
||||
* Chained memory buffer.
|
||||
*/
|
||||
struct ble_mbuf {
|
||||
/**
|
||||
* Current pointer to data in the structure
|
||||
*/
|
||||
uint8_t *om_data;
|
||||
/**
|
||||
* Flags associated with this buffer, see BLE_MBUF_F_* definitions
|
||||
*/
|
||||
uint8_t om_flags;
|
||||
/**
|
||||
* Length of packet header
|
||||
*/
|
||||
uint8_t om_pkthdr_len;
|
||||
/**
|
||||
* Length of data in this buffer
|
||||
*/
|
||||
uint16_t om_len;
|
||||
|
||||
/**
|
||||
* The mbuf pool this mbuf was allocated out of
|
||||
*/
|
||||
struct ble_mbuf_pool *om_omp;
|
||||
|
||||
SLIST_ENTRY(ble_mbuf) om_next;
|
||||
|
||||
/**
|
||||
* Pointer to the beginning of the data, after this buffer
|
||||
*/
|
||||
uint8_t om_databuf[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Checks whether a given mbuf is a packet header mbuf
|
||||
*
|
||||
* @param __om The mbuf to check
|
||||
*/
|
||||
#define BLE_MBUF_IS_PKTHDR(__om) ((__om)->om_pkthdr_len >= sizeof(struct ble_mbuf_pkthdr))
|
||||
|
||||
/** Get a packet header pointer given an mbuf pointer */
|
||||
#define BLE_MBUF_PKTHDR(__om) \
|
||||
((struct ble_mbuf_pkthdr *)(uintptr_t)(void *)((uint8_t *)&(__om)->om_data + \
|
||||
sizeof(struct ble_mbuf)))
|
||||
|
||||
/** Given a mbuf packet header pointer, return a pointer to the mbuf */
|
||||
#define BLE_MBUF_PKTHDR_TO_MBUF(__hdr) \
|
||||
(struct ble_mbuf *)(uintptr_t)((uint8_t *)(__hdr) - sizeof(struct ble_mbuf))
|
||||
|
||||
/**
|
||||
* Gets the length of an entire mbuf chain. The specified mbuf must have a
|
||||
* packet header.
|
||||
*/
|
||||
#define BLE_MBUF_PKTLEN(__om) (BLE_MBUF_PKTHDR(__om)->omp_len)
|
||||
|
||||
/**
|
||||
* Access the data of a mbuf, and cast it to type
|
||||
*
|
||||
* @param __om The mbuf to access, and cast
|
||||
* @param __type The type to cast it to
|
||||
*/
|
||||
#define BLE_MBUF_DATA(__om, __type) (__type)((__om)->om_data)
|
||||
|
||||
/**
|
||||
* Access the "user header" in the head of an mbuf chain.
|
||||
*
|
||||
* @param om Pointer to the head of an mbuf chain.
|
||||
*/
|
||||
#define BLE_MBUF_USRHDR(om) \
|
||||
(void *)((uint8_t *)om + sizeof(struct ble_mbuf) + sizeof(struct ble_mbuf_pkthdr))
|
||||
|
||||
/**
|
||||
* Retrieves the length of the user header in an mbuf.
|
||||
*
|
||||
* @param om Pointer to the mbuf to query.
|
||||
*/
|
||||
#define BLE_MBUF_USRHDR_LEN(om) ((om)->om_pkthdr_len - sizeof(struct ble_mbuf_pkthdr))
|
||||
|
||||
/*
|
||||
* Called by BLE_MBUF_LEADINGSPACE() macro
|
||||
*/
|
||||
static inline uint16_t
|
||||
_ble_mbuf_leadingspace(struct ble_mbuf *om)
|
||||
{
|
||||
extern uint16_t r_os_mbuf_leadingspace(struct ble_mbuf * om);
|
||||
return r_os_mbuf_leadingspace(om);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the leading space (space at the beginning) of the mbuf.
|
||||
* Works on both packet header, and regular mbufs, as it accounts
|
||||
* for the additional space allocated to the packet header.
|
||||
*
|
||||
* @param __omp Is the mbuf pool (which contains packet header length.)
|
||||
* @param __om Is the mbuf in that pool to get the leadingspace for
|
||||
*
|
||||
* @return Amount of leading space available in the mbuf
|
||||
*/
|
||||
#define BLE_MBUF_LEADINGSPACE(__om) _ble_mbuf_leadingspace(__om)
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
||||
/* Called by BLE_MBUF_TRAILINGSPACE() macro. */
|
||||
static inline uint16_t
|
||||
_ble_mbuf_trailingspace(struct ble_mbuf *om)
|
||||
{
|
||||
extern uint16_t r_os_mbuf_trailingspace(struct ble_mbuf * om);
|
||||
return r_os_mbuf_trailingspace(om);
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* Returns the trailing space (space at the end) of the mbuf.
|
||||
* Works on both packet header and regular mbufs.
|
||||
*
|
||||
* @param __omp The mbuf pool for this mbuf
|
||||
* @param __om Is the mbuf in that pool to get trailing space for
|
||||
*
|
||||
* @return The amount of trailing space available in the mbuf
|
||||
*/
|
||||
#define BLE_MBUF_TRAILINGSPACE(__om) _ble_mbuf_trailingspace(__om)
|
||||
|
||||
/**
|
||||
* MSYS is a system level mbuf registry. Allows the system to share
|
||||
* packet buffers amongst the various networking stacks that can be running
|
||||
* simultaeneously.
|
||||
*
|
||||
* Mbuf pools are created in the system initialization code, and then when
|
||||
* a mbuf is allocated out of msys, it will try and find the best fit based
|
||||
* upon estimated mbuf size.
|
||||
*
|
||||
* os_msys_register() registers a mbuf pool with MSYS, and allows MSYS to
|
||||
* allocate mbufs out of it.
|
||||
*
|
||||
* @param new_pool The pool to register with MSYS
|
||||
*
|
||||
* @return 0 on success, non-zero on failure
|
||||
*/
|
||||
static inline int
|
||||
ble_msys_register(struct ble_mbuf_pool *mp)
|
||||
{
|
||||
extern int r_os_msys_register(struct ble_mbuf_pool * mp);
|
||||
return r_os_msys_register(mp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a mbuf from msys. Based upon the data size requested,
|
||||
* os_msys_get() will choose the mbuf pool that has the best fit.
|
||||
*
|
||||
* @param dsize The estimated size of the data being stored in the mbuf
|
||||
* @param leadingspace The amount of leadingspace to allocate in the mbuf
|
||||
*
|
||||
* @return A freshly allocated mbuf on success, NULL on failure.
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_msys_get(uint16_t dsize, uint16_t leadingspace)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_msys_get(uint16_t dsize, uint16_t leadingspace);
|
||||
return r_os_msys_get(dsize, leadingspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* De-registers all mbuf pools from msys.
|
||||
*/
|
||||
static inline void
|
||||
ble_msys_reset(void)
|
||||
{
|
||||
extern void r_os_msys_reset(void);
|
||||
r_os_msys_reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a packet header structure from the MSYS pool. See
|
||||
* os_msys_register() for a description of MSYS.
|
||||
*
|
||||
* @param dsize The estimated size of the data being stored in the mbuf
|
||||
* @param user_hdr_len The length to allocate for the packet header structure
|
||||
*
|
||||
* @return A freshly allocated mbuf on success, NULL on failure.
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len);
|
||||
return r_os_msys_get_pkthdr(dsize, user_hdr_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of blocks in all the mbuf pools that are allocated.
|
||||
*
|
||||
* @return total number of blocks allocated in Msys
|
||||
*/
|
||||
static inline int
|
||||
ble_msys_count(void)
|
||||
{
|
||||
extern int r_os_msys_count(void);
|
||||
return r_os_msys_count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of free blocks in Msys
|
||||
*
|
||||
* @return Number of free blocks available in Msys
|
||||
*/
|
||||
static inline int
|
||||
ble_msys_num_free(void)
|
||||
{
|
||||
extern int r_os_msys_num_free(void);
|
||||
return r_os_msys_num_free();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a pool of mbufs.
|
||||
*
|
||||
* @param omp The mbuf pool to initialize
|
||||
* @param mp The memory pool that will hold this mbuf pool
|
||||
* @param buf_len The length of the buffer itself.
|
||||
* @param nbufs The number of buffers in the pool
|
||||
*
|
||||
* @return 0 on success, error code on failure.
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_pool_init(struct ble_mbuf_pool *omp, struct btdm_mempool *mp, uint16_t buf_len,
|
||||
uint16_t nbufs)
|
||||
{
|
||||
extern int r_os_mbuf_pool_init(struct ble_mbuf_pool *, struct btdm_mempool * mp, uint16_t,
|
||||
uint16_t);
|
||||
return r_os_mbuf_pool_init(omp, mp, buf_len, nbufs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an mbuf from the mbuf pool. The mbuf is allocated, and initialized
|
||||
* prior to being returned.
|
||||
*
|
||||
* @param omp The mbuf pool to return the packet from
|
||||
* @param leadingspace The amount of leadingspace to put before the data
|
||||
* section by default.
|
||||
*
|
||||
* @return An initialized mbuf on success, and NULL on failure.
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_get(struct ble_mbuf_pool *omp, uint16_t leadingspace)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_get(struct ble_mbuf_pool * omp, uint16_t leadingspace);
|
||||
return r_os_mbuf_get(omp, leadingspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new packet header mbuf out of the os_mbuf_pool.
|
||||
*
|
||||
* @param omp The mbuf pool to allocate out of
|
||||
* @param user_pkthdr_len The packet header length to reserve for the caller.
|
||||
*
|
||||
* @return A freshly allocated mbuf on success, NULL on failure.
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_get_pkthdr(struct ble_mbuf_pool *omp, uint8_t user_pkthdr_len)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_get_pkthdr(struct ble_mbuf_pool * omp,
|
||||
uint8_t user_pkthdr_len);
|
||||
return r_os_mbuf_get_pkthdr(omp, user_pkthdr_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a chain of mbufs. Return the start of the duplicated chain.
|
||||
*
|
||||
* @param omp The mbuf pool to duplicate out of
|
||||
* @param om The mbuf chain to duplicate
|
||||
*
|
||||
* @return A pointer to the new chain of mbufs
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_dup(struct ble_mbuf *m)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_dup(struct ble_mbuf * m);
|
||||
return r_os_mbuf_dup(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the specified absolute offset within an mbuf chain. The offset
|
||||
* can be one past than the total length of the chain, but no greater.
|
||||
*
|
||||
* @param om The start of the mbuf chain to seek within.
|
||||
* @param off The absolute address to find.
|
||||
* @param out_off On success, this points to the relative offset
|
||||
* within the returned mbuf.
|
||||
*
|
||||
* @return The mbuf containing the specified offset on
|
||||
* success.
|
||||
* NULL if the specified offset is out of bounds.
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_off(const struct ble_mbuf *om, int off, uint16_t *out_off)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_off(const struct ble_mbuf *om, int off, uint16_t *out_off);
|
||||
return r_os_mbuf_off(om, off, out_off);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy data from an mbuf chain starting "off" bytes from the beginning,
|
||||
* continuing for "len" bytes, into the indicated buffer.
|
||||
*
|
||||
* @param m The mbuf chain to copy from
|
||||
* @param off The offset into the mbuf chain to begin copying from
|
||||
* @param len The length of the data to copy
|
||||
* @param dst The destination buffer to copy into
|
||||
*
|
||||
* @return 0 on success;
|
||||
* -1 if the mbuf does not contain enough data.
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_copydata(const struct ble_mbuf *m, int off, int len, void *dst)
|
||||
{
|
||||
extern int r_os_mbuf_copydata(const struct ble_mbuf *m, int off, int len, void *dst);
|
||||
return r_os_mbuf_copydata(m, off, len, dst);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates the length of an mbuf chain.
|
||||
*
|
||||
* Calculates the length of an mbuf chain. If the mbuf contains a packet
|
||||
* header, you should use `OS_MBUF_PKTLEN()` as a more efficient alternative to
|
||||
* this function.
|
||||
*
|
||||
* @param om The mbuf to measure.
|
||||
*
|
||||
* @return The length, in bytes, of the provided mbuf
|
||||
* chain.
|
||||
*/
|
||||
static inline uint16_t
|
||||
ble_mbuf_len(const struct ble_mbuf *om)
|
||||
{
|
||||
extern uint16_t r_os_mbuf_len(const struct ble_mbuf *om);
|
||||
return r_os_mbuf_len(om);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data onto a mbuf
|
||||
*
|
||||
* @param om The mbuf to append the data onto
|
||||
* @param data The data to append onto the mbuf
|
||||
* @param len The length of the data to append
|
||||
*
|
||||
* @return 0 on success, and an error code on failure
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_append(struct ble_mbuf *m, const void *data, uint16_t len)
|
||||
{
|
||||
extern int r_os_mbuf_append(struct ble_mbuf * m, const void *, uint16_t);
|
||||
return r_os_mbuf_append(m, data, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from one mbuf and appends it to another. On error, the specified
|
||||
* data range may be partially appended. Neither mbuf is required to contain
|
||||
* an mbuf packet header.
|
||||
*
|
||||
* @param dst The mbuf to append to.
|
||||
* @param src The mbuf to copy data from.
|
||||
* @param src_off The absolute offset within the source mbuf
|
||||
* chain to read from.
|
||||
* @param len The number of bytes to append.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* OS_EINVAL if the specified range extends beyond
|
||||
* the end of the source mbuf chain.
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_appendfrom(struct ble_mbuf *dst, const struct ble_mbuf *src, uint16_t src_off,
|
||||
uint16_t len)
|
||||
{
|
||||
extern int r_os_mbuf_appendfrom(struct ble_mbuf * dst, const struct ble_mbuf *src,
|
||||
uint16_t src_off, uint16_t len);
|
||||
return r_os_mbuf_appendfrom(dst, src, src_off, len);
|
||||
}
|
||||
/**
|
||||
* Release a mbuf back to the pool
|
||||
*
|
||||
* @param mb The Mbuf to release back to the pool
|
||||
*
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_free(struct ble_mbuf *mb)
|
||||
{
|
||||
extern int r_os_mbuf_free(struct ble_mbuf * mb);
|
||||
return r_os_mbuf_free(mb);
|
||||
}
|
||||
/**
|
||||
* Free a chain of mbufs
|
||||
*
|
||||
* @param om The starting mbuf of the chain to free back into the pool
|
||||
*
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_free_chain(struct ble_mbuf *om)
|
||||
{
|
||||
extern int r_os_mbuf_free_chain(struct ble_mbuf * om);
|
||||
return r_os_mbuf_free_chain(om);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the length of a mbuf, trimming either from the head or the tail
|
||||
* of the mbuf.
|
||||
*
|
||||
* @param mp The mbuf chain to adjust
|
||||
* @param req_len The length to trim from the mbuf. If positive, trims
|
||||
* from the head of the mbuf, if negative, trims from the
|
||||
* tail of the mbuf.
|
||||
*/
|
||||
static inline void
|
||||
ble_mbuf_adj(struct ble_mbuf *mp, int req_len)
|
||||
{
|
||||
extern void r_os_mbuf_adj(struct ble_mbuf * mp, int req_len);
|
||||
r_os_mbuf_adj(mp, req_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a memory compare of the specified region of an mbuf chain against a
|
||||
* flat buffer.
|
||||
*
|
||||
* @param om The start of the mbuf chain to compare.
|
||||
* @param off The offset within the mbuf chain to start the
|
||||
* comparison.
|
||||
* @param data The flat buffer to compare.
|
||||
* @param len The length of the flat buffer.
|
||||
*
|
||||
* @return 0 if both memory regions are identical;
|
||||
* A memcmp return code if there is a mismatch;
|
||||
* INT_MAX if the mbuf is too short.
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_cmpf(const struct ble_mbuf *om, int off, const void *data, int len)
|
||||
{
|
||||
extern int r_os_mbuf_cmpf(const struct ble_mbuf *om, int off, const void *data, int len);
|
||||
return r_os_mbuf_cmpf(om, off, data, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the contents of two mbuf chains. The ranges of the two chains to
|
||||
* be compared are specified via the two offset parameters and the len
|
||||
* parameter. Neither mbuf chain is required to contain a packet header.
|
||||
*
|
||||
* @param om1 The first mbuf chain to compare.
|
||||
* @param offset1 The absolute offset within om1 at which to
|
||||
* start the comparison.
|
||||
* @param om2 The second mbuf chain to compare.
|
||||
* @param offset2 The absolute offset within om2 at which to
|
||||
* start the comparison.
|
||||
* @param len The number of bytes to compare.
|
||||
*
|
||||
* @return 0 if both mbuf segments are identical;
|
||||
* A memcmp() return code if the segment contents
|
||||
* differ;
|
||||
* INT_MAX if a specified range extends beyond the
|
||||
* end of its corresponding mbuf chain.
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_cmpm(const struct ble_mbuf *om1, uint16_t offset1, const struct ble_mbuf *om2,
|
||||
uint16_t offset2, uint16_t len)
|
||||
{
|
||||
extern int r_os_mbuf_cmpm(const struct ble_mbuf *om1, uint16_t offset1,
|
||||
const struct ble_mbuf *om2, uint16_t offset2, uint16_t len);
|
||||
return r_os_mbuf_cmpm(om1, offset1, om2, offset2, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the length of an mbuf chain by adding data to the front. If there
|
||||
* is insufficient room in the leading mbuf, additional mbufs are allocated and
|
||||
* prepended as necessary. If this function fails to allocate an mbuf, the
|
||||
* entire chain is freed.
|
||||
*
|
||||
* The specified mbuf chain does not need to contain a packet header.
|
||||
*
|
||||
* @param omp The mbuf pool to allocate from.
|
||||
* @param om The head of the mbuf chain.
|
||||
* @param len The number of bytes to prepend.
|
||||
*
|
||||
* @return The new head of the chain on success;
|
||||
* NULL on failure.
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_prepend(struct ble_mbuf *om, int len)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_prepend(struct ble_mbuf * om, int len);
|
||||
return r_os_mbuf_prepend(om, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends a chunk of empty data to the specified mbuf chain and ensures the
|
||||
* chunk is contiguous. If either operation fails, the specified mbuf chain is
|
||||
* freed and NULL is returned.
|
||||
*
|
||||
* @param om The mbuf chain to prepend to.
|
||||
* @param len The number of bytes to prepend and pullup.
|
||||
*
|
||||
* @return The modified mbuf on success;
|
||||
* NULL on failure (and the mbuf chain is freed).
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_prepend_pullup(struct ble_mbuf *om, uint16_t len)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_prepend_pullup(struct ble_mbuf * om, uint16_t len);
|
||||
return r_os_mbuf_prepend_pullup(om, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the contents of a flat buffer into an mbuf chain, starting at the
|
||||
* specified destination offset. If the mbuf is too small for the source data,
|
||||
* it is extended as necessary. If the destination mbuf contains a packet
|
||||
* header, the header length is updated.
|
||||
*
|
||||
* @param om The mbuf chain to copy into.
|
||||
* @param off The offset within the chain to copy to.
|
||||
* @param src The source buffer to copy from.
|
||||
* @param len The number of bytes to copy.
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_copyinto(struct ble_mbuf *om, int off, const void *src, int len)
|
||||
{
|
||||
extern int r_os_mbuf_copyinto(struct ble_mbuf * om, int off, const void *src, int len);
|
||||
return r_os_mbuf_copyinto(om, off, src, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a second mbuf chain onto the end of the first. If the first chain
|
||||
* contains a packet header, the header's length is updated. If the second
|
||||
* chain has a packet header, its header is cleared.
|
||||
*
|
||||
* @param first The mbuf chain being attached to.
|
||||
* @param second The mbuf chain that gets attached.
|
||||
*/
|
||||
static inline void
|
||||
ble_mbuf_concat(struct ble_mbuf *first, struct ble_mbuf *second)
|
||||
{
|
||||
extern void r_os_mbuf_concat(struct ble_mbuf * first, struct ble_mbuf * second);
|
||||
r_os_mbuf_concat(first, second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the length of an mbuf chain by the specified amount. If there is
|
||||
* not sufficient room in the last buffer, a new buffer is allocated and
|
||||
* appended to the chain. It is an error to request more data than can fit in
|
||||
* a single buffer.
|
||||
*
|
||||
* @param om The head of the chain to extend.
|
||||
* @param len The number of bytes to extend by.
|
||||
*
|
||||
* @return A pointer to the new data on success;
|
||||
* NULL on failure.
|
||||
*/
|
||||
static inline void *
|
||||
ble_mbuf_extend(struct ble_mbuf *om, uint16_t len)
|
||||
{
|
||||
extern void *r_os_mbuf_extend(struct ble_mbuf * om, uint16_t len);
|
||||
return r_os_mbuf_extend(om, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearrange a mbuf chain so that len bytes are contiguous,
|
||||
* and in the data area of an mbuf (so that OS_MBUF_DATA() will
|
||||
* work on a structure of size len.) Returns the resulting
|
||||
* mbuf chain on success, free's it and returns NULL on failure.
|
||||
*
|
||||
* If there is room, it will add up to "max_protohdr - len"
|
||||
* extra bytes to the contiguous region, in an attempt to avoid being
|
||||
* called next time.
|
||||
*
|
||||
* @param om The mbuf chain to make contiguous
|
||||
* @param len The number of bytes in the chain to make contiguous
|
||||
*
|
||||
* @return The contiguous mbuf chain on success, NULL on failure.
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_pullup(struct ble_mbuf *om, uint16_t len)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_pullup(struct ble_mbuf * om, uint16_t len);
|
||||
return r_os_mbuf_pullup(om, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and frees empty mbufs from the front of a chain. If the chain
|
||||
* contains a packet header, it is preserved.
|
||||
*
|
||||
* @param om The mbuf chain to trim.
|
||||
*
|
||||
* @return The head of the trimmed mbuf chain.
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_trim_front(struct ble_mbuf *om)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_trim_front(struct ble_mbuf * om);
|
||||
return r_os_mbuf_trim_front(om);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the length of an mbuf chain by inserting a gap at the specified
|
||||
* offset. The contents of the gap are indeterminate. If the mbuf chain
|
||||
* contains a packet header, its total length is increased accordingly.
|
||||
*
|
||||
* This function never frees the provided mbuf chain.
|
||||
*
|
||||
* @param om The mbuf chain to widen.
|
||||
* @param off The offset at which to insert the gap.
|
||||
* @param len The size of the gap to insert.
|
||||
*
|
||||
* @return 0 on success; SYS_[...] error code on failure.
|
||||
*/
|
||||
static inline int
|
||||
ble_mbuf_widen(struct ble_mbuf *om, uint16_t off, uint16_t len)
|
||||
{
|
||||
extern int r_os_mbuf_widen(struct ble_mbuf * om, uint16_t off, uint16_t len);
|
||||
return r_os_mbuf_widen(om, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single chained mbuf from m1 and m2 utilizing all
|
||||
* the available buffer space in all mbufs in the resulting
|
||||
* chain. In other words, ensures there is no leading space in
|
||||
* any mbuf in the resulting chain and trailing space only in
|
||||
* the last mbuf in the chain. Mbufs from either chain may be
|
||||
* freed if not needed. No mbufs are allocated. Note that mbufs
|
||||
* from m2 are added to the end of m1. If m1 has a packet
|
||||
* header, it is retained and length updated. If m2 has a packet
|
||||
* header it is discarded. If m1 is NULL, NULL is returned and
|
||||
* m2 is left untouched.
|
||||
*
|
||||
* @param m1 Pointer to first mbuf chain to pack
|
||||
* @param m2 Pointer to second mbuf chain to pack
|
||||
*
|
||||
* @return struct os_mbuf* Pointer to resulting mbuf chain
|
||||
*/
|
||||
static inline struct ble_mbuf *
|
||||
ble_mbuf_pack_chains(struct ble_mbuf *m1, struct ble_mbuf *m2)
|
||||
{
|
||||
extern struct ble_mbuf *r_os_mbuf_pack_chains(struct ble_mbuf * m1, struct ble_mbuf * m2);
|
||||
return r_os_mbuf_pack_chains(m1, m2);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLE_MBUF_H */
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _BLE_MSYS_H_
|
||||
#define _BLE_MSYS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ble_msys_init(void);
|
||||
|
||||
void ble_msys_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLE_MSYS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _ESP_BLE_PRIV_H_
|
||||
#define _ESP_BLE_PRIV_H_
|
||||
|
||||
#include "btdm_osal.h"
|
||||
|
||||
int ble_stack_init(esp_bt_controller_config_t *cfg);
|
||||
|
||||
void ble_stack_deinit(void);
|
||||
|
||||
int ble_stack_enable(void);
|
||||
|
||||
void ble_stack_disable(void);
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
esp_err_t sleep_modem_ble_mac_modem_state_init(void);
|
||||
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
|
||||
void ble_osal_elem_calc(esp_bt_controller_config_t *cfg, btdm_osal_elem_num_t *elem);
|
||||
|
||||
#endif // _ESP_BLE_PRIV_H_
|
||||
+18
-65
@@ -1,16 +1,14 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ESP_BT_CFG_H__
|
||||
#define __ESP_BT_CFG_H__
|
||||
#ifndef __BLE_USER_CFG_H__
|
||||
#define __BLE_USER_CFG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -20,8 +18,6 @@ extern "C" {
|
||||
#include "syscfg/syscfg.h"
|
||||
#endif
|
||||
|
||||
#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
#if CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
@@ -29,7 +25,6 @@ extern "C" {
|
||||
#else
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (1)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS)
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS)
|
||||
@@ -41,7 +36,8 @@ extern "C" {
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)
|
||||
|
||||
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED MYNEWT_VAL(BLE_POWER_CONTROL)
|
||||
#else
|
||||
|
||||
#if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
@@ -116,35 +112,15 @@ extern "C" {
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8)
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL)
|
||||
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL)
|
||||
#if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL
|
||||
#define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1)
|
||||
#endif
|
||||
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
|
||||
#if defined(CONFIG_BT_LE_POWER_CONTROL_ENABLED)
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (CONFIG_BT_LE_POWER_CONTROL_ENABLED)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1)
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#else
|
||||
#define HCI_UART_EN 0 // hci ram mode
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
|
||||
#define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE
|
||||
#else
|
||||
#define NIMBLE_SLEEP_ENABLE 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_BT_LE_TX_CCA_ENABLED
|
||||
@@ -162,24 +138,6 @@ extern "C" {
|
||||
#define DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N DEFAULT_BT_LE_EXT_ADV_MAX_SIZE
|
||||
|
||||
|
||||
#if HCI_UART_EN
|
||||
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (CONFIG_BT_LE_HCI_UART_TX_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (CONFIG_BT_LE_HCI_UART_RX_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PORT (CONFIG_BT_LE_HCI_UART_PORT)
|
||||
#define DEFAULT_BT_LE_HCI_UART_BAUD (CONFIG_BT_LE_HCI_UART_BAUD)
|
||||
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS)
|
||||
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PARITY (0)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PORT (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_BAUD (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PARITY (0)
|
||||
#endif
|
||||
|
||||
/* Unchanged configuration */
|
||||
|
||||
#define BLE_LL_CTRL_PROC_TIMEOUT_MS_N (40000) /* ms */
|
||||
@@ -200,26 +158,21 @@ extern "C" {
|
||||
|
||||
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000)
|
||||
|
||||
#if CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
#define RTC_FREQ_N (32768) /* in Hz */
|
||||
|
||||
#define BLE_LL_TX_PWR_DBM_N (9)
|
||||
|
||||
#ifdef CONFIG_BT_LE_BQB_TEST_EN
|
||||
#define RUN_BQB_TEST (CONFIG_BT_LE_BQB_TEST_EN)
|
||||
#else
|
||||
#define RTC_FREQ_N (32000) /* in Hz */
|
||||
#if CONFIG_RTC_CLK_SRC_EXT_OSC || CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
#pragma message "RTC clock source may not available"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define BLE_LL_TX_PWR_DBM_N (0)
|
||||
|
||||
|
||||
#define RUN_BQB_TEST (0)
|
||||
#endif // CONFIG_BT_LE_BQB_TEST_EN
|
||||
|
||||
#define RUN_QA_TEST (0)
|
||||
#define NIMBLE_DISABLE_SCAN_BACKOFF (0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BT_CFG_H__ */
|
||||
#endif /* __BLE_USER_CFG_H__ */
|
||||
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSMempool Memory Pools
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _OS_MEMPOOL_H_
|
||||
#define _OS_MEMPOOL_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "os/os.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A memory block structure. This simply contains a pointer to the free list
|
||||
* chain and is only used when the block is on the free list. When the block
|
||||
* has been removed from the free list the entire memory block is usable by the
|
||||
* caller.
|
||||
*/
|
||||
struct os_memblock {
|
||||
SLIST_ENTRY(os_memblock) mb_next;
|
||||
};
|
||||
|
||||
/* XXX: Change this structure so that we keep the first address in the pool? */
|
||||
/* XXX: add memory debug structure and associated code */
|
||||
/* XXX: Change how I coded the SLIST_HEAD here. It should be named:
|
||||
SLIST_HEAD(,os_memblock) mp_head; */
|
||||
|
||||
/**
|
||||
* Memory pool
|
||||
*/
|
||||
struct os_mempool {
|
||||
/** Size of the memory blocks, in bytes. */
|
||||
uint32_t mp_block_size;
|
||||
/** The number of memory blocks. */
|
||||
uint16_t mp_num_blocks;
|
||||
/** The number of free blocks left */
|
||||
uint16_t mp_num_free;
|
||||
/** The lowest number of free blocks seen */
|
||||
uint16_t mp_min_free;
|
||||
/** Bitmap of OS_MEMPOOL_F_[...] values. */
|
||||
uint8_t mp_flags;
|
||||
/** Address of memory buffer used by pool */
|
||||
uint32_t mp_membuf_addr;
|
||||
STAILQ_ENTRY(os_mempool) mp_list;
|
||||
SLIST_HEAD(,os_memblock);
|
||||
/** Name for memory block */
|
||||
const char *name;
|
||||
/** The number of allocated blocks. */
|
||||
uint32_t mp_alloc_blocks;
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates an extended mempool. Address can be safely cast to
|
||||
* (struct os_mempool_ext *).
|
||||
*/
|
||||
#define OS_MEMPOOL_F_EXT 0x01
|
||||
/* Flag to indicate runtime allocation mode */
|
||||
#define OS_MEMPOOL_F_RUNTIME 0x02
|
||||
/* Flag to indicate reuse block for runtime allocation mode */
|
||||
#define OS_MEMPOOL_F_REUSED 0x04
|
||||
|
||||
struct os_mempool_ext;
|
||||
|
||||
/**
|
||||
* Block put callback function. If configured, this callback gets executed
|
||||
* whenever a block is freed to the corresponding extended mempool. Note: The
|
||||
* os_memblock_put() function calls this callback instead of freeing the block
|
||||
* itself. Therefore, it is the callback's responsibility to free the block
|
||||
* via a call to os_memblock_put_from_cb().
|
||||
*
|
||||
* @param ome The extended mempool that a block is being
|
||||
* freed back to.
|
||||
* @param data The block being freed.
|
||||
* @param arg Optional argument configured along with the
|
||||
* callback.
|
||||
*
|
||||
* @return Indicates whether the block was successfully
|
||||
* freed. A non-zero value should only be
|
||||
* returned if the block was not successfully
|
||||
* released back to its pool.
|
||||
*/
|
||||
typedef os_error_t os_mempool_put_fn(struct os_mempool_ext *ome, void *data,
|
||||
void *arg);
|
||||
|
||||
struct os_mempool_ext {
|
||||
struct os_mempool mpe_mp;
|
||||
|
||||
/* Callback that is executed immediately when a block is freed. */
|
||||
os_mempool_put_fn *mpe_put_cb;
|
||||
void *mpe_put_arg;
|
||||
};
|
||||
|
||||
#define OS_MEMPOOL_INFO_NAME_LEN (32)
|
||||
|
||||
/**
|
||||
* Information describing a memory pool, used to return OS information
|
||||
* to the management layer.
|
||||
*/
|
||||
struct os_mempool_info {
|
||||
/** Size of the memory blocks in the pool */
|
||||
int omi_block_size;
|
||||
/** Number of memory blocks in the pool */
|
||||
int omi_num_blocks;
|
||||
/** Number of free memory blocks */
|
||||
int omi_num_free;
|
||||
/** Minimum number of free memory blocks ever */
|
||||
int omi_min_free;
|
||||
/** Name of the memory pool */
|
||||
char omi_name[OS_MEMPOOL_INFO_NAME_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get information about the next system memory pool.
|
||||
*
|
||||
* @param mempool The current memory pool, or NULL if starting iteration.
|
||||
* @param info A pointer to the structure to return memory pool information
|
||||
* into.
|
||||
*
|
||||
* @return The next memory pool in the list to get information about, or NULL
|
||||
* when at the last memory pool.
|
||||
*/
|
||||
struct os_mempool *os_mempool_info_get_next(struct os_mempool *,
|
||||
struct os_mempool_info *);
|
||||
|
||||
/*
|
||||
* To calculate size of the memory buffer needed for the pool. NOTE: This size
|
||||
* is NOT in bytes! The size is the number of os_membuf_t elements required for
|
||||
* the memory pool.
|
||||
*/
|
||||
#if MYNEWT_VAL(OS_MEMPOOL_GUARD)
|
||||
/*
|
||||
* Leave extra 4 bytes of guard area at the end.
|
||||
*/
|
||||
#define OS_MEMPOOL_BLOCK_SZ(sz) ((sz) + sizeof(os_membuf_t))
|
||||
#else
|
||||
#define OS_MEMPOOL_BLOCK_SZ(sz) (sz)
|
||||
#endif
|
||||
#if (OS_ALIGNMENT == 4)
|
||||
typedef uint32_t os_membuf_t;
|
||||
#elif (OS_ALIGNMENT == 8)
|
||||
typedef uint64_t os_membuf_t;
|
||||
#elif (OS_ALIGNMENT == 16)
|
||||
typedef __uint128_t os_membuf_t;
|
||||
#else
|
||||
#error "Unhandled `OS_ALIGNMENT` for `os_membuf_t`"
|
||||
#endif /* OS_ALIGNMENT == * */
|
||||
#define OS_MEMPOOL_SIZE(n,blksize) ((((blksize) + ((OS_ALIGNMENT)-1)) / (OS_ALIGNMENT)) * (n))
|
||||
|
||||
/** Calculates the number of bytes required to initialize a memory pool. */
|
||||
#define OS_MEMPOOL_BYTES(n,blksize) \
|
||||
(sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize)))
|
||||
|
||||
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
|
||||
/**
|
||||
* Initialize a memory pool.
|
||||
*
|
||||
* @param mp Pointer to a pointer to a mempool
|
||||
* @param blocks The number of blocks in the pool
|
||||
* @param blocks_size The size of the block, in bytes.
|
||||
* @param membuf Pointer to memory to contain blocks.
|
||||
* @param name Name of the pool.
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t r_os_mempool_init(struct os_mempool *mp, uint16_t blocks,
|
||||
uint32_t block_size, void *membuf, const char *name);
|
||||
#define os_mempool_init r_os_mempool_init
|
||||
/**
|
||||
* Initializes an extended memory pool. Extended attributes (e.g., callbacks)
|
||||
* are not specified when this function is called; they are assigned manually
|
||||
* after initialization.
|
||||
*
|
||||
* @param mpe The extended memory pool to initialize.
|
||||
* @param blocks The number of blocks in the pool.
|
||||
* @param block_size The size of each block, in bytes.
|
||||
* @param membuf Pointer to memory to contain blocks.
|
||||
* @param name Name of the pool.
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t r_os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks,
|
||||
uint32_t block_size, void *membuf, const char *name);
|
||||
#define os_mempool_ext_init r_os_mempool_ext_init
|
||||
/**
|
||||
* Removes the specified mempool from the list of initialized mempools.
|
||||
*
|
||||
* @param mp The mempool to unregister.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* OS_INVALID_PARM if the mempool is not
|
||||
* registered.
|
||||
*/
|
||||
// os_error_t r_os_mempool_unregister(struct os_mempool *mp);
|
||||
#define os_mempool_unregister(mp)
|
||||
|
||||
|
||||
/**
|
||||
* Clears a memory pool.
|
||||
*
|
||||
* @param mp The mempool to clear.
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t r_os_mempool_clear(struct os_mempool *mp);
|
||||
#define os_mempool_clear r_os_mempool_clear
|
||||
|
||||
|
||||
/**
|
||||
* Performs an integrity check of the specified mempool. This function
|
||||
* attempts to detect memory corruption in the specified memory pool.
|
||||
*
|
||||
* @param mp The mempool to check.
|
||||
*
|
||||
* @return true if the memory pool passes the integrity
|
||||
* check;
|
||||
* false if the memory pool is corrupt.
|
||||
*/
|
||||
bool r_os_mempool_is_sane(const struct os_mempool *mp);
|
||||
#define os_mempool_is_sane r_os_mempool_is_sane
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a memory block was allocated from the specified mempool.
|
||||
*
|
||||
* @param mp The mempool to check as parent.
|
||||
* @param block_addr The memory block to check as child.
|
||||
*
|
||||
* @return 0 if the block does not belong to the mempool;
|
||||
* 1 if the block does belong to the mempool.
|
||||
*/
|
||||
int r_os_memblock_from(const struct os_mempool *mp, const void *block_addr);
|
||||
#define os_memblock_from r_os_memblock_from
|
||||
|
||||
|
||||
/**
|
||||
* Get a memory block from a memory pool
|
||||
*
|
||||
* @param mp Pointer to the memory pool
|
||||
*
|
||||
* @return void* Pointer to block if available; NULL otherwise
|
||||
*/
|
||||
void *r_os_memblock_get(struct os_mempool *mp);
|
||||
#define os_memblock_get r_os_memblock_get
|
||||
/**
|
||||
* Puts the memory block back into the pool, ignoring the put callback, if any.
|
||||
* This function should only be called from a put callback to free a block
|
||||
* without causing infinite recursion.
|
||||
*
|
||||
* @param mp Pointer to memory pool
|
||||
* @param block_addr Pointer to memory block
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t r_os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr);
|
||||
#define os_memblock_put_from_cb r_os_memblock_put_from_cb
|
||||
|
||||
|
||||
/**
|
||||
* Puts the memory block back into the pool
|
||||
*
|
||||
* @param mp Pointer to memory pool
|
||||
* @param block_addr Pointer to memory block
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t r_os_memblock_put(struct os_mempool *mp, void *block_addr);
|
||||
#define os_memblock_put r_os_memblock_put
|
||||
|
||||
#else
|
||||
/**
|
||||
* Initialize a memory pool.
|
||||
*
|
||||
* @param mp Pointer to a pointer to a mempool
|
||||
* @param blocks The number of blocks in the pool
|
||||
* @param blocks_size The size of the block, in bytes.
|
||||
* @param membuf Pointer to memory to contain blocks.
|
||||
* @param name Name of the pool.
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t os_mempool_init(struct os_mempool *mp, uint16_t blocks,
|
||||
uint32_t block_size, void *membuf, const char *name);
|
||||
|
||||
/**
|
||||
* Initializes an extended memory pool. Extended attributes (e.g., callbacks)
|
||||
* are not specified when this function is called; they are assigned manually
|
||||
* after initialization.
|
||||
*
|
||||
* @param mpe The extended memory pool to initialize.
|
||||
* @param blocks The number of blocks in the pool.
|
||||
* @param block_size The size of each block, in bytes.
|
||||
* @param membuf Pointer to memory to contain blocks.
|
||||
* @param name Name of the pool.
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks,
|
||||
uint32_t block_size, void *membuf, const char *name);
|
||||
|
||||
/**
|
||||
* Removes the specified mempool from the list of initialized mempools.
|
||||
*
|
||||
* @param mp The mempool to unregister.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* OS_INVALID_PARM if the mempool is not
|
||||
* registered.
|
||||
*/
|
||||
os_error_t os_mempool_unregister(struct os_mempool *mp);
|
||||
|
||||
/**
|
||||
* Clears a memory pool.
|
||||
*
|
||||
* @param mp The mempool to clear.
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t os_mempool_clear(struct os_mempool *mp);
|
||||
|
||||
/**
|
||||
* Clears an extended memory pool.
|
||||
*
|
||||
* @param mpe The extended memory pool to clear.
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t os_mempool_ext_clear(struct os_mempool_ext *mpe);
|
||||
|
||||
/**
|
||||
* Performs an integrity check of the specified mempool. This function
|
||||
* attempts to detect memory corruption in the specified memory pool.
|
||||
*
|
||||
* @param mp The mempool to check.
|
||||
*
|
||||
* @return true if the memory pool passes the integrity
|
||||
* check;
|
||||
* false if the memory pool is corrupt.
|
||||
*/
|
||||
bool os_mempool_is_sane(const struct os_mempool *mp);
|
||||
|
||||
/**
|
||||
* Checks if a memory block was allocated from the specified mempool.
|
||||
*
|
||||
* @param mp The mempool to check as parent.
|
||||
* @param block_addr The memory block to check as child.
|
||||
*
|
||||
* @return 0 if the block does not belong to the mempool;
|
||||
* 1 if the block does belong to the mempool.
|
||||
*/
|
||||
int os_memblock_from(const struct os_mempool *mp, const void *block_addr);
|
||||
|
||||
/**
|
||||
* Get a memory block from a memory pool
|
||||
*
|
||||
* @param mp Pointer to the memory pool
|
||||
*
|
||||
* @return void* Pointer to block if available; NULL otherwise
|
||||
*/
|
||||
void *os_memblock_get(struct os_mempool *mp);
|
||||
|
||||
/**
|
||||
* Puts the memory block back into the pool, ignoring the put callback, if any.
|
||||
* This function should only be called from a put callback to free a block
|
||||
* without causing infinite recursion.
|
||||
*
|
||||
* @param mp Pointer to memory pool
|
||||
* @param block_addr Pointer to memory block
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr);
|
||||
|
||||
/**
|
||||
* Puts the memory block back into the pool
|
||||
*
|
||||
* @param mp Pointer to memory pool
|
||||
* @param block_addr Pointer to memory block
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_MEMPOOL_H_ */
|
||||
|
||||
|
||||
/**
|
||||
* @} OSMempool
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "esp_err.h"
|
||||
#include "queue.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
#include "syscfg/syscfg.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Local Defined Macros
|
||||
***************************************************************************************************
|
||||
*/
|
||||
#define BLE_MSYS_ALIGN(__n, __a) \
|
||||
((((__n) & ((__a) - 1)) == 0) ? (__n) : ((__n) + ((__a) - ((__n) & ((__a) - 1)))))
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
#define BLE_MSYS_1_BLOCK_COUNT MYNEWT_VAL(MSYS_1_BLOCK_COUNT)
|
||||
#define BLE_MSYS_1_BLOCK_SIZE MYNEWT_VAL(MSYS_1_BLOCK_SIZE)
|
||||
#define BLE_MSYS_2_BLOCK_COUNT MYNEWT_VAL(MSYS_2_BLOCK_COUNT)
|
||||
#define BLE_MSYS_2_BLOCK_SIZE MYNEWT_VAL(MSYS_2_BLOCK_SIZE)
|
||||
#define BLE_MSYS_BLOCK_FROM_HEAP CONFIG_BT_NIMBLE_MSYS_BUF_FROM_HEAP
|
||||
#else
|
||||
#define BLE_MSYS_1_BLOCK_COUNT CONFIG_BT_LE_MSYS_1_BLOCK_COUNT
|
||||
#define BLE_MSYS_1_BLOCK_SIZE CONFIG_BT_LE_MSYS_1_BLOCK_SIZE
|
||||
#define BLE_MSYS_2_BLOCK_COUNT CONFIG_BT_LE_MSYS_2_BLOCK_COUNT
|
||||
#define BLE_MSYS_2_BLOCK_SIZE CONFIG_BT_LE_MSYS_2_BLOCK_SIZE
|
||||
#define BLE_MSYS_BLOCK_FROM_HEAP CONFIG_BT_LE_MSYS_BUF_FROM_HEAP
|
||||
#endif /* CONFIG_BT_NIMBLE_ENABLED */
|
||||
|
||||
#if BLE_MSYS_1_BLOCK_COUNT > 0
|
||||
#define SYSINIT_MSYS_1_MEMBLOCK_SIZE BLE_MSYS_ALIGN(BLE_MSYS_1_BLOCK_SIZE, 4)
|
||||
#define SYSINIT_MSYS_1_MEMPOOL_SIZE \
|
||||
OS_MEMPOOL_SIZE(BLE_MSYS_1_BLOCK_COUNT, SYSINIT_MSYS_1_MEMBLOCK_SIZE)
|
||||
#else
|
||||
#error "BLE_MSYS_1_BLOCK_COUNT should be larger than 0!"
|
||||
#endif /* BLE_MSYS_1_BLOCK_COUNT > 0 */
|
||||
|
||||
#if BLE_MSYS_2_BLOCK_COUNT > 0
|
||||
#define SYSINIT_MSYS_2_MEMBLOCK_SIZE BLE_MSYS_ALIGN(BLE_MSYS_2_BLOCK_SIZE, 4)
|
||||
#define SYSINIT_MSYS_2_MEMPOOL_SIZE \
|
||||
OS_MEMPOOL_SIZE(BLE_MSYS_2_BLOCK_COUNT, SYSINIT_MSYS_2_MEMBLOCK_SIZE)
|
||||
#else
|
||||
#error #error "BLE_MSYS_2_BLOCK_COUNT should be larger than 0!"
|
||||
#endif /* BLE_MSYS_2_BLOCK_COUNT > 0 */
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* External Functions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
extern int r_esp_ble_msys_init(uint16_t msys_size1, uint16_t msys_size2, uint16_t msys_cnt1,
|
||||
uint16_t msys_cnt2, uint8_t from_heap);
|
||||
extern void r_esp_ble_msys_deinit(void);
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* BLE MSYS Initialization
|
||||
***************************************************************************************************
|
||||
*/
|
||||
int
|
||||
ble_msys_init(void)
|
||||
{
|
||||
return r_esp_ble_msys_init(SYSINIT_MSYS_1_MEMBLOCK_SIZE, SYSINIT_MSYS_2_MEMBLOCK_SIZE,
|
||||
BLE_MSYS_1_BLOCK_COUNT, BLE_MSYS_2_BLOCK_COUNT,
|
||||
BLE_MSYS_BLOCK_FROM_HEAP);
|
||||
}
|
||||
|
||||
void
|
||||
ble_msys_deinit(void)
|
||||
{
|
||||
r_esp_ble_msys_deinit();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BTDM_COEX_H_
|
||||
#define _BTDM_COEX_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
esp_err_t btdm_coex_init(void);
|
||||
|
||||
void btdm_coex_deinit(void);
|
||||
|
||||
esp_err_t btdm_coex_enable(void);
|
||||
|
||||
void btdm_coex_disable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BTDM_COEX_H_ */
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BTDM_ENDIAN_H_
|
||||
#define _BTDM_ENDIAN_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
btdm_put_le16(void *buf, uint16_t x)
|
||||
{
|
||||
extern void r_btdm_put_le16(void *buf, uint16_t x);
|
||||
r_btdm_put_le16(buf, x);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_put_le24(void *buf, uint32_t x)
|
||||
{
|
||||
extern void r_btdm_put_le24(void *buf, uint32_t x);
|
||||
r_btdm_put_le24(buf, x);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_put_le32(void *buf, uint32_t x)
|
||||
{
|
||||
extern void r_btdm_put_le32(void *buf, uint32_t x);
|
||||
r_btdm_put_le32(buf, x);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_put_le64(void *buf, uint64_t x)
|
||||
{
|
||||
extern void r_btdm_put_le64(void *buf, uint64_t x);
|
||||
r_btdm_put_le64(buf, x);
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
btdm_get_le16(const void *buf)
|
||||
{
|
||||
extern uint16_t r_btdm_get_le16(const void *buf);
|
||||
return r_btdm_get_le16(buf);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
btdm_get_le24(const void *buf)
|
||||
{
|
||||
extern uint32_t r_btdm_get_le24(const void *buf);
|
||||
return r_btdm_get_le24(buf);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
btdm_get_le32(const void *buf)
|
||||
{
|
||||
extern uint32_t r_btdm_get_le32(const void *buf);
|
||||
return r_btdm_get_le32(buf);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
btdm_get_le64(const void *buf)
|
||||
{
|
||||
extern uint64_t r_btdm_get_le64(const void *buf);
|
||||
return r_btdm_get_le64(buf);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_put_be16(void *buf, uint16_t x)
|
||||
{
|
||||
extern void r_btdm_put_be16(void *buf, uint16_t x);
|
||||
r_btdm_put_be16(buf, x);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_put_be24(void *buf, uint32_t x)
|
||||
{
|
||||
extern void r_btdm_put_be24(void *buf, uint32_t x);
|
||||
r_btdm_put_be24(buf, x);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_put_be32(void *buf, uint32_t x)
|
||||
{
|
||||
extern void r_btdm_put_be32(void *buf, uint32_t x);
|
||||
r_btdm_put_be32(buf, x);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_put_be64(void *buf, uint64_t x)
|
||||
{
|
||||
extern void r_btdm_put_be64(void *buf, uint64_t x);
|
||||
r_btdm_put_be64(buf, x);
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
btdm_get_be16(const void *buf)
|
||||
{
|
||||
extern uint16_t r_btdm_get_be16(const void *buf);
|
||||
return r_btdm_get_be16(buf);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
btdm_get_be24(const void *buf)
|
||||
{
|
||||
extern uint32_t r_btdm_get_be24(const void *buf);
|
||||
return r_btdm_get_be24(buf);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
btdm_get_be32(const void *buf)
|
||||
{
|
||||
extern uint32_t r_btdm_get_be32(const void *buf);
|
||||
return r_btdm_get_be32(buf);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
btdm_get_be64(const void *buf)
|
||||
{
|
||||
extern uint64_t r_btdm_get_be64(const void *buf);
|
||||
return r_btdm_get_be64(buf);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_swap_in_place(void *buf, int len)
|
||||
{
|
||||
extern void r_btdm_swap_in_place(void *buf, int len);
|
||||
r_btdm_swap_in_place(buf, len);
|
||||
}
|
||||
|
||||
static inline void
|
||||
btdm_swap_buf(uint8_t *dst, const uint8_t *src, int len)
|
||||
{
|
||||
extern void r_btdm_swap_buf(uint8_t *dst, const uint8_t *src, int len);
|
||||
r_btdm_swap_buf(dst, src, len);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BTDM_ENDIAN_H_ */
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _BTDM_EXTERNAL_H_
|
||||
#define _BTDM_EXTERNAL_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BTDM_EXTERNAL_WR_FUNC(f) wr_ ## f
|
||||
|
||||
#define btdm_external_bb_get_tx_pwr_table BTDM_EXTERNAL_WR_FUNC(btdm_external_bb_get_tx_pwr_table)
|
||||
|
||||
/*
|
||||
* Function declarations for BTDM EXTERNAL
|
||||
*/
|
||||
const int8_t *wr_btdm_external_bb_get_tx_pwr_table(uint8_t *length);
|
||||
|
||||
int btdm_external_init(void);
|
||||
void btdm_external_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BTDM_EXTERNAL_H_ */
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _BTDM_LOG_H_
|
||||
#define _BTDM_LOG_H_
|
||||
|
||||
int btdm_log_init(void);
|
||||
|
||||
void btdm_log_deinit(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _BTDM_LP_H_
|
||||
#define _BTDM_LP_H_
|
||||
|
||||
void btdm_lp_enable_clock(esp_btdm_controller_config_t *cfg);
|
||||
|
||||
void btdm_lp_disable_clock(void);
|
||||
|
||||
int btdm_lp_init(void);
|
||||
|
||||
void btdm_lp_deinit(void);
|
||||
|
||||
void btdm_lp_reset(bool enable_stage);
|
||||
|
||||
void btdm_lp_shutdown(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _BTDM_MEMPOOL_H_
|
||||
#define _BTDM_MEMPOOL_H_
|
||||
|
||||
#include "btdm_osal.h"
|
||||
#include "queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A memory block structure. This simply contains a pointer to the free list
|
||||
* chain and is only used when the block is on the free list. When the block
|
||||
* has been removed from the free list the entire memory block is usable by the
|
||||
* caller.
|
||||
*/
|
||||
struct btdm_memblock {
|
||||
SLIST_ENTRY(btdm_memblock) mb_next;
|
||||
};
|
||||
|
||||
/* XXX: Change this structure so that we keep the first address in the pool? */
|
||||
/* XXX: add memory debug structure and associated code */
|
||||
/* XXX: Change how I coded the SLIST_HEAD here. It should be named:
|
||||
SLIST_HEAD(,btdm_memblock) mp_head; */
|
||||
|
||||
/**
|
||||
* Memory pool
|
||||
*/
|
||||
struct btdm_mempool {
|
||||
/** Size of the memory blocks, in bytes. */
|
||||
uint32_t mp_block_size;
|
||||
/** The number of memory blocks. */
|
||||
uint16_t mp_num_blocks;
|
||||
/** The number of free blocks left */
|
||||
uint16_t mp_num_free;
|
||||
/** The lowest number of free blocks seen */
|
||||
uint16_t mp_min_free;
|
||||
/** Bitmap of OS_MEMPOOL_F_[...] values. */
|
||||
uint8_t mp_flags;
|
||||
/** Address of memory buffer used by pool */
|
||||
uint32_t mp_membuf_addr;
|
||||
STAILQ_ENTRY(btdm_mempool) mp_list;
|
||||
SLIST_HEAD(, btdm_memblock);
|
||||
/** Name for memory block */
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates an extended mempool. Address can be safely cast to
|
||||
* (struct btdm_mempool_ext *).
|
||||
*/
|
||||
#define BTDM_MEMPOOL_F_EXT 0x01
|
||||
|
||||
#define BTDM_ALIGNMENT 4
|
||||
#define BTDM_MEMPOOL_SIZE(n, blksize) \
|
||||
((((blksize) + ((BTDM_ALIGNMENT) - 1)) / (BTDM_ALIGNMENT)) * (n))
|
||||
|
||||
#if (BTDM_ALIGNMENT == 4)
|
||||
typedef uint32_t btdm_membuf_t;
|
||||
#elif (BTDM_ALIGNMENT == 8)
|
||||
typedef uint64_t btdm_membuf_t;
|
||||
#elif (BTDM_ALIGNMENT == 16)
|
||||
typedef __uint128_t btdm_membuf_t;
|
||||
#else
|
||||
#error "Unhandled `BTDM_ALIGNMENT` for `btdm_membuf_t`"
|
||||
#endif /* BTDM_ALIGNMENT == * */
|
||||
|
||||
/**
|
||||
* Initialize a memory pool.
|
||||
*
|
||||
* @param mp Pointer to a pointer to a mempool
|
||||
* @param blocks The number of blocks in the pool
|
||||
* @param blocks_size The size of the block, in bytes.
|
||||
* @param membuf Pointer to memory to contain blocks.
|
||||
* @param name Name of the pool.
|
||||
*
|
||||
* @return btdm_osal_error_t
|
||||
*/
|
||||
static inline btdm_osal_error_t
|
||||
btdm_mempool_init(struct btdm_mempool *mp, uint16_t blocks, uint32_t block_size, void *membuf,
|
||||
const char *name)
|
||||
{
|
||||
extern btdm_osal_error_t r_btdm_os_mempool_init(struct btdm_mempool * mp, uint16_t blocks,
|
||||
uint32_t block_size, void *membuf,
|
||||
const char *name);
|
||||
return r_btdm_os_mempool_init(mp, blocks, block_size, membuf, name);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Initializes an extended memory pool. Extended attributes (e.g., callbacks)
|
||||
* are not specified when this function is called; they are assigned manually
|
||||
* after initialization.
|
||||
*
|
||||
* @param mpe The extended memory pool to initialize.
|
||||
* @param blocks The number of blocks in the pool.
|
||||
* @param block_size The size of each block, in bytes.
|
||||
* @param membuf Pointer to memory to contain blocks.
|
||||
* @param name Name of the pool.
|
||||
*
|
||||
* @return btdm_osal_error_t
|
||||
*/
|
||||
static inline btdm_osal_error_t
|
||||
btdm_mempool_ext_init(struct btdm_mempool_ext *mpe, uint16_t blocks, uint32_t block_size,
|
||||
void *membuf, const char *name)
|
||||
{
|
||||
extern btdm_osal_error_t r_btdm_os_mempool_ext_init(struct btdm_mempool_ext * mpe,
|
||||
uint16_t blocks, uint32_t block_size,
|
||||
void *membuf, const char *name);
|
||||
return r_btdm_os_mempool_ext_init(mpe, blocks, block_size, membuf, name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Clears a memory pool.
|
||||
*
|
||||
* @param mp The mempool to clear.
|
||||
*
|
||||
* @return btdm_osal_error_t
|
||||
*/
|
||||
static inline btdm_osal_error_t
|
||||
btdm_mempool_clear(struct btdm_mempool *mp)
|
||||
{
|
||||
extern btdm_osal_error_t r_btdm_os_mempool_clear(struct btdm_mempool * mp);
|
||||
return r_btdm_os_mempool_clear(mp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an integrity check of the specified mempool. This function
|
||||
* attempts to detect memory corruption in the specified memory pool.
|
||||
*
|
||||
* @param mp The mempool to check.
|
||||
*
|
||||
* @return true if the memory pool passes the integrity
|
||||
* check;
|
||||
* false if the memory pool is corrupt.
|
||||
*/
|
||||
static inline bool
|
||||
btdm_mempool_is_sane(const struct btdm_mempool *mp)
|
||||
{
|
||||
extern bool r_btdm_os_mempool_is_sane(const struct btdm_mempool *mp);
|
||||
return r_btdm_os_mempool_is_sane(mp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a memory block was allocated from the specified mempool.
|
||||
*
|
||||
* @param mp The mempool to check as parent.
|
||||
* @param block_addr The memory block to check as child.
|
||||
*
|
||||
* @return 0 if the block does not belong to the mempool;
|
||||
* 1 if the block does belong to the mempool.
|
||||
*/
|
||||
static inline int
|
||||
btdm_memblock_from(const struct btdm_mempool *mp, const void *block_addr)
|
||||
{
|
||||
extern int r_btdm_os_memblock_from(const struct btdm_mempool *mp, const void *block_addr);
|
||||
return r_btdm_os_memblock_from(mp, block_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a memory block from a memory pool
|
||||
*
|
||||
* @param mp Pointer to the memory pool
|
||||
*
|
||||
* @return void* Pointer to block if available; NULL otherwise
|
||||
*/
|
||||
static inline void *
|
||||
btdm_memblock_get(struct btdm_mempool *mp)
|
||||
{
|
||||
extern void *r_btdm_os_memblock_get(struct btdm_mempool * mp);
|
||||
return r_btdm_os_memblock_get(mp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the memory block back into the pool, ignoring the put callback, if any.
|
||||
* This function should only be called from a put callback to free a block
|
||||
* without causing infinite recursion.
|
||||
*
|
||||
* @param mp Pointer to memory pool
|
||||
* @param block_addr Pointer to memory block
|
||||
*
|
||||
* @return btdm_osal_error_t
|
||||
*/
|
||||
static inline btdm_osal_error_t
|
||||
btdm_mempool_put_from_cb(struct btdm_mempool *mp, void *block_addr)
|
||||
{
|
||||
extern btdm_osal_error_t r_btdm_os_memblock_put_from_cb(struct btdm_mempool * mp,
|
||||
void *block_addr);
|
||||
return r_btdm_os_memblock_put_from_cb(mp, block_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the memory block back into the pool
|
||||
*
|
||||
* @param mp Pointer to memory pool
|
||||
* @param block_addr Pointer to memory block
|
||||
*
|
||||
* @return btdm_osal_error_t
|
||||
*/
|
||||
static inline btdm_osal_error_t
|
||||
btdm_memblock_put(struct btdm_mempool *mp, void *block_addr)
|
||||
{
|
||||
extern btdm_osal_error_t r_btdm_os_memblock_put(struct btdm_mempool * mp, void *block_addr);
|
||||
return r_btdm_os_memblock_put(mp, block_addr);
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
btdm_memblock_free_num_get(struct btdm_mempool *mp)
|
||||
{
|
||||
extern uint16_t r_btdm_os_memblock_num_free(struct btdm_mempool * mp);
|
||||
return r_btdm_os_memblock_num_free(mp);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BTDM_MEMPOOL_H_ */
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BTDM_OSAL_H_
|
||||
#define _BTDM_OSAL_H_
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum btdm_osal_error {
|
||||
BTDM_OSAL_OK = 0,
|
||||
BTDM_OSAL_ENOMEM = 1,
|
||||
BTDM_OSAL_EINVAL = 2,
|
||||
BTDM_OSAL_INVALID_PARM = 3,
|
||||
BTDM_OSAL_MEM_NOT_ALIGNED = 4,
|
||||
BTDM_OSAL_BAD_MUTEX = 5,
|
||||
BTDM_OSAL_TIMEOUT = 6,
|
||||
BTDM_OSAL_ERR_IN_ISR = 7, /* Function cannot be called from ISR */
|
||||
BTDM_OSAL_ERR_PRIV = 8, /* Privileged access error */
|
||||
BTDM_OSAL_NOT_STARTED = 9, /* OS must be started to call this function, but isn't */
|
||||
BTDM_OSAL_ENOENT = 10, /* No such thing */
|
||||
BTDM_OSAL_EBUSY = 11, /* Resource busy */
|
||||
BTDM_OSAL_ERROR = 12, /* Generic Error */
|
||||
};
|
||||
|
||||
enum btdm_osal_malloc_flag {
|
||||
BTDM_OSAL_MALLOC_F_INTERNAL = 0,
|
||||
BTDM_OSAL_MALLOC_F_NORMAL,
|
||||
};
|
||||
typedef enum btdm_osal_malloc_flag btdm_osal_malloc_flag_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t evt_count;
|
||||
uint16_t evtq_count;
|
||||
uint16_t co_count;
|
||||
uint16_t sem_count;
|
||||
uint16_t mutex_count;
|
||||
} btdm_osal_elem_num_t;
|
||||
|
||||
struct btdm_osal_event {
|
||||
void *event;
|
||||
};
|
||||
|
||||
struct btdm_osal_eventq {
|
||||
void *eventq;
|
||||
};
|
||||
|
||||
struct btdm_osal_callout {
|
||||
void *co;
|
||||
};
|
||||
|
||||
struct btdm_osal_mutex {
|
||||
void *mutex;
|
||||
};
|
||||
|
||||
struct btdm_osal_sem {
|
||||
void *sem;
|
||||
};
|
||||
|
||||
/*
|
||||
* Type definitions for BTDM OSAL
|
||||
*/
|
||||
typedef uint32_t btdm_osal_time_t;
|
||||
typedef int btdm_osal_error_t;
|
||||
typedef void btdm_osal_event_fn(struct btdm_osal_event *ev);
|
||||
typedef void btdm_osal_task_fn(void *arg);
|
||||
typedef void btdm_osal_intr_fn(void *arg);
|
||||
typedef void *btdm_osal_task_handle_t;
|
||||
typedef void *btdm_osal_intr_handle_t;
|
||||
|
||||
/*
|
||||
* Function declarations for BTDM OSAL
|
||||
*/
|
||||
void wr_btdm_osal_eventq_init(struct btdm_osal_eventq *evq);
|
||||
void wr_btdm_osal_eventq_deinit(struct btdm_osal_eventq *evq);
|
||||
struct btdm_osal_event *wr_btdm_osal_eventq_get(struct btdm_osal_eventq *evq, btdm_osal_time_t tmo);
|
||||
void wr_btdm_osal_eventq_put(struct btdm_osal_eventq *evq, struct btdm_osal_event *ev);
|
||||
void wr_btdm_osal_eventq_put_to_front(struct btdm_osal_eventq *evq, struct btdm_osal_event *ev);
|
||||
void wr_btdm_osal_eventq_remove(struct btdm_osal_eventq *evq, struct btdm_osal_event *ev);
|
||||
bool wr_btdm_osal_eventq_is_empty(struct btdm_osal_eventq *evq);
|
||||
|
||||
void wr_btdm_osal_event_run(struct btdm_osal_event *ev);
|
||||
void wr_btdm_osal_event_init(struct btdm_osal_event *ev, btdm_osal_event_fn *fn, void *arg);
|
||||
void wr_btdm_osal_event_deinit(struct btdm_osal_event *ev);
|
||||
void wr_btdm_osal_event_reset(struct btdm_osal_event *ev);
|
||||
bool wr_btdm_osal_event_is_queued(struct btdm_osal_event *ev);
|
||||
void *wr_btdm_osal_event_get_arg(struct btdm_osal_event *ev);
|
||||
void wr_btdm_osal_event_set_arg(struct btdm_osal_event *ev, void *arg);
|
||||
|
||||
btdm_osal_error_t wr_btdm_osal_mutex_init(struct btdm_osal_mutex *mu);
|
||||
btdm_osal_error_t wr_btdm_osal_mutex_deinit(struct btdm_osal_mutex *mu);
|
||||
btdm_osal_error_t wr_btdm_osal_mutex_pend(struct btdm_osal_mutex *mu, btdm_osal_time_t timeout);
|
||||
btdm_osal_error_t wr_btdm_osal_mutex_release(struct btdm_osal_mutex *mu);
|
||||
|
||||
btdm_osal_error_t wr_btdm_osal_sem_init(struct btdm_osal_sem *sem, uint16_t tokens);
|
||||
btdm_osal_error_t wr_btdm_osal_sem_deinit(struct btdm_osal_sem *sem);
|
||||
btdm_osal_error_t wr_btdm_osal_sem_pend(struct btdm_osal_sem *sem, btdm_osal_time_t timeout);
|
||||
btdm_osal_error_t wr_btdm_osal_sem_release(struct btdm_osal_sem *sem);
|
||||
uint16_t wr_btdm_osal_sem_get_count(struct btdm_osal_sem *sem);
|
||||
|
||||
int wr_btdm_osal_callout_init(struct btdm_osal_callout *co, struct btdm_osal_eventq *evq,
|
||||
btdm_osal_event_fn *ev_cb, void *ev_arg);
|
||||
void wr_btdm_osal_callout_deinit(struct btdm_osal_callout *co);
|
||||
btdm_osal_error_t wr_btdm_osal_callout_reset(struct btdm_osal_callout *co, btdm_osal_time_t ticks);
|
||||
void wr_btdm_osal_callout_mem_reset(struct btdm_osal_callout *co);
|
||||
void wr_btdm_osal_callout_stop(struct btdm_osal_callout *co);
|
||||
bool wr_btdm_osal_callout_is_active(struct btdm_osal_callout *co);
|
||||
btdm_osal_time_t wr_btdm_osal_callout_get_ticks(struct btdm_osal_callout *co);
|
||||
btdm_osal_time_t wr_btdm_osal_callout_remaining_ticks(struct btdm_osal_callout *co,
|
||||
btdm_osal_time_t time);
|
||||
void wr_btdm_osal_callout_set_arg(struct btdm_osal_callout *co, void *arg);
|
||||
|
||||
btdm_osal_time_t wr_btdm_osal_time_get(void);
|
||||
btdm_osal_error_t wr_btdm_osal_time_ms_to_ticks(uint32_t ms, btdm_osal_time_t *out_ticks);
|
||||
btdm_osal_error_t wr_btdm_osal_time_ticks_to_ms(btdm_osal_time_t ticks, uint32_t *out_ms);
|
||||
btdm_osal_time_t wr_btdm_osal_time_ms_to_ticks32(uint32_t ms);
|
||||
uint32_t wr_btdm_osal_time_ticks_to_ms32(btdm_osal_time_t ticks);
|
||||
|
||||
uint32_t wr_btdm_osal_hw_enter_critical(void);
|
||||
void wr_btdm_osal_hw_exit_critical(uint32_t ctx);
|
||||
uint8_t wr_btdm_osal_hw_is_in_critical(void);
|
||||
|
||||
uint32_t wr_btdm_osal_get_time_forever(void);
|
||||
|
||||
int wr_btdm_osal_task_create(btdm_osal_task_fn *fn, const char *name, uint32_t stack_size,
|
||||
void *arg, uint32_t priority, btdm_osal_task_handle_t *task_handle,
|
||||
uint32_t core_id);
|
||||
void wr_btdm_osal_task_delete(btdm_osal_task_handle_t task_handle);
|
||||
|
||||
int wr_btdm_osal_intr_alloc(int src, int flags, btdm_osal_intr_fn *fn, void *arg,
|
||||
btdm_osal_intr_handle_t *intr_handle);
|
||||
int wr_btdm_osal_intr_free(btdm_osal_intr_handle_t intr_handle);
|
||||
|
||||
void *wr_btdm_osal_malloc(uint32_t size, btdm_osal_malloc_flag_t flags);
|
||||
void wr_btdm_osal_free(void *ptr);
|
||||
|
||||
#if !CONFIG_BTDM_CTRL_MULTI_LINK_ENABLED
|
||||
void *wr_btdm_osal_mmgmt_block_malloc(uint32_t size);
|
||||
void wr_btdm_osal_mmgmt_block_free(void *ptr);
|
||||
void wr_btdm_osal_mmgmt_block_copy(void *dst, const void *src, uint16_t size);
|
||||
#endif /* !CONFIG_BTDM_CTRL_MULTI_LINK_ENABLED */
|
||||
|
||||
// void * wr_btdm_osal_ets_delay_us(uint32_t us);
|
||||
int wr_btdm_osal_read_efuse_mac(uint8_t *mac);
|
||||
void wr_btdm_osal_srand(uint32_t seed);
|
||||
int wr_btdm_osal_rand(void);
|
||||
|
||||
int btdm_osal_elem_mempool_init(btdm_osal_elem_num_t *elem_num);
|
||||
|
||||
void btdm_osal_elem_mempool_deinit(void);
|
||||
|
||||
|
||||
#define BTDM_OSAL_WR_FUNC(f) wr_ ## f
|
||||
|
||||
#define btdm_osal_eventq_init BTDM_OSAL_WR_FUNC(btdm_osal_eventq_init)
|
||||
#define btdm_osal_eventq_deinit BTDM_OSAL_WR_FUNC(btdm_osal_eventq_deinit)
|
||||
#define btdm_osal_eventq_get BTDM_OSAL_WR_FUNC(btdm_osal_eventq_get)
|
||||
#define btdm_osal_eventq_put BTDM_OSAL_WR_FUNC(btdm_osal_eventq_put)
|
||||
#define btdm_osal_eventq_put_to_front BTDM_OSAL_WR_FUNC(btdm_osal_eventq_put_to_front)
|
||||
#define btdm_osal_eventq_remove BTDM_OSAL_WR_FUNC(btdm_osal_eventq_remove)
|
||||
#define btdm_osal_eventq_is_empty BTDM_OSAL_WR_FUNC(btdm_osal_eventq_is_empty)
|
||||
#define btdm_osal_event_run BTDM_OSAL_WR_FUNC(btdm_osal_event_run)
|
||||
#define btdm_osal_event_init BTDM_OSAL_WR_FUNC(btdm_osal_event_init)
|
||||
#define btdm_osal_event_deinit BTDM_OSAL_WR_FUNC(btdm_osal_event_deinit)
|
||||
#define btdm_osal_event_reset BTDM_OSAL_WR_FUNC(btdm_osal_event_reset)
|
||||
#define btdm_osal_event_is_queued BTDM_OSAL_WR_FUNC(btdm_osal_event_is_queued)
|
||||
#define btdm_osal_event_get_arg BTDM_OSAL_WR_FUNC(btdm_osal_event_get_arg)
|
||||
#define btdm_osal_event_set_arg BTDM_OSAL_WR_FUNC(btdm_osal_event_set_arg)
|
||||
#define btdm_osal_mutex_init BTDM_OSAL_WR_FUNC(btdm_osal_mutex_init)
|
||||
#define btdm_osal_mutex_deinit BTDM_OSAL_WR_FUNC(btdm_osal_mutex_deinit)
|
||||
#define btdm_osal_mutex_pend BTDM_OSAL_WR_FUNC(btdm_osal_mutex_pend)
|
||||
#define btdm_osal_mutex_release BTDM_OSAL_WR_FUNC(btdm_osal_mutex_release)
|
||||
#define btdm_osal_sem_init BTDM_OSAL_WR_FUNC(btdm_osal_sem_init)
|
||||
#define btdm_osal_sem_deinit BTDM_OSAL_WR_FUNC(btdm_osal_sem_deinit)
|
||||
#define btdm_osal_sem_pend BTDM_OSAL_WR_FUNC(btdm_osal_sem_pend)
|
||||
#define btdm_osal_sem_release BTDM_OSAL_WR_FUNC(btdm_osal_sem_release)
|
||||
#define btdm_osal_sem_get_count BTDM_OSAL_WR_FUNC(btdm_osal_sem_get_count)
|
||||
#define btdm_osal_callout_init BTDM_OSAL_WR_FUNC(btdm_osal_callout_init)
|
||||
#define btdm_osal_callout_deinit BTDM_OSAL_WR_FUNC(btdm_osal_callout_deinit)
|
||||
#define btdm_osal_callout_reset BTDM_OSAL_WR_FUNC(btdm_osal_callout_reset)
|
||||
#define btdm_osal_callout_mem_reset BTDM_OSAL_WR_FUNC(btdm_osal_callout_mem_reset)
|
||||
#define btdm_osal_callout_stop BTDM_OSAL_WR_FUNC(btdm_osal_callout_stop)
|
||||
#define btdm_osal_callout_is_active BTDM_OSAL_WR_FUNC(btdm_osal_callout_is_active)
|
||||
#define btdm_osal_callout_get_ticks BTDM_OSAL_WR_FUNC(btdm_osal_callout_get_ticks)
|
||||
#define btdm_osal_callout_remaining_ticks BTDM_OSAL_WR_FUNC(btdm_osal_callout_remaining_ticks)
|
||||
#define btdm_osal_callout_set_arg BTDM_OSAL_WR_FUNC(btdm_osal_callout_set_arg)
|
||||
#define btdm_osal_time_get BTDM_OSAL_WR_FUNC(btdm_osal_time_get)
|
||||
#define btdm_osal_time_ms_to_ticks BTDM_OSAL_WR_FUNC(btdm_osal_time_ms_to_ticks)
|
||||
#define btdm_osal_time_ticks_to_ms BTDM_OSAL_WR_FUNC(btdm_osal_time_ticks_to_ms)
|
||||
#define btdm_osal_time_ms_to_ticks32 BTDM_OSAL_WR_FUNC(btdm_osal_time_ms_to_ticks32)
|
||||
#define btdm_osal_time_ticks_to_ms32 BTDM_OSAL_WR_FUNC(btdm_osal_time_ticks_to_ms32)
|
||||
#define btdm_osal_hw_enter_critical BTDM_OSAL_WR_FUNC(btdm_osal_hw_enter_critical)
|
||||
#define btdm_osal_hw_exit_critical BTDM_OSAL_WR_FUNC(btdm_osal_hw_exit_critical)
|
||||
#define btdm_osal_hw_is_in_critical BTDM_OSAL_WR_FUNC(btdm_osal_hw_is_in_critical)
|
||||
#define btdm_osal_get_time_forever BTDM_OSAL_WR_FUNC(btdm_osal_get_time_forever)
|
||||
#define btdm_osal_task_create BTDM_OSAL_WR_FUNC(btdm_osal_task_create)
|
||||
#define btdm_osal_task_delete BTDM_OSAL_WR_FUNC(btdm_osal_task_delete)
|
||||
#define btdm_osal_intr_alloc BTDM_OSAL_WR_FUNC(btdm_osal_intr_alloc)
|
||||
#define btdm_osal_intr_free BTDM_OSAL_WR_FUNC(btdm_osal_intr_free)
|
||||
#define btdm_osal_malloc BTDM_OSAL_WR_FUNC(btdm_osal_malloc)
|
||||
#define btdm_osal_free BTDM_OSAL_WR_FUNC(btdm_osal_free)
|
||||
#define btdm_osal_mmgmt_block_malloc BTDM_OSAL_WR_FUNC(btdm_osal_mmgmt_block_malloc)
|
||||
#define btdm_osal_mmgmt_block_free BTDM_OSAL_WR_FUNC(btdm_osal_mmgmt_block_free)
|
||||
#define btdm_osal_mmgmt_block_copy BTDM_OSAL_WR_FUNC(btdm_osal_mmgmt_block_copy)
|
||||
#define btdm_osal_ets_delay_us BTDM_OSAL_WR_FUNC(btdm_osal_ets_delay_us)
|
||||
#define btdm_osal_read_efuse_mac BTDM_OSAL_WR_FUNC(btdm_osal_read_efuse_mac)
|
||||
#define btdm_osal_rand BTDM_OSAL_WR_FUNC(btdm_osal_rand)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BTDM_OSAL_H_ */
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _BTDM_OSAL_FREERTOS_H_
|
||||
#define _BTDM_OSAL_FREERTOS_H_
|
||||
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "sdkconfig.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "btdm_osal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if ((defined(CONFIG_BT_NIMBLE_USE_ESP_TIMER) && CONFIG_BT_NIMBLE_USE_ESP_TIMER) || \
|
||||
(defined(CONFIG_BT_LE_USE_ESP_TIMER) && CONFIG_BT_LE_USE_ESP_TIMER))
|
||||
/* Use esp timer instead of FreeRTOS timer to implement the callout. */
|
||||
#define BTDM_OSAL_USE_ESP_TIMER (1)
|
||||
#else
|
||||
#define BTDM_OSAL_USE_ESP_TIMER (0)
|
||||
#endif
|
||||
|
||||
struct btdm_osal_event_freertos {
|
||||
bool queued;
|
||||
void (*fn)(struct btdm_osal_event *ev);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
struct btdm_osal_eventq_freertos {
|
||||
QueueHandle_t q;
|
||||
};
|
||||
|
||||
struct btdm_osal_callout_freertos {
|
||||
#if BTDM_OSAL_USE_ESP_TIMER
|
||||
esp_timer_handle_t handle;
|
||||
#else
|
||||
TimerHandle_t handle;
|
||||
#endif
|
||||
struct btdm_osal_eventq *evq;
|
||||
struct btdm_osal_event ev;
|
||||
};
|
||||
|
||||
struct btdm_osal_mutex_freertos {
|
||||
SemaphoreHandle_t handle;
|
||||
};
|
||||
|
||||
struct btdm_osal_sem_freertos {
|
||||
SemaphoreHandle_t handle;
|
||||
};
|
||||
|
||||
typedef void btdm_osal_event_fn_freertos(struct btdm_osal_event_freertos *ev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BTDM_OSAL_FREERTOS_H_ */
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ESP_BTDM_CFG_H__
|
||||
#define __ESP_BTDM_CFG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_CTRL_SLEEP_ENABLE
|
||||
#define UC_BT_CTRL_SLEEP_ENABLE CONFIG_BT_CTRL_SLEEP_ENABLE
|
||||
#else
|
||||
#define UC_BT_CTRL_SLEEP_ENABLE (0)
|
||||
#endif
|
||||
|
||||
#define UC_BT_CTRL_TASK_STACK_SIZE CONFIG_BT_CTRL_TASK_STACK_SIZE
|
||||
|
||||
#ifdef CONFIG_BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
#define UC_HCI_UART_EN CONFIG_BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
#else
|
||||
#define UC_HCI_UART_EN 0 // hci ram mode
|
||||
#endif
|
||||
|
||||
#if UC_HCI_UART_EN
|
||||
#define UC_BT_CTRL_HCI_UART_TX_PIN (CONFIG_BT_CTRL_HCI_UART_TX_PIN)
|
||||
#define UC_BT_CTRL_HCI_UART_RX_PIN (CONFIG_BT_CTRL_HCI_UART_RX_PIN)
|
||||
#define UC_BT_CTRL_HCI_UART_PORT (CONFIG_BT_CTRL_HCI_UART_PORT)
|
||||
#define UC_BT_CTRL_HCI_UART_BAUD (CONFIG_BT_CTRL_HCI_UART_BAUD)
|
||||
#define UC_BT_CTRL_HCI_UART_DATA_BITS (UART_DATA_8_BITS)
|
||||
#define UC_BT_CTRL_HCI_UART_STOP_BITS (UART_STOP_BITS_1)
|
||||
#define UC_BT_CTRL_HCI_UART_PARITY (0)
|
||||
#define UC_BT_CTRL_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE)
|
||||
#else
|
||||
#define UC_BT_CTRL_HCI_UART_TX_PIN (0)
|
||||
#define UC_BT_CTRL_HCI_UART_RX_PIN (0)
|
||||
#define UC_BT_CTRL_HCI_UART_PORT (0)
|
||||
#define UC_BT_CTRL_HCI_UART_BAUD (0)
|
||||
#define UC_BT_CTRL_HCI_UART_DATA_BITS (0)
|
||||
#define UC_BT_CTRL_HCI_UART_STOP_BITS (0)
|
||||
#define UC_BT_CTRL_HCI_UART_PARITY (0)
|
||||
#define UC_BT_CTRL_HCI_UART_TASK_STACK_SIZE (0)
|
||||
#endif
|
||||
|
||||
#if (CONFIG_BT_CTRL_HCI_UART_FLOWCTRL)
|
||||
#define UC_BT_CTRL_HCI_UART_FLOW_CTRL (CONFIG_BT_CTRL_HCI_UART_FLOWCTRL)
|
||||
#if UC_BT_CTRL_HCI_UART_FLOW_CTRL
|
||||
#define UC_BT_CTRL_HCI_UART_CTS_PIN (CONFIG_BT_CTRL_HCI_UART_CTS_PIN)
|
||||
#define UC_BT_CTRL_HCI_UART_RTS_PIN (CONFIG_BT_CTRL_HCI_UART_RTS_PIN)
|
||||
#else
|
||||
#define UC_BT_CTRL_HCI_UART_CTS_PIN (-1)
|
||||
#define UC_BT_CTRL_HCI_UART_RTS_PIN (-1)
|
||||
#endif
|
||||
#else
|
||||
#define UC_BT_CTRL_HCI_UART_FLOW_CTRL (0)
|
||||
#define UC_BT_CTRL_HCI_UART_CTS_PIN (-1)
|
||||
#define UC_BT_CTRL_HCI_UART_RTS_PIN (-1)
|
||||
#endif
|
||||
|
||||
#if (CONFIG_BT_CTRL_HCI_INTERFACE_USE_RAM)
|
||||
#define UC_BT_CTRL_HCI_INTERFACE_USE_RAM (1)
|
||||
#else
|
||||
#define UC_BT_CTRL_HCI_INTERFACE_USE_RAM (0)
|
||||
#endif
|
||||
|
||||
#if (CONFIG_BT_CTRL_HCI_INTERFACE_USE_UART)
|
||||
#define UC_BT_CTRL_HCI_INTERFACE_USE_UART (1)
|
||||
#else
|
||||
#define UC_BT_CTRL_HCI_INTERFACE_USE_UART (0)
|
||||
#endif
|
||||
|
||||
#if (UC_BT_CTRL_HCI_INTERFACE_USE_UART)
|
||||
#if (CONFIG_BT_CTRL_UART_HCI_DMA_MODE)
|
||||
#define UC_BT_CTRL_UART_HCI_DMA_MODE (1)
|
||||
#define UC_BT_CTRL_UART_HCI_NO_DMA_MODE (0)
|
||||
#else
|
||||
#define UC_BT_CTRL_UART_HCI_DMA_MODE (0)
|
||||
#define UC_BT_CTRL_UART_HCI_NO_DMA_MODE (1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (!UC_BT_CTRL_HCI_INTERFACE_USE_RAM)
|
||||
#define UC_BT_CTRL_HCI_TRANS_TASK_STACK_SIZE (CONFIG_BT_CTRL_HCI_TRANS_TASK_STACK_SIZE)
|
||||
#endif
|
||||
|
||||
#if (UC_BT_CTRL_UART_HCI_NO_DMA_MODE)
|
||||
#define UC_BT_CTRL_HCI_UART_RX_BUFFER_SIZE (CONFIG_BT_CTRL_HCI_UART_RX_BUFFER_SIZE)
|
||||
#define UC_BT_CTRL_HCI_UART_TX_BUFFER_SIZE (CONFIG_BT_CTRL_HCI_UART_TX_BUFFER_SIZE)
|
||||
#endif
|
||||
|
||||
#if (UC_BT_CTRL_UART_HCI_DMA_MODE)
|
||||
#define UC_BT_CTRL_HCI_TRANS_RX_MEM_NUM (CONFIG_BT_CTRL_HCI_TRANS_RX_MEM_NUM)
|
||||
#define UC_BT_CTRL_HCI_LLDESCS_POOL_NUM (CONFIG_BT_CTRL_HCI_LLDESCS_POOL_NUM)
|
||||
#endif
|
||||
|
||||
#define UC_BT_CTRL_BR_EDR_IS_ENABLE (CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM)
|
||||
#define UC_BT_CTRL_BLE_IS_ENABLE (CONFIG_BTDM_CTRL_MODE_BLE_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM)
|
||||
|
||||
//TODO
|
||||
#define UC_BT_CTRL_CONN_FC_ENABLE (1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BTDM_CFG_H__ */
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* 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 _QUEUE_H_
|
||||
#define _QUEUE_H_
|
||||
|
||||
/* The common BSD linked list queue macros are already defined here for ESP-IDF */
|
||||
#include <sys/queue.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file defines circular queues. The other types of data structures:
|
||||
* singly-linked lists, singly-linked tail queues, lists and tail queues
|
||||
* are used from sys/queue.h
|
||||
*
|
||||
* A singly-linked list is headed by a single forward pointer. The elements
|
||||
* are singly linked for minimum space and pointer manipulation overhead at
|
||||
* the expense of O(n) removal for arbitrary elements. New elements can be
|
||||
* added to the list after an existing element or at the head of the list.
|
||||
* Elements being removed from the head of the list should use the explicit
|
||||
* macro for this purpose for optimum efficiency. A singly-linked list may
|
||||
* only be traversed in the forward direction. Singly-linked lists are ideal
|
||||
* for applications with large datasets and few or no removals or for
|
||||
* implementing a LIFO queue.
|
||||
*
|
||||
* A singly-linked tail queue is headed by a pair of pointers, one to the
|
||||
* head of the list and the other to the tail of the list. The elements are
|
||||
* singly linked for minimum space and pointer manipulation overhead at the
|
||||
* expense of O(n) removal for arbitrary elements. New elements can be added
|
||||
* to the list after an existing element, at the head of the list, or at the
|
||||
* end of the list. Elements being removed from the head of the tail queue
|
||||
* should use the explicit macro for this purpose for optimum efficiency.
|
||||
* A singly-linked tail queue may only be traversed in the forward direction.
|
||||
* Singly-linked tail queues are ideal for applications with large datasets
|
||||
* and few or no removals or for implementing a FIFO queue.
|
||||
*
|
||||
* A list is headed by a single forward pointer (or an array of forward
|
||||
* pointers for a hash table header). The elements are doubly linked
|
||||
* so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before
|
||||
* or after an existing element or at the head of the list. A list
|
||||
* may only be traversed in the forward direction.
|
||||
*
|
||||
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or
|
||||
* after an existing element, at the head of the list, or at the end of
|
||||
* the list. A tail queue may be traversed in either direction.
|
||||
*
|
||||
* A circle queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or after
|
||||
* an existing element, at the head of the list, or at the end of the list.
|
||||
* A circle queue may be traversed in either direction, but has a more
|
||||
* complex end of list detection.
|
||||
*
|
||||
* For details on the use of these macros, see the queue(3) manual page.
|
||||
*
|
||||
*
|
||||
* SLIST LIST STAILQ TAILQ CIRCLEQ
|
||||
* _HEAD + + + + +
|
||||
* _HEAD_INITIALIZER + + + + +
|
||||
* _ENTRY + + + + +
|
||||
* _INIT + + + + +
|
||||
* _EMPTY + + + + +
|
||||
* _FIRST + + + + +
|
||||
* _NEXT + + + + +
|
||||
* _PREV - - - + +
|
||||
* _LAST - - + + +
|
||||
* _FOREACH + + + + +
|
||||
* _FOREACH_REVERSE - - - + +
|
||||
* _INSERT_HEAD + + + + +
|
||||
* _INSERT_BEFORE - + - + +
|
||||
* _INSERT_AFTER + + + + +
|
||||
* _INSERT_TAIL - - + + +
|
||||
* _REMOVE_HEAD + - + - -
|
||||
* _REMOVE + + + + +
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Circular queue declarations.
|
||||
*/
|
||||
#define CIRCLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *cqh_first; /* first element */ \
|
||||
struct type *cqh_last; /* last element */ \
|
||||
}
|
||||
|
||||
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
||||
{ (void *)&(head), (void *)&(head) }
|
||||
|
||||
#define CIRCLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *cqe_next; /* next element */ \
|
||||
struct type *cqe_prev; /* previous element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Circular queue functions.
|
||||
*/
|
||||
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
|
||||
|
||||
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
||||
|
||||
#define CIRCLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = CIRCLEQ_FIRST((head)); \
|
||||
(var) != (void *)(head) || ((var) = NULL); \
|
||||
(var) = CIRCLEQ_NEXT((var), field))
|
||||
|
||||
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
||||
for ((var) = CIRCLEQ_LAST((head)); \
|
||||
(var) != (void *)(head) || ((var) = NULL); \
|
||||
(var) = CIRCLEQ_PREV((var), field))
|
||||
|
||||
#define CIRCLEQ_INIT(head) do { \
|
||||
CIRCLEQ_FIRST((head)) = (void *)(head); \
|
||||
CIRCLEQ_LAST((head)) = (void *)(head); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \
|
||||
CIRCLEQ_PREV((elm), field) = (listelm); \
|
||||
if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \
|
||||
CIRCLEQ_LAST((head)) = (elm); \
|
||||
else \
|
||||
CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\
|
||||
CIRCLEQ_NEXT((listelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
||||
CIRCLEQ_NEXT((elm), field) = (listelm); \
|
||||
CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \
|
||||
if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \
|
||||
CIRCLEQ_FIRST((head)) = (elm); \
|
||||
else \
|
||||
CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\
|
||||
CIRCLEQ_PREV((listelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||
CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \
|
||||
CIRCLEQ_PREV((elm), field) = (void *)(head); \
|
||||
if (CIRCLEQ_LAST((head)) == (void *)(head)) \
|
||||
CIRCLEQ_LAST((head)) = (elm); \
|
||||
else \
|
||||
CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \
|
||||
CIRCLEQ_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
CIRCLEQ_NEXT((elm), field) = (void *)(head); \
|
||||
CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \
|
||||
if (CIRCLEQ_FIRST((head)) == (void *)(head)) \
|
||||
CIRCLEQ_FIRST((head)) = (elm); \
|
||||
else \
|
||||
CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \
|
||||
CIRCLEQ_LAST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
||||
|
||||
#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
|
||||
|
||||
#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
|
||||
|
||||
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
||||
if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \
|
||||
CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \
|
||||
else \
|
||||
CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \
|
||||
CIRCLEQ_PREV((elm), field); \
|
||||
if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \
|
||||
CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \
|
||||
else \
|
||||
CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \
|
||||
CIRCLEQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_SYS_QUEUE_H_ */
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "btdm_coex.h"
|
||||
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
#include "private/esp_coexist_internal.h"
|
||||
#endif
|
||||
|
||||
extern esp_err_t coex_iso_start(void *coex_iso_info);
|
||||
extern esp_err_t coex_iso_stop(uint16_t handle);
|
||||
extern uint16_t coex_protect_frame_thres_get(void);
|
||||
extern void coex_start_int_handle(uint16_t handle, uint32_t duration);
|
||||
extern void coex_end_int_handle(uint16_t handle, uint32_t duration);
|
||||
extern void coex_ble_idle_time_inform(uint32_t start_offset, uint32_t duration);
|
||||
extern uint8_t coex_t_ifs_pti_selection_get(void);
|
||||
extern void coex_ble_channel_map_set(uint8_t *channel_map);
|
||||
extern esp_err_t coex_register_ble_cb(uint8_t type, void *func);
|
||||
extern void bt_rf_coex_log_func_register(void *cb);
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* BTDM COEX Adapter Types
|
||||
***************************************************************************************************
|
||||
*/
|
||||
typedef void (*coex_schm_cb_t)(uint32_t __event);
|
||||
typedef void (*coex_wifi_channel_change_btdm_cb_t)(uint8_t primary, uint8_t secondary);
|
||||
typedef void (*coex_funcs_ble_cb_t)(void);
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* BTDM COEX Adapter Functions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
void
|
||||
wr_btdm_coex_schm_status_bit_set(uint32_t type, uint32_t status)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
coex_schm_status_bit_set(type, status);
|
||||
#endif // CONFIG_SW_COEXIST_ENABLE
|
||||
}
|
||||
|
||||
void
|
||||
wr_btdm_coex_schm_status_bit_clear(uint32_t type, uint32_t status)
|
||||
{
|
||||
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
coex_schm_status_bit_clear(type, status);
|
||||
#endif // CONFIG_SW_COEXIST_ENABLE
|
||||
}
|
||||
|
||||
int
|
||||
wr_btdm_coex_schm_register_btdm_callback(coex_schm_cb_t callback)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_schm_register_callback(COEX_SCHM_CALLBACK_TYPE_BT, callback);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t
|
||||
wr_btdm_coex_schm_interval_get(void)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_schm_interval_get();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t
|
||||
wr_btdm_coex_schm_curr_period_get(void)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_schm_curr_period_get();
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *
|
||||
wr_btdm_coex_schm_curr_phase_get(void)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_schm_curr_phase_get();
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
wr_btdm_coex_register_wifi_channel_change_callback(coex_wifi_channel_change_btdm_cb_t callback)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_register_wifi_channel_change_callback(callback);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
wr_btdm_coex_wifi_channel_get(uint8_t *primary, uint8_t *secondary)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_wifi_channel_get(primary, secondary);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
wr_btdm_coex_version_get(unsigned *major, unsigned *minor, unsigned *path)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
// TODO: enable it after update submodule coexist
|
||||
#if 0
|
||||
coex_version_t version;
|
||||
ESP_ERROR_CHECK(coex_version_get_value(&version));
|
||||
*major = (unsigned int)version.major;
|
||||
*minor = (unsigned int)version.minor;
|
||||
*patch = (unsigned int)version.patch;
|
||||
#endif
|
||||
return 0;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
wr_btdm_coex_iso_start(void *coex_iso_info)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE && CONFIG_BT_LE_ISO_SUPPORT
|
||||
return coex_iso_start(coex_iso_info);
|
||||
#else
|
||||
return ESP_OK;
|
||||
#endif /* CONFIG_SW_COEXIST_ENABLE */
|
||||
}
|
||||
|
||||
int
|
||||
wr_btdm_coex_iso_stop(uint16_t handle)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE && CONFIG_BT_LE_ISO_SUPPORT
|
||||
return coex_iso_stop(handle);
|
||||
#else
|
||||
return ESP_OK;
|
||||
#endif /* CONFIG_SW_COEXIST_ENABLE */
|
||||
}
|
||||
|
||||
uint16_t
|
||||
wr_btdm_coex_iso_protect_frame_thres_get(void)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE && CONFIG_BT_LE_ISO_SUPPORT
|
||||
return coex_protect_frame_thres_get();
|
||||
#else
|
||||
return 0;
|
||||
#endif /* CONFIG_SW_COEXIST_ENABLE */
|
||||
}
|
||||
|
||||
void
|
||||
wr_btdm_coex_iso_start_int_handle(uint16_t handle, uint32_t duration)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE && CONFIG_BT_LE_ISO_SUPPORT
|
||||
coex_start_int_handle(handle, duration);
|
||||
#endif /* CONFIG_SW_COEXIST_ENABLE */
|
||||
}
|
||||
|
||||
void
|
||||
wr_btdm_coex_iso_end_int_handle(uint16_t handle, uint32_t duration)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE && CONFIG_BT_LE_ISO_SUPPORT
|
||||
coex_end_int_handle(handle, duration);
|
||||
#endif /* CONFIG_SW_COEXIST_ENABLE */
|
||||
}
|
||||
|
||||
void
|
||||
wr_btdm_coex_ble_idle_time_inform(uint32_t start_offset, uint32_t duration)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
coex_ble_idle_time_inform(start_offset, duration);
|
||||
#endif /* CONFIG_SW_COEXIST_ENABLE */
|
||||
}
|
||||
|
||||
int
|
||||
wr_btdm_coex_register_ble_cb(uint32_t type, coex_funcs_ble_cb_t func)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_register_ble_cb(type, func);
|
||||
#else
|
||||
return ESP_OK;
|
||||
#endif /* CONFIG_SW_COEXIST_ENABLE */
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* BTDM COEX Initialization
|
||||
***************************************************************************************************
|
||||
*/
|
||||
esp_err_t
|
||||
btdm_coex_init(void)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_init();
|
||||
#else
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
btdm_coex_deinit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
btdm_coex_enable(void)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
return coex_enable();
|
||||
#else
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
btdm_coex_disable(void)
|
||||
{
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
coex_disable();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "btdm_external.h"
|
||||
|
||||
extern const int8_t *bt_bb_get_tx_pwr_table(uint8_t *length);
|
||||
|
||||
const int8_t *
|
||||
wr_btdm_external_bb_get_tx_pwr_table(uint8_t *length)
|
||||
{
|
||||
assert(length != NULL);
|
||||
return bt_bb_get_tx_pwr_table(length);
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* BTDM External Function Initialization
|
||||
***************************************************************************************************
|
||||
*/
|
||||
int
|
||||
btdm_external_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
btdm_external_deinit(void)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "assert.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* External Functions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
void r_btdm_sched_list_details_dump(void);
|
||||
void r_ble_phy_hw_state_dump(uint8_t);
|
||||
void esp_ble_controller_log_dump_all(bool);
|
||||
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Public Function Definitions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
void IRAM_ATTR
|
||||
wr_btdm_log_set_flags(uint8_t p0)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
extern void r_ble_log_set_buf_index_flag(uint32_t p0);
|
||||
r_ble_log_set_buf_index_flag(p0);
|
||||
#endif // BT_LE_CONTROLLER_LOG_ENABLED
|
||||
}
|
||||
|
||||
void IRAM_ATTR
|
||||
wr_btdm_log_reset_flags(uint8_t p0)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
extern void r_ble_log_reset_buf_index_flag(uint32_t p0);
|
||||
r_ble_log_reset_buf_index_flag(p0);
|
||||
#endif // BT_LE_CONTROLLER_LOG_ENABLED
|
||||
}
|
||||
|
||||
void IRAM_ATTR
|
||||
wr_btdm_log_internal_x0(uint32_t p0)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
extern void r_ble_log_internal_x0(uint32_t p0);
|
||||
r_ble_log_internal_x0(p0);
|
||||
#endif // BT_LE_CONTROLLER_LOG_ENABLED
|
||||
}
|
||||
|
||||
void IRAM_ATTR
|
||||
wr_btdm_log_internal_x1(uint32_t p0, uint32_t p1)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
extern void r_ble_log_internal_x1(uint32_t p0, uint32_t p1);
|
||||
r_ble_log_internal_x1(p0, p1);
|
||||
#endif // BT_LE_CONTROLLER_LOG_ENABLED
|
||||
}
|
||||
|
||||
void IRAM_ATTR
|
||||
wr_btdm_log_internal_x2(uint32_t p0, uint32_t p1, uint32_t p2)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
extern void r_ble_log_internal_x2(uint32_t p0, uint32_t p1, uint32_t p2);
|
||||
r_ble_log_internal_x2(p0, p1, p2);
|
||||
#endif // BT_LE_CONTROLLER_LOG_ENABLED
|
||||
}
|
||||
|
||||
void IRAM_ATTR
|
||||
wr_btdm_log_internal_x3(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
extern void r_ble_log_internal_x3(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3);
|
||||
r_ble_log_internal_x3(p0, p1, p2, p3);
|
||||
#endif // BT_LE_CONTROLLER_LOG_ENABLED
|
||||
}
|
||||
|
||||
void IRAM_ATTR
|
||||
wr_btdm_log_internal_hex(uint32_t p0, uint32_t p1, uint32_t p2)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
extern void r_ble_log_internal_hex(uint32_t p0, uint32_t p1, uint32_t p2);
|
||||
r_ble_log_internal_hex(p0, p1, p2);
|
||||
#endif // BT_LE_CONTROLLER_LOG_ENABLED
|
||||
}
|
||||
|
||||
void IRAM_ATTR
|
||||
wr_btdm_log_raw_export(uint16_t p0, uint32_t p1, uint32_t p2)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
extern void r_ble_log_raw_export(uint16_t p0, uint32_t p1, uint32_t p2);
|
||||
r_ble_log_raw_export(p0, p1, p2);
|
||||
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
}
|
||||
|
||||
void IRAM_ATTR
|
||||
wr_btdm_assert(const char *file, int line, int p0, int p1, uint8_t type)
|
||||
{
|
||||
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
r_ble_phy_hw_state_dump(false);
|
||||
r_btdm_sched_list_details_dump();
|
||||
esp_ble_controller_log_dump_all(true);
|
||||
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
|
||||
|
||||
esp_rom_printf("assert %s,%d, param:0x%x,0x%x\n", file, line, p0, p1);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* BTDM LOG Initialization
|
||||
***************************************************************************************************
|
||||
*/
|
||||
int
|
||||
btdm_log_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
btdm_log_deinit(void)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp_bt.h"
|
||||
|
||||
/* From Modem and Phy */
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
#include "esp_pm.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#include "esp_private/pm_impl.h"
|
||||
#include "esp_private/sleep_modem.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Local Defined Macros
|
||||
***************************************************************************************************
|
||||
*/
|
||||
#define BTDM_LOG_TAG "BTDM_SLEEP"
|
||||
|
||||
#define BTDM_RTC_DELAY_US_LIGHT_SLEEP (2000)
|
||||
#define BTDM_RTC_DELAY_US_MODEM_SLEEP (1500)
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* External Functions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
extern bool r_btdm_sleep_should_skip_light_sleep_check(void);
|
||||
extern const sleep_retention_entries_config_t *r_btdm_mac_retention_link_get(uint8_t *size);
|
||||
extern void r_btdm_sleep_wake_up_overhead_set(uint32_t overhead);
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
extern esp_err_t sleep_modem_bredr_mac_modem_state_init(void);
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
extern esp_err_t sleep_modem_ble_mac_modem_state_init(void);
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLEs
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
|
||||
extern void r_btdm_sleep_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, void *w_arg,
|
||||
uint32_t us_to_enabled);
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Local Variables
|
||||
***************************************************************************************************
|
||||
*/
|
||||
static bool s_bt_active = false;
|
||||
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
// static modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
|
||||
static uint32_t s_bt_lpclk_freq = 100000;
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Static Function Definitions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
static void
|
||||
btdm_lp_rtc_slow_clk_select(uint8_t slow_clk_src)
|
||||
{
|
||||
/* Select slow clock source for BT momdule */
|
||||
switch (slow_clk_src) {
|
||||
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
|
||||
ESP_LOGI(BTDM_LOG_TAG, "Using main XTAL as clock source");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (CONFIG_XTAL_FREQ * 1000000 / s_bt_lpclk_freq - 1));
|
||||
break;
|
||||
case MODEM_CLOCK_LPCLK_SRC_RC_SLOW:
|
||||
ESP_LOGW(BTDM_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1));
|
||||
break;
|
||||
case MODEM_CLOCK_LPCLK_SRC_XTAL32K:
|
||||
ESP_LOGI(BTDM_LOG_TAG, "Using external 32.768 kHz XTAL as clock source");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1));
|
||||
break;
|
||||
case MODEM_CLOCK_LPCLK_SRC_RC32K:
|
||||
ESP_LOGI(BTDM_LOG_TAG, "Using 32 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1));
|
||||
break;
|
||||
case MODEM_CLOCK_LPCLK_SRC_EXT32K:
|
||||
ESP_LOGI(BTDM_LOG_TAG, "Using 32 kHz oscillator as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
btdm_lp_timer_clk_init(esp_btdm_controller_config_t *cfg)
|
||||
{
|
||||
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) {
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
uint32_t clk_freq = 0;
|
||||
|
||||
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
if (!esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_XTAL32K, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &clk_freq)) {
|
||||
if (clk_freq > 32700 && clk_freq < 33800) {
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K;
|
||||
} else {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL detection error, switch to main XTAL as Bluetooth sleep clock");
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL detection error, switch to main XTAL as Bluetooth sleep clock");
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
|
||||
}
|
||||
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K;
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
|
||||
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K;
|
||||
#else
|
||||
ESP_LOGE(BTDM_LOG_TAG, "Unsupported clock source");
|
||||
assert(0);
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
}
|
||||
|
||||
// if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
|
||||
// cfg->rtc_freq = s_bt_lpclk_freq;
|
||||
// } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) {
|
||||
// cfg->rtc_freq = 32768;
|
||||
// } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
|
||||
// cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
|
||||
// //TODO
|
||||
// // cfg->ble_ll_sca = 3000;
|
||||
// } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) {
|
||||
// cfg->rtc_freq = 32000;
|
||||
// } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
|
||||
// cfg->rtc_freq = 32000;
|
||||
// }
|
||||
btdm_lp_rtc_slow_clk_select(s_bt_lpclk_src);
|
||||
}
|
||||
|
||||
static void
|
||||
btdm_lp_timer_clk_deinit(void)
|
||||
{
|
||||
modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE);
|
||||
}
|
||||
|
||||
void
|
||||
btdm_lp_sleep_cb(uint32_t enable_tick, void *arg)
|
||||
{
|
||||
if (!s_bt_active) {
|
||||
return;
|
||||
}
|
||||
esp_phy_disable(PHY_MODEM_BT);
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
s_bt_active = false;
|
||||
}
|
||||
|
||||
void
|
||||
btdm_lp_wake_up_cb(void *arg)
|
||||
{
|
||||
if (s_bt_active) {
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_acquire(s_pm_lock);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
esp_phy_enable(PHY_MODEM_BT);
|
||||
s_bt_active = true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
static esp_err_t
|
||||
btdm_lp_modem_retention_create(void)
|
||||
{
|
||||
uint8_t size = 0;
|
||||
const sleep_retention_entries_config_t *btdm_mac_modem_config =
|
||||
r_btdm_mac_retention_link_get(&size);
|
||||
esp_err_t err = sleep_retention_entries_create(btdm_mac_modem_config, size, REGDMA_LINK_PRI_5,
|
||||
SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(BTDM_LOG_TAG, "Modem BTDM MAC retention initialization");
|
||||
}
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
sleep_modem_bredr_mac_modem_state_init();
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
sleep_modem_ble_mac_modem_state_init();
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t
|
||||
btdm_lp_modem_state_init(void)
|
||||
{
|
||||
sleep_retention_module_init_param_t init_param = {
|
||||
.cbs = {.create = {.handle = (void *)btdm_lp_modem_retention_create, .arg = NULL}},
|
||||
.depends = RETENTION_MODULE_BITMAP_INIT(BT_BB)};
|
||||
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param);
|
||||
if (err == ESP_OK) {
|
||||
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
btdm_lp_modem_state_deinit(void)
|
||||
{
|
||||
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
if (err == ESP_OK) {
|
||||
err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
assert(err == ESP_OK);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Public Function Definitions
|
||||
***************************************************************************************************
|
||||
*/
|
||||
#include "modem/modem_syscon_reg.h"
|
||||
void
|
||||
btdm_lp_enable_clock(esp_btdm_controller_config_t *cfg)
|
||||
{
|
||||
modem_clock_module_enable(PERIPH_BT_MODULE);
|
||||
modem_clock_module_mac_reset(PERIPH_BT_MODULE);
|
||||
// TODO: set the clock ion modem_clock_module_enable
|
||||
REG_WRITE(MODEM_SYSCON_CLK_CONF_POWER_ST_REG, 0XFFFFFFFF);
|
||||
// btdm_lp_timer_clk_init(cfg);
|
||||
}
|
||||
|
||||
void
|
||||
btdm_lp_disable_clock(void)
|
||||
{
|
||||
btdm_lp_timer_clk_deinit();
|
||||
modem_clock_module_disable(PERIPH_BT_MODULE);
|
||||
}
|
||||
|
||||
int
|
||||
btdm_lp_init(void)
|
||||
{
|
||||
#if UC_BT_CTRL_SLEEP_ENABLE
|
||||
ESP_LOGI(BTDM_LOG_TAG, "Bluetooth modem sleep is enabled");
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
r_btdm_sleep_set_sleep_cb(btdm_lp_sleep_cb, btdm_lp_wake_up_cb, 0, 0,
|
||||
BTDM_RTC_DELAY_US_LIGHT_SLEEP);
|
||||
#else
|
||||
r_btdm_sleep_set_sleep_cb(btdm_lp_sleep_cb, btdm_lp_wake_up_cb, 0, 0,
|
||||
BTDM_RTC_DELAY_US_MODEM_SLEEP);
|
||||
#endif /* FREERTOS_USE_TICKLESS_IDLE */
|
||||
#endif // UC_BT_CTRL_SLEEP_ENABLE
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_err_t rc = 0;
|
||||
|
||||
rc = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "bt", &s_pm_lock);
|
||||
if (rc != ESP_OK) {
|
||||
return -1;
|
||||
}
|
||||
#if UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
/* Create a new regdma link for BLE related register restoration */
|
||||
rc = btdm_lp_modem_state_init();
|
||||
assert(rc == 0);
|
||||
esp_sleep_enable_bt_wakeup();
|
||||
ESP_LOGW(BTDM_LOG_TAG, "Enable light sleep, the wake up source is BLE timer");
|
||||
|
||||
rc = esp_pm_register_inform_out_light_sleep_overhead_callback(r_btdm_sleep_wake_up_overhead_set);
|
||||
if (rc != ESP_OK) {
|
||||
return -2;
|
||||
}
|
||||
// rc = esp_pm_register_skip_light_sleep_callback(r_btdm_sleep_should_skip_light_sleep_check);
|
||||
if (rc != ESP_OK) {
|
||||
return -3;
|
||||
}
|
||||
#endif /* UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
#endif /* CONFIG_PM_ENABLE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
btdm_lp_deinit(void)
|
||||
{
|
||||
#if UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
// esp_pm_unregister_skip_light_sleep_callback(r_btdm_sleep_should_skip_light_sleep_check);
|
||||
esp_pm_unregister_inform_out_light_sleep_overhead_callback(r_btdm_sleep_wake_up_overhead_set);
|
||||
esp_sleep_disable_bt_wakeup();
|
||||
btdm_lp_modem_state_deinit();
|
||||
#endif /* UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
/* lock should be released first */
|
||||
if (s_pm_lock) {
|
||||
esp_pm_lock_delete(s_pm_lock);
|
||||
s_pm_lock = NULL;
|
||||
}
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
}
|
||||
|
||||
void
|
||||
btdm_lp_reset(bool enable_stage)
|
||||
{
|
||||
// TODO: For enable_stage, need to disable the phy by default.
|
||||
if (enable_stage) {
|
||||
assert(!s_bt_active);
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
esp_pm_lock_acquire(s_pm_lock);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
esp_phy_enable(PHY_MODEM_BT);
|
||||
esp_btbb_enable();
|
||||
s_bt_active = true;
|
||||
} else {
|
||||
if (s_bt_active) {
|
||||
esp_btbb_disable();
|
||||
esp_phy_disable(PHY_MODEM_BT);
|
||||
#if CONFIG_PM_ENABLE
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
s_bt_active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
btdm_lp_shutdown(void)
|
||||
{
|
||||
modem_clock_module_mac_reset(PERIPH_BT_MODULE);
|
||||
if (s_bt_active) {
|
||||
// esp_phy_disable(PHY_MODEM_BT);
|
||||
s_bt_active = false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "esp_hci_internal.h"
|
||||
#include "common/hci_driver_h4.h"
|
||||
#include "common/hci_driver_util.h"
|
||||
|
||||
#ifndef min
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define HCI_H4_SM_W4_PKT_TYPE 0
|
||||
#define HCI_H4_SM_W4_HEADER 1
|
||||
#define HCI_H4_SM_W4_PAYLOAD 2
|
||||
#define HCI_H4_SM_COMPLETED 3
|
||||
|
||||
struct hci_h4_input_buffer {
|
||||
const uint8_t *buf;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
static int
|
||||
hci_h4_frame_start(struct hci_h4_sm *rxs, uint8_t pkt_type)
|
||||
{
|
||||
rxs->pkt_type = pkt_type;
|
||||
rxs->len = 0;
|
||||
rxs->exp_len = 0;
|
||||
|
||||
switch (rxs->pkt_type) {
|
||||
case HCI_H4_CMD:
|
||||
case HCI_H4_SYNC:
|
||||
rxs->min_len = 3;
|
||||
break;
|
||||
case HCI_H4_ACL:
|
||||
case HCI_H4_ISO:
|
||||
rxs->min_len = 4;
|
||||
break;
|
||||
#if (!CONFIG_BT_CONTROLLER_ENABLED)
|
||||
case HCI_H4_EVT:
|
||||
rxs->min_len = 2;
|
||||
break;
|
||||
#endif // (!CONFIG_BT_CONTROLLER_ENABLED)
|
||||
default:
|
||||
/* !TODO: Sync loss. Need to wait for reset. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_h4_ib_consume(struct hci_h4_input_buffer *ib, uint16_t len)
|
||||
{
|
||||
HCI_TRANS_ASSERT((ib->len >= len), ib->len, len);
|
||||
|
||||
ib->buf += len;
|
||||
ib->len -= len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_h4_ib_pull_min_len(struct hci_h4_sm *rxs,
|
||||
struct hci_h4_input_buffer *ib)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
len = min(ib->len, rxs->min_len - rxs->len);
|
||||
memcpy(&rxs->hdr[rxs->len], ib->buf, len);
|
||||
|
||||
rxs->len += len;
|
||||
hci_h4_ib_consume(ib, len);
|
||||
|
||||
|
||||
return rxs->len != rxs->min_len;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib)
|
||||
{
|
||||
int rc;
|
||||
uint16_t conn_handle = 0;
|
||||
|
||||
rc = hci_h4_ib_pull_min_len(h4sm, ib);
|
||||
if (rc) {
|
||||
/* need more data */
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (h4sm->pkt_type) {
|
||||
case HCI_H4_CMD:
|
||||
HCI_TRANS_ASSERT(h4sm->allocs && h4sm->allocs->cmd, 0, 0);
|
||||
h4sm->pkt = h4sm->allocs->cmd();
|
||||
if (!h4sm->pkt) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(h4sm->pkt->data, h4sm->hdr, h4sm->len);
|
||||
h4sm->exp_len = h4sm->hdr[2] + 3;
|
||||
break;
|
||||
case HCI_H4_ACL:
|
||||
conn_handle = btdm_get_le16(&h4sm->hdr[0]) & HCI_INTERNAL_CONN_MASK;
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
if (HCI_INTERNAL_CONN_IS_BLE(conn_handle)) {
|
||||
assert(h4sm->allocs && h4sm->allocs->acl);
|
||||
h4sm->om = h4sm->allocs->acl();
|
||||
if (!h4sm->om) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ble_mbuf_append(h4sm->om, h4sm->hdr, h4sm->len);
|
||||
h4sm->exp_len = btdm_get_le16(&h4sm->hdr[2]) + 4;
|
||||
break;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
if (HCI_INTERNAL_CONN_IS_BREDR(conn_handle)) {
|
||||
assert(h4sm->allocs && h4sm->allocs->bredr_acl);
|
||||
h4sm->exp_len = btdm_get_le16(&h4sm->hdr[2]) + 4;
|
||||
h4sm->pkt = h4sm->allocs->bredr_acl(conn_handle);
|
||||
if (!h4sm->pkt) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(h4sm->pkt->data, h4sm->hdr, h4sm->len);
|
||||
break;
|
||||
}
|
||||
case HCI_H4_SYNC:
|
||||
conn_handle = btdm_get_le16(&h4sm->hdr[0]) & HCI_INTERNAL_CONN_MASK;
|
||||
assert(h4sm->allocs && h4sm->allocs->sync);
|
||||
h4sm->exp_len = h4sm->hdr[2] + 3;
|
||||
h4sm->pkt = h4sm->allocs->sync(conn_handle);
|
||||
if (!h4sm->pkt) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(h4sm->pkt->data, h4sm->hdr, h4sm->len);
|
||||
break;
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
#if !CONFIG_BT_CONTROLLER_ENABLED
|
||||
case HCI_H4_EVT:
|
||||
if (h4sm->hdr[0] == BLE_HCI_EVCODE_LE_META) {
|
||||
/* For LE Meta event we need 3 bytes to parse header */
|
||||
h4sm->min_len = 3;
|
||||
rc = hci_h4_ib_pull_min_len(h4sm, ib);
|
||||
if (rc) {
|
||||
/* need more data */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
HCI_TRANS_ASSERT(h4sm->allocs && h4sm->allocs->evt, 0, 0);
|
||||
|
||||
/* We can drop legacy advertising events if there's no free buffer in
|
||||
* discardable pool.
|
||||
*/
|
||||
if (h4sm->hdr[2] == BLE_HCI_LE_SUBEV_ADV_RPT) {
|
||||
h4sm->buf = h4sm->allocs->evt(1);
|
||||
} else {
|
||||
h4sm->buf = h4sm->allocs->evt(0);
|
||||
if (!h4sm->buf) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (h4sm->buf) {
|
||||
memcpy(h4sm->buf, h4sm->hdr, h4sm->len);
|
||||
}
|
||||
|
||||
h4sm->exp_len = h4sm->hdr[1] + 2;
|
||||
break;
|
||||
#endif // !CONFIG_BT_CONTROLLER_ENABLED
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
case HCI_H4_ISO:
|
||||
assert(h4sm->allocs && h4sm->allocs->iso);
|
||||
h4sm->exp_len = (btdm_get_le16(&h4sm->hdr[2]) & 0x7fff) + 4;
|
||||
h4sm->buf = h4sm->allocs->iso(h4sm->exp_len);
|
||||
if (!h4sm->buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(h4sm->buf, h4sm->hdr, h4sm->len);
|
||||
break;
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_h4_sm_w4_payload(struct hci_h4_sm *h4sm,
|
||||
struct hci_h4_input_buffer *ib)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
len = min(ib->len, h4sm->exp_len - h4sm->len);
|
||||
|
||||
|
||||
switch (h4sm->pkt_type) {
|
||||
case HCI_H4_CMD:
|
||||
case HCI_H4_SYNC:
|
||||
if (h4sm->pkt) {
|
||||
memcpy(&h4sm->pkt->data[h4sm->len], ib->buf, len);
|
||||
}
|
||||
break;
|
||||
case HCI_H4_EVT:
|
||||
case HCI_H4_ISO:
|
||||
if (h4sm->buf) {
|
||||
memcpy(&h4sm->buf[h4sm->len], ib->buf, len);
|
||||
}
|
||||
break;
|
||||
case HCI_H4_ACL:
|
||||
HCI_TRANS_ASSERT(h4sm->om, h4sm->pkt_type, len);
|
||||
uint16_t conn_handle = btdm_get_le16(&h4sm->hdr[0]) & HCI_INTERNAL_CONN_MASK;
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
if (HCI_INTERNAL_CONN_IS_BREDR(conn_handle)) {
|
||||
memcpy(&h4sm->pkt->data[h4sm->len], ib->buf, len);
|
||||
break;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
if (HCI_INTERNAL_CONN_IS_BLE(conn_handle)) {
|
||||
uint16_t mbuf_len = BLE_MBUF_PKTLEN(h4sm->om);
|
||||
int rc = ble_mbuf_append(h4sm->om, ib->buf, len);
|
||||
if (rc) {
|
||||
/* Some data may already be appended so need to adjust h4sm only by
|
||||
* the size of appended data.
|
||||
*/
|
||||
len = BLE_MBUF_PKTLEN(h4sm->om) - mbuf_len;
|
||||
h4sm->len += len;
|
||||
hci_h4_ib_consume(ib, len);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
h4sm->len += len;
|
||||
hci_h4_ib_consume(ib, len);
|
||||
|
||||
/* return 1 if need more data */
|
||||
return h4sm->len != h4sm->exp_len;
|
||||
}
|
||||
|
||||
static void
|
||||
hci_h4_sm_completed(struct hci_h4_sm *h4sm)
|
||||
{
|
||||
int rc;
|
||||
uint8_t data_source = 0xFF;
|
||||
|
||||
HCI_TRANS_ASSERT(h4sm->frame_cb, 0, 0);
|
||||
switch (h4sm->pkt_type) {
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED
|
||||
case HCI_H4_ACL:
|
||||
uint16_t conn_handle = btdm_get_le16(&h4sm->hdr[0]) & HCI_INTERNAL_CONN_MASK;
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
if (HCI_INTERNAL_CONN_IS_BLE(conn_handle)) {
|
||||
if (h4sm->om) {
|
||||
rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->om, h4sm->len, HCI_DRIVER_LE_ACL);
|
||||
HCI_TRANS_ASSERT(rc == 0, rc, 0);
|
||||
h4sm->om = NULL;
|
||||
}
|
||||
}
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
if (HCI_INTERNAL_CONN_IS_BREDR(conn_handle)) {
|
||||
if (h4sm->buf) {
|
||||
rc = h4sm->frame_cb(h4sm->pkt_type, (void *)h4sm->buf, h4sm->len, HCI_DRIVER_BREDR_ACL);
|
||||
HCI_TRANS_ASSERT(rc == 0, rc, 0);
|
||||
h4sm->buf = NULL;
|
||||
}
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
break;
|
||||
case HCI_H4_CMD:
|
||||
case HCI_H4_SYNC:
|
||||
case HCI_H4_ISO:
|
||||
if (h4sm->buf) {
|
||||
switch(h4sm->pkt_type) {
|
||||
case HCI_H4_CMD:
|
||||
data_source = HCI_DRIVER_CMD;
|
||||
break;
|
||||
case HCI_H4_SYNC:
|
||||
data_source = HCI_DRIVER_BREDR_SYNC;
|
||||
break;
|
||||
case HCI_H4_ISO:
|
||||
data_source = HCI_DRIVER_LE_ISO;
|
||||
break;
|
||||
}
|
||||
|
||||
rc = h4sm->frame_cb(h4sm->pkt_type, (void *)h4sm->buf, h4sm->len, data_source);
|
||||
HCI_TRANS_ASSERT(rc == 0, rc, 0);
|
||||
h4sm->buf = NULL;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case HCI_H4_CMD:
|
||||
case HCI_H4_EVT:
|
||||
if (h4sm->buf) {
|
||||
assert(h4sm->frame_cb);
|
||||
rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->buf);
|
||||
if (rc != 0) {
|
||||
ble_transport_free(h4sm->buf);
|
||||
}
|
||||
h4sm->buf = NULL;
|
||||
}
|
||||
break;
|
||||
case HCI_H4_ACL:
|
||||
case HCI_H4_ISO:
|
||||
if (h4sm->om) {
|
||||
assert(h4sm->frame_cb);
|
||||
rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->om);
|
||||
if (rc != 0) {
|
||||
os_mbuf_free_chain(h4sm->om);
|
||||
}
|
||||
h4sm->om = NULL;
|
||||
}
|
||||
break;
|
||||
#endif // CONFIG_BT_CONTROLLER_ENABLED
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hci_h4_sm_free_buf(struct hci_h4_sm *h4sm)
|
||||
{
|
||||
switch (h4sm->pkt_type) {
|
||||
case HCI_H4_CMD:
|
||||
if (h4sm->buf) {
|
||||
h4sm->frees->cmd(h4sm->buf);
|
||||
h4sm->buf = NULL;
|
||||
}
|
||||
break;
|
||||
#if (!CONFIG_BT_CONTROLLER_ENABLED)
|
||||
case HCI_H4_EVT:
|
||||
if (h4sm->buf) {
|
||||
h4sm->frees->evt(h4sm->buf);
|
||||
h4sm->buf = NULL;
|
||||
}
|
||||
break;
|
||||
#endif // (!CONFIG_BT_CONTROLLER_ENABLED)
|
||||
case HCI_H4_ACL:
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
uint16_t conn_handle = btdm_get_le16(&h4sm->hdr[0]) & HCI_INTERNAL_CONN_MASK;
|
||||
if (HCI_INTERNAL_CONN_IS_BLE(conn_handle)) {
|
||||
if (h4sm->om) {
|
||||
h4sm->frees->acl(h4sm->om);
|
||||
h4sm->om = NULL;
|
||||
}
|
||||
} else {
|
||||
if (h4sm->pkt) {
|
||||
h4sm->frees->bredr_acl(h4sm->pkt);
|
||||
h4sm->pkt = NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (h4sm->om) {
|
||||
h4sm->frees->acl(h4sm->om);
|
||||
h4sm->om = NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case HCI_H4_ISO:
|
||||
if (h4sm->buf) {
|
||||
h4sm->frees->iso(h4sm->buf);
|
||||
h4sm->buf = NULL;
|
||||
}
|
||||
break;
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
case HCI_H4_SYNC:
|
||||
if (h4sm->pkt) {
|
||||
h4sm->frees->sync(h4sm->pkt);
|
||||
h4sm->pkt = NULL;
|
||||
}
|
||||
break;
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
struct hci_h4_input_buffer ib = {
|
||||
.buf = buf,
|
||||
.len = len,
|
||||
};
|
||||
|
||||
int rc = 0;
|
||||
while (ib.len && (rc >= 0)) {
|
||||
rc = 0;
|
||||
switch (h4sm->state) {
|
||||
case HCI_H4_SM_W4_PKT_TYPE:
|
||||
if (hci_h4_frame_start(h4sm, ib.buf[0]) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
hci_h4_ib_consume(&ib, 1);
|
||||
h4sm->state = HCI_H4_SM_W4_HEADER;
|
||||
/* no break */
|
||||
case HCI_H4_SM_W4_HEADER:
|
||||
rc = hci_h4_sm_w4_header(h4sm, &ib);
|
||||
assert(rc >= 0);
|
||||
if (rc) {
|
||||
break;
|
||||
}
|
||||
h4sm->state = HCI_H4_SM_W4_PAYLOAD;
|
||||
/* no break */
|
||||
case HCI_H4_SM_W4_PAYLOAD:
|
||||
rc = hci_h4_sm_w4_payload(h4sm, &ib);
|
||||
assert(rc >= 0);
|
||||
if (rc) {
|
||||
break;
|
||||
}
|
||||
h4sm->state = HCI_H4_SM_COMPLETED;
|
||||
/* no break */
|
||||
case HCI_H4_SM_COMPLETED:
|
||||
hci_h4_sm_completed(h4sm);
|
||||
h4sm->state = HCI_H4_SM_W4_PKT_TYPE;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate consumed bytes
|
||||
*
|
||||
* Note: we should always consume some bytes unless there is an oom error.
|
||||
* It's also possible that we have an oom error but already consumed some
|
||||
* data, in such case just return success and error will be returned on next
|
||||
* pass.
|
||||
*/
|
||||
len = len - ib.len;
|
||||
if (len == 0) {
|
||||
HCI_TRANS_ASSERT((rc < 0), rc, ib.len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void
|
||||
hci_h4_sm_init(struct hci_h4_sm *h4sm, const struct hci_h4_allocators *allocs, const struct hci_h4_frees *frees,
|
||||
hci_h4_frame_cb *frame_cb)
|
||||
{
|
||||
memset(h4sm, 0, sizeof(*h4sm));
|
||||
h4sm->allocs = allocs;
|
||||
h4sm->frees = frees;
|
||||
h4sm->frame_cb = frame_cb;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_hci_internal.h"
|
||||
#include "common/hci_driver_mem.h"
|
||||
#include "common/hci_driver_h4.h"
|
||||
|
||||
hci_driver_packet_t *
|
||||
hci_driver_mem_cmd_alloc(void)
|
||||
{
|
||||
return btdm_hci_trans_buf_alloc(HCI_H4_CMD, 0);
|
||||
}
|
||||
|
||||
void *
|
||||
hci_driver_mem_evt_alloc(int discardable)
|
||||
{
|
||||
/* The controller shouldn't invoke this. */
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ble_mbuf *
|
||||
hci_driver_mem_acl_alloc(void)
|
||||
{
|
||||
return ble_msys_get_pkthdr(0, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE);
|
||||
}
|
||||
|
||||
struct ble_mbuf *
|
||||
hci_driver_mem_acl_len_alloc(uint32_t len)
|
||||
{
|
||||
return ble_msys_get_pkthdr(len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE);
|
||||
}
|
||||
|
||||
void *
|
||||
hci_driver_mem_iso_alloc(uint32_t len)
|
||||
{
|
||||
return malloc(len);
|
||||
}
|
||||
|
||||
void
|
||||
hci_driver_mem_iso_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
struct ble_mbuf *
|
||||
hci_driver_mem_iso_len_alloc(uint32_t len)
|
||||
{
|
||||
return ble_msys_get_pkthdr(len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE);
|
||||
}
|
||||
|
||||
void
|
||||
hci_driver_mem_cmd_free(void * ptr)
|
||||
{
|
||||
hci_driver_packet_t *pkt = (hci_driver_packet_t *) ptr;
|
||||
btdm_hci_trans_buf_free(pkt);
|
||||
}
|
||||
|
||||
void
|
||||
hci_driver_mem_evt_free(void *ptr)
|
||||
{
|
||||
hci_driver_packet_t *pkt = (hci_driver_packet_t *) ptr;
|
||||
btdm_hci_trans_buf_free(pkt);
|
||||
}
|
||||
|
||||
#if UC_BTDM_CTRL_BR_EDR_IS_ENABLE
|
||||
hci_driver_packet_t *
|
||||
hci_driver_mem_bredr_acl_alloc(uint16_t handle)
|
||||
{
|
||||
return btdm_hci_trans_buf_alloc(HCI_H4_ACL, handle);
|
||||
}
|
||||
|
||||
void
|
||||
hci_driver_mem_bredr_acl_free(void *ptr)
|
||||
{
|
||||
hci_driver_packet_t *pkt = (hci_driver_packet_t *) ptr;
|
||||
bredr_hci_trans_acl_tx_done(pkt);
|
||||
bredr_hci_trans_acl_free(pkt);
|
||||
}
|
||||
|
||||
hci_driver_packet_t *
|
||||
hci_driver_mem_sync_alloc(uint16_t handle)
|
||||
{
|
||||
return btdm_hci_trans_buf_alloc(HCI_H4_SYNC, handle);
|
||||
}
|
||||
|
||||
void
|
||||
hci_driver_mem_sync_free(void *ptr)
|
||||
{
|
||||
hci_driver_packet_t *pkt = (hci_driver_packet_t *) ptr;
|
||||
bredr_hci_trans_sync_tx_done(pkt);
|
||||
bredr_hci_trans_sync_free(pkt);
|
||||
}
|
||||
#endif // UC_BTDM_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
const struct hci_h4_allocators s_hci_driver_mem_alloc = {
|
||||
.cmd = hci_driver_mem_cmd_alloc,
|
||||
.evt = hci_driver_mem_evt_alloc,
|
||||
.acl = hci_driver_mem_acl_alloc,
|
||||
.iso = hci_driver_mem_iso_alloc,
|
||||
#if UC_BTDM_CTRL_BR_EDR_IS_ENABLE
|
||||
.sync = hci_driver_mem_sync_alloc,
|
||||
.bredr_acl = hci_driver_mem_bredr_acl_alloc,
|
||||
#endif // UC_BTDM_CTRL_BR_EDR_IS_ENABLE
|
||||
};
|
||||
|
||||
const struct hci_h4_frees s_hci_driver_mem_free = {
|
||||
.cmd = hci_driver_mem_cmd_free,
|
||||
.evt = hci_driver_mem_evt_free,
|
||||
.acl = ble_mbuf_free_chain,
|
||||
.iso = hci_driver_mem_iso_free,
|
||||
.le_evt = r_ble_hci_trans_buf_free,
|
||||
#if UC_BTDM_CTRL_BR_EDR_IS_ENABLE
|
||||
.sync = hci_driver_mem_sync_free,
|
||||
.bredr_acl = hci_driver_mem_bredr_acl_free,
|
||||
#endif // UC_BTDM_CTRL_BR_EDR_IS_ENABLE
|
||||
};
|
||||
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_hci_driver.h"
|
||||
#include "esp_hci_internal.h"
|
||||
#include "common/hci_driver_util.h"
|
||||
|
||||
#define TAG "HCI_UTIL"
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
#define HCI_DRIVER_UTIL_BREDR_HCI_EVT_TX_POOL_NUM 4
|
||||
#define HCI_DRIVER_UTIL_BREDR_TX_POOL_NUM \
|
||||
(CONFIG_BT_CTRL_BR_EDR_ACLU_RX_BUF_NB_EFF + CONFIG_BT_CTRL_BR_EDR_SYNC_RX_BUF_NB_EFF + HCI_DRIVER_UTIL_BREDR_HCI_EVT_TX_POOL_NUM)
|
||||
#else
|
||||
#define HCI_DRIVER_UTIL_BREDR_TX_POOL_NUM 0
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
#define HCI_DRIVER_UTIL_BLE_TX_POOL_NUM \
|
||||
(CONFIG_BT_LE_ACL_BUF_COUNT + CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT + CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT)
|
||||
#else
|
||||
#define HCI_DRIVER_UTIL_BLE_TX_POOL_NUM 0
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
|
||||
#define HCI_DRIVER_UTIL_TX_POOL_NUM \
|
||||
(HCI_DRIVER_UTIL_BLE_TX_POOL_NUM + HCI_DRIVER_UTIL_BREDR_TX_POOL_NUM)
|
||||
|
||||
#ifndef min
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Structure representing HCI TX data.
|
||||
*/
|
||||
typedef struct hci_driver_util_tx_entry {
|
||||
hci_driver_data_type_t data_type; ///< Type of the HCI TX data.
|
||||
uint8_t data_source; ///< Source of the HCI TX data.
|
||||
uint32_t length; ///< Length of the TX data.
|
||||
union {
|
||||
hci_driver_packet_t *pkt;
|
||||
uint8_t *data; ///< Length of the TX ISO data.
|
||||
};
|
||||
STAILQ_ENTRY(hci_driver_util_tx_entry) next; ///< Next element in the linked list.
|
||||
} hci_driver_util_tx_entry_t;
|
||||
|
||||
/* The list for hci_driver_util_tx_entry */
|
||||
STAILQ_HEAD(hci_driver_util_tx_list, hci_driver_util_tx_entry);
|
||||
|
||||
typedef struct {
|
||||
struct hci_driver_util_tx_list tx_head;
|
||||
struct hci_driver_util_tx_entry *cur_tx_entry;
|
||||
uint32_t cur_tx_off;
|
||||
struct btdm_mempool *tx_entry_pool;
|
||||
uint8_t *tx_entry_mem;
|
||||
} hci_driver_util_env_t;
|
||||
|
||||
static hci_driver_util_env_t s_hci_driver_util_env;
|
||||
|
||||
static void
|
||||
hci_driver_util_memory_deinit(void)
|
||||
{
|
||||
if (s_hci_driver_util_env.tx_entry_pool) {
|
||||
free(s_hci_driver_util_env.tx_entry_pool);
|
||||
s_hci_driver_util_env.tx_entry_pool = NULL;
|
||||
}
|
||||
if (s_hci_driver_util_env.tx_entry_mem) {
|
||||
free(s_hci_driver_util_env.tx_entry_mem);
|
||||
s_hci_driver_util_env.tx_entry_mem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_util_memory_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
s_hci_driver_util_env.tx_entry_pool = (struct btdm_mempool *)malloc(sizeof(struct btdm_mempool));
|
||||
if (!s_hci_driver_util_env.tx_entry_pool) {
|
||||
ESP_LOGE(TAG, "No memory for tx pool");
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
s_hci_driver_util_env.tx_entry_mem = malloc(BTDM_MEMPOOL_SIZE(HCI_DRIVER_UTIL_TX_POOL_NUM,
|
||||
sizeof(hci_driver_util_tx_entry_t)) * sizeof(btdm_membuf_t));
|
||||
if (!s_hci_driver_util_env.tx_entry_mem) {
|
||||
ESP_LOGE(TAG, "No memory for tx pool buffer");
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
rc = btdm_mempool_init(s_hci_driver_util_env.tx_entry_pool, HCI_DRIVER_UTIL_TX_POOL_NUM,
|
||||
sizeof(hci_driver_util_tx_entry_t), s_hci_driver_util_env.tx_entry_mem,
|
||||
"hci_tx_entry_pool");
|
||||
if (rc) {
|
||||
ESP_LOGE(TAG, "Failed to initialize tx pool");
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
init_err:
|
||||
hci_driver_util_memory_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hci_driver_util_tx_list_enqueue(hci_driver_data_type_t type, uint8_t *data, uint32_t len, hci_driver_data_source_t data_source)
|
||||
{
|
||||
hci_driver_util_tx_entry_t *tx_entry;
|
||||
hci_driver_packet_t *pkt;
|
||||
uint8_t event_code = 0;
|
||||
|
||||
tx_entry = btdm_memblock_get(s_hci_driver_util_env.tx_entry_pool);
|
||||
if (tx_entry == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
pkt = (hci_driver_packet_t *)data;
|
||||
switch (data_source) {
|
||||
case HCI_DRIVER_BREDR_ACL:
|
||||
bredr_hci_trans_acl_tx_done(pkt);
|
||||
break;
|
||||
case HCI_DRIVER_BREDR_SYNC:
|
||||
bredr_hci_trans_sync_tx_done(pkt);
|
||||
break;
|
||||
case HCI_DRIVER_BREDR_EVT:
|
||||
bredr_hci_trans_evt_tx_done(pkt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
|
||||
tx_entry->data_type = type;
|
||||
tx_entry->data = data;
|
||||
tx_entry->length = len;
|
||||
tx_entry->data_source = data_source;
|
||||
if (data_source == HCI_DRIVER_BTDM_EVT) {
|
||||
pkt = (hci_driver_packet_t *)data;
|
||||
event_code = pkt->data[0];
|
||||
} else if (data_source == HCI_DRIVER_LE_EVT){
|
||||
event_code = data[0];
|
||||
}
|
||||
/* If the txbuf is command status event or command complete event, we should send firstly.
|
||||
* The tx list maybe used in the controller task and hci task. Therefore, enter critical area.
|
||||
*/
|
||||
if ((data_source == HCI_DRIVER_LE_EVT || data_source == HCI_DRIVER_BTDM_EVT) &&
|
||||
((event_code == 0x0E) || (event_code == 0x0F))) {
|
||||
btdm_osal_hw_enter_critical();
|
||||
STAILQ_INSERT_HEAD(&s_hci_driver_util_env.tx_head, tx_entry, next);
|
||||
btdm_osal_hw_exit_critical(0);
|
||||
} else {
|
||||
btdm_osal_hw_enter_critical();
|
||||
STAILQ_INSERT_TAIL(&s_hci_driver_util_env.tx_head, tx_entry, next);
|
||||
btdm_osal_hw_exit_critical(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_frame)
|
||||
{
|
||||
uint32_t tx_len;
|
||||
uint32_t data_len;
|
||||
hci_driver_util_tx_entry_t *tx_entry;
|
||||
hci_driver_packet_t *pkt = NULL;
|
||||
struct ble_mbuf *om = NULL;
|
||||
uint16_t out_off;
|
||||
/* Check if there is any remaining data that hasn't been sent completely. If it has been completed,
|
||||
* free the corresponding memory. Therefore, the HCI TX entry needs to be sent one by one; multiple
|
||||
* entries cannot be sent together.
|
||||
*/
|
||||
tx_len = 0;
|
||||
tx_entry = s_hci_driver_util_env.cur_tx_entry;
|
||||
if (tx_entry) {
|
||||
pkt = tx_entry->pkt;
|
||||
data_len = tx_entry->length;
|
||||
if (tx_entry->data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
if (s_hci_driver_util_env.cur_tx_off >= data_len) {
|
||||
if (tx_entry->data_source == HCI_DRIVER_LE_ACL) {
|
||||
om = (struct ble_mbuf *)tx_entry->data;
|
||||
ble_mbuf_free_chain(om);
|
||||
}
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
bredr_hci_trans_acl_free(pkt);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
} else {
|
||||
if (tx_entry->data_source == HCI_DRIVER_LE_ACL) {
|
||||
om = (struct ble_mbuf *)tx_entry->data;
|
||||
om = ble_mbuf_off(om, s_hci_driver_util_env.cur_tx_off, &out_off);
|
||||
tx_len = min(max_tx_len, om->om_len - out_off);
|
||||
*tx_data = (void *)&om->om_data[out_off];
|
||||
} else {
|
||||
tx_len = min(max_tx_len, data_len - s_hci_driver_util_env.cur_tx_off);
|
||||
*tx_data = &pkt->data[s_hci_driver_util_env.cur_tx_off];
|
||||
}
|
||||
}
|
||||
} else if (tx_entry->data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
if (s_hci_driver_util_env.cur_tx_off >= data_len) {
|
||||
if (tx_entry->data_source == HCI_DRIVER_LE_EVT) {
|
||||
r_ble_hci_trans_buf_free(tx_entry->data);
|
||||
}
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else if (tx_entry->data_source == HCI_DRIVER_BREDR_EVT) {
|
||||
bredr_hci_trans_evt_free(pkt);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
btdm_hci_trans_buf_free(pkt);
|
||||
}
|
||||
} else {
|
||||
tx_len = min(max_tx_len, data_len - s_hci_driver_util_env.cur_tx_off);
|
||||
if (tx_entry->data_source == HCI_DRIVER_LE_EVT) {
|
||||
*tx_data = &tx_entry->data[s_hci_driver_util_env.cur_tx_off];
|
||||
} else {
|
||||
*tx_data = &pkt->data[s_hci_driver_util_env.cur_tx_off];
|
||||
}
|
||||
}
|
||||
} else if (tx_entry->data_type == HCI_DRIVER_TYPE_ISO) {
|
||||
if (s_hci_driver_util_env.cur_tx_off >= data_len) {
|
||||
free(tx_entry->data);
|
||||
} else {
|
||||
tx_len = min(max_tx_len, data_len - s_hci_driver_util_env.cur_tx_off);
|
||||
*tx_data = &tx_entry->data[s_hci_driver_util_env.cur_tx_off];
|
||||
}
|
||||
}
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else if (tx_entry->data_type == HCI_DRIVER_TYPE_SYNC) {
|
||||
if (s_hci_driver_util_env.cur_tx_off >= data_len) {
|
||||
bredr_hci_trans_sync_free(pkt);
|
||||
} else {
|
||||
tx_len = min(max_tx_len, data_len - s_hci_driver_util_env.cur_tx_off);
|
||||
*tx_data = &pkt->data[s_hci_driver_util_env.cur_tx_off];
|
||||
}
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
HCI_TRANS_ASSERT(0, tx_entry->data_type, data_len);
|
||||
}
|
||||
/* If this is the last frame, inform the invoker not to call this API until the current data
|
||||
* has been completely sent.
|
||||
*/
|
||||
if (tx_len) {
|
||||
s_hci_driver_util_env.cur_tx_off += tx_len;
|
||||
|
||||
if (s_hci_driver_util_env.cur_tx_off >= data_len) {
|
||||
*last_frame = true;
|
||||
} else {
|
||||
*last_frame = false;
|
||||
}
|
||||
} else {
|
||||
btdm_memblock_put(s_hci_driver_util_env.tx_entry_pool, (void *)tx_entry);
|
||||
s_hci_driver_util_env.cur_tx_entry = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find a new entry. */
|
||||
if (!tx_len && !STAILQ_EMPTY(&s_hci_driver_util_env.tx_head)) {
|
||||
btdm_osal_hw_enter_critical();
|
||||
tx_entry = STAILQ_FIRST(&s_hci_driver_util_env.tx_head);
|
||||
STAILQ_REMOVE_HEAD(&s_hci_driver_util_env.tx_head, next);
|
||||
btdm_osal_hw_exit_critical(0);
|
||||
|
||||
*tx_data = &tx_entry->data_type;
|
||||
s_hci_driver_util_env.cur_tx_entry = tx_entry;
|
||||
s_hci_driver_util_env.cur_tx_off = 0;
|
||||
tx_len = 1;
|
||||
*last_frame = false;
|
||||
}
|
||||
|
||||
return tx_len;
|
||||
}
|
||||
|
||||
int
|
||||
hci_driver_util_init(void)
|
||||
{
|
||||
memset(&s_hci_driver_util_env, 0, sizeof(hci_driver_util_env_t));
|
||||
|
||||
if (hci_driver_util_memory_init()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
STAILQ_INIT(&s_hci_driver_util_env.tx_head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hci_driver_util_deinit(void)
|
||||
{
|
||||
hci_driver_util_tx_entry_t *tx_entry;
|
||||
hci_driver_util_tx_entry_t *next_entry;
|
||||
|
||||
/* Free all of controller buffers which haven't been sent yet. The whole mempool will be freed.
|
||||
* Therefore, it's unnecessary to put the tx_entry into mempool.
|
||||
*/
|
||||
tx_entry = STAILQ_FIRST(&s_hci_driver_util_env.tx_head);
|
||||
while (tx_entry) {
|
||||
next_entry = STAILQ_NEXT(tx_entry, next);
|
||||
if (tx_entry->data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
if (tx_entry->data_source == HCI_DRIVER_LE_EVT) {
|
||||
r_ble_hci_trans_buf_free(tx_entry->data);
|
||||
}
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else if (tx_entry->data_source == HCI_DRIVER_BREDR_EVT) {
|
||||
bredr_hci_trans_evt_tx_done((hci_driver_packet_t *)tx_entry->data);
|
||||
bredr_hci_trans_evt_free((hci_driver_packet_t *)tx_entry->data);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
btdm_hci_trans_buf_free((hci_driver_packet_t *)tx_entry->data);
|
||||
}
|
||||
} else if (tx_entry->data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
if (tx_entry->data_source == HCI_DRIVER_LE_ACL) {
|
||||
ble_mbuf_free_chain((struct ble_mbuf *)tx_entry->data);
|
||||
}
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
bredr_hci_trans_acl_tx_done((hci_driver_packet_t *)tx_entry->data);
|
||||
bredr_hci_trans_acl_free((hci_driver_packet_t *)tx_entry->data);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
} else if (tx_entry->data_type == HCI_DRIVER_TYPE_ISO) {
|
||||
free(tx_entry->data);
|
||||
}
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
// SCO data
|
||||
bredr_hci_trans_sync_tx_done((hci_driver_packet_t *)tx_entry->pkt);
|
||||
bredr_hci_trans_sync_free((hci_driver_packet_t *)tx_entry->pkt);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
tx_entry = next_entry;
|
||||
}
|
||||
|
||||
hci_driver_util_memory_deinit();
|
||||
|
||||
memset(&s_hci_driver_util_env, 0, sizeof(hci_driver_util_env_t));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hci_driver_util_assert_check(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2)
|
||||
{
|
||||
ESP_LOGE(TAG, "hci driver assert: line %d in function %s, param: 0x%x, 0x%x", ln, fn, param1, param2);
|
||||
assert(0);
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_hci_transport.h"
|
||||
#include "esp_hci_internal.h"
|
||||
#include "common/hci_driver_h4.h"
|
||||
#include "common/hci_driver_util.h"
|
||||
#include "common/hci_driver_mem.h"
|
||||
#include "hci_driver_uart.h"
|
||||
|
||||
static const char *TAG = "hci_uart";
|
||||
|
||||
#define CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN (1024)
|
||||
|
||||
typedef struct {
|
||||
TaskHandle_t tx_task_handler;
|
||||
TaskHandle_t rx_task_handler;
|
||||
hci_driver_uart_params_config_t *hci_uart_params;
|
||||
SemaphoreHandle_t tx_sem;
|
||||
QueueHandle_t rx_event_queue;
|
||||
uint8_t *rx_data;
|
||||
struct hci_h4_sm *h4_sm;
|
||||
hci_driver_forward_fn *forward_cb;
|
||||
} hci_driver_uart_env_t;
|
||||
|
||||
static hci_driver_uart_env_t s_hci_driver_uart_env;
|
||||
static struct hci_h4_sm s_hci_driver_uart_h4_sm;
|
||||
static uint8_t s_hci_driver_uart_rx_data[CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN];
|
||||
|
||||
static int
|
||||
hci_driver_uart_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
|
||||
hci_driver_direction_t dir)
|
||||
{
|
||||
int rc;
|
||||
uint8_t data_source;
|
||||
|
||||
data_source = 0;
|
||||
/* By now, this layer is only used by controller. */
|
||||
ESP_LOGD(TAG, "uart tx len:%d\n", length);
|
||||
if (dir == HCI_DRIVER_DIR_BTDMC2H) {
|
||||
if (data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
data_source = HCI_DRIVER_BTDM_EVT;
|
||||
}
|
||||
} else if (dir == HCI_DRIVER_DIR_LEC2H) {
|
||||
if (data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
data_source = HCI_DRIVER_LE_ACL;
|
||||
} else if (data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
data_source = HCI_DRIVER_LE_EVT;
|
||||
} else if (data_type == HCI_DRIVER_TYPE_ISO) {
|
||||
data_source = HCI_DRIVER_LE_ISO;
|
||||
}
|
||||
}
|
||||
#if UC_BTDM_CTRL_BR_EDR_IS_ENABLE
|
||||
else if (dir == HCI_DRIVER_DIR_BREDRC2H) {
|
||||
if (data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
data_source = HCI_DRIVER_BREDR_ACL;
|
||||
} else if (data_type == HCI_DRIVER_TYPE_SYNC) {
|
||||
data_source = HCI_DRIVER_BREDR_SYNC;
|
||||
} else if (data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
data_source = HCI_DRIVER_BREDR_EVT;
|
||||
}
|
||||
}
|
||||
#endif // UC_BTDM_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
rc = hci_driver_util_tx_list_enqueue(data_type, data, length, data_source);
|
||||
if (rc < 0) {
|
||||
ESP_LOGE(TAG, "tx data enqueue failed!\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
xSemaphoreGive(s_hci_driver_uart_env.tx_sem);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_uart_h4_frame_cb(uint8_t pkt_type, void *data, int pkt_len, uint8_t data_source)
|
||||
{
|
||||
hci_driver_forward_fn *forward_cb = s_hci_driver_uart_env.forward_cb;
|
||||
if (!forward_cb) {
|
||||
ESP_LOGE(TAG, "rx cb is NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "h4 frame\n");
|
||||
return forward_cb(pkt_type, data, pkt_len, HCI_DRIVER_DIR_H2C, data_source);
|
||||
}
|
||||
|
||||
static void
|
||||
hci_driver_uart_tx_task(void *p)
|
||||
{
|
||||
void *data;
|
||||
bool last_frame;
|
||||
uint32_t tx_len;
|
||||
uart_port_t port;
|
||||
|
||||
port = s_hci_driver_uart_env.hci_uart_params->hci_uart_port;
|
||||
while (true) {
|
||||
xSemaphoreTake(s_hci_driver_uart_env.tx_sem, portMAX_DELAY);
|
||||
while (true) {
|
||||
tx_len = hci_driver_util_tx_list_dequeue(0xffffff, &data, &last_frame);
|
||||
if (tx_len == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "uart tx");
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, data, tx_len, ESP_LOG_DEBUG);
|
||||
uart_write_bytes(port, data, tx_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hci_driver_uart_rx_task(void *p)
|
||||
{
|
||||
void *data;
|
||||
int read_len;
|
||||
int ret;
|
||||
uart_port_t port;
|
||||
uart_event_t uart_event;
|
||||
|
||||
port = s_hci_driver_uart_env.hci_uart_params->hci_uart_port;
|
||||
while (true) {
|
||||
xQueueReceive(s_hci_driver_uart_env.rx_event_queue, &uart_event, portMAX_DELAY);
|
||||
data = s_hci_driver_uart_env.rx_data;
|
||||
while (true) {
|
||||
read_len = uart_read_bytes(port, data, CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN, 0);
|
||||
if (read_len == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "uart rx read_len:%d\n", read_len);
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, data, read_len, ESP_LOG_DEBUG);
|
||||
ret = hci_h4_sm_rx(s_hci_driver_uart_env.h4_sm, data, read_len);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "parse rx data error! sm_state:%d\n", s_hci_driver_uart_env.h4_sm->state);
|
||||
r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_uart_task_create(void)
|
||||
{
|
||||
/* !TODO: Set the core id by menuconfig */
|
||||
xTaskCreatePinnedToCore(hci_driver_uart_tx_task, "hci_driver_uart_tx_task",
|
||||
UC_BTDM_CTRL_HCI_TRANS_TASK_STACK_SIZE, NULL,
|
||||
ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_env.tx_task_handler,
|
||||
0);
|
||||
assert(s_hci_driver_uart_env.tx_task_handler);
|
||||
|
||||
xTaskCreatePinnedToCore(hci_driver_uart_rx_task, "hci_driver_uart_rx_task",
|
||||
UC_BTDM_CTRL_HCI_TRANS_TASK_STACK_SIZE, NULL,
|
||||
ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_env.rx_task_handler,
|
||||
0);
|
||||
assert(s_hci_driver_uart_env.rx_task_handler);
|
||||
|
||||
ESP_LOGI(TAG, "hci transport task create successfully, prio:%d, stack size: %ld",
|
||||
ESP_TASK_BT_CONTROLLER_PRIO, UC_BTDM_CTRL_HCI_TRANS_TASK_STACK_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hci_driver_uart_task_delete(void)
|
||||
{
|
||||
if (s_hci_driver_uart_env.tx_task_handler) {
|
||||
vTaskDelete(s_hci_driver_uart_env.tx_task_handler);
|
||||
s_hci_driver_uart_env.tx_task_handler = NULL;
|
||||
}
|
||||
|
||||
if (s_hci_driver_uart_env.rx_task_handler) {
|
||||
vTaskDelete(s_hci_driver_uart_env.rx_task_handler);
|
||||
s_hci_driver_uart_env.rx_task_handler = NULL;
|
||||
}
|
||||
}
|
||||
static void
|
||||
hci_driver_uart_deinit(void)
|
||||
{
|
||||
hci_driver_uart_task_delete();
|
||||
|
||||
ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_env.hci_uart_params->hci_uart_port));
|
||||
|
||||
if (s_hci_driver_uart_env.tx_sem) {
|
||||
vSemaphoreDelete(s_hci_driver_uart_env.tx_sem);
|
||||
}
|
||||
|
||||
hci_driver_util_deinit();
|
||||
memset(&s_hci_driver_uart_env, 0, sizeof(hci_driver_uart_env_t));
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_uart_init(hci_driver_forward_fn *cb)
|
||||
{
|
||||
int rc;
|
||||
memset(&s_hci_driver_uart_env, 0, sizeof(hci_driver_uart_env_t));
|
||||
|
||||
s_hci_driver_uart_env.h4_sm = &s_hci_driver_uart_h4_sm;
|
||||
hci_h4_sm_init(s_hci_driver_uart_env.h4_sm, &s_hci_driver_mem_alloc, &s_hci_driver_mem_free, hci_driver_uart_h4_frame_cb);
|
||||
|
||||
rc = hci_driver_util_init();
|
||||
if (rc) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
s_hci_driver_uart_env.tx_sem = xSemaphoreCreateBinary();
|
||||
if (!s_hci_driver_uart_env.tx_sem) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
s_hci_driver_uart_env.rx_data = s_hci_driver_uart_rx_data;
|
||||
s_hci_driver_uart_env.forward_cb = cb;
|
||||
s_hci_driver_uart_env.hci_uart_params = hci_driver_uart_config_param_get();
|
||||
hci_driver_uart_config(s_hci_driver_uart_env.hci_uart_params);
|
||||
/* Currently, the queue size is set to 1. It will be considered as semaphore. */
|
||||
ESP_ERROR_CHECK(uart_driver_install(s_hci_driver_uart_env.hci_uart_params->hci_uart_port,
|
||||
UC_BTDM_CTRL_HCI_UART_RX_BUFFER_SIZE,
|
||||
UC_BTDM_CTRL_HCI_UART_TX_BUFFER_SIZE,
|
||||
1, &s_hci_driver_uart_env.rx_event_queue,
|
||||
0));
|
||||
|
||||
rc = hci_driver_uart_task_create();
|
||||
if (rc) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
hci_driver_uart_deinit();
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
hci_driver_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin)
|
||||
{
|
||||
int rc;
|
||||
|
||||
hci_driver_uart_task_delete();
|
||||
hci_driver_uart_pin_update(tx_pin, rx_pin, cts_pin, rts_pin);
|
||||
/* Currently, the queue size is set to 1. It will be considered as semaphore. */
|
||||
ESP_ERROR_CHECK(uart_driver_install(s_hci_driver_uart_env.hci_uart_params->hci_uart_port,
|
||||
UC_BTDM_CTRL_HCI_UART_RX_BUFFER_SIZE,
|
||||
UC_BTDM_CTRL_HCI_UART_TX_BUFFER_SIZE,
|
||||
1, &s_hci_driver_uart_env.rx_event_queue,
|
||||
0));
|
||||
rc = hci_driver_uart_task_create();
|
||||
if (rc) {
|
||||
hci_driver_uart_task_delete();
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
hci_driver_ops_t hci_driver_uart_ops = {
|
||||
.hci_driver_tx = hci_driver_uart_tx,
|
||||
.hci_driver_init = hci_driver_uart_init,
|
||||
.hci_driver_deinit = hci_driver_uart_deinit,
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
#include "driver/uart.h"
|
||||
#include "esp_bt.h"
|
||||
#include "esp_hci_transport.h"
|
||||
|
||||
/**
|
||||
* @brief UART configuration parameters for the HCI driver
|
||||
*/
|
||||
typedef struct hci_driver_uart_params_config
|
||||
{
|
||||
uint8_t hci_uart_port; /*!< Port of UART for HCI */
|
||||
uint8_t hci_uart_data_bits; /*!< Data bits of UART for HCI */
|
||||
uint8_t hci_uart_stop_bits; /*!< Stop bits of UART for HCI */
|
||||
uint8_t hci_uart_flow_ctrl; /*!< Flow control of UART for HCI */
|
||||
uint8_t hci_uart_parity; /*!< UART parity */
|
||||
uint8_t hci_uart_driver_mode; /*!< UART driver mode */
|
||||
uint32_t hci_uart_baud; /*!< Baudrate of UART for HCI */
|
||||
int hci_uart_tx_pin; /*!< Tx Pin number of UART for HCI */
|
||||
int hci_uart_rx_pin; /*!< Rx Pin number of UART for HCI */
|
||||
int hci_uart_rts_pin; /*!< RTS Pin number of UART for HCI */
|
||||
int hci_uart_cts_pin; /*!< CTS Pin number of UART for HCI */
|
||||
} hci_driver_uart_params_config_t;
|
||||
|
||||
#define BT_HCI_DRIVER_UART_CONFIG_DEFAULT() { \
|
||||
.hci_uart_port = UC_BTDM_CTRL_HCI_UART_PORT, \
|
||||
.hci_uart_baud = UC_BTDM_CTRL_HCI_UART_BAUD, \
|
||||
.hci_uart_tx_pin = UC_BTDM_CTRL_HCI_UART_TX_PIN , \
|
||||
.hci_uart_rx_pin = UC_BTDM_CTRL_HCI_UART_RX_PIN, \
|
||||
.hci_uart_cts_pin = UC_BTDM_CTRL_HCI_UART_CTS_PIN, \
|
||||
.hci_uart_rts_pin = UC_BTDM_CTRL_HCI_UART_RTS_PIN, \
|
||||
.hci_uart_data_bits = UC_BTDM_CTRL_HCI_UART_DATA_BITS, \
|
||||
.hci_uart_stop_bits = UC_BTDM_CTRL_HCI_UART_STOP_BITS, \
|
||||
.hci_uart_flow_ctrl = UC_BTDM_CTRL_HCI_UART_FLOW_CTRL, \
|
||||
.hci_uart_parity = UC_BTDM_CTRL_HCI_UART_PARITY, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the HCI driver UART parameters.
|
||||
* This function sets up the UART interface according to the specified configuration parameters.
|
||||
*
|
||||
* @param uart_config A pointer to a structure containing the UART configuration parameters.
|
||||
* The structure should include details such as baud rate, parity, stop bits, and flow control.
|
||||
* Ensure that the uart_config structure is correctly initialized before calling this function.
|
||||
*
|
||||
* @return int Returns 0 on success, or a non-zero error code on failure.
|
||||
*
|
||||
* @note This function should be called before any UART communication is initiated.
|
||||
*/
|
||||
int hci_driver_uart_config(hci_driver_uart_params_config_t *uart_config);
|
||||
|
||||
/**
|
||||
* @brief Update the UART pin configuration for the HCI driver.
|
||||
*
|
||||
* This function updates the TX, RX, CTS, and RTS pin assignments for the HCI driver operating over UART.
|
||||
* It allows dynamic reconfiguration of UART pins as needed.
|
||||
*
|
||||
* @param tx_pin The GPIO number assigned to the UART TX pin.
|
||||
* @param rx_pin The GPIO number assigned to the UART RX pin.
|
||||
* @param cts_pin The GPIO number assigned to the UART CTS pin.
|
||||
* @param rts_pin The GPIO number assigned to the UART RTS pin.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int hci_driver_uart_pin_update(int tx_pin, int rx_pin, int cts_pin, int rts_pin);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the current UART configuration parameters for the HCI driver.
|
||||
*
|
||||
* @return hci_driver_uart_params_config_t* Pointer to the structure with UART configuration parameters.
|
||||
*/
|
||||
hci_driver_uart_params_config_t * hci_driver_uart_config_param_get(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "driver/uart.h"
|
||||
#include "hci_driver_uart.h"
|
||||
#include "esp_private/esp_gpio_reserve.h"
|
||||
|
||||
static const char *TAG = "hci_uart_config";
|
||||
static uart_config_t s_uart_cfg;
|
||||
static hci_driver_uart_params_config_t s_hci_driver_uart_params = BT_HCI_DRIVER_UART_CONFIG_DEFAULT();
|
||||
|
||||
int hci_driver_uart_config(hci_driver_uart_params_config_t *uart_config)
|
||||
{
|
||||
uart_config_t *uart_cfg;
|
||||
uart_cfg = &s_uart_cfg;
|
||||
uart_cfg->baud_rate = uart_config->hci_uart_baud;
|
||||
uart_cfg->data_bits = uart_config->hci_uart_data_bits;
|
||||
uart_cfg->stop_bits = uart_config->hci_uart_stop_bits;
|
||||
uart_cfg->parity = uart_config->hci_uart_parity;
|
||||
uart_cfg->flow_ctrl = uart_config->hci_uart_flow_ctrl;
|
||||
uart_cfg->source_clk= UART_SCLK_DEFAULT;
|
||||
uart_cfg->rx_flow_ctrl_thresh = UART_HW_FIFO_LEN(uart_config->hci_uart_port) - 1;
|
||||
|
||||
ESP_LOGI(TAG,"set uart pin tx:%d, rx:%d.\n", uart_config->hci_uart_tx_pin, uart_config->hci_uart_rx_pin);
|
||||
ESP_LOGI(TAG,"set rts:%d, cts:%d.\n", uart_config->hci_uart_rts_pin, uart_config->hci_uart_cts_pin);
|
||||
ESP_LOGI(TAG,"set baud_rate:%d.\n", uart_config->hci_uart_baud);
|
||||
ESP_LOGI(TAG,"set flow_ctrl:%d.\n", uart_config->hci_uart_flow_ctrl);
|
||||
|
||||
ESP_ERROR_CHECK(uart_driver_delete(uart_config->hci_uart_port));
|
||||
ESP_ERROR_CHECK(uart_param_config(uart_config->hci_uart_port, uart_cfg));
|
||||
ESP_ERROR_CHECK(uart_set_pin(uart_config->hci_uart_port, uart_config->hci_uart_tx_pin, uart_config->hci_uart_rx_pin,
|
||||
uart_config->hci_uart_rts_pin, uart_config->hci_uart_cts_pin));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hci_driver_uart_pin_update(int tx_pin, int rx_pin, int cts_pin, int rts_pin)
|
||||
{
|
||||
hci_driver_uart_params_config_t *uart_param = &s_hci_driver_uart_params;
|
||||
/* Fixed warning that the gpio is not usable, may be used by others */
|
||||
esp_gpio_revoke(BIT64(uart_param->hci_uart_tx_pin));
|
||||
esp_gpio_revoke(BIT64(uart_param->hci_uart_rx_pin));
|
||||
if (uart_param->hci_uart_cts_pin != -1) {
|
||||
esp_gpio_revoke(BIT64(uart_param->hci_uart_cts_pin));
|
||||
}
|
||||
|
||||
if (uart_param->hci_uart_rts_pin != -1) {
|
||||
esp_gpio_revoke(BIT64(uart_param->hci_uart_rts_pin));
|
||||
}
|
||||
|
||||
uart_param->hci_uart_tx_pin = tx_pin;
|
||||
uart_param->hci_uart_rx_pin = rx_pin;
|
||||
uart_param->hci_uart_rts_pin = rts_pin;
|
||||
uart_param->hci_uart_cts_pin = cts_pin;
|
||||
return hci_driver_uart_config(uart_param);
|
||||
}
|
||||
|
||||
hci_driver_uart_params_config_t *
|
||||
hci_driver_uart_config_param_get(void)
|
||||
{
|
||||
return &s_hci_driver_uart_params;
|
||||
}
|
||||
@@ -0,0 +1,714 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_hci_transport.h"
|
||||
#include "esp_hci_internal.h"
|
||||
#include "common/hci_driver_h4.h"
|
||||
#include "common/hci_driver_util.h"
|
||||
#include "common/hci_driver_mem.h"
|
||||
#include "hci_driver_uart.h"
|
||||
|
||||
#include "ble_hci_trans.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/gdma.h"
|
||||
#include "hal/uhci_ll.h"
|
||||
|
||||
/*
|
||||
* UART DMA Desc struct
|
||||
*
|
||||
* --------------------------------------------------------------
|
||||
* | own | EoF | sub_sof | 5'b0 | length [11:0] | size [11:0] |
|
||||
* --------------------------------------------------------------
|
||||
* | buf_ptr [31:0] |
|
||||
* --------------------------------------------------------------
|
||||
* | next_desc_ptr [31:0] |
|
||||
* --------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* this bitfield is start from the LSB!!! */
|
||||
typedef struct uhci_lldesc_s {
|
||||
volatile uint32_t size : 12,
|
||||
length: 12,
|
||||
offset: 5, /* h/w reserved 5bit, s/w use it as offset in buffer */
|
||||
sosf : 1, /* start of sub-frame */
|
||||
eof : 1, /* end of frame */
|
||||
owner : 1; /* hw or sw */
|
||||
volatile const uint8_t *buf; /* point to buffer data */
|
||||
union {
|
||||
volatile uint32_t empty;
|
||||
STAILQ_ENTRY(uhci_lldesc_s) qe; /* pointing to the next desc */
|
||||
};
|
||||
} uhci_lldesc_t;
|
||||
|
||||
/**
|
||||
* @brief Enumeration of HCI transport transmission states.
|
||||
*/
|
||||
typedef enum {
|
||||
HCI_TRANS_TX_IDLE, ///< HCI Transport TX is in idle state.
|
||||
HCI_TRANS_TX_START, ///< HCI Transport TX is starting transmission.
|
||||
HCI_TRANS_TX_END, ///< HCI Transport TX has completed transmission.
|
||||
} hci_trans_tx_state_t;
|
||||
|
||||
typedef struct {
|
||||
TaskHandle_t task_handler;
|
||||
hci_driver_uart_params_config_t *hci_uart_params;
|
||||
SemaphoreHandle_t process_sem;
|
||||
struct hci_h4_sm *h4_sm;
|
||||
hci_driver_forward_fn *forward_cb;
|
||||
struct os_mempool *hci_rx_data_pool; /*!< Init a memory pool for rx_data cache */
|
||||
uint8_t *hci_rx_data_buffer;
|
||||
struct os_mempool *hci_rxinfo_pool; /*!< Init a memory pool for rxinfo cache */
|
||||
os_membuf_t *hci_rxinfo_buffer;
|
||||
volatile bool rxinfo_mem_exhausted; /*!< Indicate rxinfo memory does not exist */
|
||||
volatile bool is_continue_rx; /*!< Continue to rx */
|
||||
volatile hci_trans_tx_state_t hci_tx_state; /*!< HCI Tx State */
|
||||
struct os_mempool lldesc_mem_pool;/*!< Init a memory pool for uhci_lldesc_t */
|
||||
uhci_lldesc_t *lldesc_mem;
|
||||
} hci_driver_uart_dma_env_t;
|
||||
|
||||
#define ESP_BT_HCI_TL_STATUS_OK (0) /*!< HCI_TL Tx/Rx operation status OK */
|
||||
/* The number of lldescs pool */
|
||||
#define HCI_LLDESCS_POOL_NUM (UC_BT_CTRL_HCI_LLDESCS_POOL_NUM)
|
||||
/* Default block size for HCI RX data */
|
||||
#define HCI_RX_DATA_POOL_NUM (UC_BT_CTRL_HCI_TRANS_RX_MEM_NUM)
|
||||
#define HCI_RX_INFO_POOL_NUM (UC_BT_CTRL_HCI_TRANS_RX_MEM_NUM + 1)
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
#define HCI_RX_DATA_BLOCK_SIZE (DEFAULT_BT_LE_ACL_BUF_SIZE + BLE_HCI_TRANS_CMD_SZ)
|
||||
#else
|
||||
#define HCI_RX_DATA_BLOCK_SIZE (1024)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief callback function for HCI Transport Layer send/receive operations
|
||||
*/
|
||||
typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status);
|
||||
|
||||
struct uart_txrxchannel {
|
||||
esp_bt_hci_tl_callback_t callback;
|
||||
void *arg;
|
||||
uhci_lldesc_t *link_head;
|
||||
};
|
||||
|
||||
struct uart_env_tag {
|
||||
struct uart_txrxchannel tx;
|
||||
struct uart_txrxchannel rx;
|
||||
};
|
||||
|
||||
typedef struct hci_message {
|
||||
void *ptr; ///< Pointer to the message data.
|
||||
uint32_t length; ///< Length of the message data.
|
||||
STAILQ_ENTRY(hci_message) next; ///< Next element in the linked list.
|
||||
} hci_message_t;
|
||||
|
||||
static void hci_driver_uart_dma_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg);
|
||||
int hci_driver_uart_dma_rx_start(uint8_t *rx_data, uint32_t length);
|
||||
int hci_driver_uart_dma_tx_start(esp_bt_hci_tl_callback_t callback, void *arg);
|
||||
|
||||
static const char *TAG = "uart_dma";
|
||||
static hci_driver_uart_dma_env_t s_hci_driver_uart_dma_env;
|
||||
static struct hci_h4_sm s_hci_driver_uart_h4_sm;
|
||||
|
||||
/* The list for hci_rx_data */
|
||||
STAILQ_HEAD(g_hci_rxinfo_list, hci_message);
|
||||
|
||||
DRAM_ATTR struct g_hci_rxinfo_list g_hci_rxinfo_head;
|
||||
static DRAM_ATTR struct uart_env_tag uart_env;
|
||||
static volatile uhci_dev_t *s_uhci_hw = &UHCI0;
|
||||
static DRAM_ATTR gdma_channel_handle_t s_rx_channel;
|
||||
static DRAM_ATTR gdma_channel_handle_t s_tx_channel;
|
||||
|
||||
static int hci_driver_uart_dma_memory_deinit(void)
|
||||
{
|
||||
|
||||
if (s_hci_driver_uart_dma_env.hci_rxinfo_buffer) {
|
||||
free(s_hci_driver_uart_dma_env.hci_rxinfo_buffer);
|
||||
s_hci_driver_uart_dma_env.hci_rxinfo_buffer = NULL;
|
||||
}
|
||||
|
||||
if (s_hci_driver_uart_dma_env.hci_rxinfo_pool) {
|
||||
free(s_hci_driver_uart_dma_env.hci_rxinfo_pool);
|
||||
s_hci_driver_uart_dma_env.hci_rxinfo_pool = NULL;
|
||||
}
|
||||
|
||||
if (s_hci_driver_uart_dma_env.hci_rx_data_buffer) {
|
||||
free(s_hci_driver_uart_dma_env.hci_rx_data_buffer);
|
||||
s_hci_driver_uart_dma_env.hci_rx_data_buffer = NULL;
|
||||
}
|
||||
|
||||
if (s_hci_driver_uart_dma_env.hci_rx_data_pool) {
|
||||
free(s_hci_driver_uart_dma_env.hci_rx_data_pool);
|
||||
s_hci_driver_uart_dma_env.hci_rx_data_pool = NULL;
|
||||
}
|
||||
|
||||
if (s_hci_driver_uart_dma_env.lldesc_mem) {
|
||||
free(s_hci_driver_uart_dma_env.lldesc_mem);
|
||||
s_hci_driver_uart_dma_env.lldesc_mem = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hci_driver_uart_dma_memory_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
s_hci_driver_uart_dma_env.lldesc_mem = malloc(OS_MEMPOOL_SIZE(HCI_LLDESCS_POOL_NUM,
|
||||
sizeof (uhci_lldesc_t)) * sizeof(os_membuf_t));
|
||||
if (!s_hci_driver_uart_dma_env.lldesc_mem) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = os_mempool_init(&s_hci_driver_uart_dma_env.lldesc_mem_pool, HCI_LLDESCS_POOL_NUM,
|
||||
sizeof (uhci_lldesc_t), s_hci_driver_uart_dma_env.lldesc_mem, "hci_lldesc_pool");
|
||||
if (rc) {
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
s_hci_driver_uart_dma_env.hci_rx_data_pool = (struct os_mempool *)malloc(sizeof(struct os_mempool));
|
||||
if (!s_hci_driver_uart_dma_env.hci_rx_data_pool) {
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
memset(s_hci_driver_uart_dma_env.hci_rx_data_pool, 0, sizeof(struct os_mempool));
|
||||
s_hci_driver_uart_dma_env.hci_rx_data_buffer = malloc(OS_MEMPOOL_SIZE(HCI_RX_DATA_POOL_NUM,
|
||||
HCI_RX_DATA_BLOCK_SIZE) * sizeof(os_membuf_t));
|
||||
if (!s_hci_driver_uart_dma_env.hci_rx_data_buffer) {
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
memset(s_hci_driver_uart_dma_env.hci_rx_data_buffer, 0, OS_MEMPOOL_SIZE(HCI_RX_DATA_POOL_NUM,
|
||||
HCI_RX_DATA_BLOCK_SIZE) * sizeof(os_membuf_t));
|
||||
rc = os_mempool_init(s_hci_driver_uart_dma_env.hci_rx_data_pool, HCI_RX_DATA_POOL_NUM,
|
||||
HCI_RX_DATA_BLOCK_SIZE, s_hci_driver_uart_dma_env.hci_rx_data_buffer,
|
||||
"hci_rx_data_pool");
|
||||
if (rc) {
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
|
||||
/* Malloc hci rxinfo pool */
|
||||
s_hci_driver_uart_dma_env.hci_rxinfo_pool = (struct os_mempool *)malloc(sizeof(struct os_mempool));
|
||||
if (!s_hci_driver_uart_dma_env.hci_rxinfo_pool) {
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
memset(s_hci_driver_uart_dma_env.hci_rxinfo_pool, 0, sizeof(struct os_mempool));
|
||||
s_hci_driver_uart_dma_env.hci_rxinfo_buffer = malloc(OS_MEMPOOL_SIZE(HCI_RX_INFO_POOL_NUM,
|
||||
sizeof(hci_message_t)) * sizeof(os_membuf_t));
|
||||
if (!s_hci_driver_uart_dma_env.hci_rxinfo_buffer) {
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
memset(s_hci_driver_uart_dma_env.hci_rxinfo_buffer, 0, OS_MEMPOOL_SIZE(HCI_RX_INFO_POOL_NUM,
|
||||
sizeof(hci_message_t)) * sizeof(os_membuf_t));
|
||||
rc = os_mempool_init(s_hci_driver_uart_dma_env.hci_rxinfo_pool, HCI_RX_INFO_POOL_NUM,
|
||||
sizeof(hci_message_t), s_hci_driver_uart_dma_env.hci_rxinfo_buffer,
|
||||
"hci_rxinfo_pool");
|
||||
if (rc) {
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
return rc;
|
||||
init_err:
|
||||
hci_driver_uart_dma_memory_deinit();
|
||||
return rc;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool hci_uart_tl_rx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
|
||||
{
|
||||
esp_bt_hci_tl_callback_t callback = uart_env.rx.callback;
|
||||
void *arg = uart_env.rx.arg;
|
||||
assert(dma_chan == s_rx_channel);
|
||||
assert(uart_env.rx.callback != NULL);
|
||||
// clear callback pointer
|
||||
uart_env.rx.callback = NULL;
|
||||
uart_env.rx.arg = NULL;
|
||||
// call handler
|
||||
callback(arg, ESP_BT_HCI_TL_STATUS_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool hci_uart_tl_tx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
|
||||
{
|
||||
esp_bt_hci_tl_callback_t callback = uart_env.tx.callback;
|
||||
assert(dma_chan == s_tx_channel);
|
||||
assert(uart_env.tx.callback != NULL);
|
||||
// clear callback pointer
|
||||
uart_env.tx.callback = NULL;
|
||||
// call handler
|
||||
callback(uart_env.tx.arg, ESP_BT_HCI_TL_STATUS_OK);
|
||||
uart_env.tx.arg = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t * IRAM_ATTR hci_driver_uart_dma_rxdata_memory_get(void)
|
||||
{
|
||||
uint8_t *rx_data;
|
||||
rx_data = os_memblock_get(s_hci_driver_uart_dma_env.hci_rx_data_pool);
|
||||
return rx_data;
|
||||
}
|
||||
|
||||
hci_message_t * IRAM_ATTR hci_driver_uart_dma_rxinfo_memory_get(void)
|
||||
{
|
||||
hci_message_t *rx_info;
|
||||
rx_info = os_memblock_get(s_hci_driver_uart_dma_env.hci_rxinfo_pool);
|
||||
return rx_info;
|
||||
}
|
||||
|
||||
void IRAM_ATTR hci_driver_uart_dma_cache_rxinfo(hci_message_t *hci_rxinfo)
|
||||
{
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
STAILQ_INSERT_TAIL(&g_hci_rxinfo_head, hci_rxinfo, next);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
void IRAM_ATTR hci_driver_uart_dma_continue_rx_enable(bool enable)
|
||||
{
|
||||
os_sr_t sr;
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
s_hci_driver_uart_dma_env.is_continue_rx = enable;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
void IRAM_ATTR hci_driver_uart_dma_rxinfo_mem_exhausted_set(bool is_exhausted)
|
||||
{
|
||||
os_sr_t sr;
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
s_hci_driver_uart_dma_env.rxinfo_mem_exhausted = is_exhausted;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
void IRAM_ATTR hci_driver_uart_dma_recv_callback(void *arg, uint8_t status)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
hci_message_t *hci_rxinfo;
|
||||
uint8_t *rx_data;
|
||||
|
||||
if (s_hci_driver_uart_dma_env.rxinfo_mem_exhausted) {
|
||||
ESP_LOGE(TAG, "Will lost rx data, need adjust rxinfo memory count\n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
hci_rxinfo = hci_driver_uart_dma_rxinfo_memory_get();
|
||||
if (!hci_rxinfo) {
|
||||
ESP_LOGW(TAG, "set rxinfo mem exhausted flag\n");
|
||||
hci_driver_uart_dma_rxinfo_mem_exhausted_set(true);
|
||||
xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken);
|
||||
return;
|
||||
}
|
||||
|
||||
hci_rxinfo->ptr = (void *)uart_env.rx.link_head->buf;
|
||||
hci_rxinfo->length = uart_env.rx.link_head->length;
|
||||
hci_driver_uart_dma_cache_rxinfo(hci_rxinfo);
|
||||
xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken);
|
||||
rx_data = hci_driver_uart_dma_rxdata_memory_get();
|
||||
if (!rx_data) {
|
||||
hci_driver_uart_dma_continue_rx_enable(true);
|
||||
}else {
|
||||
hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR hci_driver_uart_dma_txstate_set(hci_trans_tx_state_t tx_state)
|
||||
{
|
||||
os_sr_t sr;
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
s_hci_driver_uart_dma_env.hci_tx_state = tx_state;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
void IRAM_ATTR hci_driver_uart_dma_send_callback(void *arg, uint8_t status)
|
||||
{
|
||||
uhci_lldesc_t *lldesc_head;
|
||||
uhci_lldesc_t *lldesc_nxt;
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
lldesc_head = uart_env.tx.link_head;
|
||||
while (lldesc_head) {
|
||||
lldesc_nxt = lldesc_head->qe.stqe_next;
|
||||
os_memblock_put(&s_hci_driver_uart_dma_env.lldesc_mem_pool, lldesc_head);
|
||||
lldesc_head = lldesc_nxt;
|
||||
}
|
||||
|
||||
uart_env.tx.link_head = NULL;
|
||||
hci_driver_uart_dma_txstate_set(HCI_TRANS_TX_IDLE);
|
||||
xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
static IRAM_ATTR void hci_driver_uart_dma_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg)
|
||||
{
|
||||
uhci_lldesc_t *lldesc_head;
|
||||
assert(buf != NULL);
|
||||
assert(size != 0);
|
||||
assert(callback != NULL);
|
||||
uart_env.rx.callback = callback;
|
||||
uart_env.rx.arg = arg;
|
||||
lldesc_head = uart_env.rx.link_head;
|
||||
|
||||
while (lldesc_head) {
|
||||
os_memblock_put(&s_hci_driver_uart_dma_env.lldesc_mem_pool, lldesc_head),
|
||||
lldesc_head = lldesc_head->qe.stqe_next;
|
||||
}
|
||||
|
||||
uart_env.rx.link_head = NULL;
|
||||
lldesc_head = os_memblock_get(&s_hci_driver_uart_dma_env.lldesc_mem_pool);
|
||||
assert(lldesc_head);
|
||||
memset(lldesc_head, 0, sizeof(uhci_lldesc_t));
|
||||
lldesc_head->buf = buf;
|
||||
lldesc_head->size = size;
|
||||
lldesc_head->eof = 0;
|
||||
s_uhci_hw->pkt_thres.pkt_thrs = size;
|
||||
uart_env.rx.link_head = lldesc_head;
|
||||
gdma_start(s_rx_channel, (intptr_t)(uart_env.rx.link_head));
|
||||
}
|
||||
|
||||
int IRAM_ATTR hci_driver_uart_dma_rx_start(uint8_t *rx_data, uint32_t length)
|
||||
{
|
||||
hci_driver_uart_dma_recv_async(rx_data, length, hci_driver_uart_dma_recv_callback, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hci_driver_uart_dma_tx_start(esp_bt_hci_tl_callback_t callback, void *arg)
|
||||
{
|
||||
void *data;
|
||||
bool last_frame;
|
||||
bool head_is_setted;
|
||||
uint32_t tx_len;
|
||||
uhci_lldesc_t *lldesc_data;
|
||||
uhci_lldesc_t *lldesc_head;
|
||||
uhci_lldesc_t *lldesc_tail;
|
||||
|
||||
lldesc_head = NULL;
|
||||
lldesc_tail = NULL;
|
||||
head_is_setted = false;
|
||||
last_frame = false;
|
||||
while (true) {
|
||||
// The length in DMA is 12 bits
|
||||
tx_len = hci_driver_util_tx_list_dequeue(0xfff, &data, &last_frame);
|
||||
if (!tx_len) {
|
||||
break;
|
||||
}
|
||||
|
||||
lldesc_data = os_memblock_get(&s_hci_driver_uart_dma_env.lldesc_mem_pool);
|
||||
/* According to the current processing logic, It should not be empty */
|
||||
assert(lldesc_data);
|
||||
memset(lldesc_data, 0, sizeof(uhci_lldesc_t));
|
||||
lldesc_data->length = tx_len;
|
||||
lldesc_data->buf = data;
|
||||
lldesc_data->eof = 0;
|
||||
if (!head_is_setted) {
|
||||
lldesc_head = lldesc_data;
|
||||
head_is_setted = true;
|
||||
} else {
|
||||
lldesc_tail->qe.stqe_next = lldesc_data;
|
||||
}
|
||||
|
||||
lldesc_tail = lldesc_data;
|
||||
if (last_frame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lldesc_head) {
|
||||
lldesc_tail->eof = 1;
|
||||
uart_env.tx.link_head = lldesc_head;
|
||||
uart_env.tx.callback = callback;
|
||||
uart_env.tx.arg = arg;
|
||||
/* The DMA interrupt may have been triggered before setting the tx_state,
|
||||
* So we set it first.
|
||||
*/
|
||||
hci_driver_uart_dma_txstate_set(HCI_TRANS_TX_START);
|
||||
gdma_start(s_tx_channel, (intptr_t)(uart_env.tx.link_head));
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void hci_driver_uart_dma_install(void)
|
||||
{
|
||||
#if __PERIPH_CTRL_DEPRECATE_ATTR
|
||||
periph_module_enable(PERIPH_UHCI0_MODULE);
|
||||
periph_module_reset(PERIPH_UHCI0_MODULE);
|
||||
#else
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
uhci_ll_enable_bus_clock(1);
|
||||
uhci_ll_reset_register();
|
||||
}
|
||||
#endif
|
||||
|
||||
// install DMA driver
|
||||
gdma_channel_alloc_config_t tx_channel_config = {
|
||||
.flags.reserve_sibling = 1,
|
||||
.direction = GDMA_CHANNEL_DIRECTION_TX,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(gdma_new_ahb_channel(&tx_channel_config, &s_tx_channel));
|
||||
gdma_channel_alloc_config_t rx_channel_config = {
|
||||
.direction = GDMA_CHANNEL_DIRECTION_RX,
|
||||
.sibling_chan = s_tx_channel,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(gdma_new_ahb_channel(&rx_channel_config, &s_rx_channel));
|
||||
gdma_connect(s_tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0));
|
||||
gdma_connect(s_rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0));
|
||||
gdma_strategy_config_t strategy_config = {
|
||||
.auto_update_desc = false,
|
||||
.owner_check = false
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(gdma_apply_strategy(s_tx_channel, &strategy_config));
|
||||
ESP_ERROR_CHECK(gdma_apply_strategy(s_rx_channel, &strategy_config));
|
||||
gdma_rx_event_callbacks_t rx_cbs = {
|
||||
.on_recv_eof = hci_uart_tl_rx_eof_callback
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(gdma_register_rx_event_callbacks(s_rx_channel, &rx_cbs, NULL));
|
||||
gdma_tx_event_callbacks_t tx_cbs = {
|
||||
.on_trans_eof = hci_uart_tl_tx_eof_callback
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(gdma_register_tx_event_callbacks(s_tx_channel, &tx_cbs, NULL));
|
||||
|
||||
// configure UHCI
|
||||
uhci_ll_init((uhci_dev_t *)s_uhci_hw);
|
||||
// uhci_ll_set_eof_mode((uhci_dev_t *)s_uhci_hw, UHCI_RX_LEN_EOF);
|
||||
uhci_ll_set_eof_mode((uhci_dev_t *)s_uhci_hw, UHCI_RX_IDLE_EOF);
|
||||
// disable software flow control
|
||||
s_uhci_hw->escape_conf.val = 0;
|
||||
uhci_ll_attach_uart_port((uhci_dev_t *)s_uhci_hw, s_hci_driver_uart_dma_env.hci_uart_params->hci_uart_port);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_uart_dma_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
|
||||
hci_driver_direction_t dir)
|
||||
{
|
||||
uint8_t data_source;
|
||||
int rc;
|
||||
|
||||
data_source = 0;
|
||||
/* By now, this layer is only used by controller. */
|
||||
ESP_LOGD(TAG, "dma tx len:%d\n", length);
|
||||
if (dir == HCI_DRIVER_DIR_BTDMC2H) {
|
||||
if (data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
data_source = HCI_DRIVER_BTDM_EVT;
|
||||
}
|
||||
} else if (dir == HCI_DRIVER_DIR_LEC2H) {
|
||||
if (data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
data_source = HCI_DRIVER_LE_ACL;
|
||||
} else if (data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
data_source = HCI_DRIVER_LE_EVT;
|
||||
} else if (data_type == HCI_DRIVER_TYPE_ISO) {
|
||||
data_source = HCI_DRIVER_LE_ISO;
|
||||
}
|
||||
}
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else if (dir == HCI_DRIVER_DIR_BREDRC2H) {
|
||||
if (data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
data_source = HCI_DRIVER_BREDR_ACL;
|
||||
} else if (data_type == HCI_DRIVER_TYPE_SYNC) {
|
||||
data_source = HCI_DRIVER_BREDR_SYNC;
|
||||
} else if (data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
data_source = HCI_DRIVER_BREDR_EVT;
|
||||
}
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
rc = hci_driver_util_tx_list_enqueue(data_type, data, length, data_source);
|
||||
if (rc < 0) {
|
||||
ESP_LOGE(TAG, "dma tx data enqueue failed!\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
xSemaphoreGive(s_hci_driver_uart_dma_env.process_sem);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_uart_dma_h4_frame_cb(uint8_t pkt_type, void *data, int pkt_len, uint8_t data_source)
|
||||
{
|
||||
hci_driver_forward_fn *forward_cb = s_hci_driver_uart_dma_env.forward_cb;
|
||||
if (!forward_cb) {
|
||||
ESP_LOGW(TAG, "rx cb is NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "h4 frame\n");
|
||||
return forward_cb(pkt_type, data, pkt_len, HCI_DRIVER_DIR_H2C, data_source);
|
||||
}
|
||||
|
||||
static void
|
||||
hci_driver_uart_dma_process_task(void *p)
|
||||
{
|
||||
hci_message_t *rxinfo_container;
|
||||
os_sr_t sr;
|
||||
int ret;
|
||||
uint8_t* rx_data;
|
||||
uint32_t rx_len;
|
||||
|
||||
while (true) {
|
||||
xSemaphoreTake(s_hci_driver_uart_dma_env.process_sem, portMAX_DELAY);
|
||||
ESP_LOGD(TAG, "task run:%d\n",s_hci_driver_uart_dma_env.hci_tx_state);
|
||||
/* Process Tx data */
|
||||
if (s_hci_driver_uart_dma_env.hci_tx_state == HCI_TRANS_TX_IDLE) {
|
||||
hci_driver_uart_dma_tx_start(hci_driver_uart_dma_send_callback, (void*)&uart_env);
|
||||
}
|
||||
|
||||
if (s_hci_driver_uart_dma_env.rxinfo_mem_exhausted) {
|
||||
rx_data = (void *)uart_env.rx.link_head->buf;
|
||||
rx_len = uart_env.rx.link_head->length;
|
||||
ESP_LOGD(TAG, "rxinfo exhausted:");
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, rx_data, rx_len, ESP_LOG_DEBUG);
|
||||
ret = hci_h4_sm_rx(s_hci_driver_uart_dma_env.h4_sm, rx_data, rx_len);
|
||||
hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE);
|
||||
hci_driver_uart_dma_rxinfo_mem_exhausted_set(false);
|
||||
if (ret < 0) {
|
||||
ESP_LOGW(TAG, "parse rx data error!\n");
|
||||
r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
while (!STAILQ_EMPTY(&g_hci_rxinfo_head)) {
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
rxinfo_container = STAILQ_FIRST(&g_hci_rxinfo_head);
|
||||
STAILQ_REMOVE_HEAD(&g_hci_rxinfo_head, next);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
rx_data = rxinfo_container->ptr;
|
||||
rx_len = rxinfo_container->length;
|
||||
ESP_LOGD(TAG, "uart rx");
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, rx_data, rx_len, ESP_LOG_DEBUG);
|
||||
ret = hci_h4_sm_rx(s_hci_driver_uart_dma_env.h4_sm, rx_data, rx_len);
|
||||
if (ret < 0) {
|
||||
ESP_LOGW(TAG, "parse rx data error!\n");
|
||||
r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR);
|
||||
}
|
||||
|
||||
os_memblock_put(s_hci_driver_uart_dma_env.hci_rxinfo_pool, rxinfo_container);
|
||||
/* No need to enter CRITICAL */
|
||||
if (s_hci_driver_uart_dma_env.is_continue_rx) {
|
||||
/* We should set continux rx flag first, RX interrupted may happened when rx start soon */
|
||||
hci_driver_uart_dma_continue_rx_enable(false);
|
||||
hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE);
|
||||
} else {
|
||||
os_memblock_put(s_hci_driver_uart_dma_env.hci_rx_data_pool, rx_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_uart_dma_task_create(void)
|
||||
{
|
||||
/* !TODO: Set the core id by menuconfig */
|
||||
xTaskCreatePinnedToCore(hci_driver_uart_dma_process_task, "hci_driver_uart_dma_process_task",
|
||||
UC_BT_CTRL_HCI_TRANS_TASK_STACK_SIZE, NULL,
|
||||
ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_dma_env.task_handler,
|
||||
0);
|
||||
assert(s_hci_driver_uart_dma_env.task_handler);
|
||||
|
||||
ESP_LOGI(TAG, "hci transport task create successfully, prio:%d, stack size: %ld",
|
||||
ESP_TASK_BT_CONTROLLER_PRIO, UC_BT_CTRL_HCI_TRANS_TASK_STACK_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hci_driver_uart_dma_deinit(void)
|
||||
{
|
||||
if (s_hci_driver_uart_dma_env.task_handler) {
|
||||
vTaskDelete(s_hci_driver_uart_dma_env.task_handler);
|
||||
s_hci_driver_uart_dma_env.task_handler = NULL;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_dma_env.hci_uart_params->hci_uart_port));
|
||||
hci_driver_uart_dma_memory_deinit();
|
||||
if (!s_hci_driver_uart_dma_env.process_sem) {
|
||||
vSemaphoreDelete(s_hci_driver_uart_dma_env.process_sem);
|
||||
}
|
||||
|
||||
hci_driver_util_deinit();
|
||||
memset(&s_hci_driver_uart_dma_env, 0, sizeof(hci_driver_uart_dma_env_t));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hci_driver_uart_dma_init(hci_driver_forward_fn *cb)
|
||||
{
|
||||
int rc;
|
||||
|
||||
memset(&s_hci_driver_uart_dma_env, 0, sizeof(hci_driver_uart_dma_env_t));
|
||||
|
||||
s_hci_driver_uart_dma_env.h4_sm = &s_hci_driver_uart_h4_sm;
|
||||
hci_h4_sm_init(s_hci_driver_uart_dma_env.h4_sm, &s_hci_driver_mem_alloc, &s_hci_driver_mem_free, hci_driver_uart_dma_h4_frame_cb);
|
||||
|
||||
rc = hci_driver_util_init();
|
||||
if (rc) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
s_hci_driver_uart_dma_env.process_sem = xSemaphoreCreateBinary();
|
||||
if (!s_hci_driver_uart_dma_env.process_sem) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = hci_driver_uart_dma_memory_init();
|
||||
if (rc) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
s_hci_driver_uart_dma_env.forward_cb = cb;
|
||||
s_hci_driver_uart_dma_env.hci_uart_params = hci_driver_uart_config_param_get();
|
||||
hci_driver_uart_config(s_hci_driver_uart_dma_env.hci_uart_params);
|
||||
|
||||
ESP_LOGI(TAG, "uart attach uhci!");
|
||||
hci_driver_uart_dma_install();
|
||||
|
||||
STAILQ_INIT(&g_hci_rxinfo_head);
|
||||
|
||||
rc = hci_driver_uart_dma_task_create();
|
||||
if (rc) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
s_hci_driver_uart_dma_env.hci_tx_state = HCI_TRANS_TX_IDLE;
|
||||
s_hci_driver_uart_dma_env.rxinfo_mem_exhausted = false;
|
||||
s_hci_driver_uart_dma_env.is_continue_rx = false;
|
||||
hci_driver_uart_dma_rx_start(os_memblock_get(s_hci_driver_uart_dma_env.hci_rx_data_pool),
|
||||
HCI_RX_DATA_BLOCK_SIZE);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
hci_driver_uart_dma_deinit();
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
hci_driver_uart_dma_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin)
|
||||
{
|
||||
return hci_driver_uart_pin_update(tx_pin, rx_pin, cts_pin, rts_pin);
|
||||
}
|
||||
|
||||
|
||||
hci_driver_ops_t hci_driver_uart_dma_ops = {
|
||||
.hci_driver_tx = hci_driver_uart_dma_tx,
|
||||
.hci_driver_init = hci_driver_uart_dma_init,
|
||||
.hci_driver_deinit = hci_driver_uart_dma_deinit,
|
||||
};
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "esp_hci_driver.h"
|
||||
#include "esp_hci_internal.h"
|
||||
|
||||
typedef struct {
|
||||
hci_driver_forward_fn *forward_cb;
|
||||
hci_driver_host_recv_fn *host_recv_cb;
|
||||
} hci_driver_vhci_env_t;
|
||||
|
||||
static hci_driver_vhci_env_t s_hci_driver_vhci_env;
|
||||
|
||||
static int
|
||||
hci_driver_vhci_host_recv(hci_driver_data_type_t type, uint8_t *data, uint16_t len)
|
||||
{
|
||||
static hci_driver_host_recv_fn *host_recv_cb;
|
||||
|
||||
host_recv_cb = s_hci_driver_vhci_env.host_recv_cb;
|
||||
if (host_recv_cb) {
|
||||
return host_recv_cb(type, data, len);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
|
||||
hci_driver_direction_t dir)
|
||||
{
|
||||
#if 1
|
||||
hci_driver_packet_t *pkt;
|
||||
|
||||
if (dir == HCI_DRIVER_DIR_BTDMC2H) {
|
||||
uint8_t *hci_evt = r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD);
|
||||
assert(hci_evt);
|
||||
pkt = (hci_driver_packet_t *)data;
|
||||
memcpy(hci_evt, pkt->data, length);
|
||||
btdm_hci_trans_buf_free(pkt);
|
||||
data = hci_evt;
|
||||
}
|
||||
#endif
|
||||
return hci_driver_vhci_host_recv(data_type, data, length);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_init(hci_driver_forward_fn *cb)
|
||||
{
|
||||
s_hci_driver_vhci_env.forward_cb = cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hci_driver_vhci_deinit(void)
|
||||
{
|
||||
memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t));
|
||||
}
|
||||
|
||||
hci_driver_ops_t hci_driver_vhci_ops = {
|
||||
.hci_driver_tx = hci_driver_vhci_tx,
|
||||
.hci_driver_init = hci_driver_vhci_init,
|
||||
.hci_driver_deinit = hci_driver_vhci_deinit,
|
||||
};
|
||||
|
||||
/* Special APIs used by host to send message. */
|
||||
int
|
||||
hci_driver_host_cmd_tx(uint8_t *data, uint32_t length)
|
||||
{
|
||||
#if 0
|
||||
hci_driver_packet_t *pkt = NULL;
|
||||
uint16_t pkt_len;
|
||||
|
||||
pkt_len = data[2] + 3;
|
||||
pkt = btdm_hci_trans_buf_alloc(HCI_DRIVER_TYPE_CMD, 0);
|
||||
assert(pkt);
|
||||
pkt->type = HCI_DRIVER_TYPE_CMD;
|
||||
pkt->length = pkt_len;
|
||||
memcpy(pkt->data, &data[0], pkt_len);
|
||||
r_ble_hci_trans_buf_free(data);
|
||||
return s_hci_driver_vhci_env.forward_cb(HCI_DRIVER_TYPE_CMD, (uint8_t *)pkt, pkt_len, HCI_DRIVER_DIR_H2C, HCI_DRIVER_CMD);
|
||||
#else
|
||||
return s_hci_driver_vhci_env.forward_cb(HCI_DRIVER_TYPE_CMD, data, length, HCI_DRIVER_DIR_H2C, HCI_DRIVER_CMD);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
hci_driver_host_acl_tx(uint8_t *data, uint32_t length)
|
||||
{
|
||||
return s_hci_driver_vhci_env.forward_cb(HCI_DRIVER_TYPE_ACL, data, length, HCI_DRIVER_DIR_H2C, HCI_DRIVER_LE_ACL);
|
||||
}
|
||||
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
int
|
||||
hci_driver_host_iso_tx(uint8_t *data, uint32_t length)
|
||||
{
|
||||
return s_hci_driver_vhci_env.forward_cb(HCI_DRIVER_TYPE_ISO, data, length, HCI_DRIVER_DIR_H2C, HCI_DRIVER_LE_ISO);
|
||||
}
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
|
||||
int
|
||||
hci_driver_host_callback_register(hci_driver_host_recv_fn *callback)
|
||||
{
|
||||
s_hci_driver_vhci_env.host_recv_cb = callback;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "ble_mbuf.h"
|
||||
#include "esp_hci_driver.h"
|
||||
#include "esp_hci_internal.h"
|
||||
#include "esp_bt.h"
|
||||
|
||||
typedef struct {
|
||||
hci_driver_forward_fn *forward_cb;
|
||||
const esp_vhci_host_callback_t *host_recv_cb;
|
||||
} hci_driver_vhci_env_t;
|
||||
|
||||
static hci_driver_vhci_env_t s_hci_driver_vhci_env;
|
||||
|
||||
|
||||
#if 0
|
||||
typedef int ble_host_rx_iso_data_fn(uint8_t *data, uint16_t len);
|
||||
static ble_host_rx_iso_data_fn *ble_host_iso_rx_cb = NULL;
|
||||
|
||||
void ble_hci_register_rx_iso_data_cb(void *cb)
|
||||
{
|
||||
/* If the iso rx cb is already registered, we will give
|
||||
* a warning log here, and the cb will still be updated.
|
||||
*/
|
||||
if (ble_host_iso_rx_cb) {
|
||||
printf("iso rx cb %p already registered\n", ble_host_iso_rx_cb);
|
||||
}
|
||||
|
||||
ble_host_iso_rx_cb = cb;
|
||||
}
|
||||
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
|
||||
static int
|
||||
hci_driver_vhci_host_recv_with_type(uint8_t data_type, uint8_t *data, uint16_t len)
|
||||
{
|
||||
static const esp_vhci_host_callback_t *host_recv_cb;
|
||||
|
||||
host_recv_cb = s_hci_driver_vhci_env.host_recv_cb;
|
||||
if (!host_recv_cb) {
|
||||
return -1;
|
||||
}
|
||||
#if 0
|
||||
if (data_type == HCI_DRIVER_TYPE_ISO) {
|
||||
if (ble_host_iso_rx_cb) {
|
||||
return ble_host_iso_rx_cb(data, len);
|
||||
}
|
||||
} else
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
{
|
||||
if (host_recv_cb->notify_host_recv) {
|
||||
return host_recv_cb->notify_host_recv(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
hci_driver_vhci_host_send_available(void)
|
||||
{
|
||||
static const esp_vhci_host_callback_t *host_recv_cb;
|
||||
|
||||
host_recv_cb = s_hci_driver_vhci_env.host_recv_cb;
|
||||
if (host_recv_cb && host_recv_cb->notify_host_send_available) {
|
||||
host_recv_cb->notify_host_send_available();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, hci_driver_direction_t dir)
|
||||
{
|
||||
int rc = 0;
|
||||
uint16_t buf_len = length + 1;;
|
||||
uint8_t *buf = NULL;
|
||||
struct ble_mbuf *om;
|
||||
uint8_t old_value = 0;
|
||||
hci_driver_packet_t *pkt = (hci_driver_packet_t *)data;
|
||||
|
||||
if (data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
if (dir == HCI_DRIVER_DIR_LEC2H) {
|
||||
om = (struct ble_mbuf *)data;
|
||||
buf = malloc(buf_len);
|
||||
/* TODO: If there is no memory, should handle it in the controller. */
|
||||
assert(buf);
|
||||
buf[0] = HCI_DRIVER_TYPE_ACL;
|
||||
ble_mbuf_copydata(om, 0, length, &buf[1]);
|
||||
ble_mbuf_free_chain(om);
|
||||
rc = hci_driver_vhci_host_recv_with_type(data_type, buf, buf_len);
|
||||
free(buf);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
if (dir == HCI_DRIVER_DIR_BREDRC2H) {
|
||||
buf = pkt->data - 1;
|
||||
old_value = *buf;
|
||||
*buf = data_type;
|
||||
rc = hci_driver_vhci_host_recv_with_type(data_type, buf, buf_len);
|
||||
*buf = old_value;
|
||||
if (rc >= 0) {
|
||||
bredr_hci_trans_acl_tx_done(pkt);
|
||||
bredr_hci_trans_acl_free(pkt);
|
||||
}
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
} else if (data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
/* TODO: If there is no memory, should handle it in the controller. */
|
||||
if (dir == HCI_DRIVER_DIR_LEC2H) {
|
||||
buf = malloc(buf_len);
|
||||
assert(buf != NULL);
|
||||
buf[0] = HCI_DRIVER_TYPE_EVT;
|
||||
memcpy(&buf[1], data, length);
|
||||
rc = hci_driver_vhci_host_recv_with_type(data_type, buf, buf_len);
|
||||
r_ble_hci_trans_buf_free(data);
|
||||
free(buf);
|
||||
}
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else if (dir == HCI_DRIVER_DIR_BREDRC2H) {
|
||||
buf = pkt->data - 1;
|
||||
old_value = *buf;
|
||||
*buf = data_type;
|
||||
rc = hci_driver_vhci_host_recv_with_type(data_type, buf, buf_len);
|
||||
*buf = old_value;
|
||||
if (rc >= 0) {
|
||||
bredr_hci_trans_evt_tx_done((hci_driver_packet_t *)data);
|
||||
bredr_hci_trans_evt_free((hci_driver_packet_t *)data);
|
||||
}
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
buf = pkt->data - 1;
|
||||
old_value = *buf;
|
||||
*buf = data_type;
|
||||
rc = hci_driver_vhci_host_recv_with_type(data_type, buf, buf_len);
|
||||
*buf = old_value;
|
||||
btdm_hci_trans_buf_free(pkt);
|
||||
}
|
||||
|
||||
}
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
else if (data_type == HCI_DRIVER_TYPE_ISO) {
|
||||
rc = hci_driver_vhci_host_recv_with_type(data_type, data, length);
|
||||
free(data);
|
||||
}
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else if (data_type == HCI_DRIVER_TYPE_SYNC) {
|
||||
/* SCO/ESCO data */
|
||||
buf = pkt->data - 1;
|
||||
old_value = *buf;
|
||||
*buf = data_type;
|
||||
rc = hci_driver_vhci_host_recv_with_type(data_type, buf, buf_len);
|
||||
*buf = old_value;
|
||||
if (rc >= 0) {
|
||||
bredr_hci_trans_sync_tx_done(pkt);
|
||||
bredr_hci_trans_sync_free(pkt);
|
||||
}
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length)
|
||||
{
|
||||
struct ble_mbuf *om;
|
||||
uint16_t pkt_len;
|
||||
uint16_t conn_handle;
|
||||
hci_driver_packet_t *pkt = NULL;
|
||||
uint8_t data_source = 0xFF;
|
||||
|
||||
pkt_len = length - 1;
|
||||
switch (data_type) {
|
||||
case HCI_DRIVER_TYPE_CMD:
|
||||
pkt = btdm_hci_trans_buf_alloc(data_type, 0);
|
||||
assert(pkt);
|
||||
//TODO: check if pkt_len is not larger than the allocated one.
|
||||
memcpy(pkt->data, &data[1], pkt_len);
|
||||
data = (uint8_t *)pkt;
|
||||
break;
|
||||
|
||||
case HCI_DRIVER_TYPE_ACL:
|
||||
conn_handle = btdm_get_le16(&data[1]) & HCI_INTERNAL_CONN_MASK;
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
if (HCI_INTERNAL_CONN_IS_BLE(conn_handle)) {
|
||||
om = ble_msys_get_pkthdr(pkt_len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE);
|
||||
assert(om);
|
||||
assert(ble_mbuf_append(om, &data[1], length - 1) == 0);
|
||||
data = (uint8_t *)om;
|
||||
data_source = HCI_DRIVER_LE_ACL;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
if (HCI_INTERNAL_CONN_IS_BREDR(conn_handle)) {
|
||||
pkt = btdm_hci_trans_buf_alloc(data_type, conn_handle);
|
||||
assert(pkt);
|
||||
memcpy(pkt->data, &data[1], pkt_len);
|
||||
data = (uint8_t *)pkt;
|
||||
data_source = HCI_DRIVER_BREDR_ACL;
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
break;
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
case HCI_DRIVER_TYPE_SYNC:
|
||||
conn_handle = btdm_get_le16(&data[1]) & HCI_INTERNAL_CONN_MASK;
|
||||
pkt = btdm_hci_trans_buf_alloc(data_type, conn_handle);
|
||||
assert(pkt);
|
||||
memcpy(pkt->data, &data[1], pkt_len);
|
||||
data = (uint8_t *)pkt;
|
||||
data_source = HCI_DRIVER_BREDR_SYNC;
|
||||
break;
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
case HCI_DRIVER_TYPE_ISO:
|
||||
data_source = HCI_DRIVER_LE_ISO;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pkt) {
|
||||
pkt->length = pkt_len;
|
||||
}
|
||||
|
||||
return s_hci_driver_vhci_env.forward_cb(data_type, data, pkt_len, HCI_DRIVER_DIR_H2C, data_source);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
|
||||
hci_driver_direction_t dir)
|
||||
{
|
||||
int rc;
|
||||
if (dir == HCI_DRIVER_DIR_H2C) {
|
||||
rc = hci_driver_vhci_host_tx(data_type, data, length);
|
||||
} else {
|
||||
rc = hci_driver_vhci_controller_tx(data_type, data, length, dir);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_init(hci_driver_forward_fn *cb)
|
||||
{
|
||||
memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t));
|
||||
s_hci_driver_vhci_env.forward_cb = cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hci_driver_vhci_deinit(void)
|
||||
{
|
||||
memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t));
|
||||
}
|
||||
|
||||
hci_driver_ops_t hci_driver_vhci_ops = {
|
||||
.hci_driver_tx = hci_driver_vhci_tx,
|
||||
.hci_driver_init = hci_driver_vhci_init,
|
||||
.hci_driver_deinit = hci_driver_vhci_deinit,
|
||||
};
|
||||
|
||||
/* Special APIs declared in the `esp_bt.h'. */
|
||||
esp_err_t
|
||||
esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
|
||||
{
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
s_hci_driver_vhci_env.host_recv_cb = callback;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void
|
||||
esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
|
||||
{
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
hci_driver_vhci_tx(data[0], data, len, HCI_DRIVER_DIR_H2C);
|
||||
}
|
||||
|
||||
bool
|
||||
esp_vhci_host_check_send_available(void)
|
||||
{
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "os/os_mbuf.h"
|
||||
#include "esp_hci_transport.h"
|
||||
#include "esp_hci_internal.h"
|
||||
#include "esp_hci_driver.h"
|
||||
|
||||
typedef struct {
|
||||
hci_driver_forward_fn *forward_cb;
|
||||
} hci_driver_vhci_env_t;
|
||||
|
||||
static hci_driver_vhci_env_t s_hci_driver_vhci_env;
|
||||
|
||||
static int
|
||||
hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length)
|
||||
{
|
||||
int rc;
|
||||
uint16_t len = 0;
|
||||
uint8_t *buf = NULL;
|
||||
struct os_mbuf *om;
|
||||
|
||||
if (data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
/* The ACL data will be packaged as structure of `os_mbuf`.
|
||||
* 1. Allocate a buffer suitable for the host. Use the following method to copy the data
|
||||
* from the os_mbuf to the newly allocated memory.
|
||||
* ```c
|
||||
* buf = malloc(length);
|
||||
* os_mbuf_copydata(om, 0, length, buf);
|
||||
* ```
|
||||
* 2. Free the controller's os_mbuf
|
||||
* ```c
|
||||
* os_mbuf_free_chain(om);
|
||||
* ```
|
||||
*/
|
||||
} else if (data_type == HCI_DRIVER_TYPE_EVT) {
|
||||
/* The event data will be packaged as an array.
|
||||
* 1. Allocate a buffer suitable for the host. Use the following method to copy the data
|
||||
* from the controller buffer to the newly allocated memory.
|
||||
* ```c
|
||||
* buf = malloc(length);
|
||||
* memcpy(buf, data, length);
|
||||
* ```
|
||||
* 2. Free the controller's buffer.
|
||||
* ```c
|
||||
* r_ble_hci_trans_buf_free(data);
|
||||
* ```
|
||||
*/
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
rc = s_hci_driver_vhci_env.forward_cb(data_type, buf, len, HCI_DRIVER_DIR_C2H);
|
||||
free(buf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length)
|
||||
{
|
||||
uint8_t *hci_data;
|
||||
struct os_mbuf *om;
|
||||
|
||||
if (data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
/* The ACL data needs to be packaged as structure of `os_mbuf`.
|
||||
* 1. Get an os_mbuf in the following way.
|
||||
* ```c
|
||||
* om = os_msys_get_pkthdr(length, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE);
|
||||
* ```
|
||||
* 2. Copy the host's data into this os_mbuf using the following method.
|
||||
* ```c
|
||||
* assert(os_mbuf_append(om, data, length) == 0);
|
||||
* hci_data = (uint8_t *)om;
|
||||
* ```
|
||||
* 3. Free the host's buffer if needed.
|
||||
*/
|
||||
} else if (data_type == HCI_DRIVER_TYPE_CMD) {
|
||||
/* The COMMAND data needs to be packaged as an array.
|
||||
* 1. Get a command buffer from the controller.
|
||||
* ```c
|
||||
* hci_data = r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD);
|
||||
* ```
|
||||
* 2. Copy the host's data into this buffer.
|
||||
* ```c
|
||||
* memcpy(hci_data, data, length);
|
||||
* ```
|
||||
* 3. Free the host's buffer if needed.
|
||||
*/
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return s_hci_driver_vhci_env.forward_cb(data_type, hci_data, length, HCI_DRIVER_DIR_H2C);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
|
||||
hci_driver_direction_t dir)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (dir == HCI_DRIVER_DIR_C2H) {
|
||||
rc = hci_driver_vhci_controller_tx(data_type, data, length);
|
||||
} else {
|
||||
rc = hci_driver_vhci_host_tx(data_type, data, length);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_driver_vhci_init(hci_driver_forward_fn *cb)
|
||||
{
|
||||
memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t));
|
||||
s_hci_driver_vhci_env.forward_cb = cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hci_driver_vhci_deinit(void)
|
||||
{
|
||||
memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t));
|
||||
}
|
||||
|
||||
hci_driver_ops_t hci_driver_vhci_ops = {
|
||||
.hci_driver_tx = hci_driver_vhci_tx,
|
||||
.hci_driver_init = hci_driver_vhci_init,
|
||||
.hci_driver_deinit = hci_driver_vhci_deinit,
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* 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 _HCI_H4_H_
|
||||
#define _HCI_H4_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_hci_internal.h"
|
||||
|
||||
#define HCI_H4_NONE 0x00
|
||||
#define HCI_H4_CMD 0x01
|
||||
#define HCI_H4_ACL 0x02
|
||||
#define HCI_H4_SYNC 0x03
|
||||
#define HCI_H4_EVT 0x04
|
||||
#define HCI_H4_ISO 0x05
|
||||
|
||||
typedef hci_driver_packet_t *(hci_h4_alloc_cmd)(void);
|
||||
typedef void *(hci_h4_alloc_evt)(int);
|
||||
typedef struct ble_mbuf *(hci_h4_alloc_acl)(void);
|
||||
typedef void *(hci_h4_alloc_iso)(uint32_t);
|
||||
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
typedef hci_driver_packet_t *(hci_h4_alloc_sync)(uint16_t);
|
||||
typedef hci_driver_packet_t *(hci_h4_alloc_bredr_acl)(uint16_t);
|
||||
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
struct hci_h4_allocators {
|
||||
hci_h4_alloc_cmd *cmd;
|
||||
hci_h4_alloc_acl *acl;
|
||||
hci_h4_alloc_evt *evt;
|
||||
hci_h4_alloc_iso *iso;
|
||||
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
hci_h4_alloc_sync *sync;
|
||||
hci_h4_alloc_bredr_acl *bredr_acl;
|
||||
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
};
|
||||
|
||||
extern const struct hci_h4_allocators hci_h4_allocs_from_ll;
|
||||
extern const struct hci_h4_allocators hci_h4_allocs_from_hs;
|
||||
|
||||
typedef void (hci_h4_free_cmd)(void * ptr);
|
||||
typedef void (hci_h4_free_evt)(void * ptr);
|
||||
typedef int (hci_h4_free_acl)(struct ble_mbuf *om);
|
||||
typedef void (hci_h4_free_iso)(void *ptr);
|
||||
typedef void (hci_h4_free_le_evt)(uint8_t *buf);
|
||||
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
typedef void (hci_h4_free_sync)(void *ptr);
|
||||
typedef void (hci_h4_free_bredr_acl)(void *ptr);
|
||||
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
struct hci_h4_frees {
|
||||
hci_h4_free_cmd *cmd;
|
||||
hci_h4_free_acl *acl;
|
||||
hci_h4_free_evt *evt;
|
||||
hci_h4_free_iso *iso;
|
||||
hci_h4_free_le_evt *le_evt;
|
||||
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
hci_h4_free_sync *sync;
|
||||
hci_h4_free_bredr_acl *bredr_acl;
|
||||
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
};
|
||||
|
||||
typedef int (hci_h4_frame_cb)(uint8_t pkt_type, void *data, int len, uint8_t data_source);
|
||||
|
||||
struct hci_h4_sm {
|
||||
uint8_t state;
|
||||
uint8_t pkt_type;
|
||||
uint8_t min_len;
|
||||
uint16_t len;
|
||||
uint16_t exp_len;
|
||||
uint8_t hdr[4];
|
||||
union {
|
||||
uint8_t *buf;
|
||||
struct ble_mbuf *om;
|
||||
hci_driver_packet_t *pkt;
|
||||
};
|
||||
|
||||
const struct hci_h4_allocators *allocs;
|
||||
const struct hci_h4_frees *frees;
|
||||
hci_h4_frame_cb *frame_cb;
|
||||
};
|
||||
|
||||
void hci_h4_sm_init(struct hci_h4_sm *h4sm,
|
||||
const struct hci_h4_allocators *allocs,
|
||||
const struct hci_h4_frees *frees,
|
||||
hci_h4_frame_cb *frame_cb);
|
||||
|
||||
int hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len);
|
||||
|
||||
#endif /* _HCI_H4_H_ */
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _H_HCI_DRIVER_MEM_
|
||||
#define _H_HCI_DRIVER_MEM_
|
||||
#include <stdint.h>
|
||||
#include "esp_hci_internal.h"
|
||||
|
||||
hci_driver_packet_t *hci_driver_mem_cmd_alloc(void);
|
||||
|
||||
void *hci_driver_mem_evt_alloc(int discardable);
|
||||
|
||||
struct ble_mbuf *hci_driver_mem_acl_alloc(void);
|
||||
|
||||
struct ble_mbuf *hci_driver_mem_acl_len_alloc(uint32_t len);
|
||||
|
||||
void *hci_driver_mem_iso_alloc(uint32_t len);
|
||||
|
||||
struct ble_mbuf *hci_driver_mem_iso_len_alloc(uint32_t len);
|
||||
|
||||
extern const struct hci_h4_allocators s_hci_driver_mem_alloc;
|
||||
extern const struct hci_h4_frees s_hci_driver_mem_free;
|
||||
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
hci_driver_packet_t *hci_driver_mem_bredr_acl_alloc(uint16_t len);
|
||||
|
||||
hci_driver_packet_t *hci_driver_mem_sync_alloc(uint16_t len);
|
||||
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
|
||||
#endif // _H_HCI_DRIVER_MEM_
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _H_HCI_DRIVER_UTIL_
|
||||
#define _H_HCI_DRIVER_UTIL_
|
||||
#include <stdint.h>
|
||||
|
||||
int hci_driver_util_init(void);
|
||||
|
||||
void hci_driver_util_deinit(void);
|
||||
|
||||
int hci_driver_util_tx_list_enqueue(hci_driver_data_type_t type, uint8_t *data, uint32_t len, hci_driver_data_source_t data_source);
|
||||
|
||||
uint32_t hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_frame);
|
||||
|
||||
void hci_driver_util_assert_check(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2);
|
||||
#define HCI_TRANS_ASSERT(cond, p1, p2) \
|
||||
if (!(cond)) { \
|
||||
hci_driver_util_assert_check(__LINE__, __func__, p1, p2); \
|
||||
}
|
||||
#endif // _H_HCI_DRIVER_UTIL_
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef H_ESP_HCI_DRIVER_
|
||||
#define H_ESP_HCI_DRIVER_
|
||||
#include <stdint.h>
|
||||
#include "queue.h"
|
||||
#include "esp_bt.h"
|
||||
#include "esp_hci_transport.h"
|
||||
/**
|
||||
* @brief Enumeration of HCI transport direction.
|
||||
*/
|
||||
typedef enum {
|
||||
HCI_DRIVER_DIR_LEC2H = 0x00, ///< From controller to host.
|
||||
HCI_DRIVER_DIR_BREDRC2H,
|
||||
HCI_DRIVER_DIR_BTDMC2H,
|
||||
HCI_DRIVER_DIR_H2C, ///< From host to controller.
|
||||
} hci_driver_direction_t;
|
||||
|
||||
typedef enum {
|
||||
HCI_DRIVER_TYPE_CMD = 0x01, ///< HCI Command Indicator.
|
||||
HCI_DRIVER_TYPE_ACL, ///< HCI ACL Data Indicator.
|
||||
HCI_DRIVER_TYPE_SYNC, ///< HCI Synchronous Data Indicator.
|
||||
HCI_DRIVER_TYPE_EVT, ///< HCI Event Indicator.
|
||||
HCI_DRIVER_TYPE_ISO, ///< HCI Isochronous Data Indicator.
|
||||
HCI_DRIVER_TYPE_VENDOR, ///< HCI Vendor data Indicator.
|
||||
} hci_driver_data_type_t;
|
||||
|
||||
typedef enum {
|
||||
HCI_DRIVER_CMD = 0x00,
|
||||
HCI_DRIVER_LE_EVT,
|
||||
HCI_DRIVER_BREDR_EVT,
|
||||
HCI_DRIVER_BTDM_EVT,
|
||||
HCI_DRIVER_LE_ACL,
|
||||
HCI_DRIVER_LE_ISO,
|
||||
HCI_DRIVER_BREDR_ACL,
|
||||
HCI_DRIVER_BREDR_SYNC,
|
||||
} hci_driver_data_source_t;
|
||||
|
||||
struct hci_driver_packet
|
||||
{
|
||||
STAILQ_ENTRY(hci_driver_packet) next;
|
||||
uint8_t *data;
|
||||
uint16_t length;
|
||||
uint8_t flags;
|
||||
uint8_t type;
|
||||
};
|
||||
typedef struct hci_driver_packet hci_driver_packet_t;
|
||||
|
||||
typedef int hci_driver_forward_fn(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
|
||||
hci_driver_direction_t dir, uint8_t data_source);
|
||||
|
||||
#define HCI_DRIVER_D2P(data) ((void *)((uint32_t)data - sizeof(hci_driver_packet_t)))
|
||||
|
||||
/**
|
||||
* @brief Structure of HCI driver operations.
|
||||
*/
|
||||
typedef struct hci_driver_ops {
|
||||
int (*hci_driver_tx)(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
|
||||
hci_driver_direction_t dir);
|
||||
int (*hci_driver_init)(hci_driver_forward_fn *cb);
|
||||
void (*hci_driver_deinit)(void);
|
||||
} hci_driver_ops_t;
|
||||
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
typedef int hci_driver_host_recv_fn(hci_driver_data_type_t type, uint8_t *data, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief Set the host's HCI callback which will be invoked when receiving ACL/Events from controller.
|
||||
* @param callback hci_driver_host_recv_fn type variable
|
||||
* @return int 0 on success, non-zero error code on failure.
|
||||
*/
|
||||
int hci_driver_host_callback_register(hci_driver_host_recv_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Called to send HCI commands form host to controller.
|
||||
* @param data Point to the commands data
|
||||
* @param length Length of data
|
||||
* @return int 0 on success, non-zero error code on failure.
|
||||
*/
|
||||
int hci_driver_host_cmd_tx(uint8_t *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called to send HCI ACL form host to controller.
|
||||
* @param data Point to the ACL data
|
||||
* @param length Length of data
|
||||
* @return int 0 on success, non-zero error code on failure.
|
||||
*/
|
||||
int hci_driver_host_acl_tx(uint8_t *data, uint32_t length);
|
||||
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
/**
|
||||
* @brief Called to send HCI ISO daata form host to controller.
|
||||
* @param data Point to the ISO data
|
||||
* @param length Length of data
|
||||
* @return int 0 on success, non-zero error code on failure.
|
||||
*/
|
||||
int hci_driver_host_iso_tx(uint8_t *data, uint32_t length);
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
#endif // CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
#if UC_BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
extern hci_driver_ops_t hci_driver_vhci_ops;
|
||||
#endif // UC_BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
|
||||
#if UC_BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
extern hci_driver_ops_t hci_driver_uart_ops;
|
||||
#if UC_BT_CTRL_UART_HCI_DMA_MODE
|
||||
extern hci_driver_ops_t hci_driver_uart_dma_ops;
|
||||
#endif // UC_BT_CTRL_UART_HCI_DMA_MODE
|
||||
#endif // UC_BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
|
||||
#endif // H_ESP_HCI_DRIVER_
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef H_ESP_HCI_INTERNAL_
|
||||
#define H_ESP_HCI_INTERNAL_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include "esp_hci_driver.h"
|
||||
#include "ble_mbuf.h"
|
||||
|
||||
|
||||
/* The leadingspace in user info header for ACL data */
|
||||
#define ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE (4)
|
||||
|
||||
#define ESP_HCI_INTERNAL_BUF_CMD (3)
|
||||
|
||||
/**
|
||||
* @brief Define the HCI hardware error code for synchronization loss.
|
||||
* This error code is used to indicate a loss of synchronization between the controller and the host.
|
||||
*/
|
||||
#define ESP_HCI_SYNC_LOSS_ERR (0x1)
|
||||
/** Callback function types; executed when HCI packets are received. */
|
||||
typedef int esp_hci_internal_rx_cmd_fn(uint8_t *cmd, void *arg);
|
||||
typedef int esp_hci_internal_rx_acl_fn(struct ble_mbuf *om, void *arg);
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
typedef int esp_hci_internal_rx_iso_fn(const uint8_t *data, uint16_t len, void *arg);
|
||||
/**
|
||||
* @brief Configure the ISO data receive callback for BLE HCI transport.
|
||||
*
|
||||
* @param iso_cb The callback to execute upon receiving ISO data.
|
||||
*
|
||||
* @param iso_arg Optional argument to pass to the ISO callback.
|
||||
*/
|
||||
void r_ble_iso_trans_cfg_hs(esp_hci_internal_rx_iso_fn *iso_cb, void *iso_arg);
|
||||
|
||||
#define ble_iso_trans_cfg_hs r_ble_iso_trans_cfg_hs
|
||||
/**
|
||||
* @brief Transmit ISO (Isochronous) data over BLE HCItransport.
|
||||
*
|
||||
* @param data Pointer to the ISO data buffer to be transmitted.
|
||||
* @param length Length of the ISO data in bytes.
|
||||
* @param arg Optional user-defined argument, passed through
|
||||
* the transport layer and may be used by the underlying driver or callback.
|
||||
*
|
||||
* @return 0 on success, or a non-zero error code on failure.
|
||||
*/
|
||||
int r_ble_hci_trans_hs_iso_tx(const uint8_t *data, uint16_t length, void *arg);
|
||||
|
||||
#define ble_hci_trans_hs_iso_tx r_ble_hci_trans_hs_iso_tx
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
/**
|
||||
* Configures the HCI transport to operate with a host. The transport will
|
||||
* execute specified callbacks upon receiving HCI packets from the controller.
|
||||
*
|
||||
* @param evt_cb The callback to execute upon receiving an HCI
|
||||
* event.
|
||||
* @param evt_arg Optional argument to pass to the event
|
||||
* callback.
|
||||
* @param acl_cb The callback to execute upon receiving ACL
|
||||
* data.
|
||||
* @param acl_arg Optional argument to pass to the ACL
|
||||
* callback.
|
||||
*/
|
||||
void r_ble_hci_trans_cfg_hs(esp_hci_internal_rx_cmd_fn *evt_cb, void *evt_arg,
|
||||
esp_hci_internal_rx_acl_fn *acl_cb, void *acl_arg);
|
||||
/**
|
||||
* Sends ACL data from host to controller.
|
||||
*
|
||||
* @param om The ACL data packet to send.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* A BLE_ERR_[...] error code on failure.
|
||||
*/
|
||||
int r_ble_hci_trans_hs_acl_tx(struct ble_mbuf *om);
|
||||
|
||||
/**
|
||||
* Sends an HCI command from the host to the controller.
|
||||
*
|
||||
* @param cmd The HCI command to send. This buffer must be
|
||||
* allocated via ble_hci_trans_buf_alloc().
|
||||
*
|
||||
* @return 0 on success;
|
||||
* A BLE_ERR_[...] error code on failure.
|
||||
*/
|
||||
int r_ble_hci_trans_hs_cmd_tx(uint8_t *cmd);
|
||||
|
||||
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
int ble_hci_trans_hs_iso_tx(const uint8_t *data, uint16_t length, void *arg);
|
||||
#endif /* CONFIG_BT_LE_ISO_SUPPORT */
|
||||
|
||||
/**
|
||||
* Allocates a flat buffer of the specified type.
|
||||
*
|
||||
* @param type The type of buffer to allocate; one of the
|
||||
* BLE_HCI_TRANS_BUF_[...] constants.
|
||||
*
|
||||
* @return The allocated buffer on success;
|
||||
* NULL on buffer exhaustion.
|
||||
*/
|
||||
uint8_t * r_ble_hci_trans_buf_alloc(int type);
|
||||
|
||||
/**
|
||||
* Frees the specified flat buffer. The buffer must have been allocated via
|
||||
* ble_hci_trans_buf_alloc().
|
||||
*
|
||||
* @param buf The buffer to free.
|
||||
*/
|
||||
void r_ble_hci_trans_buf_free(uint8_t *buf);
|
||||
|
||||
/**
|
||||
* @brief Handle an HCI hardware error event.
|
||||
* This function processes a hardware error code and generates the appropriate HCI hardware error event.
|
||||
*
|
||||
* @param hw_err The hardware error code that needs to be processed. The specific meaning of the error code
|
||||
* depends on the implementation and the hardware.
|
||||
*
|
||||
* @return int Returns 0 on success, or a non-zero error code on failure.
|
||||
*
|
||||
* @note This function should be called whenever a hardware error is detected in the HCI Layer.
|
||||
*/
|
||||
int r_ble_ll_hci_ev_hw_err(uint8_t hw_err);
|
||||
|
||||
//!TODO: Check what this API is used for
|
||||
int r_ble_hci_trans_reset(void);
|
||||
|
||||
//!TODO: Should we initialize the hci layer in IDF ?
|
||||
void esp_ble_hci_trans_init(uint8_t);
|
||||
|
||||
// ********************************************************************************************
|
||||
// btdm common
|
||||
// ********************************************************************************************
|
||||
|
||||
typedef int (*btdm_hci_trans_tx_func_t)(hci_driver_packet_t *pkt);
|
||||
|
||||
#define HCI_INTERNAL_CONN_MASK (0x0fff)
|
||||
#define HCI_INTERNAL_CONN_IS_BLE(conn_handle) (!(conn_handle & 0x0800))
|
||||
#define HCI_INTERNAL_CONN_IS_BREDR(conn_handle) (conn_handle & 0x0800)
|
||||
#define HCI_INTERNAL_CONN_IS_BREDR_ACL(conn_handle) ((conn_handle & 0x0800) && (conn_handle & 0x000f))
|
||||
#define HCI_INTERNAL_CONN_IS_BREDR_SYNC(conn_handle) ((conn_handle & 0x0800) && (conn_handle & 0x00f0))
|
||||
|
||||
int r_btdm_hci_trans_register_tx(btdm_hci_trans_tx_func_t *tx_func, bool async);
|
||||
|
||||
int r_btdm_hci_trans_rx(hci_driver_packet_t *pkt);
|
||||
|
||||
hci_driver_packet_t *r_btdm_hci_trans_buf_alloc(uint8_t type, uint16_t conn_handle);
|
||||
void r_btdm_hci_trans_buf_free(hci_driver_packet_t *pkt);
|
||||
uint16_t r_btdm_get_le16(const void *buf);
|
||||
|
||||
#define btdm_hci_trans_buf_alloc r_btdm_hci_trans_buf_alloc
|
||||
#define btdm_hci_trans_buf_free r_btdm_hci_trans_buf_free
|
||||
#define btdm_get_le16 r_btdm_get_le16
|
||||
#define btdm_hci_trans_register_tx r_btdm_hci_trans_register_tx
|
||||
#define btdm_hci_trans_rx r_btdm_hci_trans_rx
|
||||
|
||||
void btdm_hci_pkt_flag_ble_setf(hci_driver_packet_t *pkt, uint8_t is_ble);
|
||||
uint8_t btdm_hci_pkt_flag_ble_getf(hci_driver_packet_t *pkt);
|
||||
uint8_t btdm_hci_pkt_flag_bredr_getf(hci_driver_packet_t *pkt);
|
||||
uint8_t btdm_hci_pkt_flag_cmdpool_getf(hci_driver_packet_t *pkt);
|
||||
|
||||
// ********************************************************************************************
|
||||
// BREDR
|
||||
// ********************************************************************************************
|
||||
|
||||
int bredr_hci_trans_acl_rx(hci_driver_packet_t *pkt);
|
||||
int bredr_hci_trans_sync_rx(hci_driver_packet_t *pkt);
|
||||
void bredr_hci_trans_register_tx(btdm_hci_trans_tx_func_t *acl_tx_func,
|
||||
btdm_hci_trans_tx_func_t *sync_tx_func,
|
||||
btdm_hci_trans_tx_func_t *evt_tx_func);
|
||||
void bredr_hci_trans_acl_tx_done(hci_driver_packet_t *pkt);
|
||||
void bredr_hci_trans_sync_tx_done(hci_driver_packet_t *pkt);
|
||||
void bredr_hci_trans_evt_tx_done(hci_driver_packet_t *pkt);
|
||||
int bredr_hci_trans_acl_free(hci_driver_packet_t *pkt);
|
||||
int bredr_hci_trans_sync_free(hci_driver_packet_t *pkt);
|
||||
int bredr_hci_trans_evt_free(hci_driver_packet_t *pkt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* H_ESP_HCI_INTERNAL_ */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef H_ESP_HCI_TRANSPORT_
|
||||
#define H_ESP_HCI_TRANSPORT_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include "ble_mbuf.h"
|
||||
#include "esp_hci_driver.h"
|
||||
|
||||
/**
|
||||
* @brief Enumeration of HCI packet indicators
|
||||
*/
|
||||
typedef enum {
|
||||
HCI_CMD_IND = 0x01, /*!< HCI Command Indicator */
|
||||
HCI_ACL_IND, /*!< HCI ACL Data Indicator */
|
||||
HCI_SYNC_IND, /*!< HCI Synchronous Data Indicator */
|
||||
HCI_EVT_IND, /*!< HCI Event Indicator */
|
||||
HCI_ISO_IND, /*!< HCI Isochronous Data Indicator */
|
||||
HCI_VENDOR_IND, /*!< HCI Vendor data Indicator */
|
||||
} hci_trans_pkt_ind_t;
|
||||
|
||||
/**
|
||||
* @brief Enumeration of HCI Transport Mode
|
||||
*/
|
||||
typedef enum {
|
||||
HCI_TRANSPORT_VHCI, /*!< VHCI Transport Mode */
|
||||
HCI_TRANSPORT_UART_NO_DMA, /*!< UART_NO_DMA Transport Mode */
|
||||
HCI_TRANSPORT_UART_UHCI, /*!< UART_UHCI Transport Mode */
|
||||
HCI_TRANSPORT_SDIO, /*!< SDIO Transport Mode */
|
||||
HCI_TRANSPORT_USB, /*!< USB Transport Mode */
|
||||
} hci_trans_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the HCI transport layer.
|
||||
* It should be called before using any other functions in the transport layer.
|
||||
*
|
||||
* @param hci_transport_mode The mode in which the HCI transport should operate.
|
||||
*
|
||||
* @return int Returns 0 on success, or a non-zero error code on failure.
|
||||
*/
|
||||
int hci_transport_init(uint8_t hci_transport_mode);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the HCI transport layer for releasing any allocated resources.
|
||||
*/
|
||||
void hci_transport_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* H_ESP_HCI_TRANSPORT_ */
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_hci_transport.h"
|
||||
#include "esp_hci_internal.h"
|
||||
#include "esp_bt.h"
|
||||
|
||||
typedef struct hci_transport_env
|
||||
{
|
||||
hci_driver_ops_t *driver_ops;
|
||||
} hci_transport_env_t;
|
||||
|
||||
static hci_transport_env_t s_hci_transport_env;
|
||||
|
||||
/* Functions for controller Rx. */
|
||||
static int
|
||||
hci_transport_controller_rx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, hci_driver_direction_t dir, uint8_t data_source)
|
||||
{
|
||||
int rc;
|
||||
hci_driver_packet_t *pkt;
|
||||
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
assert(dir == HCI_DRIVER_DIR_H2C);
|
||||
if (data_type == HCI_DRIVER_TYPE_CMD) {
|
||||
pkt = (hci_driver_packet_t *)data;
|
||||
rc = btdm_hci_trans_rx(pkt);
|
||||
} else if (data_type == HCI_DRIVER_TYPE_ACL) {
|
||||
if (data_source == HCI_DRIVER_LE_ACL) {
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
rc = r_ble_hci_trans_hs_acl_tx((struct ble_mbuf *) data);
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
} else {
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
pkt = (hci_driver_packet_t *)data;
|
||||
pkt->length = length;
|
||||
rc = bredr_hci_trans_acl_rx(pkt);
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
}
|
||||
}
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
else if (data_type == HCI_DRIVER_TYPE_ISO) {
|
||||
rc = ble_hci_trans_hs_iso_tx(data, length, NULL);
|
||||
}
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else if (data_type == HCI_DRIVER_TYPE_SYNC) {
|
||||
pkt = (hci_driver_packet_t *)data;
|
||||
pkt->length = length;
|
||||
rc = bredr_hci_trans_sync_rx(pkt);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
else {
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
/* Functions for controller Tx. */
|
||||
static int
|
||||
hci_transport_controller_le_evt_tx(uint8_t *hci_ev, void *arg)
|
||||
{
|
||||
/* TODO: In order to support dual-host mode, use legacy interfaces for ble when nimble host is enabled */
|
||||
uint32_t len;
|
||||
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
r_ble_hci_trans_buf_free(hci_ev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = hci_ev[1] + 2;
|
||||
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_EVT, hci_ev, len,
|
||||
HCI_DRIVER_DIR_LEC2H);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_transport_controller_le_acl_tx(struct ble_mbuf *om, void *arg)
|
||||
{
|
||||
/* TODO: In order to support dual-host mode, use legacy interfaces for ble when nimble host is enabled */
|
||||
uint16_t len;
|
||||
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
ble_mbuf_free_chain(om);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = BLE_MBUF_PKTHDR(om)->omp_len;
|
||||
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ACL, (uint8_t *)om, len,
|
||||
HCI_DRIVER_DIR_LEC2H);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
static int
|
||||
hci_transport_controller_bredr_tx_dummy(hci_driver_packet_t *pkt, void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_transport_controller_bredr_acl_tx(hci_driver_packet_t *pkt, void *arg)
|
||||
{
|
||||
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ACL, (uint8_t *)pkt, pkt->length,
|
||||
HCI_DRIVER_DIR_BREDRC2H);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_transport_controller_bredr_sync_tx(hci_driver_packet_t *pkt, void *arg)
|
||||
{
|
||||
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_SYNC, (uint8_t *)pkt, pkt->length,
|
||||
HCI_DRIVER_DIR_BREDRC2H);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_transport_controller_bredr_evt_tx(hci_driver_packet_t *pkt, void *arg)
|
||||
{
|
||||
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_EVT, (uint8_t *)pkt, pkt->length,
|
||||
HCI_DRIVER_DIR_BREDRC2H);
|
||||
}
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
typedef void ble_host_rx_iso_data_fn(uint8_t *data, uint16_t len);
|
||||
|
||||
static ble_host_rx_iso_data_fn *ble_host_iso_rx_cb = NULL;
|
||||
|
||||
void ble_host_register_rx_iso_data_cb(void *cb)
|
||||
{
|
||||
/* If the iso rx cb is already registered, we will give
|
||||
* a warning log here, and the cb will still be updated.
|
||||
*/
|
||||
if (ble_host_iso_rx_cb) {
|
||||
printf("iso rx cb %p already registered\n", ble_host_iso_rx_cb);
|
||||
}
|
||||
|
||||
ble_host_iso_rx_cb = cb;
|
||||
}
|
||||
|
||||
void ble_hci_register_rx_iso_data_cb(void *cb)
|
||||
{
|
||||
ble_host_register_rx_iso_data_cb(cb);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_transport_controller_le_iso_tx_dummy(const uint8_t *data, uint16_t len, void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_transport_controller_le_iso_tx(const uint8_t *data, uint16_t len, void *arg)
|
||||
{
|
||||
//ISO_TODO: arg is not used
|
||||
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
//ISO_TODO: free this tx buffer
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ISO, (uint8_t *)data, len,
|
||||
HCI_DRIVER_DIR_LEC2H);
|
||||
#elif CONFIG_BT_BLUEDROID_ENABLED
|
||||
if (ble_host_iso_rx_cb) {
|
||||
ble_host_iso_rx_cb((uint8_t *)data, len);
|
||||
}
|
||||
|
||||
free((void *)data);
|
||||
#endif // CONFIG_BT_NIMBLE_ENABLED
|
||||
return 0;
|
||||
}
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
|
||||
/* Functions for controller Tx. */
|
||||
static int
|
||||
hci_transport_controller_le_tx_dummy(void *data, void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_transport_controller_tx_dummy(hci_driver_packet_t *pkt)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_transport_controller_tx(hci_driver_packet_t *pkt)
|
||||
{
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_INITED
|
||||
&& esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s_hci_transport_env.driver_ops->hci_driver_tx(pkt->type, (uint8_t *)pkt, pkt->length,
|
||||
HCI_DRIVER_DIR_BTDMC2H);
|
||||
}
|
||||
|
||||
int
|
||||
hci_transport_init(uint8_t hci_transport_mode)
|
||||
{
|
||||
int rc;
|
||||
hci_driver_ops_t *ops;
|
||||
|
||||
memset(&s_hci_transport_env, 0, sizeof(hci_transport_env_t));
|
||||
|
||||
switch(hci_transport_mode) {
|
||||
#if UC_BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
case HCI_TRANSPORT_VHCI:
|
||||
ops = &hci_driver_vhci_ops;
|
||||
break;
|
||||
#endif // UC_BT_CTRL_HCI_INTERFACE_USE_RAM
|
||||
#if UC_BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
#if UC_BT_CTRL_UART_HCI_DMA_MODE
|
||||
case HCI_TRANSPORT_UART_UHCI:
|
||||
ops = &hci_driver_uart_dma_ops;
|
||||
break;
|
||||
#else
|
||||
case HCI_TRANSPORT_UART_NO_DMA:
|
||||
ops = &hci_driver_uart_ops;
|
||||
break;
|
||||
#endif // UC_BT_CTRL_UART_HCI_DMA_MODE
|
||||
#endif // UC_BT_CTRL_HCI_INTERFACE_USE_UART
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
rc = ops->hci_driver_init(hci_transport_controller_rx);
|
||||
if (rc) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
s_hci_transport_env.driver_ops = ops;
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
r_ble_hci_trans_cfg_hs((esp_hci_internal_rx_cmd_fn *)hci_transport_controller_le_evt_tx, NULL,
|
||||
(esp_hci_internal_rx_acl_fn *)hci_transport_controller_le_acl_tx, NULL);
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
ble_iso_trans_cfg_hs((esp_hci_internal_rx_iso_fn *)hci_transport_controller_le_iso_tx, NULL);
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
bredr_hci_trans_register_tx((btdm_hci_trans_tx_func_t *)hci_transport_controller_bredr_acl_tx,
|
||||
(btdm_hci_trans_tx_func_t *)hci_transport_controller_bredr_sync_tx,
|
||||
(btdm_hci_trans_tx_func_t *)hci_transport_controller_bredr_evt_tx);
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
btdm_hci_trans_register_tx((btdm_hci_trans_tx_func_t *)hci_transport_controller_tx, false);
|
||||
return 0;
|
||||
error:
|
||||
hci_transport_deinit();
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
hci_transport_deinit(void)
|
||||
{
|
||||
hci_driver_ops_t *ops;
|
||||
|
||||
btdm_hci_trans_register_tx((btdm_hci_trans_tx_func_t *)hci_transport_controller_tx_dummy, false);
|
||||
#if UC_BT_CTRL_BLE_IS_ENABLE
|
||||
r_ble_hci_trans_cfg_hs((esp_hci_internal_rx_cmd_fn *)hci_transport_controller_le_tx_dummy, NULL,
|
||||
(esp_hci_internal_rx_acl_fn *)hci_transport_controller_le_tx_dummy, NULL);
|
||||
#if CONFIG_BT_LE_ISO_SUPPORT
|
||||
ble_iso_trans_cfg_hs((esp_hci_internal_rx_iso_fn *)hci_transport_controller_le_iso_tx_dummy, NULL);
|
||||
#endif // CONFIG_BT_LE_ISO_SUPPORT
|
||||
#endif // UC_BT_CTRL_BLE_IS_ENABLE
|
||||
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
bredr_hci_trans_register_tx((btdm_hci_trans_tx_func_t *)hci_transport_controller_bredr_tx_dummy,
|
||||
(btdm_hci_trans_tx_func_t *)hci_transport_controller_bredr_tx_dummy,
|
||||
(btdm_hci_trans_tx_func_t *)hci_transport_controller_bredr_tx_dummy);
|
||||
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
|
||||
ops = s_hci_transport_env.driver_ops;
|
||||
if (ops) {
|
||||
ops->hci_driver_deinit();
|
||||
}
|
||||
memset(&s_hci_transport_env, 0, sizeof(hci_transport_env_t));
|
||||
}
|
||||
@@ -34,7 +34,7 @@ uint32_t IRAM_ATTR modem_clock_get_module_deps(shared_periph_module_t module)
|
||||
case PERIPH_PHY_MODULE: deps = PHY_CLOCK_DEPS; break;
|
||||
case PERIPH_MODEM_ADC_COMMON_FE_MODULE: deps = MODEM_ADC_COMMON_FE_CLOCK_DEPS; break;
|
||||
case PERIPH_COEX_MODULE: deps = COEXIST_CLOCK_DEPS; break;
|
||||
// case PERIPH_BT_MODULE: deps = BLE_CLOCK_DEPS; break;
|
||||
case PERIPH_BT_MODULE: deps = BLE_CLOCK_DEPS; break;
|
||||
case PERIPH_PHY_CALIBRATION_MODULE: deps = PHY_CALIBRATION_CLOCK_DEPS; break;
|
||||
case PERIPH_IEEE802154_MODULE: deps = IEEE802154_CLOCK_DEPS; break;
|
||||
case PERIPH_MODEM_ETM_MODULE: deps = MODEM_ETM_CLOCK_DEPS; break;
|
||||
@@ -44,23 +44,23 @@ uint32_t IRAM_ATTR modem_clock_get_module_deps(shared_periph_module_t module)
|
||||
return deps;
|
||||
}
|
||||
|
||||
// static void IRAM_ATTR modem_clock_ble_mac_configure(modem_clock_context_t *ctx, bool enable)
|
||||
// {
|
||||
// modem_syscon_ll_enable_bt_mac_clock(ctx->hal->syscon_dev, enable);
|
||||
// modem_syscon_ll_enable_modem_sec_clock(ctx->hal->syscon_dev, enable);
|
||||
// modem_syscon_ll_enable_ble_timer_clock(ctx->hal->syscon_dev, enable);
|
||||
// }
|
||||
static void IRAM_ATTR modem_clock_ble_mac_configure(modem_clock_context_t *ctx, bool enable)
|
||||
{
|
||||
modem_syscon_ll_enable_bt_mac_clock(ctx->hal->syscon_dev, enable);
|
||||
modem_syscon_ll_enable_modem_sec_clock(ctx->hal->syscon_dev, enable);
|
||||
modem_syscon_ll_enable_ble_timer_clock(ctx->hal->syscon_dev, enable);
|
||||
}
|
||||
|
||||
// #if CONFIG_ESP_MODEM_CLOCK_ENABLE_CHECKING
|
||||
// static esp_err_t IRAM_ATTR modem_clock_ble_mac_check_enable(modem_clock_context_t *ctx)
|
||||
// {
|
||||
// bool all_clock_enabled = true;
|
||||
// all_clock_enabled &= modem_syscon_ll_bt_mac_clock_is_enabled(ctx->hal->syscon_dev);
|
||||
// all_clock_enabled &= modem_syscon_ll_modem_sec_clock_is_enabled(ctx->hal->syscon_dev);
|
||||
// all_clock_enabled &= modem_syscon_ll_ble_timer_clock_is_enabled(ctx->hal->syscon_dev);
|
||||
// return all_clock_enabled ? ESP_OK : ESP_FAIL;
|
||||
// }
|
||||
// #endif
|
||||
#if CONFIG_ESP_MODEM_CLOCK_ENABLE_CHECKING
|
||||
static esp_err_t IRAM_ATTR modem_clock_ble_mac_check_enable(modem_clock_context_t *ctx)
|
||||
{
|
||||
bool all_clock_enabled = true;
|
||||
all_clock_enabled &= modem_syscon_ll_bt_mac_clock_is_enabled(ctx->hal->syscon_dev);
|
||||
all_clock_enabled &= modem_syscon_ll_modem_sec_clock_is_enabled(ctx->hal->syscon_dev);
|
||||
all_clock_enabled &= modem_syscon_ll_ble_timer_clock_is_enabled(ctx->hal->syscon_dev);
|
||||
return all_clock_enabled ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void IRAM_ATTR modem_clock_ble_i154_bb_configure(modem_clock_context_t *ctx, bool enable)
|
||||
{
|
||||
@@ -176,7 +176,7 @@ static void IRAM_ATTR modem_clock_configure_impl(modem_clock_context_t *ctx, int
|
||||
: (dev_id == MODEM_CLOCK_COEXIST) ? modem_clock_coex_configure
|
||||
: (dev_id == MODEM_CLOCK_I2C_MASTER) ? modem_clock_i2c_master_configure
|
||||
: (dev_id == MODEM_CLOCK_ETM) ? modem_clock_etm_configure
|
||||
// : (dev_id == MODEM_CLOCK_BLE_MAC) ? modem_clock_ble_mac_configure
|
||||
: (dev_id == MODEM_CLOCK_BLE_MAC) ? modem_clock_ble_mac_configure
|
||||
: (dev_id == MODEM_CLOCK_BT_I154_COMMON_BB) ? modem_clock_ble_i154_bb_configure
|
||||
: (dev_id == MODEM_CLOCK_802154_MAC) ? modem_clock_ieee802154_mac_configure
|
||||
: (dev_id == MODEM_CLOCK_DATADUMP) ? modem_clock_data_dump_configure
|
||||
@@ -196,7 +196,7 @@ static esp_err_t IRAM_ATTR modem_clock_check_impl(modem_clock_context_t *ctx, in
|
||||
: (dev_id == MODEM_CLOCK_COEXIST) ? modem_clock_coex_check_enable
|
||||
: (dev_id == MODEM_CLOCK_I2C_MASTER) ? modem_clock_i2c_master_check_enable
|
||||
: (dev_id == MODEM_CLOCK_ETM) ? modem_clock_etm_check_enable
|
||||
// : (dev_id == MODEM_CLOCK_BLE_MAC) ? modem_clock_ble_mac_check_enable
|
||||
: (dev_id == MODEM_CLOCK_BLE_MAC) ? modem_clock_ble_mac_check_enable
|
||||
: (dev_id == MODEM_CLOCK_BT_I154_COMMON_BB) ? modem_clock_ble_i154_bb_check_enable
|
||||
: (dev_id == MODEM_CLOCK_802154_MAC) ? modem_clock_ieee802154_mac_check_enable
|
||||
: (dev_id == MODEM_CLOCK_DATADUMP) ? modem_clock_data_dump_check_enable
|
||||
|
||||
+1
-1
Submodule components/esp_phy/lib updated: ac744ff2c5...3dad662616
@@ -30,10 +30,9 @@ void IRAM_ATTR modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_conte
|
||||
case MODEM_CLOCK_DOMAIN_MODEM_PERIPH:
|
||||
modem_syscon_ll_set_modem_periph_icg_bitmap(hal->syscon_dev, bitmap);
|
||||
break;
|
||||
// TODO: PM-636
|
||||
// case MODEM_CLOCK_DOMAIN_BT:
|
||||
// modem_syscon_ll_set_bt_icg_bitmap(hal->syscon_dev, bitmap);
|
||||
// break;
|
||||
case MODEM_CLOCK_DOMAIN_BT:
|
||||
modem_syscon_ll_set_bt_icg_bitmap(hal->syscon_dev, bitmap);
|
||||
break;
|
||||
case MODEM_CLOCK_DOMAIN_MODEM_FE:
|
||||
modem_syscon_ll_set_fe_icg_bitmap(hal->syscon_dev, bitmap);
|
||||
break;
|
||||
@@ -58,6 +57,7 @@ uint32_t IRAM_ATTR modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_c
|
||||
{
|
||||
HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX);
|
||||
uint32_t bitmap = 0;
|
||||
|
||||
switch (domain)
|
||||
{
|
||||
case MODEM_CLOCK_DOMAIN_MODEM_APB:
|
||||
@@ -66,10 +66,9 @@ uint32_t IRAM_ATTR modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_c
|
||||
case MODEM_CLOCK_DOMAIN_MODEM_PERIPH:
|
||||
bitmap = modem_syscon_ll_get_modem_periph_icg_bitmap(hal->syscon_dev);
|
||||
break;
|
||||
// TODO: PM-636
|
||||
// case MODEM_CLOCK_DOMAIN_BT:
|
||||
// bitmap = modem_syscon_ll_get_bt_icg_bitmap(hal->syscon_dev);
|
||||
// break;
|
||||
case MODEM_CLOCK_DOMAIN_BT:
|
||||
bitmap = modem_syscon_ll_get_bt_icg_bitmap(hal->syscon_dev);
|
||||
break;
|
||||
case MODEM_CLOCK_DOMAIN_MODEM_FE:
|
||||
bitmap = modem_syscon_ll_get_fe_icg_bitmap(hal->syscon_dev);
|
||||
break;
|
||||
|
||||
@@ -55,6 +55,10 @@ config SOC_PARLIO_LCD_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BT_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_IEEE802154_BLE_ONLY
|
||||
bool
|
||||
default y
|
||||
@@ -1123,6 +1127,50 @@ config SOC_TOUCH_SAMPLE_CFG_NUM
|
||||
int
|
||||
default 3
|
||||
|
||||
config SOC_BLE_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_ESP_NIMBLE_CONTROLLER
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_50_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_DEVICE_PRIVACY_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_POWER_CONTROL_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_MULTI_CONN_OPTIMIZATION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_CTE_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_SUBRATE_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_PERIODIC_ADV_WITH_RESPONSE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_ISO_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_USB_OTG_PERIPH_NUM
|
||||
int
|
||||
default 1
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#define SOC_ETM_SUPPORTED 1
|
||||
#define SOC_PARLIO_SUPPORTED 1
|
||||
#define SOC_PARLIO_LCD_SUPPORTED 1
|
||||
// #define SOC_BT_SUPPORTED 1
|
||||
#define SOC_BT_SUPPORTED 1
|
||||
#define SOC_IEEE802154_BLE_ONLY 1
|
||||
#define SOC_PHY_SUPPORTED 1
|
||||
#define SOC_IEEE802154_SUPPORTED 1
|
||||
@@ -534,15 +534,18 @@
|
||||
#define SOC_TOUCH_SAMPLE_CFG_NUM (3) /*!< The sample configurations number in total, each sampler can be used to sample on one frequency */
|
||||
|
||||
/*---------------------------------- Bluetooth CAPS ----------------------------------*/
|
||||
// #define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */
|
||||
// #define SOC_BLE_MESH_SUPPORTED (1) /*!< Support BLE MESH */
|
||||
// #define SOC_ESP_NIMBLE_CONTROLLER (1) /*!< Support BLE EMBEDDED controller V1 */
|
||||
// #define SOC_BLE_50_SUPPORTED (1) /*!< Support Bluetooth 5.0 */
|
||||
// #define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (1) /*!< Support BLE device privacy mode */
|
||||
// #define SOC_BLE_POWER_CONTROL_SUPPORTED (1) /*!< Support Bluetooth Power Control */
|
||||
// #define SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED (1) /*!< Support For BLE Periodic Adv Enhancements */
|
||||
// #define SOC_BLUFI_SUPPORTED (1) /*!< Support BLUFI */
|
||||
// #define SOC_BLE_MULTI_CONN_OPTIMIZATION (1) /*!< Support multiple connections optimization */
|
||||
#define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */
|
||||
// #define SOC_BLE_MESH_SUPPORTED (1) /*!< Support BLE MESH */
|
||||
#define SOC_ESP_NIMBLE_CONTROLLER (1) /*!< Support BLE EMBEDDED controller V1 */
|
||||
#define SOC_BLE_50_SUPPORTED (1) /*!< Support Bluetooth 5.0 */
|
||||
#define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (1) /*!< Support BLE device privacy mode */
|
||||
#define SOC_BLE_POWER_CONTROL_SUPPORTED (1) /*!< Support Bluetooth Power Control */
|
||||
#define SOC_BLE_MULTI_CONN_OPTIMIZATION (1) /*!< Support multiple connections optimization */
|
||||
#define SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED (1) /*!< Support For BLE Periodic Adv Enhancements */
|
||||
#define SOC_BLE_CTE_SUPPORTED (1) /*!< Support Bluetooth LE Constant Tone Extension (CTE) */
|
||||
#define SOC_BLE_SUBRATE_SUPPORTED (1) /*!< Support Bluetooth LE Connection Subrating */
|
||||
#define SOC_BLE_PERIODIC_ADV_WITH_RESPONSE (1) /*!< Support Bluetooth LE Periodic Advertising with Response (PAwR) */
|
||||
#define SOC_BLE_ISO_SUPPORTED (1) /*!< Support Bluetooth ISO */
|
||||
|
||||
/*-------------------------- USB CAPS ----------------------------------------*/
|
||||
#define SOC_USB_OTG_PERIPH_NUM (1U)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# Bluedroid Beacon Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# Bluedroid Connection Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# Bluedroid GATT Server Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# NimBLE Beacon Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# NimBLE Connection Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# NimBLE GATT Server Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# NimBLE Security Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE ACL Latency Test - Central
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE ACL Latency Test - Peripheral
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE ANCS Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE Compatibility Test Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Eddystone Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Eddystone Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# BLE Encrypted Advertising Data Central Example (Bluedroid)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# BLE Encrypted Advertising Data Peripheral Example (Bluedroid)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE HID Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF iBeacon demo
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# BLE Multiple Connection Central Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# BLE Multiple Connection Peripheral Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF SPP GATT CLIENT demo
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
## ESP-IDF GATT SERVER SPP Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE throughput GATT CLIENT Test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE throughput GATT SERVER Test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Gatt Client Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Gatt Security Client Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Gatt Security Server Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Gatt Server Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Gatt Server Service Table Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Gatt Client Multi Connection Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Gatt Security Client Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE50 Security Server Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE 50 throughput GATT CLIENT Test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE 50 throughput GATT SERVER Test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- |
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- | -------- |
|
||||
|
||||
# BLE Connection Subrating Central Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- |
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- | -------- |
|
||||
|
||||
# BLE Connection Subrating Peripheral Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C5 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | --------- | -------- |
|
||||
| Supported Targets | ESP32-C5 | ESP32-C61 | ESP32-H2 | ESP32-H4 |
|
||||
| ----------------- | -------- | --------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE Connection Central with CTE Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C5 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | --------- | -------- |
|
||||
| Supported Targets | ESP32-C5 | ESP32-C61 | ESP32-H2 | ESP32-H4 |
|
||||
| ----------------- | -------- | --------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF BLE Connection Peripheral with CTE Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- |
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- | -------- |
|
||||
|
||||
# BLE Periodic Advertiser With Response (PAwR) Advertiser Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- |
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- | -------- |
|
||||
|
||||
# BLE Periodic Advertiser With Response (PAwR) Advertiser Connection Example
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user