Skip to content

Commit 17f13ec

Browse files
committed
nrf: Cleanup of the ble driver
Moved the functions to classes that they belong to.
1 parent 77eeecb commit 17f13ec

File tree

18 files changed

+1024
-1141
lines changed

18 files changed

+1024
-1141
lines changed

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

Lines changed: 109 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,133 @@
2828
#include <stdio.h>
2929
#include <string.h>
3030

31+
#include "ble.h"
3132
#include "ble_drv.h"
32-
#include "nrfx.h"
33-
#include "nrf_error.h"
33+
#include "nrfx_power.h"
34+
#include "nrf_nvic.h"
3435
#include "nrf_sdm.h"
3536
#include "py/nlr.h"
36-
#include "shared-module/bleio/Address.h"
37+
#include "shared-bindings/bleio/Adapter.h"
38+
39+
STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
40+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AssertionError,
41+
"Soft device assert, id: 0x%08lX, pc: 0x%08lX", id, pc));
42+
}
43+
44+
STATIC uint32_t ble_stack_enable(void) {
45+
nrf_clock_lf_cfg_t clock_config = {
46+
.source = NRF_CLOCK_LF_SRC_XTAL,
47+
#if (BLE_API_VERSION == 4)
48+
.accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM
49+
#else
50+
.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM
51+
#endif
52+
};
53+
54+
#if (BLUETOOTH_SD == 140)
55+
// The SD takes over the POWER IRQ and will fail if the IRQ is already in use
56+
nrfx_power_uninit();
57+
#endif
58+
59+
uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler);
60+
if (err_code != NRF_SUCCESS)
61+
return err_code;
62+
63+
err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
64+
if (err_code != NRF_SUCCESS)
65+
return err_code;
66+
67+
uint32_t app_ram_start;
68+
#if (BLE_API_VERSION == 2)
69+
ble_enable_params_t ble_enable_params = {
70+
.gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT,
71+
.gap_enable_params.central_conn_count = 1,
72+
.gap_enable_params.periph_conn_count = 1,
73+
};
74+
75+
app_ram_start = 0x200039c0;
76+
err_code = sd_ble_enable(&ble_enable_params, &app_ram_start);
77+
#else
78+
app_ram_start = 0x20004000;
79+
80+
ble_cfg_t ble_conf;
81+
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
82+
ble_conf.conn_cfg.params.gap_conn_cfg.conn_count = BLE_GAP_CONN_COUNT_DEFAULT;
83+
ble_conf.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT;
84+
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_conf, app_ram_start);
85+
if (err_code != NRF_SUCCESS)
86+
return err_code;
87+
88+
memset(&ble_conf, 0, sizeof(ble_conf));
89+
ble_conf.gap_cfg.role_count_cfg.periph_role_count = 1;
90+
ble_conf.gap_cfg.role_count_cfg.central_role_count = 1;
91+
err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, app_ram_start);
92+
if (err_code != NRF_SUCCESS)
93+
return err_code;
94+
95+
memset(&ble_conf, 0, sizeof(ble_conf));
96+
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
97+
ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = MAX_TX_IN_PROGRESS;
98+
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, app_ram_start);
99+
if (err_code != NRF_SUCCESS)
100+
return err_code;
101+
102+
err_code = sd_ble_enable(&app_ram_start);
103+
#endif
104+
105+
return err_code;
106+
}
37107

38108
void common_hal_bleio_adapter_set_enabled(bool enabled) {
39-
uint32_t err_code;
109+
const bool is_enabled = common_hal_bleio_adapter_get_enabled();
40110

111+
// Don't enable or disable twice
112+
if ((is_enabled && enabled) || (!is_enabled && !enabled)) {
113+
return;
114+
}
115+
116+
uint32_t err_code;
41117
if (enabled) {
42-
err_code = ble_drv_stack_enable();
118+
err_code = ble_stack_enable();
43119
} else {
44120
err_code = sd_softdevice_disable();
45121
}
46122

47123
if (err_code != NRF_SUCCESS) {
48124
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
49-
"Failed to change softdevice status, error: 0x%08lX", err_code));
125+
"Failed to change softdevice state, error: 0x%08lX", err_code));
50126
}
51127
}
52128

53129
bool common_hal_bleio_adapter_get_enabled(void) {
54-
return ble_drv_stack_enabled();
130+
uint8_t is_enabled;
131+
132+
const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled);
133+
if (err_code != NRF_SUCCESS) {
134+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
135+
"Failed to get softdevice state, error: 0x%08lX", err_code));
136+
}
137+
138+
return is_enabled;
55139
}
56140

57141
void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) {
58-
ble_drv_address_get(address);
142+
ble_gap_addr_t local_address;
143+
uint32_t err_code;
144+
145+
common_hal_bleio_adapter_set_enabled(true);
146+
147+
#if (BLE_API_VERSION == 2)
148+
err_code = sd_ble_gap_address_get(&local_address);
149+
#else
150+
err_code = sd_ble_gap_addr_get(&local_address);
151+
#endif
152+
153+
if (err_code != NRF_SUCCESS) {
154+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
155+
"Failed to get local address, error: 0x%08lX", err_code));
156+
}
157+
158+
address->type = local_address.addr_type;
159+
memcpy(address->value, local_address.addr, BLEIO_ADDRESS_BYTES);
59160
}

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

Lines changed: 153 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,173 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
#include <string.h>
28+
#include <stdio.h>
29+
2730
#include "ble_drv.h"
31+
#include "ble_gatts.h"
32+
#include "nrf_soc.h"
33+
#include "py/nlr.h"
2834
#include "shared-module/bleio/Characteristic.h"
29-
#include "shared-module/bleio/Device.h"
35+
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;
39+
//static volatile bool m_write_done;
40+
41+
STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
42+
bleio_device_obj_t *device = characteristic->service->device;
43+
const uint16_t conn_handle = device->conn_handle;
44+
45+
ble_gatts_value_t gatts_value = {
46+
.p_value = bufinfo->buf,
47+
.len = bufinfo->len,
48+
};
49+
50+
const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value);
51+
if (err_code != NRF_SUCCESS) {
52+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
53+
"Failed to write gatts value, status: 0x%08lX", err_code));
54+
}
55+
}
56+
57+
STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
58+
bleio_device_obj_t *device = characteristic->service->device;
59+
uint16_t hvx_len = bufinfo->len;
60+
61+
ble_gatts_hvx_params_t hvx_params = {
62+
.handle = characteristic->handle,
63+
.type = BLE_GATT_HVX_NOTIFICATION,
64+
.p_len = &hvx_len,
65+
.p_data = bufinfo->buf,
66+
};
67+
68+
while (m_tx_in_progress > MAX_TX_IN_PROGRESS) {
69+
#ifdef MICROPY_VM_HOOK_LOOP
70+
MICROPY_VM_HOOK_LOOP
71+
#endif
72+
}
73+
74+
const uint32_t err_code = sd_ble_gatts_hvx(device->conn_handle, &hvx_params);
75+
if (err_code != NRF_SUCCESS) {
76+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
77+
"Failed to notify attribute value, status: 0x%08lX", err_code));
78+
}
79+
80+
m_tx_in_progress += 1;
81+
}
82+
83+
STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) {
84+
bleio_service_obj_t *service = characteristic->service;
85+
bleio_device_obj_t *device = service->device;
86+
87+
m_read_characteristic = characteristic;
88+
89+
const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0);
90+
if (err_code != NRF_SUCCESS) {
91+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
92+
"Failed to read attribute value, status: 0x%08lX", err_code));
93+
}
94+
95+
while (m_read_characteristic != NULL) {
96+
#ifdef MICROPY_VM_HOOK_LOOP
97+
MICROPY_VM_HOOK_LOOP
98+
#endif
99+
}
100+
}
101+
102+
STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
103+
bleio_device_obj_t *device = characteristic->service->device;
104+
uint16_t conn_handle = device->conn_handle;
105+
uint32_t err_code;
106+
107+
ble_gattc_write_params_t write_params;
108+
write_params.write_op = BLE_GATT_OP_WRITE_REQ;
109+
110+
if (characteristic->props.write_wo_resp) {
111+
write_params.write_op = BLE_GATT_OP_WRITE_CMD;
112+
}
113+
114+
write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL;
115+
write_params.handle = characteristic->handle;
116+
write_params.offset = 0;
117+
write_params.len = bufinfo->len;
118+
write_params.p_value = bufinfo->buf;
119+
120+
if (write_params.write_op == BLE_GATT_OP_WRITE_CMD) {
121+
err_code = sd_mutex_acquire(m_write_mutex);
122+
if (err_code != NRF_SUCCESS) {
123+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
124+
"Failed to acquire mutex, status: 0x%08lX", err_code));
125+
}
126+
}
127+
128+
err_code = sd_ble_gattc_write(conn_handle, &write_params);
129+
if (err_code != 0) {
130+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
131+
"Failed to write attribute value, status: 0x%08lX", err_code));
132+
}
133+
134+
while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) {
135+
#ifdef MICROPY_VM_HOOK_LOOP
136+
MICROPY_VM_HOOK_LOOP
137+
#endif
138+
}
139+
140+
err_code = sd_mutex_release(m_write_mutex);
141+
if (err_code != NRF_SUCCESS) {
142+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
143+
"Failed to release mutex, status: 0x%08lX", err_code));
144+
}
145+
}
146+
147+
STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) {
148+
switch (ble_evt->header.evt_id) {
149+
#if (BLE_API_VERSION == 4)
150+
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
151+
m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count;
152+
break;
153+
#else
154+
case BLE_EVT_TX_COMPLETE:
155+
m_tx_in_progress -= ble_evt->evt.common_evt.params.tx_complete.count;
156+
break;
157+
#endif
158+
159+
case BLE_GATTC_EVT_READ_RSP:
160+
{
161+
ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
162+
m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data);
163+
m_read_characteristic = NULL;
164+
break;
165+
}
166+
167+
case BLE_GATTC_EVT_WRITE_RSP:
168+
sd_mutex_release(m_write_mutex);
169+
// m_write_done = true;
170+
break;
171+
}
172+
}
173+
174+
void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self) {
175+
ble_drv_add_event_handler(on_ble_evt, NULL);
176+
}
30177

31178
void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) {
32-
ble_drv_attr_c_read(self);
179+
gattc_read(self);
33180
}
34181

35182
void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
36-
const bleio_device_obj_t *device = MP_OBJ_TO_PTR(self->service->device);
183+
const bleio_device_obj_t *device = self->service->device;
37184

38185
if (device->is_peripheral) {
39186
// TODO: Add indications
40187
if (self->props.notify) {
41-
ble_drv_attr_s_notify(self, bufinfo);
188+
gatts_notify(self, bufinfo);
42189
} else {
43-
ble_drv_attr_s_write(self, bufinfo);
190+
gatts_write(self, bufinfo);
44191
}
45192
} else {
46-
ble_drv_attr_c_write(self, bufinfo);
193+
gattc_write(self, bufinfo);
47194
}
48195

49196
}

0 commit comments

Comments
 (0)