Skip to content
Snippets Groups Projects
Commit c8ccefb9 authored by graham sanderson's avatar graham sanderson
Browse files

Add Bluetooth support

parent 0d207f48
No related branches found
No related tags found
No related merge requests found
Showing
with 959 additions and 37 deletions
......@@ -10,3 +10,6 @@
[submodule "lib/mbedtls"]
path = lib/mbedtls
url = https://github.com/Mbed-TLS/mbedtls.git
[submodule "lib/btstack"]
path = lib/btstack
url = https://github.com/bluekitchen/btstack.git
......@@ -62,8 +62,9 @@
* \defgroup networking Networking Libraries
* Functions for implementing networking
* @{
* \defgroup pico_cyw43_driver pico_cyw43_driver
* \defgroup pico_btstack pico_btstack
* \defgroup pico_lwip pico_lwip
* \defgroup pico_cyw43_driver pico_cyw43_driver
* \defgroup pico_cyw43_arch pico_cyw43_arch
* @}
*
......
Subproject commit 0d212321a995ed2f9a80988f73ede854c7ad23b8
Subproject commit 83e0c700c252b392d33e70a5e9a241b921b166eb
Subproject commit 9bfca61173a94432839cd39210f1d1afdf602c42
......@@ -58,10 +58,11 @@ if (NOT PICO_BARE_METAL)
pico_add_subdirectory(cmsis)
pico_add_subdirectory(tinyusb)
pico_add_subdirectory(pico_stdio_usb)
pico_add_subdirectory(pico_i2c_slave)
# networking libraries - note dependency order is important
pico_add_subdirectory(pico_async_context)
pico_add_subdirectory(pico_btstack)
pico_add_subdirectory(pico_cyw43_driver)
pico_add_subdirectory(pico_lwip)
pico_add_subdirectory(pico_cyw43_arch)
......
......@@ -168,10 +168,12 @@ void async_context_freertos_acquire_lock_blocking(async_context_t *self_base) {
self->nesting++;
}
void async_context_freertos_lock_check(async_context_t *self_base) {
void async_context_freertos_lock_check(__unused async_context_t *self_base) {
#ifndef NDEBUG
async_context_freertos_t *self = (async_context_freertos_t *)self_base;
// Lock the other core and stop low_prio_irq running
assert(xSemaphoreGetMutexHolder(self->lock_mutex) == xTaskGetCurrentTaskHandle());
#endif
}
typedef struct sync_func_call{
......
if (DEFINED ENV{PICO_BTSTACK_PATH} AND (NOT PICO_BTSTACK_PATH))
set(PICO_BTSTACK_PATH $ENV{PICO_BTSTACK_PATH})
message("Using PICO_BTSTACK_PATH from environment ('${PICO_BTSTACK_PATH}')")
endif ()
set(BTSTACK_TEST_PATH "src/bluetooth.h")
if (NOT PICO_BTSTACK_PATH)
set(PICO_BTSTACK_PATH ${PROJECT_SOURCE_DIR}/lib/btstack)
if (PICO_CYW43_SUPPORTED AND NOT EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH})
message(WARNING "btstack submodule has not been initialized; Pico W BLE support will be unavailable.
hint: try 'git submodule update --init' from your SDK directory (${PICO_SDK_PATH}).")
endif()
elseif (NOT EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH})
message(WARNING "PICO_BTSTACK_PATH specified but content not present.")
endif()
if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH})
message("BTstack available at ${PICO_BTSTACK_PATH}")
pico_register_common_scope_var(PICO_BTSTACK_PATH)
pico_add_library(pico_btstack_base NOFLAG)
target_include_directories(pico_btstack_base_headers INTERFACE
${PICO_BTSTACK_PATH}/src
${PICO_BTSTACK_PATH}/platform/embedded
)
target_sources(pico_btstack_base INTERFACE
${PICO_BTSTACK_PATH}/3rd-party/micro-ecc/uECC.c
${PICO_BTSTACK_PATH}/3rd-party/rijndael/rijndael.c
${PICO_BTSTACK_PATH}/3rd-party/segger-rtt/SEGGER_RTT.c
${PICO_BTSTACK_PATH}/3rd-party/segger-rtt/SEGGER_RTT_printf.c
${PICO_BTSTACK_PATH}/platform/embedded/btstack_tlv_flash_bank.c
${PICO_BTSTACK_PATH}/platform/embedded/hci_dump_embedded_stdout.c
${PICO_BTSTACK_PATH}/platform/embedded/hci_dump_segger_rtt_stdout.c
${PICO_BTSTACK_PATH}/src/ad_parser.c
${PICO_BTSTACK_PATH}/src/btstack_base64_decoder.c
${PICO_BTSTACK_PATH}/src/btstack_crypto.c
${PICO_BTSTACK_PATH}/src/btstack_hid_parser.c
${PICO_BTSTACK_PATH}/src/btstack_linked_list.c
${PICO_BTSTACK_PATH}/src/btstack_memory.c
${PICO_BTSTACK_PATH}/src/btstack_memory_pool.c
${PICO_BTSTACK_PATH}/src/btstack_resample.c
${PICO_BTSTACK_PATH}/src/btstack_ring_buffer.c
${PICO_BTSTACK_PATH}/src/btstack_run_loop.c
${PICO_BTSTACK_PATH}/src/btstack_run_loop_base.c
${PICO_BTSTACK_PATH}/src/btstack_slip.c
${PICO_BTSTACK_PATH}/src/btstack_tlv.c
${PICO_BTSTACK_PATH}/src/btstack_tlv_none.c
${PICO_BTSTACK_PATH}/src/btstack_util.c
${PICO_BTSTACK_PATH}/src/hci.c
${PICO_BTSTACK_PATH}/src/hci_cmd.c
${PICO_BTSTACK_PATH}/src/hci_dump.c
${PICO_BTSTACK_PATH}/src/l2cap.c
${PICO_BTSTACK_PATH}/src/l2cap_signaling.c
${PICO_BTSTACK_PATH}/src/mesh/gatt-service/mesh_provisioning_service_server.c
${PICO_BTSTACK_PATH}/src/mesh/gatt-service/mesh_proxy_service_server.c
${PICO_BTSTACK_PATH}/3rd-party/md5/md5.c
${PICO_BTSTACK_PATH}/3rd-party/yxml/yxml.c
${CMAKE_CURRENT_LIST_DIR}/btstack_stdin_pico.c
)
target_include_directories(pico_btstack_base_headers INTERFACE
${PICO_BTSTACK_PATH}/
${PICO_BTSTACK_PATH}/3rd-party/md5
${PICO_BTSTACK_PATH}/3rd-party/yxml
${PICO_BTSTACK_PATH}/3rd-party/rijndael
${PICO_BTSTACK_PATH}/3rd-party/micro-ecc
${PICO_BTSTACK_PATH}/3rd-party/segger-rtt
)
pico_add_library(pico_btstack_ble)
target_sources(pico_btstack_ble INTERFACE
${PICO_BTSTACK_PATH}/src/ble/att_db.c
${PICO_BTSTACK_PATH}/src/ble/att_db_util.c
${PICO_BTSTACK_PATH}/src/ble/att_dispatch.c
${PICO_BTSTACK_PATH}/src/ble/att_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/battery_service_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/battery_service_client.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/cycling_power_service_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/cycling_speed_and_cadence_service_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/device_information_service_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/device_information_service_client.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/heart_rate_service_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_client.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_device.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/nordic_spp_service_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/ublox_spp_service_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/ancs_client.c
${PICO_BTSTACK_PATH}/src/ble/gatt_client.c
${PICO_BTSTACK_PATH}/src/ble/le_device_db_memory.c
${PICO_BTSTACK_PATH}/src/ble/le_device_db_tlv.c
${PICO_BTSTACK_PATH}/src/ble/sm.c
)
pico_mirrored_target_link_libraries(pico_btstack_ble INTERFACE
pico_btstack_base
)
target_compile_definitions(pico_btstack_ble INTERFACE
ENABLE_BLE=1
)
pico_add_library(pico_btstack_classic)
target_sources(pico_btstack_classic INTERFACE
${PICO_BTSTACK_PATH}/src/classic/a2dp.c
${PICO_BTSTACK_PATH}/src/classic/a2dp_sink.c
${PICO_BTSTACK_PATH}/src/classic/a2dp_source.c
${PICO_BTSTACK_PATH}/src/classic/avdtp.c
${PICO_BTSTACK_PATH}/src/classic/avdtp_acceptor.c
${PICO_BTSTACK_PATH}/src/classic/avdtp_initiator.c
${PICO_BTSTACK_PATH}/src/classic/avdtp_sink.c
${PICO_BTSTACK_PATH}/src/classic/avdtp_source.c
${PICO_BTSTACK_PATH}/src/classic/avdtp_util.c
${PICO_BTSTACK_PATH}/src/classic/avrcp.c
${PICO_BTSTACK_PATH}/src/classic/avrcp_browsing.c
${PICO_BTSTACK_PATH}/src/classic/avrcp_browsing_controller.c
${PICO_BTSTACK_PATH}/src/classic/avrcp_browsing_target.c
${PICO_BTSTACK_PATH}/src/classic/avrcp_controller.c
${PICO_BTSTACK_PATH}/src/classic/avrcp_media_item_iterator.c
${PICO_BTSTACK_PATH}/src/classic/avrcp_target.c
${PICO_BTSTACK_PATH}/src/classic/btstack_cvsd_plc.c
${PICO_BTSTACK_PATH}/src/classic/btstack_link_key_db_tlv.c
${PICO_BTSTACK_PATH}/src/classic/btstack_sbc_plc.c
${PICO_BTSTACK_PATH}/src/classic/device_id_server.c
${PICO_BTSTACK_PATH}/src/classic/gatt_sdp.c
${PICO_BTSTACK_PATH}/src/classic/goep_client.c
${PICO_BTSTACK_PATH}/src/classic/goep_server.c
${PICO_BTSTACK_PATH}/src/classic/hfp.c
${PICO_BTSTACK_PATH}/src/classic/hfp_ag.c
${PICO_BTSTACK_PATH}/src/classic/hfp_gsm_model.c
${PICO_BTSTACK_PATH}/src/classic/hfp_hf.c
${PICO_BTSTACK_PATH}/src/classic/hfp_msbc.c
${PICO_BTSTACK_PATH}/src/classic/hid_device.c
${PICO_BTSTACK_PATH}/src/classic/hid_host.c
${PICO_BTSTACK_PATH}/src/classic/hsp_ag.c
${PICO_BTSTACK_PATH}/src/classic/hsp_hs.c
${PICO_BTSTACK_PATH}/src/classic/obex_iterator.c
${PICO_BTSTACK_PATH}/src/classic/obex_message_builder.c
${PICO_BTSTACK_PATH}/src/classic/obex_parser.c
${PICO_BTSTACK_PATH}/src/classic/pan.c
${PICO_BTSTACK_PATH}/src/classic/pbap_client.c
${PICO_BTSTACK_PATH}/src/classic/rfcomm.c
${PICO_BTSTACK_PATH}/src/classic/sdp_client.c
${PICO_BTSTACK_PATH}/src/classic/sdp_client_rfcomm.c
${PICO_BTSTACK_PATH}/src/classic/sdp_server.c
${PICO_BTSTACK_PATH}/src/classic/sdp_util.c
${PICO_BTSTACK_PATH}/src/classic/spp_server.c
)
pico_mirrored_target_link_libraries(pico_btstack_classic INTERFACE
pico_btstack_base
)
target_compile_definitions(pico_btstack_classic INTERFACE
ENABLE_CLASSIC=1
)
pico_add_library(pico_btstack_flash_bank)
target_sources(pico_btstack_flash_bank INTERFACE
${CMAKE_CURRENT_LIST_DIR}/btstack_flash_bank.c
)
target_include_directories(pico_btstack_flash_bank_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
pico_add_library(pico_btstack_run_loop_async_context NOFLAG)
target_sources(pico_btstack_run_loop_async_context INTERFACE
${CMAKE_CURRENT_LIST_DIR}/btstack_run_loop_async_context.c
)
target_include_directories(pico_btstack_run_loop_async_context_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
pico_mirrored_target_link_libraries(pico_btstack_run_loop_async_context INTERFACE pico_btstack_base pico_async_context_base)
pico_add_library(pico_btstack_sbc_encoder NOFLAG)
target_sources(pico_btstack_sbc_encoder INTERFACE
# SBC codec for A2DP and HFP demos
${PICO_BTSTACK_PATH}/src/classic/btstack_sbc_encoder_bluedroid.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/srce/sbc_analysis.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/srce/sbc_dct.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/srce/sbc_dct_coeffs.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/srce/sbc_enc_bit_alloc_mono.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/srce/sbc_enc_bit_alloc_ste.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/srce/sbc_enc_coeffs.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/srce/sbc_encoder.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/srce/sbc_packing.c
)
target_include_directories(pico_btstack_sbc_encoder_headers INTERFACE
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/encoder/include
)
pico_add_library(pico_btstack_sbc_decoder NOFLAG)
target_sources(pico_btstack_sbc_decoder INTERFACE
${PICO_BTSTACK_PATH}/src/classic/btstack_sbc_decoder_bluedroid.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/alloc.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/bitalloc.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/bitalloc-sbc.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/bitstream-decode.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/decoder-oina.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/decoder-private.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/decoder-sbc.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/dequant.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/framing.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/framing-sbc.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/oi_codec_version.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/synthesis-sbc.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/synthesis-dct8.c
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/srce/synthesis-8-generated.c
)
target_include_directories(pico_btstack_sbc_decoder_headers INTERFACE
${PICO_BTSTACK_PATH}/3rd-party/bluedroid/decoder/include
)
pico_add_library(pico_btstack_bnep_lwip NOFLAG)
target_sources(pico_btstack_bnep_lwip INTERFACE
${PICO_BTSTACK_PATH}/src/classic/bnep.c
${PICO_BTSTACK_PATH}/platform/lwip/bnep_lwip.c
)
target_include_directories(pico_btstack_bnep_lwip_headers INTERFACE
${PICO_BTSTACK_PATH}/platform/lwip
)
pico_add_library(pico_btstack_bnep_lwip_sys_freertos NOFLAG)
target_include_directories(pico_btstack_bnep_lwip_sys_freertos INTERFACE
${PICO_BTSTACK_PATH}/platform/freertos
)
pico_mirrored_target_link_libraries(pico_btstack_bnep_lwip_sys_freertos INTERFACE
pico_btstack_bnep_lwip
)
target_compile_definitions(pico_btstack_bnep_lwip_sys_freertos INTERFACE
LWIP_PROVIDE_ERRNO=1
PICO_LWIP_CUSTOM_LOCK_TCPIP_CORE=1
)
pico_promote_common_scope_vars()
# Make a GATT header file from a BTstack GATT file
# Pass the target library name library type and path to the GATT input file
function(pico_btstack_make_gatt_header TARGET_LIB TARGET_TYPE GATT_FILE)
find_package (Python3 REQUIRED COMPONENTS Interpreter)
get_filename_component(GATT_NAME "${GATT_FILE}" NAME_WE)
get_filename_component(GATT_PATH "${GATT_FILE}" PATH)
set(GATT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set(GATT_HEADER "${GATT_BINARY_DIR}/${GATT_NAME}.h")
set(TARGET_GATT "${TARGET_LIB}_gatt_header")
add_custom_target(${TARGET_GATT} DEPENDS ${GATT_HEADER})
add_custom_command(
OUTPUT ${GATT_HEADER}
DEPENDS ${GATT_FILE}
WORKING_DIRECTORY ${GATT_PATH}
COMMAND ${CMAKE_COMMAND} -E make_directory ${GATT_BINARY_DIR} &&
${Python3_EXECUTABLE} ${PICO_SDK_PATH}/lib/btstack/tool/compile_gatt.py ${GATT_FILE} ${GATT_HEADER}
VERBATIM)
add_dependencies(${TARGET_LIB}
${TARGET_GATT}
)
target_include_directories(${TARGET_LIB} ${TARGET_TYPE}
${GATT_BINARY_DIR}
)
endfunction()
function(suppress_btstack_warnings)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/ble/att_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/device_information_service_server.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_client.c
${PICO_BTSTACK_PATH}/src/btstack_util.c
${PICO_BTSTACK_PATH}/src/btstack_crypto.c
${PICO_BTSTACK_PATH}/src/classic/a2dp.c
${PICO_BTSTACK_PATH}/src/classic/a2dp_sink.c
${PICO_BTSTACK_PATH}/src/classic/a2dp_source.c
${PICO_BTSTACK_PATH}/src/classic/avdtp.c
${PICO_BTSTACK_PATH}/src/classic/avdtp_source.c
${PICO_BTSTACK_PATH}/src/classic/avrcp.c
${PICO_BTSTACK_PATH}/src/classic/avrcp_controller.c
${PICO_BTSTACK_PATH}/src/classic/btstack_sbc_decoder_bluedroid.c
${PICO_BTSTACK_PATH}/src/classic/avrcp_target.c
${PICO_BTSTACK_PATH}/src/classic/hid_device.c
${PICO_BTSTACK_PATH}/src/classic/hsp_ag.c
${PICO_BTSTACK_PATH}/src/classic/hsp_hs.c
${PICO_BTSTACK_PATH}/src/classic/pan.c
${PICO_BTSTACK_PATH}/src/classic/pbap_client.c
${PICO_BTSTACK_PATH}/src/classic/rfcomm.c
${PICO_BTSTACK_PATH}/src/classic/sdp_client_rfcomm.c
${PICO_BTSTACK_PATH}/src/classic/sdp_server.c
${PICO_BTSTACK_PATH}/src/classic/spp_server.c
PROPERTIES
COMPILE_OPTIONS "-Wno-cast-qual"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/ble/sm.c
${PICO_BTSTACK_PATH}/src/l2cap.c
PROPERTIES
COMPILE_OPTIONS "-Wno-cast-qual;-Wno-unused-parameter"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/btstack_hid_parser.c
PROPERTIES
COMPILE_OPTIONS "-Wno-maybe-uninitialized"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/btstack_tlv_none.c
${PICO_BTSTACK_PATH}/src/classic/avdtp_util.c
PROPERTIES
COMPILE_OPTIONS "-Wno-unused-parameter"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/platform/embedded/hci_dump_embedded_stdout.c
PROPERTIES
COMPILE_OPTIONS "-Wno-suggest-attribute=format"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/hci.c
${PICO_BTSTACK_PATH}/src/classic/rfcomm.c
PROPERTIES
COMPILE_OPTIONS "-Wno-cast-qual;-Wno-format"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/platform/embedded/hal_flash_bank_memory.c
PROPERTIES
COMPILE_OPTIONS "-Wno-sign-compare;-Wno-format"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/platform/embedded/btstack_tlv_flash_bank.c
PROPERTIES
COMPILE_OPTIONS "-Wno-unused-parameter;-Wno-sign-compare"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_client.c
PROPERTIES
COMPILE_OPTIONS "-Wno-cast-qual;-Wno-null-dereference"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/classic/hfp.c
PROPERTIES
COMPILE_OPTIONS "-Wno-cast-qual;-Wno-null-dereference;-Wno-unused-parameter"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/classic/goep_server.c
PROPERTIES
COMPILE_OPTIONS "-Wno-unused-parameter;-Wno-null-dereference"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/ble/gatt-service/battery_service_client.c
${PICO_BTSTACK_PATH}/src/ble/gatt-service/device_information_service_client.c
PROPERTIES
COMPILE_OPTIONS "-Wno-null-dereference"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/classic/hfp_hf.c
PROPERTIES
COMPILE_OPTIONS "-Wno-type-limits;-Wno-stringop-overflow"
)
set_source_files_properties(
${PICO_BTSTACK_PATH}/src/btstack_crypto.c
PROPERTIES
COMPILE_OPTIONS "-Wno-cast-qual;-Wno-sign-compare"
)
endfunction()
endif()
/*
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "pico/btstack_flash_bank.h"
#include "hardware/flash.h"
#include "hardware/sync.h"
#include <string.h>
// Check sizes
static_assert(PICO_FLASH_BANK_TOTAL_SIZE % (FLASH_SECTOR_SIZE * 2) == 0, "PICO_FLASH_BANK_TOTAL_SIZE invalid");
static_assert(PICO_FLASH_BANK_TOTAL_SIZE <= PICO_FLASH_SIZE_BYTES, "PICO_FLASH_BANK_TOTAL_SIZE too big");
static_assert(PICO_FLASH_BANK_STORAGE_OFFSET + PICO_FLASH_BANK_TOTAL_SIZE <= PICO_FLASH_SIZE_BYTES, "PICO_FLASH_BANK_TOTAL_SIZE too big");
// Size of one bank
#define PICO_FLASH_BANK_SIZE (PICO_FLASH_BANK_TOTAL_SIZE / 2)
#if 0
#define DEBUG_PRINT(format,args...) printf(format, ## args)
#else
#define DEBUG_PRINT(...)
#endif
static uint32_t pico_flash_bank_get_size(void * context) {
(void)(context);
return PICO_FLASH_BANK_SIZE;
}
static uint32_t pico_flash_bank_get_alignment(void * context) {
(void)(context);
return 1;
}
static void pico_flash_bank_erase(void * context, int bank) {
(void)(context);
DEBUG_PRINT("erase: bank %d\n", bank);
uint32_t status = save_and_disable_interrupts();
flash_range_erase(PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank), PICO_FLASH_BANK_SIZE);
restore_interrupts(status);
}
static void pico_flash_bank_read(void *context, int bank, uint32_t offset, uint8_t *buffer, uint32_t size) {
(void)(context);
DEBUG_PRINT("read: bank %d offset %u size %u\n", bank, offset, size);
assert(bank <= 1);
if (bank > 1) return;
assert(offset < PICO_FLASH_BANK_SIZE);
if (offset >= PICO_FLASH_BANK_SIZE) return;
assert((offset + size) <= PICO_FLASH_BANK_SIZE);
if ((offset + size) > PICO_FLASH_BANK_SIZE) return;
// Flash is xip
memcpy(buffer, (void *)(XIP_BASE + PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank) + offset), size);
}
static void pico_flash_bank_write(void * context, int bank, uint32_t offset, const uint8_t *data, uint32_t size) {
(void)(context);
DEBUG_PRINT("write: bank %d offset %u size %u\n", bank, offset, size);
assert(bank <= 1);
if (bank > 1) return;
assert(offset < PICO_FLASH_BANK_SIZE);
if (offset >= PICO_FLASH_BANK_SIZE) return;
assert((offset + size) <= PICO_FLASH_BANK_SIZE);
if ((offset + size) > PICO_FLASH_BANK_SIZE) return;
if (size == 0) return;
// calc bank start position
const uint32_t bank_start_pos = PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank);
// Calculate first and last page in the bank
const uint32_t first_page = offset / FLASH_PAGE_SIZE;
const uint32_t last_page = (offset + size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE;
// Now we only care about the offset in the first page
offset %= FLASH_PAGE_SIZE;
// Amount of data we've copied
uint32_t data_pos = 0;
uint32_t size_left = size;
// Write all the pages required
for(uint32_t page = first_page; page < last_page; page++) {
uint8_t page_data[FLASH_PAGE_SIZE];
assert(data_pos < size && size_left <= size);
// Copy data we're not going to overwrite in the first page
if (page == first_page && offset > 0) {
memcpy(page_data,
(void *)(XIP_BASE + bank_start_pos + (page * FLASH_PAGE_SIZE)),
offset);
}
// Copy the data we're not going to overwrite in the last page
if (page == last_page - 1 && (offset + size_left) < FLASH_PAGE_SIZE) {
memcpy(page_data + offset + size_left,
(void *)(XIP_BASE + bank_start_pos + (page * FLASH_PAGE_SIZE) + offset + size_left),
FLASH_PAGE_SIZE - offset - size_left);
}
// Now copy the new data into the page
const uint32_t size_to_copy = MIN(size_left, FLASH_PAGE_SIZE - offset);
memcpy(page_data + offset, data + data_pos, size_to_copy);
data_pos += size_to_copy;
size_left -= size_to_copy;
// zero offset for the following pages
offset = 0;
// Now program the entire page
uint32_t status = save_and_disable_interrupts();
flash_range_program(bank_start_pos + (page * FLASH_PAGE_SIZE), page_data, FLASH_PAGE_SIZE);
restore_interrupts(status);
}
}
static const hal_flash_bank_t pico_flash_bank_instance_obj = {
/* uint32_t (*get_size)(..) */ &pico_flash_bank_get_size,
/* uint32_t (*get_alignment)(..); */ &pico_flash_bank_get_alignment,
/* void (*erase)(..); */ &pico_flash_bank_erase,
/* void (*read)(..); */ &pico_flash_bank_read,
/* void (*write)(..); */ &pico_flash_bank_write,
};
const hal_flash_bank_t *pico_flash_bank_instance(void) {
#ifndef NDEBUG
// Check we're not overlapping the binary in flash
extern char __flash_binary_end;
assert((uintptr_t)&__flash_binary_end - XIP_BASE <= PICO_FLASH_BANK_STORAGE_OFFSET);
#endif
return &pico_flash_bank_instance_obj;
}
/*
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "pico/btstack_run_loop_async_context.h"
#include "hardware/sync.h"
static async_context_t *btstack_async_context;
static async_at_time_worker_t btstack_timeout_worker;
static async_when_pending_worker_t btstack_processing_worker;
static void btstack_timeout_reached(async_context_t *context, async_at_time_worker_t *worker);
static void btstack_work_pending(async_context_t *context, async_when_pending_worker_t *worker);
static volatile bool run_loop_exit;
static void btstack_run_loop_async_context_init(void) {
btstack_run_loop_base_init();
btstack_timeout_worker.do_work = btstack_timeout_reached;
btstack_processing_worker.do_work = btstack_work_pending;
async_context_add_when_pending_worker(btstack_async_context, &btstack_processing_worker);
}
static void btstack_run_loop_async_context_add_data_source(btstack_data_source_t * data_source) {
async_context_acquire_lock_blocking(btstack_async_context);
btstack_run_loop_base_add_data_source(data_source);
async_context_release_lock(btstack_async_context);
}
static bool btstack_run_loop_async_context_remove_data_source(btstack_data_source_t * data_source) {
async_context_acquire_lock_blocking(btstack_async_context);
bool rc = btstack_run_loop_base_remove_data_source(data_source);
async_context_release_lock(btstack_async_context);
return rc;
}
static void btstack_run_loop_async_context_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks) {
async_context_acquire_lock_blocking(btstack_async_context);
btstack_run_loop_base_enable_data_source_callbacks(data_source, callbacks);
async_context_release_lock(btstack_async_context);
}
static void btstack_run_loop_async_context_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks) {
async_context_acquire_lock_blocking(btstack_async_context);
btstack_run_loop_base_disable_data_source_callbacks(data_source, callbacks);
async_context_release_lock(btstack_async_context);
}
static void btstack_run_loop_async_context_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){
async_context_acquire_lock_blocking(btstack_async_context);
ts->timeout = to_ms_since_boot(get_absolute_time()) + timeout_in_ms + 1;
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker);
async_context_release_lock(btstack_async_context);
}
static void btstack_run_loop_async_context_add_timer(btstack_timer_source_t *timer) {
async_context_acquire_lock_blocking(btstack_async_context);
btstack_run_loop_base_add_timer(timer);
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker);
async_context_release_lock(btstack_async_context);
}
static bool btstack_run_loop_async_context_remove_timer(btstack_timer_source_t *timer) {
async_context_acquire_lock_blocking(btstack_async_context);
bool rc = btstack_run_loop_base_remove_timer(timer);
async_context_release_lock(btstack_async_context);
return rc;
}
static void btstack_run_loop_async_context_dump_timer(void){
async_context_acquire_lock_blocking(btstack_async_context);
btstack_run_loop_base_dump_timer();
async_context_release_lock(btstack_async_context);
}
static uint32_t btstack_run_loop_async_context_get_time_ms(void)
{
return to_ms_since_boot(get_absolute_time());
}
static void btstack_run_loop_async_context_execute(void)
{
run_loop_exit = false;
while (!run_loop_exit) {
async_context_poll(btstack_async_context);
async_context_wait_for_work_until(btstack_async_context, at_the_end_of_time);
}
}
static void btstack_run_loop_async_context_trigger_exit(void)
{
run_loop_exit = true;
}
static void btstack_run_loop_async_context_execute_on_main_thread(btstack_context_callback_registration_t *callback_registration)
{
async_context_acquire_lock_blocking(btstack_async_context);
btstack_run_loop_base_add_callback(callback_registration);
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker);
async_context_release_lock(btstack_async_context);
}
static void btstack_run_loop_async_context_poll_data_sources_from_irq(void)
{
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker);
}
static const btstack_run_loop_t btstack_run_loop_async_context = {
&btstack_run_loop_async_context_init,
&btstack_run_loop_async_context_add_data_source,
&btstack_run_loop_async_context_remove_data_source,
&btstack_run_loop_async_context_enable_data_source_callbacks,
&btstack_run_loop_async_context_disable_data_source_callbacks,
&btstack_run_loop_async_context_set_timer,
&btstack_run_loop_async_context_add_timer,
&btstack_run_loop_async_context_remove_timer,
&btstack_run_loop_async_context_execute,
&btstack_run_loop_async_context_dump_timer,
&btstack_run_loop_async_context_get_time_ms,
&btstack_run_loop_async_context_poll_data_sources_from_irq,
&btstack_run_loop_async_context_execute_on_main_thread,
&btstack_run_loop_async_context_trigger_exit,
};
const btstack_run_loop_t *btstack_run_loop_async_context_get_instance(async_context_t *async_context)
{
assert(!btstack_async_context || btstack_async_context == async_context);
btstack_async_context = async_context;
return &btstack_run_loop_async_context;
}
static void btstack_timeout_reached(__unused async_context_t *context, __unused async_at_time_worker_t *worker) {
// simply wakeup worker
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker);
}
static void btstack_work_pending(__unused async_context_t *context, __unused async_when_pending_worker_t *worker) {
// poll data sources
btstack_run_loop_base_poll_data_sources();
// execute callbacks
btstack_run_loop_base_execute_callbacks();
uint32_t now = to_ms_since_boot(get_absolute_time());
// process timers
btstack_run_loop_base_process_timers(now);
now = to_ms_since_boot(get_absolute_time());
int ms = btstack_run_loop_base_get_time_until_timeout(now);
if (ms == -1) {
async_context_remove_at_time_worker(btstack_async_context, &btstack_timeout_worker);
} else {
async_context_add_at_time_worker_in_ms(btstack_async_context, &btstack_timeout_worker, ms);
}
}
/*
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "btstack_config.h"
#ifdef HAVE_BTSTACK_STDIN
#include "btstack_stdin.h"
#include "btstack_run_loop.h"
#include "pico/stdio.h"
static btstack_data_source_t stdin_data_source;
static void (*stdin_handler)(char c);
// Data source callback, return any character received
static void btstack_stdin_process(__unused struct btstack_data_source *ds, __unused btstack_data_source_callback_type_t callback_type){
if (stdin_handler) {
while(true) {
int c = getchar_timeout_us(0);
if (c == PICO_ERROR_TIMEOUT) return;
(*stdin_handler)(c);
}
}
}
void on_chars_available_callback(__unused void *param) {
btstack_run_loop_poll_data_sources_from_irq();
}
// Test code calls this if HAVE_BTSTACK_STDIN is defined and it wants key presses
void btstack_stdin_setup(void (*handler)(char c)) {
if (stdin_handler) {
return;
}
// set handler
stdin_handler = handler;
// set up polling data_source
btstack_run_loop_set_data_source_handler(&stdin_data_source, &btstack_stdin_process);
btstack_run_loop_enable_data_source_callbacks(&stdin_data_source, DATA_SOURCE_CALLBACK_POLL);
btstack_run_loop_add_data_source(&stdin_data_source);
stdio_set_chars_available_callback(on_chars_available_callback, NULL);
}
// Deinit everything
void btstack_stdin_reset(void){
if (!stdin_handler) {
return;
}
stdio_set_chars_available_callback(NULL, NULL);
stdin_handler = NULL;
btstack_run_loop_remove_data_source(&stdin_data_source);
}
#endif
\ No newline at end of file
/**
* \defgroup pico_btstack pico_btstack
* \brief Integration/wrapper libraries for <a href="https://github.com/bluekitchen/btstack">BTstack</a>
* the documentation for which is <a href="https://bluekitchen-gmbh.com/btstack/">here</a>.
*
* The \c \b pico_btstack_ble library adds the support needed for Bluetooth Low Energy (BLE). The \c \b pico_btstack_classic library adds the support needed for Bluetooth Classic.
* You can link to either library individually, or to both libraries thus enabling dual-mode support provided by BTstack.
*
* To use BTstack you need to provide a \c btstack_config.h file in your source tree and add its location to your include path.
* The BTstack configuration macros \c ENABLE_CLASSIC and \c ENABLE_BLE are defined for you when you link the \c pico_btstack_classic and \c pico_btstack_ble libraries respectively, so you should not define them yourself.
*
* For more details, see <a href="https://bluekitchen-gmbh.com/btstack/develop/#how_to/">How to configure BTstack</a> and the relevant <a href="https://github.com/raspberrypi/pico-examples#pico-w-bluetooth">pico-examples</a>.
*
* The follow ibraries provided for you to link.
* * \c \b pico_btstack_ble - Adds Bluetooth Low Energy (LE) support.
* * \c \b pico_btstack_classic - Adds Bluetooth Classic support.
* * \c \b pico_btstack_sbc_encoder - Adds Bluetooth Sub Band Coding (SBC) encoder support.
* * \c \b pico_btstack_sbc_decoder - Adds Bluetooth Sub Band Coding (SBC) decoder support.
* * \c \b pico_btstack_bnep_lwip - Adds Bluetooth Network Encapsulation Protocol (BNEP) support using LwIP.
* * \c \b pico_btstack_bnep_lwip_sys_freertos - Adds Bluetooth Network Encapsulation Protocol (BNEP) support using LwIP with FreeRTOS for NO_SYS=0.
*
* \note The CMake function pico_btstack_make_gatt_header can be used to run the BTstack compile_gatt tool to make a GATT header file from a BTstack GATT file.
*
* \sa pico_btstack_cyw43 in pico_cyw43_driver, which adds the cyw43 driver support needed for BTstack including BTstack run loop support.
*/
/*
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _PICO_BTSTACK_FLASH_BANK_H
#define _PICO_BTSTACK_FLASH_BANK_H
#include "pico.h"
#include "hal_flash_bank.h"
#ifdef __cplusplus
extern "C" {
#endif
// PICO_CONFIG: PICO_FLASH_BANK_TOTAL_SIZE, Total size of the Bluetooth flash storage. Must be an even multiple of FLASH_SECTOR_SIZE, type=int default=FLASH_SECTOR_SIZE*2, group=pico_btstack
#ifndef PICO_FLASH_BANK_TOTAL_SIZE
#define PICO_FLASH_BANK_TOTAL_SIZE (FLASH_SECTOR_SIZE * 2u)
#endif
// PICO_CONFIG: PICO_FLASH_BANK_STORAGE_OFFSET, Offset in flash of the Bluetooth flash storage, type=int default=PICO_FLASH_SIZE_BYTES-PICO_FLASH_BANK_TOTAL_SIZE, group=pico_btstack
#ifndef PICO_FLASH_BANK_STORAGE_OFFSET
#define PICO_FLASH_BANK_STORAGE_OFFSET (PICO_FLASH_SIZE_BYTES - PICO_FLASH_BANK_TOTAL_SIZE)
#endif
/**
* \brief Return the singleton BTstack HAL flash instance, used for non-volatile storage
* \ingroup pico_btstack
*
* \note By default two sectors at the end of flash are used (see \c PICO_FLASH_BANK_STORAGE_OFFSET
*/
const hal_flash_bank_t *pico_flash_bank_instance(void);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _PICO_BTSTACK_RUN_LOOP_ASYNC_CONTEXT_H
#define _PICO_BTSTACK_RUN_LOOP_ASYNC_CONTEXT_H
#include "btstack_run_loop.h"
#include "pico/async_context.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initialize and eturn the singleton BTstack run loop instance that integrates with the async_context API
* \ingroup pico_btstack
*
* \param context the async_context instance that provides the abstraction for handling asynchronous work.
* \return the BTstack run loop instance
*/
const btstack_run_loop_t *btstack_run_loop_async_context_get_instance(async_context_t *context);
#ifdef __cplusplus
}
#endif
#endif
......@@ -20,7 +20,7 @@ if (PICO_CYW43_SUPPORTED) # set by BOARD=pico-w
if (NOT TARGET pico_lwip)
message(WARNING "lwIP is not available; Full Pico W wireless support will be unavailable")
else()
message("Pico W wireless build support available.")
message("Pico W Wi-Fi build support available.")
pico_add_library(pico_cyw43_arch_poll NOFLAG)
target_compile_definitions(pico_cyw43_arch_poll_headers INTERFACE
PICO_CYW43_ARCH_POLL=1
......
......@@ -47,7 +47,7 @@ void cyw43_arch_enable_ap_mode(const char *ssid, const char *password, uint32_t
#if PICO_CYW43_ARCH_DEBUG_ENABLED
// Return a string for the wireless state
const char* cyw43_tcpip_link_status_name(int status)
static const char* cyw43_tcpip_link_status_name(int status)
{
switch (status) {
case CYW43_LINK_DOWN:
......
......@@ -15,6 +15,10 @@
#include <lwip/tcpip.h>
#endif
#if CYW43_ENABLE_BLUETOOTH
#include "pico/btstack_cyw43.h"
#endif
#if NO_SYS
#error example_cyw43_arch_freetos_sys requires NO_SYS=0
#endif
......@@ -44,6 +48,9 @@ int cyw43_arch_init(void) {
bool ok = cyw43_driver_init(context);
#if CYW43_LWIP
ok &= lwip_freertos_init(context);
#endif
#if CYW43_ENABLE_BLUETOOTH
ok &= btstack_cyw43_init(context);
#endif
if (!ok) {
cyw43_arch_deinit();
......@@ -55,6 +62,9 @@ int cyw43_arch_init(void) {
void cyw43_arch_deinit(void) {
async_context_t *context = cyw43_arch_async_context();
#if CYW43_ENABLE_BLUETOOTH
btstack_cyw43_deinit(context);
#endif
// there is a bit of a circular dependency here between lwIP and cyw43_driver. We
// shut down cyw43_driver first as it has IRQs calling back into lwIP. Also lwIP itself
// does not actually get shut down.
......
......@@ -13,6 +13,10 @@
#include "pico/lwip_nosys.h"
#endif
#if CYW43_ENABLE_BLUETOOTH
#include "pico/btstack_cyw43.h"
#endif
#if CYW43_LWIP && !NO_SYS
#error PICO_CYW43_ARCH_POLL requires lwIP NO_SYS=1
#endif
......@@ -35,6 +39,9 @@ int cyw43_arch_init(void) {
bool ok = cyw43_driver_init(context);
#if CYW43_LWIP
ok &= lwip_nosys_init(context);
#endif
#if CYW43_ENABLE_BLUETOOTH
ok &= btstack_cyw43_init(context);
#endif
if (!ok) {
cyw43_arch_deinit();
......@@ -46,6 +53,9 @@ int cyw43_arch_init(void) {
void cyw43_arch_deinit(void) {
async_context_t *context = cyw43_arch_async_context();
#if CYW43_ENABLE_BLUETOOTH
btstack_cyw43_deinit(context);
#endif
// there is a bit of a circular dependency here between lwIP and cyw43_driver. We
// shut down cyw43_driver first as it has IRQs calling back into lwIP. Also lwIP itself
// does not actually get shut down.
......
......@@ -14,6 +14,10 @@
#include "pico/lwip_nosys.h"
#endif
#if CYW43_ENABLE_BLUETOOTH
#include "pico/btstack_cyw43.h"
#endif
#if CYW43_LWIP && !NO_SYS
#error PICO_CYW43_ARCH_THREADSAFE_BACKGROUND requires lwIP NO_SYS=1
#endif
......@@ -41,6 +45,9 @@ int cyw43_arch_init(void) {
bool ok = cyw43_driver_init(context);
#if CYW43_LWIP
ok &= lwip_nosys_init(context);
#endif
#if CYW43_ENABLE_BLUETOOTH
ok &= btstack_cyw43_init(context);
#endif
if (!ok) {
cyw43_arch_deinit();
......@@ -52,6 +59,9 @@ int cyw43_arch_init(void) {
void cyw43_arch_deinit(void) {
async_context_t *context = cyw43_arch_async_context();
#if CYW43_ENABLE_BLUETOOTH
btstack_cyw43_deinit(context);
#endif
// there is a bit of a circular dependency here between lwIP and cyw43_driver. We
// shut down cyw43_driver first as it has IRQs calling back into lwIP. Also lwIP itself
// does not actually get shut down.
......
......@@ -18,6 +18,8 @@ endif()
if (EXISTS ${PICO_CYW43_DRIVER_PATH}/${CYW43_DRIVER_TEST_FILE})
message("cyw43-driver available at ${PICO_CYW43_DRIVER_PATH}")
add_subdirectory(cybt_shared_bus)
pico_register_common_scope_var(PICO_CYW43_DRIVER_PATH)
# base driver without our bus
......@@ -40,47 +42,51 @@ if (EXISTS ${PICO_CYW43_DRIVER_PATH}/${CYW43_DRIVER_TEST_FILE})
target_include_directories(pico_cyw43_driver_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
pico_mirrored_target_link_libraries(pico_cyw43_driver INTERFACE cyw43_driver)
# Firmware stuff
set(CYW43_FIRMWARE_BIN 43439A0-7.95.49.00.combined)
string(REGEX REPLACE [\\\.\-] _ CYW43_FIRMWARE_BIN_ ${CYW43_FIRMWARE_BIN})
string(REGEX MATCH [^_]+_?[^_]*_?[^_]*_?[^_]*_?[^_]* CYW43_FIRMWARE_PRETTY ${CYW43_FIRMWARE_BIN_})
set(CYW43_FIRMWARE_PRETTY fw_${CYW43_FIRMWARE_PRETTY})
set(RESOURCE_SECNAME .big_const)
set(RESOURCE_SECFLAGS contents,alloc,load,readonly,data)
set(CYW43_FIRMWARE_OBJ ${CMAKE_CURRENT_BINARY_DIR}/cyw43_resource.o)
add_custom_target(cyw43_firmware_package DEPENDS ${CYW43_FIRMWARE_OBJ})
# cyw43_resource.o contains the WiFi and BT firmware as a binary blob
add_custom_command(
OUTPUT ${CYW43_FIRMWARE_OBJ}
DEPENDS ${PICO_CYW43_DRIVER_PATH}/firmware/${CYW43_FIRMWARE_BIN}
WORKING_DIRECTORY ${PICO_CYW43_DRIVER_PATH}/firmware
COMMAND ${CMAKE_OBJCOPY} -I binary -O elf32-littlearm -B arm
--readonly-text
--rename-section .data=${RESOURCE_SECNAME},${RESOURCE_SECFLAGS}
--redefine-sym _binary_${CYW43_FIRMWARE_BIN_}_start=${CYW43_FIRMWARE_PRETTY}_start
--redefine-sym _binary_${CYW43_FIRMWARE_BIN_}_end=${CYW43_FIRMWARE_PRETTY}_end
--redefine-sym _binary_${CYW43_FIRMWARE_BIN_}_size=${CYW43_FIRMWARE_PRETTY}_size
${CYW43_FIRMWARE_BIN} ${CYW43_FIRMWARE_OBJ}
VERBATIM)
# cyw43_driver_picow is cyw43_driver plus Pico W specific bus implementation, and Pico W firmware
# cyw43_driver_picow is cyw43_driver plus Pico W specific bus implementation
pico_add_library(cyw43_driver_picow NOFLAG)
target_sources(cyw43_driver_picow INTERFACE
${CMAKE_CURRENT_LIST_DIR}/cyw43_bus_pio_spi.c
)
pico_generate_pio_header(cyw43_driver_picow_headers ${CMAKE_CURRENT_LIST_DIR}/cyw43_bus_pio_spi.pio)
add_dependencies(cyw43_driver_picow INTERFACE cyw43_firmware_package)
target_link_libraries(cyw43_driver_picow INTERFACE
${CYW43_FIRMWARE_OBJ}
)
pico_generate_pio_header(cyw43_driver_picow ${CMAKE_CURRENT_LIST_DIR}/cyw43_bus_pio_spi.pio)
pico_mirrored_target_link_libraries(cyw43_driver_picow INTERFACE
cyw43_driver
cybt_shared_bus
hardware_pio
hardware_dma
hardware_exception
)
# Note: This is used by MP, so check for issues when making changes
# e.g. Don't add new depenedences
pico_add_library(pico_btstack_hci_transport_cyw43 NOFLAG)
target_sources(pico_btstack_hci_transport_cyw43 INTERFACE
${CMAKE_CURRENT_LIST_DIR}/btstack_hci_transport_cyw43.c
)
target_include_directories(pico_btstack_hci_transport_cyw43_headers INTERFACE
${CMAKE_CURRENT_LIST_DIR}/include
)
target_compile_definitions(pico_btstack_hci_transport_cyw43_headers INTERFACE
CYW43_ENABLE_BLUETOOTH=1
)
if (TARGET pico_btstack_base)
message("Pico W Bluetooth build support available.")
pico_add_library(pico_btstack_cyw43)
target_sources(pico_btstack_cyw43 INTERFACE
${CMAKE_CURRENT_LIST_DIR}/btstack_cyw43.c
)
target_include_directories(pico_btstack_cyw43_headers INTERFACE
${CMAKE_CURRENT_LIST_DIR}/include
)
pico_mirrored_target_link_libraries(pico_btstack_cyw43 INTERFACE
pico_btstack_base
pico_btstack_flash_bank
pico_btstack_run_loop_async_context
pico_cyw43_arch
pico_btstack_hci_transport_cyw43
)
endif()
pico_promote_common_scope_vars()
endif()
/*
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "ble/le_device_db_tlv.h"
#include "classic/btstack_link_key_db_tlv.h"
#include "btstack_tlv.h"
#include "btstack_tlv_flash_bank.h"
#include "btstack_memory.h"
#include "hci.h"
#if WANT_HCI_DUMP
#include "hci_dump.h"
#ifdef ENABLE_SEGGER_RTT
#include "hci_dump_segger_rtt_stdout.h"
#else
#include "hci_dump_embedded_stdout.h"
#endif
#endif
#include "pico/btstack_hci_transport_cyw43.h"
#include "pico/btstack_run_loop_async_context.h"
#include "pico/btstack_flash_bank.h"
#include "pico/btstack_cyw43.h"
static void setup_tlv(void) {
static btstack_tlv_flash_bank_t btstack_tlv_flash_bank_context;
const hal_flash_bank_t *hal_flash_bank_impl = pico_flash_bank_instance();
const btstack_tlv_t *btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(
&btstack_tlv_flash_bank_context,
hal_flash_bank_impl,
NULL);
// setup global TLV
btstack_tlv_set_instance(btstack_tlv_impl, &btstack_tlv_flash_bank_context);
#ifdef ENABLE_CLASSIC
const btstack_link_key_db_t *btstack_link_key_db = btstack_link_key_db_tlv_get_instance(btstack_tlv_impl, &btstack_tlv_flash_bank_context);
hci_set_link_key_db(btstack_link_key_db);
#endif
#ifdef ENABLE_BLE
// configure LE Device DB for TLV
le_device_db_tlv_configure(btstack_tlv_impl, &btstack_tlv_flash_bank_context);
#endif
}
bool btstack_cyw43_init(async_context_t *context) {
// Initialise bluetooth
btstack_memory_init();
btstack_run_loop_init(btstack_run_loop_async_context_get_instance(context));
#if WANT_HCI_DUMP
#ifdef ENABLE_SEGGER_RTT
hci_dump_init(hci_dump_segger_rtt_stdout_get_instance());
#else
hci_dump_init(hci_dump_embedded_stdout_get_instance());
#endif
#endif
hci_init(hci_transport_cyw43_instance(), NULL);
// setup TLV storage
setup_tlv();
return true;
}
void btstack_cyw43_deinit(__unused async_context_t *context) {
hci_power_control(HCI_POWER_OFF);
hci_close();
btstack_run_loop_deinit();
btstack_memory_deinit();
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment