diff --git a/nrf5/drivers/bluetooth/ble_drv.c b/nrf5/drivers/bluetooth/ble_drv.c index 418c1f4a3f..8d3348f5fc 100644 --- a/nrf5/drivers/bluetooth/ble_drv.c +++ b/nrf5/drivers/bluetooth/ble_drv.c @@ -77,6 +77,7 @@ static mp_obj_t mp_gatts_observer; #if (BLUETOOTH_SD == 130) || (BLUETOOTH_SD == 132) static volatile bool m_primary_service_found; static volatile bool m_characteristic_found; +static volatile bool m_write_done; static volatile ble_drv_adv_evt_callback_t adv_event_handler; static volatile ble_drv_gattc_evt_callback_t gattc_event_handler; @@ -679,23 +680,34 @@ void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, bl } } -void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) { +void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response) { - ble_gattc_write_params_t write_params; + ble_gattc_write_params_t write_params; - write_params.write_op = BLE_GATT_OP_WRITE_CMD; - write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL; - write_params.handle = handle; - write_params.offset = 0; - write_params.len = len; - write_params.p_value = p_data; + if (w_response) { + write_params.write_op = BLE_GATT_OP_WRITE_REQ; + } else { + write_params.write_op = BLE_GATT_OP_WRITE_CMD; + } - uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); + write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL; + write_params.handle = handle; + write_params.offset = 0; + write_params.len = len; + write_params.p_value = p_data; - if (err_code != 0) { + m_write_done = !w_response; + + uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); + + if (err_code != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Can not write attribute value. status: 0x" HEX2_FMT, (uint16_t)err_code)); - } + } + + while (m_write_done != true) { + ; + } } void ble_drv_scan_start(void) { @@ -1007,6 +1019,7 @@ static void ble_evt_handler(ble_evt_t * p_ble_evt) { case BLE_GATTC_EVT_WRITE_RSP: BLE_DRIVER_LOG("BLE EVT WRITE RESPONSE\n"); + m_write_done = true; break; case BLE_GATTC_EVT_HVX: diff --git a/nrf5/drivers/bluetooth/ble_drv.h b/nrf5/drivers/bluetooth/ble_drv.h index dc3cf168ef..e038f5cc96 100644 --- a/nrf5/drivers/bluetooth/ble_drv.h +++ b/nrf5/drivers/bluetooth/ble_drv.h @@ -104,7 +104,7 @@ void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, u void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); -void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); +void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response); void ble_drv_scan_start(void); diff --git a/nrf5/modules/ubluepy/ubluepy_characteristic.c b/nrf5/modules/ubluepy/ubluepy_characteristic.c index 18b58809f3..ea3f9b29e5 100644 --- a/nrf5/modules/ubluepy/ubluepy_characteristic.c +++ b/nrf5/modules/ubluepy/ubluepy_characteristic.c @@ -111,11 +111,20 @@ STATIC mp_obj_t char_read(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_characteristic_read_obj, char_read); -/// \method write(data) +/// \method write(data, [with_response=False]) /// Write Characteristic value. /// -STATIC mp_obj_t char_write(mp_obj_t self_in, mp_obj_t data) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t char_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + ubluepy_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_obj_t data = pos_args[1]; + + static const mp_arg_t allowed_args[] = { + { MP_QSTR_with_response, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } }, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_buffer_info_t bufinfo; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); @@ -137,16 +146,18 @@ STATIC mp_obj_t char_write(mp_obj_t self_in, mp_obj_t data) { } } else { #if MICROPY_PY_UBLUEPY_CENTRAL + bool with_response = args[0].u_bool; + ble_drv_attr_c_write(self->p_service->p_periph->conn_handle, self->handle, bufinfo.len, - bufinfo.buf); + bufinfo.buf, + with_response); #endif } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_characteristic_write_obj, char_write); - +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_characteristic_write_obj, 2, char_write); /// \method properties() /// Read Characteristic value properties.