Skip to content
Open
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
42 changes: 28 additions & 14 deletions lib/pbio/drv/bluetooth/bluetooth_btstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,18 +228,23 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
const uint8_t *rp = hci_event_command_complete_get_return_parameters(packet);
switch (hci_event_command_complete_get_command_opcode(packet)) {
case HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION: {
uint16_t lmp_pal_subversion = pbio_get_uint16_le(&rp[7]);
pbdrv_bluetooth_btstack_set_chipset(lmp_pal_subversion);
pbdrv_bluetooth_btstack_device_discriminator_t info;
info.hci_version = rp[1];
info.hci_revision = pbio_get_uint16_le(&rp[2]);
info.lmp_pal_version = rp[4];
info.manufacturer = pbio_get_uint16_le(&rp[5]);
info.lmp_pal_subversion = pbio_get_uint16_le(&rp[7]);
Comment on lines +232 to +236
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wouldn't hurt to put this unpacking in a separate function.

pbdrv_bluetooth_btstack_set_chipset(&info);

#if DEBUG
// Show version in ev3dev format.
uint16_t chip = (lmp_pal_subversion & 0x7C00) >> 10;
uint16_t min_ver = (lmp_pal_subversion & 0x007F);
uint16_t maj_ver = (lmp_pal_subversion & 0x0380) >> 7;
if (lmp_pal_subversion & 0x8000) {
uint16_t chip = (info.lmp_pal_subversion & 0x7C00) >> 10;
uint16_t min_ver = (info.lmp_pal_subversion & 0x007F);
uint16_t maj_ver = (info.lmp_pal_subversion & 0x0380) >> 7;
if (info.lmp_pal_subversion & 0x8000) {
maj_ver |= 0x0008;
}
DEBUG_PRINT("LMP %04x: TIInit_%d.%d.%d.bts\n", lmp_pal_subversion, chip, maj_ver, min_ver);
DEBUG_PRINT("LMP %04x: TIInit_%d.%d.%d.bts\n", info.lmp_pal_subversion, chip, maj_ver, min_ver);
#endif
break;
}
Expand Down Expand Up @@ -1000,6 +1005,13 @@ static void bluetooth_btstack_run_loop_execute(void) {
// not used
}

static bool do_poll_handler;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should be volatile if pbdrv_bluetooth_btstack_run_loop_trigger() is called from IRQ handlers.


static void pbdrv_bluetooth_btstack_run_loop_trigger(void) {
do_poll_handler = true;
pbio_os_request_poll();
}

static const btstack_run_loop_t bluetooth_btstack_run_loop = {
.init = btstack_run_loop_base_init,
.add_data_source = btstack_run_loop_base_add_data_source,
Expand All @@ -1012,15 +1024,9 @@ static const btstack_run_loop_t bluetooth_btstack_run_loop = {
.execute = bluetooth_btstack_run_loop_execute,
.dump_timer = btstack_run_loop_base_dump_timer,
.get_time_ms = pbdrv_clock_get_ms,
.poll_data_sources_from_irq = pbdrv_bluetooth_btstack_run_loop_trigger,
};

static bool do_poll_handler;

void pbdrv_bluetooth_btstack_run_loop_trigger(void) {
do_poll_handler = true;
pbio_os_request_poll();
}

static pbio_os_process_t pbdrv_bluetooth_hci_process;

/**
Expand All @@ -1034,6 +1040,8 @@ static pbio_error_t pbdrv_bluetooth_hci_process_thread(pbio_os_state_t *state, v
btstack_run_loop_base_poll_data_sources();
}

pbdrv_bluetooth_btstack_platform_poll();

static pbio_os_timer_t btstack_timer = {
.duration = 1,
};
Expand All @@ -1055,6 +1063,12 @@ const uint8_t cc256x_init_script[] = {};

void pbdrv_bluetooth_init_hci(void) {

// Proceed to start Bluetooth process only if platform init passes.
pbio_error_t err = pbdrv_bluetooth_btstack_platform_init();
if (err != PBIO_SUCCESS) {
return;
}

static btstack_packet_callback_registration_t hci_event_callback_registration;

#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
Expand Down
36 changes: 34 additions & 2 deletions lib/pbio/drv/bluetooth/bluetooth_btstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@
#include <btstack_control.h>
#include <btstack_uart_block.h>

#include <pbio/error.h>

/**
* Optional platform initialization before BTstack takes over.
*
* Unlike some BTstack init code, this is guaranteed to be called only once.
*
* @return Any error code to skip Bluetooth or ::PBIO_SUCCESS to proceed.
*/
pbio_error_t pbdrv_bluetooth_btstack_platform_init(void);

/**
* Optional platform poll handler, called on every process iteration.
*/
void pbdrv_bluetooth_btstack_platform_poll(void);

/** Chipset info */
typedef struct {
/** Version */
Expand All @@ -21,15 +37,31 @@ typedef struct {
const uint32_t init_script_size;
} pbdrv_bluetooth_btstack_chipset_info_t;

void pbdrv_bluetooth_btstack_run_loop_trigger(void);
/**
* Device discriminator info from the HCI read local version information command.
*/
typedef struct {
/** HCI version. */
uint8_t hci_version;
/** HCI revision. */
uint16_t hci_revision;
/** LMP/PAL version. */
uint8_t lmp_pal_version;
/** Manufacturer. */
uint16_t manufacturer;
/** LMP/PAL subversion. */
uint16_t lmp_pal_subversion;
} pbdrv_bluetooth_btstack_device_discriminator_t;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put local_version_info in the name rather than device_discriminator. The latter describes one use for it, but the former describes what it actually is and where it came from.

This is just an unpacked version of the return values from HCI Read Local Version Info.


/**
* Hook called when BTstack reads the local version information.
*
* This is called _after_ hci_set_chipset but _before_ the init script is sent
* over the wire, so this can be used to dynamically select the init script.
*
* @param device_info The device information read from the Bluetooth chip.
*/
void pbdrv_bluetooth_btstack_set_chipset(uint16_t lmp_pal_subversion);
void pbdrv_bluetooth_btstack_set_chipset(pbdrv_bluetooth_btstack_device_discriminator_t *device_info);

typedef struct {
const hci_transport_t *(*transport_instance)(void);
Expand Down
19 changes: 13 additions & 6 deletions lib/pbio/drv/bluetooth/bluetooth_btstack_ev3.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,15 @@ static const hci_dump_t bluetooth_btstack_classic_hci_dump = {
#define DEBUG_PRINT(...)
#endif

void pbdrv_bluetooth_btstack_set_chipset(uint16_t lmp_pal_subversion) {
const pbdrv_bluetooth_btstack_chipset_info_t *info = lmp_pal_subversion == cc2560_info.lmp_version ?
pbio_error_t pbdrv_bluetooth_btstack_platform_init(void) {
return PBIO_SUCCESS;
}

void pbdrv_bluetooth_btstack_platform_poll(void) {
}

void pbdrv_bluetooth_btstack_set_chipset(pbdrv_bluetooth_btstack_device_discriminator_t *device_info) {
const pbdrv_bluetooth_btstack_chipset_info_t *info = device_info->lmp_pal_subversion == cc2560_info.lmp_version ?
&cc2560_info : &cc2560a_info;
btstack_chipset_cc256x_set_init_script((uint8_t *)info->init_script, info->init_script_size);

Expand Down Expand Up @@ -218,7 +225,7 @@ static volatile bool rx_interrupts_enabled;
void pbdrv_bluetooth_btstack_ev3_handle_tx_complete(void) {
EDMA3DisableTransfer(EDMA_BASE, DMA_CHA_TX, EDMA3_TRIG_MODE_EVENT);
dma_write_complete = true;
pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
}

static inline void uart_rx_interrupt_set_enabled(bool enabled) {
Expand Down Expand Up @@ -250,11 +257,11 @@ static void uart_rx_interrupt_handler(void) {
// RX buffer full, disable further RX interrupts until btstack consumes
// some of the data.
uart_rx_interrupt_set_enabled(false);
pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
return;
}
if (read_buf && (size_t)read_buf_len <= lwrb_get_full(&uart_rx_pending_ring_buffer)) {
pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
}
}

Expand Down Expand Up @@ -427,7 +434,7 @@ static void pbdrv_bluetooth_btstack_ev3_receive_block(uint8_t *buffer,

read_buf = buffer;
read_buf_len = len;
pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
}

static void pbdrv_bluetooth_btstack_ev3_send_block(const uint8_t *data,
Expand Down
15 changes: 12 additions & 3 deletions lib/pbio/drv/bluetooth/bluetooth_btstack_stm32_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,16 @@

#include <pbdrv/gpio.h>

void pbdrv_bluetooth_btstack_set_chipset(uint16_t lmp_pal_subversion) {
#include <pbio/error.h>

pbio_error_t pbdrv_bluetooth_btstack_platform_init(void) {
return PBIO_SUCCESS;
}

void pbdrv_bluetooth_btstack_platform_poll(void) {
}

void pbdrv_bluetooth_btstack_set_chipset(pbdrv_bluetooth_btstack_device_discriminator_t *device_info) {

const pbdrv_bluetooth_btstack_platform_data_t *pdata =
&pbdrv_bluetooth_btstack_platform_data;
Expand Down Expand Up @@ -92,12 +101,12 @@ static void (*block_received)(void);

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
send_complete = true;
pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
receive_complete = true;
pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
}

static int btstack_stm32_hal_init(const btstack_uart_config_t *config) {
Expand Down
14 changes: 10 additions & 4 deletions lib/pbio/test/drv/test_bluetooth_btstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,9 +770,15 @@ static void handle_data_source(btstack_data_source_t *ds, btstack_data_source_c
}
}

void pbdrv_bluetooth_btstack_set_chipset(uint16_t lmp_pal_subversion) {
void pbdrv_bluetooth_btstack_set_chipset(pbdrv_bluetooth_btstack_device_discriminator_t *device_info) {
}

pbio_error_t pbdrv_bluetooth_btstack_platform_init(void) {
return PBIO_SUCCESS;
}

void pbdrv_bluetooth_btstack_platform_poll(void) {
}

static pbio_error_t test_btstack_run_loop_contiki_poll(pbio_os_state_t *state, void *context) {
static btstack_data_source_t data_source;
Expand All @@ -786,20 +792,20 @@ static pbio_error_t test_btstack_run_loop_contiki_poll(pbio_os_state_t *state, v
btstack_run_loop_enable_data_source_callbacks(&data_source, DATA_SOURCE_CALLBACK_POLL);
btstack_run_loop_add_data_source(&data_source);

pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
PBIO_OS_AWAIT_ONCE(state);
tt_want_uint_op(callback_count, ==, 1);

callback_count = 0;
btstack_run_loop_disable_data_source_callbacks(&data_source, DATA_SOURCE_CALLBACK_POLL);
pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
PBIO_OS_AWAIT_ONCE(state);
tt_want_uint_op(callback_count, ==, 0);

callback_count = 0;
btstack_run_loop_enable_data_source_callbacks(&data_source, DATA_SOURCE_CALLBACK_POLL);
btstack_run_loop_remove_data_source(&data_source);
pbdrv_bluetooth_btstack_run_loop_trigger();
btstack_run_loop_poll_data_sources_from_irq();
PBIO_OS_AWAIT_ONCE(state);
tt_want_uint_op(callback_count, ==, 0);

Expand Down
Loading