Skip to content

Commit 4167bf5

Browse files
committed
wip: advertising works, but not connection
1 parent f5b15c9 commit 4167bf5

17 files changed

Lines changed: 163 additions & 115 deletions

File tree

docs/drivers.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ These provide functionality similar to `analogio`, `digitalio`, `pulseio`, and `
213213

214214
Adafruit SeeSaw <https://circuitpython.readthedocs.io/projects/seesaw/en/latest/>
215215
ADS1x15 Analog-to-Digital Converter <https://circuitpython.readthedocs.io/projects/ads1x15/en/latest/>
216-
Crickit Robotics Boards <<https://circuitpython.readthedocs.io/projects/crickit/en/latest/>
216+
Crickit Robotics Boards <https://circuitpython.readthedocs.io/projects/crickit/en/latest/>
217217
DS2413 OneWire GPIO Expander <https://circuitpython.readthedocs.io/projects/ds2413/en/latest/>
218218
FocalTech Capacitive Touch <https://circuitpython.readthedocs.io/projects/focaltouch/en/latest/>
219219
MCP230xx GPIO Expander <https://circuitpython.readthedocs.io/projects/mcp230xx/en/latest/>

ports/atmel-samd/Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,10 @@ BASE_CFLAGS = \
8181
-DCIRCUITPY_SAFE_RESTART_WORD=0xDEADBEEF \
8282
--param max-inline-insns-single=500
8383

84-
# Use these flags to debug build times and header includes.
85-
# -ftime-report
86-
# -H
84+
# Use these flags to debug build times and header includes.
85+
# -ftime-report
86+
# -H
87+
8788
# NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt.
8889

8990
ifeq ($(CHIP_FAMILY), samd21)

ports/nrf/Makefile

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,14 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_C
7979

8080
#Debugging/Optimization
8181
ifeq ($(DEBUG), 1)
82-
#ASMFLAGS += -g -gtabs+
83-
CFLAGS += -O1 -ggdb
84-
LDFLAGS += -O1
82+
#ASMFLAGS += -g -gtabs+
83+
CFLAGS += -O1 -ggdb
84+
LDFLAGS += -O1
85+
# You may want to enable these flags to make setting breakpoints easier.
86+
CFLAGS += -fno-inline -fno-ipa-sra
8587
else
86-
CFLAGS += -Os -DNDEBUG
87-
LDFLAGS += -Os
88+
CFLAGS += -Os -DNDEBUG
89+
LDFLAGS += -Os
8890
endif
8991

9092
LIBM_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-file-name=libm.a)
@@ -172,7 +174,7 @@ SRC_COMMON_HAL += \
172174
bleio/Adapter.c \
173175
bleio/Characteristic.c \
174176
bleio/Descriptor.c \
175-
bleio/Device.c \
177+
bleio/LocalPeripheral.c \
176178
bleio/Scanner.c \
177179
bleio/Service.c \
178180
bleio/UUID.c

ports/nrf/common-hal/bleio/Characteristic.c

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,19 @@
3030
#include "ble_drv.h"
3131
#include "ble_gatts.h"
3232
#include "nrf_soc.h"
33+
3334
#include "py/runtime.h"
35+
#include "common-hal/bleio/__init__.h"
3436
#include "shared-module/bleio/Characteristic.h"
3537

36-
static volatile bleio_characteristic_obj_t *m_read_characteristic;
37-
static volatile uint8_t m_tx_in_progress;
38-
static nrf_mutex_t *m_write_mutex;
38+
39+
STATIC volatile bleio_characteristic_obj_t *m_read_characteristic;
40+
STATIC volatile uint8_t m_tx_in_progress;
41+
STATIC nrf_mutex_t *m_write_mutex;
42+
3943

4044
STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
41-
bleio_device_obj_t *device = characteristic->service->device;
42-
const uint16_t conn_handle = device->conn_handle;
45+
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
4346

4447
ble_gatts_value_t gatts_value = {
4548
.p_value = bufinfo->buf,
@@ -48,17 +51,17 @@ STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in
4851

4952
const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value);
5053
if (err_code != NRF_SUCCESS) {
51-
mp_raise_OSError_msg(translate("Failed to write gatts value"));
54+
mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code);
5255
}
5356
}
5457

5558
STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
56-
bleio_device_obj_t *device = characteristic->service->device;
5759
uint16_t hvx_len = bufinfo->len;
5860

5961
ble_gatts_hvx_params_t hvx_params = {
6062
.handle = characteristic->handle,
6163
.type = BLE_GATT_HVX_NOTIFICATION,
64+
.offset = 0,
6265
.p_len = &hvx_len,
6366
.p_data = bufinfo->buf,
6467
};
@@ -69,25 +72,26 @@ STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_i
6972
#endif
7073
}
7174

72-
const uint32_t err_code = sd_ble_gatts_hvx(device->conn_handle, &hvx_params);
75+
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
76+
const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
7377
if (err_code != NRF_SUCCESS) {
74-
mp_raise_OSError_msg(translate("Failed to notify attribute value"));
78+
mp_raise_OSError_msg_varg(translate("Failed to notify attribute value, err %0x04x"), err_code);
7579
}
7680

7781
m_tx_in_progress += 1;
7882
}
7983

8084
STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) {
81-
bleio_service_obj_t *service = characteristic->service;
82-
bleio_device_obj_t *device = service->device;
85+
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
8386

8487
m_read_characteristic = characteristic;
8588

86-
const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0);
89+
const uint32_t err_code = sd_ble_gattc_read(conn_handle, characteristic->handle, 0);
8790
if (err_code != NRF_SUCCESS) {
88-
mp_raise_OSError_msg(translate("Failed to read attribute value"));
91+
mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err %0x04x"), err_code);
8992
}
9093

94+
//
9195
while (m_read_characteristic != NULL) {
9296
#ifdef MICROPY_VM_HOOK_LOOP
9397
MICROPY_VM_HOOK_LOOP
@@ -96,7 +100,7 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) {
96100
}
97101

98102
STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
99-
bleio_device_obj_t *device = characteristic->service->device;
103+
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
100104
uint32_t err_code;
101105

102106
ble_gattc_write_params_t write_params = {
@@ -112,13 +116,13 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in
112116

113117
err_code = sd_mutex_acquire(m_write_mutex);
114118
if (err_code != NRF_SUCCESS) {
115-
mp_raise_OSError_msg(translate("Failed to acquire mutex"));
119+
mp_raise_OSError_msg_varg(translate("Failed to acquire mutex, err 0x%04x"), err_code);
116120
}
117121
}
118122

119-
err_code = sd_ble_gattc_write(device->conn_handle, &write_params);
123+
err_code = sd_ble_gattc_write(conn_handle, &write_params);
120124
if (err_code != NRF_SUCCESS) {
121-
mp_raise_OSError_msg(translate("Failed to write attribute value"));
125+
mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code);
122126
}
123127

124128
while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) {
@@ -129,33 +133,28 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in
129133

130134
err_code = sd_mutex_release(m_write_mutex);
131135
if (err_code != NRF_SUCCESS) {
132-
mp_raise_OSError_msg(translate("Failed to release mutex"));
136+
mp_raise_OSError_msg_varg(translate("Failed to release mutex, err 0x%04x"), err_code);
133137
}
134138
}
135139

136140
STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) {
137141
switch (ble_evt->header.evt_id) {
138-
#if (BLE_API_VERSION == 4)
139142
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
140143
m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count;
141144
break;
142-
#else
143-
case BLE_EVT_TX_COMPLETE:
144-
m_tx_in_progress -= ble_evt->evt.common_evt.params.tx_complete.count;
145-
break;
146-
#endif
147145

148146
case BLE_GATTC_EVT_READ_RSP:
149147
{
150148
ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
151149
m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data);
150+
// Flag to busy-wait loop that we've read the characteristic.
152151
m_read_characteristic = NULL;
153152
break;
154153
}
155154

156155
case BLE_GATTC_EVT_WRITE_RSP:
156+
// Someone else can write now.
157157
sd_mutex_release(m_write_mutex);
158-
// m_write_done = true;
159158
break;
160159
}
161160
}
@@ -165,21 +164,34 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self)
165164
}
166165

167166
void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) {
168-
gattc_read(self);
167+
switch (common_hal_bleio_device_get_gatt_role(self->service->device)) {
168+
case GATT_ROLE_CLIENT:
169+
gattc_read(self);
170+
break;
171+
172+
default:
173+
mp_raise_RuntimeError(translate("bad GATT role"));
174+
break;
175+
}
169176
}
170177

171178
void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
172-
const bleio_device_obj_t *device = self->service->device;
173-
174-
if (device->is_peripheral) {
175-
// TODO: Add indications
179+
switch (common_hal_bleio_device_get_gatt_role(self->service->device)) {
180+
case GATT_ROLE_SERVER:
176181
if (self->props.notify) {
177182
gatts_notify(self, bufinfo);
178183
} else {
179184
gatts_write(self, bufinfo);
180185
}
181-
} else {
186+
break;
187+
188+
case GATT_ROLE_CLIENT:
189+
// TODO: Add indications
182190
gattc_write(self, bufinfo);
183-
}
191+
break;
184192

193+
default:
194+
mp_raise_RuntimeError(translate("bad GATT role"));
195+
break;
196+
}
185197
}

ports/nrf/common-hal/bleio/Scanner.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) {
7272
#if (BLUETOOTH_SD == 140)
7373
const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer);
7474
if (err_code != NRF_SUCCESS) {
75-
mp_raise_OSError_msg(translate("Failed to continue scanning"));
75+
mp_raise_OSError_msg_varg(translate("Failed to continue scanning, err 0x%04x"), err_code);
7676
}
7777
#endif
7878
}
@@ -98,7 +98,7 @@ void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout)
9898
#endif
9999

100100
if (err_code != NRF_SUCCESS) {
101-
mp_raise_OSError_msg(translate("Failed to start scanning"));
101+
mp_raise_OSError_msg_varg(translate("Failed to start scanning, err 0x%04x"), err_code);
102102
}
103103

104104
if (timeout > 0) {

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

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,58 +27,69 @@
2727
#include "ble_drv.h"
2828
#include "ble.h"
2929
#include "py/runtime.h"
30+
#include "common-hal/bleio/__init__.h"
3031
#include "shared-bindings/bleio/Service.h"
3132
#include "shared-bindings/bleio/Adapter.h"
3233

33-
void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) {
34-
ble_gatts_char_md_t char_md = {
35-
.char_props.broadcast = characteristic->props.broadcast,
36-
.char_props.read = characteristic->props.read,
37-
.char_props.write_wo_resp = characteristic->props.write_no_response,
38-
.char_props.write = characteristic->props.write,
39-
.char_props.notify = characteristic->props.notify,
40-
.char_props.indicate = characteristic->props.indicate,
41-
};
34+
void common_hal_bleio_service_construct(bleio_service_obj_t *self) {
35+
}
4236

43-
ble_gatts_attr_md_t cccd_md = {
44-
.vloc = BLE_GATTS_VLOC_STACK,
45-
};
37+
// Call this after the Service has been added to the LocalPeripheral.
38+
void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) {
39+
// Add all the characteristics.
40+
const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(self->char_list);
41+
for (size_t char_idx = 0; char_idx < char_list->len; ++char_idx) {
42+
bleio_characteristic_obj_t *characteristic = char_list->items[char_idx];
4643

47-
if (char_md.char_props.notify || char_md.char_props.indicate) {
48-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
49-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
44+
ble_gatts_char_md_t char_md = {
45+
.char_props.broadcast = characteristic->props.broadcast,
46+
.char_props.read = characteristic->props.read,
47+
.char_props.write_wo_resp = characteristic->props.write_no_response,
48+
.char_props.write = characteristic->props.write,
49+
.char_props.notify = characteristic->props.notify,
50+
.char_props.indicate = characteristic->props.indicate,
51+
};
5052

51-
char_md.p_cccd_md = &cccd_md;
52-
}
53+
ble_gatts_attr_md_t cccd_md = {
54+
.vloc = BLE_GATTS_VLOC_STACK,
55+
};
5356

54-
ble_uuid_t uuid;
55-
bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &uuid);
57+
if (char_md.char_props.notify || char_md.char_props.indicate) {
58+
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
59+
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
5660

57-
ble_gatts_attr_md_t attr_md = {
58-
.vloc = BLE_GATTS_VLOC_STACK,
59-
.vlen = 1,
60-
};
61+
char_md.p_cccd_md = &cccd_md;
62+
}
6163

62-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
63-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
64+
ble_uuid_t uuid;
65+
bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &uuid);
6466

65-
ble_gatts_attr_t attr_char_value = {
66-
.p_uuid = &uuid,
67-
.p_attr_md = &attr_md,
68-
.init_len = sizeof(uint8_t),
69-
.max_len = (BLE_GATT_ATT_MTU_DEFAULT - 3),
70-
};
67+
ble_gatts_attr_md_t attr_md = {
68+
.vloc = BLE_GATTS_VLOC_STACK,
69+
.vlen = 1,
70+
};
7171

72-
ble_gatts_char_handles_t handles;
72+
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
73+
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
7374

74-
uint32_t err_code;
75-
err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles);
76-
if (err_code != NRF_SUCCESS) {
77-
mp_raise_OSError_msg(translate("Could not add characteristic"));
78-
}
75+
ble_gatts_attr_t attr_char_value = {
76+
.p_uuid = &uuid,
77+
.p_attr_md = &attr_md,
78+
.init_len = sizeof(uint8_t),
79+
.max_len = GATT_MAX_DATA_LENGTH,
80+
};
7981

80-
characteristic->user_desc_handle = handles.user_desc_handle;
81-
characteristic->cccd_handle = handles.cccd_handle;
82-
characteristic->sccd_handle = handles.sccd_handle;
83-
characteristic->handle = handles.value_handle;
82+
ble_gatts_char_handles_t handles;
83+
84+
uint32_t err_code;
85+
err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles);
86+
if (err_code != NRF_SUCCESS) {
87+
mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code);
88+
}
89+
90+
characteristic->user_desc_handle = handles.user_desc_handle;
91+
characteristic->cccd_handle = handles.cccd_handle;
92+
characteristic->sccd_handle = handles.sccd_handle;
93+
characteristic->handle = handles.value_handle;
94+
}
8495
}

ports/nrf/common-hal/bleio/UUID.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, ui
5151
// Register this vendor-specific UUID. Bytes 12 and 13 will be zero.
5252
const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->nrf_ble_uuid.type);
5353
if (err_code != NRF_SUCCESS) {
54-
mp_raise_OSError_msg(translate("Could not register Vendor-Specific UUID"));
54+
mp_raise_OSError_msg_varg(translate("Failed to register Vendor-Specific UUID, err 0x%04x"), err_code);
5555
}
5656
}
5757
}
@@ -70,7 +70,7 @@ bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[1
7070
const uint32_t err_code = sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128);
7171

7272
if (err_code != NRF_SUCCESS) {
73-
mp_raise_RuntimeError(translate("Could not decode ble_uuid"));
73+
mp_raise_OSError_msg_varg(translate("Could not decode ble_uuid, err 0x%04x"), err_code);
7474
}
7575
// If not 16 bytes, this is not a 128-bit UUID, so return.
7676
return length == 16;

0 commit comments

Comments
 (0)