Skip to content

Commit 17c8356

Browse files
committed
Add connection interval and debugging
This also sets TinyUSB to master and to not include its submodules. It also fixes an old displayio example comment and retries gattc reads.
1 parent 19dc219 commit 17c8356

File tree

12 files changed

+159
-23
lines changed

12 files changed

+159
-23
lines changed

.gitmodules

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
[submodule "lib/tinyusb"]
7777
path = lib/tinyusb
7878
url = https://github.com/hathach/tinyusb.git
79-
branch = develop
79+
branch = master
80+
fetchRecurseSubmodules = false
8081
[submodule "tools/huffman"]
8182
path = tools/huffman
8283
url = https://github.com/tannewt/huffman.git

ports/nrf/bluetooth/ble_drv.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ void SD_EVT_IRQHandler(void) {
134134
}
135135

136136
ble_evt_t* event = (ble_evt_t *)m_ble_evt_buf;
137+
#if CIRCUITPY_VERBOSE_BLE
138+
mp_printf(&mp_plat_print, "BLE event: 0x%04x\n", event->header.evt_id);
139+
#endif
137140

138141
if (supervisor_bluetooth_hook(event)) {
139142
continue;
@@ -145,8 +148,15 @@ void SD_EVT_IRQHandler(void) {
145148
done = it->func(event, it->param) || done;
146149
it = it->next;
147150
}
151+
#if CIRCUITPY_VERBOSE_BLE
152+
if (event->header.evt_id == BLE_GATTS_EVT_WRITE) {
153+
ble_gatts_evt_write_t* write_evt = &event->evt.gatts_evt.params.write;
154+
mp_printf(&mp_plat_print, "Write to: UUID(0x%04x) handle %x of length %d auth %x\n", write_evt->uuid.uuid, write_evt->handle, write_evt->len, write_evt->auth_required);
155+
}
148156
if (!done) {
149-
//mp_printf(&mp_plat_print, "Unhandled ble event: 0x%04x\n", event->header.evt_id);
157+
mp_printf(&mp_plat_print, "Unhandled ble event: 0x%04x\n", event->header.evt_id);
158+
150159
}
160+
#endif
151161
}
152162
}

ports/nrf/common-hal/_bleio/Adapter.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,18 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
180180
connection->conn_handle = ble_evt->evt.gap_evt.conn_handle;
181181
connection->connection_obj = mp_const_none;
182182
connection->pair_status = PAIR_NOT_PAIRED;
183+
183184
ble_drv_add_event_handler_entry(&connection->handler_entry, connection_on_ble_evt, connection);
184185
self->connection_objs = NULL;
185186

187+
// Save the current connection parameters.
188+
memcpy(&connection->conn_params, &connected->conn_params, sizeof(ble_gap_conn_params_t));
189+
190+
#if CIRCUITPY_VERBOSE_BLE
191+
ble_gap_conn_params_t *cp = &connected->conn_params;
192+
mp_printf(&mp_plat_print, "conn params: min_ci %d max_ci %d s_l %d sup_timeout %d\n", cp->min_conn_interval, cp->max_conn_interval, cp->slave_latency, cp->conn_sup_timeout);
193+
#endif
194+
186195
// See if connection interval set by Central is out of range.
187196
// If so, negotiate our preferred range.
188197
ble_gap_conn_params_t conn_params;

ports/nrf/common-hal/_bleio/Connection.c

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ static volatile bool m_discovery_successful;
7070
static bleio_service_obj_t *m_char_discovery_service;
7171
static bleio_characteristic_obj_t *m_desc_discovery_characteristic;
7272

73-
bool dump_events = false;
74-
7573
bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
7674
bleio_connection_internal_t *self = (bleio_connection_internal_t*)self_in;
7775

@@ -84,16 +82,9 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
8482
return false;
8583
}
8684

87-
// For debugging.
88-
if (dump_events) {
89-
mp_printf(&mp_plat_print, "Connection event: 0x%04x\n", ble_evt->header.evt_id);
90-
}
91-
9285
switch (ble_evt->header.evt_id) {
9386
case BLE_GAP_EVT_DISCONNECTED:
9487
break;
95-
case BLE_GAP_EVT_CONN_PARAM_UPDATE: // 0x12
96-
break;
9788
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
9889
ble_gap_phys_t const phys = {
9990
.rx_phys = BLE_GAP_PHY_AUTO,
@@ -124,15 +115,61 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
124115
sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
125116
break;
126117

127-
case BLE_GATTS_EVT_HVN_TX_COMPLETE: // Capture this for now. 0x55
118+
#if CIRCUITPY_VERBOSE_BLE
119+
// Use read authorization to snoop on all reads when doing verbose debugging.
120+
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: {
121+
122+
ble_gatts_evt_rw_authorize_request_t *request =
123+
&ble_evt->evt.gatts_evt.params.authorize_request;
124+
125+
mp_printf(&mp_plat_print, "Read %x offset %d ", request->request.read.handle, request->request.read.offset);
126+
uint8_t value_bytes[22];
127+
ble_gatts_value_t value;
128+
value.offset = request->request.read.offset;
129+
value.len = 22;
130+
value.p_value = value_bytes;
131+
132+
sd_ble_gatts_value_get(self->conn_handle, request->request.read.handle, &value);
133+
size_t len = value.len;
134+
if (len > 22) {
135+
len = 22;
136+
}
137+
for (uint8_t i = 0; i < len; i++) {
138+
mp_printf(&mp_plat_print, " %02x", value_bytes[i]);
139+
}
140+
mp_printf(&mp_plat_print, "\n");
141+
ble_gatts_rw_authorize_reply_params_t reply;
142+
reply.type = request->type;
143+
reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
144+
reply.params.read.update = false;
145+
reply.params.read.offset = request->request.read.offset;
146+
sd_ble_gatts_rw_authorize_reply(self->conn_handle, &reply);
128147
break;
148+
}
149+
#endif
129150

151+
case BLE_GATTS_EVT_HVN_TX_COMPLETE: // Capture this for now. 0x55
152+
break;
130153
case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: {
154+
self->conn_params_updating = true;
131155
ble_gap_evt_conn_param_update_request_t *request =
132156
&ble_evt->evt.gap_evt.params.conn_param_update_request;
133157
sd_ble_gap_conn_param_update(self->conn_handle, &request->conn_params);
134158
break;
135159
}
160+
case BLE_GAP_EVT_CONN_PARAM_UPDATE: { // 0x12
161+
ble_gap_evt_conn_param_update_t *result =
162+
&ble_evt->evt.gap_evt.params.conn_param_update;
163+
164+
#if CIRCUITPY_VERBOSE_BLE
165+
ble_gap_conn_params_t *cp = &ble_evt->evt.gap_evt.params.conn_param_update.conn_params;
166+
mp_printf(&mp_plat_print, "conn params updated: min_ci %d max_ci %d s_l %d sup_timeout %d\n", cp->min_conn_interval, cp->max_conn_interval, cp->slave_latency, cp->conn_sup_timeout);
167+
#endif
168+
169+
memcpy(&self->conn_params, &result->conn_params, sizeof(ble_gap_conn_params_t));
170+
self->conn_params_updating = false;
171+
break;
172+
}
136173
case BLE_GAP_EVT_SEC_PARAMS_REQUEST: {
137174
ble_gap_sec_keyset_t keyset = {
138175
.keys_own = {
@@ -212,9 +249,9 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
212249

213250
default:
214251
// For debugging.
215-
if (dump_events) {
252+
#if CIRCUITPY_VERBOSE_BLE
216253
mp_printf(&mp_plat_print, "Unhandled connection event: 0x%04x\n", ble_evt->header.evt_id);
217-
}
254+
#endif
218255

219256
return false;
220257
}
@@ -262,6 +299,25 @@ void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bo
262299
check_sec_status(self->sec_status);
263300
}
264301

302+
mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self) {
303+
while (self->conn_params_updating && !mp_hal_is_interrupted()) {
304+
RUN_BACKGROUND_TASKS;
305+
}
306+
return 1.25f * self->conn_params.min_conn_interval;
307+
}
308+
309+
void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval) {
310+
self->conn_params_updating = true;
311+
uint16_t interval = new_interval / 1.25f;
312+
self->conn_params.min_conn_interval = interval;
313+
self->conn_params.max_conn_interval = interval;
314+
uint32_t status = NRF_ERROR_BUSY;
315+
while (status == NRF_ERROR_BUSY) {
316+
status = sd_ble_gap_conn_param_update(self->conn_handle, &self->conn_params);
317+
RUN_BACKGROUND_TASKS;
318+
}
319+
check_nrf_error(status);
320+
}
265321

266322
// service_uuid may be NULL, to discover all services.
267323
STATIC bool discover_next_services(bleio_connection_internal_t* connection, uint16_t start_handle, ble_uuid_t *service_uuid) {
@@ -600,6 +656,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
600656
ble_drv_remove_event_handler(discovery_on_ble_evt, self);
601657

602658
}
659+
603660
mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) {
604661
discover_remote_services(self->connection, service_uuids_whitelist);
605662
// Convert to a tuple and then clear the list so the callee will take ownership.
@@ -609,7 +666,6 @@ mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_conne
609666
return services_tuple;
610667
}
611668

612-
613669
uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self) {
614670
if (self == NULL || self->connection == NULL) {
615671
return BLE_CONN_HANDLE_INVALID;

ports/nrf/common-hal/_bleio/Connection.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ typedef struct {
6363
uint8_t sec_status; // Internal security status.
6464
mp_obj_t connection_obj;
6565
ble_drv_evt_handler_entry_t handler_entry;
66+
ble_gap_conn_params_t conn_params;
67+
volatile bool conn_params_updating;
6668
} bleio_connection_internal_t;
6769

6870
typedef struct {

ports/nrf/common-hal/_bleio/Service.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
119119

120120
bleio_attribute_gatts_set_security_mode(&char_attr_md.read_perm, characteristic->read_perm);
121121
bleio_attribute_gatts_set_security_mode(&char_attr_md.write_perm, characteristic->write_perm);
122+
#if CIRCUITPY_VERBOSE_BLE
123+
// Turn on read authorization so that we receive an event to print on every read.
124+
char_attr_md.rd_auth = true;
125+
#endif
122126

123127
ble_gatts_attr_t char_attr = {
124128
.p_uuid = &char_uuid,
@@ -137,6 +141,9 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
137141
characteristic->cccd_handle = char_handles.cccd_handle;
138142
characteristic->sccd_handle = char_handles.sccd_handle;
139143
characteristic->handle = char_handles.value_handle;
144+
#if CIRCUITPY_VERBOSE_BLE
145+
mp_printf(&mp_plat_print, "Char handle %x user %x cccd %x sccd %x\n", characteristic->handle, characteristic->user_desc_handle, characteristic->cccd_handle, characteristic->sccd_handle);
146+
#endif
140147

141148
mp_obj_list_append(self->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
142149
}

ports/nrf/common-hal/_bleio/__init__.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,11 @@ size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_
187187
read_info.done = false;
188188
ble_drv_add_event_handler(_on_gattc_read_rsp_evt, &read_info);
189189

190-
check_nrf_error(sd_ble_gattc_read(conn_handle, handle, 0));
190+
uint32_t nrf_error = NRF_ERROR_BUSY;
191+
while (nrf_error == NRF_ERROR_BUSY) {
192+
nrf_error = sd_ble_gattc_read(conn_handle, handle, 0);
193+
}
194+
check_nrf_error(nrf_error);
191195

192196
while (!read_info.done) {
193197
RUN_BACKGROUND_TASKS;

py/circuitpy_mpconfig.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,4 +666,6 @@ void supervisor_run_background_tasks_if_tick(void);
666666
#define CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS 1000
667667
#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt"
668668

669+
#define CIRCUITPY_VERBOSE_BLE 0
670+
669671
#endif // __INCLUDED_MPCONFIG_CIRCUITPY_H

shared-bindings/_bleio/Connection.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,57 @@ const mp_obj_property_t bleio_connection_paired_obj = {
195195
(mp_obj_t)&mp_const_none_obj },
196196
};
197197

198+
199+
//| .. attribute:: connection_interval
200+
//|
201+
//| Time between transmissions in milliseconds. Will be multiple of 1.25ms. Lower numbers
202+
//| increase speed and decrease latency but increase power consumption.
203+
//|
204+
//| When setting connection_interval, the peer may reject the new interval and
205+
//| `connection_interval` will then remain the same.
206+
//|
207+
//| Apple has additional guidelines that dictate should be a multiple of 15ms except if HID is
208+
//| available. When HID is available Apple devices may accept 11.25ms intervals.
209+
//|
210+
//|
211+
STATIC mp_obj_t bleio_connection_get_connection_interval(mp_obj_t self_in) {
212+
bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
213+
214+
ensure_connected(self);
215+
return mp_obj_new_float(common_hal_bleio_connection_get_connection_interval(self->connection));
216+
}
217+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_connection_interval_obj, bleio_connection_get_connection_interval);
218+
219+
STATIC mp_obj_t bleio_connection_set_connection_interval(mp_obj_t self_in, mp_obj_t interval_in) {
220+
bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
221+
222+
mp_float_t interval = mp_obj_get_float(interval_in);
223+
224+
ensure_connected(self);
225+
common_hal_bleio_connection_set_connection_interval(self->connection, interval);
226+
227+
return mp_const_none;
228+
}
229+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_connection_set_connection_interval_obj, bleio_connection_set_connection_interval);
230+
231+
const mp_obj_property_t bleio_connection_connection_interval_obj = {
232+
.base.type = &mp_type_property,
233+
.proxy = { (mp_obj_t)&bleio_connection_get_connection_interval_obj,
234+
(mp_obj_t)&bleio_connection_set_connection_interval_obj,
235+
(mp_obj_t)&mp_const_none_obj },
236+
};
237+
198238
STATIC const mp_rom_map_elem_t bleio_connection_locals_dict_table[] = {
199239
// Methods
200240
{ MP_ROM_QSTR(MP_QSTR_pair), MP_ROM_PTR(&bleio_connection_pair_obj) },
201241
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_connection_disconnect_obj) },
202242
{ MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_connection_discover_remote_services_obj) },
203243

204244
// Properties
205-
{ MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_connection_connected_obj) },
206-
{ MP_ROM_QSTR(MP_QSTR_paired), MP_ROM_PTR(&bleio_connection_paired_obj) },
245+
{ MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_connection_connected_obj) },
246+
{ MP_ROM_QSTR(MP_QSTR_paired), MP_ROM_PTR(&bleio_connection_paired_obj) },
247+
{ MP_ROM_QSTR(MP_QSTR_connection_interval), MP_ROM_PTR(&bleio_connection_connection_interval_obj) },
248+
207249
};
208250

209251
STATIC MP_DEFINE_CONST_DICT(bleio_connection_locals_dict, bleio_connection_locals_dict_table);

shared-bindings/_bleio/Connection.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,7 @@ extern bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *se
4040
extern bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self);
4141
extern mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist);
4242

43+
mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self);
44+
void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval);
45+
4346
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CONNECTION_H

shared-bindings/displayio/OnDiskBitmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
//|
6060
//| with open("/sample.bmp", "rb") as f:
6161
//| odb = displayio.OnDiskBitmap(f)
62-
//| face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter(), position=(0,0))
62+
//| face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter())
6363
//| splash.append(face)
6464
//| # Wait for the image to load.
6565
//| board.DISPLAY.wait_for_frame()

supervisor/shared/bluetooth.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ bleio_uuid_obj_t supervisor_ble_length_uuid;
5252
bleio_characteristic_obj_t supervisor_ble_contents_characteristic;
5353
bleio_uuid_obj_t supervisor_ble_contents_uuid;
5454
const uint8_t circuitpython_base_uuid[16] = {0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x00, 0xaf, 0xad };
55-
uint8_t circuitpython_advertising_data[] = { 0x02, 0x01, 0x06, 0x02, 0x0a, 0x00, 0x11, 0x07, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x01, 0xaf, 0xad, 0x06, 0x08, 0x43, 0x49, 0x52, 0x43, 0x55 };
55+
uint8_t circuitpython_advertising_data[] = { 0x02, 0x01, 0x06, 0x02, 0x0a, 0x00, 0x11, 0x07, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x01, 0xaf, 0xad, 0x06, 0x08, 0x43, 0x49, 0x52, 0x43, 0x55 };
5656
uint8_t circuitpython_scan_response_data[15] = {0x0e, 0x09, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x50, 0x59, 0x00, 0x00, 0x00, 0x00};
5757
mp_obj_list_t service_list;
5858
mp_obj_t service_list_items[1];
@@ -86,7 +86,7 @@ void supervisor_start_bluetooth(void) {
8686
characteristic_list.len = 0;
8787
characteristic_list.items = characteristic_list_items;
8888
mp_seq_clear(characteristic_list.items, 0, characteristic_list.alloc, sizeof(*characteristic_list.items));
89-
89+
9090
_common_hal_bleio_service_construct(&supervisor_ble_service, &supervisor_ble_service_uuid, false /* is secondary */, &characteristic_list);
9191

9292
// File length
@@ -225,7 +225,7 @@ void supervisor_bluetooth_background(void) {
225225
uint16_t current_length = ((uint16_t*) current_command)[0];
226226
if (current_length > 0 && current_length == current_offset) {
227227
uint16_t command = ((uint16_t *) current_command)[1];
228-
228+
229229
if (command == 1) {
230230
uint16_t max_len = 20; //supervisor_ble_contents_characteristic.max_length;
231231
uint8_t buf[max_len];
@@ -274,7 +274,7 @@ void supervisor_bluetooth_background(void) {
274274
f_write(&active_file, &data, 1, &actual);
275275
}
276276
}
277-
277+
278278
f_lseek(&active_file, offset);
279279
uint8_t* data = (uint8_t *) (current_command + 4);
280280
UINT written;

0 commit comments

Comments
 (0)