kopia lustrzana https://github.com/micropython/micropython
nrf/nimble: Use soft timer for hci polling.
Signed-off-by: Andrew Leech <andrew@alelec.net>pull/8318/head
rodzic
6ff6468968
commit
0b200ce34e
|
@ -29,53 +29,92 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "shared/runtime/softtimer.h"
|
||||
|
||||
#if MICROPY_PY_BLUETOOTH
|
||||
|
||||
#define DEBUG_printf(...) // mp_printf(&mp_plat_print, "mpbthciport.c: " __VA_ARGS__)
|
||||
|
||||
#include "mpbthciport.h"
|
||||
#include "drivers/ticker.h"
|
||||
// #include "drivers/ticker.h"
|
||||
|
||||
#define BLUETOOTH_TICKER_SLOT 0
|
||||
// #define BLUETOOTH_TICKER_SLOT 0
|
||||
|
||||
// Soft timer and scheduling node for scheduling a HCI poll.
|
||||
static soft_timer_entry_t mp_bluetooth_hci_soft_timer;
|
||||
static mp_sched_node_t mp_bluetooth_hci_sched_node;
|
||||
|
||||
|
||||
// This is called by soft_timer and executes at PendSV level.
|
||||
static void mp_bluetooth_hci_soft_timer_callback(soft_timer_entry_t *self) {
|
||||
mp_bluetooth_hci_poll_now();
|
||||
}
|
||||
|
||||
// // Prevent double-enqueuing of the scheduled task.
|
||||
static volatile bool events_task_is_scheduled = false;
|
||||
// static volatile bool events_task_is_scheduled = false;
|
||||
|
||||
void mp_bluetooth_hci_init(void) {
|
||||
/* Start regular background task to handle events */
|
||||
events_task_is_scheduled = false;
|
||||
set_ticker_callback(BLUETOOTH_TICKER_SLOT, mp_bluetooth_hci_poll_now, 0);
|
||||
// events_task_is_scheduled = false;
|
||||
// set_ticker_callback(BLUETOOTH_TICKER_SLOT, mp_bluetooth_hci_poll_now, 0);
|
||||
soft_timer_static_init(
|
||||
&mp_bluetooth_hci_soft_timer,
|
||||
SOFT_TIMER_MODE_ONE_SHOT,
|
||||
0,
|
||||
mp_bluetooth_hci_soft_timer_callback
|
||||
);
|
||||
}
|
||||
|
||||
void mp_bluetooth_hci_deinit(void) {
|
||||
clear_ticker_callback(BLUETOOTH_TICKER_SLOT);
|
||||
events_task_is_scheduled = false;
|
||||
// clear_ticker_callback(BLUETOOTH_TICKER_SLOT);
|
||||
// events_task_is_scheduled = false;
|
||||
soft_timer_remove(&mp_bluetooth_hci_soft_timer);
|
||||
|
||||
}
|
||||
|
||||
// // For synchronous mode, we run all BLE stack code inside a scheduled task.
|
||||
// // This task is scheduled periodically via a timer.
|
||||
// static mp_obj_t run_events_scheduled_task(mp_obj_t none_in) {
|
||||
// (void)none_in;
|
||||
// events_task_is_scheduled = false;
|
||||
// mp_bluetooth_hci_poll();
|
||||
// return mp_const_none;
|
||||
// }
|
||||
// static MP_DEFINE_CONST_FUN_OBJ_1(run_events_scheduled_task_obj, run_events_scheduled_task);
|
||||
|
||||
|
||||
// // Called periodically (ticker) to request that processing happens in the scheduler.
|
||||
// int32_t mp_bluetooth_hci_poll_now(void) {
|
||||
// // Return interval (128ms in 16us ticks) until next callback run
|
||||
// uint32_t next_tick = 128000 / 16;
|
||||
// if (!events_task_is_scheduled) {
|
||||
// events_task_is_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&run_events_scheduled_task_obj), mp_const_none);
|
||||
// if (!events_task_is_scheduled) {
|
||||
// // The schedule queue is full, set callback to try again soon (5ms).
|
||||
// next_tick = 5000 / 16;
|
||||
// }
|
||||
// }
|
||||
// return next_tick;
|
||||
// }
|
||||
|
||||
// static void mp_bluetooth_hci_start_polling(void) {
|
||||
// mp_bluetooth_hci_poll_now();
|
||||
// }
|
||||
|
||||
void mp_bluetooth_hci_poll_in_ms(uint32_t ms) {
|
||||
soft_timer_reinsert(&mp_bluetooth_hci_soft_timer, ms);
|
||||
}
|
||||
|
||||
// For synchronous mode, we run all BLE stack code inside a scheduled task.
|
||||
// This task is scheduled periodically via a timer.
|
||||
static mp_obj_t run_events_scheduled_task(mp_obj_t none_in) {
|
||||
(void)none_in;
|
||||
events_task_is_scheduled = false;
|
||||
static void run_events_scheduled_task(mp_sched_node_t *node) {
|
||||
// This will process all buffered HCI UART data, and run any callouts or events.
|
||||
mp_bluetooth_hci_poll();
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(run_events_scheduled_task_obj, run_events_scheduled_task);
|
||||
|
||||
|
||||
// Called periodically (ticker) to request that processing happens in the scheduler.
|
||||
int32_t mp_bluetooth_hci_poll_now(void) {
|
||||
// Return interval (128ms in 16us ticks) until next callback run
|
||||
uint32_t next_tick = 128000 / 16;
|
||||
if (!events_task_is_scheduled) {
|
||||
events_task_is_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&run_events_scheduled_task_obj), mp_const_none);
|
||||
if (!events_task_is_scheduled) {
|
||||
// The schedule queue is full, set callback to try again soon (5ms).
|
||||
next_tick = 5000 / 16;
|
||||
}
|
||||
}
|
||||
return next_tick;
|
||||
// Called periodically (systick) or directly (e.g. UART RX IRQ) in order to
|
||||
// request that processing happens ASAP in the scheduler.
|
||||
void mp_bluetooth_hci_poll_now(void) {
|
||||
mp_sched_schedule_node(&mp_bluetooth_hci_sched_node, run_events_scheduled_task);
|
||||
}
|
||||
|
||||
#endif // MICROPY_PY_BLUETOOTH
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
void mp_bluetooth_hci_init(void);
|
||||
void mp_bluetooth_hci_deinit(void);
|
||||
|
||||
// Poll the HCI now.
|
||||
int32_t mp_bluetooth_hci_poll_now(void);
|
||||
// Poll the HCI now, or after a certain timeout.
|
||||
void mp_bluetooth_hci_poll_now(void);
|
||||
void mp_bluetooth_hci_poll_in_ms(uint32_t ms);
|
||||
|
||||
// Must be provided by the stack bindings (e.g. mpnimbleport.c or mpbtstackport.c).
|
||||
// Request new HCI data and pass to the stack, and run pending events/callouts.
|
||||
|
|
|
@ -61,10 +61,14 @@ void mp_bluetooth_hci_controller_init(void) {
|
|||
|
||||
// Tell the host that we are ready to receive packets
|
||||
ble_ll_hci_send_noop();
|
||||
|
||||
// Start polling for date.
|
||||
mp_bluetooth_hci_poll_now();
|
||||
}
|
||||
|
||||
void mp_bluetooth_hci_controller_deinit(void) {
|
||||
mp_bluetooth_hci_deinit();
|
||||
|
||||
}
|
||||
|
||||
// The global BLE controller LL data object
|
||||
|
@ -92,6 +96,11 @@ void mp_bluetooth_hci_poll(void) {
|
|||
// Run any remaining events.
|
||||
mp_bluetooth_nimble_os_eventq_run_all();
|
||||
}
|
||||
if (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Port-specific helpers for the generic NimBLE bindings. -----------------
|
||||
|
@ -123,6 +132,7 @@ static func nrf_ble_isr_rtc0 = NULL;
|
|||
void RADIO_IRQHandler(void) {
|
||||
if (nrf_ble_isr_phy != NULL) {
|
||||
nrf_ble_isr_phy();
|
||||
mp_bluetooth_hci_poll_in_ms(5);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue