Skip to content

Incorporate BlueKitchen BTstack as an alternative stack to NimBLE for ubluetooth module #5672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Mar 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@
[submodule "lib/mynewt-nimble"]
path = lib/mynewt-nimble
url = https://github.com/apache/mynewt-nimble.git
[submodule "lib/btstack"]
path = lib/btstack
url = https://github.com/bluekitchen/btstack.git
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ jobs:
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/stm32 submodules
- git submodule update --init lib/btstack
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_F091RC
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 NANBOX=1
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 NANBOX=1 MICROPY_BLUETOOTH_NIMBLE=0 MICROPY_BLUETOOTH_BTSTACK=1
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1'
- make ${MAKEOPTS} -C ports/stm32 BOARD=B_L072Z_LRWAN1
- make ${MAKEOPTS} -C ports/stm32 BOARD=STM32L476DISC
Expand Down
100 changes: 76 additions & 24 deletions drivers/cyw43/cywbt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Damien P. George
* Copyright (c) 2019-2020 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -31,8 +31,7 @@
#include "py/mphal.h"
#include "pin_static_af.h"
#include "uart.h"
#include "cywbt.h"
#include "nimble/hci_uart.h"
#include "extmod/modbluetooth_hci.h"

#if MICROPY_PY_NETWORK_CYW43

Expand All @@ -42,7 +41,7 @@ extern const char fw_4343WA1_7_45_98_50_start;
/******************************************************************************/
// CYW BT HCI low-level driver

static void cywbt_wait_cts_low(void) {
STATIC void cywbt_wait_cts_low(void) {
mp_hal_pin_config(pyb_pin_BT_CTS, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
for (int i = 0; i < 200; ++i) {
if (mp_hal_pin_read(pyb_pin_BT_CTS) == 0) {
Expand All @@ -53,13 +52,13 @@ static void cywbt_wait_cts_low(void) {
mp_hal_pin_config_alt_static(pyb_pin_BT_CTS, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_USART6_CTS);
}

static int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) {
uart_tx_strn(&bt_hci_uart_obj, (void*)buf, len);
STATIC int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) {
uart_tx_strn(&mp_bluetooth_hci_uart_obj, (void*)buf, len);
for (int i = 0; i < 6; ++i) {
while (!uart_rx_any(&bt_hci_uart_obj)) {
while (!uart_rx_any(&mp_bluetooth_hci_uart_obj)) {
MICROPY_EVENT_POLL_HOOK
}
buf[i] = uart_rx_char(&bt_hci_uart_obj);
buf[i] = uart_rx_char(&mp_bluetooth_hci_uart_obj);
}

// expect a comand complete event (event 0x0e)
Expand All @@ -76,17 +75,17 @@ static int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) {

int sz = buf[2] - 3;
for (int i = 0; i < sz; ++i) {
while (!uart_rx_any(&bt_hci_uart_obj)) {
while (!uart_rx_any(&mp_bluetooth_hci_uart_obj)) {
MICROPY_EVENT_POLL_HOOK
}
buf[i] = uart_rx_char(&bt_hci_uart_obj);
buf[i] = uart_rx_char(&mp_bluetooth_hci_uart_obj);
}

return 0;
}

static int cywbt_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_buf) {
uint8_t *buf = bt_hci_cmd_buf;
STATIC int cywbt_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_buf) {
uint8_t *buf = mp_bluetooth_hci_cmd_buf;
buf[0] = 0x01;
buf[1] = ocf;
buf[2] = ogf << 2 | ocf >> 8;
Expand All @@ -97,32 +96,32 @@ static int cywbt_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *para
return cywbt_hci_cmd_raw(4 + param_len, buf);
}

static void put_le16(uint8_t *buf, uint16_t val) {
STATIC void put_le16(uint8_t *buf, uint16_t val) {
buf[0] = val;
buf[1] = val >> 8;
}

static void put_le32(uint8_t *buf, uint32_t val) {
STATIC void put_le32(uint8_t *buf, uint32_t val) {
buf[0] = val;
buf[1] = val >> 8;
buf[2] = val >> 16;
buf[3] = val >> 24;
}

static int cywbt_set_baudrate(uint32_t baudrate) {
STATIC int cywbt_set_baudrate(uint32_t baudrate) {
uint8_t buf[6];
put_le16(buf, 0);
put_le32(buf + 2, baudrate);
return cywbt_hci_cmd(0x3f, 0x18, 6, buf);
}

// download firmware
static int cywbt_download_firmware(const uint8_t *firmware) {
STATIC int cywbt_download_firmware(const uint8_t *firmware) {
cywbt_hci_cmd(0x3f, 0x2e, 0, NULL);

bool last_packet = false;
while (!last_packet) {
uint8_t *buf = bt_hci_cmd_buf;
uint8_t *buf = mp_bluetooth_hci_cmd_buf;
memcpy(buf + 1, firmware, 3);
firmware += 3;
last_packet = buf[1] == 0x4e;
Expand All @@ -149,15 +148,15 @@ static int cywbt_download_firmware(const uint8_t *firmware) {
cywbt_wait_cts_low();
mp_hal_pin_config(pyb_pin_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_DOWN, 0); // Select chip antenna (could also select external)

nimble_hci_uart_set_baudrate(115200);
mp_bluetooth_hci_uart_set_baudrate(115200);
cywbt_set_baudrate(3000000);
nimble_hci_uart_set_baudrate(3000000);
mp_bluetooth_hci_uart_set_baudrate(3000000);

return 0;
}

int cywbt_init(void) {
// This is called from Nimble via hal_uart_config which will have already initialized the UART.
int mp_bluetooth_hci_controller_init(void) {
// This is called immediately after the UART is initialised during stack initialisation.

mp_hal_pin_output(pyb_pin_BT_REG_ON);
mp_hal_pin_low(pyb_pin_BT_REG_ON);
Expand All @@ -172,11 +171,11 @@ int cywbt_init(void) {
return 0;
}

int cywbt_activate(void) {
int mp_bluetooth_hci_controller_activate(void) {
uint8_t buf[256];

mp_hal_pin_low(pyb_pin_BT_REG_ON);
nimble_hci_uart_set_baudrate(115200);
mp_bluetooth_hci_uart_set_baudrate(115200);
mp_hal_delay_ms(100);
mp_hal_pin_high(pyb_pin_BT_REG_ON);
cywbt_wait_cts_low();
Expand All @@ -186,7 +185,7 @@ int cywbt_activate(void) {

// Change baudrate
cywbt_set_baudrate(3000000);
nimble_hci_uart_set_baudrate(3000000);
mp_bluetooth_hci_uart_set_baudrate(3000000);

cywbt_download_firmware((const uint8_t*)CYWBT_FW_ADDR);

Expand Down Expand Up @@ -220,4 +219,57 @@ int cywbt_activate(void) {
return 0;
}

int mp_bluetooth_hci_controller_deactivate(void) {
mp_hal_pin_low(pyb_pin_BT_REG_ON);

return 0;
}

#ifdef pyb_pin_BT_DEV_WAKE
STATIC uint32_t bt_sleep_ticks;
#endif

int mp_bluetooth_hci_controller_sleep_maybe(void) {
#ifdef pyb_pin_BT_DEV_WAKE
if (mp_hal_pin_read(pyb_pin_BT_DEV_WAKE) == 0) {
if (mp_hal_ticks_ms() - bt_sleep_ticks > 500) {
mp_hal_pin_high(pyb_pin_BT_DEV_WAKE); // let sleep
}
}
#endif
return 0;
}

bool mp_bluetooth_hci_controller_woken(void) {
#ifdef pyb_pin_BT_HOST_WAKE
bool host_wake = mp_hal_pin_read(pyb_pin_BT_HOST_WAKE);
/*
// this is just for info/tracing purposes
static bool last_host_wake = false;
if (host_wake != last_host_wake) {
printf("HOST_WAKE change %d -> %d\n", last_host_wake, host_wake);
last_host_wake = host_wake;
}
*/
return host_wake;
#else
return true;
#endif
}

int mp_bluetooth_hci_controller_wakeup(void) {
#ifdef pyb_pin_BT_DEV_WAKE
bt_sleep_ticks = mp_hal_ticks_ms();

if (mp_hal_pin_read(pyb_pin_BT_DEV_WAKE) == 1) {
mp_hal_pin_low(pyb_pin_BT_DEV_WAKE); // wake up
// Use delay_us rather than delay_ms to prevent running the scheduler (which
// might result in more BLE operations).
mp_hal_delay_us(5000); // can't go lower than this
}
#endif

return 0;
}

#endif
35 changes: 0 additions & 35 deletions drivers/cyw43/cywbt.h

This file was deleted.

48 changes: 48 additions & 0 deletions extmod/btstack/btstack.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Makefile directives for BlueKitchen BTstack

ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1)

BTSTACK_EXTMOD_DIR = extmod/btstack

EXTMOD_SRC_C += extmod/btstack/modbluetooth_btstack.c

INC += -I$(TOP)/$(BTSTACK_EXTMOD_DIR)

CFLAGS_MOD += -DMICROPY_BLUETOOTH_BTSTACK=1

BTSTACK_DIR = $(TOP)/lib/btstack

include $(BTSTACK_DIR)/src/Makefile.inc
include $(BTSTACK_DIR)/src/ble/Makefile.inc

INC += -I$(BTSTACK_DIR)/src
INC += -I$(BTSTACK_DIR)/3rd-party/bluedroid/decoder/include
INC += -I$(BTSTACK_DIR)/3rd-party/bluedroid/encoder/include
INC += -I$(BTSTACK_DIR)/3rd-party/md5
INC += -I$(BTSTACK_DIR)/3rd-party/yxml

SRC_BTSTACK = \
$(addprefix lib/btstack/src/, $(SRC_FILES)) \
$(addprefix lib/btstack/src/ble/, $(filter-out %_tlv.c, $(SRC_BLE_FILES))) \
lib/btstack/platform/embedded/btstack_run_loop_embedded.c \

ifeq ($MICROPY_BLUETOOTH_BTSTACK_ENABLE_CLASSIC,1)
include $(BTSTACK_DIR)/src/classic/Makefile.inc
SRC_BTSTACK += \
$(addprefix lib/btstack/src/classic/, $(SRC_CLASSIC_FILES))
endif

SRC_LIB += $(SRC_BTSTACK)

#$(BUILD)/lib/btstack/src/classic/btstack_link_key_db_static.o: CFLAGS += -Wno-error=pointer-arith

# Incorrect %u, should be %lu.
$(BUILD)/lib/btstack/src/classic/a2dp_source.o: CFLAGS += -Wno-error=format=
$(BUILD)/lib/btstack/src/classic/btstack_sbc_decoder_bluedroid.o: CFLAGS += -Wno-error=format=
$(BUILD)/lib/btstack/src/classic/btstack_link_key_db_tlv.o: CFLAGS += -Wno-error=format=
$(BUILD)/lib/btstack/src/classic/goep_client.o: CFLAGS += -Wno-error=format=
$(BUILD)/lib/btstack/src/ble/le_device_db_tlv.o: CFLAGS += -Wno-error=format=



endif
44 changes: 44 additions & 0 deletions extmod/btstack/btstack_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef MICROPY_INCLUDED_EXTMOD_BTSTACK_BTSTACK_CONFIG_H
#define MICROPY_INCLUDED_EXTMOD_BTSTACK_BTSTACK_CONFIG_H

// BTstack features that can be enabled
#define ENABLE_BLE
#define ENABLE_LE_PERIPHERAL
#define ENABLE_LE_CENTRAL
// #define ENABLE_CLASSIC
#define ENABLE_LE_DATA_CHANNELS
// #define ENABLE_LOG_INFO
#define ENABLE_LOG_ERROR

// BTstack configuration. buffers, sizes, ...
#define HCI_ACL_PAYLOAD_SIZE 1021
#define MAX_NR_GATT_CLIENTS 1
#define MAX_NR_HCI_CONNECTIONS 1
#define MAX_NR_L2CAP_SERVICES 3
#define MAX_NR_L2CAP_CHANNELS 3
#define MAX_NR_RFCOMM_MULTIPLEXERS 1
#define MAX_NR_RFCOMM_SERVICES 1
#define MAX_NR_RFCOMM_CHANNELS 1
#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 2
#define MAX_NR_BNEP_SERVICES 1
#define MAX_NR_BNEP_CHANNELS 1
#define MAX_NR_HFP_CONNECTIONS 1
#define MAX_NR_WHITELIST_ENTRIES 1
#define MAX_NR_SM_LOOKUP_ENTRIES 3
#define MAX_NR_SERVICE_RECORD_ITEMS 1
#define MAX_NR_AVDTP_STREAM_ENDPOINTS 1
#define MAX_NR_AVDTP_CONNECTIONS 1
#define MAX_NR_AVRCP_CONNECTIONS 1

#define MAX_NR_LE_DEVICE_DB_ENTRIES 4

// Link Key DB and LE Device DB using TLV on top of Flash Sector interface
// #define NVM_NUM_DEVICE_DB_ENTRIES 16

// We don't give btstack a malloc, so use a fixed-size ATT DB.
#define MAX_ATT_DB_SIZE 512

// BTstack HAL configuration
#define HAVE_EMBEDDED_TIME_MS

#endif // MICROPY_INCLUDED_EXTMOD_BTSTACK_BTSTACK_CONFIG_H
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy