diff --git a/extmod/btstack/btstack.mk b/extmod/btstack/btstack.mk index 17bbb16f88..9e1857263b 100644 --- a/extmod/btstack/btstack.mk +++ b/extmod/btstack/btstack.mk @@ -30,7 +30,6 @@ 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_USB),1) ifeq ($(MICROPY_BLUETOOTH_BTSTACK_H4),1) diff --git a/ports/stm32/mpbtstackport.c b/ports/stm32/mpbtstackport.c index abe4f6d3e2..795534042e 100644 --- a/ports/stm32/mpbtstackport.c +++ b/ports/stm32/mpbtstackport.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Damien P. George + * Copyright (c) 2020-2021 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 @@ -31,31 +31,79 @@ #if MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_BTSTACK #include "lib/btstack/src/btstack.h" -#include "lib/btstack/platform/embedded/btstack_run_loop_embedded.h" -#include "lib/btstack/platform/embedded/hal_cpu.h" -#include "lib/btstack/platform/embedded/hal_time_ms.h" - #include "extmod/mpbthci.h" #include "extmod/btstack/btstack_hci_uart.h" #include "extmod/btstack/modbluetooth_btstack.h" #include "mpbthciport.h" -// The IRQ functionality in btstack_run_loop_embedded.c is not used, so the -// following three functions are empty. +void mp_bluetooth_hci_poll_in_ms(uint32_t ms); -void hal_cpu_disable_irqs(void) { +static btstack_linked_list_t mp_btstack_runloop_timers; + +static void mp_btstack_runloop_init(void) { + mp_btstack_runloop_timers = NULL; } -void hal_cpu_enable_irqs(void) { +static void mp_btstack_runloop_set_timer(btstack_timer_source_t *tim, uint32_t timeout_ms) { + tim->timeout = mp_hal_ticks_ms() + timeout_ms + 1; } -void hal_cpu_enable_irqs_and_sleep(void) { +static void mp_btstack_runloop_add_timer(btstack_timer_source_t *tim) { + btstack_linked_item_t **node = &mp_btstack_runloop_timers; + for (; *node; node = &(*node)->next) { + btstack_timer_source_t *node_tim = (btstack_timer_source_t *)*node; + if (node_tim == tim) { + // Timer is already in the list, don't add it. + return; + } + int32_t delta = btstack_time_delta(tim->timeout, node_tim->timeout); + if (delta < 0) { + // Found sorted location in list. + break; + } + } + + // Insert timer into list in sorted location. + tim->item.next = *node; + *node = &tim->item; + + // Reschedule the HCI poll if this timer is at the head of the list. + if (mp_btstack_runloop_timers == &tim->item) { + int32_t delta_ms = btstack_time_delta(tim->timeout, mp_hal_ticks_ms()); + mp_bluetooth_hci_poll_in_ms(delta_ms); + } } -uint32_t hal_time_ms(void) { +static bool mp_btstack_runloop_remove_timer(btstack_timer_source_t *tim) { + return btstack_linked_list_remove(&mp_btstack_runloop_timers, (btstack_linked_item_t *)tim); +} + +static void mp_btstack_runloop_execute(void) { + // Should not be called. +} + +static void mp_btstack_runloop_dump_timer(void) { + // Not implemented/needed. +} + +static uint32_t mp_btstack_runloop_get_time_ms(void) { return mp_hal_ticks_ms(); } +static const btstack_run_loop_t mp_btstack_runloop_stm32 = { + &mp_btstack_runloop_init, + NULL, // add_data_source, + NULL, // remove_data_source, + NULL, // enable_data_source_callbacks, + NULL, // disable_data_source_callbacks, + &mp_btstack_runloop_set_timer, + &mp_btstack_runloop_add_timer, + &mp_btstack_runloop_remove_timer, + &mp_btstack_runloop_execute, + &mp_btstack_runloop_dump_timer, + &mp_btstack_runloop_get_time_ms, +}; + STATIC const hci_transport_config_uart_t hci_transport_config_uart = { HCI_TRANSPORT_CONFIG_UART, MICROPY_HW_BLE_UART_BAUDRATE, @@ -69,26 +117,32 @@ void mp_bluetooth_hci_poll(void) { return; } - // Process uart data. + // Process UART data. if (mp_bluetooth_btstack_state != MP_BLUETOOTH_BTSTACK_STATE_HALTING) { mp_bluetooth_btstack_hci_uart_process(); } - // Call the BTstack run loop. - btstack_run_loop_embedded_execute_once(); - - // Call this function again in 128ms to check for new events. - // TODO: improve this by only calling back when needed. - mp_bluetooth_hci_poll_in_ms(128); + // Process any BTstack timers. + while (mp_btstack_runloop_timers != NULL) { + btstack_timer_source_t *tim = (btstack_timer_source_t *)mp_btstack_runloop_timers; + int32_t delta_ms = btstack_time_delta(tim->timeout, mp_hal_ticks_ms()); + if (delta_ms > 0) { + // Timer has not expired yet, reschedule HCI poll for this timer. + mp_bluetooth_hci_poll_in_ms(delta_ms); + break; + } + btstack_linked_list_pop(&mp_btstack_runloop_timers); + tim->process(tim); + } } void mp_bluetooth_btstack_port_init(void) { static bool run_loop_init = false; if (!run_loop_init) { run_loop_init = true; - btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); + btstack_run_loop_init(&mp_btstack_runloop_stm32); } else { - btstack_run_loop_embedded_get_instance()->init(); + mp_btstack_runloop_stm32.init(); } // hci_dump_open(NULL, HCI_DUMP_STDOUT); diff --git a/ports/unix/Makefile b/ports/unix/Makefile index fe86018aa0..d97e4bc7e0 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -177,6 +177,7 @@ endif # BTstack is enabled. GIT_SUBMODULES += lib/btstack include $(TOP)/extmod/btstack/btstack.mk +SRC_BTSTACK += lib/btstack/platform/embedded/btstack_run_loop_embedded.c else