|
29 | 29 | #include "py/runtime.h" |
30 | 30 | #include "py/mperrno.h" |
31 | 31 | #include "py/mphal.h" |
| 32 | +#include "shared/runtime/softtimer.h" |
32 | 33 |
|
33 | 34 | #if MICROPY_PY_BLUETOOTH |
34 | 35 |
|
35 | 36 | #define DEBUG_printf(...) // mp_printf(&mp_plat_print, "mpbthciport.c: " __VA_ARGS__) |
36 | 37 |
|
37 | 38 | #include "mpbthciport.h" |
38 | | -#include "drivers/ticker.h" |
| 39 | +// #include "drivers/ticker.h" |
39 | 40 |
|
40 | | -#define BLUETOOTH_TICKER_SLOT 0 |
| 41 | +// #define BLUETOOTH_TICKER_SLOT 0 |
| 42 | + |
| 43 | +// Soft timer and scheduling node for scheduling a HCI poll. |
| 44 | +static soft_timer_entry_t mp_bluetooth_hci_soft_timer; |
| 45 | +static mp_sched_node_t mp_bluetooth_hci_sched_node; |
| 46 | + |
| 47 | + |
| 48 | +// This is called by soft_timer and executes at PendSV level. |
| 49 | +static void mp_bluetooth_hci_soft_timer_callback(soft_timer_entry_t *self) { |
| 50 | + mp_bluetooth_hci_poll_now(); |
| 51 | +} |
41 | 52 |
|
42 | 53 | // // Prevent double-enqueuing of the scheduled task. |
43 | | -static volatile bool events_task_is_scheduled = false; |
| 54 | +// static volatile bool events_task_is_scheduled = false; |
44 | 55 |
|
45 | 56 | void mp_bluetooth_hci_init(void) { |
46 | 57 | /* Start regular background task to handle events */ |
47 | | - events_task_is_scheduled = false; |
48 | | - set_ticker_callback(BLUETOOTH_TICKER_SLOT, mp_bluetooth_hci_poll_now, 0); |
| 58 | + // events_task_is_scheduled = false; |
| 59 | + // set_ticker_callback(BLUETOOTH_TICKER_SLOT, mp_bluetooth_hci_poll_now, 0); |
| 60 | + soft_timer_static_init( |
| 61 | + &mp_bluetooth_hci_soft_timer, |
| 62 | + SOFT_TIMER_MODE_ONE_SHOT, |
| 63 | + 0, |
| 64 | + mp_bluetooth_hci_soft_timer_callback |
| 65 | + ); |
49 | 66 | } |
50 | 67 |
|
51 | 68 | void mp_bluetooth_hci_deinit(void) { |
52 | | - clear_ticker_callback(BLUETOOTH_TICKER_SLOT); |
53 | | - events_task_is_scheduled = false; |
| 69 | + // clear_ticker_callback(BLUETOOTH_TICKER_SLOT); |
| 70 | + // events_task_is_scheduled = false; |
| 71 | + soft_timer_remove(&mp_bluetooth_hci_soft_timer); |
| 72 | + |
| 73 | +} |
| 74 | + |
| 75 | +// // For synchronous mode, we run all BLE stack code inside a scheduled task. |
| 76 | +// // This task is scheduled periodically via a timer. |
| 77 | +// static mp_obj_t run_events_scheduled_task(mp_obj_t none_in) { |
| 78 | +// (void)none_in; |
| 79 | +// events_task_is_scheduled = false; |
| 80 | +// mp_bluetooth_hci_poll(); |
| 81 | +// return mp_const_none; |
| 82 | +// } |
| 83 | +// static MP_DEFINE_CONST_FUN_OBJ_1(run_events_scheduled_task_obj, run_events_scheduled_task); |
| 84 | + |
| 85 | + |
| 86 | +// // Called periodically (ticker) to request that processing happens in the scheduler. |
| 87 | +// int32_t mp_bluetooth_hci_poll_now(void) { |
| 88 | +// // Return interval (128ms in 16us ticks) until next callback run |
| 89 | +// uint32_t next_tick = 128000 / 16; |
| 90 | +// if (!events_task_is_scheduled) { |
| 91 | +// events_task_is_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&run_events_scheduled_task_obj), mp_const_none); |
| 92 | +// if (!events_task_is_scheduled) { |
| 93 | +// // The schedule queue is full, set callback to try again soon (5ms). |
| 94 | +// next_tick = 5000 / 16; |
| 95 | +// } |
| 96 | +// } |
| 97 | +// return next_tick; |
| 98 | +// } |
| 99 | + |
| 100 | +// static void mp_bluetooth_hci_start_polling(void) { |
| 101 | +// mp_bluetooth_hci_poll_now(); |
| 102 | +// } |
| 103 | + |
| 104 | +void mp_bluetooth_hci_poll_in_ms(uint32_t ms) { |
| 105 | + soft_timer_reinsert(&mp_bluetooth_hci_soft_timer, ms); |
54 | 106 | } |
55 | 107 |
|
56 | 108 | // For synchronous mode, we run all BLE stack code inside a scheduled task. |
57 | | -// This task is scheduled periodically via a timer. |
58 | | -static mp_obj_t run_events_scheduled_task(mp_obj_t none_in) { |
59 | | - (void)none_in; |
60 | | - events_task_is_scheduled = false; |
| 109 | +static void run_events_scheduled_task(mp_sched_node_t *node) { |
| 110 | + // This will process all buffered HCI UART data, and run any callouts or events. |
61 | 111 | mp_bluetooth_hci_poll(); |
62 | | - return mp_const_none; |
63 | 112 | } |
64 | | -static MP_DEFINE_CONST_FUN_OBJ_1(run_events_scheduled_task_obj, run_events_scheduled_task); |
65 | | - |
66 | | - |
67 | | -// Called periodically (ticker) to request that processing happens in the scheduler. |
68 | | -int32_t mp_bluetooth_hci_poll_now(void) { |
69 | | - // Return interval (128ms in 16us ticks) until next callback run |
70 | | - uint32_t next_tick = 128000 / 16; |
71 | | - if (!events_task_is_scheduled) { |
72 | | - events_task_is_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&run_events_scheduled_task_obj), mp_const_none); |
73 | | - if (!events_task_is_scheduled) { |
74 | | - // The schedule queue is full, set callback to try again soon (5ms). |
75 | | - next_tick = 5000 / 16; |
76 | | - } |
77 | | - } |
78 | | - return next_tick; |
| 113 | + |
| 114 | +// Called periodically (systick) or directly (e.g. UART RX IRQ) in order to |
| 115 | +// request that processing happens ASAP in the scheduler. |
| 116 | +void mp_bluetooth_hci_poll_now(void) { |
| 117 | + mp_sched_schedule_node(&mp_bluetooth_hci_sched_node, run_events_scheduled_task); |
79 | 118 | } |
80 | 119 |
|
81 | 120 | #endif // MICROPY_PY_BLUETOOTH |
0 commit comments