Skip to content

Commit b27d511

Browse files
committed
address review; use constructor for HCI Adapter
1 parent 770c204 commit b27d511

File tree

10 files changed

+133
-42
lines changed

10 files changed

+133
-42
lines changed

devices/ble_hci/common-hal/_bleio/Adapter.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) {
341341
}
342342
}
343343

344-
void common_hal_bleio_adapter_hci_uart_init(bleio_adapter_obj_t *self, busio_uart_obj_t *uart, digitalio_digitalinout_obj_t *rts, digitalio_digitalinout_obj_t *cts) {
344+
void common_hal_bleio_adapter_construct_hci_uart(bleio_adapter_obj_t *self, busio_uart_obj_t *uart, digitalio_digitalinout_obj_t *rts, digitalio_digitalinout_obj_t *cts) {
345+
self->allocated = true;
345346
self->hci_uart = uart;
346347
self->rts_digitalinout = rts;
347348
self->cts_digitalinout = cts;

devices/ble_hci/common-hal/_bleio/Adapter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ typedef struct _bleio_adapter_obj_t {
5252
busio_uart_obj_t* hci_uart;
5353
digitalio_digitalinout_obj_t *rts_digitalinout;
5454
digitalio_digitalinout_obj_t *cts_digitalinout;
55+
bool allocated; // True when in use.
5556
bool now_advertising;
5657
bool extended_advertising;
5758
bool circuitpython_advertising;

devices/ble_hci/common-hal/_bleio/__init__.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ void bleio_reset() {
7474
return;
7575
}
7676
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
77+
common_hal_bleio_adapter_obj.allocated = false;
78+
79+
bleio_set_adapter(mp_const_none);
7780

7881
//FIX bonding_reset();
7982
supervisor_start_bluetooth();
@@ -86,6 +89,13 @@ bleio_adapter_obj_t common_hal_bleio_adapter_obj = {
8689
},
8790
};
8891

92+
bleio_adapter_obj_t *common_hal_bleio_allocate_adapter_or_raise(void) {
93+
if (common_hal_bleio_adapter_obj.allocated) {
94+
mp_raise_RuntimeError(translate("Too many Adapters"));
95+
}
96+
return &common_hal_bleio_adapter_obj;
97+
}
98+
8999
void common_hal_bleio_check_connected(uint16_t conn_handle) {
90100
if (conn_handle == BLE_CONN_HANDLE_INVALID) {
91101
mp_raise_bleio_ConnectionError(translate("Not connected"));
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
The HCI-related include files here are copied from the Zephyr project:
2-
https://github.com/zephyrproject-rtos/zephyr/tree/master/include/bluetooth
1+
The HCI-related include files here were copied from the Zephyr project, from this commit:
2+
https://github.com/zephyrproject-rtos/zephyr/tree/0a87f9359edf1ec1c169626df3e19c2b4a4e9646/include/bluetooth

py/obj.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t;
303303
(mp_obj_t)&mp_const_none_obj, \
304304
(mp_obj_t)&mp_const_none_obj}, }
305305

306-
// These macros are used to define constant map/dict objects
306+
// These macros are used to define constant or mutable map/dict objects
307307
// You can put "static" in front of the definition to make it local
308308

309309
#define MP_DEFINE_CONST_MAP(map_name, table_name) \
@@ -329,6 +329,29 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t;
329329
}, \
330330
}
331331

332+
#define MP_DEFINE_MUTABLE_MAP(map_name, table_name) \
333+
mp_map_t map_name = { \
334+
.all_keys_are_qstrs = 1, \
335+
.is_fixed = 1, \
336+
.is_ordered = 1, \
337+
.used = MP_ARRAY_SIZE(table_name), \
338+
.alloc = MP_ARRAY_SIZE(table_name), \
339+
.table = table_name, \
340+
}
341+
342+
#define MP_DEFINE_MUTABLE_DICT(dict_name, table_name) \
343+
mp_obj_dict_t dict_name = { \
344+
.base = {&mp_type_dict}, \
345+
.map = { \
346+
.all_keys_are_qstrs = 1, \
347+
.is_fixed = 1, \
348+
.is_ordered = 1, \
349+
.used = MP_ARRAY_SIZE(table_name), \
350+
.alloc = MP_ARRAY_SIZE(table_name), \
351+
.table = table_name, \
352+
}, \
353+
}
354+
332355
// These macros are used to declare and define constant staticmethond and classmethod objects
333356
// You can put "static" in front of the definitions to make them local
334357

shared-bindings/_bleio/Adapter.c

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,46 +48,42 @@
4848
#define WINDOW_DEFAULT (0.1f)
4949

5050
//| class Adapter:
51-
//| """BLE adapter
52-
//|
53-
//| The Adapter manages the discovery and connection to other nearby Bluetooth Low Energy devices.
51+
//| """
52+
//| The BLE Adapter object manages the discovery and connection to other nearby Bluetooth Low Energy devices.
5453
//| This part of the Bluetooth Low Energy Specification is known as Generic Access Profile (GAP).
5554
//|
5655
//| Discovery of other devices happens during a scanning process that listens for small packets of
5756
//| information, known as advertisements, that are broadcast unencrypted. The advertising packets
5857
//| have two different uses. The first is to broadcast a small piece of data to anyone who cares and
59-
//| and nothing more. These are known as Beacons. The second class of advertisement is to promote
58+
//| and nothing more. These are known as beacons. The second class of advertisement is to promote
6059
//| additional functionality available after the devices establish a connection. For example, a
61-
//| BLE keyboard may advertise that it can provide key information, but not what the key info is.
60+
//| BLE heart rate monitor would advertise that it provides the standard BLE Heart Rate Service.
6261
//|
63-
//| The built-in BLE adapter can do both parts of this process: it can scan for other device
62+
//| The Adapter can do both parts of this process: it can scan for other device
6463
//| advertisements and it can advertise its own data. Furthermore, Adapters can accept incoming
6564
//| connections and also initiate connections."""
6665
//|
6766

68-
//| def __init__(self) -> None:
69-
//| """You cannot create an instance of `_bleio.Adapter`.
70-
//| Use `_bleio.adapter` to access the sole instance available."""
71-
//| ...
72-
//|
73-
74-
//| def hci_uart_init(self, *, uart: busio.UART, rts: digitalio.DigitalInOut, cts: digitalio.DigitalInOut, baudrate: int = 115200, buffer_size: int = 256) -> None:
75-
//| """On boards that do not have native BLE, you can an use HCI co-processor.
67+
//| def __init__(self, *, uart: busio.UART, rts: digitalio.DigitalInOut, cts: digitalio.DigitalInOut) -> None:
68+
//| """On boards that do not have native BLE, you can use an HCI co-processor.
7669
//| Pass the uart and pins used to communicate with the co-processor, such as an Adafruit AirLift.
7770
//| The co-processor must have been reset and put into BLE mode beforehand
7871
//| by the appropriate pin manipulation.
7972
//| The ``uart``, ``rts``, and ``cts`` objects are used to
8073
//| communicate with the HCI co-processor in HCI mode.
74+
//| The `Adapter` object is enabled during this call.
8175
//|
82-
//| The `_bleio.adapter` object is enabled during this call.
76+
//| After instantiating the Adapter, assign it to _bleio.adapter
8377
//|
84-
//| Raises `RuntimeError` on boards with native BLE.
78+
//| On boards with native BLE, you cannot create an instance of `_bleio.Adapter`;
79+
//| this constructor will raise `NotImplementedError`.
80+
//| Use `_bleio.adapter` to access the sole instance already available."""
8581
//| """
8682
//| ...
8783
//|
88-
STATIC mp_obj_t bleio_adapter_hci_uart_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
84+
STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
8985
#if CIRCUITPY_BLEIO_HCI
90-
bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
86+
bleio_adapter_obj_t *self = common_hal_bleio_allocate_adapter_or_raise();
9187

9288
enum { ARG_uart, ARG_rts, ARG_cts };
9389
static const mp_arg_t allowed_args[] = {
@@ -97,7 +93,7 @@ STATIC mp_obj_t bleio_adapter_hci_uart_init(mp_uint_t n_args, const mp_obj_t *po
9793
};
9894

9995
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
100-
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
96+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
10197

10298
busio_uart_obj_t *uart = args[ARG_uart].u_obj;
10399
if (!MP_OBJ_IS_TYPE(uart, &busio_uart_type)) {
@@ -112,15 +108,14 @@ STATIC mp_obj_t bleio_adapter_hci_uart_init(mp_uint_t n_args, const mp_obj_t *po
112108
}
113109

114110
// Will enable the adapter.
115-
common_hal_bleio_adapter_hci_uart_init(self, uart, rts, cts);
111+
common_hal_bleio_adapter_construct_hci_uart(self, uart, rts, cts);
116112

117-
return mp_const_none;
113+
return MP_OBJ_FROM_PTR(self);
118114
#else
119-
mp_raise_RuntimeError(translate("hci_uart_init not available"));
115+
mp_raise_NotImplementedError(translate("Cannot create a new Adapter; use _bleio.adapter;"));
120116
return mp_const_none;
121117
#endif // CIRCUITPY_BLEIO_HCI
122118
}
123-
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_hci_uart_init_obj, 1, bleio_adapter_hci_uart_init);
124119

125120
//|
126121
//| enabled: bool
@@ -454,7 +449,6 @@ STATIC mp_obj_t bleio_adapter_erase_bonding(mp_obj_t self_in) {
454449
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_erase_bonding_obj, bleio_adapter_erase_bonding);
455450

456451
STATIC const mp_rom_map_elem_t bleio_adapter_locals_dict_table[] = {
457-
{ MP_ROM_QSTR(MP_QSTR_hci_uart_init), MP_ROM_PTR(&bleio_adapter_hci_uart_init_obj) },
458452
{ MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&bleio_adapter_enabled_obj) },
459453
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_adapter_address_obj) },
460454
{ MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_adapter_name_obj) },
@@ -479,5 +473,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_adapter_locals_dict, bleio_adapter_locals_dict
479473
const mp_obj_type_t bleio_adapter_type = {
480474
.base = { &mp_type_type },
481475
.name = MP_QSTR_Adapter,
476+
.make_new = bleio_adapter_make_new,
482477
.locals_dict = (mp_obj_t)&bleio_adapter_locals_dict,
483478
};

shared-bindings/_bleio/Adapter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
const mp_obj_type_t bleio_adapter_type;
3939

4040
#if CIRCUITPY_BLEIO_HCI
41-
void common_hal_bleio_adapter_hci_uart_init(bleio_adapter_obj_t *self, busio_uart_obj_t *uart, digitalio_digitalinout_obj_t *rts, digitalio_digitalinout_obj_t *cts);
41+
void common_hal_bleio_adapter_construct_hci_uart(bleio_adapter_obj_t *self, busio_uart_obj_t *uart, digitalio_digitalinout_obj_t *rts, digitalio_digitalinout_obj_t *cts);
4242
#endif // CIRCUITPY_BLEIO_HCI
4343

4444
extern bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self);

shared-bindings/_bleio/__init__.c

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,83 @@ NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* fmt, ...)
108108

109109
// Called when _bleio is imported.
110110
STATIC mp_obj_t bleio___init__(void) {
111+
// HCI cannot be enabled on import, because we need to setup the HCI adapter first.
111112
#if !CIRCUITPY_BLEIO_HCI
112-
// HCI cannot be enabled on import, because we need to setup the HCI adapter first.
113113
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true);
114114
#endif
115115
return mp_const_none;
116116
}
117117
STATIC MP_DEFINE_CONST_FUN_OBJ_0(bleio___init___obj, bleio___init__);
118118

119119

120+
// Need a forward reference due to mutual references.
121+
#if CIRCUITPY_BLEIO_HCI
122+
STATIC mp_obj_dict_t bleio_module_globals;
123+
#endif
124+
125+
//| def set_adapter(adapter: Optional[_bleio.Adapter]) -> None:
126+
//| """Set the adapter to use for BLE. Not settable when the adapter is a singleton."""
127+
//| ...
128+
//|
129+
mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj) {
130+
#if CIRCUITPY_BLEIO_HCI
131+
if (adapter_obj != mp_const_none && !MP_OBJ_IS_TYPE(adapter_obj, &bleio_adapter_type)) {
132+
mp_raise_TypeError_varg(translate("Expected a %q"), bleio_adapter_type.name);
133+
}
134+
135+
// Equivalent of:
136+
// bleio.adapter = adapter_obj
137+
mp_map_elem_t *elem = mp_map_lookup(&bleio_module_globals.map, MP_ROM_QSTR(MP_QSTR_adapter), MP_MAP_LOOKUP);
138+
if (elem) {
139+
elem->value = adapter_obj;
140+
}
141+
#else
142+
mp_raise_NotImplementedError(translate("Not settable"));
143+
#endif
144+
return mp_const_none;
145+
}
146+
MP_DEFINE_CONST_FUN_OBJ_1(bleio_set_adapter_obj, bleio_set_adapter);
147+
148+
#if CIRCUITPY_BLEIO_HCI
149+
// Make the module dictionary be in RAM, so that _bleio.adapter can be set.
150+
151+
STATIC mp_map_elem_t bleio_module_globals_table[] = {
152+
// Name must be the first entry so that the exception printing below is correct.
153+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__bleio) },
154+
{ MP_ROM_QSTR(MP_QSTR_Adapter), MP_OBJ_FROM_PTR(&bleio_adapter_type) },
155+
{ MP_ROM_QSTR(MP_QSTR_Address), MP_OBJ_FROM_PTR(&bleio_address_type) },
156+
{ MP_ROM_QSTR(MP_QSTR_Attribute), MP_OBJ_FROM_PTR(&bleio_attribute_type) },
157+
{ MP_ROM_QSTR(MP_QSTR_Connection), MP_OBJ_FROM_PTR(&bleio_connection_type) },
158+
{ MP_ROM_QSTR(MP_QSTR_Characteristic), MP_OBJ_FROM_PTR(&bleio_characteristic_type) },
159+
{ MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_OBJ_FROM_PTR(&bleio_characteristic_buffer_type) },
160+
{ MP_ROM_QSTR(MP_QSTR_Descriptor), MP_OBJ_FROM_PTR(&bleio_descriptor_type) },
161+
{ MP_ROM_QSTR(MP_QSTR_PacketBuffer), MP_OBJ_FROM_PTR(&bleio_packet_buffer_type) },
162+
{ MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_OBJ_FROM_PTR(&bleio_scanentry_type) },
163+
{ MP_ROM_QSTR(MP_QSTR_ScanResults), MP_OBJ_FROM_PTR(&bleio_scanresults_type) },
164+
{ MP_ROM_QSTR(MP_QSTR_Service), MP_OBJ_FROM_PTR(&bleio_service_type) },
165+
{ MP_ROM_QSTR(MP_QSTR_UUID), MP_OBJ_FROM_PTR(&bleio_uuid_type) },
166+
167+
// Attributes
168+
{ MP_ROM_QSTR(MP_QSTR_adapter), mp_const_none },
169+
170+
// Functions
171+
{ MP_ROM_QSTR(MP_QSTR_set_adapter), (mp_obj_t) &bleio_set_adapter_obj },
172+
173+
// Errors
174+
{ MP_ROM_QSTR(MP_QSTR_BluetoothError), MP_OBJ_FROM_PTR(&mp_type_bleio_BluetoothError) },
175+
{ MP_ROM_QSTR(MP_QSTR_ConnectionError), MP_OBJ_FROM_PTR(&mp_type_bleio_ConnectionError) },
176+
{ MP_ROM_QSTR(MP_QSTR_RoleError), MP_OBJ_FROM_PTR(&mp_type_bleio_RoleError) },
177+
{ MP_ROM_QSTR(MP_QSTR_SecurityError), MP_OBJ_FROM_PTR(&mp_type_bleio_SecurityError) },
178+
179+
// Initialization
180+
{ MP_ROM_QSTR(MP_QSTR___init__), MP_OBJ_FROM_PTR(&bleio___init___obj) },
181+
};
182+
183+
STATIC MP_DEFINE_MUTABLE_DICT(bleio_module_globals, bleio_module_globals_table);
184+
185+
#else
186+
// When _bleio.adapter is a singleton, and can't be set.
187+
120188
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
121189
// Name must be the first entry so that the exception printing below is correct.
122190
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__bleio) },
@@ -144,10 +212,10 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
144212

145213
// Initialization
146214
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&bleio___init___obj) },
147-
148215
};
149216

150217
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);
218+
#endif
151219

152220
void bleio_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
153221
mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS;

shared-bindings/_bleio/__init__.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,14 @@ extern const mp_obj_type_t mp_type_bleio_ConnectionError;
5555
extern const mp_obj_type_t mp_type_bleio_RoleError;
5656
extern const mp_obj_type_t mp_type_bleio_SecurityError;
5757

58+
extern mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj);
59+
5860
NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t* msg, ...);
5961
NORETURN void mp_raise_bleio_ConnectionError(const compressed_string_t* msg, ...);
6062
NORETURN void mp_raise_bleio_RoleError(const compressed_string_t* msg);
6163
NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* msg, ...);
6264

65+
bleio_adapter_obj_t *common_hal_bleio_allocate_adapter_or_raise(void);
6366
void common_hal_bleio_check_connected(uint16_t conn_handle);
6467

6568
uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);

shared-bindings/usb_midi/__init__.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,7 @@ mp_map_elem_t usb_midi_module_globals_table[] = {
5151
};
5252

5353
// This isn't const so we can set ports dynamically.
54-
mp_obj_dict_t usb_midi_module_globals = {
55-
.base = {&mp_type_dict},
56-
.map = {
57-
.all_keys_are_qstrs = 1,
58-
.is_fixed = 1,
59-
.is_ordered = 1,
60-
.used = MP_ARRAY_SIZE(usb_midi_module_globals_table),
61-
.alloc = MP_ARRAY_SIZE(usb_midi_module_globals_table),
62-
.table = usb_midi_module_globals_table,
63-
},
64-
};
54+
MP_DEFINE_MUTABLE_DICT(usb_midi_module_globals, usb_midi_module_globals_table);
6555

6656
const mp_obj_module_t usb_midi_module = {
6757
.base = { &mp_type_module },

0 commit comments

Comments
 (0)