Skip to content

Commit ae30a1e

Browse files
committed
Refine _bleio
This PR refines the _bleio API. It was originally motivated by the addition of a new CircuitPython service that enables reading and modifying files on the device. Moving the BLE lifecycle outside of the VM motivated a number of changes to remove heap allocations in some APIs. It also motivated unifying connection initiation to the Adapter class rather than the Central and Peripheral classes which have been removed. Adapter now handles the GAP portion of BLE including advertising, which has moved but is largely unchanged, and scanning, which has been enhanced to return an iterator of filtered results. Once a connection is created (either by us (aka Central) or a remote device (aka Peripheral)) it is represented by a new Connection class. This class knows the current connection state and can discover and instantiate remote Services along with their Characteristics and Descriptors. Relates to #586
1 parent 84c0d6c commit ae30a1e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2880
-2142
lines changed

lib/utils/interrupt_char.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void mp_keyboard_interrupt(void) {
4949

5050
// Check to see if we've been CTRL-C'ed by autoreload or the user.
5151
bool mp_hal_is_interrupted(void) {
52-
return MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception));
52+
return MP_STATE_VM(mp_pending_exception) != NULL;
5353
}
5454

5555
#endif

main.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@
6969
#include "shared-module/board/__init__.h"
7070
#endif
7171

72+
#if CIRCUITPY_BLEIO
73+
#include "shared-bindings/_bleio/__init__.h"
74+
#include "supervisor/shared/bluetooth.h"
75+
#endif
76+
7277
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
7378
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
7479
if (lex == NULL) {
@@ -439,6 +444,10 @@ int __attribute__((used)) main(void) {
439444
// Start serial and HID after giving boot.py a chance to tweak behavior.
440445
serial_init();
441446

447+
#if CIRCUITPY_BLEIO
448+
supervisor_start_bluetooth();
449+
#endif
450+
442451
// Boot script is finished, so now go into REPL/main mode.
443452
int exit_code = PYEXEC_FORCED_EXIT;
444453
bool skip_repl = true;
@@ -475,6 +484,10 @@ void gc_collect(void) {
475484
displayio_gc_collect();
476485
#endif
477486

487+
#if CIRCUITPY_BLEIO
488+
common_hal_bleio_gc_collect();
489+
#endif
490+
478491
// This naively collects all object references from an approximate stack
479492
// range.
480493
gc_collect_root((void**)sp, ((uint32_t)port_stack_get_top() - sp) / sizeof(uint32_t));

ports/nrf/background.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
#include "common-hal/audiopwmio/PWMAudioOut.h"
4242
#endif
4343

44+
#if CIRCUITPY_BLEIO
45+
#include "supervisor/shared/bluetooth.h"
46+
#endif
47+
4448
static bool running_background_tasks = false;
4549

4650
void background_tasks_reset(void) {
@@ -62,6 +66,9 @@ void run_background_tasks(void) {
6266
i2s_background();
6367
#endif
6468

69+
#if CIRCUITPY_BLEIO
70+
supervisor_bluetooth_background();
71+
#endif
6572

6673
#if CIRCUITPY_DISPLAYIO
6774
displayio_background();

ports/nrf/bluetooth/ble_drv.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
#include "py/misc.h"
3939
#include "py/mpstate.h"
4040

41+
#include "supervisor/shared/bluetooth.h"
42+
4143
nrf_nvic_state_t nrf_nvic_state = { 0 };
4244

4345
// Flag indicating progress of internal flash operation.
@@ -52,6 +54,14 @@ void ble_drv_reset() {
5254
sd_flash_operation_status = SD_FLASH_OPERATION_DONE;
5355
}
5456

57+
void ble_drv_add_event_handler_entry(ble_drv_evt_handler_entry_t* entry, ble_drv_evt_handler_t func, void *param) {
58+
entry->next = MP_STATE_VM(ble_drv_evt_handler_entries);
59+
entry->param = param;
60+
entry->func = func;
61+
62+
MP_STATE_VM(ble_drv_evt_handler_entries) = entry;
63+
}
64+
5565
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
5666
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
5767
while (it != NULL) {
@@ -64,11 +74,7 @@ void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
6474

6575
// Add a new handler to the front of the list
6676
ble_drv_evt_handler_entry_t *handler = m_new_ll(ble_drv_evt_handler_entry_t, 1);
67-
handler->next = MP_STATE_VM(ble_drv_evt_handler_entries);
68-
handler->param = param;
69-
handler->func = func;
70-
71-
MP_STATE_VM(ble_drv_evt_handler_entries) = handler;
77+
ble_drv_add_event_handler_entry(handler, func, param);
7278
}
7379

7480
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param) {
@@ -127,10 +133,20 @@ void SD_EVT_IRQHandler(void) {
127133
break;
128134
}
129135

136+
ble_evt_t* event = (ble_evt_t *)m_ble_evt_buf;
137+
138+
if (supervisor_bluetooth_hook(event)) {
139+
continue;
140+
}
141+
130142
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
143+
bool done = false;
131144
while (it != NULL) {
132-
it->func((ble_evt_t *)m_ble_evt_buf, it->param);
145+
done = it->func(event, it->param) || done;
133146
it = it->next;
134147
}
148+
if (!done) {
149+
//mp_printf(&mp_plat_print, "Unhandled ble event: 0x%04x\n", event->header.evt_id);
150+
}
135151
}
136152
}

ports/nrf/bluetooth/ble_drv.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H
3030
#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H
3131

32+
#include <stdbool.h>
33+
3234
#include "ble.h"
3335

3436
#define MAX_TX_IN_PROGRESS 10
@@ -48,7 +50,7 @@
4850
#define UNIT_1_25_MS (1250)
4951
#define UNIT_10_MS (10000)
5052

51-
typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
53+
typedef bool (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
5254

5355
typedef enum {
5456
SD_FLASH_OPERATION_DONE,
@@ -69,4 +71,7 @@ void ble_drv_reset(void);
6971
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param);
7072
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param);
7173

74+
// Allow for user provided entries to prevent allocations outside the VM.
75+
void ble_drv_add_event_handler_entry(ble_drv_evt_handler_entry_t* entry, ble_drv_evt_handler_t func, void *param);
76+
7277
#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H

ports/nrf/boards/adafruit_nrf52840_s140_v6.ld

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
0x00000000..0x00000FFF (4KB) Master Boot Record
1717
*/
1818

19+
1920
/* Specify the memory areas (S140 6.x.x) */
2021
MEMORY
2122
{
@@ -26,7 +27,10 @@ MEMORY
2627
FLASH_FATFS (r) : ORIGIN = 0x000AD000, LENGTH = 0x040000
2728

2829
/* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */
29-
RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x20040000 - 0x20004000
30+
/* SoftDevice 6.1.0 takes 0x1628 bytes (5.54 kb) minimum. */
31+
/* To measure the minimum required amount of memory for given configuration, set this number
32+
high enough to work and then check the mutation of the value done by sd_ble_enable. */
33+
RAM (xrw) : ORIGIN = 0x20000000 + 16K, LENGTH = 256K - 16K
3034
}
3135

3236
/* produce a link error if there is not this amount of RAM for these sections */
@@ -38,7 +42,8 @@ _minimum_heap_size = 0;
3842
/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
3943
_estack = ORIGIN(RAM) + LENGTH(RAM);
4044

41-
/* RAM extents for the garbage collector */
45+
/* RAM extents for the garbage collector and soft device init */
46+
_ram_start = ORIGIN(RAM);
4247
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
4348
_heap_end = 0x20020000; /* tunable */
4449

0 commit comments

Comments
 (0)