summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml8
-rw-r--r--devices/ble_hci/common-hal/_bleio/Adapter.c958
-rw-r--r--devices/ble_hci/common-hal/_bleio/Adapter.h99
-rw-r--r--devices/ble_hci/common-hal/_bleio/Attribute.c49
-rw-r--r--devices/ble_hci/common-hal/_bleio/Attribute.h35
-rw-r--r--devices/ble_hci/common-hal/_bleio/Characteristic.c228
-rw-r--r--devices/ble_hci/common-hal/_bleio/Characteristic.h63
-rw-r--r--devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c104
-rw-r--r--devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.h43
-rw-r--r--devices/ble_hci/common-hal/_bleio/Connection.c772
-rw-r--r--devices/ble_hci/common-hal/_bleio/Connection.h89
-rw-r--r--devices/ble_hci/common-hal/_bleio/Descriptor.c114
-rw-r--r--devices/ble_hci/common-hal/_bleio/Descriptor.h53
-rw-r--r--devices/ble_hci/common-hal/_bleio/PacketBuffer.c265
-rw-r--r--devices/ble_hci/common-hal/_bleio/PacketBuffer.h53
-rw-r--r--devices/ble_hci/common-hal/_bleio/Service.c129
-rw-r--r--devices/ble_hci/common-hal/_bleio/Service.h54
-rw-r--r--devices/ble_hci/common-hal/_bleio/UUID.c75
-rw-r--r--devices/ble_hci/common-hal/_bleio/UUID.h58
-rw-r--r--devices/ble_hci/common-hal/_bleio/__init__.c112
-rw-r--r--devices/ble_hci/common-hal/_bleio/__init__.h62
-rw-r--r--devices/ble_hci/common-hal/_bleio/att.c1787
-rw-r--r--devices/ble_hci/common-hal/_bleio/att.h57
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci.c806
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci.h81
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_debug.c335
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/NOTE.txt2
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/addr.h101
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/att.h41
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/att_internal.h266
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/hci.h1767
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/hci_err.h92
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/hci_raw.h152
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/hci_vs.h379
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_include/l2cap_internal.h230
-rw-r--r--devices/ble_hci/supervisor/bluetooth.c29
-rw-r--r--devices/ble_hci/supervisor/bluetooth.h34
m---------lib/protomatter0
-rw-r--r--locale/ID.po92
-rw-r--r--locale/circuitpython.pot30
-rw-r--r--locale/cs.po92
-rw-r--r--locale/de_DE.po95
-rw-r--r--locale/es.po95
-rw-r--r--locale/fil.po92
-rw-r--r--locale/fr.po95
-rw-r--r--locale/hi.po92
-rw-r--r--locale/it_IT.po92
-rw-r--r--locale/ja.po405
-rw-r--r--locale/ko.po92
-rw-r--r--locale/nl.po95
-rw-r--r--locale/pl.po92
-rw-r--r--locale/pt_BR.po110
-rw-r--r--locale/sv.po165
-rw-r--r--locale/zh_Latn_pinyin.po92
-rwxr-xr-xmain.c10
-rw-r--r--ports/atmel-samd/Makefile9
-rw-r--r--ports/atmel-samd/boards/blm_badge/pins.c2
-rw-r--r--ports/atmel-samd/boards/matrixportal_m4/board.c39
-rw-r--r--ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.h30
-rw-r--r--ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.mk12
-rw-r--r--ports/atmel-samd/boards/matrixportal_m4/pins.c61
-rw-r--r--ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk4
-rw-r--r--ports/esp32s2/boards/electroniccats_bastwifi/board.c47
-rw-r--r--ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h32
-rw-r--r--ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.mk19
-rw-r--r--ports/esp32s2/boards/electroniccats_bastwifi/pins.c64
-rw-r--r--ports/esp32s2/boards/electroniccats_bastwifi/sdkconfig0
-rw-r--r--ports/esp32s2/boards/espressif_kaluga_1/board.c47
-rw-r--r--ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h34
-rw-r--r--ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk17
-rw-r--r--ports/esp32s2/boards/espressif_kaluga_1/pins.c125
-rw-r--r--ports/esp32s2/boards/espressif_kaluga_1/sdkconfig33
-rw-r--r--ports/nrf/bluetooth/ble_drv.c1
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.c3
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.c18
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.h4
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.c44
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.h5
-rw-r--r--ports/nrf/common-hal/_bleio/Descriptor.c5
-rw-r--r--ports/nrf/common-hal/_bleio/Descriptor.h3
-rw-r--r--ports/nrf/common-hal/_bleio/Service.c11
-rw-r--r--ports/nrf/common-hal/_bleio/Service.h1
-rw-r--r--ports/nrf/common-hal/_bleio/UUID.c2
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.c5
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.h1
-rw-r--r--ports/nrf/supervisor/bluetooth.c81
-rw-r--r--ports/nrf/supervisor/bluetooth.h36
-rw-r--r--ports/stm/boards/meowbit_v121/board.c2
-rw-r--r--ports/stm/boards/meowbit_v121/mpconfigboard.h3
-rw-r--r--ports/stm/boards/meowbit_v121/mpconfigboard.mk2
-rw-r--r--ports/stm/common-hal/pwmio/PWMOut.c3
-rw-r--r--ports/stm/mpconfigport.mk1
-rw-r--r--ports/stm/peripherals/stm32f4/clocks.c17
-rw-r--r--ports/stm/peripherals/stm32f7/clocks.c17
-rw-r--r--ports/stm/peripherals/stm32h7/clocks.c17
-rw-r--r--py/builtinimport.c2
-rw-r--r--py/circuitpy_defns.mk24
-rw-r--r--py/circuitpy_mpconfig.mk4
-rw-r--r--py/misc.h2
-rw-r--r--py/mkrules.mk5
-rw-r--r--py/obj.h25
-rw-r--r--py/py.mk2
-rw-r--r--shared-bindings/_bleio/Adapter.c68
-rw-r--r--shared-bindings/_bleio/Adapter.h4
-rw-r--r--shared-bindings/_bleio/Characteristic.c30
-rw-r--r--shared-bindings/_bleio/Characteristic.h10
-rw-r--r--shared-bindings/_bleio/Connection.c1
-rw-r--r--shared-bindings/_bleio/Descriptor.c11
-rw-r--r--shared-bindings/_bleio/Service.c24
-rw-r--r--shared-bindings/_bleio/Service.h4
-rw-r--r--shared-bindings/_bleio/UUID.c2
-rw-r--r--shared-bindings/_bleio/UUID.h4
-rw-r--r--shared-bindings/_bleio/__init__.c92
-rw-r--r--shared-bindings/_bleio/__init__.h4
-rw-r--r--shared-bindings/displayio/Display.c23
-rw-r--r--shared-bindings/rgbmatrix/RGBMatrix.c2
-rw-r--r--shared-bindings/rgbmatrix/RGBMatrix.h21
-rw-r--r--shared-bindings/usb_midi/__init__.c12
-rw-r--r--shared-module/_bleio/Characteristic.h13
-rw-r--r--shared-module/displayio/Display.c2
-rw-r--r--shared-module/framebufferio/FramebufferDisplay.c6
-rw-r--r--shared-module/rgbmatrix/RGBMatrix.c72
-rw-r--r--shared-module/rgbmatrix/RGBMatrix.h47
-rw-r--r--shared-module/rgbmatrix/allocator.h54
-rw-r--r--supervisor/shared/bluetooth.c81
-rw-r--r--supervisor/shared/bluetooth.h5
-rw-r--r--supervisor/shared/display.c8
-rw-r--r--supervisor/shared/tick.c4
-rw-r--r--supervisor/supervisor.mk2
-rw-r--r--tools/gen_usb_descriptor.py4
130 files changed, 11940 insertions, 1009 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e54bbb84b..6bb9612f8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -234,6 +234,7 @@ jobs:
- "makerdiary_nrf52840_m2_devkit"
- "makerdiary_nrf52840_mdk"
- "makerdiary_nrf52840_mdk_usb_dongle"
+ - "matrixportal_m4"
- "meowbit_v121"
- "meowmeow"
- "metro_m0_express"
@@ -408,6 +409,8 @@ jobs:
fail-fast: false
matrix:
board:
+ - "electroniccats_bastwifi"
+ - "espressif_kaluga_1"
- "espressif_saola_1_wroom"
- "espressif_saola_1_wrover"
- "microdev_micro_s2"
@@ -431,6 +434,11 @@ jobs:
with:
path: ${{ github.workspace }}/.idf_tools
key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/esp32s2/esp-idf/HEAD') }}-20200801
+ - name: Clone IDF submodules
+ run: |
+ (cd $IDF_PATH && git submodule update --init)
+ env:
+ IDF_PATH: ${{ github.workspace }}/ports/esp32s2/esp-idf
- name: Install IDF tools
run: |
$IDF_PATH/tools/idf_tools.py --non-interactive install required
diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c
new file mode 100644
index 000000000..559b586de
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Adapter.c
@@ -0,0 +1,958 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "hci.h"
+
+#include "py/gc.h"
+#include "py/mphal.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "supervisor/shared/safe_mode.h"
+#include "supervisor/shared/tick.h"
+#include "supervisor/usb.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Address.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/nvm/ByteArray.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/ScanEntry.h"
+#include "shared-bindings/time/__init__.h"
+
+#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
+#define SEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000000) / (RESOLUTION))
+#define UNITS_TO_SEC(TIME, RESOLUTION) (((TIME) * (RESOLUTION)) / 1000000)
+// 0.625 msecs (625 usecs)
+#define ADV_INTERVAL_UNIT_FLOAT_SECS (0.000625)
+// Microseconds is the base unit. The macros above know that.
+#define UNIT_0_625_MS (625)
+#define UNIT_1_25_MS (1250)
+#define UNIT_10_MS (10000)
+
+#define MAX_ADVERTISEMENT_SIZE (31)
+
+// TODO make this settable from Python.
+#define DEFAULT_TX_POWER 0 // 0 dBm
+#define MAX_ANONYMOUS_ADV_TIMEOUT_SECS (60*15)
+#define MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS (180)
+
+#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
+#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
+#define BLE_SLAVE_LATENCY 0
+#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
+
+bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
+
+STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
+ // Create Generic Access UUID, Service, and Characteristics.
+
+ // Generic Access Service setup.
+
+ bleio_uuid_obj_t *generic_access_service_uuid = m_new_obj(bleio_uuid_obj_t);
+ generic_access_service_uuid->base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(generic_access_service_uuid, 0x1800, NULL);
+
+ bleio_uuid_obj_t *device_name_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
+ device_name_characteristic_uuid->base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(device_name_characteristic_uuid, 0x2A00, NULL);
+
+ bleio_uuid_obj_t *appearance_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
+ appearance_characteristic_uuid->base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(appearance_characteristic_uuid, 0x2A01, NULL);
+
+ // Not implemented:
+ // Peripheral Preferred Connection Parameters
+ // Central Address Resolution
+
+ bleio_service_obj_t *generic_access_service = m_new_obj(bleio_service_obj_t);
+ generic_access_service->base.type = &bleio_service_type;
+ common_hal_bleio_service_construct(generic_access_service, generic_access_service_uuid, false);
+
+ adapter->device_name_characteristic = m_new_obj(bleio_characteristic_obj_t);
+ adapter->device_name_characteristic->base.type = &bleio_characteristic_type;
+
+ char generic_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 'n', 'n', 'n', 'n' };
+ mp_buffer_info_t generic_name_bufinfo = {
+ .buf = generic_name,
+ .len = sizeof(generic_name),
+ };
+
+ // Will be added to service by constructor.
+ common_hal_bleio_characteristic_construct(
+ adapter->device_name_characteristic,
+ generic_access_service,
+ BLE_GATT_HANDLE_INVALID,
+ device_name_characteristic_uuid,
+ CHAR_PROP_READ,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_NO_ACCESS,
+ 248, // max length, from Bluetooth spec
+ false, // not fixed length
+ &generic_name_bufinfo
+ );
+
+ uint16_t zero_16 = 0;
+ mp_buffer_info_t zero_16_value = {
+ .buf = &zero_16,
+ .len = sizeof(zero_16),
+ };
+
+ adapter->appearance_characteristic = m_new_obj(bleio_characteristic_obj_t);
+ adapter->appearance_characteristic->base.type = &bleio_characteristic_type;
+
+ common_hal_bleio_characteristic_construct(
+ adapter->appearance_characteristic,
+ generic_access_service,
+ BLE_GATT_HANDLE_INVALID,
+ appearance_characteristic_uuid,
+ CHAR_PROP_READ,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_NO_ACCESS,
+ 2, // max length, from Bluetooth spec
+ true, // fixed length
+ &zero_16_value
+ );
+
+ // Generic Attribute Service setup.
+
+ bleio_uuid_obj_t *generic_attribute_service_uuid = m_new_obj(bleio_uuid_obj_t);
+ generic_attribute_service_uuid->base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(generic_attribute_service_uuid, 0x1801, NULL);
+
+ bleio_uuid_obj_t *service_changed_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
+ service_changed_characteristic_uuid->base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(service_changed_characteristic_uuid, 0x2A05, NULL);
+
+ bleio_service_obj_t *generic_attribute_service = m_new_obj(bleio_service_obj_t);
+ generic_attribute_service->base.type = &bleio_service_type;
+ common_hal_bleio_service_construct(generic_attribute_service, generic_attribute_service_uuid, false);
+
+ adapter->service_changed_characteristic = m_new_obj(bleio_characteristic_obj_t);
+ adapter->service_changed_characteristic->base.type = &bleio_characteristic_type;
+
+ uint32_t zero_32 = 0;
+ mp_buffer_info_t zero_32_value = {
+ .buf = &zero_32,
+ .len = sizeof(zero_32),
+ };
+
+ common_hal_bleio_characteristic_construct(
+ adapter->service_changed_characteristic,
+ generic_attribute_service,
+ BLE_GATT_HANDLE_INVALID,
+ service_changed_characteristic_uuid,
+ CHAR_PROP_INDICATE,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_NO_ACCESS,
+ 4, // max length, from Bluetooth spec
+ true, // fixed length
+ &zero_32_value
+ );
+}
+
+
+STATIC void check_enabled(bleio_adapter_obj_t *adapter) {
+ if (!common_hal_bleio_adapter_get_enabled(adapter)) {
+ mp_raise_bleio_BluetoothError(translate("Adapter not enabled"));
+ }
+}
+
+// STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
+// bleio_adapter_obj_t *self = (bleio_adapter_obj_t*)self_in;
+
+// // For debugging.
+// // mp_printf(&mp_plat_print, "Adapter event: 0x%04x\n", ble_evt->header.evt_id);
+
+// switch (ble_evt->header.evt_id) {
+// case BLE_GAP_EVT_CONNECTED: {
+// // Find an empty connection. One must always be available because the SD has the same
+// // total connection limit.
+// bleio_connection_internal_t *connection;
+// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+// connection = &bleio_connections[i];
+// if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
+// break;
+// }
+// }
+
+// // Central has connected.
+// ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected;
+
+// connection->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+// connection->connection_obj = mp_const_none;
+// connection->pair_status = PAIR_NOT_PAIRED;
+// connection->mtu = 0;
+
+// ble_drv_add_event_handler_entry(&connection->handler_entry, connection_on_ble_evt, connection);
+// self->connection_objs = NULL;
+
+// // Save the current connection parameters.
+// memcpy(&connection->conn_params, &connected->conn_params, sizeof(ble_gap_conn_params_t));
+
+// #if CIRCUITPY_VERBOSE_BLE
+// ble_gap_conn_params_t *cp = &connected->conn_params;
+// 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);
+// #endif
+
+// // See if connection interval set by Central is out of range.
+// // If so, negotiate our preferred range.
+// ble_gap_conn_params_t conn_params;
+// sd_ble_gap_ppcp_get(&conn_params);
+// if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval ||
+// conn_params.min_conn_interval > connected->conn_params.max_conn_interval) {
+// sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
+// }
+// self->current_advertising_data = NULL;
+// break;
+// }
+// case BLE_GAP_EVT_DISCONNECTED: {
+// // Find the connection that was disconnected.
+// bleio_connection_internal_t *connection;
+// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+// connection = &bleio_connections[i];
+// if (connection->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
+// break;
+// }
+// }
+// ble_drv_remove_event_handler(connection_on_ble_evt, connection);
+// connection->conn_handle = BLE_CONN_HANDLE_INVALID;
+// connection->pair_status = PAIR_NOT_PAIRED;
+// if (connection->connection_obj != mp_const_none) {
+// bleio_connection_obj_t* obj = connection->connection_obj;
+// obj->connection = NULL;
+// obj->disconnect_reason = ble_evt->evt.gap_evt.params.disconnected.reason;
+// }
+// self->connection_objs = NULL;
+
+// break;
+// }
+
+// case BLE_GAP_EVT_ADV_SET_TERMINATED:
+// self->current_advertising_data = NULL;
+// break;
+
+// default:
+// // For debugging.
+// // mp_printf(&mp_plat_print, "Unhandled adapter event: 0x%04x\n", ble_evt->header.evt_id);
+// return false;
+// break;
+// }
+// return true;
+// }
+
+char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0};
+
+// Get various values and limits set by the adapter.
+// Set event mask.
+STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) {
+
+ const size_t len = sizeof(default_ble_name);
+
+ bt_addr_t addr;
+ hci_check_error(hci_read_bd_addr(&addr));
+
+ default_ble_name[len - 4] = nibble_to_hex_lower[addr.val[1] >> 4 & 0xf];
+ default_ble_name[len - 3] = nibble_to_hex_lower[addr.val[1] & 0xf];
+ default_ble_name[len - 2] = nibble_to_hex_lower[addr.val[0] >> 4 & 0xf];
+ default_ble_name[len - 1] = nibble_to_hex_lower[addr.val[0] & 0xf];
+ self->name = mp_obj_new_str(default_ble_name, len);
+
+ // Get version information.
+ if (hci_read_local_version(&self->hci_version, &self->hci_revision, &self->lmp_version,
+ &self->manufacturer, &self->lmp_subversion) != HCI_OK) {
+ mp_raise_bleio_BluetoothError(translate("Could not read HCI version"));
+ }
+ // Get supported features.
+ if (hci_le_read_local_supported_features(self->features) != HCI_OK) {
+ mp_raise_bleio_BluetoothError(translate("Could not read BLE features"));
+ }
+
+ // Enabled desired events.
+ // Most importantly, includes:
+ // BT_EVT_MASK_LE_META_EVENT BT_EVT_BIT(61)
+ if (hci_set_event_mask(0x3FFFFFFFFFFFFFFF) != HCI_OK) {
+ mp_raise_bleio_BluetoothError(translate("Could not set event mask"));
+ }
+ // The default events for LE are:
+ // BT_EVT_MASK_LE_CONN_COMPLETE, BT_EVT_MASK_LE_ADVERTISING_REPORT,
+ // BT_EVT_MASK_LE_CONN_UPDATE_COMPLETE, BT_EVT_MASK_LE_REMOTE_FEAT_COMPLETE
+ // BT_EVT_MASK_LE_LTK_REQUEST.
+ // That's all we need right now, so we don't bother to set the LE event mask.
+
+ // Get ACL buffer info.
+ uint16_t le_max_len;
+ uint8_t le_max_num;
+ if (hci_le_read_buffer_size(&le_max_len, &le_max_num) == HCI_OK) {
+ self->max_acl_buffer_len = le_max_len;
+ self->max_acl_num_buffers = le_max_num;
+ } else {
+ // LE Read Buffer Size not available; use the general Read Buffer Size.
+ uint16_t acl_max_len;
+ uint8_t sco_max_len;
+ uint16_t acl_max_num;
+ uint16_t sco_max_num;
+ if (hci_read_buffer_size(&acl_max_len, &sco_max_len, &acl_max_num, &sco_max_num) != HCI_OK) {
+ mp_raise_bleio_BluetoothError(translate("Could not read BLE buffer info"));
+ }
+ self->max_acl_buffer_len = acl_max_len;
+ self->max_acl_num_buffers = acl_max_num;
+ }
+
+ // Get max advertising length if extended advertising is supported.
+ if (BT_FEAT_LE_EXT_ADV(self->features)) {
+ uint16_t max_adv_data_len;
+ if (hci_le_read_maximum_advertising_data_length(&max_adv_data_len) != HCI_OK) {
+ mp_raise_bleio_BluetoothError(translate("Could not get max advertising length"));
+ }
+ self->max_adv_data_len = max_adv_data_len;
+ } else {
+ self->max_adv_data_len = MAX_ADVERTISEMENT_SIZE;
+ }
+}
+
+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) {
+ self->allocated = true;
+ self->hci_uart = uart;
+ self->rts_digitalinout = rts;
+ self->cts_digitalinout = cts;
+
+ // Advertising-related fields are initialized by common_hal_bleio_adapter_set_enabled().
+ self->enabled = false;
+
+ common_hal_bleio_adapter_set_enabled(self, true);
+ bleio_adapter_hci_init(self);
+ common_hal_bleio_adapter_set_name(self, default_ble_name);
+}
+
+void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled) {
+ const bool is_enabled = common_hal_bleio_adapter_get_enabled(self);
+
+ // Don't enable or disable twice
+ if (is_enabled == enabled) {
+ return;
+ }
+
+ self->enabled = enabled;
+
+ // We must poll for input from the HCI adapter.
+ // TODO Can we instead trigger an interrupt on UART input traffic?
+ if (enabled) {
+ supervisor_enable_tick();
+ } else {
+ supervisor_disable_tick();
+ }
+
+ // Enabling or disabling: stop any current activity; reset to known state.
+ hci_reset();
+ self->now_advertising = false;
+ self->extended_advertising = false;
+ self->circuitpython_advertising = false;
+ self->advertising_timeout_msecs = 0;
+
+ if (enabled) {
+ // Reset list of known attributes.
+ // Indices into the list are handles. Handle 0x0000 designates an invalid handle,
+ // so store None there to skip it.
+ self->attributes = mp_obj_new_list(0, NULL);
+ bleio_adapter_add_attribute(self, mp_const_none);
+ add_generic_services(self);
+ }
+}
+
+bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {
+ return self->enabled;
+}
+
+bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self) {
+ check_enabled(self);
+
+ bt_addr_t addr;
+ hci_check_error(hci_read_bd_addr(&addr));
+
+ bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
+ address->base.type = &bleio_address_type;
+
+ common_hal_bleio_address_construct(address, addr.val, BT_ADDR_LE_PUBLIC);
+ return address;
+}
+
+bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_address_obj_t *address) {
+ mp_buffer_info_t bufinfo;
+ if (!mp_get_buffer(address->bytes, &bufinfo, MP_BUFFER_READ)) {
+ return false;
+ }
+ return hci_le_set_random_address(bufinfo.buf) == HCI_OK;
+}
+
+mp_obj_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
+ return self->name;
+}
+
+void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name) {
+ self->name = mp_obj_new_str(name, strlen(name));
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(self->name, &bufinfo, MP_BUFFER_READ);
+ bleio_characteristic_set_local_value(self->device_name_characteristic, &bufinfo);
+}
+
+
+// STATIC bool scan_on_ble_evt(ble_evt_t *ble_evt, void *scan_results_in) {
+// bleio_scanresults_obj_t *scan_results = (bleio_scanresults_obj_t*)scan_results_in;
+
+// if (ble_evt->header.evt_id == BLE_GAP_EVT_TIMEOUT &&
+// ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) {
+// shared_module_bleio_scanresults_set_done(scan_results, true);
+// ble_drv_remove_event_handler(scan_on_ble_evt, scan_results);
+// return true;
+// }
+
+// if (ble_evt->header.evt_id != BLE_GAP_EVT_ADV_REPORT) {
+// return false;
+// }
+// ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report;
+
+// shared_module_bleio_scanresults_append(scan_results,
+// supervisor_ticks_ms64(),
+// report->type.connectable,
+// report->type.scan_response,
+// report->rssi,
+// report->peer_addr.addr,
+// report->peer_addr.addr_type,
+// report->data.p_data,
+// report->data.len);
+
+// const uint32_t err_code = sd_ble_gap_scan_start(NULL, scan_results->common_hal_data);
+// if (err_code != NRF_SUCCESS) {
+// // TODO: Pass the error into the scan results so it can throw an exception.
+// scan_results->done = true;
+// }
+// return true;
+// }
+
+mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) {
+ // TODO
+ mp_raise_NotImplementedError(NULL);
+ check_enabled(self);
+
+ if (self->scan_results != NULL) {
+ if (!shared_module_bleio_scanresults_get_done(self->scan_results)) {
+ mp_raise_bleio_BluetoothError(translate("Scan already in progess. Stop with stop_scan."));
+ }
+ self->scan_results = NULL;
+ }
+ self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi);
+
+ // size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX;
+ // uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size, false);
+ // ble_data_t * sd_data = (ble_data_t *) raw_data;
+ // self->scan_results->common_hal_data = sd_data;
+ // sd_data->len = max_packet_size;
+ // sd_data->p_data = raw_data + sizeof(ble_data_t);
+
+ // ble_drv_add_event_handler(scan_on_ble_evt, self->scan_results);
+
+ // uint32_t nrf_timeout = SEC_TO_UNITS(timeout, UNIT_10_MS);
+ // if (timeout <= 0.0001) {
+ // nrf_timeout = BLE_GAP_SCAN_TIMEOUT_UNLIMITED;
+ // }
+
+ // ble_gap_scan_params_t scan_params = {
+ // .extended = extended,
+ // .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
+ // .timeout = nrf_timeout,
+ // .window = SEC_TO_UNITS(window, UNIT_0_625_MS),
+ // .scan_phys = BLE_GAP_PHY_1MBPS,
+ // .active = active
+ // };
+ // uint32_t err_code;
+ // vm_used_ble = true;
+ // err_code = sd_ble_gap_scan_start(&scan_params, sd_data);
+
+ // if (err_code != NRF_SUCCESS) {
+ // self->scan_results = NULL;
+ // ble_drv_remove_event_handler(scan_on_ble_evt, self->scan_results);
+ // check_nrf_error(err_code);
+ // }
+
+ return MP_OBJ_FROM_PTR(self->scan_results);
+}
+
+void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self) {
+ // TODO
+ mp_raise_NotImplementedError(NULL);
+ check_enabled(self);
+
+ // If not already scanning, no problem.
+ if (hci_le_set_scan_enable(BT_HCI_LE_SCAN_DISABLE, BT_HCI_LE_SCAN_FILTER_DUP_DISABLE) == HCI_OK) {
+ shared_module_bleio_scanresults_set_done(self->scan_results, true);
+ self->scan_results = NULL;
+ }
+}
+
+// typedef struct {
+// uint16_t conn_handle;
+// volatile bool done;
+// } connect_info_t;
+
+// STATIC bool connect_on_ble_evt(ble_evt_t *ble_evt, void *info_in) {
+// connect_info_t *info = (connect_info_t*)info_in;
+
+// switch (ble_evt->header.evt_id) {
+// case BLE_GAP_EVT_CONNECTED:
+// info->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+// info->done = true;
+
+// break;
+
+// case BLE_GAP_EVT_TIMEOUT:
+// // Handle will be invalid.
+// info->done = true;
+// break;
+// default:
+// // For debugging.
+// // mp_printf(&mp_plat_print, "Unhandled central event: 0x%04x\n", ble_evt->header.evt_id);
+// return false;
+// break;
+// }
+// return true;
+// }
+
+mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout) {
+ // TODO
+ mp_raise_NotImplementedError(NULL);
+
+ check_enabled(self);
+
+ // ble_gap_addr_t addr;
+
+ // addr.addr_type = address->type;
+ // mp_buffer_info_t address_buf_info;
+ // mp_get_buffer_raise(address->bytes, &address_buf_info, MP_BUFFER_READ);
+ // memcpy(addr.addr, (uint8_t *) address_buf_info.buf, NUM_BLEIO_ADDRESS_BYTES);
+
+ // ble_gap_scan_params_t scan_params = {
+ // .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS),
+ // .window = MSEC_TO_UNITS(100, UNIT_0_625_MS),
+ // .scan_phys = BLE_GAP_PHY_1MBPS,
+ // // timeout of 0 means no timeout
+ // .timeout = SEC_TO_UNITS(timeout, UNIT_10_MS),
+ // };
+
+ // ble_gap_conn_params_t conn_params = {
+ // .conn_sup_timeout = MSEC_TO_UNITS(4000, UNIT_10_MS),
+ // .min_conn_interval = MSEC_TO_UNITS(15, UNIT_1_25_MS),
+ // .max_conn_interval = MSEC_TO_UNITS(300, UNIT_1_25_MS),
+ // .slave_latency = 0, // number of conn events
+ // };
+
+ // connect_info_t event_info;
+ // ble_drv_add_event_handler(connect_on_ble_evt, &event_info);
+ // event_info.done = false;
+
+ vm_used_ble = true;
+ // uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
+
+ // if (err_code != NRF_SUCCESS) {
+ // ble_drv_remove_event_handler(connect_on_ble_evt, &event_info);
+ // check_nrf_error(err_code);
+ // }
+
+ // while (!event_info.done) {
+ // RUN_BACKGROUND_TASKS;
+ // }
+
+ // ble_drv_remove_event_handler(connect_on_ble_evt, &event_info);
+
+ // uint16_t conn_handle = event_info.conn_handle;
+ // if (conn_handle == BLE_CONN_HANDLE_INVALID) {
+ // mp_raise_bleio_BluetoothError(translate("Failed to connect: timeout"));
+ // }
+
+ // // Negotiate for better PHY, larger MTU and data lengths since we are the central. These are
+ // // nice-to-haves so ignore any errors.
+ // ble_gap_phys_t const phys = {
+ // .rx_phys = BLE_GAP_PHY_AUTO,
+ // .tx_phys = BLE_GAP_PHY_AUTO,
+ // };
+ // sd_ble_gap_phy_update(conn_handle, &phys);
+ // sd_ble_gattc_exchange_mtu_request(conn_handle, BLE_GATTS_VAR_ATTR_LEN_MAX);
+ // sd_ble_gap_data_length_update(conn_handle, NULL, NULL);
+
+ // Make the connection object and return it.
+ // for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ // bleio_connection_internal_t *connection = &bleio_connections[i];
+ // if (connection->conn_handle == conn_handle) {
+ // return bleio_connection_new_from_internal(connection);
+ // }
+ // }
+
+ mp_raise_bleio_BluetoothError(translate("Failed to connect: internal error"));
+
+ return mp_const_none;
+}
+
+STATIC void check_data_fit(size_t data_len, bool connectable) {
+ if (data_len > MAX_ADVERTISEMENT_SIZE) {
+ mp_raise_ValueError(translate("Data too large for advertisement packet"));
+ }
+}
+
+// STATIC bool advertising_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
+// bleio_adapter_obj_t *self = (bleio_adapter_obj_t*)self_in;
+
+// switch (ble_evt->header.evt_id) {
+// case BLE_GAP_EVT_ADV_SET_TERMINATED:
+// common_hal_bleio_adapter_stop_advertising(self);
+// ble_drv_remove_event_handler(advertising_on_ble_evt, self_in);
+// break;
+
+// default:
+// // For debugging.
+// // mp_printf(&mp_plat_print, "Unhandled advertising event: 0x%04x\n", ble_evt->header.evt_id);
+// return false;
+// break;
+// }
+// return true;
+// }
+
+uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len) {
+ check_enabled(self);
+
+ if (self->now_advertising) {
+ if (self->circuitpython_advertising) {
+ common_hal_bleio_adapter_stop_advertising(self);
+ } else {
+ // User-requested advertising.
+ // TODO allow multiple advertisements.
+ // Already advertising. Can't advertise twice.
+ return 1;
+ }
+ }
+
+ // Peer address, which we don't use (no directed advertising).
+ bt_addr_le_t empty_addr = { 0 };
+
+ bool extended =
+ advertising_data_len > self->max_adv_data_len || scan_response_data_len > self->max_adv_data_len;
+
+ if (extended) {
+ if (!BT_FEAT_LE_EXT_ADV(self->features)) {
+ mp_raise_bleio_BluetoothError(translate("Data length needs extended advertising, but this adapter does not support it"));
+ }
+
+ uint16_t props = 0;
+ if (connectable) {
+ props |= BT_HCI_LE_ADV_PROP_CONN;
+ }
+ if (scan_response_data_len > 0) {
+ props |= BT_HCI_LE_ADV_PROP_SCAN;
+ }
+
+ // Advertising interval.
+ uint32_t interval_units = SEC_TO_UNITS(interval, UNIT_0_625_MS);
+
+ hci_check_error(
+ hci_le_set_extended_advertising_parameters(
+ 0, // handle
+ props, // adv properties
+ interval_units, // min interval
+ interval_units, // max interval
+ 0b111, // channel map: channels 37, 38, 39
+ anonymous ? BT_ADDR_LE_RANDOM : BT_ADDR_LE_PUBLIC,
+ &empty_addr, // peer_addr,
+ 0x00, // filter policy: no filter
+ DEFAULT_TX_POWER,
+ BT_HCI_LE_EXT_SCAN_PHY_1M, // Secondary PHY to use
+ 0x00, // AUX_ADV_IND shall be sent prior to next adv event
+ BT_HCI_LE_EXT_SCAN_PHY_1M, // Secondary PHY to use
+ 0x00, // Advertising SID
+ 0x00 // Scan req notify disable
+ ));
+
+ // We can use the duration mechanism provided, instead of our own.
+ self->advertising_timeout_msecs = 0;
+
+ uint8_t handle[1] = { 0 };
+ uint16_t duration_10msec[1] = { timeout * 100 };
+ uint8_t max_ext_adv_evts[1] = { 0 };
+ hci_check_error(
+ hci_le_set_extended_advertising_enable(
+ BT_HCI_LE_ADV_ENABLE,
+ 1, // one advertising set.
+ handle,
+ duration_10msec,
+ max_ext_adv_evts
+ ));
+
+ self->extended_advertising = true;
+ } else {
+ // Legacy advertising (not extended).
+
+ uint8_t adv_type;
+ if (connectable) {
+ // Connectable, scannable, undirected.
+ adv_type = BT_HCI_ADV_IND;
+ } else if (scan_response_data_len > 0) {
+ // Unconnectable, scannable, undirected.
+ adv_type = BT_HCI_ADV_SCAN_IND;
+ } else {
+ // Unconnectable, unscannable, undirected.
+ adv_type = BT_HCI_ADV_NONCONN_IND;
+ }
+
+ // Advertising interval.
+ uint16_t interval_units = SEC_TO_UNITS(interval, UNIT_0_625_MS);
+
+ hci_check_error(
+ hci_le_set_advertising_parameters(
+ interval_units, // min interval
+ interval_units, // max interval
+ adv_type,
+ anonymous ? BT_ADDR_LE_RANDOM : BT_ADDR_LE_PUBLIC,
+ &empty_addr,
+ 0b111, // channel map: channels 37, 38, 39
+ 0x00 // filter policy: no filter
+ ));
+
+ // The HCI commands expect MAX_ADVERTISEMENT_SIZE (31)octets,
+ // even though the actual data length may be shorter.
+ uint8_t full_data[MAX_ADVERTISEMENT_SIZE] = { 0 };
+ memcpy(full_data, advertising_data, MIN(sizeof(full_data), advertising_data_len));
+ hci_check_error(hci_le_set_advertising_data(advertising_data_len, full_data));
+ memset(full_data, 0, sizeof(full_data));
+ if (scan_response_data_len > 0) {
+ memcpy(full_data, scan_response_data, MIN(sizeof(full_data), scan_response_data_len));
+ hci_check_error(hci_le_set_scan_response_data(scan_response_data_len, full_data));
+ }
+
+ // No duration mechanism is provided for legacy advertising, so we need to do our own.
+ self->advertising_timeout_msecs = timeout * 1000;
+ self->advertising_start_ticks = supervisor_ticks_ms64();
+
+ // Start advertising.
+ hci_check_error(hci_le_set_advertising_enable(BT_HCI_LE_ADV_ENABLE));
+ self->extended_advertising = false;
+ } // end legacy advertising setup
+
+ vm_used_ble = true;
+ self->now_advertising = true;
+ return 0;
+}
+
+void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
+ check_enabled(self);
+
+ // interval value has already been validated.
+
+ check_data_fit(advertising_data_bufinfo->len, connectable);
+ check_data_fit(scan_response_data_bufinfo->len, connectable);
+
+ if (advertising_data_bufinfo->len > MAX_ADVERTISEMENT_SIZE && scan_response_data_bufinfo->len > 0) {
+ mp_raise_bleio_BluetoothError(translate("Extended advertisements with scan response not supported."));
+ }
+
+ // Anonymous mode requires a timeout so that we don't continue to broadcast
+ // the same data while cycling the MAC address -- otherwise, what's the
+ // point of randomizing the MAC address?
+ if (timeout == 0 && anonymous) {
+ timeout = MAX_ANONYMOUS_ADV_TIMEOUT_SECS;
+ } else {
+ if (timeout > MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS) {
+ mp_raise_bleio_BluetoothError(translate("Timeout is too long: Maximum timeout length is %d seconds"),
+ MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS);
+ }
+ }
+
+ const uint32_t result =_common_hal_bleio_adapter_start_advertising(
+ self, connectable, anonymous, timeout, interval,
+ advertising_data_bufinfo->buf,
+ advertising_data_bufinfo->len,
+ scan_response_data_bufinfo->buf,
+ scan_response_data_bufinfo->len);
+
+ if (result) {
+ mp_raise_bleio_BluetoothError(translate("Already advertising"));
+ }
+ self->circuitpython_advertising = false;
+}
+
+void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
+ check_enabled(self);
+
+ self->now_advertising = false;
+ self->extended_advertising = false;
+ self->circuitpython_advertising = false;
+
+ int result = hci_le_set_advertising_enable(BT_HCI_LE_ADV_DISABLE);
+ // OK if we're already stopped. There seems to be an ESP32 HCI bug:
+ // If advertising is already off, then LE_SET_ADV_ENABLE does not return a response.
+ if (result != HCI_RESPONSE_TIMEOUT) {
+ hci_check_error(result);
+ }
+
+ //TODO startup CircuitPython advertising again.
+}
+
+// Note that something stopped advertising, such as a connection happening.
+//Don't ask the adapter to stop.
+void bleio_adapter_advertising_was_stopped(bleio_adapter_obj_t *self) {
+ self->now_advertising = false;
+ self->extended_advertising = false;
+ self->circuitpython_advertising = false;
+}
+
+bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self) {
+ check_enabled(self);
+
+ return self->now_advertising;
+}
+
+bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) {
+ check_enabled(self);
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &bleio_connections[i];
+ if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ return true;
+ }
+ }
+ return false;
+}
+
+mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
+ check_enabled(self);
+
+ if (self->connection_objs != NULL) {
+ return self->connection_objs;
+ }
+ size_t total_connected = 0;
+ mp_obj_t items[BLEIO_TOTAL_CONNECTION_COUNT];
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &bleio_connections[i];
+ if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ if (connection->connection_obj == mp_const_none) {
+ connection->connection_obj = bleio_connection_new_from_internal(connection);
+ }
+ items[total_connected] = connection->connection_obj;
+ total_connected++;
+ }
+ }
+ self->connection_objs = mp_obj_new_tuple(total_connected, items);
+ return self->connection_objs;
+}
+
+void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) {
+ // TODO
+ mp_raise_NotImplementedError(NULL);
+ check_enabled(self);
+
+ //FIX bonding_erase_storage();
+}
+
+uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute) {
+ check_enabled(adapter);
+
+ // The handle is the index of this attribute in the attributes list.
+ uint16_t handle = (uint16_t) adapter->attributes->len;
+ mp_obj_list_append(adapter->attributes, attribute);
+
+ if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) {
+ adapter->last_added_service_handle = handle;
+ }
+ if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
+ adapter->last_added_characteristic_handle = handle;
+ }
+
+ return handle;
+}
+
+mp_obj_t* bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle) {
+ check_enabled(adapter);
+
+ if (handle == 0 || handle >= adapter->attributes->len) {
+ return mp_const_none;
+ }
+ return adapter->attributes->items[handle];
+}
+
+uint16_t bleio_adapter_max_attribute_handle(bleio_adapter_obj_t *adapter) {
+ check_enabled(adapter);
+
+ return adapter->attributes->len - 1;
+}
+
+
+void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) {
+ gc_collect_root((void**)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t));
+ gc_collect_root((void**)bleio_connections, sizeof(bleio_connections) / sizeof(size_t));
+}
+
+void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
+
+ if (!common_hal_bleio_adapter_get_enabled(adapter)) {
+ return;
+ }
+
+ // Adapter will be reset.
+ common_hal_bleio_adapter_set_enabled(adapter, false);
+
+ adapter->connection_objs = NULL;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &bleio_connections[i];
+ // Disconnect all connections with Python state cleanly. Keep any supervisor-only connections.
+ if (connection->connection_obj != mp_const_none &&
+ connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ common_hal_bleio_connection_disconnect(connection);
+ }
+ connection->connection_obj = mp_const_none;
+ }
+
+}
+
+void bleio_adapter_background(bleio_adapter_obj_t* adapter) {
+ if (!common_hal_bleio_adapter_get_enabled(adapter)) {
+ return;
+ }
+
+ if (adapter->advertising_timeout_msecs > 0 &&
+ supervisor_ticks_ms64() - adapter->advertising_start_ticks > adapter->advertising_timeout_msecs) {
+ adapter->advertising_timeout_msecs = 0;
+ common_hal_bleio_adapter_stop_advertising(adapter);
+ }
+
+ hci_result_t result = hci_poll_for_incoming_pkt();
+ if (result != HCI_OK) {
+ mp_printf(&mp_plat_print, "bad hci_poll_for_incoming_pkt() result in background: %d\n", result);
+ }
+}
diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.h b/devices/ble_hci/common-hal/_bleio/Adapter.h
new file mode 100644
index 000000000..bec1329f2
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Adapter.h
@@ -0,0 +1,99 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ADAPTER_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ADAPTER_H
+
+#include "py/obj.h"
+#include "py/objtuple.h"
+
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/ScanResults.h"
+#include "shared-bindings/busio/UART.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+
+#ifndef BLEIO_TOTAL_CONNECTION_COUNT
+#define BLEIO_TOTAL_CONNECTION_COUNT 5
+#endif
+
+extern bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
+
+typedef struct _bleio_adapter_obj_t {
+ mp_obj_base_t base;
+ bleio_scanresults_obj_t *scan_results;
+ mp_obj_t name;
+ mp_obj_tuple_t *connection_objs;
+ busio_uart_obj_t* hci_uart;
+ digitalio_digitalinout_obj_t *rts_digitalinout;
+ digitalio_digitalinout_obj_t *cts_digitalinout;
+ bool allocated; // True when in use.
+ bool now_advertising;
+ bool extended_advertising;
+ bool circuitpython_advertising;
+ bool enabled;
+
+ // HCI adapter version info.
+ uint8_t hci_version;
+ uint8_t lmp_version;
+ uint16_t hci_revision;
+ uint16_t manufacturer;
+ uint16_t lmp_subversion;
+
+ // Used to monitor advertising timeout for legacy avertising.
+ uint64_t advertising_start_ticks;
+ uint64_t advertising_timeout_msecs; // If zero, do not check.
+
+ // Generic services characteristics.
+ bleio_characteristic_obj_t *device_name_characteristic;
+ bleio_characteristic_obj_t *appearance_characteristic;
+ bleio_characteristic_obj_t * service_changed_characteristic;
+
+ uint16_t max_acl_buffer_len;
+ uint16_t max_acl_num_buffers;
+ uint16_t max_adv_data_len;
+ uint8_t features[8]; // Supported BLE features.
+
+ // All the local attributes for this device. The index into the list
+ // corresponds to the handle.
+ mp_obj_list_t *attributes;
+ // Handle for last added service. Characteristics can only be added immediately after
+ // the service they belong to. This vets that.
+ uint16_t last_added_service_handle;
+ uint16_t last_added_characteristic_handle;
+} bleio_adapter_obj_t;
+
+uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute);
+void bleio_adapter_advertising_was_stopped(bleio_adapter_obj_t *self);
+mp_obj_t* bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle);
+uint16_t bleio_adapter_max_attribute_handle(bleio_adapter_obj_t *adapter);
+void bleio_adapter_background(bleio_adapter_obj_t* adapter);
+void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter);
+void bleio_adapter_reset(bleio_adapter_obj_t* adapter);
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ADAPTER_H
diff --git a/devices/ble_hci/common-hal/_bleio/Attribute.c b/devices/ble_hci/common-hal/_bleio/Attribute.c
new file mode 100644
index 000000000..26fabed09
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Attribute.c
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+
+#include "shared-bindings/_bleio/Attribute.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Descriptor.h"
+#include "shared-bindings/_bleio/Service.h"
+
+
+bleio_uuid_obj_t *bleio_attribute_get_uuid(mp_obj_t *attribute) {
+ if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute);
+ return characteristic->uuid;
+ }
+ if (MP_OBJ_IS_TYPE(attribute, &bleio_descriptor_type)) {
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute);
+ return descriptor->uuid;
+ }
+ if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) {
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute);
+ return service->uuid;
+ }
+ mp_raise_RuntimeError(translate("Invalid BLE attribute"));
+}
diff --git a/devices/ble_hci/common-hal/_bleio/Attribute.h b/devices/ble_hci/common-hal/_bleio/Attribute.h
new file mode 100644
index 000000000..b8702cae4
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Attribute.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ATTRIBUTE_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ATTRIBUTE_H
+
+#include "shared-module/_bleio/Attribute.h"
+#include "shared-bindings/_bleio/UUID.h"
+
+bleio_uuid_obj_t *bleio_attribute_get_uuid(mp_obj_t *attribute);
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ATTRIBUTE_H
diff --git a/devices/ble_hci/common-hal/_bleio/Characteristic.c b/devices/ble_hci/common-hal/_bleio/Characteristic.c
new file mode 100644
index 000000000..393b80459
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Characteristic.c
@@ -0,0 +1,228 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/CharacteristicBuffer.h"
+#include "shared-bindings/_bleio/Descriptor.h"
+#include "shared-bindings/_bleio/PacketBuffer.h"
+#include "shared-bindings/_bleio/Service.h"
+
+#include "common-hal/_bleio/Adapter.h"
+#include "common-hal/_bleio/att.h"
+
+#define CCCD_NOTIFY 0x1
+#define CCCD_INDICATE 0x2
+
+
+void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) {
+ self->service = service;
+ self->uuid = uuid;
+ self->decl_handle = BLE_GATT_HANDLE_INVALID;
+ self->handle = BLE_GATT_HANDLE_INVALID;
+ self->props = props;
+ self->read_perm = read_perm;
+ self->write_perm = write_perm;
+ self->descriptor_list = mp_obj_new_list(0, NULL);
+ self->observer = mp_const_none;
+ self->user_desc = NULL;
+ self->cccd = NULL;
+ self->sccd = NULL;
+ self->value = mp_obj_new_bytes(initial_value_bufinfo->buf, initial_value_bufinfo->len);
+
+ const mp_int_t max_length_max = 512;
+ if (max_length < 0 || max_length > max_length_max) {
+ mp_raise_ValueError(translate("max_length must be <= 512"));
+ }
+ self->max_length = max_length;
+ self->fixed_length = fixed_length;
+
+ if (service->is_remote) {
+ self->handle = handle;
+ } else {
+ common_hal_bleio_service_add_characteristic(self->service, self, initial_value_bufinfo);
+ }
+}
+
+mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self) {
+ return mp_obj_new_tuple(self->descriptor_list->len, self->descriptor_list->items);
+}
+
+bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self) {
+ return self->service;
+}
+
+size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len) {
+ // Do GATT operations only if this characteristic has been added to a registered service.
+ if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ //FIX uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
+ if (common_hal_bleio_service_get_is_remote(self->service)) {
+ //FIX read remote chars
+ //uint8_t rsp[MAX(len, 512)];
+ //FIX improve att_read_req to write into our requested buffer.
+ // return att_read_req(conn_handle, self->handle, rsp);
+ return 0; //FIX
+ } else {
+ mp_buffer_info_t bufinfo;
+ if (!mp_get_buffer(self->value, &bufinfo, MP_BUFFER_READ)) {
+ return 0;
+ }
+ const size_t actual_length = MIN(len, bufinfo.len);
+ memcpy(buf, bufinfo.buf, actual_length);
+ return actual_length;
+ }
+ }
+
+ return 0;
+}
+
+void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
+ if (self->fixed_length && bufinfo->len != self->max_length) {
+ mp_raise_ValueError(translate("Value length != required fixed length"));
+ }
+ if (bufinfo->len > self->max_length) {
+ mp_raise_ValueError(translate("Value length > max_length"));
+ }
+
+ // Do GATT operations only if this characteristic has been added to a registered service.
+ if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ if (common_hal_bleio_service_get_is_remote(self->service)) {
+ //FIX uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
+ if (self->props & CHAR_PROP_WRITE) {
+ //FIX writing remote chars
+ //uint8_t rsp[sizeof(bt_att_error_rsp)];
+ //att_write_req(conn_handle, self->handle, bufinfo->buf, bufinfo->len, rsp);
+ } else if (self->props & CHAR_PROP_WRITE_NO_RESPONSE) {
+ //att_write_cmd(conn_handle, self->handle, bufinfo->buff, bufinfo->len);
+ } else {
+ mp_raise_bleio_BluetoothError(translate("Characteristic not writable"));
+ }
+ } else {
+ // Always write the value locally even if no connections are active.
+ bleio_characteristic_set_local_value(self, bufinfo);
+ // Notify or indicate all active connections.
+
+ uint16_t cccd_value = 0;
+ mp_buffer_info_t cccd_bufinfo = {
+ .buf = &cccd_value,
+ .len = sizeof(cccd_value),
+ };
+
+ const bool notify = self->props & CHAR_PROP_NOTIFY;
+ const bool indicate = self->props & CHAR_PROP_INDICATE;
+ // Read the CCCD value, if there is one.
+ if ((notify | indicate) && self->cccd != NULL) {
+ common_hal_bleio_descriptor_get_value(self->cccd, cccd_bufinfo.buf, cccd_bufinfo.len);
+ }
+
+ // It's possible that both notify and indicate are set.
+ if (notify && (cccd_value & CCCD_NOTIFY)) {
+ att_notify(self->handle, bufinfo->buf, MIN(bufinfo->len, self->max_length));
+ }
+ if (indicate && (cccd_value & CCCD_INDICATE)) {
+ att_indicate(self->handle, bufinfo->buf, MIN(bufinfo->len, self->max_length));
+
+ }
+ }
+ }
+}
+
+bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) {
+ return self->uuid;
+}
+
+bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self) {
+ return self->props;
+}
+
+void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor) {
+ if (self->handle != common_hal_bleio_adapter_obj.last_added_characteristic_handle) {
+ mp_raise_bleio_BluetoothError(
+ translate("Descriptor can only be added to most recently added characteristic"));
+ }
+
+ descriptor->handle = bleio_adapter_add_attribute(&common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(descriptor));
+ // Include this descriptor in the service handle's range.
+ self->service->end_handle = descriptor->handle;
+
+ mp_obj_list_append(MP_OBJ_FROM_PTR(self->descriptor_list),
+ MP_OBJ_FROM_PTR(descriptor));
+}
+
+void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) {
+ if (self->cccd == NULL) {
+ mp_raise_bleio_BluetoothError(translate("No CCCD for this Characteristic"));
+ }
+
+ if (!common_hal_bleio_service_get_is_remote(self->service)) {
+ mp_raise_bleio_RoleError(translate("Can't set CCCD on local Characteristic"));
+ }
+
+ const uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
+ common_hal_bleio_check_connected(conn_handle);
+
+ uint16_t cccd_value =
+ (notify ? CCCD_NOTIFY : 0) |
+ (indicate ? CCCD_INDICATE : 0);
+
+ //FIX do remote
+ (void) cccd_value;
+ // uint8_t rsp[sizeof(bt_att_error_rsp)];
+ // if (att_write_req(conn_handle, self->cccd->handle, &cccd_value, sizeof(cccd_value)) == 0) {
+ // mp_raise_bleio_BluetoothError(translate("Could not write CCCD"));
+ // }
+}
+
+bool bleio_characteristic_set_local_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
+ if (self->fixed_length && bufinfo->len != self->max_length) {
+ return false;
+ }
+ if (bufinfo->len > self->max_length) {
+ return false;
+ }
+
+ self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
+
+ if (MP_OBJ_IS_TYPE(self->observer, &bleio_characteristic_buffer_type)) {
+ bleio_characteristic_buffer_update(MP_OBJ_FROM_PTR(self->observer), bufinfo);
+ } else if (MP_OBJ_IS_TYPE(self->observer, &bleio_packet_buffer_type)) {
+ bleio_packet_buffer_update(MP_OBJ_FROM_PTR(self->observer), bufinfo);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+void bleio_characteristic_set_observer(bleio_characteristic_obj_t *self, mp_obj_t observer) {
+ self->observer = observer;
+}
+
+void bleio_characteristic_clear_observer(bleio_characteristic_obj_t *self) {
+ self->observer = mp_const_none;
+}
diff --git a/devices/ble_hci/common-hal/_bleio/Characteristic.h b/devices/ble_hci/common-hal/_bleio/Characteristic.h
new file mode 100644
index 000000000..6d5a12509
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Characteristic.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CHARACTERISTIC_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CHARACTERISTIC_H
+
+#include "shared-bindings/_bleio/Attribute.h"
+#include "common-hal/_bleio/Descriptor.h"
+#include "shared-module/_bleio/Characteristic.h"
+#include "common-hal/_bleio/Service.h"
+#include "common-hal/_bleio/UUID.h"
+
+typedef struct _bleio_characteristic_obj {
+ mp_obj_base_t base;
+ // Will be MP_OBJ_NULL before being assigned to a Service.
+ bleio_service_obj_t *service;
+ bleio_uuid_obj_t *uuid;
+ mp_obj_t value;
+ mp_obj_t observer;
+ mp_obj_list_t *descriptor_list;
+ uint16_t max_length;
+ bool fixed_length;
+ uint16_t decl_handle;
+ uint16_t handle; // Should be decl_handle+1.
+ bleio_characteristic_properties_t props;
+ bleio_attribute_security_mode_t read_perm;
+ bleio_attribute_security_mode_t write_perm;
+ bleio_descriptor_obj_t *descriptor_linked_list;
+ bleio_descriptor_obj_t *user_desc;
+ bleio_descriptor_obj_t *cccd;
+ bleio_descriptor_obj_t *sccd;
+} bleio_characteristic_obj_t;
+
+bool bleio_characteristic_set_local_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
+
+void bleio_characteristic_set_observer(bleio_characteristic_obj_t *self, mp_obj_t observer);
+void bleio_characteristic_clear_observer(bleio_characteristic_obj_t *self);
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CHARACTERISTIC_H
diff --git a/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c
new file mode 100644
index 000000000..e8cd51880
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c
@@ -0,0 +1,104 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "lib/utils/interrupt_char.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "supervisor/shared/tick.h"
+#include "common-hal/_bleio/CharacteristicBuffer.h"
+
+// Push all the data onto the ring buffer. When the buffer is full, new bytes will be dropped.
+STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
+ ringbuf_put_n(&self->ringbuf, data, len);
+}
+
+void bleio_characteristic_buffer_update(bleio_characteristic_buffer_obj_t *self, mp_buffer_info_t *bufinfo) {
+ write_to_ringbuf(self, bufinfo->buf, bufinfo->len);
+}
+
+// Assumes that timeout and buffer_size have been validated before call.
+void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self,
+ bleio_characteristic_obj_t *characteristic,
+ mp_float_t timeout,
+ size_t buffer_size) {
+
+ self->characteristic = characteristic;
+ self->timeout_ms = timeout * 1000;
+ // This is a macro.
+ // true means long-lived, so it won't be moved.
+ ringbuf_alloc(&self->ringbuf, buffer_size, true);
+
+ bleio_characteristic_set_observer(characteristic, self);
+}
+
+uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
+ uint64_t start_ticks = supervisor_ticks_ms64();
+
+ // Wait for all bytes received or timeout
+ while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
+ RUN_BACKGROUND_TASKS;
+ // Allow user to break out of a timeout with a KeyboardInterrupt.
+ if ( mp_hal_is_interrupted() ) {
+ return 0;
+ }
+ }
+
+ uint32_t num_bytes_read = ringbuf_get_n(&self->ringbuf, data, len);
+ return num_bytes_read;
+}
+
+uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) {
+ uint16_t count = ringbuf_num_filled(&self->ringbuf);
+ return count;
+}
+
+void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self) {
+ ringbuf_clear(&self->ringbuf);
+}
+
+bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self) {
+ return self->characteristic == NULL;
+}
+
+void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) {
+ if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
+ bleio_characteristic_clear_observer(self->characteristic);
+ }
+}
+
+bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self) {
+ return self->characteristic != NULL &&
+ self->characteristic->service != NULL &&
+ (!self->characteristic->service->is_remote ||
+ (self->characteristic->service->connection != MP_OBJ_NULL &&
+ common_hal_bleio_connection_get_connected(self->characteristic->service->connection)));
+}
diff --git a/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.h b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.h
new file mode 100644
index 000000000..107e5801f
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CHARACTERISTICBUFFER_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CHARACTERISTICBUFFER_H
+
+#include "py/ringbuf.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ bleio_characteristic_obj_t *characteristic;
+ uint32_t timeout_ms;
+ // Ring buffer storing consecutive incoming values.
+ ringbuf_t ringbuf;
+} bleio_characteristic_buffer_obj_t;
+
+void bleio_characteristic_buffer_update(bleio_characteristic_buffer_obj_t *self, mp_buffer_info_t *bufinfo);
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CHARACTERISTICBUFFER_H
diff --git a/devices/ble_hci/common-hal/_bleio/Connection.c b/devices/ble_hci/common-hal/_bleio/Connection.c
new file mode 100644
index 000000000..ba4eb477d
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Connection.c
@@ -0,0 +1,772 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/_bleio/Connection.h"
+
+#include "att.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#include "lib/utils/interrupt_char.h"
+#include "py/gc.h"
+#include "py/objlist.h"
+#include "py/objstr.h"
+#include "py/qstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Attribute.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/UUID.h"
+#include "supervisor/shared/tick.h"
+
+#define BLE_ADV_LENGTH_FIELD_SIZE 1
+#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
+#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
+
+// static const ble_gap_sec_params_t pairing_sec_params = {
+// .bond = 1,
+// .mitm = 0,
+// .lesc = 0,
+// .keypress = 0,
+// .oob = 0,
+// .io_caps = BLE_GAP_IO_CAPS_NONE,
+// .min_key_size = 7,
+// .max_key_size = 16,
+// .kdist_own = { .enc = 1, .id = 1},
+// .kdist_peer = { .enc = 1, .id = 1},
+// };
+
+#define CONNECTION_DEBUG (1)
+#if CONNECTION_DEBUG
+ #define CONNECTION_DEBUG_PRINTF(...) printf(__VA_ARGS__)
+#else
+ #define CONNECTION_DEBUG_PRINTF(...)
+#endif
+
+static volatile bool m_discovery_in_process;
+static volatile bool m_discovery_successful;
+
+//FIX static bleio_service_obj_t *m_char_discovery_service;
+//FIX static bleio_characteristic_obj_t *m_desc_discovery_characteristic;
+
+// bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
+// bleio_connection_internal_t *self = (bleio_connection_internal_t*)self_in;
+
+// if (BLE_GAP_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GAP_EVT_LAST &&
+// ble_evt->evt.gap_evt.conn_handle != self->conn_handle) {
+// return false;
+// }
+// if (BLE_GATTS_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GATTS_EVT_LAST &&
+// ble_evt->evt.gatts_evt.conn_handle != self->conn_handle) {
+// return false;
+// }
+
+// switch (ble_evt->header.evt_id) {
+// case BLE_GAP_EVT_DISCONNECTED:
+// // Adapter.c does the work for this event.
+// break;
+
+// case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
+// ble_gap_phys_t const phys = {
+// .rx_phys = BLE_GAP_PHY_AUTO,
+// .tx_phys = BLE_GAP_PHY_AUTO,
+// };
+// sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys);
+// break;
+// }
+
+// case BLE_GAP_EVT_PHY_UPDATE: { // 0x22
+// break;
+// }
+
+// case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+// // SoftDevice will respond to a length update request.
+// sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
+// break;
+
+// case BLE_GAP_EVT_DATA_LENGTH_UPDATE: { // 0x24
+// break;
+// }
+
+// case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
+// ble_gatts_evt_exchange_mtu_request_t *request =
+// &ble_evt->evt.gatts_evt.params.exchange_mtu_request;
+
+// uint16_t new_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX;
+// if (request->client_rx_mtu < new_mtu) {
+// new_mtu = request->client_rx_mtu;
+// }
+// if (new_mtu < BLE_GATT_ATT_MTU_DEFAULT) {
+// new_mtu = BLE_GATT_ATT_MTU_DEFAULT;
+// }
+// if (self->mtu > 0) {
+// new_mtu = self->mtu;
+// }
+
+// self->mtu = new_mtu;
+// sd_ble_gatts_exchange_mtu_reply(self->conn_handle, new_mtu);
+// break;
+// }
+
+
+// case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: {
+// ble_gattc_evt_exchange_mtu_rsp_t *response =
+// &ble_evt->evt.gattc_evt.params.exchange_mtu_rsp;
+
+// self->mtu = response->server_rx_mtu;
+// break;
+// }
+
+// case BLE_GATTS_EVT_WRITE:
+// // A client wrote a value.
+// // If we are bonded and it's a CCCD (UUID 0x2902), store the CCCD value.
+// if (self->conn_handle != BLE_CONN_HANDLE_INVALID &&
+// self->pair_status == PAIR_PAIRED &&
+// ble_evt->evt.gatts_evt.params.write.uuid.type == BLE_UUID_TYPE_BLE &&
+// ble_evt->evt.gatts_evt.params.write.uuid.uuid == 0x2902) {
+// //
+// // Save sys_attr data (CCCD state) in bonding area at
+// // next opportunity, but also remember time of this
+// // request, so we can consolidate closely-spaced requests.
+// self->do_bond_cccds = true;
+// self->do_bond_cccds_request_time = supervisor_ticks_ms64();
+// }
+// // Return false so other handlers get this event as well.
+// return false;
+
+// case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+// sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
+// break;
+
+// #if CIRCUITPY_VERBOSE_BLE
+// // Use read authorization to snoop on all reads when doing verbose debugging.
+// case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: {
+
+// ble_gatts_evt_rw_authorize_request_t *request =
+// &ble_evt->evt.gatts_evt.params.authorize_request;
+
+// mp_printf(&mp_plat_print, "Read %x offset %d ", request->request.read.handle, request->request.read.offset);
+// uint8_t value_bytes[22];
+// ble_gatts_value_t value;
+// value.offset = request->request.read.offset;
+// value.len = 22;
+// value.p_value = value_bytes;
+
+// sd_ble_gatts_value_get(self->conn_handle, request->request.read.handle, &value);
+// size_t len = value.len;
+// if (len > 22) {
+// len = 22;
+// }
+// for (uint8_t i = 0; i < len; i++) {
+// mp_printf(&mp_plat_print, " %02x", value_bytes[i]);
+// }
+// mp_printf(&mp_plat_print, "\n");
+// ble_gatts_rw_authorize_reply_params_t reply;
+// reply.type = request->type;
+// reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
+// reply.params.read.update = false;
+// reply.params.read.offset = request->request.read.offset;
+// sd_ble_gatts_rw_authorize_reply(self->conn_handle, &reply);
+// break;
+// }
+// #endif
+
+// case BLE_GATTS_EVT_HVN_TX_COMPLETE: // Capture this for now. 0x55
+// break;
+// case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: {
+// self->conn_params_updating = true;
+// ble_gap_evt_conn_param_update_request_t *request =
+// &ble_evt->evt.gap_evt.params.conn_param_update_request;
+// sd_ble_gap_conn_param_update(self->conn_handle, &request->conn_params);
+// break;
+// }
+// case BLE_GAP_EVT_CONN_PARAM_UPDATE: { // 0x12
+// ble_gap_evt_conn_param_update_t *result =
+// &ble_evt->evt.gap_evt.params.conn_param_update;
+
+// #if CIRCUITPY_VERBOSE_BLE
+// ble_gap_conn_params_t *cp = &ble_evt->evt.gap_evt.params.conn_param_update.conn_params;
+// 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);
+// #endif
+
+// memcpy(&self->conn_params, &result->conn_params, sizeof(ble_gap_conn_params_t));
+// self->conn_params_updating = false;
+// break;
+// }
+// case BLE_GAP_EVT_SEC_PARAMS_REQUEST: {
+// // First time pairing.
+// // 1. Either we or peer initiate the process
+// // 2. Peer asks for security parameters using BLE_GAP_EVT_SEC_PARAMS_REQUEST.
+// // 3. Pair Key exchange ("just works" implemented now; TODO: out-of-band key pairing)
+// // 4. Connection is secured: BLE_GAP_EVT_CONN_SEC_UPDATE
+// // 5. Long-term Keys exchanged: BLE_GAP_EVT_AUTH_STATUS
+
+// bonding_clear_keys(&self->bonding_keys);
+// self->ediv = EDIV_INVALID;
+// ble_gap_sec_keyset_t keyset = {
+// .keys_own = {
+// .p_enc_key = &self->bonding_keys.own_enc,
+// .p_id_key = NULL,
+// .p_sign_key = NULL,
+// .p_pk = NULL
+// },
+
+// .keys_peer = {
+// .p_enc_key = &self->bonding_keys.peer_enc,
+// .p_id_key = &self->bonding_keys.peer_id,
+// .p_sign_key = NULL,
+// .p_pk = NULL
+// }
+// };
+
+// sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS,
+// self->is_central ? NULL : &pairing_sec_params,
+// &keyset);
+// break;
+// }
+
+// case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
+// // TODO for LESC pairing:
+// // sd_ble_gap_lesc_dhkey_reply(...);
+// break;
+
+// case BLE_GAP_EVT_AUTH_STATUS: { // 0x19
+// // Key exchange completed.
+// ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status;
+// self->sec_status = status->auth_status;
+// if (status->auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
+// self->ediv = self->bonding_keys.own_enc.master_id.ediv;
+// self->pair_status = PAIR_PAIRED;
+// // Save keys in bonding area at next opportunity.
+// self->do_bond_keys = true;
+// } else {
+// // Inform busy-waiter pairing has failed.
+// self->pair_status = PAIR_NOT_PAIRED;
+// }
+// break;
+// }
+
+// case BLE_GAP_EVT_SEC_INFO_REQUEST: { // 0x14
+// // Peer asks for the stored keys.
+// // - load key and return if bonded previously.
+// // - Else return NULL --> Initiate key exchange
+// ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request;
+// (void) sec_info_request;
+// if ( bonding_load_keys(self->is_central, sec_info_request->master_id.ediv, &self->bonding_keys) ) {
+// sd_ble_gap_sec_info_reply(
+// self->conn_handle,
+// &self->bonding_keys.own_enc.enc_info,
+// &self->bonding_keys.peer_id.id_info,
+// NULL);
+// self->ediv = self->bonding_keys.own_enc.master_id.ediv;
+// } else {
+// // We don't have stored keys. Ask for keys.
+// sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL);
+// }
+// break;
+// }
+
+// case BLE_GAP_EVT_CONN_SEC_UPDATE: { // 0x1a
+// // We get this both on first-time pairing and on subsequent pairings using stored keys.
+// ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec;
+// if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) {
+// // Security setup did not succeed:
+// // mode 0, level 0 means no access
+// // mode 1, level 1 means open link
+// // mode >=1 and/or level >=1 means encryption is set up
+// self->pair_status = PAIR_NOT_PAIRED;
+// } else {
+// if (bonding_load_cccd_info(self->is_central, self->conn_handle, self->ediv)) {
+// // Did an sd_ble_gatts_sys_attr_set() with the stored sys_attr values.
+// } else {
+// // No matching bonding found, so use fresh system attributes.
+// sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
+// }
+// self->pair_status = PAIR_PAIRED;
+// }
+// break;
+// }
+
+// default:
+// return false;
+// }
+// return true;
+// }
+
+void bleio_connection_clear(bleio_connection_internal_t *self) {
+ mp_obj_list_clear(MP_OBJ_FROM_PTR(self->remote_service_list));
+
+ self->conn_handle = BLE_CONN_HANDLE_INVALID;
+ self->pair_status = PAIR_NOT_PAIRED;
+ self->is_central = false;
+ //FIX bonding_clear_keys(&self->bonding_keys);
+}
+
+bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self) {
+ if (self->connection == NULL) {
+ return false;
+ }
+ return self->connection->pair_status == PAIR_PAIRED;
+}
+
+bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self) {
+ if (self->connection == NULL) {
+ return false;
+ }
+ return self->connection->conn_handle != BLE_CONN_HANDLE_INVALID;
+}
+
+void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) {
+ hci_disconnect(self->conn_handle);
+}
+
+void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond) {
+ self->pair_status = PAIR_WAITING;
+
+ //FIX check_nrf_error(sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params));
+
+ while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) {
+ RUN_BACKGROUND_TASKS;
+ }
+ if (mp_hal_is_interrupted()) {
+ return;
+ }
+ //FIX check_sec_status(self->sec_status);
+}
+
+mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self) {
+ while (self->conn_params_updating && !mp_hal_is_interrupted()) {
+ RUN_BACKGROUND_TASKS;
+ }
+ //FIX return 1.25f * self->conn_params.min_conn_interval;
+ return 0.0f;
+}
+
+// Return the current negotiated MTU length, minus overhead.
+mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_internal_t *self) {
+ return (self->mtu == 0 ? BT_ATT_DEFAULT_LE_MTU : self->mtu) - 3;
+}
+
+void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval) {
+ // self->conn_params_updating = true;
+ // uint16_t interval = new_interval / 1.25f;
+ // self->conn_params.min_conn_interval = interval;
+ // self->conn_params.max_conn_interval = interval;
+ // uint32_t status = NRF_ERROR_BUSY;
+ // while (status == NRF_ERROR_BUSY) {
+ // status = sd_ble_gap_conn_param_update(self->conn_handle, &self->conn_params);
+ // RUN_BACKGROUND_TASKS;
+ // }
+ // check_nrf_error(status);
+}
+
+// service_uuid may be NULL, to discover all services.
+// STATIC bool discover_next_services(bleio_connection_internal_t* connection, uint16_t start_handle, ble_uuid_t *service_uuid) {
+// m_discovery_successful = false;
+// m_discovery_in_process = true;
+
+// uint32_t nrf_err = NRF_ERROR_BUSY;
+// while (nrf_err == NRF_ERROR_BUSY) {
+// nrf_err = sd_ble_gattc_primary_services_discover(connection->conn_handle, start_handle, service_uuid);
+// }
+// check_nrf_error(nrf_err);
+
+// // Wait for a discovery event.
+// while (m_discovery_in_process) {
+// MICROPY_VM_HOOK_LOOP;
+// }
+// return m_discovery_successful;
+// }
+
+// STATIC bool discover_next_characteristics(bleio_connection_internal_t* connection, bleio_service_obj_t *service, uint16_t start_handle) {
+// m_char_discovery_service = service;
+
+// ble_gattc_handle_range_t handle_range;
+// handle_range.start_handle = start_handle;
+// handle_range.end_handle = service->end_handle;
+
+// m_discovery_successful = false;
+// m_discovery_in_process = true;
+
+// uint32_t err_code = sd_ble_gattc_characteristics_discover(connection->conn_handle, &handle_range);
+// if (err_code != NRF_SUCCESS) {
+// return false;
+// }
+
+// // Wait for a discovery event.
+// while (m_discovery_in_process) {
+// MICROPY_VM_HOOK_LOOP;
+// }
+// return m_discovery_successful;
+// }
+
+// STATIC bool discover_next_descriptors(bleio_connection_internal_t* connection, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) {
+// m_desc_discovery_characteristic = characteristic;
+
+// ble_gattc_handle_range_t handle_range;
+// handle_range.start_handle = start_handle;
+// handle_range.end_handle = end_handle;
+
+// m_discovery_successful = false;
+// m_discovery_in_process = true;
+
+// uint32_t err_code = sd_ble_gattc_descriptors_discover(connection->conn_handle, &handle_range);
+// if (err_code != NRF_SUCCESS) {
+// return false;
+// }
+
+// // Wait for a discovery event.
+// while (m_discovery_in_process) {
+// MICROPY_VM_HOOK_LOOP;
+// }
+// return m_discovery_successful;
+// }
+
+// STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_connection_internal_t* connection) {
+// for (size_t i = 0; i < response->count; ++i) {
+// ble_gattc_service_t *gattc_service = &response->services[i];
+
+// bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
+// service->base.type = &bleio_service_type;
+
+// // Initialize several fields at once.
+// bleio_service_from_connection(service, bleio_connection_new_from_internal(connection));
+
+// service->is_remote = true;
+// service->start_handle = gattc_service->handle_range.start_handle;
+// service->end_handle = gattc_service->handle_range.end_handle;
+// service->handle = gattc_service->handle_range.start_handle;
+
+// if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+// // Known service UUID.
+// bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
+// uuid->base.type = &bleio_uuid_type;
+// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
+// service->uuid = uuid;
+// } else {
+// // The discovery response contained a 128-bit UUID that has not yet been registered with the
+// // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+// // For now, just set the UUID to NULL.
+// service->uuid = NULL;
+// }
+//
+// mp_obj_list_append(MP_OBJ_FROM_PTR(connection->remote_service_list),
+// MP_OBJ_FROM_PTR(service));
+// }
+//
+// if (response->count > 0) {
+// m_discovery_successful = true;
+// }
+// m_discovery_in_process = false;
+// }
+
+// STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_connection_internal_t* connection) {
+// for (size_t i = 0; i < response->count; ++i) {
+// ble_gattc_char_t *gattc_char = &response->chars[i];
+
+// bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
+// characteristic->base.type = &bleio_characteristic_type;
+
+// bleio_uuid_obj_t *uuid = NULL;
+
+// if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+// // Known characteristic UUID.
+// uuid = m_new_obj(bleio_uuid_obj_t);
+// uuid->base.type = &bleio_uuid_type;
+// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
+// } else {
+// // The discovery response contained a 128-bit UUID that has not yet been registered with the
+// // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+// // For now, just leave the UUID as NULL.
+// }
+
+// bleio_characteristic_properties_t props =
+// (gattc_char->char_props.broadcast ? CHAR_PROP_BROADCAST : 0) |
+// (gattc_char->char_props.indicate ? CHAR_PROP_INDICATE : 0) |
+// (gattc_char->char_props.notify ? CHAR_PROP_NOTIFY : 0) |
+// (gattc_char->char_props.read ? CHAR_PROP_READ : 0) |
+// (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) |
+// (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0);
+
+// // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler.
+// common_hal_bleio_characteristic_construct(
+// characteristic, m_char_discovery_service, gattc_char->handle_value, uuid,
+// props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
+// GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc
+// NULL);
+
+// mp_obj_list_append(MP_OBJ_FROM_PTR(m_char_discovery_service->characteristic_list),
+// MP_OBJ_FROM_PTR(characteristic));
+// }
+
+// if (response->count > 0) {
+// m_discovery_successful = true;
+// }
+// m_discovery_in_process = false;
+// }
+
+// STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio_connection_internal_t* connection) {
+// for (size_t i = 0; i < response->count; ++i) {
+// ble_gattc_desc_t *gattc_desc = &response->descs[i];
+
+// // Remember handles for certain well-known descriptors.
+// switch (gattc_desc->uuid.uuid) {
+// case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
+// m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle;
+// break;
+
+// case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG:
+// m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle;
+// break;
+
+// case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC:
+// m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle;
+// break;
+
+// default:
+// // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors,
+// // so ignore those.
+// // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors
+// break;
+// }
+
+// bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
+// descriptor->base.type = &bleio_descriptor_type;
+
+// bleio_uuid_obj_t *uuid = NULL;
+
+// if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+// // Known descriptor UUID.
+// uuid = m_new_obj(bleio_uuid_obj_t);
+// uuid->base.type = &bleio_uuid_type;
+// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
+// } else {
+// // The discovery response contained a 128-bit UUID that has not yet been registered with the
+// // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+// // For now, just leave the UUID as NULL.
+// }
+
+// common_hal_bleio_descriptor_construct(
+// descriptor, m_desc_discovery_characteristic, uuid,
+// SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
+// GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes);
+// descriptor->handle = gattc_desc->handle;
+
+// mp_obj_list_append(MP_OBJ_FROM_PTR(m_desc_discovery_characteristic->descriptor_list),
+// MP_OBJ_FROM_PTR(descriptor));
+// }
+
+// if (response->count > 0) {
+// m_discovery_successful = true;
+// }
+// m_discovery_in_process = false;
+// }
+
+// STATIC bool discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t payload) {
+// bleio_connection_internal_t* connection = MP_OBJ_TO_PTR(payload);
+// switch (ble_evt->header.evt_id) {
+// case BLE_GAP_EVT_DISCONNECTED:
+// m_discovery_successful = false;
+// m_discovery_in_process = false;
+// break;
+
+// case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+// on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, connection);
+// break;
+
+// case BLE_GATTC_EVT_CHAR_DISC_RSP:
+// on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, connection);
+// break;
+
+// case BLE_GATTC_EVT_DESC_DISC_RSP:
+// on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, connection);
+// break;
+
+// default:
+// // CONNECTION_DEBUG_PRINTF(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
+// return false;
+// break;
+// }
+// return true;
+// }
+
+// STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t service_uuids_whitelist) {
+// ble_drv_add_event_handler(discovery_on_ble_evt, self);
+
+// // Start over with an empty list.
+// self->remote_service_list = mp_obj_new_list(0, NULL);
+
+
+// if (service_uuids_whitelist == mp_const_none) {
+// // List of service UUID's not given, so discover all available services.
+
+// uint16_t next_service_start_handle = BLE_GATT_HANDLE_START;
+
+// while (discover_next_services(self, next_service_start_handle, MP_OBJ_NULL)) {
+// // discover_next_services() appends to remote_services_list.
+
+// // Get the most recently discovered service, and then ask for services
+// // whose handles start after the last attribute handle inside that service.
+// // There must be at least one if discover_next_services() returned true.
+// const bleio_service_obj_t *service =
+// self->remote_service_list->items[self->remote_service_list->len - 1];
+// next_service_start_handle = service->end_handle + 1;
+// }
+// } else {
+// mp_obj_iter_buf_t iter_buf;
+// mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf);
+// mp_obj_t uuid_obj;
+// while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
+// if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
+// mp_raise_TypeError(translate("non-UUID found in service_uuids_whitelist"));
+// }
+// bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
+
+// ble_uuid_t nrf_uuid;
+// bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid);
+
+// // Service might or might not be discovered; that's ok. Caller has to check
+// // Central.remote_services to find out.
+// // We only need to call this once for each service to discover.
+// discover_next_services(self, BLE_GATT_HANDLE_START, &nrf_uuid);
+// }
+// }
+
+
+// for (size_t i = 0; i < self->remote_service_list->len; i++) {
+// bleio_service_obj_t *service = MP_OBJ_TO_PTR(self->remote_service_list->items[i]);
+// // Skip the service if it had an unknown (unregistered) UUID.
+// if (service->uuid == NULL) {
+// continue;
+// }
+
+// uint16_t next_char_start_handle = service->start_handle;
+
+// // Stop when we go past the end of the range of handles for this service or
+// // discovery call returns nothing.
+// // discover_next_characteristics() appends to the characteristic_list.
+// while (next_char_start_handle <= service->end_handle &&
+// discover_next_characteristics(self, service, next_char_start_handle)) {
+
+
+// // Get the most recently discovered characteristic, and then ask for characteristics
+// // whose handles start after the last attribute handle inside that characteristic.
+// const bleio_characteristic_obj_t *characteristic =
+// MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]);
+
+// next_char_start_handle = characteristic->handle + 1;
+// }
+
+// // Got characteristics for this service. Now discover descriptors for each characteristic.
+// size_t char_list_len = service->characteristic_list->len;
+// for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) {
+// bleio_characteristic_obj_t *characteristic =
+// MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]);
+// const bool last_characteristic = char_idx == char_list_len - 1;
+// bleio_characteristic_obj_t *next_characteristic = last_characteristic
+// ? NULL
+// : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]);
+
+// // Skip the characteristic if it had an unknown (unregistered) UUID.
+// if (characteristic->uuid == NULL) {
+// continue;
+// }
+
+// uint16_t next_desc_start_handle = characteristic->handle + 1;
+
+// // Don't run past the end of this service or the beginning of the next characteristic.
+// uint16_t next_desc_end_handle = next_characteristic == NULL
+// ? service->end_handle
+// : next_characteristic->handle - 1;
+
+// // Stop when we go past the end of the range of handles for this service or
+// // discovery call returns nothing.
+// // discover_next_descriptors() appends to the descriptor_linked_list.
+// while (next_desc_start_handle <= service->end_handle &&
+// next_desc_start_handle <= next_desc_end_handle &&
+// discover_next_descriptors(self, characteristic,
+// next_desc_start_handle, next_desc_end_handle)) {
+// // Get the most recently discovered descriptor, and then ask for descriptors
+// // whose handles start after that descriptor's handle.
+// // There must be at least one if discover_next_descriptors() returned true.
+// const bleio_descriptor_obj_t *descriptor =
+// characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1];
+// next_desc_start_handle = descriptor->handle + 1;
+// }
+// }
+// }
+
+// // This event handler is no longer needed.
+// ble_drv_remove_event_handler(discovery_on_ble_evt, self);
+
+// }
+
+mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) {
+ //FIX discover_remote_services(self->connection, service_uuids_whitelist);
+ bleio_connection_ensure_connected(self);
+ // Convert to a tuple and then clear the list so the callee will take ownership.
+ mp_obj_tuple_t *services_tuple =
+ mp_obj_new_tuple(self->connection->remote_service_list->len,
+ self->connection->remote_service_list->items);
+ mp_obj_list_clear(MP_OBJ_FROM_PTR(self->connection->remote_service_list));
+ return services_tuple;
+}
+
+uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self) {
+ if (self == NULL || self->connection == NULL) {
+ return BLE_CONN_HANDLE_INVALID;
+ }
+ return self->connection->conn_handle;
+}
+
+mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* internal) {
+ if (internal->connection_obj != mp_const_none) {
+ return internal->connection_obj;
+ }
+ bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t);
+ connection->base.type = &bleio_connection_type;
+ connection->connection = internal;
+ internal->connection_obj = connection;
+
+ return MP_OBJ_FROM_PTR(connection);
+}
+
+// Find the connection that uses the given conn_handle. Return NULL if not found.
+bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle) {
+ bleio_connection_internal_t *connection;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ connection = &bleio_connections[i];
+ if (connection->conn_handle == conn_handle) {
+ return connection;
+ }
+ }
+
+ return NULL;
+}
diff --git a/devices/ble_hci/common-hal/_bleio/Connection.h b/devices/ble_hci/common-hal/_bleio/Connection.h
new file mode 100644
index 000000000..0b1f26a21
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Connection.h
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CONNECTION_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CONNECTION_H
+
+#include <stdbool.h>
+
+#include "py/obj.h"
+#include "py/objlist.h"
+
+#include "common-hal/_bleio/__init__.h"
+#include "shared-module/_bleio/Address.h"
+#include "common-hal/_bleio/Service.h"
+
+typedef enum {
+ PAIR_NOT_PAIRED,
+ PAIR_WAITING,
+ PAIR_PAIRED,
+} pair_status_t;
+
+// We split the Connection object into two so that the internal mechanics can live outside of the
+// VM. If it were one object, then we'd risk user code seeing a connection object of theirs be
+// reused.
+typedef struct {
+ uint16_t conn_handle;
+ bool is_central;
+ // Remote services discovered when this peripheral is acting as a client.
+ mp_obj_list_t *remote_service_list;
+ // The advertising data and scan response buffers are held by us, not by the SD, so we must
+ // maintain them and not change it. If we need to change the contents during advertising,
+ // there are tricks to get the SD to notice (see DevZone - TBS).
+ bonding_keys_t bonding_keys;
+ // EDIV: Encrypted Diversifier: Identifies LTK during legacy pairing.
+ uint16_t ediv;
+ volatile pair_status_t pair_status;
+ uint8_t sec_status; // Internal security status.
+ mp_obj_t connection_obj;
+ //REMOVE ble_gap_conn_params_t conn_params;
+ volatile bool conn_params_updating;
+ uint16_t mtu;
+ // Request that CCCD values for this connection be saved, using sys_attr values.
+ volatile bool do_bond_cccds;
+ // Request that security key info for this connection be saved.
+ volatile bool do_bond_keys;
+ // Time of setting do_bond_ccds: we delay a bit to consolidate multiple CCCD changes
+ // into one write. Time is currently in ticks_ms.
+ uint64_t do_bond_cccds_request_time;
+ //FIX from att.c
+ uint8_t role;
+ bt_addr_le_t addr;
+} bleio_connection_internal_t;
+
+typedef struct {
+ mp_obj_base_t base;
+ bleio_connection_internal_t* connection;
+ // The HCI disconnect reason.
+ uint8_t disconnect_reason;
+} bleio_connection_obj_t;
+
+uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self);
+mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* connection);
+bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle);
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CONNECTION_H
diff --git a/devices/ble_hci/common-hal/_bleio/Descriptor.c b/devices/ble_hci/common-hal/_bleio/Descriptor.c
new file mode 100644
index 000000000..645273e28
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Descriptor.c
@@ -0,0 +1,114 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Descriptor.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/UUID.h"
+
+void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_characteristic_obj_t *characteristic, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) {
+ self->characteristic = characteristic;
+ self->uuid = uuid;
+ self->handle = BLE_GATT_HANDLE_INVALID;
+ self->read_perm = read_perm;
+ self->write_perm = write_perm;
+ self->value = mp_obj_new_bytes(initial_value_bufinfo->buf, initial_value_bufinfo->len);
+
+ const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX;
+ if (max_length < 0 || max_length > max_length_max) {
+ mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"),
+ max_length_max, fixed_length ? "True" : "False");
+ }
+ self->max_length = max_length;
+ self->fixed_length = fixed_length;
+
+ common_hal_bleio_descriptor_set_value(self, initial_value_bufinfo);
+}
+
+bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) {
+ return self->uuid;
+}
+
+bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self) {
+ return self->characteristic;
+}
+
+size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8_t* buf, size_t len) {
+ // Do GATT operations only if this descriptor has been registered
+ if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
+ //uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection);
+ //FIX have att_read_req fill in a buffer
+ //uint8_t rsp[MAX(len, 512)];
+ //return att_read_req(conn_handle, self->handle, rsp, len);
+ return 0;
+ } else {
+ mp_buffer_info_t bufinfo;
+ if (!mp_get_buffer(self->value, &bufinfo, MP_BUFFER_READ)) {
+ return 0;
+ }
+ const size_t actual_length = MIN(len, bufinfo.len);
+ memcpy(buf, bufinfo.buf, actual_length);
+ return actual_length;
+ }
+ }
+
+ return 0;
+}
+
+void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) {
+ if (self->fixed_length && bufinfo->len != self->max_length) {
+ mp_raise_ValueError(translate("Value length != required fixed length"));
+ }
+ if (bufinfo->len > self->max_length) {
+ mp_raise_ValueError(translate("Value length > max_length"));
+ }
+
+ self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
+
+ // Do GATT operations only if this descriptor has been registered.
+ if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
+ //FIX
+ // uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
+ // att_write_req(conn_handle, self->handle, bufinfo->buf, bufinfo->len, rsp);
+ } else {
+ // Always write the value locally even if no connections are active.
+ if (self->fixed_length && bufinfo->len != self->max_length) {
+ return;
+ }
+ if (bufinfo->len > self->max_length) {
+ return;
+ }
+
+ self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
+ }
+ }
+}
diff --git a/devices/ble_hci/common-hal/_bleio/Descriptor.h b/devices/ble_hci/common-hal/_bleio/Descriptor.h
new file mode 100644
index 000000000..097a49f8e
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Descriptor.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_DESCRIPTOR_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_DESCRIPTOR_H
+
+#include "py/obj.h"
+
+#include "common-hal/_bleio/UUID.h"
+
+// Forward declare characteristic because it includes a Descriptor.
+struct _bleio_characteristic_obj;
+
+typedef struct _bleio_descriptor_obj {
+ mp_obj_base_t base;
+ // Will be MP_OBJ_NULL before being assigned to a Characteristic.
+ struct _bleio_characteristic_obj *characteristic;
+ bleio_uuid_obj_t *uuid;
+ mp_obj_t value;
+ uint16_t max_length;
+ bool fixed_length;
+ uint16_t handle;
+ bleio_attribute_security_mode_t read_perm;
+ bleio_attribute_security_mode_t write_perm;
+ struct _bleio_descriptor_obj* next;
+} bleio_descriptor_obj_t;
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_DESCRIPTOR_H
diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c
new file mode 100644
index 000000000..98912ba90
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c
@@ -0,0 +1,265 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019-2020 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "lib/utils/interrupt_char.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/PacketBuffer.h"
+#include "supervisor/shared/tick.h"
+
+STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
+ if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
+ // This shouldn't happen.
+ return;
+ }
+ // Push all the data onto the ring buffer.
+ // Make room for the new value by dropping the oldest packets first.
+ while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
+ uint16_t packet_length;
+ ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
+ for (uint16_t i = 0; i < packet_length; i++) {
+ ringbuf_get(&self->ringbuf);
+ }
+ // set an overflow flag?
+ }
+ ringbuf_put_n(&self->ringbuf, (uint8_t*) &len, sizeof(uint16_t));
+ ringbuf_put_n(&self->ringbuf, data, len);
+}
+
+STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) {
+ // Queue up the next outgoing buffer. We use two, one that has been passed to the SD for
+ // transmission (when packet_queued is true) and the other is `pending` and can still be
+ // modified. By primarily appending to the `pending` buffer we can reduce the protocol overhead
+ // of the lower level link and ATT layers.
+ self->packet_queued = false;
+ if (self->pending_size > 0) {
+ mp_buffer_info_t bufinfo = {
+ .buf = self->outgoing[self->pending_index],
+ .len = self->pending_size,
+ };
+ common_hal_bleio_characteristic_set_value(self->characteristic, &bufinfo);
+
+ self->pending_size = 0;
+ self->pending_index = (self->pending_index + 1) % 2;
+ self->packet_queued = true;
+ }
+ return 0;
+}
+
+void bleio_packet_buffer_update(bleio_packet_buffer_obj_t *self, mp_buffer_info_t *bufinfo) {
+ write_to_ringbuf(self, bufinfo->buf, bufinfo->len);
+}
+
+void common_hal_bleio_packet_buffer_construct(
+ bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
+ size_t buffer_size) {
+
+ self->characteristic = characteristic;
+ self->client = self->characteristic->service->is_remote;
+ bleio_characteristic_properties_t incoming =
+ self->characteristic->props & (CHAR_PROP_WRITE_NO_RESPONSE | CHAR_PROP_WRITE);
+ bleio_characteristic_properties_t outgoing =
+ self->characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE);
+
+ if (self->client) {
+ // Swap if we're the client.
+ bleio_characteristic_properties_t temp = incoming;
+ incoming = outgoing;
+ outgoing = temp;
+ self->conn_handle = bleio_connection_get_conn_handle(MP_OBJ_TO_PTR(self->characteristic->service->connection));
+ } else {
+ self->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+
+ if (incoming) {
+ if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) {
+ mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
+ }
+ }
+
+ if (outgoing) {
+ self->packet_queued = false;
+ self->pending_index = 0;
+ self->pending_size = 0;
+ self->outgoing[0] = m_malloc(characteristic->max_length, false);
+ self->outgoing[1] = m_malloc(characteristic->max_length, false);
+ } else {
+ self->outgoing[0] = NULL;
+ self->outgoing[1] = NULL;
+ }
+
+ bleio_characteristic_set_observer(self->characteristic, self);
+}
+
+mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
+ if (ringbuf_num_filled(&self->ringbuf) < 2) {
+ return 0;
+ }
+
+ // Copy received data.
+ // Get packet length, which is in first two bytes of packet.
+ uint16_t packet_length;
+ ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
+
+ mp_int_t ret;
+ if (packet_length > len) {
+ // Packet is longer than requested. Return negative of overrun value.
+ ret = len - packet_length;
+ // Discard the packet if it's too large. Don't fill data.
+ while (packet_length--) {
+ (void) ringbuf_get(&self->ringbuf);
+ }
+ } else {
+ // Read as much as possible, but might be shorter than len.
+ ringbuf_get_n(&self->ringbuf, data, packet_length);
+ ret = packet_length;
+ }
+
+ return ret;
+}
+
+mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) {
+ if (self->outgoing[0] == NULL) {
+ mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic"));
+ }
+ if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ return -1;
+ }
+ uint16_t outgoing_packet_length = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
+
+ if (len + header_len > outgoing_packet_length) {
+ // Supplied data will not fit in a single BLE packet.
+ mp_raise_ValueError(translate("Total data to write is larger than outgoing_packet_length"));
+ }
+
+ if (len + self->pending_size > outgoing_packet_length) {
+ // No room to append len bytes to packet. Wait until we get a free buffer,
+ // and keep checking that we haven't been disconnected.
+ while (self->pending_size != 0 && self->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ RUN_BACKGROUND_TASKS;
+ }
+ }
+ if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ return -1;
+ }
+
+ size_t num_bytes_written = 0;
+
+ uint8_t* pending = self->outgoing[self->pending_index];
+
+ if (self->pending_size == 0) {
+ memcpy(pending, header, header_len);
+ self->pending_size += header_len;
+ num_bytes_written += header_len;
+ }
+ memcpy(pending + self->pending_size, data, len);
+ self->pending_size += len;
+ num_bytes_written += len;
+
+ // If no writes are queued then sneak in this data.
+ if (!self->packet_queued) {
+ queue_next_write(self);
+ }
+ return num_bytes_written;
+}
+
+mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self) {
+ // If this PacketBuffer is coming from a remote service via NOTIFY or INDICATE
+ // the maximum size is what can be sent in one
+ // BLE packet. But we must be connected to know that value.
+ //
+ // Otherwise it can be as long as the characteristic
+ // will permit, whether or not we're connected.
+
+ if (self->characteristic == NULL) {
+ return -1;
+ }
+
+ if (self->characteristic->service != NULL &&
+ self->characteristic->service->is_remote &&
+ (common_hal_bleio_characteristic_get_properties(self->characteristic) &
+ (CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) {
+ // We are talking to a remote service, and data is arriving via NOTIFY or INDICATE.
+ if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
+ if (connection) {
+ return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
+ self->characteristic->max_length);
+ }
+ }
+ // There's no current connection, so we don't know the MTU, and
+ // we can't tell what the largest incoming packet length would be.
+ return -1;
+ }
+ return self->characteristic->max_length;
+}
+
+mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_buffer_obj_t *self) {
+ // If we are sending data via NOTIFY or INDICATE, the maximum size
+ // is what can be sent in one BLE packet. But we must be connected
+ // to know that value.
+ //
+ // Otherwise it can be as long as the characteristic
+ // will permit, whether or not we're connected.
+
+ if (self->characteristic == NULL) {
+ return -1;
+ }
+
+ if (self->characteristic->service != NULL &&
+ !self->characteristic->service->is_remote &&
+ (common_hal_bleio_characteristic_get_properties(self->characteristic) &
+ (CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) {
+ // We are sending to a client, via NOTIFY or INDICATE.
+ if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
+ if (connection) {
+ return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
+ self->characteristic->max_length);
+ }
+ }
+ // There's no current connection, so we don't know the MTU, and
+ // we can't tell what the largest outgoing packet length would be.
+ return -1;
+ }
+ return self->characteristic->max_length;
+}
+
+bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
+ return self->characteristic == NULL;
+}
+
+void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
+ if (!common_hal_bleio_packet_buffer_deinited(self)) {
+ bleio_characteristic_clear_observer(self->characteristic);
+ }
+}
diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.h b/devices/ble_hci/common-hal/_bleio/PacketBuffer.h
new file mode 100644
index 000000000..074c03dc6
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019-2020 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_PACKETBUFFER_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_PACKETBUFFER_H
+
+#include "py/ringbuf.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ bleio_characteristic_obj_t *characteristic;
+ // Ring buffer storing consecutive incoming values.
+ ringbuf_t ringbuf;
+ // Two outgoing buffers to alternate between. One will be queued for transmission by the SD and
+ // the other is waiting to be queued and can be extended.
+ uint8_t* outgoing[2];
+ volatile uint16_t pending_size;
+ // We remember the conn_handle so we can do a NOTIFY/INDICATE to a client.
+ // We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read).
+ volatile uint16_t conn_handle;
+ uint8_t pending_index;
+ uint8_t write_type;
+ bool client;
+ bool packet_queued;
+} bleio_packet_buffer_obj_t;
+
+void bleio_packet_buffer_update(bleio_packet_buffer_obj_t *self, mp_buffer_info_t *bufinfo);
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_PACKETBUFFER_H
diff --git a/devices/ble_hci/common-hal/_bleio/Service.c b/devices/ble_hci/common-hal/_bleio/Service.c
new file mode 100644
index 000000000..5803f5309
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Service.c
@@ -0,0 +1,129 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Descriptor.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/Adapter.h"
+
+uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary, mp_obj_list_t * characteristic_list) {
+ self->uuid = uuid;
+ self->characteristic_list = characteristic_list;
+ self->is_remote = false;
+ self->connection = NULL;
+ self->is_secondary = is_secondary;
+
+ vm_used_ble = true;
+
+ self->handle = bleio_adapter_add_attribute(&common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(self));
+ self->start_handle = self->handle;
+ self->end_handle = self->handle;
+ if (self->handle == BLE_GATT_HANDLE_INVALID) {
+ return 1;
+ }
+ return 0;
+}
+
+void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary) {
+ if (_common_hal_bleio_service_construct(self, uuid, is_secondary,
+ mp_obj_new_list(0, NULL)) != 0) {
+ mp_raise_RuntimeError(translate("Failed to add service"));
+ }
+}
+
+void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection) {
+ self->handle = 0xFFFF;
+ self->uuid = NULL;
+ self->characteristic_list = mp_obj_new_list(0, NULL);
+ self->is_remote = true;
+ self->is_secondary = false;
+ self->connection = connection;
+}
+
+bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) {
+ return self->uuid;
+}
+
+mp_obj_tuple_t *common_hal_bleio_service_get_characteristics(bleio_service_obj_t *self) {
+ return mp_obj_new_tuple(self->characteristic_list->len, self->characteristic_list->items);
+}
+
+bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) {
+ return self->is_remote;
+}
+
+bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) {
+ return self->is_secondary;
+}
+
+void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
+ bleio_characteristic_obj_t *characteristic,
+ mp_buffer_info_t *initial_value_bufinfo) {
+
+ if (self->handle != common_hal_bleio_adapter_obj.last_added_service_handle) {
+ mp_raise_bleio_BluetoothError(
+ translate("Characteristic can only be added to most recently added service"));
+ }
+ characteristic->decl_handle = bleio_adapter_add_attribute(
+ &common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(characteristic));
+ // This is the value handle.
+ characteristic->handle = bleio_adapter_add_attribute(
+ &common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(characteristic));
+
+ self->end_handle = characteristic->handle;
+
+ if (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) {
+ // We need a CCCD if this characteristic is doing notify or indicate.
+ bleio_descriptor_obj_t *cccd = m_new_obj(bleio_descriptor_obj_t);
+ cccd->base.type = &bleio_descriptor_type;
+
+ uint16_t zero = 0;
+ mp_buffer_info_t zero_cccd_value = {
+ .buf = &zero,
+ .len = sizeof(zero),
+ };
+
+ common_hal_bleio_descriptor_construct(
+ cccd,
+ characteristic,
+ &cccd_uuid, // 0x2902
+ SECURITY_MODE_OPEN, // CCCD read perm
+ characteristic->read_perm, // Make CCCD write perm match characteristic read perm.
+ 2, // 2 bytes
+ true, // fixed length
+ &zero_cccd_value // Initial value is 0.
+ );
+
+ // Adds CCCD to attribute table, and also extends self->end_handle to include the CCCD.
+ common_hal_bleio_characteristic_add_descriptor(characteristic, cccd);
+ characteristic->cccd = cccd;
+ }
+
+ mp_obj_list_append(self->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
+}
diff --git a/devices/ble_hci/common-hal/_bleio/Service.h b/devices/ble_hci/common-hal/_bleio/Service.h
new file mode 100644
index 000000000..11e7d1c96
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/Service.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_SERVICE_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_SERVICE_H
+
+#include "py/objlist.h"
+#include "common-hal/_bleio/UUID.h"
+
+typedef struct bleio_service_obj {
+ mp_obj_base_t base;
+ // Handle for the local service.
+ uint16_t handle;
+ // True if created during discovery.
+ bool is_remote;
+ bool is_secondary;
+ bleio_uuid_obj_t *uuid;
+ // The connection object is set only when this is a remote service.
+ // A local service doesn't know the connection.
+ mp_obj_t connection;
+ mp_obj_list_t *characteristic_list;
+ // Range of attribute handles of this service.
+ uint16_t start_handle;
+ uint16_t end_handle;
+ struct bleio_service_obj* next;
+} bleio_service_obj_t;
+
+void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection);
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_SERVICE_H
diff --git a/devices/ble_hci/common-hal/_bleio/UUID.c b/devices/ble_hci/common-hal/_bleio/UUID.c
new file mode 100644
index 000000000..a50efc3b1
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/UUID.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "py/runtime.h"
+#include "common-hal/_bleio/UUID.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+
+// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
+// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
+// the 16-bit part goes. Those 16 bits are passed in uuid16.
+void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]) {
+ self->size = uuid128 == NULL ? 16 : 128;
+ self->uuid16 = uuid16;
+ if (uuid128) {
+ memcpy(self->uuid128, uuid128, 16);
+ self->uuid128[12] = uuid16 & 0xff;
+ self->uuid128[13] = uuid16 >> 8;
+ } else {
+ memset(self->uuid128, 0, 16);
+ }
+}
+
+uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) {
+ return self->size;
+}
+
+uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) {
+ return self->uuid16;
+}
+
+void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) {
+ memcpy(uuid128, self->uuid128, 16);
+}
+
+void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf) {
+ if (self->size == 16) {
+ buf[0] = self->uuid16 & 0xff;
+ buf[1] = self->uuid16 >> 8;
+ } else {
+ common_hal_bleio_uuid_get_uuid128(self, buf);
+ }
+}
+
+// Return a uui16 only if this is a standard uuid. Otherwise return BLE_UUID_UNKNOWN.
+uint16_t bleio_uuid_get_uuid16_or_unknown(bleio_uuid_obj_t *uuid) {
+ return uuid->size == 16 ? uuid->uuid16 : BLE_UUID_UNKNOWN;
+}
diff --git a/devices/ble_hci/common-hal/_bleio/UUID.h b/devices/ble_hci/common-hal/_bleio/UUID.h
new file mode 100644
index 000000000..1a0ab91c4
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/UUID.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_UUID_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_UUID_H
+
+#include "py/obj.h"
+
+// Types returned by attribute table lookups. These are UUIDs.
+typedef enum {
+ BLE_UUID_UNKNOWN = 0x0000,
+ BLE_UUID_SERVICE_PRIMARY = 0x2800,
+ BLE_UUID_SERVICE_SECONDARY = 0x2801,
+ BLE_UUID_SERVICE_INCLUDE = 0x2802, // not yet implemented by us
+ BLE_UUID_CHARACTERISTIC = 0x2803,
+ BLE_UUID_CHAR_EXTENDED_PROPS = 0x2900, // not yet implemented by us
+ BLE_UUID_CHAR_USER_DESC = 0x2901, // not yet implemented by us
+ BLE_UUID_CCCD = 0x2902,
+ BLE_UUID_SCCD = 0x2903, // not yet implemented by us
+ BLE_UUID_CHAR_PRESENTATION_FMT = 0x2904, // not yet implemented by us
+ BLE_UUID_CHAR_AGGREGATE_FMT = 0x2905, // not yet implemented by us
+} ble_standard_uuid;
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t size;
+ uint16_t uuid16;
+ uint8_t uuid128[16];
+} bleio_uuid_obj_t;
+
+uint16_t bleio_uuid_get_uuid16_or_unknown(bleio_uuid_obj_t *uuid);
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_UUID_H
diff --git a/devices/ble_hci/common-hal/_bleio/__init__.c b/devices/ble_hci/common-hal/_bleio/__init__.c
new file mode 100644
index 000000000..9fc4b480d
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/__init__.c
@@ -0,0 +1,112 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/Descriptor.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/UUID.h"
+#include "supervisor/shared/bluetooth.h"
+
+// UUID shared by all cccd's.
+bleio_uuid_obj_t cccd_uuid;
+
+bool vm_used_ble;
+
+// void check_sec_status(uint8_t sec_status) {
+// if (sec_status == BLE_GAP_SEC_STATUS_SUCCESS) {
+// return;
+// }
+
+// switch (sec_status) {
+// case BLE_GAP_SEC_STATUS_UNSPECIFIED:
+// mp_raise_bleio_SecurityError(translate("Unspecified issue. Can be that the pairing prompt on the other device was declined or ignored."));
+// return;
+// default:
+// mp_raise_bleio_SecurityError(translate("Unknown security error: 0x%04x"), sec_status);
+// }
+// }
+
+// Turn off BLE on a reset or reload.
+void bleio_reset() {
+ // Create a UUID object for all CCCD's.
+ cccd_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&cccd_uuid, BLE_UUID_CCCD, NULL);
+
+ bleio_hci_reset();
+
+ if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
+ return;
+ }
+ bleio_adapter_reset(&common_hal_bleio_adapter_obj);
+ if (!vm_used_ble) {
+ // No user-code BLE operations were done, so we can maintain the supervisor state.
+ return;
+ }
+ common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
+ common_hal_bleio_adapter_obj.allocated = false;
+
+ bleio_set_adapter(mp_const_none);
+
+ //FIX bonding_reset();
+ supervisor_start_bluetooth();
+}
+
+// The singleton _bleio.Adapter object, bound to _bleio.adapter
+bleio_adapter_obj_t common_hal_bleio_adapter_obj = {
+ .base = {
+ .type = &bleio_adapter_type,
+ },
+};
+
+bleio_adapter_obj_t *common_hal_bleio_allocate_adapter_or_raise(void) {
+ if (common_hal_bleio_adapter_obj.allocated) {
+ mp_raise_RuntimeError(translate("Too many Adapters"));
+ }
+ return &common_hal_bleio_adapter_obj;
+}
+
+void common_hal_bleio_check_connected(uint16_t conn_handle) {
+ if (conn_handle == BLE_CONN_HANDLE_INVALID) {
+ mp_raise_bleio_ConnectionError(translate("Not connected"));
+ }
+}
+
+void common_hal_bleio_gc_collect(void) {
+ bleio_adapter_gc_collect(&common_hal_bleio_adapter_obj);
+}
+
+
+void bleio_background(void) {
+ bleio_adapter_background(&common_hal_bleio_adapter_obj);
+}
diff --git a/devices/ble_hci/common-hal/_bleio/__init__.h b/devices/ble_hci/common-hal/_bleio/__init__.h
new file mode 100644
index 000000000..cd9940bf0
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/__init__.h
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H
+#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H
+
+#include <stdbool.h>
+
+#include "shared-bindings/_bleio/UUID.h"
+
+#include "att.h"
+#include "hci.h"
+
+void bleio_background(void);
+void bleio_reset(void);
+
+typedef struct {
+ // ble_gap_enc_key_t own_enc;
+ // ble_gap_enc_key_t peer_enc;
+ // ble_gap_id_key_t peer_id;
+} bonding_keys_t;
+
+// We assume variable length data.
+// 20 bytes max (23 - 3).
+#define GATT_MAX_DATA_LENGTH (BT_ATT_DEFAULT_LE_MTU - 3)
+
+//FIX
+#define BLE_GATT_HANDLE_INVALID 0x0000
+#define BLE_CONN_HANDLE_INVALID 0xFFFF
+#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */
+#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */
+
+// Track if the user code modified the BLE state to know if we need to undo it on reload.
+extern bool vm_used_ble;
+
+// UUID shared by all CCCD's.
+extern bleio_uuid_obj_t cccd_uuid;
+
+#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H
diff --git a/devices/ble_hci/common-hal/_bleio/att.c b/devices/ble_hci/common-hal/_bleio/att.c
new file mode 100644
index 000000000..591e508a6
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/att.c
@@ -0,0 +1,1787 @@
+// Derived from ArduinoBLE.
+// Copyright 2020 Dan Halbert for Adafruit Industries
+
+/*
+ This file is part of the ArduinoBLE library.
+ Copyright (c) 2018 Arduino SA. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "hci.h"
+#include "att.h"
+
+// Zephyr include files to define HCI communication values and structs.
+//#include "hci_include/hci.h"
+//#include "hci_include/hci_err.h"
+#include "hci_include/l2cap_internal.h"
+
+#include "py/obj.h"
+#include "common-hal/_bleio/Adapter.h"
+#include "common-hal/_bleio/Attribute.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Descriptor.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/UUID.h"
+#include "supervisor/shared/tick.h"
+
+STATIC uint16_t max_mtu = BT_ATT_DEFAULT_LE_MTU; // 23
+STATIC unsigned long timeout = 5000;
+
+STATIC volatile bool confirm;
+
+STATIC uint16_t long_write_handle = BLE_GATT_HANDLE_INVALID;
+STATIC uint8_t* long_write_value = NULL;
+STATIC uint16_t long_write_value_length = 0;
+
+// When we send a request, fill this struct with info about the expected response.
+// We check this against the actual received response.
+STATIC struct {
+ uint16_t conn_handle; // Expected handle.
+ uint8_t opcode; // Expected RSP opcode.
+ uint8_t* buffer; // Pointer to response packet
+ uint8_t length; // Length of response packet.
+} expected_rsp;
+
+// A characteristic declaration has this data, in this order:
+// See Bluetooth v5.1 spec, section 3.3.1 Characteristic declaration.
+typedef struct __packed {
+ uint8_t properties;
+ uint16_t value_handle;
+ uint8_t uuid[0]; // 2 or 16 bytes
+} characteristic_declaration_t;
+
+STATIC uint8_t bleio_properties_to_ble_spec_properties(uint8_t bleio_properties) {
+ uint8_t ble_spec_properties = 0;
+ if (bleio_properties & CHAR_PROP_BROADCAST) {
+ ble_spec_properties |= BT_GATT_CHRC_BROADCAST;
+ }
+ if (bleio_properties & CHAR_PROP_INDICATE) {
+ ble_spec_properties |= BT_GATT_CHRC_INDICATE;
+ }
+ if (bleio_properties & CHAR_PROP_NOTIFY) {
+ ble_spec_properties |= BT_GATT_CHRC_NOTIFY;
+ }
+ if (bleio_properties & CHAR_PROP_READ) {
+ ble_spec_properties |= BT_GATT_CHRC_READ;
+ }
+ if (bleio_properties & CHAR_PROP_WRITE) {
+ ble_spec_properties |= BT_GATT_CHRC_WRITE;
+ }
+ if (bleio_properties & CHAR_PROP_WRITE_NO_RESPONSE) {
+ ble_spec_properties |= BT_GATT_CHRC_WRITE_WITHOUT_RESP;
+ }
+
+ return ble_spec_properties;
+}
+
+//FIX not currently used; reenable when used.
+#if 0
+STATIC uint8_t ble_spec_properties_to_bleio_properties(uint8_t ble_spec_properties) {
+ uint8_t bleio_properties = 0;
+ if (ble_spec_properties & BT_GATT_CHRC_BROADCAST) {
+ bleio_properties |= CHAR_PROP_BROADCAST;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_INDICATE) {
+ bleio_properties |= CHAR_PROP_INDICATE;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_NOTIFY) {
+ bleio_properties |= CHAR_PROP_NOTIFY;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_READ) {
+ bleio_properties |= CHAR_PROP_READ;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_WRITE) {
+ bleio_properties |= CHAR_PROP_WRITE;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_WRITE_WITHOUT_RESP) {
+ bleio_properties |= CHAR_PROP_WRITE_NO_RESPONSE;
+ }
+
+ return bleio_properties;
+}
+#endif // #if 0
+
+STATIC void send_error(uint16_t conn_handle, uint8_t opcode, uint16_t handle, uint8_t code) {
+ struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_error_rsp r;
+ } rsp = { {
+ .code = BT_ATT_OP_ERROR_RSP,
+ }, {
+ .request = opcode,
+ }
+ };
+
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *) &rsp);
+}
+
+STATIC void send_req(uint16_t conn_handle, size_t request_length, uint8_t* request_buffer) {
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, request_length, request_buffer);
+}
+
+STATIC int send_req_wait_for_rsp(uint16_t conn_handle, size_t request_length, uint8_t* request_buffer, uint8_t response_buffer[]) {
+ // We expect a particular kind of response after this request.
+ expected_rsp.conn_handle = conn_handle;
+ // The response opcode is the request opcode + 1.
+ expected_rsp.opcode = request_buffer[0] + 1;
+ expected_rsp.buffer = response_buffer;
+ expected_rsp.length = 0;
+
+ send_req(conn_handle, request_length, request_buffer);
+
+ if (response_buffer == NULL) {
+ // not expecting a response.
+ return 0;
+ }
+
+ for (uint64_t start = supervisor_ticks_ms64(); supervisor_ticks_ms64() - start < timeout;) {
+ // RUN_BACKGROUND_TASKS includes hci_poll_for_incoming_pkt();
+ RUN_BACKGROUND_TASKS;
+
+ if (!att_handle_is_connected(conn_handle)) {
+ break;
+ }
+
+ if (expected_rsp.length != 0) {
+ expected_rsp.conn_handle = 0xffff;
+ return expected_rsp.length;
+ }
+ }
+
+ expected_rsp.conn_handle = 0xffff;
+ return 0;
+}
+
+// If a response matches what is in expected_rsp, copy the rest of it into the buffer.
+STATIC void check_and_save_expected_rsp(uint16_t conn_handle, uint8_t opcode, uint8_t dlen, uint8_t data[]) {
+ if (conn_handle == expected_rsp.conn_handle && expected_rsp.opcode == opcode) {
+ expected_rsp.buffer[0] = opcode;
+ memcpy(&expected_rsp.buffer[1], data, dlen);
+ expected_rsp.length = dlen + 1;
+ }
+}
+
+void bleio_att_reset(void) {
+ max_mtu = BT_ATT_DEFAULT_LE_MTU;
+ timeout = 5000;
+ long_write_handle = BLE_GATT_HANDLE_INVALID;
+ long_write_value = NULL;
+ long_write_value_length = 0;
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connections[i].conn_handle = BLE_CONN_HANDLE_INVALID;
+ bleio_connections[i].role = 0x00;
+ bleio_connections[i].addr.type = 0;
+ memset(bleio_connections[i].addr.a.val, 0, sizeof_field(bt_addr_t, val));
+ bleio_connections[i].mtu = BT_ATT_DEFAULT_LE_MTU;
+ }
+}
+
+bool att_connect_to_address(bt_addr_le_t *addr) {
+ //FIX
+ if (hci_le_create_conn(0x0060, 0x0030, 0x00, addr, 0x00,
+ 0x0006, 0x000c, 0x0000, 0x00c8, 0x0004, 0x0006) != 0) {
+ return false;
+ }
+
+ bool is_connected = false;
+
+ for (uint64_t start = supervisor_ticks_ms64(); supervisor_ticks_ms64() - start < timeout;) {
+ // RUN_BACKGROUND_TASKS includes hci_poll_for_incoming_pkt();
+ RUN_BACKGROUND_TASKS;
+
+ is_connected = att_address_is_connected(addr);
+
+ if (is_connected) {
+ break;
+ }
+ }
+
+ if (!is_connected) {
+ hci_le_cancel_conn();
+ }
+
+ return is_connected;
+}
+
+bool att_disconnect(uint16_t conn_handle) {
+ if (conn_handle == BLE_CONN_HANDLE_INVALID) {
+ return false;
+ }
+
+ hci_disconnect(conn_handle);
+
+ // Confirm we're now disconnected.
+ return !att_handle_is_connected(conn_handle);
+}
+
+//FIX
+// STATIC bool discover_services(uint16_t conn_handle, BLERemoteDevice* device, const char* serviceUuidFilter) {
+// uint16_t reqStart_handle = 0x0001;
+// uint16_t reqEnd_handle = 0xffff;
+
+// uint8_t response_buffer[max_mtu];
+
+// BLEUuid serviceUuid(serviceUuidFilter);
+
+// while (reqEnd_handle == 0xffff) {
+// int respLength = readByGroupReq(conn_handle, reqStart_handle, reqEnd_handle, BLE_UUID_SERVICE_PRIMARY, response_buffer);
+
+// if (respLength == 0) {
+// return false;
+// }
+
+// if (response_buffer[0] == BT_ATT_OP_READ_GROUP_RSP) {
+// uint16_t lengthPerService = response_buffer[1];
+// uint8_t uuidLen = lengthPerService - 4;
+
+// for (size_t i = 2; i < respLength; i += lengthPerService) {
+// struct __attribute__ ((packed)) RawService {
+// uint16_t start_handle;
+// uint16_t end_handle;
+// uint8_t uuid[16];
+// } *rawService = (RawService*)&response_buffer[i];
+
+// if (serviceUuidFilter == NULL ||
+// (uuidLen == serviceUuid.length() && memcmp(rawService->uuid, serviceUuid.data(), uuidLen) == 0)) {
+
+// BLERemoteService* service = new BLERemoteService(rawService->uuid, uuidLen,
+// rawService->start_handle,
+// rawService->end_handle);
+
+// if (service == NULL) {
+// return false;
+// }
+
+// device->addService(service);
+
+// }
+
+// reqStart_handle = rawService->end_handle + 1;
+
+// if (reqStart_handle == BLE_GATT_HANDLE_INVALID) {
+// reqEnd_handle = BLE_GATT_HANDLE_INVALID;
+// }
+// }
+// } else {
+// reqEnd_handle = BLE_GATT_HANDLE_INVALID;
+// }
+// }
+
+// return true;
+// }
+
+// STATIC bool discover_characteristics(uint16_t conn_handle, BLERemoteDevice* device) {
+// uint16_t reqStart_handle = 0x0001;
+// uint16_t reqEnd_handle = 0xffff;
+
+// uint8_t response_buffer[max_mtu];
+
+// int serviceCount = device->serviceCount();
+
+// for (size_t i = 0; i < serviceCount; i++) {
+// BLERemoteService* service = device->service(i);
+
+// reqStart_handle = service->start_handle();
+// reqEnd_handle = service->end_handle();
+
+// while (1) {
+// int respLength = readByTypeReq(conn_handle, reqStart_handle, reqEnd_handle, BLE_UUID_CHARACTERISTIC, response_buffer);
+
+// if (respLength == 0) {
+// return false;
+// }
+
+// if (response_buffer[0] == BT_ATT_OP_READ_TYPE_RSP) {
+// uint16_t lengthPerCharacteristic = response_buffer[1];
+// uint8_t uuidLen = lengthPerCharacteristic - 5;
+
+// for (size_t i = 2; i < respLength; i += lengthPerCharacteristic) {
+// struct __attribute__ ((packed)) RawCharacteristic {
+// uint16_t start_handle;
+// uint8_t properties;
+// uint16_t value_handle;
+// uint8_t uuid[16];
+// } *rawCharacteristic = (RawCharacteristic*)&response_buffer[i];
+
+// BLERemoteCharacteristic* characteristic = new BLERemoteCharacteristic(rawCharacteristic->uuid, uuidLen,
+// conn_handle,
+// rawCharacteristic->start_handle,
+// rawCharacteristic->properties,
+// rawCharacteristic->value_handle);
+
+// if (characteristic == NULL) {
+// return false;
+// }
+
+// service->addCharacteristic(characteristic);
+
+// reqStart_handle = rawCharacteristic->value_handle + 1;
+// }
+// } else {
+// break;
+// }
+// }
+// }
+
+// return true;
+// }
+
+// STATIC bool discover_descriptors(uint16_t conn_handle, BLERemoteDevice* device) {
+// uint16_t reqStart_handle = 0x0001;
+// uint16_t reqEnd_handle = 0xffff;
+
+// uint8_t response_buffer[max_mtu];
+
+// int serviceCount = device->serviceCount();
+
+// for (size_t i = 0; i < serviceCount; i++) {
+// BLERemoteService* service = device->service(i);
+
+// uint16_t serviceEnd_handle = service->end_handle();
+
+// int characteristicCount = service->characteristicCount();
+
+// for (int j = 0; j < characteristicCount; j++) {
+// BLERemoteCharacteristic* characteristic = service->characteristic(j);
+// BLERemoteCharacteristic* nextCharacteristic = (j == (characteristicCount - 1)) ? NULL : service->characteristic(j);
+
+// reqStart_handle = characteristic->value_handle() + 1;
+// reqEnd_handle = nextCharacteristic ? nextCharacteristic->value_handle() : serviceEnd_handle;
+
+// if (reqStart_handle > reqEnd_handle) {
+// continue;
+// }
+
+// while (1) {
+// int respLength = findInfoReq(conn_handle, reqStart_handle, reqEnd_handle, response_buffer);
+
+// if (respLength == 0) {
+// return false;
+// }
+
+// if (response_buffer[0] == BT_ATT_OP_FIND_INFO_RSP) {
+// uint16_t lengthPerDescriptor = response_buffer[1] * 4;
+// uint8_t uuidLen = 2;
+
+// for (size_t i = 2; i < respLength; i += lengthPerDescriptor) {
+// struct __attribute__ ((packed)) RawDescriptor {
+// uint16_t handle;
+// uint8_t uuid[16];
+// } *rawDescriptor = (RawDescriptor*)&response_buffer[i];
+
+// BLERemoteDescriptor* descriptor = new BLERemoteDescriptor(rawDescriptor->uuid, uuidLen,
+// conn_handle,
+// rawDescriptor->handle);
+
+// if (descriptor == NULL) {
+// return false;
+// }
+
+// characteristic->addDescriptor(descriptor);
+
+// reqStart_handle = rawDescriptor->handle + 1;
+// }
+// } else {
+// break;
+// }
+// }
+// }
+// }
+
+// return true;
+// }
+
+bool att_discover_attributes(bt_addr_le_t *addr, const char* service_uuid_filter) {
+ uint16_t conn_handle = att_conn_handle(addr);
+ if (conn_handle == 0xffff) {
+ return false;
+ }
+
+ // send MTU request
+ if (!att_exchange_mtu(conn_handle)) {
+ return false;
+ }
+
+ // find the device entry for the peeer
+ //FIX BLERemoteDevice* device = NULL;
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ // if (bleio_connections[i].conn_handle == conn_handle) {
+ // //FIX if (bleio_connections[i].device == NULL) {
+ // //FIX
+ // //bleio_connections[i].device = new BLERemoteDevice();
+ // //}
+
+ // //device = bleio_connections[i].device;
+
+ // break;
+ // }
+ // }
+
+ // //FIX if (device == NULL) {
+ // // return false;
+ // // }
+
+ // if (service_uuid_filter == NULL) {
+ // // clear existing services
+ // //FIX device->clear_services();
+ // } else {
+ // //FIX int service_count = device->service_count();
+
+ // for (size_t i = 0; i < service_count; i++) {
+ // //FIX BLERemoteService* service = device->service(i);
+
+ // if (strcasecmp(service->uuid(), service_uuid_filter) == 0) {
+ // // found an existing service with same UUID
+ // return true;
+ // }
+ // }
+ }
+
+ // discover services
+ //FIX
+ // if (!att_discover_services(conn_handle, device, service_uuid_filter)) {
+ // return false;
+ // }
+
+ // // discover characteristics
+ // if (!discover_characteristics(conn_handle, device)) {
+ // return false;
+ // }
+
+ // // discover descriptors396
+ // if (!discover_descriptors(conn_handle, device)) {
+ // return false;
+ // }
+
+ return true;
+}
+
+void att_set_max_mtu(uint16_t max_mtu_in) {
+ max_mtu = max_mtu_in;
+}
+
+void att_set_timeout(unsigned long timeout_in) {
+ timeout = timeout_in;
+}
+
+void att_add_connection(uint16_t handle, uint8_t role, bt_addr_le_t *peer_addr, uint16_t interval, uint16_t latency, uint16_t supervision_timeout, uint8_t master_clock_accuracy) {
+ (void) interval;
+ (void) latency;
+ (void) supervision_timeout;
+ (void) master_clock_accuracy;
+
+ int peer_index = -1;
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == 0xffff) {
+ peer_index = i;
+ break;
+ }
+ }
+
+ if (peer_index == -1) {
+ // bail, no space
+ return;
+ }
+
+ bleio_connections[peer_index].conn_handle = handle;
+ bleio_connections[peer_index].role = role;
+ bleio_connections[peer_index].mtu = BT_ATT_DEFAULT_LE_MTU;
+ memcpy(&bleio_connections[peer_index].addr, peer_addr, sizeof(bleio_connections[peer_index].addr));
+}
+
+
+void att_remove_connection(uint16_t conn_handle, uint8_t reason) {
+ (void) reason;
+ int peer_index = -1;
+ int peer_count = 0;
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == conn_handle) {
+ peer_index = i;
+ }
+
+ if (bleio_connections[i].conn_handle != 0xffff) {
+ peer_count++;
+ }
+ }
+
+ if (peer_index == -1) {
+ // Peer not found
+ return;
+ }
+
+ if (peer_count == 1) {
+
+ // Clear CCCD values on disconnect.
+ size_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
+ for (size_t handle = 1; handle <= max_attribute_handle; handle++) {
+ mp_obj_t attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
+
+ uint16_t zero = 0;
+ mp_buffer_info_t zero_cccd_value = {
+ .buf = &zero,
+ .len = sizeof(zero),
+ };
+
+ if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
+ if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == BLE_UUID_CCCD) {
+ common_hal_bleio_descriptor_set_value(descriptor, &zero_cccd_value);
+ }
+ }
+ }
+
+ long_write_handle = BLE_GATT_HANDLE_INVALID;
+ long_write_value_length = 0;
+ }
+
+ bleio_connections[peer_index].conn_handle = 0xffff;
+ bleio_connections[peer_index].role = 0x00;
+ memset(&bleio_connections[peer_index].addr, 0x00, sizeof(bleio_connections[peer_index].addr));
+ bleio_connections[peer_index].mtu = BT_ATT_DEFAULT_LE_MTU;
+}
+
+uint16_t att_conn_handle(bt_addr_le_t *addr) {
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].addr.type == addr->type &&
+ memcmp(&bleio_connections[i].addr.a.val, addr->a.val, sizeof(addr->a.val)) == 0) {
+ return bleio_connections[i].conn_handle;
+ }
+ }
+
+ return 0xffff;
+}
+
+bool att_is_connected(void) {
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle != 0xffff) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool att_address_is_connected(bt_addr_le_t *addr) {
+ return (att_conn_handle(addr) != 0xffff);
+}
+
+bool att_handle_is_connected(uint16_t handle) {
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == handle) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+uint16_t att_mtu(uint16_t handle) {
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == handle) {
+ return bleio_connections[i].mtu;
+ }
+ }
+
+ return BT_ATT_DEFAULT_LE_MTU;
+}
+
+bool att_disconnect_all(void) {
+ int num_disconnects = 0;
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == 0xffff) {
+ continue;
+ }
+
+ if (att_disconnect(bleio_connections[i].conn_handle) != 0) {
+ continue;
+ }
+
+ num_disconnects++;
+
+ bleio_connections[i].conn_handle = 0xffff;
+ bleio_connections[i].role = 0x00;
+ bleio_connections[i].addr.type = 0;
+ memset(bleio_connections[i].addr.a.val, 0, sizeof(bleio_connections[i].addr.a.val));
+ bleio_connections[i].mtu = BT_ATT_DEFAULT_LE_MTU;
+ }
+
+ return (num_disconnects > 0);
+}
+
+bool att_notify(uint16_t handle, const uint8_t* value, int length) {
+ int num_notifications = 0;
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == 0xffff) {
+ continue;
+ }
+
+ typedef struct __packed {
+ struct bt_att_hdr hdr;
+ struct bt_att_notify ntf;
+ } notify_t;
+
+ size_t allowed_length = MIN((uint16_t)(bleio_connections[i].mtu - sizeof(notify_t)), (uint16_t)length);
+
+ uint8_t notify_bytes[sizeof(notify_t) + allowed_length];
+ notify_t *notify = (notify_t *) notify_bytes;
+ notify->hdr.code = BT_ATT_OP_NOTIFY;;
+ notify->ntf.handle = handle;
+ memcpy(notify->ntf.value, value, allowed_length);
+ hci_send_acl_pkt(bleio_connections[i].conn_handle, BT_L2CAP_CID_ATT,
+ sizeof(notify_bytes), notify_bytes);
+
+ num_notifications++;
+ }
+
+ return (num_notifications > 0);
+}
+
+bool att_indicate(uint16_t handle, const uint8_t* value, int length) {
+ int num_indications = 0;
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == 0xffff) {
+ continue;
+ }
+
+ typedef struct __packed {
+ struct bt_att_hdr hdr;
+ struct bt_att_indicate ind;
+ } indicate_t;
+
+ size_t allowed_length = MIN((uint16_t)(bleio_connections[i].mtu - sizeof(indicate_t)), (uint16_t)length);
+
+ uint8_t indicate_bytes[sizeof(indicate_t) + allowed_length];
+ indicate_t *indicate = (indicate_t *) indicate_bytes;
+ indicate->hdr.code = BT_ATT_OP_INDICATE;;
+ indicate->ind.handle = handle;
+ memcpy(indicate->ind.value, value, allowed_length);
+
+ confirm = false;
+
+ hci_send_acl_pkt(bleio_connections[i].conn_handle, BT_L2CAP_CID_ATT,
+ sizeof(indicate_bytes), indicate_bytes);
+
+ while (!confirm) {
+ // RUN_BACKGROUND_TASKS includes hci_poll_for_incoming_pkt();
+ RUN_BACKGROUND_TASKS;
+
+ if (!att_address_is_connected(&bleio_connections[i].addr)) {
+ break;
+ }
+ }
+
+ num_indications++;
+ }
+
+ return (num_indications > 0);
+}
+
+STATIC void process_error(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_error_rsp *rsp = (struct bt_att_error_rsp *) data;
+
+ if (dlen != sizeof(struct bt_att_error_rsp)) {
+ // Incorrect size; ignore.
+ return;
+ }
+
+ // expected_rsp.opcode is an RSP opcode. Does it match the REQ opcode in this response?
+ if (expected_rsp.conn_handle == conn_handle && (expected_rsp.opcode - 1) == rsp->request) {
+ expected_rsp.buffer[0] = BT_ATT_OP_ERROR_RSP;
+ memcpy(&expected_rsp.buffer[1], data, dlen);
+ expected_rsp.length = dlen + 1;
+ }
+}
+
+STATIC void process_mtu_req(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_exchange_mtu_req *req = (struct bt_att_exchange_mtu_req *) data;
+
+ if (dlen != sizeof(struct bt_att_exchange_mtu_req)) {
+ send_error(conn_handle, BT_ATT_OP_MTU_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ uint16_t mtu = req->mtu;
+
+ if (mtu > max_mtu) {
+ mtu = max_mtu;
+ }
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == conn_handle) {
+ bleio_connections[i].mtu = mtu;
+ break;
+ }
+ }
+
+ struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_exchange_mtu_rsp r;
+ } rsp = { {
+ .code = BT_ATT_OP_MTU_RSP,
+ }, {
+ .mtu = mtu,
+ }
+ };
+
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *) &rsp);
+}
+
+STATIC void process_mtu_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_exchange_mtu_rsp *rsp = (struct bt_att_exchange_mtu_rsp *) data;
+
+ if (dlen != sizeof(struct bt_att_exchange_mtu_rsp)) {
+ return;
+ }
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == conn_handle) {
+ bleio_connections[i].mtu = rsp->mtu;
+ break;
+ }
+ }
+
+ check_and_save_expected_rsp(conn_handle, BT_ATT_OP_MTU_RSP, dlen, data);
+}
+
+STATIC void process_find_info_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_find_info_req *req = (struct bt_att_find_info_req *) data;
+
+ if (dlen != sizeof(struct bt_att_find_info_req)) {
+ send_error(conn_handle, BT_ATT_OP_FIND_INFO_REQ, req->start_handle, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ typedef struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_find_info_rsp r;
+ } rsp_t;
+
+ uint8_t rsp_bytes[mtu];
+ rsp_t *rsp = (rsp_t *) rsp_bytes;
+ rsp->h.code = BT_ATT_OP_FIND_INFO_RSP;
+
+ // Keeps track of total length of the response.
+ size_t rsp_length = sizeof(rsp_t);
+
+ bool no_data = true;
+
+ // All the data chunks must have uuid's that are the same size.
+ // Keep track of the first one to make sure.
+ size_t sizeof_first_uuid = 0;
+
+ const uint16_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
+ for (uint16_t handle = req->start_handle;
+ handle <= max_attribute_handle && handle <= req->end_handle;
+ handle++) {
+
+ mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
+
+ // Fetch the uuid for the given attribute, which might be a characteristic or a descriptor.
+ bleio_uuid_obj_t *uuid;
+
+ if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
+ if (characteristic->handle != handle) {
+ // If the handles don't match, this is the characteristic definition attribute.
+ // Skip it. We want the characteristic value attribute.
+ continue;
+ }
+ uuid = characteristic->uuid;
+
+ } else {
+ uuid = bleio_attribute_get_uuid(attribute_obj);
+ }
+
+ const uint32_t sizeof_uuid = common_hal_bleio_uuid_get_size(uuid) / 8;
+ if (sizeof_first_uuid == 0) {
+ sizeof_first_uuid = sizeof_uuid;
+ // All the uuids in the response will be the same size.
+ rsp->r.format = sizeof_uuid == 2 ? BT_ATT_INFO_16 : BT_ATT_INFO_128;
+ }
+
+ if (sizeof_uuid != sizeof_first_uuid) {
+ // Previous UUID was a different size. We can't mix sizes.
+ // Stop and send what we have so far.
+ break;
+ }
+
+ if (rsp_length + sizeof_uuid > mtu) {
+ // No remaining room in response for this uuid.
+ break;
+ }
+
+ if (sizeof_uuid == 2) {
+ struct bt_att_info_16 *info_16 = (struct bt_att_info_16 *) &rsp_bytes[rsp_length];
+ info_16->handle = handle;
+ info_16->uuid = common_hal_bleio_uuid_get_uuid16(uuid);
+
+ rsp_length += sizeof(struct bt_att_info_16);
+ } else {
+ struct bt_att_info_128 *info_128 = (struct bt_att_info_128 *) &rsp_bytes[rsp_length];
+ info_128->handle = handle;
+ common_hal_bleio_uuid_get_uuid128(uuid, info_128->uuid);
+
+ rsp_length += sizeof(struct bt_att_info_128);
+ }
+
+ no_data =false;
+ } // end for
+
+
+ if (no_data) {
+ send_error(conn_handle, BT_ATT_OP_FIND_INFO_REQ, req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ } else {
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
+ }
+}
+
+int att_find_info_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, uint8_t response_buffer[]) {
+ struct __packed req {
+ struct bt_att_hdr h;
+ struct bt_att_find_info_req r;
+ } req = { {
+ .code = BT_ATT_OP_FIND_INFO_REQ,
+ }, {
+ .start_handle = start_handle,
+ .end_handle = end_handle,
+ }
+ };
+
+ return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
+}
+
+STATIC void process_find_info_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ if (dlen < 2) {
+ return; // invalid, drop
+ }
+
+ check_and_save_expected_rsp(conn_handle, BT_ATT_OP_FIND_INFO_RSP, dlen, data);
+}
+
+STATIC void process_find_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_find_type_req *req = (struct bt_att_find_type_req *) data;
+
+ if (dlen < sizeof(struct bt_att_find_type_req)) {
+ send_error(conn_handle, BT_ATT_OP_FIND_TYPE_RSP, req->start_handle, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ uint8_t response[mtu];
+ uint16_t response_length;
+
+ response[0] = BT_ATT_OP_FIND_TYPE_RSP;
+ response_length = 1;
+
+ //FIX
+ // if (find_type_req->type == BLE_UUID_SERVICE_PRIMARY) {
+ // for (uint16_t i = (find_type_req->start_handle - 1); i < GATT.attributeCount() && i <= (find_type_req->end_handle - 1); i++) {
+ // BLELocalAttribute* attribute = GATT.attribute(i);
+
+ // if ((attribute->type() == find_type_req->type) && (attribute->uuidLength() == value_length) && memcmp(attribute->uuidData(), value, value_length) == 0) {
+ // BLELocalService* service = (BLELocalService*)attribute;
+
+ // // add the start handle
+ // uint16_t start_handle = service->start_handle();
+ // memcpy(&response[response_length], &start_handle, sizeof(start_handle));
+ // response_length += sizeof(start_handle);
+
+ // // add the end handle
+ // uint16_t end_handle = service->end_handle();
+ // memcpy(&response[response_length], &end_handle, sizeof(end_handle));
+ // response_length += sizeof(end_handle);
+ // }
+
+ // if ((response_length + 4) > mtu) {
+ // break;
+ // }
+ // }
+ // }
+
+ if (response_length == 1) {
+ send_error(conn_handle, BT_ATT_OP_FIND_TYPE_RSP, req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ } else {
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
+ }
+}
+
+void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_read_group_req *req = (struct bt_att_read_group_req *) data;
+ uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8);
+
+ // We only support returning services for BT_ATT_OP_READ_GROUP_REQ, which is typically used
+ // for service discovery.
+ if (dlen != sizeof(struct bt_att_read_group_req) + sizeof(type_uuid) ||
+ (type_uuid != BLE_UUID_SERVICE_PRIMARY &&
+ type_uuid != BLE_UUID_SERVICE_SECONDARY)) {
+ send_error(conn_handle, BT_ATT_OP_READ_GROUP_REQ, req->start_handle, BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE);
+ return;
+ }
+
+ typedef struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_read_group_rsp r;
+ } rsp_t;
+
+ uint8_t rsp_bytes[mtu];
+ rsp_t *rsp = (rsp_t *) rsp_bytes;
+ rsp->h.code = BT_ATT_OP_READ_GROUP_RSP;
+ rsp->r.len = 0;
+
+ // Keeps track of total length of the response.
+ size_t rsp_length = sizeof(rsp_t);
+
+ bool no_data = true;
+
+ // All the data chunks must have uuid's that are the same size.
+ // Keep track of the first one to make sure.
+ size_t sizeof_first_service_uuid = 0;
+
+ // Size of a single bt_att_group_data chunk. Start with the intial size, and
+ // add the uuid size in the loop below.
+ size_t data_length = sizeof(struct bt_att_group_data);
+
+ const uint16_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
+ for (uint16_t handle = req->start_handle;
+ handle <= max_attribute_handle && handle <= req->end_handle;
+ handle++) {
+
+ if (rsp_length + data_length > mtu) {
+ // The next possible bt_att_group_data chunk won't fit. The response is full.
+ break;
+ }
+
+ mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
+ if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_service_type)) {
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute_obj);
+
+ // Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute
+ // in this transmission.
+ const uint32_t sizeof_service_uuid = common_hal_bleio_uuid_get_size(service->uuid) / 8;
+ if (sizeof_first_service_uuid == 0) {
+ sizeof_first_service_uuid = sizeof_service_uuid;
+ data_length += sizeof_service_uuid;
+ } else if (sizeof_first_service_uuid != sizeof_service_uuid) {
+ // Mismatched sizes, which can't be in the same batch.
+ // Transmit just what we have so far in this batch.
+ break;
+ }
+
+ // Pass the length of ONE bt_att_group_data chunk.
+ // There may be multiple chunks in this transmission.
+ rsp->r.len = data_length;
+
+ struct bt_att_group_data *group_data = (struct bt_att_group_data *) &rsp_bytes[rsp_length];
+
+ group_data->start_handle = service->start_handle;
+ group_data->end_handle = service->end_handle;
+ common_hal_bleio_uuid_pack_into(service->uuid, group_data->value);
+
+ rsp_length += data_length;
+ no_data = false;
+ }
+ }
+
+ if (no_data) {
+ send_error(conn_handle, BT_ATT_OP_READ_GROUP_REQ, req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ } else {
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
+ }
+}
+
+int att_read_group_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid, uint8_t response_buffer[]) {
+ struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_read_group_req r;
+ } req = { {
+ .code = BT_ATT_OP_READ_GROUP_REQ,
+ }, {
+ .start_handle = start_handle,
+ .end_handle = end_handle,
+ }
+ };
+ req.r.uuid[0] = uuid & 0xff;
+ req.r.uuid[1] = uuid >> 8;
+
+
+ return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
+}
+
+STATIC void process_read_group_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ if (dlen < 2) {
+ return; // invalid, drop
+ }
+
+ check_and_save_expected_rsp(conn_handle, BT_ATT_OP_READ_GROUP_RSP, dlen, data);
+}
+
+STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, uint8_t opcode, uint8_t dlen, uint8_t data[]) {
+ uint16_t handle;
+ uint16_t offset = 0;
+ uint8_t response_opcode;
+
+ if (opcode == BT_ATT_OP_READ_REQ) {
+ if (dlen != sizeof(struct bt_att_read_req)) {
+ send_error(conn_handle, BT_ATT_OP_READ_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ struct bt_att_read_req *req = (struct bt_att_read_req *) data;
+ handle = req->handle;
+ response_opcode = BT_ATT_OP_READ_RSP;
+
+ } else if (opcode == BT_ATT_OP_READ_BLOB_REQ) {
+ if (dlen != sizeof(struct bt_att_read_blob_req)) {
+ send_error(conn_handle, BT_ATT_OP_READ_BLOB_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ struct bt_att_read_blob_req *req = (struct bt_att_read_blob_req *) data;
+ handle = req->handle;
+ offset = req->offset;
+ response_opcode = BT_ATT_OP_READ_BLOB_RSP;
+ } else {
+ return;
+ }
+
+
+ if (handle > bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj)) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ return;
+ }
+
+ typedef struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_read_rsp r; // Same as bt_att_read_blob_rsp.
+ } rsp_t;
+
+ uint8_t rsp_bytes[mtu];
+ rsp_t *rsp = (rsp_t *) rsp_bytes;
+ rsp->h.code = response_opcode;
+
+ // Keeps track of total length of the response.
+ size_t rsp_length = sizeof(rsp_t);
+
+ mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
+ if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_service_type)) {
+ if (offset) {
+ send_error(conn_handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG, handle, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute_obj);
+ const uint32_t sizeof_service_uuid = common_hal_bleio_uuid_get_size(service->uuid) / 8;
+
+ common_hal_bleio_uuid_pack_into(service->uuid, rsp->r.value);
+ rsp_length += sizeof_service_uuid;
+
+ } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
+ if (characteristic->decl_handle == handle) {
+ // Read characteristic declaration. Return properties, value handle, and uuid.
+ if (offset) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG);
+ return;
+ }
+
+ characteristic_declaration_t *char_decl = (characteristic_declaration_t *) rsp->r.value;
+
+ // Convert from the bleio properties bit values to the BLE spec properties bit values.
+ // They are not the same :(.
+ char_decl->properties = bleio_properties_to_ble_spec_properties(characteristic->props);
+ char_decl->value_handle = characteristic->handle;
+
+ const uint32_t sizeof_char_uuid = common_hal_bleio_uuid_get_size(characteristic->uuid) / 8;
+ common_hal_bleio_uuid_pack_into(characteristic->uuid, char_decl->uuid);
+ rsp_length += sizeof_char_uuid;
+
+ } else {
+ // Read characteristic value.
+
+ if ((characteristic->props & CHAR_PROP_READ) == 0) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_READ_NOT_PERMITTED);
+ return;
+ }
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer(characteristic->value, &bufinfo, MP_BUFFER_READ);
+
+ if (offset >= bufinfo.len) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
+ return;
+ }
+
+ size_t value_length = MIN(mtu - rsp_length, bufinfo.len - offset);
+ memcpy(rsp->r.value, bufinfo.buf + offset, value_length);
+ rsp_length += value_length;
+ }
+ } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer(descriptor->value, &bufinfo, MP_BUFFER_READ);
+
+ if (offset >= bufinfo.len) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
+ return;
+ }
+
+ size_t value_length = MIN(mtu - rsp_length, bufinfo.len - offset);
+ memcpy(rsp->r.value, bufinfo.buf + offset, value_length);
+ rsp_length += value_length;
+ }
+
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
+}
+
+STATIC void process_read_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ check_and_save_expected_rsp(conn_handle, BT_ATT_OP_READ_RSP, dlen, data);
+}
+
+STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_read_type_req *req = (struct bt_att_read_type_req *) data;
+ uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8);
+
+ if (dlen != sizeof(struct bt_att_read_type_req) + sizeof(type_uuid)) {
+ send_error(conn_handle, BT_ATT_OP_READ_TYPE_REQ, req->start_handle, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ typedef struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_read_type_rsp r;
+ } rsp_t;
+
+ uint8_t rsp_bytes[mtu];
+ rsp_t *rsp = (rsp_t *) rsp_bytes;
+ rsp->h.code = BT_ATT_OP_READ_TYPE_RSP;
+ rsp->r.len = 0;
+
+ // Keeps track of total length of the response.
+ size_t rsp_length = sizeof(rsp_t);
+
+ bool no_data = true;
+
+ // All the data chunks must have uuid's that are the same size.
+ // Keep track of the first one to make sure.
+ size_t sizeof_first_uuid = 0;
+
+ // Size of a single bt_att_data chunk. Start with the initial size, and
+ // add the uuid size and other data sizes in the loop below.
+ size_t data_length = sizeof(struct bt_att_data);
+
+ const uint16_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
+ for (uint16_t handle = req->start_handle;
+ handle <= max_attribute_handle && handle <= req->end_handle;
+ handle++) {
+
+ if (rsp_length + data_length > mtu) {
+ // The next possible bt_att_data chunk won't fit. The response is full.
+ break;
+ }
+
+ mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
+
+ if (type_uuid == BLE_UUID_CHARACTERISTIC &&
+ MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
+ // Request is for characteristic declarations.
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
+
+ if (characteristic->handle == handle) {
+ // If the characteristic's handle is this attribute's handle, skip it:
+ // it's the attribute for characteristic value. We want to return the declaration
+ // handle attribute instead. (It will probably get skipped below, by the
+ // handle++).
+ continue;
+ }
+
+ // Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute
+ // in this transmission.
+ const uint32_t sizeof_uuid = common_hal_bleio_uuid_get_size(characteristic->uuid) / 8;
+ if (sizeof_first_uuid == 0) {
+ sizeof_first_uuid = sizeof_uuid;
+ data_length += sizeof_uuid;
+ data_length += sizeof(characteristic_declaration_t);
+ } else if (sizeof_first_uuid != sizeof_uuid) {
+ // Mismatched sizes, which can't be in the same batch.
+ // Transmit just what we have so far in this batch.
+ break;
+ }
+
+ // Pass the length of ONE bt_att_data chunk.
+ // There may be multiple chunks in this transmission.
+ rsp->r.len = data_length;
+
+ struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length];
+
+ att_data->handle = characteristic->decl_handle;
+
+ characteristic_declaration_t *char_decl = (characteristic_declaration_t *) att_data->value;
+
+ // Convert from the bleio properties bit values to the BLE spec properties bit values.
+ // They are not the same :(.
+ char_decl->properties = bleio_properties_to_ble_spec_properties(characteristic->props);
+ char_decl->value_handle = characteristic->handle;
+ common_hal_bleio_uuid_pack_into(characteristic->uuid, char_decl->uuid);
+
+ // We know the next handle will be the characteristic value handle, so skip it.
+ handle++;
+
+ rsp_length += data_length;
+ no_data = false;
+
+ } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
+ // See if request is for a descriptor value with a 16-bit UUID, such as the CCCD.
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
+ if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == type_uuid) {
+ struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length];
+
+ att_data->handle = handle;
+
+ mp_buffer_info_t bufinfo;
+ if (!mp_get_buffer(descriptor->value, &bufinfo, MP_BUFFER_READ)) {
+ break;
+ }
+ uint16_t value_size = MIN(mtu - rsp_length, bufinfo.len);
+ memcpy(att_data->value, bufinfo.buf, value_size);
+ rsp_length += value_size;
+
+ // Only return one descriptor value.
+ no_data = false;
+ break;
+ }
+
+ } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
+ // See if request is for a characteristic value with a 16-bit UUID.
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
+ if (bleio_uuid_get_uuid16_or_unknown(characteristic->uuid) == type_uuid) {
+
+ struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length];
+
+ att_data->handle = handle;
+
+ mp_buffer_info_t bufinfo;
+ if (!mp_get_buffer(characteristic->value, &bufinfo, MP_BUFFER_READ)) {
+ // This shouldn't happen. There should be a buf in characteristic->value.
+ break;
+ }
+ uint16_t value_size = MIN(mtu - rsp_length, bufinfo.len);
+ memcpy(att_data->value, bufinfo.buf, value_size);
+ rsp_length += value_size;
+
+ // Only return one characteristic value.
+ no_data = false;
+ break;
+ }
+ }
+ } // end for loop
+
+ if (no_data) {
+ send_error(conn_handle, BT_ATT_OP_READ_TYPE_REQ,
+ req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ } else {
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
+ }
+}
+
+int att_read_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, uint16_t type, uint8_t response_buffer[]) {
+ struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_read_type_req r;
+ } req = { {
+ .code = BT_ATT_OP_READ_TYPE_REQ,
+ }, {
+ .start_handle = start_handle,
+ .end_handle = end_handle,
+ }
+ };
+ req.r.uuid[0] = type & 0xff;
+ req.r.uuid[1] = type >> 8;
+
+ return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
+}
+
+STATIC void process_read_type_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ if (dlen < 1) {
+ return; // invalid, drop
+ }
+
+ check_and_save_expected_rsp(conn_handle, BT_ATT_OP_READ_TYPE_RSP, dlen, data);
+}
+
+// Handles BT_ATT_OP_WRITE_REQ or BT_ATT_OP_WRITE_
+STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t op, uint8_t dlen, uint8_t data[]) {
+ // struct bt_att_write_cmd is identical, so don't bother to split code paths based on opcode.
+ struct bt_att_write_req *req = (struct bt_att_write_req *) data;
+
+ bool with_response = (op == BT_ATT_OP_WRITE_REQ);
+
+ if (dlen < sizeof(struct bt_att_write_req)) {
+ if (with_response) {
+ send_error(conn_handle, BT_ATT_OP_WRITE_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
+ }
+ return;
+ }
+
+ if (req->handle > bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj)) {
+ if (with_response) {
+ send_error(conn_handle, BT_ATT_OP_WRITE_REQ, req->handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ }
+ return;
+ }
+
+ size_t value_length = dlen - sizeof(struct bt_att_write_req);
+
+ mp_buffer_info_t bufinfo;
+ bufinfo.buf = req->value;
+ bufinfo.len = value_length;
+
+ mp_obj_t attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, req->handle);
+
+ if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
+
+ // Don't write the characteristic declaration.
+ // Also, this must be a writable characteristic.
+ if (req->handle != characteristic->handle ||
+ (with_response
+ ? (characteristic->props & CHAR_PROP_WRITE) == 0
+ : (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) == 0)) {
+ if (with_response) {
+ send_error(conn_handle, BT_ATT_OP_WRITE_REQ, req->handle, BT_ATT_ERR_WRITE_NOT_PERMITTED);
+ }
+ return;
+ }
+
+ // Just change the local value. Don't fire off notifications, etc.
+ bleio_characteristic_set_local_value(characteristic, &bufinfo);
+
+ } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
+ // Only CCCD's are writable.
+ if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) != BLE_UUID_CCCD) {
+ if (with_response) {
+ send_error(conn_handle, BT_ATT_OP_WRITE_REQ, req->handle, BT_ATT_ERR_WRITE_NOT_PERMITTED);
+ }
+ return;
+ }
+
+ common_hal_bleio_descriptor_set_value(descriptor, &bufinfo);
+ }
+
+ if (with_response) {
+ // There's no data in the response. We just indicate the write happened.
+ struct bt_att_hdr rsp = {
+ .code = BT_ATT_OP_WRITE_RSP,
+ };
+
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *) &rsp);
+ }
+}
+
+STATIC void process_write_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ if (dlen != 0) {
+ return; // drop
+ }
+
+ check_and_save_expected_rsp(conn_handle, BT_ATT_OP_WRITE_RSP, dlen, data);
+}
+
+STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_prepare_write_req *req = (struct bt_att_prepare_write_req *) data;
+
+ if (dlen < sizeof(struct bt_att_prepare_write_req)) {
+ send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ uint16_t handle = req->handle;
+ uint16_t offset = req->offset;
+ (void) offset;
+
+ if (handle > bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj)) {
+ send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ return;
+ }
+
+ mp_obj_t *attribute = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
+
+ if (!MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
+ send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG);
+ return;
+ }
+
+ bleio_characteristic_obj_t* characteristic = MP_OBJ_TO_PTR(attribute);
+
+ if (handle != characteristic->handle) {
+ send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG);
+ return;
+ }
+
+ if ((characteristic->props & CHAR_PROP_WRITE) == 0) {
+ send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_WRITE_NOT_PERMITTED);
+ return;
+ }
+
+ //FIX if (long_write_handle == BLE_GATT_HANDLE_INVALID)
+ // int valueSize = characteristic->valueSize();
+
+ // long_write_value = (uint8_t*)realloc(long_write_value, valueSize);
+ // long_write_value_length = 0;
+ // long_write_handle = handle;
+
+ // memset(long_write_value, 0x00, valueSize);
+ // } else if (long_write_handle != handle) {
+ // send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_UNLIKELY);
+ // return;
+ // }
+
+ // uint8_t value_length = dlen - sizeof(struct bt_att_prepare_write_req);
+ // uint8_t* value = &data[sizeof(struct bt_att_prepare_write_req)];
+
+ // if ((offset != long_write_value_length) || ((offset + value_length) > (uint16_t)characteristic->valueSize())) {
+ // send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_INVALID_OFFSET);
+ // return;
+ // }
+
+ // memcpy(long_write_value + offset, value, value_length);
+ // long_write_value_length += value_length;
+
+ // uint8_t response[mtu];
+ // uint16_t response_length;
+
+ // response[0] = BT_ATT_OP_PREP_WRITE_RSP;
+ // memcpy(&response[1], data, dlen);
+ // response_length = dlen + 1;
+
+ // hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
+}
+
+STATIC void process_exec_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
+ struct bt_att_exec_write_req *req = (struct bt_att_exec_write_req *) data;
+
+ if (dlen != sizeof(struct bt_att_exec_write_req)) {
+ send_error(conn_handle, BT_ATT_OP_EXEC_WRITE_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
+
+ if (long_write_handle && (req->flags & 0x01)) {
+ //FIX BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)GATT.attribute(long_write_handle - 1);
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle == conn_handle) {
+ //FIX characteristic->writeValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), long_write_value, long_write_value_length);
+ break;
+ }
+ }
+ }
+
+ long_write_handle = BLE_GATT_HANDLE_INVALID;
+ long_write_value_length = 0;
+
+ uint8_t response[mtu];
+ uint16_t response_length;
+
+ response[0] = BT_ATT_OP_EXEC_WRITE_RSP;
+ response_length = 1;
+
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
+}
+
+STATIC void process_notify_or_indicate(uint16_t conn_handle, uint8_t opcode, uint8_t dlen, uint8_t data[]) {
+ if (dlen < 2) {
+ return; // drop
+ }
+
+ // struct bt_att_notify and bt_att_indicate are identical.
+ //FIXunused struct bt_att_notify *req = (struct bt_att_notify *) data;
+
+ //FIXunused uint8_t handle = req->handle;
+
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ if (bleio_connections[i].conn_handle != conn_handle) {
+ continue;
+ }
+
+ //FIX BLERemoteDevice* device = bleio_connections[i].device;
+
+ // if (!device) {
+ // break;
+ // }
+
+ // int serviceCount = device->serviceCount();
+
+ // for (size_t i = 0; i < serviceCount; i++) {
+ // BLERemoteService* s = device->service(i);
+
+ // if (s->start_handle() < handle && s->end_handle() >= handle) {
+ // int characteristicCount = s->characteristicCount();
+
+ // for (int j = 0; j < characteristicCount; j++) {
+ // BLERemoteCharacteristic* c = s->characteristic(j);
+
+ // if (c->value_handle() == handle) {
+ // //FIX c->writeValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), &data[2], dlen - 2);
+ // }
+ // }
+
+ // break;
+ // }
+ // }
+ }
+
+ if (opcode == BT_ATT_OP_INDICATE) {
+ // send CONFIRM for INDICATE
+
+ uint8_t op_confirm = BT_ATT_OP_CONFIRM;
+
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(op_confirm), &op_confirm);
+ }
+}
+
+STATIC void process_confirm(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ (void) conn_handle;
+ (void) dlen;
+ (void) data;
+
+ confirm = true;
+}
+
+bool att_exchange_mtu(uint16_t conn_handle) {
+ uint8_t response_buffer[max_mtu];
+ struct bt_att_exchange_mtu_req req = {
+ .mtu = max_mtu,
+ };
+ return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
+}
+
+int att_read_req(uint16_t conn_handle, uint16_t handle, uint8_t response_buffer[]) {
+ struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_read_req r;
+ } req = { {
+ .code = BT_ATT_OP_READ_REQ,
+ }, {
+ .handle = handle,
+ }
+ };
+
+ return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
+}
+
+int att_write_req(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len, uint8_t response_buffer[]) {
+ typedef struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_write_req r;
+ } req_t;
+
+ uint8_t req_bytes[sizeof(req_t) + data_len];
+ req_t *req = (req_t *) req_bytes;
+ req->h.code = BT_ATT_OP_WRITE_REQ;
+ req->r.handle = handle;
+ memcpy(req->r.value, data, data_len);
+
+ return send_req_wait_for_rsp(conn_handle, sizeof(req_bytes), req_bytes, response_buffer);
+}
+
+void att_write_cmd(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len) {
+ typedef struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_write_cmd r;
+ } cmd_t;
+
+ uint8_t cmd_bytes[sizeof(cmd_t) + data_len];
+ cmd_t *cmd = (cmd_t *) cmd_bytes;
+ cmd->h.code = BT_ATT_OP_WRITE_CMD;
+ cmd->r.handle = handle;
+ memcpy(cmd->r.value, data, data_len);
+
+ send_req(conn_handle, sizeof(cmd_bytes), cmd_bytes);
+}
+
+void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+ // Opcode is a single byte at the front of the data.
+ uint8_t opcode = data[0];
+
+ // Skip over opcode.
+ dlen--;
+ data++;
+
+ uint16_t mtu = att_mtu(conn_handle);
+
+ switch (opcode) {
+ case BT_ATT_OP_ERROR_RSP:
+ process_error(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_MTU_REQ:
+ process_mtu_req(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_MTU_RSP:
+ process_mtu_rsp(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_FIND_INFO_REQ:
+ process_find_info_req(conn_handle, mtu, dlen, data);
+ break;
+
+ case BT_ATT_OP_FIND_INFO_RSP:
+ process_find_info_rsp(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_FIND_TYPE_REQ:
+ process_find_type_req(conn_handle, mtu, dlen, data);
+ break;
+
+ case BT_ATT_OP_READ_TYPE_REQ:
+ process_read_type_req(conn_handle, mtu, dlen, data);
+ break;
+
+ case BT_ATT_OP_READ_TYPE_RSP:
+ process_read_type_rsp(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_READ_GROUP_REQ:
+ process_read_group_req(conn_handle, mtu, dlen, data);
+ break;
+
+ case BT_ATT_OP_READ_GROUP_RSP:
+ process_read_group_rsp(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_READ_REQ:
+ case BT_ATT_OP_READ_BLOB_REQ:
+ process_read_or_read_blob_req(conn_handle, mtu, opcode, dlen, data);
+ break;
+
+ case BT_ATT_OP_READ_RSP:
+ process_read_rsp(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_WRITE_REQ:
+ case BT_ATT_OP_WRITE_CMD:
+ process_write_req_or_cmd(conn_handle, mtu, opcode, dlen, data);
+ break;
+
+ case BT_ATT_OP_WRITE_RSP:
+ process_write_rsp(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_PREPARE_WRITE_REQ:
+ process_prepare_write_req(conn_handle, mtu, dlen, data);
+ break;
+
+ case BT_ATT_OP_EXEC_WRITE_REQ:
+ process_exec_write_req(conn_handle, mtu, dlen, data);
+ break;
+
+ case BT_ATT_OP_NOTIFY:
+ case BT_ATT_OP_INDICATE:
+ process_notify_or_indicate(conn_handle, opcode, dlen, data);
+ break;
+
+ case BT_ATT_OP_CONFIRM:
+ process_confirm(conn_handle, dlen, data);
+ break;
+
+ case BT_ATT_OP_READ_MULT_REQ:
+ case BT_ATT_OP_SIGNED_WRITE_CMD:
+ default:
+ send_error(conn_handle, opcode, 0x00, BT_ATT_ERR_NOT_SUPPORTED);
+ break;
+ }
+}
+
+//FIX Do we need all of these?
+void check_att_err(uint8_t err) {
+ const compressed_string_t *msg = NULL;
+ switch (err) {
+ case 0:
+ return;
+ case BT_ATT_ERR_INVALID_HANDLE:
+ msg = translate("Invalid handle");
+ break;
+ case BT_ATT_ERR_READ_NOT_PERMITTED:
+ msg = translate("Read not permitted");
+ break;
+ case BT_ATT_ERR_WRITE_NOT_PERMITTED:
+ msg = translate("Write not permitted");
+ break;
+ case BT_ATT_ERR_INVALID_PDU:
+ msg = translate("Invalid PDU");
+ break;
+ case BT_ATT_ERR_NOT_SUPPORTED:
+ msg = translate("Not supported");
+ break;
+ case BT_ATT_ERR_INVALID_OFFSET:
+ msg = translate("Invalid offset");
+ break;
+ case BT_ATT_ERR_PREPARE_QUEUE_FULL:
+ msg = translate("Prepare queue full");
+ break;
+ case BT_ATT_ERR_ATTRIBUTE_NOT_FOUND:
+ msg = translate("Attribute not found");
+ break;
+ case BT_ATT_ERR_ATTRIBUTE_NOT_LONG:
+ msg = translate("Attribute not long");
+ break;
+ case BT_ATT_ERR_ENCRYPTION_KEY_SIZE:
+ msg = translate("Encryption key size");
+ case BT_ATT_ERR_INVALID_ATTRIBUTE_LEN:
+ msg = translate("Invalid attribute length");
+ break;
+ case BT_ATT_ERR_UNLIKELY:
+ msg = translate("Unlikely");
+ break;
+ case BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE:
+ msg = translate("Unsupported group type");
+ break;
+ case BT_ATT_ERR_INSUFFICIENT_RESOURCES:
+ msg = translate("Insufficient resources");
+ break;
+ case BT_ATT_ERR_DB_OUT_OF_SYNC:
+ msg = translate("DB out of sync");
+ break;
+ case BT_ATT_ERR_VALUE_NOT_ALLOWED:
+ msg = translate("Value not allowed");
+ break;
+ }
+ if (msg) {
+ mp_raise_bleio_BluetoothError(msg);
+ }
+
+ switch (err) {
+ case BT_ATT_ERR_AUTHENTICATION:
+ msg = translate("Insufficient authentication");
+ break;
+ case BT_ATT_ERR_INSUFFICIENT_ENCRYPTION:
+ msg = translate("Insufficient encryption");
+ break;
+ }
+ if (msg) {
+ mp_raise_bleio_SecurityError(msg);
+ }
+
+ mp_raise_bleio_BluetoothError(translate("Unknown ATT error: 0x%02x"), err);
+}
diff --git a/devices/ble_hci/common-hal/_bleio/att.h b/devices/ble_hci/common-hal/_bleio/att.h
new file mode 100644
index 000000000..b34b74dc3
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/att.h
@@ -0,0 +1,57 @@
+// Derived from ArduinoBLE.
+// Copyright 2020 Dan Halbert for Adafruit Industries
+
+/*
+ This file is part of the ArduinoBLE library.
+ Copyright (c) 2018 Arduino SA. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef MICROPY_INCLUDED_DEVICES_BLE_HCI_COMMON_HAL_BLEIO_ATT_H
+#define MICROPY_INCLUDED_DEVICES_BLE_HCI_COMMON_HAL_BLEIO_ATT_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "hci_include/addr.h"
+#include "hci_include/att.h"
+#include "hci_include/att_internal.h"
+
+void bleio_att_reset(void);
+
+//FIX void att_set_event_handler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler);
+bool att_address_is_connected(bt_addr_le_t *addr);
+bool att_connect_to_address(bt_addr_le_t *addr);
+bool att_disconnect(uint16_t conn_handle);
+bool att_disconnect_all(void);
+bool att_discover_attributes(bt_addr_le_t *addr, const char* service_uuid_filter);
+bool att_exchange_mtu(uint16_t conn_handle);
+bool att_handle_is_connected(uint16_t handle);
+bool att_indicate(uint16_t handle, const uint8_t* value, int length);
+bool att_is_connected(void);
+bool att_notify(uint16_t handle, const uint8_t* value, int length);
+int att_read_req(uint16_t conn_handle, uint16_t handle, uint8_t response_buffer[]);
+int att_write_req(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len, uint8_t response_buffer[]);
+uint16_t att_conn_handle(bt_addr_le_t *addr);
+uint16_t att_mtu(uint16_t handle);
+void att_add_connection(uint16_t handle, uint8_t role, bt_addr_le_t *peer_addr, uint16_t interval, uint16_t latency, uint16_t supervision_timeout, uint8_t master_clock_accuracy);
+void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]);
+void att_remove_connection(uint16_t conn_handle, uint8_t reason);
+void att_set_max_mtu(uint16_t max_mtu);
+void att_set_timeout(unsigned long timeout);
+void att_write_cmd(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len);
+
+#endif // MICROPY_INCLUDED_DEVICES_BLE_HCI_COMMON_HAL_BLEIO_ATT_H
diff --git a/devices/ble_hci/common-hal/_bleio/hci.c b/devices/ble_hci/common-hal/_bleio/hci.c
new file mode 100644
index 000000000..e261a9847
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci.c
@@ -0,0 +1,806 @@
+// This file is derived from the ArduinoBLE library. Its header is below.
+/*
+ This file is part of the ArduinoBLE library.
+ Copyright (c) 2018 Arduino SA. All rights reserved.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "att.h"
+#include "hci.h"
+
+#include "py/obj.h"
+#include "py/mperrno.h"
+#include "py/runtime.h"
+
+// Zephyr include files to define HCI communication values and structs.
+#include "hci_include/hci.h"
+#include "hci_include/hci_err.h"
+#include "hci_include/l2cap_internal.h"
+
+#include <string.h>
+
+#include "py/mphal.h" //*****************************
+#include "supervisor/shared/tick.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "common-hal/_bleio/Adapter.h"
+#include "shared-bindings/microcontroller/__init__.h"
+
+// Set to 1 for extensive HCI packet logging.
+#define HCI_DEBUG 0
+
+// HCI H4 protocol packet types: first byte in the packet.
+#define H4_CMD 0x01
+#define H4_ACL 0x02
+#define H4_SCO 0x03
+#define H4_EVT 0x04
+
+#define CTS_TIMEOUT_MSECS (1000)
+#define RESPONSE_TIMEOUT_MSECS (1000)
+
+// These are the headers of the full packets that are sent over the serial interface.
+// They all have a one-byte type-field at the front, one of the H4_xxx packet types.
+
+typedef struct __attribute__ ((packed)) {
+ uint8_t pkt_type;
+ uint16_t opcode;
+ uint8_t param_len;
+ uint8_t params[];
+} h4_hci_cmd_pkt_t;
+
+#define ACL_DATA_PB_FIRST_NON_FLUSH 0
+#define ACL_DATA_PB_MIDDLE 1
+#define ACL_DATA_PB_FIRST_FLUSH 2
+#define ACL_DATA_PB_FULL 3
+
+typedef struct __attribute__ ((packed)) {
+ uint8_t pkt_type;
+ uint16_t handle : 12;
+ uint8_t pb: 2; // Packet boundary flag: ACL_DATA_PB values.
+ uint8_t bc: 2; // Broadcast flag: always 0b00 for BLE.
+ uint16_t data_len; // length of data[] in this packet.
+ uint8_t data[];
+} h4_hci_acl_pkt_t;
+
+// The ACL data in an h4_hci_acl_pkt_t may be fragmented across
+// multiple ACL_DATA packets, and need to be recombined. This is the
+// structure of the combined packet or the first fragment.
+typedef struct __attribute__ ((packed)) {
+ uint16_t acl_data_len; // Length of acl_data. Does not include this header.
+ uint16_t cid; // Channel ID.
+ uint8_t acl_data[]; // Length is acl_data_len of full packet.
+} acl_data_t;
+
+typedef struct __attribute__ ((packed)) {
+ uint8_t pkt_type;
+ uint8_t evt;
+ uint8_t param_len;
+ uint8_t params[];
+} h4_hci_evt_pkt_t;
+
+
+//////////////////////////////////////////////////////////////////////
+// Static storage:
+
+//FIX size
+#define RX_BUFFER_SIZE (3 + 255)
+#define ACL_DATA_BUFFER_SIZE (255)
+
+STATIC uint8_t rx_buffer[RX_BUFFER_SIZE];
+STATIC size_t rx_idx;
+
+STATIC uint8_t acl_data_buffer[ACL_DATA_BUFFER_SIZE];
+STATIC size_t acl_data_len;
+
+STATIC size_t num_command_packets_allowed;
+STATIC volatile size_t pending_pkt;
+
+// Results from parsing a command response packet.
+STATIC bool cmd_response_received;
+STATIC uint16_t cmd_response_opcode;
+STATIC uint8_t cmd_response_status;
+STATIC size_t cmd_response_len;
+STATIC uint8_t* cmd_response_data;
+
+STATIC volatile bool hci_poll_in_progress = false;
+
+
+//////////////////////////////////////////////////////////////////////
+
+#if HCI_DEBUG
+#include "hci_debug.c"
+#endif // HCI_DEBUG
+
+STATIC void process_acl_data_pkt(uint8_t pkt_len, uint8_t pkt_data[]) {
+ h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t*) pkt_data;
+
+ if (pkt->pb != ACL_DATA_PB_MIDDLE) {
+ // This is the start of a fragmented acl_data packet or is a full packet.
+ memcpy(acl_data_buffer, pkt->data, pkt->data_len);
+ acl_data_len = pkt->data_len;
+ } else {
+ // This is a middle or end fragment of acl data.
+ // Append to the accumulated data so far.
+ memcpy(&acl_data_buffer[acl_data_len], pkt->data, pkt->data_len);
+ acl_data_len += pkt->data_len;
+ }
+
+ acl_data_t *acl = (acl_data_t *) &acl_data_buffer;
+ if (acl_data_len != sizeof(acl) + acl->acl_data_len) {
+ // We don't have the full packet yet.
+ return;
+ }
+
+ if (acl->cid == BT_L2CAP_CID_ATT) {
+ att_process_data(pkt->handle, acl->acl_data_len, acl->acl_data);
+ }
+ // } else if (aclHdr->cid == BT_L2CAP_CID_LE_SIG) {
+ // L2CAPSignaling.handleData(aclHdr->handle & 0x0fff, aclHdr->len, &rx_buffer[1 + sizeof(HCIACLHdr)]);
+ // } else {
+ // struct __attribute__ ((packed)) {
+ // uint8_t op;
+ // uint8_t id;
+ // uint16_t length;
+ // uint16_t reason;
+ // uint16_t localCid;
+ // uint16_t remoteCid;
+ // } l2capRejectCid= { 0x01, 0x00, 0x006, 0x0002, aclHdr->cid, 0x0000 };
+
+ // sendAclPkt(aclHdr->handle & 0x0fff, 0x0005, sizeof(l2capRejectCid), &l2capRejectCid);
+ // }
+}
+
+// Process number of completed packets. Reduce number of pending packets by reported
+// number of completed.
+STATIC void process_num_comp_pkts(uint16_t handle, uint16_t num_pkts) {
+ if (num_pkts && pending_pkt > num_pkts) {
+ pending_pkt -= num_pkts;
+ } else {
+ pending_pkt = 0;
+ }
+}
+
+STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
+{
+ h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t*) pkt_data;
+
+ switch (pkt->evt) {
+ case BT_HCI_EVT_DISCONN_COMPLETE: {
+ struct bt_hci_evt_disconn_complete *disconn_complete =
+ (struct bt_hci_evt_disconn_complete*) pkt->params;
+ (void) disconn_complete;
+
+ att_remove_connection(disconn_complete->handle, disconn_complete->reason);
+ //FIX L2CAPSignaling.removeConnection(disconn_complete->handle, disconn_complete->reason);
+ break;
+ }
+
+ case BT_HCI_EVT_CMD_COMPLETE: {
+ struct cmd_complete_with_status {
+ struct bt_hci_evt_cmd_complete cmd_complete;
+ struct bt_hci_evt_cc_status cc_status;
+ } __packed;
+
+ struct cmd_complete_with_status *evt = (struct cmd_complete_with_status *) pkt->params;
+
+ num_command_packets_allowed = evt->cmd_complete.ncmd;
+
+ cmd_response_received = true;
+ cmd_response_opcode = evt->cmd_complete.opcode;
+ cmd_response_status = evt->cc_status.status;
+ // All the bytes following cmd_complete, -including- the status byte, which is
+ // included in all the _bt_hci_rp_* structs.
+ cmd_response_data = (uint8_t *) &evt->cc_status;
+ // Includes status byte.
+ cmd_response_len = pkt->param_len - sizeof_field(struct cmd_complete_with_status, cmd_complete);
+
+ break;
+ }
+
+ case BT_HCI_EVT_CMD_STATUS: {
+ struct bt_hci_evt_cmd_status *evt = (struct bt_hci_evt_cmd_status *) pkt->params;
+
+ num_command_packets_allowed = evt->ncmd;
+
+ cmd_response_received = true;
+ cmd_response_opcode = evt->opcode;
+ cmd_response_status = evt->status;
+ cmd_response_data = NULL;
+ cmd_response_len = 0;
+
+ break;
+ }
+
+ case BT_HCI_EVT_NUM_COMPLETED_PACKETS: {
+ struct bt_hci_evt_num_completed_packets *evt =
+ (struct bt_hci_evt_num_completed_packets *) pkt->params;
+
+ // Start at zero-th pair: (conn handle, num completed packets).
+ struct bt_hci_handle_count *handle_and_count = &(evt->h[0]);
+ for (uint8_t i = 0; i < evt->num_handles; i++) {
+ process_num_comp_pkts(handle_and_count->handle, handle_and_count->count);
+ handle_and_count++;
+ }
+ break;
+ }
+
+ case BT_HCI_EVT_LE_META_EVENT: {
+ struct bt_hci_evt_le_meta_event *meta_evt = (struct bt_hci_evt_le_meta_event *) pkt->params;
+ uint8_t *le_evt = pkt->params + sizeof (struct bt_hci_evt_le_meta_event);
+
+ if (meta_evt->subevent == BT_HCI_EVT_LE_CONN_COMPLETE) {
+ // Advertising stops when connection occurs.
+ // We don't tell the adapter to stop, because stopping advertising
+ // when it's already stopped seems to exercise a bug in the ESP32 HCI code:
+ // It doesn't return a response.
+ bleio_adapter_advertising_was_stopped(&common_hal_bleio_adapter_obj);
+
+ struct bt_hci_evt_le_conn_complete *le_conn_complete =
+ (struct bt_hci_evt_le_conn_complete *) le_evt;
+
+ if (le_conn_complete->status == BT_HCI_ERR_SUCCESS) {
+ att_add_connection(
+ le_conn_complete->handle,
+ le_conn_complete->role,
+ &le_conn_complete->peer_addr,
+ le_conn_complete->interval,
+ le_conn_complete->latency,
+ le_conn_complete->supv_timeout,
+ le_conn_complete->clock_accuracy);
+
+ }
+ } else if (meta_evt->subevent == BT_HCI_EVT_LE_ADVERTISING_REPORT) {
+ struct bt_hci_evt_le_advertising_info *le_advertising_info =
+ (struct bt_hci_evt_le_advertising_info *) le_evt;
+ if (le_advertising_info->evt_type == BT_HCI_ADV_DIRECT_IND) {
+ //FIX
+ // last byte is RSSI
+ // GAP.handleLeAdvertisingReport(leAdvertisingReport->type,
+ // leAdvertisingReport->peerBdaddrType,
+ // leAdvertisingReport->peerBdaddr,
+ // leAdvertisingReport->eirLength,
+ // leAdvertisingReport->eirData,
+ // rssi); //FIX, don't separate
+
+ }
+ }
+ break;
+ }
+
+ default:
+#if HCI_DEBUG
+ mp_printf(&mp_plat_print, "process_evt_pkt: Unknown event: %02x\n");
+#endif
+ break;
+ }
+}
+
+void bleio_hci_reset(void) {
+ rx_idx = 0;
+ pending_pkt = 0;
+ hci_poll_in_progress = false;
+ bleio_att_reset();
+}
+
+hci_result_t hci_poll_for_incoming_pkt(void) {
+ common_hal_mcu_disable_interrupts();
+ if (hci_poll_in_progress) {
+ common_hal_mcu_enable_interrupts();
+ return HCI_OK;
+ }
+ hci_poll_in_progress = true;
+ common_hal_mcu_enable_interrupts();
+
+ // Assert RTS low to say we're ready to read data.
+ common_hal_digitalio_digitalinout_set_value(common_hal_bleio_adapter_obj.rts_digitalinout, false);
+
+ int errcode = 0;
+ bool packet_is_complete = false;
+
+ // Read bytes until we run out. There may be more than one packet in the input buffer.
+ while (!packet_is_complete &&
+ common_hal_busio_uart_rx_characters_available(common_hal_bleio_adapter_obj.hci_uart) > 0) {
+
+ // Read just one character a a time, so we don't accidentally get part of a second
+ // packet.
+ size_t num_read =
+ common_hal_busio_uart_read(common_hal_bleio_adapter_obj.hci_uart, rx_buffer + rx_idx, 1, &errcode);
+ if (num_read == 0) {
+ return HCI_OK;
+ }
+ if (errcode) {
+ if (errcode == EAGAIN) {
+ continue;
+ }
+ hci_poll_in_progress = false;
+ mp_printf(&mp_plat_print, "HCI_READ_ERROR, errcode: %x\n", errcode);
+ return HCI_READ_ERROR;
+ }
+ rx_idx++;
+ if (rx_idx >= sizeof(rx_buffer)) {
+ // Incoming packet is too large. Should not happen.
+ return HCI_READ_ERROR;
+ }
+
+ switch (rx_buffer[0]) {
+ case H4_ACL:
+ if (rx_idx >= sizeof(h4_hci_acl_pkt_t)) {
+ const size_t total_len =
+ sizeof(h4_hci_acl_pkt_t) + ((h4_hci_acl_pkt_t *) rx_buffer)->data_len;
+ if (rx_idx == total_len) {
+ packet_is_complete = true;
+ }
+ if (rx_idx > total_len) {
+ return HCI_PACKET_SIZE_ERROR;
+ }
+ }
+ break;
+
+ case H4_EVT:
+ if (rx_idx >= sizeof(h4_hci_evt_pkt_t)) {
+ const size_t total_len =
+ sizeof(h4_hci_evt_pkt_t) + ((h4_hci_evt_pkt_t *) rx_buffer)->param_len;
+ if (rx_idx == total_len) {
+ packet_is_complete = true;
+ }
+ if (rx_idx > total_len) {
+ return HCI_PACKET_SIZE_ERROR;
+ }
+ }
+ break;
+
+ default:
+ // Unknown or bad packet type. Start over.
+ rx_idx = 0;
+ break;
+ }
+ } // end while
+
+ if (packet_is_complete) {
+ // Stop incoming data while processing packet.
+ common_hal_digitalio_digitalinout_set_value(common_hal_bleio_adapter_obj.rts_digitalinout, true);
+ size_t pkt_len = rx_idx;
+
+ // Reset for next packet.
+ rx_idx = 0;
+ packet_is_complete = false;
+
+ switch (rx_buffer[0]) {
+ case H4_ACL:
+#if HCI_DEBUG
+ dump_acl_pkt(false, pkt_len, rx_buffer);
+#endif
+ process_acl_data_pkt(pkt_len, rx_buffer);
+ break;
+
+ case H4_EVT:
+#if HCI_DEBUG
+ dump_evt_pkt(false, pkt_len, rx_buffer);
+#endif
+ process_evt_pkt(pkt_len, rx_buffer);
+ break;
+
+ default:
+#if HCI_DEBUG
+ mp_printf(&mp_plat_print, "Unknown HCI packet type: %d\n", rx_buffer[0]);
+#endif
+ break;
+ }
+
+ // Let incoming bytes flow again.
+ common_hal_digitalio_digitalinout_set_value(common_hal_bleio_adapter_obj.rts_digitalinout, false);
+ }
+
+ // All done with this batch. Hold off receiving bytes until we're ready again.
+ ///common_hal_digitalio_digitalinout_set_value(common_hal_bleio_adapter_obj.rts_digitalinout, true);
+ hci_poll_in_progress = false;
+ return HCI_OK;
+}
+
+
+STATIC hci_result_t write_pkt(uint8_t *buffer, size_t len) {
+ // Wait for CTS to go low before writing to HCI adapter.
+ uint64_t start = supervisor_ticks_ms64();
+
+ while (common_hal_digitalio_digitalinout_get_value(common_hal_bleio_adapter_obj.cts_digitalinout)) {
+ RUN_BACKGROUND_TASKS;
+ if (supervisor_ticks_ms64() - start > CTS_TIMEOUT_MSECS) {
+ return HCI_WRITE_TIMEOUT;
+ }
+ }
+
+ int errcode = 0;
+ common_hal_busio_uart_write(common_hal_bleio_adapter_obj.hci_uart, buffer, len, &errcode);
+ if (errcode) {
+ return HCI_WRITE_ERROR;
+ }
+
+ return HCI_OK;
+}
+
+STATIC hci_result_t send_command(uint16_t opcode, uint8_t params_len, void* params) {
+ uint8_t cmd_pkt_len = sizeof(h4_hci_cmd_pkt_t) + params_len;
+ uint8_t tx_buffer[cmd_pkt_len];
+
+ // cmd header is at the beginning of tx_buffer
+ h4_hci_cmd_pkt_t *cmd_pkt = (h4_hci_cmd_pkt_t *) tx_buffer;
+ cmd_pkt->pkt_type = H4_CMD;
+ cmd_pkt->opcode = opcode;
+ cmd_pkt->param_len = params_len;
+
+ memcpy(cmd_pkt->params, params, params_len);
+
+#if HCI_DEBUG
+ dump_cmd_pkt(true, sizeof(tx_buffer), tx_buffer);
+#endif
+
+ int result = write_pkt(tx_buffer, cmd_pkt_len);
+ if (result != HCI_OK) {
+ return result;
+ }
+
+ cmd_response_received = false;
+
+ // Wait for a response. Note that other packets may be received that are not
+ // command responses.
+ uint64_t start = supervisor_ticks_ms64();
+ while (supervisor_ticks_ms64() - start < RESPONSE_TIMEOUT_MSECS) {
+ // RUN_BACKGROUND_TASKS includes hci_poll_for_incoming_pkt();
+ RUN_BACKGROUND_TASKS;
+ if (cmd_response_received && cmd_response_opcode == opcode) {
+ // If this is definitely a response to the command that was sent,
+ // return the status value, which will will be
+ // BT_HCI_ERR_SUCCESS (0x00) if the command succeeded,
+ // or a BT_HCI_ERR_x value (> 0x00) if there was a problem.
+ return cmd_response_status;
+ }
+ }
+
+ // No I/O error, but no response sent back in time.
+ return HCI_RESPONSE_TIMEOUT;
+}
+
+hci_result_t hci_send_acl_pkt(uint16_t handle, uint8_t cid, uint16_t data_len, uint8_t *data) {
+ // Wait for all backlogged packets to finish.
+ while (pending_pkt >= common_hal_bleio_adapter_obj.max_acl_num_buffers) {
+ // RUN_BACKGROUND_TASKS includes hci_poll_for_incoming_pkt();
+ RUN_BACKGROUND_TASKS;
+ }
+
+ // buf_len is size of entire packet including header.
+ const size_t buf_len = sizeof(h4_hci_acl_pkt_t) + sizeof(acl_data_t) + data_len;
+ uint8_t tx_buffer[buf_len];
+
+ h4_hci_acl_pkt_t *acl_pkt = (h4_hci_acl_pkt_t *) tx_buffer;
+ acl_data_t *acl_data = (acl_data_t *) acl_pkt->data;
+ acl_pkt->pkt_type = H4_ACL;
+ acl_pkt->handle = handle;
+ acl_pkt->pb = ACL_DATA_PB_FIRST_FLUSH;
+ acl_pkt->bc = 0;
+ acl_pkt->data_len = (uint16_t)(sizeof(acl_data_t) + data_len);
+ acl_data->acl_data_len = data_len;
+ acl_data->cid = cid;
+
+ memcpy(&acl_data->acl_data, data, data_len);
+
+#if HCI_DEBUG
+ dump_acl_pkt(true, buf_len, tx_buffer);
+#endif
+
+ pending_pkt++;
+
+ int errcode = 0;
+ common_hal_busio_uart_write(common_hal_bleio_adapter_obj.hci_uart, tx_buffer, buf_len, &errcode);
+ if (errcode) {
+ return HCI_WRITE_ERROR;
+ }
+ return HCI_OK;
+}
+
+hci_result_t hci_reset(void) {
+ return send_command(BT_HCI_OP_RESET, 0, NULL);
+}
+
+hci_result_t hci_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_version, uint16_t *manufacturer, uint16_t *lmp_subversion) {
+ hci_result_t result = send_command(BT_HCI_OP_READ_LOCAL_VERSION_INFO, 0, NULL);
+ if (result == HCI_OK) {
+ struct bt_hci_rp_read_local_version_info *response =
+ (struct bt_hci_rp_read_local_version_info *) cmd_response_data;
+ *hci_version = response->hci_version;
+ *hci_revision = response->hci_revision;
+ *lmp_version = response->lmp_version;
+ *manufacturer = response->manufacturer;
+ *lmp_subversion = response->lmp_subversion;
+ }
+
+ return result;
+}
+
+hci_result_t hci_read_bd_addr(bt_addr_t *addr) {
+ int result = send_command(BT_HCI_OP_READ_BD_ADDR, 0, NULL);
+ if (result == HCI_OK) {
+ struct bt_hci_rp_read_bd_addr *response = (struct bt_hci_rp_read_bd_addr *) cmd_response_data;
+ memcpy(addr->val, response->bdaddr.val, sizeof_field(bt_addr_t, val));
+ }
+
+ return result;
+}
+
+hci_result_t hci_read_rssi(uint16_t handle, int *rssi) {
+ int result = send_command(BT_HCI_OP_READ_RSSI, sizeof(handle), &handle);
+ if (result == HCI_OK) {
+ struct bt_hci_rp_read_rssi *response = (struct bt_hci_rp_read_rssi *) cmd_response_data;
+ *rssi = response->rssi;
+ }
+
+ return result;
+}
+
+hci_result_t hci_set_event_mask(uint64_t event_mask) {
+ return send_command(BT_HCI_OP_SET_EVENT_MASK, sizeof(event_mask), &event_mask);
+}
+
+hci_result_t hci_le_read_buffer_size(uint16_t *le_max_len, uint8_t *le_max_num) {
+ int result = send_command(BT_HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
+ if (result == HCI_OK) {
+ struct bt_hci_rp_le_read_buffer_size *response =
+ (struct bt_hci_rp_le_read_buffer_size *) cmd_response_data;
+ *le_max_len = response->le_max_len;
+ *le_max_num = response->le_max_num;
+ }
+
+ return result;
+}
+
+hci_result_t hci_read_buffer_size(uint16_t *acl_max_len, uint8_t *sco_max_len, uint16_t *acl_max_num, uint16_t *sco_max_num) {
+ int result = send_command(BT_HCI_OP_READ_BUFFER_SIZE, 0, NULL);
+ if (result == HCI_OK) {
+ struct bt_hci_rp_read_buffer_size *response =
+ (struct bt_hci_rp_read_buffer_size *) cmd_response_data;
+ *acl_max_len = response->acl_max_len;
+ *sco_max_len = response->sco_max_len;
+ *acl_max_num = response->acl_max_num;
+ *sco_max_num = response->sco_max_num;
+ }
+
+ return result;
+}
+
+hci_result_t hci_le_set_random_address(uint8_t addr[6]) {
+ return send_command(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, 6, addr);
+}
+
+hci_result_t hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t type, uint8_t own_addr_type, bt_addr_le_t *direct_addr, uint8_t channel_map, uint8_t filter_policy) {
+ struct bt_hci_cp_le_set_adv_param params = {
+ .min_interval = min_interval,
+ .max_interval = max_interval,
+ .type = type,
+ .own_addr_type = own_addr_type,
+ // .direct_addr set below.
+ .channel_map = channel_map,
+ .filter_policy = filter_policy,
+ };
+ params.direct_addr.type = direct_addr->type;
+ memcpy(params.direct_addr.a.val, direct_addr->a.val, sizeof(params.direct_addr.a.val));
+
+ return send_command(BT_HCI_OP_LE_SET_ADV_PARAM, sizeof(params), &params);
+}
+
+hci_result_t hci_le_set_extended_advertising_parameters(uint8_t handle, uint16_t props, uint32_t prim_min_interval, uint32_t prim_max_interval, uint8_t prim_channel_map, uint8_t own_addr_type, bt_addr_le_t *peer_addr, uint8_t filter_policy, int8_t tx_power, uint8_t prim_adv_phy, uint8_t sec_adv_max_skip, uint8_t sec_adv_phy, uint8_t sid, uint8_t scan_req_notify_enable) {
+ struct bt_hci_cp_le_set_ext_adv_param params = {
+ .handle = handle,
+ .props = props,
+ // .prim_min_interval and .prim_max_interval set below
+ .prim_channel_map = prim_channel_map,
+ .own_addr_type = own_addr_type,
+ // .peer_addr set below.
+ .tx_power = tx_power,
+ .sec_adv_max_skip = sec_adv_max_skip,
+ .sec_adv_phy = sec_adv_phy,
+ .sid = sid,
+ .scan_req_notify_enable = scan_req_notify_enable,
+ };
+ // Assumes little-endian.
+ memcpy(params.prim_min_interval, (void *) &prim_min_interval,
+ sizeof_field(struct bt_hci_cp_le_set_ext_adv_param, prim_min_interval));
+ memcpy(params.prim_max_interval, (void *) &prim_max_interval,
+ sizeof_field(struct bt_hci_cp_le_set_ext_adv_param, prim_max_interval));
+ memcpy(params.peer_addr.a.val, peer_addr->a.val, sizeof_field(bt_addr_le_t, a.val));
+ return send_command(BT_HCI_OP_LE_SET_EXT_ADV_PARAM, sizeof(params), &params);
+}
+
+hci_result_t hci_le_read_maximum_advertising_data_length(uint16_t *max_adv_data_len) {
+ int result = send_command(BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN, 0, NULL);
+ if (result == HCI_OK) {
+ struct bt_hci_rp_le_read_max_adv_data_len *response =
+ (struct bt_hci_rp_le_read_max_adv_data_len *) cmd_response_data;
+ *max_adv_data_len = response->max_adv_data_len;
+ }
+
+ return result;
+}
+
+hci_result_t hci_le_read_local_supported_features(uint8_t features[8]) {
+ int result = send_command(BT_HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
+ if (result == HCI_OK) {
+ struct bt_hci_rp_le_read_local_features *response =
+ (struct bt_hci_rp_le_read_local_features *) cmd_response_data;
+ memcpy(features, response->features,
+ sizeof_field(struct bt_hci_rp_le_read_local_features, features));
+ }
+
+ return result;
+}
+
+hci_result_t hci_le_set_advertising_data(uint8_t len, uint8_t data[]) {
+ struct bt_hci_cp_le_set_adv_data params = {
+ // Zero out unused data bytes.
+ .data = { 0 },
+ };
+
+ params.len = len;
+ memcpy(params.data, data, len);
+
+ // All data bytes are sent even if some are unused.
+ return send_command(BT_HCI_OP_LE_SET_ADV_DATA, sizeof(params), &params);
+}
+
+hci_result_t hci_le_set_extended_advertising_data(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len, uint8_t data[]) {
+ const uint8_t max_len = sizeof_field(struct bt_hci_cp_le_set_ext_adv_data, data);
+ uint8_t valid_len = MIN(len, max_len);
+ struct bt_hci_cp_le_set_ext_adv_data params = {
+ .handle = handle,
+ .op = op,
+ .frag_pref = frag_pref,
+ .len = valid_len,
+ };
+ memcpy(params.data, data, valid_len);
+ return send_command(BT_HCI_OP_LE_SET_EXT_ADV_DATA, sizeof(params) - (max_len - valid_len), &params);
+}
+
+
+hci_result_t hci_le_set_scan_response_data(uint8_t len, uint8_t data[]) {
+ struct bt_hci_cp_le_set_scan_rsp_data params = {
+ // Zero out unused data bytes.
+ .data = { 0 },
+ };
+ params.len = len;
+ memcpy(params.data, data, len);
+
+ // All data bytes are sent even if some are unused.
+ return send_command(BT_HCI_OP_LE_SET_SCAN_RSP_DATA, sizeof(params), &params);
+}
+
+hci_result_t hci_le_set_advertising_enable(uint8_t enable) {
+ return send_command(BT_HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
+}
+
+hci_result_t hci_le_set_extended_advertising_enable(uint8_t enable, uint8_t set_num, uint8_t handle[], uint16_t duration[], uint8_t max_ext_adv_evts[]) {
+ uint8_t params[sizeof(struct bt_hci_cp_le_set_ext_adv_enable) +
+ set_num * (sizeof(struct bt_hci_ext_adv_set))];
+ struct bt_hci_cp_le_set_ext_adv_enable *params_p = (struct bt_hci_cp_le_set_ext_adv_enable *) &params;
+ params_p->enable = enable;
+ params_p->set_num = set_num;
+ for (size_t i = 0; i < set_num; i++) {
+ params_p->s[i].handle = handle[i];
+ params_p->s[i].duration = duration[i];
+ params_p->s[i].max_ext_adv_evts = max_ext_adv_evts[i];
+ }
+
+ return send_command(BT_HCI_OP_LE_SET_EXT_ADV_ENABLE, sizeof(params), &params);
+}
+
+hci_result_t hci_le_set_scan_parameters(uint8_t scan_type, uint16_t interval, uint16_t window, uint8_t addr_type, uint8_t filter_policy) {
+ struct bt_hci_cp_le_set_scan_param params = {
+ .scan_type = scan_type,
+ .interval = interval,
+ .window = window,
+ .addr_type = addr_type,
+ .filter_policy = filter_policy,
+ };
+
+ return send_command(BT_HCI_OP_LE_SET_SCAN_PARAM, sizeof(params), &params);
+}
+
+hci_result_t hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) {
+ struct bt_hci_cp_le_set_scan_enable params = {
+ .enable = enable,
+ .filter_dup = filter_dup,
+ };
+
+ return send_command(BT_HCI_OP_LE_SET_SCAN_ENABLE, sizeof(params), &params);
+}
+
+hci_result_t hci_le_create_conn(uint16_t scan_interval, uint16_t scan_window, uint8_t filter_policy, bt_addr_le_t *peer_addr, uint8_t own_addr_type, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_len, uint16_t max_ce_len) {
+ struct bt_hci_cp_le_create_conn params = {
+ .scan_interval = scan_interval,
+ .scan_window = scan_window,
+ .filter_policy = filter_policy,
+ // .peer_addr is set below
+ .own_addr_type = own_addr_type,
+ .conn_interval_min = conn_interval_min,
+ .conn_interval_max = conn_interval_max,
+ .conn_latency = conn_latency,
+ .supervision_timeout = supervision_timeout,
+ .min_ce_len = min_ce_len,
+ .max_ce_len = max_ce_len,
+ };
+ params.peer_addr.type = peer_addr->type;
+ memcpy(params.peer_addr.a.val, peer_addr->a.val, sizeof(params.peer_addr.a.val));
+
+ return send_command(BT_HCI_OP_LE_CREATE_CONN, sizeof(params), &params);
+}
+
+hci_result_t hci_le_cancel_conn(void) {
+ return send_command(BT_HCI_OP_CONNECT_CANCEL, 0, NULL);
+}
+
+hci_result_t hci_le_conn_update(uint16_t handle, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout) {
+ struct hci_cp_le_conn_update params = {
+ .handle = handle,
+ .conn_interval_min = conn_interval_min,
+ .conn_interval_max = conn_interval_max,
+ .conn_latency = conn_latency,
+ .supervision_timeout = supervision_timeout,
+ .min_ce_len = 4,
+ .max_ce_len = 6,
+ };
+
+ return send_command(BT_HCI_OP_LE_CONN_UPDATE, sizeof(params), &params);
+}
+
+hci_result_t hci_disconnect(uint16_t handle) {
+ struct bt_hci_cp_disconnect params = {
+ .handle = handle,
+ .reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN,
+ };
+
+ return send_command(BT_HCI_OP_DISCONNECT, sizeof(params), &params);
+}
+
+void hci_check_error(hci_result_t result) {
+ switch (result) {
+ case HCI_OK:
+ return;
+
+ case HCI_RESPONSE_TIMEOUT:
+ mp_raise_bleio_BluetoothError(translate("Timeout waiting for HCI response"));
+ return;
+
+ case HCI_WRITE_TIMEOUT:
+ mp_raise_bleio_BluetoothError(translate("Timeout waiting to write HCI request"));
+ return;
+
+ case HCI_READ_ERROR:
+ mp_raise_bleio_BluetoothError(translate("Error reading from HCI adapter"));
+ return;
+
+ case HCI_WRITE_ERROR:
+ mp_raise_bleio_BluetoothError(translate("Error writing to HCI adapter"));
+ return;
+
+ case HCI_PACKET_SIZE_ERROR:
+ mp_raise_RuntimeError(translate("HCI packet size mismatch"));
+ return;
+
+ case HCI_ATT_ERROR:
+ mp_raise_RuntimeError(translate("Error in ATT protocol code"));
+ return;
+
+ default:
+ // Should be an HCI status error, > 0.
+ if (result > 0) {
+ mp_raise_bleio_BluetoothError(translate("HCI status error: %02x"), result);
+ } else {
+ mp_raise_bleio_BluetoothError(translate("Unknown hci_result_t: %d"), result);
+ }
+ return;
+ }
+}
diff --git a/devices/ble_hci/common-hal/_bleio/hci.h b/devices/ble_hci/common-hal/_bleio/hci.h
new file mode 100644
index 000000000..c9fd2393a
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci.h
@@ -0,0 +1,81 @@
+/*
+ This file is part of the ArduinoBLE library.
+ Copyright (c) 2018 Arduino SA. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef MICROPY_INCLUDED_DEVICES_BLE_HCI_COMMON_HAL_BLEIO_HCI_H
+#define MICROPY_INCLUDED_DEVICES_BLE_HCI_COMMON_HAL_BLEIO_HCI_H
+
+#include <stdint.h>
+
+#include "common-hal/_bleio/hci_include/hci.h"
+#include "common-hal/_bleio/hci_include/hci_err.h"
+
+// Incomplete forward declaration to get around mutually-dependent include files.
+typedef struct _bleio_adapter_obj_t bleio_adapter_obj_t;
+
+// An hci_result_t is one of the HCI_x values below,
+// or it is > 0 and is an HCI command status value (see hci_include/hci_err.h)
+typedef int hci_result_t;
+#define HCI_OK (0)
+#define HCI_RESPONSE_TIMEOUT (-1)
+#define HCI_WRITE_TIMEOUT (-2)
+#define HCI_READ_ERROR (-3)
+#define HCI_WRITE_ERROR (-4)
+#define HCI_ATT_ERROR (-5)
+#define HCI_PACKET_SIZE_ERROR (-6)
+
+extern void bleio_hci_reset(void);
+
+void hci_check_error(hci_result_t result);
+
+hci_result_t hci_disconnect(uint16_t handle);
+
+hci_result_t hci_le_cancel_conn(void);
+hci_result_t hci_le_conn_update(uint16_t handle, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout);
+hci_result_t hci_le_create_conn(uint16_t scan_interval, uint16_t scan_window, uint8_t filter_policy, bt_addr_le_t *peer_addr, uint8_t own_addr_type, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_len, uint16_t max_ce_len);
+
+hci_result_t hci_le_read_buffer_size(uint16_t *le_max_len, uint8_t *le_max_num);
+hci_result_t hci_le_read_maximum_advertising_data_length(uint16_t *max_adv_data_len);
+hci_result_t hci_le_read_local_supported_features(uint8_t features[8]);
+
+hci_result_t hci_le_set_advertising_data(uint8_t length, uint8_t data[]);
+hci_result_t hci_le_set_advertising_enable(uint8_t enable);
+hci_result_t hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t type, uint8_t own_addr_type, bt_addr_le_t *direct_addr, uint8_t channel_map, uint8_t filter_policy);
+
+hci_result_t hci_le_set_extended_advertising_data(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len, uint8_t data[]);
+hci_result_t hci_le_set_extended_advertising_enable(uint8_t enable, uint8_t set_num, uint8_t handle[], uint16_t duration[], uint8_t max_ext_adv_evts[]);
+hci_result_t hci_le_set_extended_advertising_parameters(uint8_t handle, uint16_t props, uint32_t prim_min_interval, uint32_t prim_max_interval, uint8_t prim_channel_map, uint8_t own_addr_type, bt_addr_le_t *peer_addr, uint8_t filter_policy, int8_t tx_power, uint8_t prim_adv_phy, uint8_t sec_adv_max_skip, uint8_t sec_adv_phy, uint8_t sid, uint8_t scan_req_notify_enable);
+
+hci_result_t hci_le_set_random_address(uint8_t addr[6]);
+hci_result_t hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup);
+hci_result_t hci_le_set_scan_parameters(uint8_t scan_type, uint16_t interval, uint16_t window, uint8_t addr_type, uint8_t filter_policy);
+hci_result_t hci_le_set_scan_response_data(uint8_t length, uint8_t data[]);
+
+hci_result_t hci_poll_for_incoming_pkt(void);
+
+hci_result_t hci_read_bd_addr(bt_addr_t *addr);
+hci_result_t hci_read_buffer_size(uint16_t *acl_max_len, uint8_t *sco_max_len, uint16_t *acl_max_num, uint16_t *sco_max_num);
+hci_result_t hci_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_version, uint16_t *manufacturer, uint16_t *lmp_subversion);
+hci_result_t hci_read_rssi(uint16_t handle, int *rssi);
+
+hci_result_t hci_reset(void);
+
+hci_result_t hci_send_acl_pkt(uint16_t handle, uint8_t cid, uint16_t data_len, uint8_t *data);
+hci_result_t hci_set_event_mask(uint64_t event_mask);
+
+#endif // MICROPY_INCLUDED_DEVICES_BLE_HCI_COMMON_HAL_BLEIO_HCI_H
diff --git a/devices/ble_hci/common-hal/_bleio/hci_debug.c b/devices/ble_hci/common-hal/_bleio/hci_debug.c
new file mode 100644
index 000000000..9cdd38981
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_debug.c
@@ -0,0 +1,335 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// This file is #include'd in hci.c when HCI_DEBUG is non-zero.
+
+STATIC const char* att_opcode_name(uint16_t opcode) {
+ switch (opcode) {
+ case BT_ATT_OP_ERROR_RSP: return "ERROR_RSP";
+ case BT_ATT_OP_MTU_REQ: return "MTU_REQ";
+ case BT_ATT_OP_MTU_RSP: return "MTU_RSP";
+ case BT_ATT_OP_FIND_INFO_REQ: return "FIND_INFO_REQ";
+ case BT_ATT_OP_FIND_INFO_RSP: return "FIND_INFO_RSP";
+ case BT_ATT_OP_FIND_TYPE_REQ: return "FIND_TYPE_REQ";
+ case BT_ATT_OP_FIND_TYPE_RSP: return "FIND_TYPE_RSP";
+ case BT_ATT_OP_READ_TYPE_REQ: return "READ_TYPE_REQ";
+ case BT_ATT_OP_READ_TYPE_RSP: return "READ_TYPE_RSP";
+ case BT_ATT_OP_READ_REQ: return "READ_REQ";
+ case BT_ATT_OP_READ_RSP: return "READ_RSP";
+ case BT_ATT_OP_READ_BLOB_REQ: return "READ_BLOB_REQ";
+ case BT_ATT_OP_READ_BLOB_RSP: return "READ_BLOB_RSP";
+ case BT_ATT_OP_READ_MULT_REQ: return "READ_MULT_REQ";
+ case BT_ATT_OP_READ_MULT_RSP: return "READ_MULT_RSP";
+ case BT_ATT_OP_READ_GROUP_REQ: return "READ_GROUP_REQ";
+ case BT_ATT_OP_READ_GROUP_RSP: return "READ_GROUP_RSP";
+ case BT_ATT_OP_WRITE_REQ: return "WRITE_REQ";
+ case BT_ATT_OP_WRITE_RSP: return "WRITE_RSP";
+ case BT_ATT_OP_PREPARE_WRITE_REQ: return "PREPARE_WRITE_REQ";
+ case BT_ATT_OP_PREPARE_WRITE_RSP: return "PREPARE_WRITE_RSP";
+ case BT_ATT_OP_EXEC_WRITE_REQ: return "EXEC_WRITE_REQ";
+ case BT_ATT_OP_EXEC_WRITE_RSP: return "EXEC_WRITE_RSP";
+ case BT_ATT_OP_NOTIFY: return "NOTIFY";
+ case BT_ATT_OP_INDICATE: return "INDICATE";
+ case BT_ATT_OP_CONFIRM: return "CONFIRM";
+ case BT_ATT_OP_READ_MULT_VL_REQ: return "READ_MULT_VL_REQ";
+ case BT_ATT_OP_READ_MULT_VL_RSP: return "READ_MULT_VL_RSP";
+ case BT_ATT_OP_NOTIFY_MULT: return "NOTIFY_MULT";
+ case BT_ATT_OP_WRITE_CMD: return "WRITE_CMD";
+ case BT_ATT_OP_SIGNED_WRITE_CMD: return "SIGNED_WRITE_CMD";
+ default: return "";
+ }
+}
+
+STATIC const char* hci_evt_name(uint8_t evt) {
+ switch (evt) {
+ case BT_HCI_EVT_UNKNOWN: return "UNKNOWN";
+ case BT_HCI_EVT_VENDOR: return "VENDOR";
+ case BT_HCI_EVT_INQUIRY_COMPLETE: return "INQUIRY_COMPLETE";
+ case BT_HCI_EVT_CONN_COMPLETE: return "CONN_COMPLETE";
+ case BT_HCI_EVT_CONN_REQUEST: return "CONN_REQUEST";
+ case BT_HCI_EVT_DISCONN_COMPLETE: return "DISCONN_COMPLETE";
+ case BT_HCI_EVT_AUTH_COMPLETE: return "AUTH_COMPLETE";
+ case BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE: return "REMOTE_NAME_REQ_COMPLETE";
+ case BT_HCI_EVT_ENCRYPT_CHANGE: return "ENCRYPT_CHANGE";
+ case BT_HCI_EVT_REMOTE_FEATURES: return "REMOTE_FEATURES";
+ case BT_HCI_EVT_REMOTE_VERSION_INFO: return "REMOTE_VERSION_INFO";
+ case BT_HCI_EVT_CMD_COMPLETE: return "CMD_COMPLETE";
+ case BT_HCI_EVT_CMD_STATUS: return "CMD_STATUS";
+ case BT_HCI_EVT_ROLE_CHANGE: return "ROLE_CHANGE";
+ case BT_HCI_EVT_NUM_COMPLETED_PACKETS: return "NUM_COMPLETED_PACKETS";
+ case BT_HCI_EVT_PIN_CODE_REQ: return "PIN_CODE_REQ";
+ case BT_HCI_EVT_LINK_KEY_REQ: return "LINK_KEY_REQ";
+ case BT_HCI_EVT_LINK_KEY_NOTIFY: return "LINK_KEY_NOTIFY";
+ case BT_HCI_EVT_DATA_BUF_OVERFLOW: return "DATA_BUF_OVERFLOW";
+ case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: return "INQUIRY_RESULT_WITH_RSSI";
+ case BT_HCI_EVT_REMOTE_EXT_FEATURES: return "REMOTE_EXT_FEATURES";
+ case BT_HCI_EVT_SYNC_CONN_COMPLETE: return "SYNC_CONN_COMPLETE";
+ case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: return "EXTENDED_INQUIRY_RESULT";
+ case BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE: return "ENCRYPT_KEY_REFRESH_COMPLETE";
+ case BT_HCI_EVT_IO_CAPA_REQ: return "IO_CAPA_REQ";
+ case BT_HCI_EVT_IO_CAPA_RESP: return "IO_CAPA_RESP";
+ case BT_HCI_EVT_USER_CONFIRM_REQ: return "USER_CONFIRM_REQ";
+ case BT_HCI_EVT_USER_PASSKEY_REQ: return "USER_PASSKEY_REQ";
+ case BT_HCI_EVT_SSP_COMPLETE: return "SSP_COMPLETE";
+ case BT_HCI_EVT_USER_PASSKEY_NOTIFY: return "USER_PASSKEY_NOTIFY";
+ case BT_HCI_EVT_LE_META_EVENT: return "LE_META_EVENT";
+ case BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP: return "AUTH_PAYLOAD_TIMEOUT_EXP";
+ default: return "";
+ }
+}
+
+STATIC const char* hci_evt_le_name(uint8_t evt_le) {
+ switch (evt_le) {
+ case BT_HCI_EVT_LE_CONN_COMPLETE: return "LE_CONN_COMPLETE";
+ case BT_HCI_EVT_LE_ADVERTISING_REPORT: return "LE_ADVERTISING_REPORT";
+ case BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE: return "LE_CONN_UPDATE_COMPLETE";
+ case BT_HCI_EVT_LE_LTK_REQUEST: return "LE_LTK_REQUEST";
+ case BT_HCI_EVT_LE_CONN_PARAM_REQ: return "LE_CONN_PARAM_REQ";
+ case BT_HCI_EVT_LE_DATA_LEN_CHANGE: return "LE_DATA_LEN_CHANGE";
+ case BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE: return "LE_P256_PUBLIC_KEY_COMPLETE";
+ case BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE: return "LE_GENERATE_DHKEY_COMPLETE";
+ case BT_HCI_EVT_LE_ENH_CONN_COMPLETE: return "LE_ENH_CONN_COMPLETE";
+ case BT_HCI_EVT_LE_DIRECT_ADV_REPORT: return "LE_DIRECT_ADV_REPORT";
+ case BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE: return "LE_PHY_UPDATE_COMPLETE";
+ case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT: return "LE_EXT_ADVERTISING_REPORT";
+ case BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED: return "LE_PER_ADV_SYNC_ESTABLISHED";
+ case BT_HCI_EVT_LE_PER_ADVERTISING_REPORT: return "LE_PER_ADVERTISING_REPORT";
+ case BT_HCI_EVT_LE_PER_ADV_SYNC_LOST: return "LE_PER_ADV_SYNC_LOST";
+ case BT_HCI_EVT_LE_SCAN_TIMEOUT: return "LE_SCAN_TIMEOUT";
+ case BT_HCI_EVT_LE_ADV_SET_TERMINATED: return "LE_ADV_SET_TERMINATED";
+ case BT_HCI_EVT_LE_SCAN_REQ_RECEIVED: return "LE_SCAN_REQ_RECEIVED";
+ case BT_HCI_EVT_LE_CHAN_SEL_ALGO: return "LE_CHAN_SEL_ALGO";
+ default: return "";
+ }
+}
+
+STATIC const char* hci_opcode_name(uint16_t opcode) {
+ switch (opcode) {
+ case BT_OP_NOP: return "NOP";
+ case BT_HCI_OP_INQUIRY: return "INQUIRY";
+ case BT_HCI_OP_INQUIRY_CANCEL: return "INQUIRY_CANCEL";
+ case BT_HCI_OP_CONNECT: return "CONNECT";
+ case BT_HCI_OP_DISCONNECT: return "DISCONNECT";
+ case BT_HCI_OP_CONNECT_CANCEL: return "CONNECT_CANCEL";
+ case BT_HCI_OP_ACCEPT_CONN_REQ: return "ACCEPT_CONN_REQ";
+ case BT_HCI_OP_SETUP_SYNC_CONN: return "SETUP_SYNC_CONN";
+ case BT_HCI_OP_ACCEPT_SYNC_CONN_REQ: return "ACCEPT_SYNC_CONN_REQ";
+ case BT_HCI_OP_REJECT_CONN_REQ: return "REJECT_CONN_REQ";
+ case BT_HCI_OP_LINK_KEY_REPLY: return "LINK_KEY_REPLY";
+ case BT_HCI_OP_LINK_KEY_NEG_REPLY: return "LINK_KEY_NEG_REPLY";
+ case BT_HCI_OP_PIN_CODE_REPLY: return "PIN_CODE_REPLY";
+ case BT_HCI_OP_PIN_CODE_NEG_REPLY: return "PIN_CODE_NEG_REPLY";
+ case BT_HCI_OP_AUTH_REQUESTED: return "AUTH_REQUESTED";
+ case BT_HCI_OP_SET_CONN_ENCRYPT: return "SET_CONN_ENCRYPT";
+ case BT_HCI_OP_REMOTE_NAME_REQUEST: return "REMOTE_NAME_REQUEST";
+ case BT_HCI_OP_REMOTE_NAME_CANCEL: return "REMOTE_NAME_CANCEL";
+ case BT_HCI_OP_READ_REMOTE_FEATURES: return "READ_REMOTE_FEATURES";
+ case BT_HCI_OP_READ_REMOTE_EXT_FEATURES: return "READ_REMOTE_EXT_FEATURES";
+ case BT_HCI_OP_READ_REMOTE_VERSION_INFO: return "READ_REMOTE_VERSION_INFO";
+ case BT_HCI_OP_IO_CAPABILITY_REPLY: return "IO_CAPABILITY_REPLY";
+ case BT_HCI_OP_USER_CONFIRM_REPLY: return "USER_CONFIRM_REPLY";
+ case BT_HCI_OP_USER_CONFIRM_NEG_REPLY: return "USER_CONFIRM_NEG_REPLY";
+ case BT_HCI_OP_USER_PASSKEY_REPLY: return "USER_PASSKEY_REPLY";
+ case BT_HCI_OP_USER_PASSKEY_NEG_REPLY: return "USER_PASSKEY_NEG_REPLY";
+ case BT_HCI_OP_IO_CAPABILITY_NEG_REPLY: return "IO_CAPABILITY_NEG_REPLY";
+ case BT_HCI_OP_SET_EVENT_MASK: return "SET_EVENT_MASK";
+ case BT_HCI_OP_RESET: return "RESET";
+ case BT_HCI_OP_WRITE_LOCAL_NAME: return "WRITE_LOCAL_NAME";
+ case BT_HCI_OP_WRITE_PAGE_TIMEOUT: return "WRITE_PAGE_TIMEOUT";
+ case BT_HCI_OP_WRITE_SCAN_ENABLE: return "WRITE_SCAN_ENABLE";
+ case BT_HCI_OP_READ_TX_POWER_LEVEL: return "READ_TX_POWER_LEVEL";
+ case BT_HCI_OP_SET_CTL_TO_HOST_FLOW: return "SET_CTL_TO_HOST_FLOW";
+ case BT_HCI_OP_HOST_BUFFER_SIZE: return "HOST_BUFFER_SIZE";
+ case BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS: return "HOST_NUM_COMPLETED_PACKETS";
+ case BT_HCI_OP_WRITE_INQUIRY_MODE: return "WRITE_INQUIRY_MODE";
+ case BT_HCI_OP_WRITE_SSP_MODE: return "WRITE_SSP_MODE";
+ case BT_HCI_OP_SET_EVENT_MASK_PAGE_2: return "SET_EVENT_MASK_PAGE_2";
+ case BT_HCI_OP_LE_WRITE_LE_HOST_SUPP: return "LE_WRITE_LE_HOST_SUPP";
+ case BT_HCI_OP_WRITE_SC_HOST_SUPP: return "WRITE_SC_HOST_SUPP";
+ case BT_HCI_OP_READ_AUTH_PAYLOAD_TIMEOUT: return "READ_AUTH_PAYLOAD_TIMEOUT";
+ case BT_HCI_OP_WRITE_AUTH_PAYLOAD_TIMEOUT: return "WRITE_AUTH_PAYLOAD_TIMEOUT";
+ case BT_HCI_OP_READ_LOCAL_VERSION_INFO: return "READ_LOCAL_VERSION_INFO";
+ case BT_HCI_OP_READ_SUPPORTED_COMMANDS: return "READ_SUPPORTED_COMMANDS";
+ case BT_HCI_OP_READ_LOCAL_EXT_FEATURES: return "READ_LOCAL_EXT_FEATURES";
+ case BT_HCI_OP_READ_LOCAL_FEATURES: return "READ_LOCAL_FEATURES";
+ case BT_HCI_OP_READ_BUFFER_SIZE: return "READ_BUFFER_SIZE";
+ case BT_HCI_OP_READ_BD_ADDR: return "READ_BD_ADDR";
+ case BT_HCI_OP_READ_RSSI: return "READ_RSSI";
+ case BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE: return "READ_ENCRYPTION_KEY_SIZE";
+ case BT_HCI_OP_LE_SET_EVENT_MASK: return "LE_SET_EVENT_MASK";
+ case BT_HCI_OP_LE_READ_BUFFER_SIZE: return "LE_READ_BUFFER_SIZE";
+ case BT_HCI_OP_LE_READ_LOCAL_FEATURES: return "LE_READ_LOCAL_FEATURES";
+ case BT_HCI_OP_LE_SET_RANDOM_ADDRESS: return "LE_SET_RANDOM_ADDRESS";
+ case BT_HCI_OP_LE_SET_ADV_PARAM: return "LE_SET_ADV_PARAM";
+ case BT_HCI_OP_LE_READ_ADV_CHAN_TX_POWER: return "LE_READ_ADV_CHAN_TX_POWER";
+ case BT_HCI_OP_LE_SET_ADV_DATA: return "LE_SET_ADV_DATA";
+ case BT_HCI_OP_LE_SET_SCAN_RSP_DATA: return "LE_SET_SCAN_RSP_DATA";
+ case BT_HCI_OP_LE_SET_ADV_ENABLE: return "LE_SET_ADV_ENABLE";
+ case BT_HCI_OP_LE_SET_SCAN_PARAM: return "LE_SET_SCAN_PARAM";
+ case BT_HCI_OP_LE_SET_SCAN_ENABLE: return "LE_SET_SCAN_ENABLE";
+ case BT_HCI_OP_LE_CREATE_CONN: return "LE_CREATE_CONN";
+ case BT_HCI_OP_LE_CREATE_CONN_CANCEL: return "LE_CREATE_CONN_CANCEL";
+ case BT_HCI_OP_LE_READ_WL_SIZE: return "LE_READ_WL_SIZE";
+ case BT_HCI_OP_LE_CLEAR_WL: return "LE_CLEAR_WL";
+ case BT_HCI_OP_LE_ADD_DEV_TO_WL: return "LE_ADD_DEV_TO_WL";
+ case BT_HCI_OP_LE_REM_DEV_FROM_WL: return "LE_REM_DEV_FROM_WL";
+ case BT_HCI_OP_LE_CONN_UPDATE: return "LE_CONN_UPDATE";
+ case BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF: return "LE_SET_HOST_CHAN_CLASSIF";
+ case BT_HCI_OP_LE_READ_CHAN_MAP: return "LE_READ_CHAN_MAP";
+ case BT_HCI_OP_LE_READ_REMOTE_FEATURES: return "LE_READ_REMOTE_FEATURES";
+ case BT_HCI_OP_LE_ENCRYPT: return "LE_ENCRYPT";
+ case BT_HCI_OP_LE_RAND: return "LE_RAND";
+ case BT_HCI_OP_LE_START_ENCRYPTION: return "LE_START_ENCRYPTION";
+ case BT_HCI_OP_LE_LTK_REQ_REPLY: return "LE_LTK_REQ_REPLY";
+ case BT_HCI_OP_LE_LTK_REQ_NEG_REPLY: return "LE_LTK_REQ_NEG_REPLY";
+ case BT_HCI_OP_LE_READ_SUPP_STATES: return "LE_READ_SUPP_STATES";
+ case BT_HCI_OP_LE_RX_TEST: return "LE_RX_TEST";
+ case BT_HCI_OP_LE_TX_TEST: return "LE_TX_TEST";
+ case BT_HCI_OP_LE_TEST_END: return "LE_TEST_END";
+ case BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY: return "LE_CONN_PARAM_REQ_REPLY";
+ case BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY: return "LE_CONN_PARAM_REQ_NEG_REPLY";
+ case BT_HCI_OP_LE_SET_DATA_LEN: return "LE_SET_DATA_LEN";
+ case BT_HCI_OP_LE_READ_DEFAULT_DATA_LEN: return "LE_READ_DEFAULT_DATA_LEN";
+ case BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN: return "LE_WRITE_DEFAULT_DATA_LEN";
+ case BT_HCI_OP_LE_P256_PUBLIC_KEY: return "LE_P256_PUBLIC_KEY";
+ case BT_HCI_OP_LE_GENERATE_DHKEY: return "LE_GENERATE_DHKEY";
+ case BT_HCI_OP_LE_ADD_DEV_TO_RL: return "LE_ADD_DEV_TO_RL";
+ case BT_HCI_OP_LE_REM_DEV_FROM_RL: return "LE_REM_DEV_FROM_RL";
+ case BT_HCI_OP_LE_CLEAR_RL: return "LE_CLEAR_RL";
+ case BT_HCI_OP_LE_READ_RL_SIZE: return "LE_READ_RL_SIZE";
+ case BT_HCI_OP_LE_READ_PEER_RPA: return "LE_READ_PEER_RPA";
+ case BT_HCI_OP_LE_READ_LOCAL_RPA: return "LE_READ_LOCAL_RPA";
+ case BT_HCI_OP_LE_SET_ADDR_RES_ENABLE: return "LE_SET_ADDR_RES_ENABLE";
+ case BT_HCI_OP_LE_SET_RPA_TIMEOUT: return "LE_SET_RPA_TIMEOUT";
+ case BT_HCI_OP_LE_READ_MAX_DATA_LEN: return "LE_READ_MAX_DATA_LEN";
+ case BT_HCI_OP_LE_READ_PHY: return "LE_READ_PHY";
+ case BT_HCI_OP_LE_SET_DEFAULT_PHY: return "LE_SET_DEFAULT_PHY";
+ case BT_HCI_OP_LE_SET_PHY: return "LE_SET_PHY";
+ case BT_HCI_OP_LE_ENH_RX_TEST: return "LE_ENH_RX_TEST";
+ case BT_HCI_OP_LE_ENH_TX_TEST: return "LE_ENH_TX_TEST";
+ case BT_HCI_OP_LE_SET_ADV_SET_RANDOM_ADDR: return "LE_SET_ADV_SET_RANDOM_ADDR";
+ case BT_HCI_OP_LE_SET_EXT_ADV_PARAM: return "LE_SET_EXT_ADV_PARAM";
+ case BT_HCI_OP_LE_SET_EXT_ADV_DATA: return "LE_SET_EXT_ADV_DATA";
+ case BT_HCI_OP_LE_SET_EXT_SCAN_RSP_DATA: return "LE_SET_EXT_SCAN_RSP_DATA";
+ case BT_HCI_OP_LE_SET_EXT_ADV_ENABLE: return "LE_SET_EXT_ADV_ENABLE";
+ case BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN: return "LE_READ_MAX_ADV_DATA_LEN";
+ case BT_HCI_OP_LE_READ_NUM_ADV_SETS: return "LE_READ_NUM_ADV_SETS";
+ case BT_HCI_OP_LE_REMOVE_ADV_SET: return "LE_REMOVE_ADV_SET";
+ case BT_HCI_OP_CLEAR_ADV_SETS: return "CLEAR_ADV_SETS";
+ case BT_HCI_OP_LE_SET_PER_ADV_PARAM: return "LE_SET_PER_ADV_PARAM";
+ case BT_HCI_OP_LE_SET_PER_ADV_DATA: return "LE_SET_PER_ADV_DATA";
+ case BT_HCI_OP_LE_SET_PER_ADV_ENABLE: return "LE_SET_PER_ADV_ENABLE";
+ case BT_HCI_OP_LE_SET_EXT_SCAN_PARAM: return "LE_SET_EXT_SCAN_PARAM";
+ case BT_HCI_OP_LE_SET_EXT_SCAN_ENABLE: return "LE_SET_EXT_SCAN_ENABLE";
+ case BT_HCI_OP_LE_EXT_CREATE_CONN: return "LE_EXT_CREATE_CONN";
+ case BT_HCI_OP_LE_PER_ADV_CREATE_SYNC: return "LE_PER_ADV_CREATE_SYNC";
+ case BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL: return "LE_PER_ADV_CREATE_SYNC_CANCEL";
+ case BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC: return "LE_PER_ADV_TERMINATE_SYNC";
+ case BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST: return "LE_ADD_DEV_TO_PER_ADV_LIST";
+ case BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST: return "LE_REM_DEV_FROM_PER_ADV_LIST";
+ case BT_HCI_OP_LE_CLEAR_PER_ADV_LIST: return "LE_CLEAR_PER_ADV_LIST";
+ case BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE: return "LE_READ_PER_ADV_LIST_SIZE";
+ case BT_HCI_OP_LE_READ_TX_POWER: return "LE_READ_TX_POWER";
+ case BT_HCI_OP_LE_READ_RF_PATH_COMP: return "LE_READ_RF_PATH_COMP";
+ case BT_HCI_OP_LE_WRITE_RF_PATH_COMP: return "LE_WRITE_RF_PATH_COMP";
+ case BT_HCI_OP_LE_SET_PRIVACY_MODE: return "LE_SET_PRIVACY_MODE";
+ default: return "";
+ }
+}
+
+
+STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
+ h4_hci_cmd_pkt_t *pkt = (h4_hci_cmd_pkt_t *) pkt_data;
+ mp_printf(&mp_plat_print,
+ "%s HCI COMMAND (%x) op: %s (%04x), len: %d, data: ",
+ tx ? "TX->" : "RX<-",
+ pkt->pkt_type,
+ hci_opcode_name(pkt->opcode), pkt->opcode, pkt->param_len);
+ for (size_t i = 0; i < pkt->param_len; i++) {
+ mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
+ }
+ if (pkt_len != sizeof(h4_hci_cmd_pkt_t) + pkt->param_len) {
+ mp_printf(&mp_plat_print, " LENGTH MISMATCH, pkt_len: %d", pkt_len);
+ }
+ mp_printf(&mp_plat_print, "\n");
+}
+
+STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
+ h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t *) pkt_data;
+ acl_data_t *acl = (acl_data_t *) pkt->data;
+
+ mp_printf(&mp_plat_print,
+ "%s HCI ACLDATA (%x) ",
+ tx ? "TX->" : "RX<-", pkt->pkt_type);
+
+ if (pkt->pb != ACL_DATA_PB_MIDDLE && acl->cid == BT_L2CAP_CID_ATT) {
+ // This is the start of a fragmented acl_data packet or is a full packet,
+ // and is an ATT protocol packet.
+ mp_printf(&mp_plat_print, "att: %s (%02x), ", att_opcode_name(acl->acl_data[0]), acl->acl_data[0]);
+ }
+
+ mp_printf(&mp_plat_print,
+ "handle: %04x, pb: %d, bc: %d, data_len: %d, ",
+ pkt->handle, pkt->pb, pkt->bc, pkt->data_len);
+
+ if (pkt->pb != ACL_DATA_PB_MIDDLE) {
+ // This is the start of a fragmented acl_data packet or is a full packet.
+ mp_printf(&mp_plat_print,
+ "acl data_len: %d, cid: %04x, data: ",
+ acl->acl_data_len, acl->cid);
+ for (size_t i = 0; i < acl->acl_data_len; i++) {
+ mp_printf(&mp_plat_print, "%02x ", acl->acl_data[i]);
+ }
+ } else {
+ for (size_t i = 0; i < pkt->data_len; i++) {
+ mp_printf(&mp_plat_print, "more data: %02x ", pkt->data[i]);
+ }
+ }
+
+ if (pkt_len != sizeof(h4_hci_acl_pkt_t) + pkt->data_len) {
+ mp_printf(&mp_plat_print, " LENGTH MISMATCH, pkt_len: %d", pkt_len);
+ }
+ mp_printf(&mp_plat_print, "\n");
+}
+
+STATIC void dump_evt_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
+ h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t *) pkt_data;
+ mp_printf(&mp_plat_print,
+ "%s HCI EVENT (%x) evt: %s (%02x), param_len: %d, data: ",
+ tx ? "TX->" : "RX<-",
+ pkt->pkt_type,
+ pkt->evt == BT_HCI_EVT_LE_META_EVENT
+ ? hci_evt_le_name(pkt->params[0])
+ : hci_evt_name(pkt->evt),
+ pkt->evt, pkt->param_len);
+ for (size_t i = 0; i < pkt->param_len; i++) {
+ mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
+ }
+ if (pkt_len != sizeof(h4_hci_evt_pkt_t) + pkt->param_len) {
+ mp_printf(&mp_plat_print, " LENGTH MISMATCH, pkt_len: %d", pkt_len);
+ }
+ mp_printf(&mp_plat_print, "\n");
+}
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/NOTE.txt b/devices/ble_hci/common-hal/_bleio/hci_include/NOTE.txt
new file mode 100644
index 000000000..ac34c815c
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/NOTE.txt
@@ -0,0 +1,2 @@
+The HCI-related include files here were copied from the Zephyr project, from this commit:
+https://github.com/zephyrproject-rtos/zephyr/tree/0a87f9359edf1ec1c169626df3e19c2b4a4e9646/include/bluetooth
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/addr.h b/devices/ble_hci/common-hal/_bleio/hci_include/addr.h
new file mode 100644
index 000000000..fd74a95e8
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/addr.h
@@ -0,0 +1,101 @@
+// CircuitPython: Adapted from Zephyer include files.
+/** @file
+ * @brief Bluetooth device address definitions and utilities.
+ */
+
+/*
+ * Copyright (c) 2019 Nordic Semiconductor ASA
+ * Copyright 2020 Dan Halbert for Adafruit Industries
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef ZEPHYR_INCLUDE_BLUETOOTH_ADDR_H_
+#define ZEPHYR_INCLUDE_BLUETOOTH_ADDR_H_
+
+#include <stdbool.h>
+#include <string.h>
+
+/**
+ * @brief Bluetooth device address definitions and utilities.
+ * @defgroup bt_addr Device Address
+ * @ingroup bluetooth
+ * @{
+ */
+
+#define BT_ADDR_LE_PUBLIC 0x00
+#define BT_ADDR_LE_RANDOM 0x01
+#define BT_ADDR_LE_PUBLIC_ID 0x02
+#define BT_ADDR_LE_RANDOM_ID 0x03
+
+/** Bluetooth Device Address */
+typedef struct {
+ uint8_t val[6];
+} bt_addr_t;
+
+/** Bluetooth LE Device Address */
+typedef struct {
+ uint8_t type;
+ bt_addr_t a;
+} bt_addr_le_t;
+
+#define BT_ADDR_ANY ((bt_addr_t[]) { { { 0, 0, 0, 0, 0, 0 } } })
+#define BT_ADDR_NONE ((bt_addr_t[]) { { \
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } })
+#define BT_ADDR_LE_ANY ((bt_addr_le_t[]) { { 0, { { 0, 0, 0, 0, 0, 0 } } } })
+#define BT_ADDR_LE_NONE ((bt_addr_le_t[]) { { 0, \
+ { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } } })
+
+static inline int bt_addr_cmp(const bt_addr_t *a, const bt_addr_t *b)
+{
+ return memcmp(a, b, sizeof(*a));
+}
+
+static inline int bt_addr_le_cmp(const bt_addr_le_t *a, const bt_addr_le_t *b)
+{
+ return memcmp(a, b, sizeof(*a));
+}
+
+static inline void bt_addr_copy(bt_addr_t *dst, const bt_addr_t *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+}
+
+static inline void bt_addr_le_copy(bt_addr_le_t *dst, const bt_addr_le_t *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+}
+
+#define BT_ADDR_IS_RPA(a) (((a)->val[5] & 0xc0) == 0x40)
+#define BT_ADDR_IS_NRPA(a) (((a)->val[5] & 0xc0) == 0x00)
+#define BT_ADDR_IS_STATIC(a) (((a)->val[5] & 0xc0) == 0xc0)
+
+#define BT_ADDR_SET_RPA(a) ((a)->val[5] = (((a)->val[5] & 0x3f) | 0x40))
+#define BT_ADDR_SET_NRPA(a) ((a)->val[5] &= 0x3f)
+#define BT_ADDR_SET_STATIC(a) ((a)->val[5] |= 0xc0)
+
+int bt_addr_le_create_nrpa(bt_addr_le_t *addr);
+int bt_addr_le_create_static(bt_addr_le_t *addr);
+
+static inline bool bt_addr_le_is_rpa(const bt_addr_le_t *addr)
+{
+ if (addr->type != BT_ADDR_LE_RANDOM) {
+ return false;
+ }
+
+ return BT_ADDR_IS_RPA(&addr->a);
+}
+
+static inline bool bt_addr_le_is_identity(const bt_addr_le_t *addr)
+{
+ if (addr->type == BT_ADDR_LE_PUBLIC) {
+ return true;
+ }
+
+ return BT_ADDR_IS_STATIC(&addr->a);
+}
+
+/**
+ * @}
+ */
+
+#endif /* ZEPHYR_INCLUDE_BLUETOOTH_ADDR_H_ */
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/att.h b/devices/ble_hci/common-hal/_bleio/hci_include/att.h
new file mode 100644
index 000000000..8117a48f4
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/att.h
@@ -0,0 +1,41 @@
+// CircuitPython: Adapted from Zephyr include file.
+/** @file
+ * @brief Attribute Protocol handling.
+ */
+
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef ZEPHYR_INCLUDE_BLUETOOTH_ATT_H_
+#define ZEPHYR_INCLUDE_BLUETOOTH_ATT_H_
+
+/* Error codes for Error response PDU */
+#define BT_ATT_ERR_INVALID_HANDLE 0x01
+#define BT_ATT_ERR_READ_NOT_PERMITTED 0x02
+#define BT_ATT_ERR_WRITE_NOT_PERMITTED 0x03
+#define BT_ATT_ERR_INVALID_PDU 0x04
+#define BT_ATT_ERR_AUTHENTICATION 0x05
+#define BT_ATT_ERR_NOT_SUPPORTED 0x06
+#define BT_ATT_ERR_INVALID_OFFSET 0x07
+#define BT_ATT_ERR_AUTHORIZATION 0x08
+#define BT_ATT_ERR_PREPARE_QUEUE_FULL 0x09
+#define BT_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0a
+#define BT_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0b
+#define BT_ATT_ERR_ENCRYPTION_KEY_SIZE 0x0c
+#define BT_ATT_ERR_INVALID_ATTRIBUTE_LEN 0x0d
+#define BT_ATT_ERR_UNLIKELY 0x0e
+#define BT_ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f
+#define BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10
+#define BT_ATT_ERR_INSUFFICIENT_RESOURCES 0x11
+#define BT_ATT_ERR_DB_OUT_OF_SYNC 0x12
+#define BT_ATT_ERR_VALUE_NOT_ALLOWED 0x13
+
+/* Common Profile Error Codes (from CSS) */
+#define BT_ATT_ERR_WRITE_REQ_REJECTED 0xfc
+#define BT_ATT_ERR_CCC_IMPROPER_CONF 0xfd
+#define BT_ATT_ERR_PROCEDURE_IN_PROGRESS 0xfe
+#define BT_ATT_ERR_OUT_OF_RANGE 0xff
+
+#endif /* ZEPHYR_INCLUDE_BLUETOOTH_ATT_H_ */
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/att_internal.h b/devices/ble_hci/common-hal/_bleio/hci_include/att_internal.h
new file mode 100644
index 000000000..1c75275da
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/att_internal.h
@@ -0,0 +1,266 @@
+// CircuitPython: Adapted from Zephyr include file.
+
+/* att_internal.h - Attribute protocol handling */
+
+/*
+ * Copyright (c) 2015-2016 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+#include <stdbool.h>
+// for __packed
+#include <string.h>
+
+#define BT_EATT_PSM 0x27
+#define BT_ATT_DEFAULT_LE_MTU 23
+#define BT_ATT_TIMEOUT K_SECONDS(30)
+
+//FIX #if BT_L2CAP_RX_MTU < CONFIG_BT_L2CAP_TX_MTU
+// #define BT_ATT_MTU BT_L2CAP_RX_MTU
+// #else
+// #define BT_ATT_MTU CONFIG_BT_L2CAP_TX_MTU
+// #endif
+
+struct bt_att_hdr {
+ uint8_t code;
+} __packed;
+
+#define BT_ATT_OP_ERROR_RSP 0x01
+struct bt_att_error_rsp {
+ uint8_t request;
+ uint16_t handle;
+ uint8_t error;
+} __packed;
+
+#define BT_ATT_OP_MTU_REQ 0x02
+struct bt_att_exchange_mtu_req {
+ uint16_t mtu;
+} __packed;
+
+#define BT_ATT_OP_MTU_RSP 0x03
+struct bt_att_exchange_mtu_rsp {
+ uint16_t mtu;
+} __packed;
+
+/* Find Information Request */
+#define BT_ATT_OP_FIND_INFO_REQ 0x04
+struct bt_att_find_info_req {
+ uint16_t start_handle;
+ uint16_t end_handle;
+} __packed;
+
+/* Format field values for BT_ATT_OP_FIND_INFO_RSP */
+#define BT_ATT_INFO_16 0x01
+#define BT_ATT_INFO_128 0x02
+
+struct bt_att_info_16 {
+ uint16_t handle;
+ uint16_t uuid;
+} __packed;
+
+struct bt_att_info_128 {
+ uint16_t handle;
+ uint8_t uuid[16];
+} __packed;
+
+/* Find Information Response */
+#define BT_ATT_OP_FIND_INFO_RSP 0x05
+struct bt_att_find_info_rsp {
+ uint8_t format;
+ uint8_t info[0];
+} __packed;
+
+/* Find By Type Value Request */
+#define BT_ATT_OP_FIND_TYPE_REQ 0x06
+struct bt_att_find_type_req {
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint16_t type;
+ uint8_t value[0];
+} __packed;
+
+struct bt_att_handle_group {
+ uint16_t start_handle;
+ uint16_t end_handle;
+} __packed;
+
+/* Find By Type Value Response */
+#define BT_ATT_OP_FIND_TYPE_RSP 0x07
+struct bt_att_find_type_rsp {
+ struct bt_att_handle_group list[0];
+} __packed;
+
+/* Read By Type Request */
+#define BT_ATT_OP_READ_TYPE_REQ 0x08
+struct bt_att_read_type_req {
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t uuid[0];
+} __packed;
+
+struct bt_att_data {
+ uint16_t handle;
+ uint8_t value[0];
+} __packed;
+
+/* Read By Type Response */
+#define BT_ATT_OP_READ_TYPE_RSP 0x09
+struct bt_att_read_type_rsp {
+ uint8_t len;
+ struct bt_att_data data[0];
+} __packed;
+
+/* Read Request */
+#define BT_ATT_OP_READ_REQ 0x0a
+struct bt_att_read_req {
+ uint16_t handle;
+} __packed;
+
+/* Read Response */
+#define BT_ATT_OP_READ_RSP 0x0b
+struct bt_att_read_rsp {
+ uint8_t value[0];
+} __packed;
+
+/* Read Blob Request */
+#define BT_ATT_OP_READ_BLOB_REQ 0x0c
+struct bt_att_read_blob_req {
+ uint16_t handle;
+ uint16_t offset;
+} __packed;
+
+/* Read Blob Response */
+#define BT_ATT_OP_READ_BLOB_RSP 0x0d
+struct bt_att_read_blob_rsp {
+ uint8_t value[0];
+} __packed;
+
+/* Read Multiple Request */
+#define BT_ATT_READ_MULT_MIN_LEN_REQ 0x04
+
+#define BT_ATT_OP_READ_MULT_REQ 0x0e
+struct bt_att_read_mult_req {
+ uint16_t handles[0];
+} __packed;
+
+/* Read Multiple Respose */
+#define BT_ATT_OP_READ_MULT_RSP 0x0f
+struct bt_att_read_mult_rsp {
+ uint8_t value[0];
+} __packed;
+
+/* Read by Group Type Request */
+#define BT_ATT_OP_READ_GROUP_REQ 0x10
+struct bt_att_read_group_req {
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t uuid[0];
+} __packed;
+
+struct bt_att_group_data {
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t value[0];
+} __packed;
+
+/* Read by Group Type Response */
+#define BT_ATT_OP_READ_GROUP_RSP 0x11
+struct bt_att_read_group_rsp {
+ uint8_t len;
+ struct bt_att_group_data data[0];
+} __packed;
+
+/* Write Request */
+#define BT_ATT_OP_WRITE_REQ 0x12
+struct bt_att_write_req {
+ uint16_t handle;
+ uint8_t value[0];
+} __packed;
+
+/* Write Response */
+#define BT_ATT_OP_WRITE_RSP 0x13
+
+/* Prepare Write Request */
+#define BT_ATT_OP_PREPARE_WRITE_REQ 0x16
+struct bt_att_prepare_write_req {
+ uint16_t handle;
+ uint16_t offset;
+ uint8_t value[0];
+} __packed;
+
+/* Prepare Write Respond */
+#define BT_ATT_OP_PREPARE_WRITE_RSP 0x17
+struct bt_att_prepare_write_rsp {
+ uint16_t handle;
+ uint16_t offset;
+ uint8_t value[0];
+} __packed;
+
+/* Execute Write Request */
+#define BT_ATT_FLAG_CANCEL 0x00
+#define BT_ATT_FLAG_EXEC 0x01
+
+#define BT_ATT_OP_EXEC_WRITE_REQ 0x18
+struct bt_att_exec_write_req {
+ uint8_t flags;
+} __packed;
+
+/* Execute Write Response */
+#define BT_ATT_OP_EXEC_WRITE_RSP 0x19
+
+/* Handle Value Notification */
+#define BT_ATT_OP_NOTIFY 0x1b
+struct bt_att_notify {
+ uint16_t handle;
+ uint8_t value[0];
+} __packed;
+
+/* Handle Value Indication */
+#define BT_ATT_OP_INDICATE 0x1d
+struct bt_att_indicate {
+ uint16_t handle;
+ uint8_t value[0];
+} __packed;
+
+/* Handle Value Confirm */
+#define BT_ATT_OP_CONFIRM 0x1e
+
+struct bt_att_signature {
+ uint8_t value[12];
+} __packed;
+
+#define BT_ATT_OP_READ_MULT_VL_REQ 0x20
+struct bt_att_read_mult_vl_req {
+ uint16_t handles[0];
+} __packed;
+
+/* Read Multiple Respose */
+#define BT_ATT_OP_READ_MULT_VL_RSP 0x21
+struct bt_att_read_mult_vl_rsp {
+ uint16_t len;
+ uint8_t value[0];
+} __packed;
+
+/* Handle Multiple Value Notification */
+#define BT_ATT_OP_NOTIFY_MULT 0x23
+struct bt_att_notify_mult {
+ uint16_t handle;
+ uint16_t len;
+ uint8_t value[0];
+} __packed;
+
+/* Write Command */
+#define BT_ATT_OP_WRITE_CMD 0x52
+struct bt_att_write_cmd {
+ uint16_t handle;
+ uint8_t value[0];
+} __packed;
+
+/* Signed Write Command */
+#define BT_ATT_OP_SIGNED_WRITE_CMD 0xd2
+struct bt_att_signed_write_cmd {
+ uint16_t handle;
+ uint8_t value[0];
+} __packed;
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/hci.h b/devices/ble_hci/common-hal/_bleio/hci_include/hci.h
new file mode 100644
index 000000000..6c3a2b5bd
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/hci.h
@@ -0,0 +1,1767 @@
+// CircuitPython: Adapted from Zephyr include file.
+
+/* hci.h - Bluetooth Host Control Interface definitions */
+
+/*
+ * Copyright 2020 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2015-2016 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef ZEPHYR_INCLUDE_BLUETOOTH_HCI_H_
+#define ZEPHYR_INCLUDE_BLUETOOTH_HCI_H_
+
+#include <stdbool.h>
+#include <string.h>
+#include "addr.h"
+
+#define BIT(n) (1UL << (n))
+
+/* Special own address types for LL privacy (used in adv & scan parameters) */
+#define BT_HCI_OWN_ADDR_RPA_OR_PUBLIC 0x02
+#define BT_HCI_OWN_ADDR_RPA_OR_RANDOM 0x03
+#define BT_HCI_OWN_ADDR_RPA_MASK 0x02
+
+#define BT_HCI_PEER_ADDR_RPA_UNRESOLVED 0xfe
+#define BT_HCI_PEER_ADDR_ANONYMOUS 0xff
+
+#define BT_ENC_KEY_SIZE_MIN 0x07
+#define BT_ENC_KEY_SIZE_MAX 0x10
+
+struct bt_hci_evt_hdr {
+ uint8_t evt;
+ uint8_t len;
+} __packed;
+#define BT_HCI_EVT_HDR_SIZE 2
+
+#define BT_ACL_START_NO_FLUSH 0x00
+#define BT_ACL_CONT 0x01
+#define BT_ACL_START 0x02
+#define BT_ACL_COMPLETE 0x03
+
+#define BT_ACL_POINT_TO_POINT 0x00
+#define BT_ACL_BROADCAST 0x01
+
+#define bt_acl_handle(h) ((h) & BIT_MASK(12))
+#define bt_acl_flags(h) ((h) >> 12)
+#define bt_acl_flags_pb(f) ((f) & BIT_MASK(2))
+#define bt_acl_flags_bc(f) ((f) >> 2)
+#define bt_acl_handle_pack(h, f) ((h) | ((f) << 12))
+
+struct bt_hci_acl_hdr {
+ uint16_t handle;
+ uint16_t len;
+} __packed;
+#define BT_HCI_ACL_HDR_SIZE 4
+
+struct bt_hci_cmd_hdr {
+ uint16_t opcode;
+ uint8_t param_len;
+} __packed;
+#define BT_HCI_CMD_HDR_SIZE 3
+
+/* Supported Commands */
+#define BT_CMD_TEST(cmd, octet, bit) (cmd[octet] & BIT(bit))
+#define BT_CMD_LE_STATES(cmd) BT_CMD_TEST(cmd, 28, 3)
+
+#define BT_FEAT_TEST(feat, page, octet, bit) (feat[page][octet] & BIT(bit))
+
+#define BT_FEAT_BREDR(feat) !BT_FEAT_TEST(feat, 0, 4, 5)
+#define BT_FEAT_LE(feat) BT_FEAT_TEST(feat, 0, 4, 6)
+#define BT_FEAT_EXT_FEATURES(feat) BT_FEAT_TEST(feat, 0, 7, 7)
+#define BT_FEAT_HOST_SSP(feat) BT_FEAT_TEST(feat, 1, 0, 0)
+#define BT_FEAT_SC(feat) BT_FEAT_TEST(feat, 2, 1, 0)
+
+#define BT_FEAT_LMP_ESCO_CAPABLE(feat) BT_FEAT_TEST(feat, 0, 3, 7)
+#define BT_FEAT_HV2_PKT(feat) BT_FEAT_TEST(feat, 0, 1, 4)
+#define BT_FEAT_HV3_PKT(feat) BT_FEAT_TEST(feat, 0, 1, 5)
+#define BT_FEAT_EV4_PKT(feat) BT_FEAT_TEST(feat, 0, 4, 0)
+#define BT_FEAT_EV5_PKT(feat) BT_FEAT_TEST(feat, 0, 4, 1)
+#define BT_FEAT_2EV3_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 5)
+#define BT_FEAT_3EV3_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 6)
+#define BT_FEAT_3SLOT_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 7)
+
+/* LE features */
+#define BT_LE_FEAT_BIT_ENC 0
+#define BT_LE_FEAT_BIT_CONN_PARAM_REQ 1
+#define BT_LE_FEAT_BIT_EXT_REJ_IND 2
+#define BT_LE_FEAT_BIT_SLAVE_FEAT_REQ 3
+#define BT_LE_FEAT_BIT_PING 4
+#define BT_LE_FEAT_BIT_DLE 5
+#define BT_LE_FEAT_BIT_PRIVACY 6
+#define BT_LE_FEAT_BIT_EXT_SCAN 7
+#define BT_LE_FEAT_BIT_PHY_2M 8
+#define BT_LE_FEAT_BIT_SMI_TX 9
+#define BT_LE_FEAT_BIT_SMI_RX 10
+#define BT_LE_FEAT_BIT_PHY_CODED 11
+#define BT_LE_FEAT_BIT_EXT_ADV 12
+#define BT_LE_FEAT_BIT_PER_ADV 13
+#define BT_LE_FEAT_BIT_CHAN_SEL_ALGO_2 14
+#define BT_LE_FEAT_BIT_PWR_CLASS_1 15
+#define BT_LE_FEAT_BIT_MIN_USED_CHAN_PROC 16
+#define BT_LE_FEAT_BIT_CONN_CTE_REQ 17
+#define BT_LE_FEAT_BIT_CONN_CTE_RESP 18
+#define BT_LE_FEAT_BIT_CONNECTIONLESS_CTE_TX 19
+#define BT_LE_FEAT_BIT_CONNECTIONLESS_CTE_RX 20
+#define BT_LE_FEAT_BIT_ANT_SWITCH_TX_AOD 21
+#define BT_LE_FEAT_BIT_ANT_SWITCH_RX_AOA 22
+#define BT_LE_FEAT_BIT_RX_CTE 23
+#define BT_LE_FEAT_BIT_PERIODIC_SYNC_XFER_SEND 24
+#define BT_LE_FEAT_BIT_PERIODIC_SYNC_XFER_RECV 25
+#define BT_LE_FEAT_BIT_SCA_UPDATE 26
+#define BT_LE_FEAT_BIT_REMOTE_PUB_KEY_VALIDATE 27
+#define BT_LE_FEAT_BIT_CIS_MASTER 28
+#define BT_LE_FEAT_BIT_CIS_SLAVE 29
+#define BT_LE_FEAT_BIT_ISO_BROADCASTER 30
+#define BT_LE_FEAT_BIT_SYNC_RECEIVER 31
+#define BT_LE_FEAT_BIT_ISO_CHANNELS 32
+#define BT_LE_FEAT_BIT_PWR_CTRL_REQ 33
+#define BT_LE_FEAT_BIT_PWR_CHG_IND 34
+#define BT_LE_FEAT_BIT_PATH_LOSS_MONITOR 35
+
+#define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \
+ BIT((n) & 7))
+
+#define BT_FEAT_LE_ENCR(feat) BT_LE_FEAT_TEST(feat, \
+ BT_LE_FEAT_BIT_ENC)
+#define BT_FEAT_LE_CONN_PARAM_REQ_PROC(feat) BT_LE_FEAT_TEST(feat, \
+ BT_LE_FEAT_BIT_CONN_PARAM_REQ)
+#define BT_FEAT_LE_SLAVE_FEATURE_XCHG(feat) BT_LE_FEAT_TEST(feat, \
+ BT_LE_FEAT_BIT_SLAVE_FEAT_REQ)
+#define BT_FEAT_LE_DLE(feat) BT_LE_FEAT_TEST(feat, \
+ BT_LE_FEAT_BIT_DLE)
+#define BT_FEAT_LE_PHY_2M(feat) BT_LE_FEAT_TEST(feat, \
+ BT_LE_FEAT_BIT_PHY_2M)
+#define BT_FEAT_LE_PHY_CODED(feat) BT_LE_FEAT_TEST(feat, \
+ BT_LE_FEAT_BIT_PHY_CODED)
+#define BT_FEAT_LE_PRIVACY(feat) BT_LE_FEAT_TEST(feat, \
+ BT_LE_FEAT_BIT_PRIVACY)
+#define BT_FEAT_LE_EXT_ADV(feat) BT_LE_FEAT_TEST(feat, \
+ BT_LE_FEAT_BIT_EXT_ADV)
+
+/* LE States */
+#define BT_LE_STATES_SLAVE_CONN_ADV(states) (states & 0x0000004000000000)
+
+/* Bonding/authentication types */
+#define BT_HCI_NO_BONDING 0x00
+#define BT_HCI_NO_BONDING_MITM 0x01
+#define BT_HCI_DEDICATED_BONDING 0x02
+#define BT_HCI_DEDICATED_BONDING_MITM 0x03
+#define BT_HCI_GENERAL_BONDING 0x04
+#define BT_HCI_GENERAL_BONDING_MITM 0x05
+
+/*
+ * MITM protection is enabled in SSP authentication requirements octet when
+ * LSB bit is set.
+ */
+#define BT_MITM 0x01
+
+/* I/O capabilities */
+#define BT_IO_DISPLAY_ONLY 0x00
+#define BT_IO_DISPLAY_YESNO 0x01
+#define BT_IO_KEYBOARD_ONLY 0x02
+#define BT_IO_NO_INPUT_OUTPUT 0x03
+
+/* SCO packet types */
+#define HCI_PKT_TYPE_HV1 0x0020
+#define HCI_PKT_TYPE_HV2 0x0040
+#define HCI_PKT_TYPE_HV3 0x0080
+
+/* eSCO packet types */
+#define HCI_PKT_TYPE_ESCO_HV1 0x0001
+#define HCI_PKT_TYPE_ESCO_HV2 0x0002
+#define HCI_PKT_TYPE_ESCO_HV3 0x0004
+#define HCI_PKT_TYPE_ESCO_EV3 0x0008
+#define HCI_PKT_TYPE_ESCO_EV4 0x0010
+#define HCI_PKT_TYPE_ESCO_EV5 0x0020
+#define HCI_PKT_TYPE_ESCO_2EV3 0x0040
+#define HCI_PKT_TYPE_ESCO_3EV3 0x0080
+#define HCI_PKT_TYPE_ESCO_2EV5 0x0100
+#define HCI_PKT_TYPE_ESCO_3EV5 0x0200
+
+
+#define ESCO_PKT_MASK (HCI_PKT_TYPE_ESCO_HV1 | \
+ HCI_PKT_TYPE_ESCO_HV2 | \
+ HCI_PKT_TYPE_ESCO_HV3)
+#define SCO_PKT_MASK (HCI_PKT_TYPE_HV1 | \
+ HCI_PKT_TYPE_HV2 | \
+ HCI_PKT_TYPE_HV3)
+#define EDR_ESCO_PKT_MASK (HCI_PKT_TYPE_ESCO_2EV3 | \
+ HCI_PKT_TYPE_ESCO_3EV3 | \
+ HCI_PKT_TYPE_ESCO_2EV5 | \
+ HCI_PKT_TYPE_ESCO_3EV5)
+
+/* HCI BR/EDR link types */
+#define BT_HCI_SCO 0x00
+#define BT_HCI_ACL 0x01
+#define BT_HCI_ESCO 0x02
+
+/* OpCode Group Fields */
+#define BT_OGF_LINK_CTRL 0x01
+#define BT_OGF_BASEBAND 0x03
+#define BT_OGF_INFO 0x04
+#define BT_OGF_STATUS 0x05
+#define BT_OGF_LE 0x08
+#define BT_OGF_VS 0x3f
+
+/* Construct OpCode from OGF and OCF */
+#define BT_OP(ogf, ocf) ((ocf) | ((ogf) << 10))
+
+/* Invalid opcode */
+#define BT_OP_NOP 0x0000
+
+/* Obtain OGF from OpCode */
+#define BT_OGF(opcode) (((opcode) >> 10) & BIT_MASK(6))
+/* Obtain OCF from OpCode */
+#define BT_OCF(opcode) ((opcode) & BIT_MASK(10))
+
+#define BT_HCI_OP_INQUIRY BT_OP(BT_OGF_LINK_CTRL, 0x0001)
+struct bt_hci_op_inquiry {
+ uint8_t lap[3];
+ uint8_t length;
+ uint8_t num_rsp;
+} __packed;
+
+#define BT_HCI_OP_INQUIRY_CANCEL BT_OP(BT_OGF_LINK_CTRL, 0x0002)
+
+#define BT_HCI_OP_CONNECT BT_OP(BT_OGF_LINK_CTRL, 0x0005)
+struct bt_hci_cp_connect {
+ bt_addr_t bdaddr;
+ uint16_t packet_type;
+ uint8_t pscan_rep_mode;
+ uint8_t reserved;
+ uint16_t clock_offset;
+ uint8_t allow_role_switch;
+} __packed;
+
+#define BT_HCI_OP_DISCONNECT BT_OP(BT_OGF_LINK_CTRL, 0x0006)
+struct bt_hci_cp_disconnect {
+ uint16_t handle;
+ uint8_t reason;
+} __packed;
+
+#define BT_HCI_OP_CONNECT_CANCEL BT_OP(BT_OGF_LINK_CTRL, 0x0008)
+struct bt_hci_cp_connect_cancel {
+ bt_addr_t bdaddr;
+} __packed;
+struct bt_hci_rp_connect_cancel {
+ uint8_t status;
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_OP_ACCEPT_CONN_REQ BT_OP(BT_OGF_LINK_CTRL, 0x0009)
+struct bt_hci_cp_accept_conn_req {
+ bt_addr_t bdaddr;
+ uint8_t role;
+} __packed;
+
+#define BT_HCI_OP_SETUP_SYNC_CONN BT_OP(BT_OGF_LINK_CTRL, 0x0028)
+struct bt_hci_cp_setup_sync_conn {
+ uint16_t handle;
+ uint32_t tx_bandwidth;
+ uint32_t rx_bandwidth;
+ uint16_t max_latency;
+ uint16_t content_format;
+ uint8_t retrans_effort;
+ uint16_t pkt_type;
+} __packed;
+
+#define BT_HCI_OP_ACCEPT_SYNC_CONN_REQ BT_OP(BT_OGF_LINK_CTRL, 0x0029)
+struct bt_hci_cp_accept_sync_conn_req {
+ bt_addr_t bdaddr;
+ uint32_t tx_bandwidth;
+ uint32_t rx_bandwidth;
+ uint16_t max_latency;
+ uint16_t content_format;
+ uint8_t retrans_effort;
+ uint16_t pkt_type;
+} __packed;
+
+#define BT_HCI_OP_REJECT_CONN_REQ BT_OP(BT_OGF_LINK_CTRL, 0x000a)
+struct bt_hci_cp_reject_conn_req {
+ bt_addr_t bdaddr;
+ uint8_t reason;
+} __packed;
+
+#define BT_HCI_OP_LINK_KEY_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x000b)
+struct bt_hci_cp_link_key_reply {
+ bt_addr_t bdaddr;
+ uint8_t link_key[16];
+} __packed;
+
+#define BT_HCI_OP_LINK_KEY_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x000c)
+struct bt_hci_cp_link_key_neg_reply {
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_OP_PIN_CODE_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x000d)
+struct bt_hci_cp_pin_code_reply {
+ bt_addr_t bdaddr;
+ uint8_t pin_len;
+ uint8_t pin_code[16];
+} __packed;
+struct bt_hci_rp_pin_code_reply {
+ uint8_t status;
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_OP_PIN_CODE_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x000e)
+struct bt_hci_cp_pin_code_neg_reply {
+ bt_addr_t bdaddr;
+} __packed;
+struct bt_hci_rp_pin_code_neg_reply {
+ uint8_t status;
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_OP_AUTH_REQUESTED BT_OP(BT_OGF_LINK_CTRL, 0x0011)
+struct bt_hci_cp_auth_requested {
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_SET_CONN_ENCRYPT BT_OP(BT_OGF_LINK_CTRL, 0x0013)
+struct bt_hci_cp_set_conn_encrypt {
+ uint16_t handle;
+ uint8_t encrypt;
+} __packed;
+
+#define BT_HCI_OP_REMOTE_NAME_REQUEST BT_OP(BT_OGF_LINK_CTRL, 0x0019)
+struct bt_hci_cp_remote_name_request {
+ bt_addr_t bdaddr;
+ uint8_t pscan_rep_mode;
+ uint8_t reserved;
+ uint16_t clock_offset;
+} __packed;
+
+#define BT_HCI_OP_REMOTE_NAME_CANCEL BT_OP(BT_OGF_LINK_CTRL, 0x001a)
+struct bt_hci_cp_remote_name_cancel {
+ bt_addr_t bdaddr;
+} __packed;
+struct bt_hci_rp_remote_name_cancel {
+ uint8_t status;
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_OP_READ_REMOTE_FEATURES BT_OP(BT_OGF_LINK_CTRL, 0x001b)
+struct bt_hci_cp_read_remote_features {
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_READ_REMOTE_EXT_FEATURES BT_OP(BT_OGF_LINK_CTRL, 0x001c)
+struct bt_hci_cp_read_remote_ext_features {
+ uint16_t handle;
+ uint8_t page;
+} __packed;
+
+#define BT_HCI_OP_READ_REMOTE_VERSION_INFO BT_OP(BT_OGF_LINK_CTRL, 0x001d)
+struct bt_hci_cp_read_remote_version_info {
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_IO_CAPABILITY_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002b)
+struct bt_hci_cp_io_capability_reply {
+ bt_addr_t bdaddr;
+ uint8_t capability;
+ uint8_t oob_data;
+ uint8_t authentication;
+} __packed;
+
+#define BT_HCI_OP_USER_CONFIRM_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002c)
+#define BT_HCI_OP_USER_CONFIRM_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002d)
+struct bt_hci_cp_user_confirm_reply {
+ bt_addr_t bdaddr;
+} __packed;
+struct bt_hci_rp_user_confirm_reply {
+ uint8_t status;
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_OP_USER_PASSKEY_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002e)
+struct bt_hci_cp_user_passkey_reply {
+ bt_addr_t bdaddr;
+ uint32_t passkey;
+} __packed;
+
+#define BT_HCI_OP_USER_PASSKEY_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002f)
+struct bt_hci_cp_user_passkey_neg_reply {
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_OP_IO_CAPABILITY_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x0034)
+struct bt_hci_cp_io_capability_neg_reply {
+ bt_addr_t bdaddr;
+ uint8_t reason;
+} __packed;
+
+#define BT_HCI_OP_SET_EVENT_MASK BT_OP(BT_OGF_BASEBAND, 0x0001)
+struct bt_hci_cp_set_event_mask {
+ uint8_t events[8];
+} __packed;
+
+#define BT_HCI_OP_RESET BT_OP(BT_OGF_BASEBAND, 0x0003)
+
+#define BT_HCI_OP_WRITE_LOCAL_NAME BT_OP(BT_OGF_BASEBAND, 0x0013)
+struct bt_hci_write_local_name {
+ uint8_t local_name[248];
+} __packed;
+
+#define BT_HCI_OP_WRITE_PAGE_TIMEOUT BT_OP(BT_OGF_BASEBAND, 0x0018)
+
+#define BT_HCI_OP_WRITE_SCAN_ENABLE BT_OP(BT_OGF_BASEBAND, 0x001a)
+#define BT_BREDR_SCAN_DISABLED 0x00
+#define BT_BREDR_SCAN_INQUIRY 0x01
+#define BT_BREDR_SCAN_PAGE 0x02
+
+#define BT_TX_POWER_LEVEL_CURRENT 0x00
+#define BT_TX_POWER_LEVEL_MAX 0x01
+#define BT_HCI_OP_READ_TX_POWER_LEVEL BT_OP(BT_OGF_BASEBAND, 0x002d)
+struct bt_hci_cp_read_tx_power_level {
+ uint16_t handle;
+ uint8_t type;
+} __packed;
+
+struct bt_hci_rp_read_tx_power_level {
+ uint8_t status;
+ uint16_t handle;
+ int8_t tx_power_level;
+} __packed;
+
+#define BT_HCI_CTL_TO_HOST_FLOW_DISABLE 0x00
+#define BT_HCI_CTL_TO_HOST_FLOW_ENABLE 0x01
+#define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031)
+struct bt_hci_cp_set_ctl_to_host_flow {
+ uint8_t flow_enable;
+} __packed;
+
+#define BT_HCI_OP_HOST_BUFFER_SIZE BT_OP(BT_OGF_BASEBAND, 0x0033)
+struct bt_hci_cp_host_buffer_size {
+ uint16_t acl_mtu;
+ uint8_t sco_mtu;
+ uint16_t acl_pkts;
+ uint16_t sco_pkts;
+} __packed;
+
+struct bt_hci_handle_count {
+ uint16_t handle;
+ uint16_t count;
+} __packed;
+
+#define BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS BT_OP(BT_OGF_BASEBAND, 0x0035)
+struct bt_hci_cp_host_num_completed_packets {
+ uint8_t num_handles;
+ struct bt_hci_handle_count h[0];
+} __packed;
+
+#define BT_HCI_OP_WRITE_INQUIRY_MODE BT_OP(BT_OGF_BASEBAND, 0x0045)
+struct bt_hci_cp_write_inquiry_mode {
+ uint8_t mode;
+} __packed;
+
+#define BT_HCI_OP_WRITE_SSP_MODE BT_OP(BT_OGF_BASEBAND, 0x0056)
+struct bt_hci_cp_write_ssp_mode {
+ uint8_t mode;
+} __packed;
+
+#define BT_HCI_OP_SET_EVENT_MASK_PAGE_2 BT_OP(BT_OGF_BASEBAND, 0x0063)
+struct bt_hci_cp_set_event_mask_page_2 {
+ uint8_t events_page_2[8];
+} __packed;
+
+#define BT_HCI_OP_LE_WRITE_LE_HOST_SUPP BT_OP(BT_OGF_BASEBAND, 0x006d)
+struct bt_hci_cp_write_le_host_supp {
+ uint8_t le;
+ uint8_t simul;
+} __packed;
+
+#define BT_HCI_OP_WRITE_SC_HOST_SUPP BT_OP(BT_OGF_BASEBAND, 0x007a)
+struct bt_hci_cp_write_sc_host_supp {
+ uint8_t sc_support;
+} __packed;
+
+#define BT_HCI_OP_READ_AUTH_PAYLOAD_TIMEOUT BT_OP(BT_OGF_BASEBAND, 0x007b)
+struct bt_hci_cp_read_auth_payload_timeout {
+ uint16_t handle;
+} __packed;
+
+struct bt_hci_rp_read_auth_payload_timeout {
+ uint8_t status;
+ uint16_t handle;
+ uint16_t auth_payload_timeout;
+} __packed;
+
+#define BT_HCI_OP_WRITE_AUTH_PAYLOAD_TIMEOUT BT_OP(BT_OGF_BASEBAND, 0x007c)
+struct bt_hci_cp_write_auth_payload_timeout {
+ uint16_t handle;
+ uint16_t auth_payload_timeout;
+} __packed;
+
+struct bt_hci_rp_write_auth_payload_timeout {
+ uint8_t status;
+ uint16_t handle;
+} __packed;
+
+/* HCI version from Assigned Numbers */
+#define BT_HCI_VERSION_1_0B 0
+#define BT_HCI_VERSION_1_1 1
+#define BT_HCI_VERSION_1_2 2
+#define BT_HCI_VERSION_2_0 3
+#define BT_HCI_VERSION_2_1 4
+#define BT_HCI_VERSION_3_0 5
+#define BT_HCI_VERSION_4_0 6
+#define BT_HCI_VERSION_4_1 7
+#define BT_HCI_VERSION_4_2 8
+#define BT_HCI_VERSION_5_0 9
+#define BT_HCI_VERSION_5_1 10
+#define BT_HCI_VERSION_5_2 11
+
+#define BT_HCI_OP_READ_LOCAL_VERSION_INFO BT_OP(BT_OGF_INFO, 0x0001)
+struct bt_hci_rp_read_local_version_info {
+ uint8_t status;
+ uint8_t hci_version;
+ uint16_t hci_revision;
+ uint8_t lmp_version;
+ uint16_t manufacturer;
+ uint16_t lmp_subversion;
+} __packed;
+
+#define BT_HCI_OP_READ_SUPPORTED_COMMANDS BT_OP(BT_OGF_INFO, 0x0002)
+struct bt_hci_rp_read_supported_commands {
+ uint8_t status;
+ uint8_t commands[64];
+} __packed;
+
+#define BT_HCI_OP_READ_LOCAL_EXT_FEATURES BT_OP(BT_OGF_INFO, 0x0004)
+struct bt_hci_cp_read_local_ext_features {
+ uint8_t page;
+};
+struct bt_hci_rp_read_local_ext_features {
+ uint8_t status;
+ uint8_t page;
+ uint8_t max_page;
+ uint8_t ext_features[8];
+} __packed;
+
+#define BT_HCI_OP_READ_LOCAL_FEATURES BT_OP(BT_OGF_INFO, 0x0003)
+struct bt_hci_rp_read_local_features {
+ uint8_t status;
+ uint8_t features[8];
+} __packed;
+
+#define BT_HCI_OP_READ_BUFFER_SIZE BT_OP(BT_OGF_INFO, 0x0005)
+struct bt_hci_rp_read_buffer_size {
+ uint8_t status;
+ uint16_t acl_max_len;
+ uint8_t sco_max_len;
+ uint16_t acl_max_num;
+ uint16_t sco_max_num;
+} __packed;
+
+#define BT_HCI_OP_READ_BD_ADDR BT_OP(BT_OGF_INFO, 0x0009)
+struct bt_hci_rp_read_bd_addr {
+ uint8_t status;
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_OP_READ_RSSI BT_OP(BT_OGF_STATUS, 0x0005)
+struct bt_hci_cp_read_rssi {
+ uint16_t handle;
+} __packed;
+struct bt_hci_rp_read_rssi {
+ uint8_t status;
+ uint16_t handle;
+ int8_t rssi;
+} __packed;
+
+#define BT_HCI_ENCRYPTION_KEY_SIZE_MIN 7
+#define BT_HCI_ENCRYPTION_KEY_SIZE_MAX 16
+
+#define BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE BT_OP(BT_OGF_STATUS, 0x0008)
+struct bt_hci_cp_read_encryption_key_size {
+ uint16_t handle;
+} __packed;
+struct bt_hci_rp_read_encryption_key_size {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t key_size;
+} __packed;
+
+/* BLE */
+
+#define BT_HCI_OP_LE_SET_EVENT_MASK BT_OP(BT_OGF_LE, 0x0001)
+struct bt_hci_cp_le_set_event_mask {
+ uint8_t events[8];
+} __packed;
+
+#define BT_HCI_OP_LE_READ_BUFFER_SIZE BT_OP(BT_OGF_LE, 0x0002)
+struct bt_hci_rp_le_read_buffer_size {
+ uint8_t status;
+ uint16_t le_max_len;
+ uint8_t le_max_num;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_LOCAL_FEATURES BT_OP(BT_OGF_LE, 0x0003)
+struct bt_hci_rp_le_read_local_features {
+ uint8_t status;
+ uint8_t features[8];
+} __packed;
+
+#define BT_HCI_OP_LE_SET_RANDOM_ADDRESS BT_OP(BT_OGF_LE, 0x0005)
+struct bt_hci_cp_le_set_random_address {
+ bt_addr_t bdaddr;
+} __packed;
+
+/* LE Advertising Types (LE Advertising Parameters Set)*/
+#define BT_LE_ADV_IND (__DEPRECATED_MACRO 0x00)
+#define BT_LE_ADV_DIRECT_IND (__DEPRECATED_MACRO 0x01)
+#define BT_LE_ADV_SCAN_IND (__DEPRECATED_MACRO 0x02)
+#define BT_LE_ADV_NONCONN_IND (__DEPRECATED_MACRO 0x03)
+#define BT_LE_ADV_DIRECT_IND_LOW_DUTY (__DEPRECATED_MACRO 0x04)
+/* LE Advertising PDU Types. */
+#define BT_LE_ADV_SCAN_RSP (__DEPRECATED_MACRO 0x04)
+
+#define BT_HCI_ADV_IND 0x00
+#define BT_HCI_ADV_DIRECT_IND 0x01
+#define BT_HCI_ADV_SCAN_IND 0x02
+#define BT_HCI_ADV_NONCONN_IND 0x03
+#define BT_HCI_ADV_DIRECT_IND_LOW_DUTY 0x04
+#define BT_HCI_ADV_SCAN_RSP 0x04
+
+#define BT_LE_ADV_FP_NO_WHITELIST 0x00
+#define BT_LE_ADV_FP_WHITELIST_SCAN_REQ 0x01
+#define BT_LE_ADV_FP_WHITELIST_CONN_IND 0x02
+#define BT_LE_ADV_FP_WHITELIST_BOTH 0x03
+
+#define BT_HCI_OP_LE_SET_ADV_PARAM BT_OP(BT_OGF_LE, 0x0006)
+struct bt_hci_cp_le_set_adv_param {
+ uint16_t min_interval;
+ uint16_t max_interval;
+ uint8_t type;
+ uint8_t own_addr_type;
+ bt_addr_le_t direct_addr;
+ uint8_t channel_map;
+ uint8_t filter_policy;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_ADV_CHAN_TX_POWER BT_OP(BT_OGF_LE, 0x0007)
+struct bt_hci_rp_le_read_chan_tx_power {
+ uint8_t status;
+ int8_t tx_power_level;
+} __packed;
+
+#define BT_HCI_OP_LE_SET_ADV_DATA BT_OP(BT_OGF_LE, 0x0008)
+struct bt_hci_cp_le_set_adv_data {
+ uint8_t len;
+ uint8_t data[31];
+} __packed;
+
+#define BT_HCI_OP_LE_SET_SCAN_RSP_DATA BT_OP(BT_OGF_LE, 0x0009)
+struct bt_hci_cp_le_set_scan_rsp_data {
+ uint8_t len;
+ uint8_t data[31];
+} __packed;
+
+#define BT_HCI_LE_ADV_DISABLE 0x00
+#define BT_HCI_LE_ADV_ENABLE 0x01
+
+#define BT_HCI_OP_LE_SET_ADV_ENABLE BT_OP(BT_OGF_LE, 0x000a)
+struct bt_hci_cp_le_set_adv_enable {
+ uint8_t enable;
+} __packed;
+
+/* Scan types */
+#define BT_HCI_OP_LE_SET_SCAN_PARAM BT_OP(BT_OGF_LE, 0x000b)
+#define BT_HCI_LE_SCAN_PASSIVE 0x00
+#define BT_HCI_LE_SCAN_ACTIVE 0x01
+
+#define BT_HCI_LE_SCAN_FP_NO_WHITELIST 0x00
+#define BT_HCI_LE_SCAN_FP_USE_WHITELIST 0x01
+
+struct bt_hci_cp_le_set_scan_param {
+ uint8_t scan_type;
+ uint16_t interval;
+ uint16_t window;
+ uint8_t addr_type;
+ uint8_t filter_policy;
+} __packed;
+
+#define BT_HCI_OP_LE_SET_SCAN_ENABLE BT_OP(BT_OGF_LE, 0x000c)
+
+#define BT_HCI_LE_SCAN_DISABLE 0x00
+#define BT_HCI_LE_SCAN_ENABLE 0x01
+
+#define BT_HCI_LE_SCAN_FILTER_DUP_DISABLE 0x00
+#define BT_HCI_LE_SCAN_FILTER_DUP_ENABLE 0x01
+
+struct bt_hci_cp_le_set_scan_enable {
+ uint8_t enable;
+ uint8_t filter_dup;
+} __packed;
+
+#define BT_HCI_OP_LE_CREATE_CONN BT_OP(BT_OGF_LE, 0x000d)
+
+#define BT_HCI_LE_CREATE_CONN_FP_DIRECT 0x00
+#define BT_HCI_LE_CREATE_CONN_FP_WHITELIST 0x01
+
+struct bt_hci_cp_le_create_conn {
+ uint16_t scan_interval;
+ uint16_t scan_window;
+ uint8_t filter_policy;
+ bt_addr_le_t peer_addr;
+ uint8_t own_addr_type;
+ uint16_t conn_interval_min;
+ uint16_t conn_interval_max;
+ uint16_t conn_latency;
+ uint16_t supervision_timeout;
+ uint16_t min_ce_len;
+ uint16_t max_ce_len;
+} __packed;
+
+#define BT_HCI_OP_LE_CREATE_CONN_CANCEL BT_OP(BT_OGF_LE, 0x000e)
+
+#define BT_HCI_OP_LE_READ_WL_SIZE BT_OP(BT_OGF_LE, 0x000f)
+struct bt_hci_rp_le_read_wl_size {
+ uint8_t status;
+ uint8_t wl_size;
+} __packed;
+
+#define BT_HCI_OP_LE_CLEAR_WL BT_OP(BT_OGF_LE, 0x0010)
+
+#define BT_HCI_OP_LE_ADD_DEV_TO_WL BT_OP(BT_OGF_LE, 0x0011)
+struct bt_hci_cp_le_add_dev_to_wl {
+ bt_addr_le_t addr;
+} __packed;
+
+#define BT_HCI_OP_LE_REM_DEV_FROM_WL BT_OP(BT_OGF_LE, 0x0012)
+struct bt_hci_cp_le_rem_dev_from_wl {
+ bt_addr_le_t addr;
+} __packed;
+
+#define BT_HCI_OP_LE_CONN_UPDATE BT_OP(BT_OGF_LE, 0x0013)
+struct hci_cp_le_conn_update {
+ uint16_t handle;
+ uint16_t conn_interval_min;
+ uint16_t conn_interval_max;
+ uint16_t conn_latency;
+ uint16_t supervision_timeout;
+ uint16_t min_ce_len;
+ uint16_t max_ce_len;
+} __packed;
+
+#define BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF BT_OP(BT_OGF_LE, 0x0014)
+struct bt_hci_cp_le_set_host_chan_classif {
+ uint8_t ch_map[5];
+} __packed;
+
+#define BT_HCI_OP_LE_READ_CHAN_MAP BT_OP(BT_OGF_LE, 0x0015)
+struct bt_hci_cp_le_read_chan_map {
+ uint16_t handle;
+} __packed;
+struct bt_hci_rp_le_read_chan_map {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t ch_map[5];
+} __packed;
+
+#define BT_HCI_OP_LE_READ_REMOTE_FEATURES BT_OP(BT_OGF_LE, 0x0016)
+struct bt_hci_cp_le_read_remote_features {
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_LE_ENCRYPT BT_OP(BT_OGF_LE, 0x0017)
+struct bt_hci_cp_le_encrypt {
+ uint8_t key[16];
+ uint8_t plaintext[16];
+} __packed;
+struct bt_hci_rp_le_encrypt {
+ uint8_t status;
+ uint8_t enc_data[16];
+} __packed;
+
+#define BT_HCI_OP_LE_RAND BT_OP(BT_OGF_LE, 0x0018)
+struct bt_hci_rp_le_rand {
+ uint8_t status;
+ uint8_t rand[8];
+} __packed;
+
+#define BT_HCI_OP_LE_START_ENCRYPTION BT_OP(BT_OGF_LE, 0x0019)
+struct bt_hci_cp_le_start_encryption {
+ uint16_t handle;
+ uint64_t rand;
+ uint16_t ediv;
+ uint8_t ltk[16];
+} __packed;
+
+#define BT_HCI_OP_LE_LTK_REQ_REPLY BT_OP(BT_OGF_LE, 0x001a)
+struct bt_hci_cp_le_ltk_req_reply {
+ uint16_t handle;
+ uint8_t ltk[16];
+} __packed;
+struct bt_hci_rp_le_ltk_req_reply {
+ uint8_t status;
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_LE_LTK_REQ_NEG_REPLY BT_OP(BT_OGF_LE, 0x001b)
+struct bt_hci_cp_le_ltk_req_neg_reply {
+ uint16_t handle;
+} __packed;
+struct bt_hci_rp_le_ltk_req_neg_reply {
+ uint8_t status;
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_SUPP_STATES BT_OP(BT_OGF_LE, 0x001c)
+struct bt_hci_rp_le_read_supp_states {
+ uint8_t status;
+ uint8_t le_states[8];
+} __packed;
+
+#define BT_HCI_OP_LE_RX_TEST BT_OP(BT_OGF_LE, 0x001d)
+struct bt_hci_cp_le_rx_test {
+ uint8_t rx_ch;
+} __packed;
+
+#define BT_HCI_OP_LE_TX_TEST BT_OP(BT_OGF_LE, 0x001e)
+struct bt_hci_cp_le_tx_test {
+ uint8_t tx_ch;
+ uint8_t test_data_len;
+ uint8_t pkt_payload;
+} __packed;
+
+#define BT_HCI_OP_LE_TEST_END BT_OP(BT_OGF_LE, 0x001f)
+struct bt_hci_rp_le_test_end {
+ uint8_t status;
+ uint16_t rx_pkt_count;
+} __packed;
+
+#define BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY BT_OP(BT_OGF_LE, 0x0020)
+struct bt_hci_cp_le_conn_param_req_reply {
+ uint16_t handle;
+ uint16_t interval_min;
+ uint16_t interval_max;
+ uint16_t latency;
+ uint16_t timeout;
+ uint16_t min_ce_len;
+ uint16_t max_ce_len;
+} __packed;
+struct bt_hci_rp_le_conn_param_req_reply {
+ uint8_t status;
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY BT_OP(BT_OGF_LE, 0x0021)
+struct bt_hci_cp_le_conn_param_req_neg_reply {
+ uint16_t handle;
+ uint8_t reason;
+} __packed;
+struct bt_hci_rp_le_conn_param_req_neg_reply {
+ uint8_t status;
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_LE_SET_DATA_LEN BT_OP(BT_OGF_LE, 0x0022)
+struct bt_hci_cp_le_set_data_len {
+ uint16_t handle;
+ uint16_t tx_octets;
+ uint16_t tx_time;
+} __packed;
+struct bt_hci_rp_le_set_data_len {
+ uint8_t status;
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_DEFAULT_DATA_LEN BT_OP(BT_OGF_LE, 0x0023)
+struct bt_hci_rp_le_read_default_data_len {
+ uint8_t status;
+ uint16_t max_tx_octets;
+ uint16_t max_tx_time;
+} __packed;
+
+#define BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN BT_OP(BT_OGF_LE, 0x0024)
+struct bt_hci_cp_le_write_default_data_len {
+ uint16_t max_tx_octets;
+ uint16_t max_tx_time;
+} __packed;
+
+#define BT_HCI_OP_LE_P256_PUBLIC_KEY BT_OP(BT_OGF_LE, 0x0025)
+
+#define BT_HCI_OP_LE_GENERATE_DHKEY BT_OP(BT_OGF_LE, 0x0026)
+struct bt_hci_cp_le_generate_dhkey {
+ uint8_t key[64];
+} __packed;
+
+#define BT_HCI_OP_LE_ADD_DEV_TO_RL BT_OP(BT_OGF_LE, 0x0027)
+struct bt_hci_cp_le_add_dev_to_rl {
+ bt_addr_le_t peer_id_addr;
+ uint8_t peer_irk[16];
+ uint8_t local_irk[16];
+} __packed;
+
+#define BT_HCI_OP_LE_REM_DEV_FROM_RL BT_OP(BT_OGF_LE, 0x0028)
+struct bt_hci_cp_le_rem_dev_from_rl {
+ bt_addr_le_t peer_id_addr;
+} __packed;
+
+#define BT_HCI_OP_LE_CLEAR_RL BT_OP(BT_OGF_LE, 0x0029)
+
+#define BT_HCI_OP_LE_READ_RL_SIZE BT_OP(BT_OGF_LE, 0x002a)
+struct bt_hci_rp_le_read_rl_size {
+ uint8_t status;
+ uint8_t rl_size;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_PEER_RPA BT_OP(BT_OGF_LE, 0x002b)
+struct bt_hci_cp_le_read_peer_rpa {
+ bt_addr_le_t peer_id_addr;
+} __packed;
+struct bt_hci_rp_le_read_peer_rpa {
+ uint8_t status;
+ bt_addr_t peer_rpa;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_LOCAL_RPA BT_OP(BT_OGF_LE, 0x002c)
+struct bt_hci_cp_le_read_local_rpa {
+ bt_addr_le_t peer_id_addr;
+} __packed;
+struct bt_hci_rp_le_read_local_rpa {
+ uint8_t status;
+ bt_addr_t local_rpa;
+} __packed;
+
+#define BT_HCI_ADDR_RES_DISABLE 0x00
+#define BT_HCI_ADDR_RES_ENABLE 0x01
+
+#define BT_HCI_OP_LE_SET_ADDR_RES_ENABLE BT_OP(BT_OGF_LE, 0x002d)
+struct bt_hci_cp_le_set_addr_res_enable {
+ uint8_t enable;
+} __packed;
+
+#define BT_HCI_OP_LE_SET_RPA_TIMEOUT BT_OP(BT_OGF_LE, 0x002e)
+struct bt_hci_cp_le_set_rpa_timeout {
+ uint16_t rpa_timeout;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_MAX_DATA_LEN BT_OP(BT_OGF_LE, 0x002f)
+struct bt_hci_rp_le_read_max_data_len {
+ uint8_t status;
+ uint16_t max_tx_octets;
+ uint16_t max_tx_time;
+ uint16_t max_rx_octets;
+ uint16_t max_rx_time;
+} __packed;
+
+#define BT_HCI_LE_PHY_1M 0x01
+#define BT_HCI_LE_PHY_2M 0x02
+#define BT_HCI_LE_PHY_CODED 0x03
+
+#define BT_HCI_OP_LE_READ_PHY BT_OP(BT_OGF_LE, 0x0030)
+struct bt_hci_cp_le_read_phy {
+ uint16_t handle;
+} __packed;
+struct bt_hci_rp_le_read_phy {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t tx_phy;
+ uint8_t rx_phy;
+} __packed;
+
+#define BT_HCI_LE_PHY_TX_ANY BIT(0)
+#define BT_HCI_LE_PHY_RX_ANY BIT(1)
+
+#define BT_HCI_LE_PHY_PREFER_1M BIT(0)
+#define BT_HCI_LE_PHY_PREFER_2M BIT(1)
+#define BT_HCI_LE_PHY_PREFER_CODED BIT(2)
+
+#define BT_HCI_OP_LE_SET_DEFAULT_PHY BT_OP(BT_OGF_LE, 0x0031)
+struct bt_hci_cp_le_set_default_phy {
+ uint8_t all_phys;
+ uint8_t tx_phys;
+ uint8_t rx_phys;
+} __packed;
+
+#define BT_HCI_LE_PHY_CODED_ANY 0x00
+#define BT_HCI_LE_PHY_CODED_S2 0x01
+#define BT_HCI_LE_PHY_CODED_S8 0x02
+
+#define BT_HCI_OP_LE_SET_PHY BT_OP(BT_OGF_LE, 0x0032)
+struct bt_hci_cp_le_set_phy {
+ uint16_t handle;
+ uint8_t all_phys;
+ uint8_t tx_phys;
+ uint8_t rx_phys;
+ uint16_t phy_opts;
+} __packed;
+
+#define BT_HCI_LE_MOD_INDEX_STANDARD 0x00
+#define BT_HCI_LE_MOD_INDEX_STABLE 0x01
+
+#define BT_HCI_OP_LE_ENH_RX_TEST BT_OP(BT_OGF_LE, 0x0033)
+struct bt_hci_cp_le_enh_rx_test {
+ uint8_t rx_ch;
+ uint8_t phy;
+ uint8_t mod_index;
+} __packed;
+
+/* Extends BT_HCI_LE_PHY */
+#define BT_HCI_LE_TX_PHY_CODED_S8 0x03
+#define BT_HCI_LE_TX_PHY_CODED_S2 0x04
+
+#define BT_HCI_OP_LE_ENH_TX_TEST BT_OP(BT_OGF_LE, 0x0034)
+struct bt_hci_cp_le_enh_tx_test {
+ uint8_t tx_ch;
+ uint8_t test_data_len;
+ uint8_t pkt_payload;
+ uint8_t phy;
+} __packed;
+
+#define BT_HCI_OP_LE_SET_ADV_SET_RANDOM_ADDR BT_OP(BT_OGF_LE, 0x0035)
+struct bt_hci_cp_le_set_adv_set_random_addr {
+ uint8_t handle;
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_LE_ADV_PROP_CONN BIT(0)
+#define BT_HCI_LE_ADV_PROP_SCAN BIT(1)
+#define BT_HCI_LE_ADV_PROP_DIRECT BIT(2)
+#define BT_HCI_LE_ADV_PROP_HI_DC_CONN BIT(3)
+#define BT_HCI_LE_ADV_PROP_LEGACY BIT(4)
+#define BT_HCI_LE_ADV_PROP_ANON BIT(5)
+#define BT_HCI_LE_ADV_PROP_TX_POWER BIT(6)
+
+#define BT_HCI_LE_ADV_SCAN_REQ_ENABLE 1
+#define BT_HCI_LE_ADV_SCAN_REQ_DISABLE 0
+
+#define BT_HCI_LE_ADV_TX_POWER_NO_PREF 0x7F
+
+#define BT_HCI_OP_LE_SET_EXT_ADV_PARAM BT_OP(BT_OGF_LE, 0x0036)
+struct bt_hci_cp_le_set_ext_adv_param {
+ uint8_t handle;
+ uint16_t props;
+ uint8_t prim_min_interval[3];
+ uint8_t prim_max_interval[3];
+ uint8_t prim_channel_map;
+ uint8_t own_addr_type;
+ bt_addr_le_t peer_addr;
+ uint8_t filter_policy;
+ int8_t tx_power;
+ uint8_t prim_adv_phy;
+ uint8_t sec_adv_max_skip;
+ uint8_t sec_adv_phy;
+ uint8_t sid;
+ uint8_t scan_req_notify_enable;
+} __packed;
+struct bt_hci_rp_le_set_ext_adv_param {
+ uint8_t status;
+ int8_t tx_power;
+} __packed;
+
+#define BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG 0x00
+#define BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG 0x01
+#define BT_HCI_LE_EXT_ADV_OP_LAST_FRAG 0x02
+#define BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA 0x03
+#define BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA 0x04
+
+#define BT_HCI_LE_EXT_ADV_FRAG_ENABLED 0x00
+#define BT_HCI_LE_EXT_ADV_FRAG_DISABLED 0x01
+
+#define BT_HCI_LE_EXT_ADV_FRAG_MAX_LEN 251
+
+#define BT_HCI_OP_LE_SET_EXT_ADV_DATA BT_OP(BT_OGF_LE, 0x0037)
+struct bt_hci_cp_le_set_ext_adv_data {
+ uint8_t handle;
+ uint8_t op;
+ uint8_t frag_pref;
+ uint8_t len;
+ uint8_t data[251];
+} __packed;
+
+#define BT_HCI_OP_LE_SET_EXT_SCAN_RSP_DATA BT_OP(BT_OGF_LE, 0x0038)
+struct bt_hci_cp_le_set_ext_scan_rsp_data {
+ uint8_t handle;
+ uint8_t op;
+ uint8_t frag_pref;
+ uint8_t len;
+ uint8_t data[251];
+} __packed;
+
+#define BT_HCI_OP_LE_SET_EXT_ADV_ENABLE BT_OP(BT_OGF_LE, 0x0039)
+struct bt_hci_ext_adv_set {
+ uint8_t handle;
+ uint16_t duration;
+ uint8_t max_ext_adv_evts;
+} __packed;
+
+struct bt_hci_cp_le_set_ext_adv_enable {
+ uint8_t enable;
+ uint8_t set_num;
+ struct bt_hci_ext_adv_set s[0];
+} __packed;
+
+#define BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN BT_OP(BT_OGF_LE, 0x003a)
+struct bt_hci_rp_le_read_max_adv_data_len {
+ uint8_t status;
+ uint16_t max_adv_data_len;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_NUM_ADV_SETS BT_OP(BT_OGF_LE, 0x003b)
+struct bt_hci_rp_le_read_num_adv_sets {
+ uint8_t status;
+ uint8_t num_sets;
+} __packed;
+
+#define BT_HCI_OP_LE_REMOVE_ADV_SET BT_OP(BT_OGF_LE, 0x003c)
+struct bt_hci_cp_le_remove_adv_set {
+ uint8_t handle;
+} __packed;
+
+#define BT_HCI_OP_CLEAR_ADV_SETS BT_OP(BT_OGF_LE, 0x003d)
+
+#define BT_HCI_OP_LE_SET_PER_ADV_PARAM BT_OP(BT_OGF_LE, 0x003e)
+struct bt_hci_cp_le_set_per_adv_param {
+ uint8_t handle;
+ uint16_t min_interval;
+ uint16_t max_interval;
+ uint16_t props;
+} __packed;
+
+#define BT_HCI_OP_LE_SET_PER_ADV_DATA BT_OP(BT_OGF_LE, 0x003f)
+struct bt_hci_cp_le_set_per_adv_data {
+ uint8_t handle;
+ uint8_t op;
+ uint8_t len;
+ uint8_t data[251];
+} __packed;
+
+#define BT_HCI_OP_LE_SET_PER_ADV_ENABLE BT_OP(BT_OGF_LE, 0x0040)
+struct bt_hci_cp_le_set_per_adv_enable {
+ uint8_t enable;
+ uint8_t handle;
+} __packed;
+
+#define BT_HCI_OP_LE_SET_EXT_SCAN_PARAM BT_OP(BT_OGF_LE, 0x0041)
+struct bt_hci_ext_scan_phy {
+ uint8_t type;
+ uint16_t interval;
+ uint16_t window;
+} __packed;
+
+#define BT_HCI_LE_EXT_SCAN_PHY_1M BIT(0)
+#define BT_HCI_LE_EXT_SCAN_PHY_2M BIT(1)
+#define BT_HCI_LE_EXT_SCAN_PHY_CODED BIT(2)
+
+struct bt_hci_cp_le_set_ext_scan_param {
+ uint8_t own_addr_type;
+ uint8_t filter_policy;
+ uint8_t phys;
+ struct bt_hci_ext_scan_phy p[0];
+} __packed;
+
+/* Extends BT_HCI_LE_SCAN_FILTER_DUP */
+#define BT_HCI_LE_EXT_SCAN_FILTER_DUP_ENABLE_RESET 0x02
+
+#define BT_HCI_OP_LE_SET_EXT_SCAN_ENABLE BT_OP(BT_OGF_LE, 0x0042)
+struct bt_hci_cp_le_set_ext_scan_enable {
+ uint8_t enable;
+ uint8_t filter_dup;
+ uint16_t duration;
+ uint16_t period;
+} __packed;
+
+#define BT_HCI_OP_LE_EXT_CREATE_CONN BT_OP(BT_OGF_LE, 0x0043)
+struct bt_hci_ext_conn_phy {
+ uint16_t scan_interval;
+ uint16_t scan_window;
+ uint16_t conn_interval_min;
+ uint16_t conn_interval_max;
+ uint16_t conn_latency;
+ uint16_t supervision_timeout;
+ uint16_t min_ce_len;
+ uint16_t max_ce_len;
+} __packed;
+
+struct bt_hci_cp_le_ext_create_conn {
+ uint8_t filter_policy;
+ uint8_t own_addr_type;
+ bt_addr_le_t peer_addr;
+ uint8_t phys;
+ struct bt_hci_ext_conn_phy p[0];
+} __packed;
+
+#define BT_HCI_OP_LE_PER_ADV_CREATE_SYNC BT_OP(BT_OGF_LE, 0x0044)
+struct bt_hci_cp_le_per_adv_create_sync {
+ uint8_t filter_policy;
+ uint8_t sid;
+ bt_addr_le_t addr;
+ uint16_t skip;
+ uint16_t sync_timeout;
+ uint8_t unused;
+} __packed;
+
+#define BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL BT_OP(BT_OGF_LE, 0x0045)
+
+#define BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC BT_OP(BT_OGF_LE, 0x0046)
+struct bt_hci_cp_le_per_adv_terminate_sync {
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST BT_OP(BT_OGF_LE, 0x0047)
+struct bt_hci_cp_le_add_dev_to_per_adv_list {
+ bt_addr_le_t addr;
+ uint8_t sid;
+} __packed;
+
+#define BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST BT_OP(BT_OGF_LE, 0x0048)
+struct bt_hci_cp_le_rem_dev_from_per_adv_list {
+ bt_addr_le_t addr;
+ uint8_t sid;
+} __packed;
+
+#define BT_HCI_OP_LE_CLEAR_PER_ADV_LIST BT_OP(BT_OGF_LE, 0x0049)
+
+#define BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE BT_OP(BT_OGF_LE, 0x004a)
+struct bt_hci_rp_le_read_per_adv_list_size {
+ uint8_t status;
+ uint8_t list_size;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_TX_POWER BT_OP(BT_OGF_LE, 0x004b)
+struct bt_hci_rp_le_read_tx_power {
+ uint8_t status;
+ int8_t min_tx_power;
+ int8_t max_tx_power;
+} __packed;
+
+#define BT_HCI_OP_LE_READ_RF_PATH_COMP BT_OP(BT_OGF_LE, 0x004c)
+struct bt_hci_rp_le_read_rf_path_comp {
+ uint8_t status;
+ int16_t tx_path_comp;
+ int16_t rx_path_comp;
+} __packed;
+
+#define BT_HCI_OP_LE_WRITE_RF_PATH_COMP BT_OP(BT_OGF_LE, 0x004d)
+struct bt_hci_cp_le_write_rf_path_comp {
+ int16_t tx_path_comp;
+ int16_t rx_path_comp;
+} __packed;
+
+#define BT_HCI_LE_PRIVACY_MODE_NETWORK 0x00
+#define BT_HCI_LE_PRIVACY_MODE_DEVICE 0x01
+
+#define BT_HCI_OP_LE_SET_PRIVACY_MODE BT_OP(BT_OGF_LE, 0x004e)
+struct bt_hci_cp_le_set_privacy_mode {
+ bt_addr_le_t id_addr;
+ uint8_t mode;
+} __packed;
+
+/* Event definitions */
+
+#define BT_HCI_EVT_UNKNOWN 0x00
+#define BT_HCI_EVT_VENDOR 0xff
+
+#define BT_HCI_EVT_INQUIRY_COMPLETE 0x01
+struct bt_hci_evt_inquiry_complete {
+ uint8_t status;
+} __packed;
+
+#define BT_HCI_EVT_CONN_COMPLETE 0x03
+struct bt_hci_evt_conn_complete {
+ uint8_t status;
+ uint16_t handle;
+ bt_addr_t bdaddr;
+ uint8_t link_type;
+ uint8_t encr_enabled;
+} __packed;
+
+#define BT_HCI_EVT_CONN_REQUEST 0x04
+struct bt_hci_evt_conn_request {
+ bt_addr_t bdaddr;
+ uint8_t dev_class[3];
+ uint8_t link_type;
+} __packed;
+
+#define BT_HCI_EVT_DISCONN_COMPLETE 0x05
+struct bt_hci_evt_disconn_complete {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t reason;
+} __packed;
+
+#define BT_HCI_EVT_AUTH_COMPLETE 0x06
+struct bt_hci_evt_auth_complete {
+ uint8_t status;
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE 0x07
+struct bt_hci_evt_remote_name_req_complete {
+ uint8_t status;
+ bt_addr_t bdaddr;
+ uint8_t name[248];
+} __packed;
+
+#define BT_HCI_EVT_ENCRYPT_CHANGE 0x08
+struct bt_hci_evt_encrypt_change {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t encrypt;
+} __packed;
+
+#define BT_HCI_EVT_REMOTE_FEATURES 0x0b
+struct bt_hci_evt_remote_features {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t features[8];
+} __packed;
+
+#define BT_HCI_EVT_REMOTE_VERSION_INFO 0x0c
+struct bt_hci_evt_remote_version_info {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t version;
+ uint16_t manufacturer;
+ uint16_t subversion;
+} __packed;
+
+#define BT_HCI_EVT_CMD_COMPLETE 0x0e
+struct bt_hci_evt_cmd_complete {
+ uint8_t ncmd;
+ uint16_t opcode;
+} __packed;
+
+struct bt_hci_evt_cc_status {
+ uint8_t status;
+} __packed;
+
+#define BT_HCI_EVT_CMD_STATUS 0x0f
+struct bt_hci_evt_cmd_status {
+ uint8_t status;
+ uint8_t ncmd;
+ uint16_t opcode;
+} __packed;
+
+#define BT_HCI_EVT_ROLE_CHANGE 0x12
+struct bt_hci_evt_role_change {
+ uint8_t status;
+ bt_addr_t bdaddr;
+ uint8_t role;
+} __packed;
+
+#define BT_HCI_EVT_NUM_COMPLETED_PACKETS 0x13
+struct bt_hci_evt_num_completed_packets {
+ uint8_t num_handles;
+ struct bt_hci_handle_count h[0];
+} __packed;
+
+#define BT_HCI_EVT_PIN_CODE_REQ 0x16
+struct bt_hci_evt_pin_code_req {
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_EVT_LINK_KEY_REQ 0x17
+struct bt_hci_evt_link_key_req {
+ bt_addr_t bdaddr;
+} __packed;
+
+/* Link Key types */
+#define BT_LK_COMBINATION 0x00
+#define BT_LK_LOCAL_UNIT 0x01
+#define BT_LK_REMOTE_UNIT 0x02
+#define BT_LK_DEBUG_COMBINATION 0x03
+#define BT_LK_UNAUTH_COMBINATION_P192 0x04
+#define BT_LK_AUTH_COMBINATION_P192 0x05
+#define BT_LK_CHANGED_COMBINATION 0x06
+#define BT_LK_UNAUTH_COMBINATION_P256 0x07
+#define BT_LK_AUTH_COMBINATION_P256 0x08
+
+#define BT_HCI_EVT_LINK_KEY_NOTIFY 0x18
+struct bt_hci_evt_link_key_notify {
+ bt_addr_t bdaddr;
+ uint8_t link_key[16];
+ uint8_t key_type;
+} __packed;
+
+/* Overflow link types */
+#define BT_OVERFLOW_LINK_SYNCH 0x00
+#define BT_OVERFLOW_LINK_ACL 0x01
+
+#define BT_HCI_EVT_DATA_BUF_OVERFLOW 0x1a
+struct bt_hci_evt_data_buf_overflow {
+ uint8_t link_type;
+} __packed;
+
+#define BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI 0x22
+struct bt_hci_evt_inquiry_result_with_rssi {
+ bt_addr_t addr;
+ uint8_t pscan_rep_mode;
+ uint8_t reserved;
+ uint8_t cod[3];
+ uint16_t clock_offset;
+ int8_t rssi;
+} __packed;
+
+#define BT_HCI_EVT_REMOTE_EXT_FEATURES 0x23
+struct bt_hci_evt_remote_ext_features {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t page;
+ uint8_t max_page;
+ uint8_t features[8];
+} __packed;
+
+#define BT_HCI_EVT_SYNC_CONN_COMPLETE 0x2c
+struct bt_hci_evt_sync_conn_complete {
+ uint8_t status;
+ uint16_t handle;
+ bt_addr_t bdaddr;
+ uint8_t link_type;
+ uint8_t tx_interval;
+ uint8_t retansmission_window;
+ uint16_t rx_pkt_length;
+ uint16_t tx_pkt_length;
+ uint8_t air_mode;
+} __packed;
+
+#define BT_HCI_EVT_EXTENDED_INQUIRY_RESULT 0x2f
+struct bt_hci_evt_extended_inquiry_result {
+ uint8_t num_reports;
+ bt_addr_t addr;
+ uint8_t pscan_rep_mode;
+ uint8_t reserved;
+ uint8_t cod[3];
+ uint16_t clock_offset;
+ int8_t rssi;
+ uint8_t eir[240];
+} __packed;
+
+#define BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE 0x30
+struct bt_hci_evt_encrypt_key_refresh_complete {
+ uint8_t status;
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_EVT_IO_CAPA_REQ 0x31
+struct bt_hci_evt_io_capa_req {
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_EVT_IO_CAPA_RESP 0x32
+struct bt_hci_evt_io_capa_resp {
+ bt_addr_t bdaddr;
+ uint8_t capability;
+ uint8_t oob_data;
+ uint8_t authentication;
+} __packed;
+
+#define BT_HCI_EVT_USER_CONFIRM_REQ 0x33
+struct bt_hci_evt_user_confirm_req {
+ bt_addr_t bdaddr;
+ uint32_t passkey;
+} __packed;
+
+#define BT_HCI_EVT_USER_PASSKEY_REQ 0x34
+struct bt_hci_evt_user_passkey_req {
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_EVT_SSP_COMPLETE 0x36
+struct bt_hci_evt_ssp_complete {
+ uint8_t status;
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_EVT_USER_PASSKEY_NOTIFY 0x3b
+struct bt_hci_evt_user_passkey_notify {
+ bt_addr_t bdaddr;
+ uint32_t passkey;
+} __packed;
+
+#define BT_HCI_EVT_LE_META_EVENT 0x3e
+struct bt_hci_evt_le_meta_event {
+ uint8_t subevent;
+} __packed;
+
+#define BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP 0x57
+struct bt_hci_evt_auth_payload_timeout_exp {
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_ROLE_MASTER 0x00
+#define BT_HCI_ROLE_SLAVE 0x01
+
+#define BT_HCI_EVT_LE_CONN_COMPLETE 0x01
+struct bt_hci_evt_le_conn_complete {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t role;
+ bt_addr_le_t peer_addr;
+ uint16_t interval;
+ uint16_t latency;
+ uint16_t supv_timeout;
+ uint8_t clock_accuracy;
+} __packed;
+
+#define BT_HCI_EVT_LE_ADVERTISING_REPORT 0x02
+struct bt_hci_evt_le_advertising_info {
+ uint8_t evt_type;
+ bt_addr_le_t addr;
+ uint8_t length;
+ uint8_t data[0];
+} __packed;
+struct bt_hci_evt_le_advertising_report {
+ uint8_t num_reports;
+ struct bt_hci_evt_le_advertising_info adv_info[0];
+} __packed;
+
+#define BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE 0x03
+struct bt_hci_evt_le_conn_update_complete {
+ uint8_t status;
+ uint16_t handle;
+ uint16_t interval;
+ uint16_t latency;
+ uint16_t supv_timeout;
+} __packed;
+
+#define BT_HCI_EV_LE_REMOTE_FEAT_COMPLETE 0x04
+struct bt_hci_evt_le_remote_feat_complete {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t features[8];
+} __packed;
+
+#define BT_HCI_EVT_LE_LTK_REQUEST 0x05
+struct bt_hci_evt_le_ltk_request {
+ uint16_t handle;
+ uint64_t rand;
+ uint16_t ediv;
+} __packed;
+
+#define BT_HCI_EVT_LE_CONN_PARAM_REQ 0x06
+struct bt_hci_evt_le_conn_param_req {
+ uint16_t handle;
+ uint16_t interval_min;
+ uint16_t interval_max;
+ uint16_t latency;
+ uint16_t timeout;
+} __packed;
+
+#define BT_HCI_EVT_LE_DATA_LEN_CHANGE 0x07
+struct bt_hci_evt_le_data_len_change {
+ uint16_t handle;
+ uint16_t max_tx_octets;
+ uint16_t max_tx_time;
+ uint16_t max_rx_octets;
+ uint16_t max_rx_time;
+} __packed;
+
+#define BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE 0x08
+struct bt_hci_evt_le_p256_public_key_complete {
+ uint8_t status;
+ uint8_t key[64];
+} __packed;
+
+#define BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE 0x09
+struct bt_hci_evt_le_generate_dhkey_complete {
+ uint8_t status;
+ uint8_t dhkey[32];
+} __packed;
+
+#define BT_HCI_EVT_LE_ENH_CONN_COMPLETE 0x0a
+struct bt_hci_evt_le_enh_conn_complete {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t role;
+ bt_addr_le_t peer_addr;
+ bt_addr_t local_rpa;
+ bt_addr_t peer_rpa;
+ uint16_t interval;
+ uint16_t latency;
+ uint16_t supv_timeout;
+ uint8_t clock_accuracy;
+} __packed;
+
+#define BT_HCI_EVT_LE_DIRECT_ADV_REPORT 0x0b
+struct bt_hci_evt_le_direct_adv_info {
+ uint8_t evt_type;
+ bt_addr_le_t addr;
+ bt_addr_le_t dir_addr;
+ int8_t rssi;
+} __packed;
+struct bt_hci_evt_le_direct_adv_report {
+ uint8_t num_reports;
+ struct bt_hci_evt_le_direct_adv_info direct_adv_info[0];
+} __packed;
+
+#define BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE 0x0c
+struct bt_hci_evt_le_phy_update_complete {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t tx_phy;
+ uint8_t rx_phy;
+} __packed;
+
+#define BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT 0x0d
+
+#define BT_HCI_LE_ADV_EVT_TYPE_CONN BIT(0)
+#define BT_HCI_LE_ADV_EVT_TYPE_SCAN BIT(1)
+#define BT_HCI_LE_ADV_EVT_TYPE_DIRECT BIT(2)
+#define BT_HCI_LE_ADV_EVT_TYPE_SCAN_RSP BIT(3)
+#define BT_HCI_LE_ADV_EVT_TYPE_LEGACY BIT(4)
+
+#define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS(ev_type) (((ev_type) >> 5) & 0x03)
+#define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE 0
+#define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL 1
+#define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE 2
+
+struct bt_hci_evt_le_ext_advertising_info {
+ uint16_t evt_type;
+ bt_addr_le_t addr;
+ uint8_t prim_phy;
+ uint8_t sec_phy;
+ uint8_t sid;
+ int8_t tx_power;
+ int8_t rssi;
+ uint16_t interval;
+ bt_addr_le_t direct_addr;
+ uint8_t length;
+ uint8_t data[0];
+} __packed;
+struct bt_hci_evt_le_ext_advertising_report {
+ uint8_t num_reports;
+ struct bt_hci_evt_le_ext_advertising_info adv_info[0];
+} __packed;
+
+#define BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED 0x0e
+struct bt_hci_evt_le_per_adv_sync_established {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t sid;
+ bt_addr_le_t adv_addr;
+ uint8_t phy;
+ uint16_t interval;
+ uint8_t clock_accuracy;
+} __packed;
+
+#define BT_HCI_EVT_LE_PER_ADVERTISING_REPORT 0x0f
+struct bt_hci_evt_le_per_advertising_report {
+ uint16_t handle;
+ int8_t tx_power;
+ int8_t rssi;
+ uint8_t unused;
+ uint8_t data_status;
+ uint8_t length;
+ uint8_t data[0];
+} __packed;
+
+#define BT_HCI_EVT_LE_PER_ADV_SYNC_LOST 0x10
+struct bt_hci_evt_le_per_adv_sync_lost {
+ uint16_t handle;
+} __packed;
+
+#define BT_HCI_EVT_LE_SCAN_TIMEOUT 0x11
+
+#define BT_HCI_EVT_LE_ADV_SET_TERMINATED 0x12
+struct bt_hci_evt_le_adv_set_terminated {
+ uint8_t status;
+ uint8_t adv_handle;
+ uint16_t conn_handle;
+ uint8_t num_completed_ext_adv_evts;
+} __packed;
+
+#define BT_HCI_EVT_LE_SCAN_REQ_RECEIVED 0x13
+struct bt_hci_evt_le_scan_req_received {
+ uint8_t handle;
+ bt_addr_le_t addr;
+} __packed;
+
+#define BT_HCI_LE_CHAN_SEL_ALGO_1 0x00
+#define BT_HCI_LE_CHAN_SEL_ALGO_2 0x01
+
+#define BT_HCI_EVT_LE_CHAN_SEL_ALGO 0x14
+struct bt_hci_evt_le_chan_sel_algo {
+ uint16_t handle;
+ uint8_t chan_sel_algo;
+} __packed;
+
+/* Event mask bits */
+
+#define BT_EVT_BIT(n) (1ULL << (n))
+
+#define BT_EVT_MASK_INQUIRY_COMPLETE BT_EVT_BIT(0)
+#define BT_EVT_MASK_CONN_COMPLETE BT_EVT_BIT(2)
+#define BT_EVT_MASK_CONN_REQUEST BT_EVT_BIT(3)
+#define BT_EVT_MASK_DISCONN_COMPLETE BT_EVT_BIT(4)
+#define BT_EVT_MASK_AUTH_COMPLETE BT_EVT_BIT(5)
+#define BT_EVT_MASK_REMOTE_NAME_REQ_COMPLETE BT_EVT_BIT(6)
+#define BT_EVT_MASK_ENCRYPT_CHANGE BT_EVT_BIT(7)
+#define BT_EVT_MASK_REMOTE_FEATURES BT_EVT_BIT(10)
+#define BT_EVT_MASK_REMOTE_VERSION_INFO BT_EVT_BIT(11)
+#define BT_EVT_MASK_HARDWARE_ERROR BT_EVT_BIT(15)
+#define BT_EVT_MASK_ROLE_CHANGE BT_EVT_BIT(17)
+#define BT_EVT_MASK_PIN_CODE_REQ BT_EVT_BIT(21)
+#define BT_EVT_MASK_LINK_KEY_REQ BT_EVT_BIT(22)
+#define BT_EVT_MASK_LINK_KEY_NOTIFY BT_EVT_BIT(23)
+#define BT_EVT_MASK_DATA_BUFFER_OVERFLOW BT_EVT_BIT(25)
+#define BT_EVT_MASK_INQUIRY_RESULT_WITH_RSSI BT_EVT_BIT(33)
+#define BT_EVT_MASK_REMOTE_EXT_FEATURES BT_EVT_BIT(34)
+#define BT_EVT_MASK_SYNC_CONN_COMPLETE BT_EVT_BIT(43)
+#define BT_EVT_MASK_EXTENDED_INQUIRY_RESULT BT_EVT_BIT(46)
+#define BT_EVT_MASK_ENCRYPT_KEY_REFRESH_COMPLETE BT_EVT_BIT(47)
+#define BT_EVT_MASK_IO_CAPA_REQ BT_EVT_BIT(48)
+#define BT_EVT_MASK_IO_CAPA_RESP BT_EVT_BIT(49)
+#define BT_EVT_MASK_USER_CONFIRM_REQ BT_EVT_BIT(50)
+#define BT_EVT_MASK_USER_PASSKEY_REQ BT_EVT_BIT(51)
+#define BT_EVT_MASK_SSP_COMPLETE BT_EVT_BIT(53)
+#define BT_EVT_MASK_USER_PASSKEY_NOTIFY BT_EVT_BIT(58)
+#define BT_EVT_MASK_LE_META_EVENT BT_EVT_BIT(61)
+
+/* Page 2 */
+#define BT_EVT_MASK_PHY_LINK_COMPLETE BT_EVT_BIT(0)
+#define BT_EVT_MASK_CH_SELECTED_COMPLETE BT_EVT_BIT(1)
+#define BT_EVT_MASK_DISCONN_PHY_LINK_COMPLETE BT_EVT_BIT(2)
+#define BT_EVT_MASK_PHY_LINK_LOSS_EARLY_WARN BT_EVT_BIT(3)
+#define BT_EVT_MASK_PHY_LINK_RECOVERY BT_EVT_BIT(4)
+#define BT_EVT_MASK_LOG_LINK_COMPLETE BT_EVT_BIT(5)
+#define BT_EVT_MASK_DISCONN_LOG_LINK_COMPLETE BT_EVT_BIT(6)
+#define BT_EVT_MASK_FLOW_SPEC_MODIFY_COMPLETE BT_EVT_BIT(7)
+#define BT_EVT_MASK_NUM_COMPLETE_DATA_BLOCKS BT_EVT_BIT(8)
+#define BT_EVT_MASK_AMP_START_TEST BT_EVT_BIT(9)
+#define BT_EVT_MASK_AMP_TEST_END BT_EVT_BIT(10)
+#define BT_EVT_MASK_AMP_RX_REPORT BT_EVT_BIT(11)
+#define BT_EVT_MASK_AMP_SR_MODE_CHANGE_COMPLETE BT_EVT_BIT(12)
+#define BT_EVT_MASK_AMP_STATUS_CHANGE BT_EVT_BIT(13)
+#define BT_EVT_MASK_TRIGG_CLOCK_CAPTURE BT_EVT_BIT(14)
+#define BT_EVT_MASK_SYNCH_TRAIN_COMPLETE BT_EVT_BIT(15)
+#define BT_EVT_MASK_SYNCH_TRAIN_RX BT_EVT_BIT(16)
+#define BT_EVT_MASK_CL_SLAVE_BC_RX BT_EVT_BIT(17)
+#define BT_EVT_MASK_CL_SLAVE_BC_TIMEOUT BT_EVT_BIT(18)
+#define BT_EVT_MASK_TRUNC_PAGE_COMPLETE BT_EVT_BIT(19)
+#define BT_EVT_MASK_SLAVE_PAGE_RSP_TIMEOUT BT_EVT_BIT(20)
+#define BT_EVT_MASK_CL_SLAVE_BC_CH_MAP_CHANGE BT_EVT_BIT(21)
+#define BT_EVT_MASK_INQUIRY_RSP_NOT BT_EVT_BIT(22)
+#define BT_EVT_MASK_AUTH_PAYLOAD_TIMEOUT_EXP BT_EVT_BIT(23)
+#define BT_EVT_MASK_SAM_STATUS_CHANGE BT_EVT_BIT(24)
+
+#define BT_EVT_MASK_LE_CONN_COMPLETE BT_EVT_BIT(0)
+#define BT_EVT_MASK_LE_ADVERTISING_REPORT BT_EVT_BIT(1)
+#define BT_EVT_MASK_LE_CONN_UPDATE_COMPLETE BT_EVT_BIT(2)
+#define BT_EVT_MASK_LE_REMOTE_FEAT_COMPLETE BT_EVT_BIT(3)
+#define BT_EVT_MASK_LE_LTK_REQUEST BT_EVT_BIT(4)
+#define BT_EVT_MASK_LE_CONN_PARAM_REQ BT_EVT_BIT(5)
+#define BT_EVT_MASK_LE_DATA_LEN_CHANGE BT_EVT_BIT(6)
+#define BT_EVT_MASK_LE_P256_PUBLIC_KEY_COMPLETE BT_EVT_BIT(7)
+#define BT_EVT_MASK_LE_GENERATE_DHKEY_COMPLETE BT_EVT_BIT(8)
+#define BT_EVT_MASK_LE_ENH_CONN_COMPLETE BT_EVT_BIT(9)
+#define BT_EVT_MASK_LE_DIRECT_ADV_REPORT BT_EVT_BIT(10)
+#define BT_EVT_MASK_LE_PHY_UPDATE_COMPLETE BT_EVT_BIT(11)
+#define BT_EVT_MASK_LE_EXT_ADVERTISING_REPORT BT_EVT_BIT(12)
+#define BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED BT_EVT_BIT(13)
+#define BT_EVT_MASK_LE_PER_ADVERTISING_REPORT BT_EVT_BIT(14)
+#define BT_EVT_MASK_LE_PER_ADV_SYNC_LOST BT_EVT_BIT(15)
+#define BT_EVT_MASK_LE_SCAN_TIMEOUT BT_EVT_BIT(16)
+#define BT_EVT_MASK_LE_ADV_SET_TERMINATED BT_EVT_BIT(17)
+#define BT_EVT_MASK_LE_SCAN_REQ_RECEIVED BT_EVT_BIT(18)
+#define BT_EVT_MASK_LE_CHAN_SEL_ALGO BT_EVT_BIT(19)
+
+//
+
+#endif /* ZEPHYR_INCLUDE_BLUETOOTH_HCI_H_ */
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/hci_err.h b/devices/ble_hci/common-hal/_bleio/hci_include/hci_err.h
new file mode 100644
index 000000000..476d3f463
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/hci_err.h
@@ -0,0 +1,92 @@
+/** @file
+ * @brief Bluetooth Host Control Interface status codes.
+ */
+
+/*
+ * Copyright (c) 2019 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef ZEPHYR_INCLUDE_BLUETOOTH_HCI_STATUS_H_
+#define ZEPHYR_INCLUDE_BLUETOOTH_HCI_STATUS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** HCI Error Codes, BT Core Spec v5.2 [Vol 1, Part F]. */
+#define BT_HCI_ERR_SUCCESS 0x00
+#define BT_HCI_ERR_UNKNOWN_CMD 0x01
+#define BT_HCI_ERR_UNKNOWN_CONN_ID 0x02
+#define BT_HCI_ERR_HW_FAILURE 0x03
+#define BT_HCI_ERR_PAGE_TIMEOUT 0x04
+#define BT_HCI_ERR_AUTH_FAIL 0x05
+#define BT_HCI_ERR_PIN_OR_KEY_MISSING 0x06
+#define BT_HCI_ERR_MEM_CAPACITY_EXCEEDED 0x07
+#define BT_HCI_ERR_CONN_TIMEOUT 0x08
+#define BT_HCI_ERR_CONN_LIMIT_EXCEEDED 0x09
+#define BT_HCI_ERR_SYNC_CONN_LIMIT_EXCEEDED 0x0a
+#define BT_HCI_ERR_CONN_ALREADY_EXISTS 0x0b
+#define BT_HCI_ERR_CMD_DISALLOWED 0x0c
+#define BT_HCI_ERR_INSUFFICIENT_RESOURCES 0x0d
+#define BT_HCI_ERR_INSUFFICIENT_SECURITY 0x0e
+#define BT_HCI_ERR_BD_ADDR_UNACCEPTABLE 0x0f
+#define BT_HCI_ERR_CONN_ACCEPT_TIMEOUT 0x10
+#define BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL 0x11
+#define BT_HCI_ERR_INVALID_PARAM 0x12
+#define BT_HCI_ERR_REMOTE_USER_TERM_CONN 0x13
+#define BT_HCI_ERR_REMOTE_LOW_RESOURCES 0x14
+#define BT_HCI_ERR_REMOTE_POWER_OFF 0x15
+#define BT_HCI_ERR_LOCALHOST_TERM_CONN 0x16
+#define BT_HCI_ERR_REPEATED_ATTEMPTS 0x17
+#define BT_HCI_ERR_PAIRING_NOT_ALLOWED 0x18
+#define BT_HCI_ERR_UNKNOWN_LMP_PDU 0x19
+#define BT_HCI_ERR_UNSUPP_REMOTE_FEATURE 0x1a
+#define BT_HCI_ERR_SCO_OFFSET_REJECTED 0x1b
+#define BT_HCI_ERR_SCO_INTERVAL_REJECTED 0x1c
+#define BT_HCI_ERR_SCO_AIR_MODE_REJECTED 0x1d
+#define BT_HCI_ERR_INVALID_LL_PARAM 0x1e
+#define BT_HCI_ERR_UNSPECIFIED 0x1f
+#define BT_HCI_ERR_UNSUPP_LL_PARAM_VAL 0x20
+#define BT_HCI_ERR_ROLE_CHANGE_NOT_ALLOWED 0x21
+#define BT_HCI_ERR_LL_RESP_TIMEOUT 0x22
+#define BT_HCI_ERR_LL_PROC_COLLISION 0x23
+#define BT_HCI_ERR_LMP_PDU_NOT_ALLOWED 0x24
+#define BT_HCI_ERR_ENC_MODE_NOT_ACCEPTABLE 0x25
+#define BT_HCI_ERR_LINK_KEY_CANNOT_BE_CHANGED 0x26
+#define BT_HCI_ERR_REQUESTED_QOS_NOT_SUPPORTED 0x27
+#define BT_HCI_ERR_INSTANT_PASSED 0x28
+#define BT_HCI_ERR_PAIRING_NOT_SUPPORTED 0x29
+#define BT_HCI_ERR_DIFF_TRANS_COLLISION 0x2a
+#define BT_HCI_ERR_QOS_UNACCEPTABLE_PARAM 0x2c
+#define BT_HCI_ERR_QOS_REJECTED 0x2d
+#define BT_HCI_ERR_CHAN_ASSESS_NOT_SUPPORTED 0x2e
+#define BT_HCI_ERR_INSUFF_SECURITY 0x2f
+#define BT_HCI_ERR_PARAM_OUT_OF_MANDATORY_RANGE 0x30
+#define BT_HCI_ERR_ROLE_SWITCH_PENDING 0x32
+#define BT_HCI_ERR_RESERVED_SLOT_VIOLATION 0x34
+#define BT_HCI_ERR_ROLE_SWITCH_FAILED 0x35
+#define BT_HCI_ERR_EXT_INQ_RESP_TOO_LARGE 0x36
+#define BT_HCI_ERR_SIMPLE_PAIR_NOT_SUPP_BY_HOST 0x37
+#define BT_HCI_ERR_HOST_BUSY_PAIRING 0x38
+#define BT_HCI_ERR_CONN_REJECTED_DUE_TO_NO_CHAN 0x39
+#define BT_HCI_ERR_CONTROLLER_BUSY 0x3a
+#define BT_HCI_ERR_UNACCEPT_CONN_PARAM 0x3b
+#define BT_HCI_ERR_ADV_TIMEOUT 0x3c
+#define BT_HCI_ERR_TERM_DUE_TO_MIC_FAIL 0x3d
+#define BT_HCI_ERR_CONN_FAIL_TO_ESTAB 0x3e
+#define BT_HCI_ERR_MAC_CONN_FAILED 0x3f
+#define BT_HCI_ERR_CLOCK_ADJUST_REJECTED 0x40
+#define BT_HCI_ERR_SUBMAP_NOT_DEFINED 0x41
+#define BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER 0x42
+#define BT_HCI_ERR_LIMIT_REACHED 0x43
+#define BT_HCI_ERR_OP_CANCELLED_BY_HOST 0x44
+#define BT_HCI_ERR_PACKET_TOO_LONG 0x45
+
+#define BT_HCI_ERR_AUTHENTICATION_FAIL __DEPRECATED_MACRO BT_HCI_ERR_AUTH_FAIL
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZEPHYR_INCLUDE_BLUETOOTH_HCI_STATUS_H_ */
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/hci_raw.h b/devices/ble_hci/common-hal/_bleio/hci_include/hci_raw.h
new file mode 100644
index 000000000..030fb0ca3
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/hci_raw.h
@@ -0,0 +1,152 @@
+/** @file
+ * @brief Bluetooth HCI RAW channel handling
+ */
+
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef ZEPHYR_INCLUDE_BLUETOOTH_HCI_RAW_H_
+#define ZEPHYR_INCLUDE_BLUETOOTH_HCI_RAW_H_
+
+/**
+ * @brief HCI RAW channel
+ * @defgroup hci_raw HCI RAW channel
+ * @ingroup bluetooth
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(CONFIG_BT_CTLR_TX_BUFFER_SIZE)
+#define BT_L2CAP_MTU (CONFIG_BT_CTLR_TX_BUFFER_SIZE - BT_L2CAP_HDR_SIZE)
+#else
+#define BT_L2CAP_MTU 65 /* 64-byte public key + opcode */
+#endif /* CONFIG_BT_CTLR */
+
+/** Data size needed for ACL buffers */
+#define BT_BUF_ACL_SIZE BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU)
+
+#if defined(CONFIG_BT_CTLR_TX_BUFFERS)
+#define BT_HCI_ACL_COUNT CONFIG_BT_CTLR_TX_BUFFERS
+#else
+#define BT_HCI_ACL_COUNT 6
+#endif
+
+#define BT_BUF_TX_SIZE MAX(BT_BUF_RX_SIZE, BT_BUF_ACL_SIZE)
+
+/** @brief Send packet to the Bluetooth controller
+ *
+ * Send packet to the Bluetooth controller. Caller needs to
+ * implement netbuf pool.
+ *
+ * @param buf netbuf packet to be send
+ *
+ * @return Zero on success or (negative) error code otherwise.
+ */
+int bt_send(struct net_buf *buf);
+
+enum {
+ /** Passthrough mode
+ *
+ * While in this mode the buffers are passed as is between the stack
+ * and the driver.
+ */
+ BT_HCI_RAW_MODE_PASSTHROUGH = 0x00,
+
+ /** H:4 mode
+ *
+ * While in this mode H:4 headers will added into the buffers
+ * according to the buffer type when coming from the stack and will be
+ * removed and used to set the buffer type.
+ */
+ BT_HCI_RAW_MODE_H4 = 0x01,
+};
+
+/** @brief Set Bluetooth RAW channel mode
+ *
+ * Set access mode of Bluetooth RAW channel.
+ *
+ * @param mode Access mode.
+ *
+ * @return Zero on success or (negative) error code otherwise.
+ */
+int bt_hci_raw_set_mode(uint8_t mode);
+
+/** @brief Get Bluetooth RAW channel mode
+ *
+ * Get access mode of Bluetooth RAW channel.
+ *
+ * @return Access mode.
+ */
+uint8_t bt_hci_raw_get_mode(void);
+
+#define BT_HCI_ERR_EXT_HANDLED 0xff
+
+/** Helper macro to define a command extension
+ *
+ * @param _op Opcode of the command.
+ * @param _min_len Minimal length of the command.
+ * @param _func Handler function to be called.
+ */
+#define BT_HCI_RAW_CMD_EXT(_op, _min_len, _func) \
+ { \
+ .op = _op, \
+ .min_len = _min_len, \
+ .func = _func, \
+ }
+
+struct bt_hci_raw_cmd_ext {
+ /** Opcode of the command */
+ uint16_t op;
+
+ /** Minimal length of the command */
+ size_t min_len;
+
+ /** Handler function.
+ *
+ * Handler function to be called when a command is intercepted.
+ *
+ * @param buf Buffer containing the command.
+ *
+ * @return HCI Status code or BT_HCI_ERR_EXT_HANDLED if command has
+ * been handled already and a response has been sent as oppose to
+ * BT_HCI_ERR_SUCCESS which just indicates that the command can be
+ * sent to the controller to be processed.
+ */
+ uint8_t (*func)(struct net_buf *buf);
+};
+
+/** @brief Register Bluetooth RAW command extension table
+ *
+ * Register Bluetooth RAW channel command extension table, opcodes in this
+ * table are intercepted to sent to the handler function.
+ *
+ * @param cmds Pointer to the command extension table.
+ * @param size Size of the command extension table.
+ */
+void bt_hci_raw_cmd_ext_register(struct bt_hci_raw_cmd_ext *cmds, size_t size);
+
+/** @brief Enable Bluetooth RAW channel:
+ *
+ * Enable Bluetooth RAW HCI channel.
+ *
+ * @param rx_queue netbuf queue where HCI packets received from the Bluetooth
+ * controller are to be queued. The queue is defined in the caller while
+ * the available buffers pools are handled in the stack.
+ *
+ * @return Zero on success or (negative) error code otherwise.
+ */
+int bt_enable_raw(struct k_fifo *rx_queue);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+
+#endif /* ZEPHYR_INCLUDE_BLUETOOTH_HCI_RAW_H_ */
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/hci_vs.h b/devices/ble_hci/common-hal/_bleio/hci_include/hci_vs.h
new file mode 100644
index 000000000..e4f94b6a8
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/hci_vs.h
@@ -0,0 +1,379 @@
+/* hci_vs.h - Bluetooth Host Control Interface Vendor Specific definitions */
+
+/*
+ * Copyright (c) 2017-2018 Nordic Semiconductor ASA
+ * Copyright (c) 2015-2016 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef ZEPHYR_INCLUDE_BLUETOOTH_HCI_VS_H_
+#define ZEPHYR_INCLUDE_BLUETOOTH_HCI_VS_H_
+
+#include <bluetooth/hci.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BT_VS_CMD_BIT_VERSION 0
+#define BT_VS_CMD_BIT_SUP_CMD 1
+#define BT_VS_CMD_BIT_SUP_FEAT 2
+#define BT_VS_CMD_BIT_SET_EVT_MASK 3
+#define BT_VS_CMD_BIT_RESET 4
+#define BT_VS_CMD_BIT_WRITE_BDADDR 5
+#define BT_VS_CMD_BIT_SET_TRACE_ENABLE 6
+#define BT_VS_CMD_BIT_READ_BUILD_INFO 7
+#define BT_VS_CMD_BIT_READ_STATIC_ADDRS 8
+#define BT_VS_CMD_BIT_READ_KEY_ROOTS 9
+#define BT_VS_CMD_BIT_READ_CHIP_TEMP 10
+#define BT_VS_CMD_BIT_READ_HOST_STACK_CMD 11
+#define BT_VS_CMD_BIT_SET_SCAN_REP_ENABLE 12
+#define BT_VS_CMD_BIT_WRITE_TX_POWER 13
+#define BT_VS_CMD_BIT_READ_TX_POWER 14
+
+#define BT_VS_CMD_SUP_FEAT(cmd) BT_LE_FEAT_TEST(cmd, \
+ BT_VS_CMD_BIT_SUP_FEAT)
+#define BT_VS_CMD_READ_STATIC_ADDRS(cmd) BT_LE_FEAT_TEST(cmd, \
+ BT_VS_CMD_BIT_READ_STATIC_ADDRS)
+#define BT_VS_CMD_READ_KEY_ROOTS(cmd) BT_LE_FEAT_TEST(cmd, \
+ BT_VS_CMD_BIT_READ_KEY_ROOTS)
+
+#define BT_HCI_VS_HW_PLAT_INTEL 0x0001
+#define BT_HCI_VS_HW_PLAT_NORDIC 0x0002
+#define BT_HCI_VS_HW_PLAT_NXP 0x0003
+
+#define BT_HCI_VS_HW_VAR_NORDIC_NRF51X 0x0001
+#define BT_HCI_VS_HW_VAR_NORDIC_NRF52X 0x0002
+#define BT_HCI_VS_HW_VAR_NORDIC_NRF53X 0x0003
+
+#define BT_HCI_VS_FW_VAR_STANDARD_CTLR 0x0001
+#define BT_HCI_VS_FW_VAR_VS_CTLR 0x0002
+#define BT_HCI_VS_FW_VAR_FW_LOADER 0x0003
+#define BT_HCI_VS_FW_VAR_RESCUE_IMG 0x0004
+#define BT_HCI_OP_VS_READ_VERSION_INFO BT_OP(BT_OGF_VS, 0x0001)
+struct bt_hci_rp_vs_read_version_info {
+ uint8_t status;
+ uint16_t hw_platform;
+ uint16_t hw_variant;
+ uint8_t fw_variant;
+ uint8_t fw_version;
+ uint16_t fw_revision;
+ uint32_t fw_build;
+} __packed;
+
+#define BT_HCI_OP_VS_READ_SUPPORTED_COMMANDS BT_OP(BT_OGF_VS, 0x0002)
+struct bt_hci_rp_vs_read_supported_commands {
+ uint8_t status;
+ uint8_t commands[64];
+} __packed;
+
+#define BT_HCI_OP_VS_READ_SUPPORTED_FEATURES BT_OP(BT_OGF_VS, 0x0003)
+struct bt_hci_rp_vs_read_supported_features {
+ uint8_t status;
+ uint8_t features[8];
+} __packed;
+
+#define BT_HCI_OP_VS_SET_EVENT_MASK BT_OP(BT_OGF_VS, 0x0004)
+struct bt_hci_cp_vs_set_event_mask {
+ uint8_t event_mask[8];
+} __packed;
+
+#define BT_HCI_VS_RESET_SOFT 0x00
+#define BT_HCI_VS_RESET_HARD 0x01
+#define BT_HCI_OP_VS_RESET BT_OP(BT_OGF_VS, 0x0005)
+struct bt_hci_cp_vs_reset {
+ uint8_t type;
+} __packed;
+
+#define BT_HCI_OP_VS_WRITE_BD_ADDR BT_OP(BT_OGF_VS, 0x0006)
+struct bt_hci_cp_vs_write_bd_addr {
+ bt_addr_t bdaddr;
+} __packed;
+
+#define BT_HCI_VS_TRACE_DISABLED 0x00
+#define BT_HCI_VS_TRACE_ENABLED 0x01
+
+#define BT_HCI_VS_TRACE_HCI_EVTS 0x00
+#define BT_HCI_VS_TRACE_VDC 0x01
+#define BT_HCI_OP_VS_SET_TRACE_ENABLE BT_OP(BT_OGF_VS, 0x0007)
+struct bt_hci_cp_vs_set_trace_enable {
+ uint8_t enable;
+ uint8_t type;
+} __packed;
+
+#define BT_HCI_OP_VS_READ_BUILD_INFO BT_OP(BT_OGF_VS, 0x0008)
+struct bt_hci_rp_vs_read_build_info {
+ uint8_t status;
+ uint8_t info[0];
+} __packed;
+
+struct bt_hci_vs_static_addr {
+ bt_addr_t bdaddr;
+ uint8_t ir[16];
+} __packed;
+
+#define BT_HCI_OP_VS_READ_STATIC_ADDRS BT_OP(BT_OGF_VS, 0x0009)
+struct bt_hci_rp_vs_read_static_addrs {
+ uint8_t status;
+ uint8_t num_addrs;
+ struct bt_hci_vs_static_addr a[0];
+} __packed;
+
+#define BT_HCI_OP_VS_READ_KEY_HIERARCHY_ROOTS BT_OP(BT_OGF_VS, 0x000a)
+struct bt_hci_rp_vs_read_key_hierarchy_roots {
+ uint8_t status;
+ uint8_t ir[16];
+ uint8_t er[16];
+} __packed;
+
+#define BT_HCI_OP_VS_READ_CHIP_TEMP BT_OP(BT_OGF_VS, 0x000b)
+struct bt_hci_rp_vs_read_chip_temp {
+ uint8_t status;
+ int8_t temps;
+} __packed;
+
+struct bt_hci_vs_cmd {
+ uint16_t vendor_id;
+ uint16_t opcode_base;
+} __packed;
+
+#define BT_HCI_VS_VID_ANDROID 0x0001
+#define BT_HCI_VS_VID_MICROSOFT 0x0002
+#define BT_HCI_OP_VS_READ_HOST_STACK_CMDS BT_OP(BT_OGF_VS, 0x000c)
+struct bt_hci_rp_vs_read_host_stack_cmds {
+ uint8_t status;
+ uint8_t num_cmds;
+ struct bt_hci_vs_cmd c[0];
+} __packed;
+
+#define BT_HCI_VS_SCAN_REQ_REPORTS_DISABLED 0x00
+#define BT_HCI_VS_SCAN_REQ_REPORTS_ENABLED 0x01
+#define BT_HCI_OP_VS_SET_SCAN_REQ_REPORTS BT_OP(BT_OGF_VS, 0x000d)
+struct bt_hci_cp_vs_set_scan_req_reports {
+ uint8_t enable;
+} __packed;
+
+#define BT_HCI_VS_LL_HANDLE_TYPE_ADV 0x00
+#define BT_HCI_VS_LL_HANDLE_TYPE_SCAN 0x01
+#define BT_HCI_VS_LL_HANDLE_TYPE_CONN 0x02
+#define BT_HCI_VS_LL_TX_POWER_LEVEL_NO_PREF 0x7F
+#define BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL BT_OP(BT_OGF_VS, 0x000e)
+struct bt_hci_cp_vs_write_tx_power_level {
+ uint8_t handle_type;
+ uint16_t handle;
+ int8_t tx_power_level;
+} __packed;
+
+struct bt_hci_rp_vs_write_tx_power_level {
+ uint8_t status;
+ uint8_t handle_type;
+ uint16_t handle;
+ int8_t selected_tx_power;
+} __packed;
+
+#define BT_HCI_OP_VS_READ_TX_POWER_LEVEL BT_OP(BT_OGF_VS, 0x000f)
+struct bt_hci_cp_vs_read_tx_power_level {
+ uint8_t handle_type;
+ uint16_t handle;
+} __packed;
+
+struct bt_hci_rp_vs_read_tx_power_level {
+ uint8_t status;
+ uint8_t handle_type;
+ uint16_t handle;
+ int8_t tx_power_level;
+} __packed;
+
+#define BT_HCI_OP_VS_READ_USB_TRANSPORT_MODE BT_OP(BT_OGF_VS, 0x0010)
+
+struct bt_hci_rp_vs_read_usb_transport_mode {
+ uint8_t status;
+ uint8_t num_supported_modes;
+ uint8_t supported_mode[0];
+} __packed;
+
+#define BT_HCI_VS_USB_H2_MODE 0x00
+#define BT_HCI_VS_USB_H4_MODE 0x01
+
+#define BT_HCI_OP_VS_SET_USB_TRANSPORT_MODE BT_OP(BT_OGF_VS, 0x0011)
+
+struct bt_hci_cp_vs_set_usb_transport_mode {
+ uint8_t mode;
+} __packed;
+
+/* Events */
+
+struct bt_hci_evt_vs {
+ uint8_t subevent;
+} __packed;
+
+#define BT_HCI_EVT_VS_FATAL_ERROR 0x02
+struct bt_hci_evt_vs_fatal_error {
+ uint64_t pc;
+ uint8_t err_info[0];
+} __packed;
+
+#define BT_HCI_VS_TRACE_LMP_TX 0x01
+#define BT_HCI_VS_TRACE_LMP_RX 0x02
+#define BT_HCI_VS_TRACE_LLCP_TX 0x03
+#define BT_HCI_VS_TRACE_LLCP_RX 0x04
+#define BT_HCI_VS_TRACE_LE_CONN_IND 0x05
+#define BT_HCI_EVT_VS_TRACE_INFO 0x03
+struct bt_hci_evt_vs_trace_info {
+ uint8_t type;
+ uint8_t data[0];
+} __packed;
+
+#define BT_HCI_EVT_VS_SCAN_REQ_RX 0x04
+struct bt_hci_evt_vs_scan_req_rx {
+ bt_addr_le_t addr;
+ int8_t rssi;
+} __packed;
+
+/* Event mask bits */
+
+#define BT_EVT_MASK_VS_FATAL_ERROR BT_EVT_BIT(1)
+#define BT_EVT_MASK_VS_TRACE_INFO BT_EVT_BIT(2)
+#define BT_EVT_MASK_VS_SCAN_REQ_RX BT_EVT_BIT(3)
+
+/* Mesh HCI commands */
+#define BT_HCI_MESH_REVISION 0x01
+
+#define BT_HCI_OP_VS_MESH BT_OP(BT_OGF_VS, 0x0042)
+#define BT_HCI_MESH_EVT_PREFIX 0xF0
+
+struct bt_hci_cp_mesh {
+ uint8_t opcode;
+} __packed;
+
+#define BT_HCI_OC_MESH_GET_OPTS 0x00
+struct bt_hci_rp_mesh_get_opts {
+ uint8_t status;
+ uint8_t opcode;
+ uint8_t revision;
+ uint8_t ch_map;
+ int8_t min_tx_power;
+ int8_t max_tx_power;
+ uint8_t max_scan_filter;
+ uint8_t max_filter_pattern;
+ uint8_t max_adv_slot;
+ uint8_t max_tx_window;
+ uint8_t evt_prefix_len;
+ uint8_t evt_prefix;
+} __packed;
+
+#define BT_HCI_MESH_PATTERN_LEN_MAX 0x0f
+
+#define BT_HCI_OC_MESH_SET_SCAN_FILTER 0x01
+struct bt_hci_mesh_pattern {
+ uint8_t pattern_len;
+ uint8_t pattern[0];
+} __packed;
+
+struct bt_hci_cp_mesh_set_scan_filter {
+ uint8_t scan_filter;
+ uint8_t filter_dup;
+ uint8_t num_patterns;
+ struct bt_hci_mesh_pattern patterns[0];
+} __packed;
+struct bt_hci_rp_mesh_set_scan_filter {
+ uint8_t status;
+ uint8_t opcode;
+ uint8_t scan_filter;
+} __packed;
+
+#define BT_HCI_OC_MESH_ADVERTISE 0x02
+struct bt_hci_cp_mesh_advertise {
+ uint8_t adv_slot;
+ uint8_t own_addr_type;
+ bt_addr_t random_addr;
+ uint8_t ch_map;
+ int8_t tx_power;
+ uint8_t min_tx_delay;
+ uint8_t max_tx_delay;
+ uint8_t retx_count;
+ uint8_t retx_interval;
+ uint8_t scan_delay;
+ uint16_t scan_duration;
+ uint8_t scan_filter;
+ uint8_t data_len;
+ uint8_t data[31];
+} __packed;
+struct bt_hci_rp_mesh_advertise {
+ uint8_t status;
+ uint8_t opcode;
+ uint8_t adv_slot;
+} __packed;
+
+#define BT_HCI_OC_MESH_ADVERTISE_TIMED 0x03
+struct bt_hci_cp_mesh_advertise_timed {
+ uint8_t adv_slot;
+ uint8_t own_addr_type;
+ bt_addr_t random_addr;
+ uint8_t ch_map;
+ int8_t tx_power;
+ uint8_t retx_count;
+ uint8_t retx_interval;
+ uint32_t instant;
+ uint16_t tx_delay;
+ uint16_t tx_window;
+ uint8_t data_len;
+ uint8_t data[31];
+} __packed;
+struct bt_hci_rp_mesh_advertise_timed {
+ uint8_t status;
+ uint8_t opcode;
+ uint8_t adv_slot;
+} __packed;
+
+#define BT_HCI_OC_MESH_ADVERTISE_CANCEL 0x04
+struct bt_hci_cp_mesh_advertise_cancel {
+ uint8_t adv_slot;
+} __packed;
+struct bt_hci_rp_mesh_advertise_cancel {
+ uint8_t status;
+ uint8_t opcode;
+ uint8_t adv_slot;
+} __packed;
+
+#define BT_HCI_OC_MESH_SET_SCANNING 0x05
+struct bt_hci_cp_mesh_set_scanning {
+ uint8_t enable;
+ uint8_t ch_map;
+ uint8_t scan_filter;
+} __packed;
+struct bt_hci_rp_mesh_set_scanning {
+ uint8_t status;
+ uint8_t opcode;
+} __packed;
+
+/* Events */
+struct bt_hci_evt_mesh {
+ uint8_t prefix;
+ uint8_t subevent;
+} __packed;
+
+#define BT_HCI_EVT_MESH_ADV_COMPLETE 0x00
+struct bt_hci_evt_mesh_adv_complete {
+ uint8_t adv_slot;
+} __packed;
+
+#define BT_HCI_EVT_MESH_SCANNING_REPORT 0x01
+struct bt_hci_evt_mesh_scan_report {
+ bt_addr_le_t addr;
+ uint8_t chan;
+ int8_t rssi;
+ uint32_t instant;
+ uint8_t data_len;
+ uint8_t data[0];
+} __packed;
+struct bt_hci_evt_mesh_scanning_report {
+ uint8_t num_reports;
+ struct bt_hci_evt_mesh_scan_report reports[0];
+} __packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZEPHYR_INCLUDE_BLUETOOTH_HCI_VS_H_ */
diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/l2cap_internal.h b/devices/ble_hci/common-hal/_bleio/hci_include/l2cap_internal.h
new file mode 100644
index 000000000..bed311cf3
--- /dev/null
+++ b/devices/ble_hci/common-hal/_bleio/hci_include/l2cap_internal.h
@@ -0,0 +1,230 @@
+// CircuitPython: Adapted from Zephyr include file.
+
+/** @file
+ * @brief Internal APIs for Bluetooth L2CAP handling.
+ */
+
+/*
+ * Copyright (c) 2015-2016 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdbool.h>
+// for __packed
+#include <string.h>
+
+enum l2cap_conn_list_action {
+ BT_L2CAP_CHAN_LOOKUP,
+ BT_L2CAP_CHAN_DETACH,
+};
+
+#define BT_L2CAP_CID_BR_SIG 0x0001
+#define BT_L2CAP_CID_ATT 0x0004
+#define BT_L2CAP_CID_LE_SIG 0x0005
+#define BT_L2CAP_CID_SMP 0x0006
+#define BT_L2CAP_CID_BR_SMP 0x0007
+
+#define BT_L2CAP_PSM_RFCOMM 0x0003
+
+struct bt_l2cap_hdr {
+ uint16_t len;
+ uint16_t cid;
+} __packed;
+
+struct bt_l2cap_sig_hdr {
+ uint8_t code;
+ uint8_t ident;
+ uint16_t len;
+} __packed;
+
+#define BT_L2CAP_REJ_NOT_UNDERSTOOD 0x0000
+#define BT_L2CAP_REJ_MTU_EXCEEDED 0x0001
+#define BT_L2CAP_REJ_INVALID_CID 0x0002
+
+#define BT_L2CAP_CMD_REJECT 0x01
+struct bt_l2cap_cmd_reject {
+ uint16_t reason;
+ uint8_t data[0];
+} __packed;
+
+struct bt_l2cap_cmd_reject_cid_data {
+ uint16_t scid;
+ uint16_t dcid;
+} __packed;
+
+#define BT_L2CAP_CONN_REQ 0x02
+struct bt_l2cap_conn_req {
+ uint16_t psm;
+ uint16_t scid;
+} __packed;
+
+/* command statuses in reposnse */
+#define BT_L2CAP_CS_NO_INFO 0x0000
+#define BT_L2CAP_CS_AUTHEN_PEND 0x0001
+
+/* valid results in conn response on BR/EDR */
+#define BT_L2CAP_BR_SUCCESS 0x0000
+#define BT_L2CAP_BR_PENDING 0x0001
+#define BT_L2CAP_BR_ERR_PSM_NOT_SUPP 0x0002
+#define BT_L2CAP_BR_ERR_SEC_BLOCK 0x0003
+#define BT_L2CAP_BR_ERR_NO_RESOURCES 0x0004
+#define BT_L2CAP_BR_ERR_INVALID_SCID 0x0006
+#define BT_L2CAP_BR_ERR_SCID_IN_USE 0x0007
+
+#define BT_L2CAP_CONN_RSP 0x03
+struct bt_l2cap_conn_rsp {
+ uint16_t dcid;
+ uint16_t scid;
+ uint16_t result;
+ uint16_t status;
+} __packed;
+
+#define BT_L2CAP_CONF_SUCCESS 0x0000
+#define BT_L2CAP_CONF_UNACCEPT 0x0001
+#define BT_L2CAP_CONF_REJECT 0x0002
+
+#define BT_L2CAP_CONF_REQ 0x04
+struct bt_l2cap_conf_req {
+ uint16_t dcid;
+ uint16_t flags;
+ uint8_t data[0];
+} __packed;
+
+#define BT_L2CAP_CONF_RSP 0x05
+struct bt_l2cap_conf_rsp {
+ uint16_t scid;
+ uint16_t flags;
+ uint16_t result;
+ uint8_t data[0];
+} __packed;
+
+/* Option type used by MTU config request data */
+#define BT_L2CAP_CONF_OPT_MTU 0x01
+/* Options bits selecting most significant bit (hint) in type field */
+#define BT_L2CAP_CONF_HINT 0x80
+#define BT_L2CAP_CONF_MASK 0x7f
+
+struct bt_l2cap_conf_opt {
+ uint8_t type;
+ uint8_t len;
+ uint8_t data[0];
+} __packed;
+
+#define BT_L2CAP_DISCONN_REQ 0x06
+struct bt_l2cap_disconn_req {
+ uint16_t dcid;
+ uint16_t scid;
+} __packed;
+
+#define BT_L2CAP_DISCONN_RSP 0x07
+struct bt_l2cap_disconn_rsp {
+ uint16_t dcid;
+ uint16_t scid;
+} __packed;
+
+#define BT_L2CAP_INFO_FEAT_MASK 0x0002
+#define BT_L2CAP_INFO_FIXED_CHAN 0x0003
+
+#define BT_L2CAP_INFO_REQ 0x0a
+struct bt_l2cap_info_req {
+ uint16_t type;
+} __packed;
+
+/* info result */
+#define BT_L2CAP_INFO_SUCCESS 0x0000
+#define BT_L2CAP_INFO_NOTSUPP 0x0001
+
+#define BT_L2CAP_INFO_RSP 0x0b
+struct bt_l2cap_info_rsp {
+ uint16_t type;
+ uint16_t result;
+ uint8_t data[0];
+} __packed;
+
+#define BT_L2CAP_CONN_PARAM_REQ 0x12
+struct bt_l2cap_conn_param_req {
+ uint16_t min_interval;
+ uint16_t max_interval;
+ uint16_t latency;
+ uint16_t timeout;
+} __packed;
+
+#define BT_L2CAP_CONN_PARAM_ACCEPTED 0x0000
+#define BT_L2CAP_CONN_PARAM_REJECTED 0x0001
+
+#define BT_L2CAP_CONN_PARAM_RSP 0x13
+struct bt_l2cap_conn_param_rsp {
+ uint16_t result;
+} __packed;
+
+#define BT_L2CAP_LE_CONN_REQ 0x14
+struct bt_l2cap_le_conn_req {
+ uint16_t psm;
+ uint16_t scid;
+ uint16_t mtu;
+ uint16_t mps;
+ uint16_t credits;
+} __packed;
+
+/* valid results in conn response on LE */
+#define BT_L2CAP_LE_SUCCESS 0x0000
+#define BT_L2CAP_LE_ERR_PSM_NOT_SUPP 0x0002
+#define BT_L2CAP_LE_ERR_NO_RESOURCES 0x0004
+#define BT_L2CAP_LE_ERR_AUTHENTICATION 0x0005
+#define BT_L2CAP_LE_ERR_AUTHORIZATION 0x0006
+#define BT_L2CAP_LE_ERR_KEY_SIZE 0x0007
+#define BT_L2CAP_LE_ERR_ENCRYPTION 0x0008
+#define BT_L2CAP_LE_ERR_INVALID_SCID 0x0009
+#define BT_L2CAP_LE_ERR_SCID_IN_USE 0x000A
+#define BT_L2CAP_LE_ERR_UNACCEPT_PARAMS 0x000B
+#define BT_L2CAP_LE_ERR_INVALID_PARAMS 0x000C
+
+#define BT_L2CAP_LE_CONN_RSP 0x15
+struct bt_l2cap_le_conn_rsp {
+ uint16_t dcid;
+ uint16_t mtu;
+ uint16_t mps;
+ uint16_t credits;
+ uint16_t result;
+} __packed;
+
+#define BT_L2CAP_LE_CREDITS 0x16
+struct bt_l2cap_le_credits {
+ uint16_t cid;
+ uint16_t credits;
+} __packed;
+
+#define BT_L2CAP_ECRED_CONN_REQ 0x17
+struct bt_l2cap_ecred_conn_req {
+ uint16_t psm;
+ uint16_t mtu;
+ uint16_t mps;
+ uint16_t credits;
+ uint16_t scid[0];
+} __packed;
+
+#define BT_L2CAP_ECRED_CONN_RSP 0x18
+struct bt_l2cap_ecred_conn_rsp {
+ uint16_t mtu;
+ uint16_t mps;
+ uint16_t credits;
+ uint16_t result;
+ uint16_t dcid[0];
+} __packed;
+
+#define BT_L2CAP_ECRED_RECONF_REQ 0x19
+struct bt_l2cap_ecred_reconf_req {
+ uint16_t mtu;
+ uint16_t mps;
+ uint16_t scid[0];
+} __packed;
+
+#define BT_L2CAP_RECONF_SUCCESS 0x0000
+#define BT_L2CAP_RECONF_INVALID_MTU 0x0001
+#define BT_L2CAP_RECONF_INVALID_MPS 0x0002
+
+#define BT_L2CAP_ECRED_RECONF_RSP 0x1a
+struct bt_l2cap_ecred_reconf_rsp {
+ uint16_t result;
+} __packed;
diff --git a/devices/ble_hci/supervisor/bluetooth.c b/devices/ble_hci/supervisor/bluetooth.c
new file mode 100644
index 000000000..83a46728e
--- /dev/null
+++ b/devices/ble_hci/supervisor/bluetooth.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if CIRCUITPY_BLE_FILE_SERVICE
+#error CIRCUITPY_BLE_FILE_SERVICE not implemented for CIRCUITPY_BLEIO_HCI
+#endif
diff --git a/devices/ble_hci/supervisor/bluetooth.h b/devices/ble_hci/supervisor/bluetooth.h
new file mode 100644
index 000000000..03645829b
--- /dev/null
+++ b/devices/ble_hci/supervisor/bluetooth.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_DEVICE_BLE_HCI_SUPERVISOR_BLUETOOTH_H
+#define MICROPY_INCLUDED_DEVICE_BLE_HCI_SUPERVISOR_BLUETOOTH_H
+
+void supervisor_start_bluetooth(void);
+bool supervisor_bluetooth_hook(ble_evt_t *ble_evt);
+void supervisor_bluetooth_background(void);
+
+#endif // MICROPY_INCLUDED_DEVICE_BLE_HCI_SUPERVISOR_BLUETOOTH_H
diff --git a/lib/protomatter b/lib/protomatter
-Subproject 761d6437e8cd6a131d51de96974337121a9c716
+Subproject 2a1ba8fa4753b2bcb158c9b17351cf18eade0d2
diff --git a/locale/ID.po b/locale/ID.po
index ec5b6f6e8..dd41b740f 100644
--- a/locale/ID.po
+++ b/locale/ID.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2020-07-06 18:10+0000\n"
"Last-Translator: oon arfiandwi <oon.arfiandwi@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -308,7 +308,7 @@ msgstr "Semua channel event sedang digunakan"
msgid "All sync event channels in use"
msgstr "Semua channel event yang disinkronisasi sedang digunakan"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Semua timer untuk pin ini sedang digunakan"
@@ -320,7 +320,7 @@ msgstr "Semua timer untuk pin ini sedang digunakan"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Semua timer sedang digunakan"
@@ -498,6 +498,10 @@ msgstr "Panggil super().__init__() sebelum mengakses objek asli."
msgid "Can't set CCCD on local Characteristic"
msgstr "Tidak dapat mengatur CCCD pada Karakteristik lokal"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -566,7 +570,7 @@ msgstr "Tidak dapat transfer tanpa pin MOSI dan MISO."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "tidak dapat mendapatkan ukuran scalar secara tidak ambigu"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
"Tidak dapat membuat variasi frekuensi pada penghitung waktu yang sudah "
@@ -640,23 +644,23 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Tidak dapat menginisialisasi UART"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "Tidak dapat menginisialisasi kanal"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "Tidak dapat menginisialisasi timer"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "Tidak dapat menginisialisasi ulang kanal"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "Tidak dapat menginisialisasi ulang timer"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "Tidak dapat memulai ulang PWM"
@@ -664,7 +668,7 @@ msgstr "Tidak dapat memulai ulang PWM"
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "Tidak dapat memulai PWM"
@@ -762,8 +766,8 @@ msgstr "Channel EXTINT sedang digunakan"
msgid "Error in regex"
msgstr "Error pada regex"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -774,10 +778,18 @@ msgstr "Diharapkan %q"
msgid "Expected a Characteristic"
msgstr "Diharapkan sebuah Karakteristik"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Diharapkan sebuah Layanan"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -857,7 +869,7 @@ msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
"Frekuensi yang ditangkap berada di atas kemampuan. Penangkapan Ditunda."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr "Frekuensi harus cocok dengan PWMOut yang ada menggunakan timer ini"
@@ -961,9 +973,9 @@ msgstr "File BMP tidak valid"
msgid "Invalid DAC pin supplied"
msgstr "Pin DAC yang diberikan tidak valid"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Frekuensi PWM tidak valid"
@@ -1003,7 +1015,7 @@ msgstr "File tidak valid"
msgid "Invalid format chunk size"
msgstr "Ukuran potongan format tidak valid"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "Frekuensi yang diberikan tidak valid"
@@ -1021,8 +1033,8 @@ msgid "Invalid phase"
msgstr "Fase tidak valid"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Pin tidak valid"
@@ -1046,7 +1058,7 @@ msgstr "Pin untuk channel kanan tidak valid"
msgid "Invalid pins"
msgstr "Pin-pin tidak valid"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "Pin untuk PWMOut tidak valid"
@@ -1228,7 +1240,7 @@ msgstr ""
msgid "No long integer support"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@@ -1267,6 +1279,10 @@ msgstr ""
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1297,12 +1313,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1357,8 +1373,8 @@ msgstr ""
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1375,10 +1391,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr ""
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr ""
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr ""
@@ -1591,7 +1603,7 @@ msgstr ""
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2488,6 +2500,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "inline assembler harus sebuah fungsi"
@@ -2680,6 +2696,10 @@ msgstr ""
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2915,6 +2935,14 @@ msgstr ""
msgid "ord() expected a character, but string of length %d found"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr ""
@@ -3092,6 +3120,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr ""
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index 5122e7ba8..d0a314d0c 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-09-03 15:16-0700\n"
+"POT-Creation-Date: 2020-09-03 16:33-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -494,6 +494,10 @@ msgstr ""
msgid "Can't set CCCD on local Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -746,8 +750,8 @@ msgstr ""
msgid "Error in regex"
msgstr ""
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -758,10 +762,18 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -1255,6 +1267,10 @@ msgstr ""
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -2477,6 +2493,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr ""
@@ -2669,6 +2689,10 @@ msgstr ""
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
diff --git a/locale/cs.po b/locale/cs.po
index b353f4630..cd81c258f 100644
--- a/locale/cs.po
+++ b/locale/cs.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2020-05-24 03:22+0000\n"
"Last-Translator: dronecz <mzuzelka@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -308,7 +308,7 @@ msgstr ""
msgid "All sync event channels in use"
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr ""
@@ -320,7 +320,7 @@ msgstr ""
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr ""
@@ -496,6 +496,10 @@ msgstr ""
msgid "Can't set CCCD on local Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -558,7 +562,7 @@ msgstr ""
msgid "Cannot unambiguously get sizeof scalar"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
@@ -627,23 +631,23 @@ msgstr ""
msgid "Could not initialize UART"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr ""
@@ -651,7 +655,7 @@ msgstr ""
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr ""
@@ -748,8 +752,8 @@ msgstr ""
msgid "Error in regex"
msgstr ""
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -760,10 +764,18 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -842,7 +854,7 @@ msgstr ""
msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
@@ -944,9 +956,9 @@ msgstr ""
msgid "Invalid DAC pin supplied"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr ""
@@ -986,7 +998,7 @@ msgstr ""
msgid "Invalid format chunk size"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr ""
@@ -1004,8 +1016,8 @@ msgid "Invalid phase"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr ""
@@ -1029,7 +1041,7 @@ msgstr ""
msgid "Invalid pins"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr ""
@@ -1211,7 +1223,7 @@ msgstr ""
msgid "No long integer support"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@@ -1249,6 +1261,10 @@ msgstr ""
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1279,12 +1295,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1339,8 +1355,8 @@ msgstr ""
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1355,10 +1371,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr ""
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr ""
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr ""
@@ -1570,7 +1582,7 @@ msgstr ""
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2459,6 +2471,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr ""
@@ -2651,6 +2667,10 @@ msgstr ""
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2885,6 +2905,14 @@ msgstr ""
msgid "ord() expected a character, but string of length %d found"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr ""
@@ -3062,6 +3090,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr ""
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 87cca4a77..3debbcb62 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2020-06-16 18:24+0000\n"
"Last-Translator: Andreas Buchen <andreas.buchen@gmail.com>\n"
"Language: de_DE\n"
@@ -307,7 +307,7 @@ msgstr "Alle event Kanäle werden benutzt"
msgid "All sync event channels in use"
msgstr "Alle sync event Kanäle werden benutzt"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Alle timer für diesen Pin werden bereits benutzt"
@@ -319,7 +319,7 @@ msgstr "Alle timer für diesen Pin werden bereits benutzt"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Alle timer werden benutzt"
@@ -499,6 +499,10 @@ msgstr "Rufe super().__init__() vor dem Zugriff auf ein natives Objekt auf."
msgid "Can't set CCCD on local Characteristic"
msgstr "CCCD kann nicht auf lokales Merkmal eingestellt werden"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -562,7 +566,7 @@ msgstr "Übertragung ohne MOSI- und MISO-Pins nicht möglich."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "sizeof scalar kann nicht eindeutig bestimmt werden"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
"Die Frequenz eines bereits verwendeten Timers kann nicht variiert werden"
@@ -637,23 +641,23 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Konnte UART nicht initialisieren"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "Kanal konnte nicht initialisiert werden"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "Timer konnte nicht initialisiert werden"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "Kanal konnte nicht neu initiiert werden"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "Timer konnte nicht neu gestartet werden"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "PWM konnte nicht neu gestartet werden"
@@ -661,7 +665,7 @@ msgstr "PWM konnte nicht neu gestartet werden"
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "PWM konnte nicht gestartet werden"
@@ -758,8 +762,8 @@ msgstr "EXTINT Kanal ist schon in Benutzung"
msgid "Error in regex"
msgstr "Fehler in regex"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -770,10 +774,18 @@ msgstr "Erwartet ein(e) %q"
msgid "Expected a Characteristic"
msgstr "Characteristic wird erwartet"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Ein Service wird erwartet"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -855,7 +867,7 @@ msgstr ""
"Die aufgezeichnete Frequenz liegt über der Leistungsgrenze. Aufnahme "
"angehalten."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
"Die Frequenz muss mit dem vorhandenen PWMOut unter Verwendung dieses Timers "
@@ -961,9 +973,9 @@ msgstr "Ungültige BMP-Datei"
msgid "Invalid DAC pin supplied"
msgstr "Ungültiger DAC-Pin angegeben"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Ungültige PWM Frequenz"
@@ -1003,7 +1015,7 @@ msgstr "Ungültige Datei"
msgid "Invalid format chunk size"
msgstr "Ungültige format chunk size"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "Ungültige Frequenz geliefert"
@@ -1021,8 +1033,8 @@ msgid "Invalid phase"
msgstr "Ungültige Phase"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Ungültiger Pin"
@@ -1046,7 +1058,7 @@ msgstr "Ungültiger Pin für rechten Kanal"
msgid "Invalid pins"
msgstr "Ungültige Pins"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "Ungültige Pins für PWMOut"
@@ -1230,7 +1242,7 @@ msgstr "Es wurde kein Schlüssel angegeben"
msgid "No long integer support"
msgstr "Keine langen Integer (long) unterstützt"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "An diesem Pin sind keine Timer mehr verfügbar."
@@ -1268,6 +1280,10 @@ msgstr "Spielt nicht ab"
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1304,12 +1320,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "Oversample muss ein Vielfaches von 8 sein."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr "PWM duty_cycle muss zwischen 0 und 65535 (16 Bit Auflösung) liegen"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr "Die PWM-Frequenz ist nicht schreibbar wenn variable_Frequenz = False."
@@ -1367,8 +1383,8 @@ msgstr "Polygone brauchen mindestens 3 Punkte"
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1385,10 +1401,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr "Pull wird nicht verwendet, wenn die Richtung output ist."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr "PulseOut wird auf diesem Chip nicht unterstützt"
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr "RNG DeInit-Fehler"
@@ -1612,7 +1624,7 @@ msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""
"Zeitbeschränkung ist zu groß: Maximale Zeitbeschränkung ist %d Sekunden"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2530,6 +2542,10 @@ msgstr "Indizes müssen Integer, Slices oder Boolesche Listen sein"
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "inline assembler muss eine function sein"
@@ -2728,6 +2744,10 @@ msgstr "Matrix ist nicht positiv definitiv"
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr "max_length muss 0-%d sein, wenn fixed_length %s ist"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "maximale Rekursionstiefe überschritten"
@@ -2966,6 +2986,14 @@ msgstr ""
"ord() erwartet einen Buchstaben(char) aber es wurde ein String mit Länge %d "
"gefunden"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "Überlauf beim konvertieren von long int zu machine word"
@@ -3145,6 +3173,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr "start/end Indizes"
@@ -3446,6 +3478,9 @@ msgstr ""
msgid "zi must be of shape (n_section, 2)"
msgstr ""
+#~ msgid "PulseOut not supported on this chip"
+#~ msgstr "PulseOut wird auf diesem Chip nicht unterstützt"
+
#~ msgid "tuple/list required on RHS"
#~ msgstr "Tupel / Liste auf RHS erforderlich"
diff --git a/locale/es.po b/locale/es.po
index 882904f64..15b4fe780 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2020-08-17 21:11+0000\n"
"Last-Translator: Alvaro Figueroa <alvaro@greencore.co.cr>\n"
"Language-Team: \n"
@@ -313,7 +313,7 @@ msgstr ""
"Todos los canales de eventos de sincronización (sync event channels) están "
"siendo utilizados"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Todos los timers para este pin están siendo utilizados"
@@ -325,7 +325,7 @@ msgstr "Todos los timers para este pin están siendo utilizados"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Todos los timers en uso"
@@ -505,6 +505,10 @@ msgstr "Llame a super().__ init __() antes de acceder al objeto nativo."
msgid "Can't set CCCD on local Characteristic"
msgstr "No se puede configurar CCCD en la característica local"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -569,7 +573,7 @@ msgstr "No se puede transmitir sin pines MOSI y MISO."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "No se puede obtener inequívocamente sizeof escalar"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr "No puede variar la frecuencia en un temporizador que ya está en uso"
@@ -642,23 +646,23 @@ msgstr "No se pudo inicializar SDCard"
msgid "Could not initialize UART"
msgstr "No se puede inicializar la UART"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "No se pudo inicializar el canal"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "No se pudo inicializar el temporizador"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "No se pudo reiniciar el canal"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "No se pudo reiniciar el temporizador"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "No se pudo reiniciar el PWM"
@@ -666,7 +670,7 @@ msgstr "No se pudo reiniciar el PWM"
msgid "Could not set address"
msgstr "No se puede definir la dirección"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "No se pudo iniciar el PWM"
@@ -763,8 +767,8 @@ msgstr "El canal EXTINT ya está siendo utilizado"
msgid "Error in regex"
msgstr "Error en regex"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -775,10 +779,18 @@ msgstr "Se espera un %q"
msgid "Expected a Characteristic"
msgstr "Se esperaba una Característica"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Se esperaba un servicio"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -857,7 +869,7 @@ msgstr "Framebuffer requiere %d bytes"
msgid "Frequency captured is above capability. Capture Paused."
msgstr "Frecuencia capturada por encima de la capacidad. Captura en pausa."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
"La frecuencia debe coincidir con PWMOut existente usando este temporizador"
@@ -962,9 +974,9 @@ msgstr "Archivo BMP inválido"
msgid "Invalid DAC pin supplied"
msgstr "Pin suministrado inválido para DAC"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Frecuencia PWM inválida"
@@ -1004,7 +1016,7 @@ msgstr "Archivo inválido"
msgid "Invalid format chunk size"
msgstr "Formato de fragmento de formato no válido"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "Frecuencia suministrada no válida"
@@ -1022,8 +1034,8 @@ msgid "Invalid phase"
msgstr "Fase inválida"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Pin inválido"
@@ -1047,7 +1059,7 @@ msgstr "Pin inválido para canal derecho"
msgid "Invalid pins"
msgstr "pines inválidos"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "Pines inválidos para PWMOut"
@@ -1229,7 +1241,7 @@ msgstr "No se especificó ninguna llave"
msgid "No long integer support"
msgstr "No hay soporte de entero largo"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "No hay más temporizadores disponibles en este pin."
@@ -1267,6 +1279,10 @@ msgstr "No reproduciendo"
msgid "Not running saved code.\n"
msgstr "No ejecutando el código almacenado.\n"
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1303,12 +1319,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "El sobremuestreo debe ser un múltiplo de 8."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr "PWM duty_cycle debe ser entre 0 y 65535 inclusivo (16 bit resolution)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1367,8 +1383,8 @@ msgstr "El polígono necesita al menos 3 puntos"
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1384,10 +1400,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr "Pull no se usa cuando la dirección es output."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr "PulseOut no es compatible con este chip"
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr "Error de desinicializado del RNG"
@@ -1610,7 +1622,7 @@ msgstr ""
"Tiempo de espera demasiado largo: El tiempo máximo de espera es de %d "
"segundos"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2520,6 +2532,10 @@ msgstr "los índices deben ser enteros, particiones o listas de booleanos"
msgid "initial values must be iterable"
msgstr "los valores iniciales deben permitir iteración"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "ensamblador en línea debe ser una función"
@@ -2715,6 +2731,10 @@ msgstr "matrix no es definida positiva"
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr "max_length debe ser 0-%d cuando fixed_length es %s"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "profundidad máxima de recursión excedida"
@@ -2952,6 +2972,14 @@ msgstr "ord espera un carácter"
msgid "ord() expected a character, but string of length %d found"
msgstr "ord() espera un carácter, pero encontró un string de longitud %d"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "desbordamiento convirtiendo long int a palabra de máquina"
@@ -3131,6 +3159,10 @@ msgstr "sos[:, 3] deberían ser todos unos"
msgid "sosfilt requires iterable arguments"
msgstr "sosfilt requiere argumentos iterables"
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr "índices inicio/final"
@@ -3428,6 +3460,9 @@ msgstr "zi debe ser de tipo flotante"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi debe ser una forma (n_section,2)"
+#~ msgid "PulseOut not supported on this chip"
+#~ msgstr "PulseOut no es compatible con este chip"
+
#~ msgid "tuple/list required on RHS"
#~ msgstr "tuple/lista se require en RHS"
diff --git a/locale/fil.po b/locale/fil.po
index ec4f9f685..5bb696c83 100644
--- a/locale/fil.po
+++ b/locale/fil.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@@ -304,7 +304,7 @@ msgstr "Lahat ng event channels ginagamit"
msgid "All sync event channels in use"
msgstr "Lahat ng sync event channels ay ginagamit"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Lahat ng timers para sa pin na ito ay ginagamit"
@@ -316,7 +316,7 @@ msgstr "Lahat ng timers para sa pin na ito ay ginagamit"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Lahat ng timer ginagamit"
@@ -495,6 +495,10 @@ msgstr ""
msgid "Can't set CCCD on local Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -558,7 +562,7 @@ msgstr "Hindi maaaring ilipat kapag walang MOSI at MISO pin."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "Hindi puedeng hindi sigurado ang get sizeof scalar"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
@@ -628,23 +632,23 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Hindi ma-initialize ang UART"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr ""
@@ -652,7 +656,7 @@ msgstr ""
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr ""
@@ -752,8 +756,8 @@ msgstr "Ginagamit na ang EXTINT channel"
msgid "Error in regex"
msgstr "May pagkakamali sa REGEX"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -765,10 +769,18 @@ msgstr "Umasa ng %q"
msgid "Expected a Characteristic"
msgstr "Hindi mabasa and Characteristic."
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
#, fuzzy
@@ -848,7 +860,7 @@ msgstr ""
msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
@@ -952,9 +964,9 @@ msgstr "Mali ang BMP file"
msgid "Invalid DAC pin supplied"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Mali ang PWM frequency"
@@ -994,7 +1006,7 @@ msgstr "Mali ang file"
msgid "Invalid format chunk size"
msgstr "Mali ang format ng chunk size"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr ""
@@ -1012,8 +1024,8 @@ msgid "Invalid phase"
msgstr "Mali ang phase"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Mali ang pin"
@@ -1037,7 +1049,7 @@ msgstr "Mali ang pin para sa kanang channel"
msgid "Invalid pins"
msgstr "Mali ang pins"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr ""
@@ -1219,7 +1231,7 @@ msgstr ""
msgid "No long integer support"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@@ -1258,6 +1270,10 @@ msgstr "Hindi playing"
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1290,12 +1306,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "Oversample ay dapat multiple ng 8."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr "PWM duty_cycle ay dapat sa loob ng 0 at 65535 (16 bit resolution)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1351,8 +1367,8 @@ msgstr ""
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1369,10 +1385,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr "Pull hindi ginagamit kapag ang direksyon ay output."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr ""
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr ""
@@ -1585,7 +1597,7 @@ msgstr ""
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2497,6 +2509,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "inline assembler ay dapat na function"
@@ -2693,6 +2709,10 @@ msgstr ""
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "lumagpas ang maximum recursion depth"
@@ -2928,6 +2948,14 @@ msgstr "ord umaasa ng character"
msgid "ord() expected a character, but string of length %d found"
msgstr "ord() umaasa ng character pero string ng %d haba ang nakita"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "overflow nagcoconvert ng long int sa machine word"
@@ -3108,6 +3136,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr "start/end indeks"
diff --git a/locale/fr.po b/locale/fr.po
index 0562053f1..3ab485802 100644
--- a/locale/fr.po
+++ b/locale/fr.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2020-07-27 21:27+0000\n"
"Last-Translator: Nathan <bonnemainsnathan@gmail.com>\n"
"Language: fr\n"
@@ -312,7 +312,7 @@ msgstr "Tous les canaux d'événements sont utilisés"
msgid "All sync event channels in use"
msgstr "Tous les canaux d'événements de synchro sont utilisés"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Tous les timers pour cette broche sont utilisés"
@@ -324,7 +324,7 @@ msgstr "Tous les timers pour cette broche sont utilisés"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Tous les timers sont utilisés"
@@ -505,6 +505,10 @@ msgstr "Appelez super () .__ init __ () avant d'accéder à l'objet natif."
msgid "Can't set CCCD on local Characteristic"
msgstr "Impossible de définir CCCD sur une caractéristique locale"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -570,7 +574,7 @@ msgstr "Pas de transfert sans broches MOSI et MISO."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "Impossible d'obtenir la taille du scalaire sans ambigüité"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
"Impossible de faire varier la fréquence sur une minuterie déjà utilisée"
@@ -645,23 +649,23 @@ msgstr "Impossible d'initialiser la carte SD"
msgid "Could not initialize UART"
msgstr "L'UART n'a pu être initialisé"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "Impossible d'initialiser la chaîne"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "Impossible d'initialiser la minuterie"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "Impossible de réinitialiser la chaîne"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "Impossible de réinitialiser le minuteur"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "Impossible de redémarrer PWM"
@@ -669,7 +673,7 @@ msgstr "Impossible de redémarrer PWM"
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "Impossible de démarrer PWM"
@@ -766,8 +770,8 @@ msgstr "Canal EXTINT déjà utilisé"
msgid "Error in regex"
msgstr "Erreur dans l'expression régulière"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -778,10 +782,18 @@ msgstr "Attendu un %q"
msgid "Expected a Characteristic"
msgstr "Une 'Characteristic' est attendue"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Attendu un service"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -861,7 +873,7 @@ msgstr ""
msgid "Frequency captured is above capability. Capture Paused."
msgstr "La fréquence capturée est au delà des capacités. Capture en pause."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
"La fréquence doit correspondre à PWMOut existant à l'aide de cette minuterie"
@@ -966,9 +978,9 @@ msgstr "Fichier BMP invalide"
msgid "Invalid DAC pin supplied"
msgstr "Broche DAC non valide fournie"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Fréquence de PWM invalide"
@@ -1008,7 +1020,7 @@ msgstr "Fichier invalide"
msgid "Invalid format chunk size"
msgstr "Taille de bloc de formatage invalide"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "Fréquence invalide fournie"
@@ -1026,8 +1038,8 @@ msgid "Invalid phase"
msgstr "Phase invalide"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Broche invalide"
@@ -1051,7 +1063,7 @@ msgstr "Broche invalide pour le canal droit"
msgid "Invalid pins"
msgstr "Broches invalides"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "Broches non valides pour PWMOut"
@@ -1233,7 +1245,7 @@ msgstr "Aucune clé n'a été spécifiée"
msgid "No long integer support"
msgstr "Pas de support entier long"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "Plus de minuteurs disponibles sur cette broche."
@@ -1271,6 +1283,10 @@ msgstr "Ne joue pas"
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1307,14 +1323,14 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "Le sur-échantillonage doit être un multiple de 8."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
"La valeur de cycle PWM doit être entre 0 et 65535 inclus (résolution de 16 "
"bits)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1374,8 +1390,8 @@ msgstr "Polygone a besoin d’au moins 3 points"
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1390,10 +1406,6 @@ msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger."
msgid "Pull not used when direction is output."
msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr "PulseOut non pris en charge sur cette puce"
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr "Erreur RNG DeInit"
@@ -1614,7 +1626,7 @@ msgstr "La largeur de la tuile doit diviser exactement la largeur de l'image"
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr "Le délai est trop long : le délai maximal est de %d secondes"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2538,6 +2550,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr "les valeurs initiales doivent être itérables"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "l'assembleur doit être une fonction"
@@ -2734,6 +2750,10 @@ msgstr "la matrice n'est pas définie positive"
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr "max_length doit être 0-%d lorsque fixed_length est %s"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "profondeur maximale de récursivité dépassée"
@@ -2972,6 +2992,14 @@ msgstr ""
"ord() attend un caractère mais une chaîne de caractère de longueur %d a été "
"trouvée"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "dépassement de capacité en convertissant un entier long en mot machine"
@@ -3152,6 +3180,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr "indices de début/fin"
@@ -3449,6 +3481,9 @@ msgstr ""
msgid "zi must be of shape (n_section, 2)"
msgstr ""
+#~ msgid "PulseOut not supported on this chip"
+#~ msgstr "PulseOut non pris en charge sur cette puce"
+
#~ msgid "tuple/list required on RHS"
#~ msgstr "tuple ou liste requis en partie droite"
diff --git a/locale/hi.po b/locale/hi.po
index 50a1887f6..3803348aa 100644
--- a/locale/hi.po
+++ b/locale/hi.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -301,7 +301,7 @@ msgstr ""
msgid "All sync event channels in use"
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr ""
@@ -313,7 +313,7 @@ msgstr ""
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr ""
@@ -489,6 +489,10 @@ msgstr ""
msgid "Can't set CCCD on local Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -551,7 +555,7 @@ msgstr ""
msgid "Cannot unambiguously get sizeof scalar"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
@@ -620,23 +624,23 @@ msgstr ""
msgid "Could not initialize UART"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr ""
@@ -644,7 +648,7 @@ msgstr ""
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr ""
@@ -741,8 +745,8 @@ msgstr ""
msgid "Error in regex"
msgstr ""
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -753,10 +757,18 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -835,7 +847,7 @@ msgstr ""
msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
@@ -937,9 +949,9 @@ msgstr ""
msgid "Invalid DAC pin supplied"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr ""
@@ -979,7 +991,7 @@ msgstr ""
msgid "Invalid format chunk size"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr ""
@@ -997,8 +1009,8 @@ msgid "Invalid phase"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr ""
@@ -1022,7 +1034,7 @@ msgstr ""
msgid "Invalid pins"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr ""
@@ -1204,7 +1216,7 @@ msgstr ""
msgid "No long integer support"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@@ -1242,6 +1254,10 @@ msgstr ""
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1272,12 +1288,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1332,8 +1348,8 @@ msgstr ""
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1348,10 +1364,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr ""
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr ""
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr ""
@@ -1563,7 +1575,7 @@ msgstr ""
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2452,6 +2464,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr ""
@@ -2644,6 +2660,10 @@ msgstr ""
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2878,6 +2898,14 @@ msgstr ""
msgid "ord() expected a character, but string of length %d found"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr ""
@@ -3055,6 +3083,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr ""
diff --git a/locale/it_IT.po b/locale/it_IT.po
index 9635220af..e9dfc0474 100644
--- a/locale/it_IT.po
+++ b/locale/it_IT.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@@ -303,7 +303,7 @@ msgstr "Tutti i canali eventi utilizati"
msgid "All sync event channels in use"
msgstr "Tutti i canali di eventi sincronizzati in uso"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Tutti i timer per questo pin sono in uso"
@@ -315,7 +315,7 @@ msgstr "Tutti i timer per questo pin sono in uso"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Tutti i timer utilizzati"
@@ -495,6 +495,10 @@ msgstr ""
msgid "Can't set CCCD on local Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -559,7 +563,7 @@ msgstr "Impossibile trasferire senza i pin MOSI e MISO."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "Impossibile ricavare la grandezza scalare di sizeof inequivocabilmente"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
@@ -629,23 +633,23 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Impossibile inizializzare l'UART"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr ""
@@ -653,7 +657,7 @@ msgstr ""
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr ""
@@ -752,8 +756,8 @@ msgstr "Canale EXTINT già in uso"
msgid "Error in regex"
msgstr "Errore nella regex"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -765,10 +769,18 @@ msgstr "Atteso un %q"
msgid "Expected a Characteristic"
msgstr "Non è possibile aggiungere Characteristic."
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
#, fuzzy
@@ -848,7 +860,7 @@ msgstr ""
msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
@@ -952,9 +964,9 @@ msgstr "File BMP non valido"
msgid "Invalid DAC pin supplied"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Frequenza PWM non valida"
@@ -996,7 +1008,7 @@ msgstr "File non valido"
msgid "Invalid format chunk size"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr ""
@@ -1014,8 +1026,8 @@ msgid "Invalid phase"
msgstr "Fase non valida"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Pin non valido"
@@ -1039,7 +1051,7 @@ msgstr "Pin non valido per il canale destro"
msgid "Invalid pins"
msgstr "Pin non validi"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr ""
@@ -1223,7 +1235,7 @@ msgstr ""
msgid "No long integer support"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@@ -1262,6 +1274,10 @@ msgstr "In pausa"
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1295,14 +1311,14 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "L'oversampling deve essere multiplo di 8."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
"duty_cycle del PWM deve essere compresa tra 0 e 65535 inclusiva (risoluzione "
"a 16 bit)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
#, fuzzy
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
@@ -1361,8 +1377,8 @@ msgstr ""
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1378,10 +1394,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr ""
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr ""
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr ""
@@ -1596,7 +1608,7 @@ msgstr ""
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2498,6 +2510,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "inline assembler deve essere una funzione"
@@ -2695,6 +2711,10 @@ msgstr ""
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "profondità massima di ricorsione superata"
@@ -2934,6 +2954,14 @@ msgid "ord() expected a character, but string of length %d found"
msgstr ""
"ord() aspettava un carattere, ma ha ricevuto una stringa di lunghezza %d"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "overflow convertendo long int in parola"
@@ -3115,6 +3143,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr ""
diff --git a/locale/ja.po b/locale/ja.po
index 7c3b42580..b9fb7ce7a 100644
--- a/locale/ja.po
+++ b/locale/ja.po
@@ -7,16 +7,16 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
-"PO-Revision-Date: 2020-08-16 13:25+0000\n"
-"Last-Translator: Taku Fukada <naninunenor@gmail.com>\n"
+"POT-Creation-Date: 2020-08-27 11:21-0400\n"
+"PO-Revision-Date: 2020-09-01 18:44+0000\n"
+"Last-Translator: Jeff Epler <jepler@gmail.com>\n"
"Language-Team: none\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.2.1-dev\n"
#: main.c
msgid ""
@@ -42,7 +42,7 @@ msgid ""
"To exit, please reset the board without "
msgstr ""
"\n"
-"終了ã™ã‚‹ã«ã¯ã€æ¬¡ã®æ“作ãªã—ã«ãƒªã‚»ãƒƒãƒˆã—ã¦ãã ã•ã„: "
+"終了ã™ã‚‹ã«ã¯ã€æ¬¡ã®æ“作をã›ãšã«ãƒªã‚»ãƒƒãƒˆã—ã¦ãã ã•ã„: "
#: py/obj.c
msgid " File \"%q\""
@@ -84,7 +84,7 @@ msgstr "%q インデックスã¯ç¯„囲外"
#: py/obj.c
msgid "%q indices must be integers, not %q"
-msgstr "%qインデクスã¯ã€%qã§ãªãæ•´æ•°ãŒå¿…è¦ã§ã™"
+msgstr "%qインデクスã¯ã€%qã§ãªãæ•´æ•°ãŒå¿…è¦"
#: shared-bindings/vectorio/Polygon.c
msgid "%q list must be a list"
@@ -121,7 +121,7 @@ msgstr "%q()ã¯%d個ã®ä½ç½®å¼•æ•°ã‚’å—ã‘å–りã¾ã™ãŒã€%d個ã—ã‹ä¸Žãˆã
#: py/argcheck.c
msgid "'%q' argument required"
-msgstr "引数'%q'ãŒå¿…è¦"
+msgstr "引数 '%q' ãŒå¿…è¦"
#: py/runtime.c
msgid "'%q' object cannot assign attribute '%q'"
@@ -177,7 +177,7 @@ msgstr ""
#: py/emitinlinethumb.c
#, c-format
msgid "'%s' expects an FPU register"
-msgstr ""
+msgstr "'%s'ã«ã¯FPUレジスタãŒå¿…è¦"
#: py/emitinlinethumb.c
#, c-format
@@ -227,15 +227,15 @@ msgstr "関数外ã§ã®await"
#: py/compile.c
msgid "'await', 'async for' or 'async with' outside async function"
-msgstr "async関数外ã§ã®await, async for, async with"
+msgstr "async関数外ã§ã® await, async for, async with"
#: py/compile.c
msgid "'break' outside loop"
-msgstr "ループ外ã§ã® 'break'"
+msgstr "ループ外ã§ã®break"
#: py/compile.c
msgid "'continue' outside loop"
-msgstr "ループ外ã§ã® 'continue'"
+msgstr "ループ外ã§ã®continue"
#: py/objgenerator.c
msgid "'coroutine' object is not an iterator"
@@ -243,11 +243,11 @@ msgstr "'coroutine' オブジェクトã¯ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ã§ã¯ã‚りã¾ã›ã‚“"
#: py/compile.c
msgid "'data' requires at least 2 arguments"
-msgstr ""
+msgstr "'data'ã«ã¯å°‘ãªãã¨ã‚‚2ã¤ã®å¼•æ•°ãŒå¿…è¦"
#: py/compile.c
msgid "'data' requires integer arguments"
-msgstr ""
+msgstr "'data'ã«ã¯æ•´æ•°ã®å¼•æ•°ãŒå¿…è¦"
#: py/compile.c
msgid "'label' requires 1 argument"
@@ -255,11 +255,11 @@ msgstr ""
#: py/compile.c
msgid "'return' outside function"
-msgstr "関数外ã§ã® 'return'"
+msgstr "関数外ã§ã®return"
#: py/compile.c
msgid "'yield' outside function"
-msgstr "関数外ã§ã® 'yield'"
+msgstr "関数外ã§ã®yield"
#: py/compile.c
msgid "*x must be assignment target"
@@ -285,7 +285,7 @@ msgstr "ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢å‰²ã‚Šè¾¼ã¿ãƒãƒ£ãƒãƒ«ã¯ä½¿ç”¨ä¸­"
#: shared-bindings/_bleio/Address.c
#, c-format
msgid "Address must be %d bytes long"
-msgstr "アドレスã®é•·ã•㯠%d ãƒã‚¤ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "アドレスã¯ã€%dãƒã‚¤ãƒˆé•·ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: shared-bindings/_bleio/Address.c
msgid "Address type out of range"
@@ -311,7 +311,7 @@ msgstr "å…¨ã¦ã®ã‚¤ãƒ™ãƒ³ãƒˆãƒãƒ£ãƒãƒ«ãŒä½¿ç”¨ä¸­"
msgid "All sync event channels in use"
msgstr "å…¨ã¦ã®åŒæœŸã‚¤ãƒ™ãƒ³ãƒˆãƒãƒ£ãƒãƒ«ãŒä½¿ç”¨ä¸­"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "ã“ã®ãƒ”ン用ã®å…¨ã¦ã®ã‚¿ã‚¤ãƒžãŒä½¿ç”¨ä¸­"
@@ -323,7 +323,7 @@ msgstr "ã“ã®ãƒ”ン用ã®å…¨ã¦ã®ã‚¿ã‚¤ãƒžãŒä½¿ç”¨ä¸­"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "å…¨ã¦ã®ã‚¿ã‚¤ãƒžãƒ¼ãŒä½¿ç”¨ä¸­"
@@ -369,16 +369,16 @@ msgstr "Arrayã®å„値ã¯1ãƒã‚¤ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: shared-bindings/microcontroller/Pin.c
msgid "At most %d %q may be specified (not %d)"
-msgstr "最大㧠%d 個㮠%q ãŒæŒ‡å®šã§ãã¾ã™ï¼ˆ%d個ã§ãªã)"
+msgstr "最大㧠%d個㮠%q ãŒæŒ‡å®šã§ãã¾ã™ï¼ˆ%d個ã§ãªã)"
#: shared-module/memorymonitor/AllocationAlarm.c
#, c-format
msgid "Attempt to allocate %d blocks"
-msgstr "%d 個ã®ãƒ–ロックã®ç¢ºä¿ã‚’試ã¿ã¾ã—ãŸ"
+msgstr "%d個ã®ãƒ–ロックã®ç¢ºä¿ã‚’試ã¿ã¾ã—ãŸ"
#: supervisor/shared/safe_mode.c
msgid "Attempted heap allocation when MicroPython VM not running."
-msgstr "MicroPython VMã®éžå®Ÿè¡Œæ™‚ã«ãƒ’ープã®ç¢ºä¿ã‚’試ã¿ã¾ã—ãŸ"
+msgstr "MicroPython VM éžå®Ÿè¡Œæ™‚ã«ãƒ’ープã®ç¢ºä¿ã‚’試ã¿ã¾ã—ãŸ"
#: main.c
msgid "Auto-reload is off.\n"
@@ -407,7 +407,7 @@ msgstr "ビット深度ã¯8ã®å€æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: ports/mimxrt10xx/common-hal/busio/UART.c
msgid "Both RX and TX required for flow control"
-msgstr "フロー制御ã®ãŸã‚ã«RXã¨TXã®ä¸¡æ–¹ãŒå¿…è¦"
+msgstr "フロー制御ã®ãŸã‚RXã¨TXã®ä¸¡æ–¹ãŒå¿…è¦"
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
msgid "Both pins must support hardware interrupts"
@@ -417,7 +417,7 @@ msgstr "両方ã®ãƒ”ンã«ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢å‰²ã‚Šè¾¼ã¿å¯¾å¿œãŒå¿…è¦"
#: shared-bindings/framebufferio/FramebufferDisplay.c
#: shared-bindings/rgbmatrix/RGBMatrix.c
msgid "Brightness must be 0-1.0"
-msgstr "Brightnessã¯0ã‹ã‚‰1.0ã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "brightnessã¯0ã‹ã‚‰1.0ã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
@@ -529,7 +529,7 @@ msgstr "åŒã˜ãƒ”ン上ã®ä¸¡ãƒãƒ£ãƒãƒ«ã«å‡ºåŠ›ã§ãã¾ã›ã‚“"
#: shared-module/bitbangio/SPI.c
msgid "Cannot read without MISO pin."
-msgstr "MISOピンãªã—ã§èª­ã¿è¾¼ã¿ã¯ã§ãã¾ã›ã‚“"
+msgstr "MISOピンãªã—ã§èª­ã¿è¾¼ã‚ã¾ã›ã‚“"
#: shared-bindings/audiobusio/PDMIn.c
msgid "Cannot record to a file"
@@ -537,13 +537,13 @@ msgstr "ファイルã¸è¨˜éŒ²ã§ãã¾ã›ã‚“"
#: shared-module/storage/__init__.c
msgid "Cannot remount '/' when USB is active."
-msgstr "USBãŒã‚¢ã‚¯ãƒ†ã‚£ãƒ–ãªæ™‚ã« '/' ã‚’å†ãƒžã‚¦ãƒ³ãƒˆã§ãã¾ã›ã‚“"
+msgstr "USBãŒã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã®æ™‚ã«'/'ã‚’å†ãƒžã‚¦ãƒ³ãƒˆã§ãã¾ã›ã‚“"
#: ports/atmel-samd/common-hal/microcontroller/__init__.c
#: ports/cxd56/common-hal/microcontroller/__init__.c
#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c
msgid "Cannot reset into bootloader because no bootloader is present."
-msgstr "ブートローダãŒå­˜åœ¨ã—ãªã„ãŸã‚ブートローダã¸ã¨ãƒªã‚»ãƒƒãƒˆã§ãã¾ã›ã‚“"
+msgstr "ブートローダãŒå­˜åœ¨ã—ãªã„ãŸã‚ã€ãƒ–ートローダã¸ã¨ãƒªã‚»ãƒƒãƒˆã§ãã¾ã›ã‚“"
#: shared-bindings/digitalio/DigitalInOut.c
msgid "Cannot set value when direction is input."
@@ -565,13 +565,13 @@ msgstr "MOSIピンã¨MISOピンãªã—ã«è»¢é€ã§ãã¾ã›ã‚“"
msgid "Cannot unambiguously get sizeof scalar"
msgstr "スカラã®ã‚µã‚¤ã‚ºã‚’曖昧ã•ãªã—ã«å–å¾—ã§ãã¾ã›ã‚“"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
-msgstr "使用中ã®ã‚¿ã‚¤ãƒžãƒ¼ä¸Šã§å‘¨æ³¢æ•°ã‚’変ãˆã‚‰ã‚Œã¾ã›ã‚“"
+msgstr "使用中ã®ã‚¿ã‚¤ãƒžãƒ¼ä¸Šã§ã¯å‘¨æ³¢æ•°ã‚’変ãˆã‚‰ã‚Œã¾ã›ã‚“"
#: shared-module/bitbangio/SPI.c
msgid "Cannot write without MOSI pin."
-msgstr "MOSIピンãªã—ã«æ›¸ãè¾¼ã¿ã§ãã¾ã›ã‚“"
+msgstr "MOSIピンãªã—ã§æ›¸ãè¾¼ã¿ã§ãã¾ã›ã‚“"
#: shared-bindings/_bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
@@ -622,7 +622,7 @@ msgstr "ç ´æã—㟠.mpy ファイル"
#: py/emitglue.c
msgid "Corrupt raw code"
-msgstr "ç ´æã—㟠raw code"
+msgstr "ç ´æã—ãŸraw code"
#: ports/cxd56/common-hal/gnss/GNSS.c
msgid "Could not initialize GNSS"
@@ -636,31 +636,31 @@ msgstr "SDã‚«ãƒ¼ãƒ‰ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
msgid "Could not initialize UART"
msgstr "UARTã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "ãƒãƒ£ãƒãƒ«ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "ã‚¿ã‚¤ãƒžãƒ¼ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "ãƒãƒ£ãƒãƒ«ã‚’å†åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "タイマーをå†åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "PWMã‚’å†ã‚¹ã‚¿ãƒ¼ãƒˆã§ãã¾ã›ã‚“"
#: shared-bindings/_bleio/Adapter.c
msgid "Could not set address"
-msgstr ""
+msgstr "アドレスをセットã§ãã¾ã›ã‚“"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "PWMをスタートã§ãã¾ã›ã‚“"
@@ -762,7 +762,7 @@ msgstr "æ­£è¦è¡¨ç¾ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™"
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
-msgstr ""
+msgstr "%qãŒå¿…è¦"
#: shared-bindings/_bleio/CharacteristicBuffer.c
#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
@@ -776,7 +776,7 @@ msgstr ""
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
-msgstr ""
+msgstr "UUIDãŒå¿…è¦"
#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
@@ -793,7 +793,7 @@ msgstr ""
#: extmod/ulab/code/fft/fft.c
msgid "FFT is defined for ndarrays only"
-msgstr "FFT㯠ndarray ã«å¯¾ã—ã¦ã®ã¿å®šç¾©ã•れã¦ã„ã¾ã™"
+msgstr "FFTã¯ndarrayã§ã®ã¿ä½¿ãˆã¾ã™"
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
@@ -815,7 +815,7 @@ msgstr "RXãƒãƒƒãƒ•ã‚¡ã®ç¢ºä¿ã«å¤±æ•—"
#: ports/stm/common-hal/pulseio/PulseIn.c
#, c-format
msgid "Failed to allocate RX buffer of %d bytes"
-msgstr "%d ãƒã‚¤ãƒˆã®RXãƒãƒƒãƒ•ã‚¡ã®ç¢ºä¿ã«å¤±æ•—"
+msgstr "%dãƒã‚¤ãƒˆã®RXãƒãƒƒãƒ•ã‚¡ã®ç¢ºä¿ã«å¤±æ•—"
#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: internal error"
@@ -849,11 +849,11 @@ msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
msgid "Frequency captured is above capability. Capture Paused."
-msgstr ""
+msgstr "キャプãƒãƒ£ã—ãŸå‘¨æ³¢æ•°ã¯èƒ½åŠ›ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚キャプãƒãƒ£åœæ­¢"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
-msgstr "ã“ã®ã‚¿ã‚¤ãƒžãƒ¼ã‚’ä½¿ã†æ—¢å­˜ã®PWMOutã¨å‘¨æ³¢æ•°ã‚’一致ã•ã›ã¦ãã ã•ã„"
+msgstr "ã“ã®ã‚¿ã‚¤ãƒžãƒ¼ã‚’ä½¿ã†æ—¢å­˜ã®PWMOutã¨å‘¨æ³¢æ•°ã‚’一致ã•ã›ã‚‹å¿…è¦ãŒã‚りã¾ã™"
#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c
#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c
@@ -877,11 +877,11 @@ msgstr "ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãƒ“ジー。代替ã®ãƒ”ンを試ã—ã¦ãã ã•ã„"
#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c
msgid "Hardware in use, try alternative pins"
-msgstr "ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ä½¿ç”¨ä¸­ã€‚代替ã®ãƒ”ンを試ã—ã¦ãã ã•ã„"
+msgstr "ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ä½¿ç”¨ä¸­ã€‚代ã‚りã®ãƒ”ンを試ã—ã¦ãã ã•ã„"
#: extmod/vfs_posix_file.c py/objstringio.c
msgid "I/O operation on closed file"
-msgstr "é–‰ã˜ã‚‰ã‚ŒãŸãƒ•ァイルã«å¯¾ã™ã‚‹I/Oæ“作"
+msgstr "é–‰ã˜ã‚‰ã‚ŒãŸãƒ•ァイルã¸ã®I/Oæ“作"
#: ports/stm/common-hal/busio/I2C.c
msgid "I2C Init Error"
@@ -894,15 +894,13 @@ msgstr "I2SOutãŒåˆ©ç”¨ã§ãã¾ã›ã‚“"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
-msgstr "IV ã®é•·ã•㯠%d ãƒã‚¤ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "IVã¯%dãƒã‚¤ãƒˆé•·ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
"mpy-update for more info."
-msgstr ""
-"éžäº’æ›ã®.mpyファイルã§ã™ã€‚å…¨ã¦ã®.mpyファイルをアップデートã—ã¦ãã ã•ã„。詳細"
-"㯠http://adafru.it/mpy-update ã‚’å‚ç…§"
+msgstr "éžäº’æ›ã®.mpyファイルã§ã™ã€‚å…¨ã¦ã®.mpyファイルを更新ã—ã¦ãã ã•ã„。詳細㯠http://adafru.it/mpy-update ã‚’å‚ç…§"
#: shared-bindings/_pew/PewPew.c
msgid "Incorrect buffer size"
@@ -941,7 +939,7 @@ msgstr "䏿­£ãª%qピン"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/stm/common-hal/busio/UART.c ports/stm/common-hal/sdioio/SDCard.c
msgid "Invalid %q pin selection"
-msgstr ""
+msgstr "䏿­£ãª%qãƒ”ãƒ³é¸æŠž"
#: ports/stm/common-hal/analogio/AnalogIn.c
msgid "Invalid ADC Unit value"
@@ -953,11 +951,11 @@ msgstr "䏿­£ãªBMPファイル"
#: ports/stm/common-hal/analogio/AnalogOut.c
msgid "Invalid DAC pin supplied"
-msgstr "無効ãªDACピンãŒä¸Žãˆã‚‰ã‚Œã¾ã—ãŸ"
+msgstr "䏿­£ãªDACピンãŒä¸Žãˆã‚‰ã‚Œã¾ã—ãŸ"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "無効ãªPWM周波数"
@@ -967,7 +965,7 @@ msgstr "䏿­£ãªå¼•æ•°"
#: shared-module/displayio/Bitmap.c
msgid "Invalid bits per value"
-msgstr "値ã”ã¨ã®ãƒ“ット数ãŒä¸æ­£"
+msgstr "䏿­£ãªbits per value"
#: ports/nrf/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c
msgid "Invalid buffer size"
@@ -979,7 +977,7 @@ msgstr "䏿­£ãªãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ãƒ¼æ–‡å­—列"
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
msgid "Invalid capture period. Valid range: 1 - 500"
-msgstr "䏿­£ãªã‚­ãƒ£ãƒ—ãƒãƒ£å‘¨æœŸã€‚有効ãªå‘¨æœŸã¯1 - 500"
+msgstr "䏿­£ãªã‚­ãƒ£ãƒ—ãƒãƒ£å‘¨æœŸã€‚有効ãªå‘¨æœŸã¯1-500"
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid channel count"
@@ -987,7 +985,7 @@ msgstr "䏿­£ãªãƒãƒ£ãƒ³ãƒãƒ«æ•°"
#: shared-bindings/digitalio/DigitalInOut.c
msgid "Invalid direction."
-msgstr "䏿­£ãªæ–¹å‘"
+msgstr "䏿­£ãªå…¥å‡ºåŠ›æ–¹å‘"
#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
@@ -997,7 +995,7 @@ msgstr "䏿­£ãªãƒ•ァイル"
msgid "Invalid format chunk size"
msgstr "フォーマットãƒãƒ£ãƒ³ã‚¯ã®ã‚µã‚¤ã‚ºãŒä¸æ­£"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "䏿­£ãªå‘¨æ³¢æ•°ãŒä¸Žãˆã‚‰ã‚Œã¾ã—ãŸ"
@@ -1012,11 +1010,11 @@ msgstr "䏿­£ãªãƒ“ット数"
#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c
#: shared-bindings/displayio/FourWire.c
msgid "Invalid phase"
-msgstr ""
+msgstr "䏿­£ãªphase"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "䏿­£ãªãƒ”ン"
@@ -1040,7 +1038,7 @@ msgstr "å³ãƒãƒ£ãƒãƒ«ã®ãƒ”ンãŒä¸æ­£"
msgid "Invalid pins"
msgstr "ピンãŒä¸æ­£"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "PWMOutã®ãƒ”ンãŒä¸æ­£"
@@ -1055,11 +1053,11 @@ msgstr "䏿­£ãªãƒ—ロパティ"
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
-msgstr "䏿­£ãª Run Mode"
+msgstr "䏿­£ãªRun Mode"
#: shared-module/_bleio/Attribute.c
msgid "Invalid security_mode"
-msgstr "䏿­£ãª security_mode"
+msgstr "䏿­£ãªsecurity_mode"
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
@@ -1071,7 +1069,7 @@ msgstr "䏿­£ãªãƒœã‚¤ã‚¹æ•°"
#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
-msgstr "䏿­£ãªWaveファイル"
+msgstr "䏿­£ãªwaveファイル"
#: ports/stm/common-hal/busio/UART.c
msgid "Invalid word/bit length"
@@ -1167,7 +1165,7 @@ msgstr "DMAãƒãƒ£ãƒãƒ«ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
-msgstr "MISOピンãŒã‚りã¾ã›ã‚“"
+msgstr "MISOピンãªã—"
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
@@ -1203,7 +1201,7 @@ msgstr "使ã‚れã¦ã„ãªã„GCLKãŒã‚りã¾ã›ã‚“"
#: shared-bindings/os/__init__.c
msgid "No hardware random available"
-msgstr "ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ä¹±æ•°ãŒåˆ©ç”¨ã§ãã¾ã›ã‚“"
+msgstr "利用å¯èƒ½ãªãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ä¹±æ•°ãªã—"
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
msgid "No hardware support on clk pin"
@@ -1222,7 +1220,7 @@ msgstr "ã‚­ãƒ¼ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
msgid "No long integer support"
msgstr "long integerサãƒãƒ¼ãƒˆãŒã‚りã¾ã›ã‚“"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "ã“ã®ãƒ”ンã«åˆ©ç”¨å¯èƒ½ãªã‚¿ã‚¤ãƒžãƒ¼ãŒã‚‚ã†ã‚りã¾ã›ã‚“"
@@ -1254,7 +1252,7 @@ msgstr "接続ã•れã¦ã„ã¾ã›ã‚“"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
-msgstr "å†ç”Ÿä¸­ã—ã¦ã„ã¾ã›ã‚“"
+msgstr "å†ç”Ÿã—ã¦ã„ã¾ã›ã‚“"
#: main.c
msgid "Not running saved code.\n"
@@ -1290,15 +1288,14 @@ msgstr ""
#: shared-bindings/audiobusio/PDMIn.c
msgid "Oversample must be multiple of 8."
-msgstr "オーãƒãƒ¼ã‚µãƒ³ãƒ—ルã¯8ã®å€æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "オーãƒãƒ¼ã‚µãƒ³ãƒ—ルã¯8ã®å€æ•°ãŒå¿…è¦"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
-msgstr ""
-"PWMã® duty_cycle 値㯠0 ã‹ã‚‰ 65535 ã®é–“ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“(16ビット解åƒåº¦ï¼‰"
+msgstr "PWMã®duty_cycle値ã¯0ã‹ã‚‰65535ã®é–“ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“(16ビット解åƒåº¦ï¼‰"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr "PWM周波数ã¯ã€ç”Ÿæˆæ™‚ã®variable_frequencyãŒFalseã®ã¨ãæ›¸ãæ›ãˆä¸å¯"
@@ -1353,8 +1350,8 @@ msgstr "ãƒãƒªã‚´ãƒ³ã«ã¯å°‘ãªãã¨ã‚‚3ã¤ã®ç‚¹ãŒå¿…è¦"
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1364,7 +1361,7 @@ msgstr "Prefixãƒãƒƒãƒ•ã‚¡ã¯ãƒ’ープ上ã«ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: main.c
#, fuzzy
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
-msgstr "何らã‹ã®ã‚­ãƒ¼ã‚’押ã™ã¨REPLã«å…¥ã‚Šã¾ã™ã€‚CTRL-Dã§ãƒªãƒ­ãƒ¼ãƒ‰ã—ã¾ã™"
+msgstr "ã„ãšã‚Œã‹ã®ã‚­ãƒ¼ã‚’押ã™ã¨REPLã«å…¥ã‚Šã¾ã™ã€‚リロードã¯CTRL-D"
#: shared-bindings/digitalio/DigitalInOut.c
msgid "Pull not used when direction is output."
@@ -1372,11 +1369,11 @@ msgstr "æ–¹å‘ãŒoutputã®ã¨ãpullã¯ä½¿ã‚れã¾ã›ã‚“"
#: ports/stm/ref/pulseout-pre-timeralloc.c
msgid "PulseOut not supported on this chip"
-msgstr ""
+msgstr "PulseOutã¯ã“ã®ãƒãƒƒãƒ—ã§ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
-msgstr "乱数生æˆå™¨ã®è§£ä½“エラー"
+msgstr "RNG解体エラー"
#: ports/stm/common-hal/os/__init__.c
msgid "RNG Init Error"
@@ -1427,7 +1424,7 @@ msgstr "è¦æ±‚ã®AESモードã¯éžã‚µãƒãƒ¼ãƒˆ"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
-msgstr "å³ãƒãƒ£ãƒãƒ«ã¯éžã‚µãƒãƒ¼ãƒˆ"
+msgstr "å³ãƒãƒ£ãƒãƒ«ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
#: shared-bindings/_pew/PewPew.c
msgid "Row entry must be digitalio.DigitalInOut"
@@ -1454,7 +1451,7 @@ msgstr ""
#: ports/stm/common-hal/sdioio/SDCard.c
#, c-format
msgid "SDIO Init Error %d"
-msgstr ""
+msgstr "SDIOåˆæœŸåŒ–エラー %d"
#: ports/stm/common-hal/busio/SPI.c
msgid "SPI Init Error"
@@ -1466,7 +1463,7 @@ msgstr "SPIå†åˆæœŸåŒ–エラー"
#: shared-bindings/audiomixer/Mixer.c
msgid "Sample rate must be positive"
-msgstr "ã‚µãƒ³ãƒ—ãƒ«ãƒ¬ãƒ¼ãƒˆã¯æ­£æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "サンプルレートã«ã¯æ­£ã®æ•°ãŒå¿…è¦"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
#, c-format
@@ -1479,7 +1476,7 @@ msgstr "スキャンã¯ã™ã§ã«é€²è¡Œä¸­ã€‚stop_scanã§åœæ­¢ã—ã¦ãã ã•ã„
#: ports/mimxrt10xx/common-hal/busio/UART.c
msgid "Selected CTS pin not valid"
-msgstr "é¸æŠžã•れãŸCTSピンãŒä¸æ­£ã§ã™"
+msgstr "é¸æŠžã•れãŸCTSピンãŒä¸æ­£"
#: ports/mimxrt10xx/common-hal/busio/UART.c
msgid "Selected RTS pin not valid"
@@ -1515,7 +1512,7 @@ msgstr "スタックサイズã¯å°‘ãªãã¨ã‚‚256以上ãŒå¿…è¦"
#: shared-bindings/multiterminal/__init__.c
msgid "Stream missing readinto() or write() method."
-msgstr ""
+msgstr "streamã«readinto()ã¾ãŸã¯write()メソッドãŒã‚りã¾ã›ã‚“"
#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c
msgid "Supply at least one UART pin"
@@ -1534,8 +1531,8 @@ msgid ""
"The CircuitPython heap was corrupted because the stack was too small.\n"
"Please increase the stack size if you know how, or if not:"
msgstr ""
-"スタックãŒå°ã•ã™ãŽãŸã“ã¨ã«ã‚ˆã‚ŠCircuitPythonã®ãƒ’ープãŒç ´æã—ã¾ã—ãŸã€‚\n"
-"スタックサイズを上ã’ã‚‹ã‹ã€ãã®æ–¹æ³•ãŒåˆ†ã‹ã‚‰ãªã‘れã°ï¼š"
+"スタックãŒå°ã•ã™ãŽãŸãŸã‚CircuitPythonã®ãƒ’ープãŒå£Šã‚Œã¾ã—ãŸã€‚\n"
+"スタックサイズを上ã’ã‚‹ã‹ã€ãã®æ–¹æ³•ãŒåˆ†ã‹ã‚‰ãªã‘れã°:"
#: supervisor/shared/safe_mode.c
msgid ""
@@ -1566,11 +1563,11 @@ msgstr ""
#: shared-module/audiomixer/MixerVoice.c
msgid "The sample's sample rate does not match the mixer's"
-msgstr ""
+msgstr "サンプルレートãŒã‚µãƒ³ãƒ—ルã¨ãƒŸã‚­ã‚µãƒ¼ã§ä¸€è‡´ã—ã¾ã›ã‚“"
#: shared-module/audiomixer/MixerVoice.c
msgid "The sample's signedness does not match the mixer's"
-msgstr "サンプルã®ç¬¦å·æœ‰ç„¡ãŒãƒŸã‚­ã‚µãƒ¼ã¨ä¸€è‡´ã—ã¾ã›ã‚“"
+msgstr "符å·ã®æœ‰ç„¡ãŒã‚µãƒ³ãƒ—ルã¨ãƒŸã‚­ã‚µãƒ¼ã§ä¸€è‡´ã—ã¾ã›ã‚“"
#: shared-bindings/displayio/TileGrid.c
msgid "Tile height must exactly divide bitmap height"
@@ -1582,7 +1579,7 @@ msgstr "タイルã®ã‚¤ãƒ³ãƒ‡ã‚¯ã‚¹ãŒç¯„囲外"
#: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds"
-msgstr "タイルã®å€¤ãŒç¯„囲外"
+msgstr "タイル値ãŒç¯„囲外"
#: shared-bindings/displayio/TileGrid.c
msgid "Tile width must exactly divide bitmap width"
@@ -1591,9 +1588,9 @@ msgstr "タイルã®å¹…ã¯ãƒ“ットマップã®å¹…を割り切れる値ã§ãªã‘
#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Timeout is too long: Maximum timeout length is %d seconds"
-msgstr "タイムアウトãŒé•·ã™ãŽã€‚最大ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆé•·ã¯%dç§’"
+msgstr "タイムアウトãŒé•·ã™ãŽã§ã™ã€‚最大ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆé•·ã¯%dç§’"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -1616,7 +1613,7 @@ msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
-msgstr ""
+msgstr "トレースãƒãƒƒã‚¯ï¼ˆæœ€æ–°ã®å‘¼ã³å‡ºã—ãŒæœ«å°¾ï¼‰:\n"
#: shared-bindings/time/__init__.c
msgid "Tuple or struct_time argument required"
@@ -1672,7 +1669,7 @@ msgstr ""
#: shared-module/displayio/I2CDisplay.c
#, c-format
msgid "Unable to find I2C Display at %x"
-msgstr ""
+msgstr "I2Cディスプレイを %x ã«è¦‹ã¤ã‘られã¾ã›ã‚“"
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
@@ -1685,7 +1682,7 @@ msgstr "ãƒ‘ãƒ¼ã‚¶ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
#: shared-module/displayio/OnDiskBitmap.c
msgid "Unable to read color palette data"
-msgstr "カラーパレットã®ãƒ‡ãƒ¼ã‚¿ã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“"
+msgstr "カラーパレットデータを読ã¿è¾¼ã‚ã¾ã›ã‚“"
#: shared-bindings/nvm/ByteArray.c
msgid "Unable to write to nvm."
@@ -1728,7 +1725,7 @@ msgstr ""
#: ports/atmel-samd/common-hal/busio/I2C.c ports/cxd56/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
-msgstr ""
+msgstr "éžã‚µãƒãƒ¼ãƒˆã®baudrate"
#: shared-module/displayio/display_core.c
msgid "Unsupported display bus type"
@@ -1736,11 +1733,11 @@ msgstr ""
#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
-msgstr ""
+msgstr "サãƒãƒ¼ãƒˆã•れã¦ã„ãªã„フォーマット"
#: py/moduerrno.c
msgid "Unsupported operation"
-msgstr ""
+msgstr "サãƒãƒ¼ãƒˆã•れã¦ã„ãªã„æ“作"
#: shared-bindings/digitalio/DigitalInOut.c
msgid "Unsupported pull value."
@@ -1762,7 +1759,7 @@ msgstr ""
#: ports/stm/common-hal/microcontroller/Processor.c
msgid "Voltage read timed out"
-msgstr ""
+msgstr "電圧読ã¿å–りãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆ"
#: main.c
msgid "WARNING: Your code filename has two extensions\n"
@@ -1824,11 +1821,11 @@ msgstr ""
#: extmod/modubinascii.c extmod/moduhashlib.c py/objarray.c
msgid "a bytes-like object is required"
-msgstr ""
+msgstr "bytes-likeオブジェクトãŒå¿…è¦"
#: lib/embed/abort_.c
msgid "abort() called"
-msgstr ""
+msgstr "abort()ãŒå‘¼ã°ã‚Œã¾ã—ãŸ"
#: extmod/machine_mem.c
#, c-format
@@ -1837,7 +1834,7 @@ msgstr ""
#: shared-bindings/i2cperipheral/I2CPeripheral.c
msgid "address out of bounds"
-msgstr ""
+msgstr "アドレスãŒç¯„囲外"
#: shared-bindings/i2cperipheral/I2CPeripheral.c
msgid "addresses is empty"
@@ -1870,7 +1867,7 @@ msgstr ""
#: py/runtime.c
msgid "argument should be a '%q' not a '%q'"
-msgstr ""
+msgstr "引数ã«ã¯ '%q' ãŒå¿…è¦ï¼ˆ'%q' ã§ã¯ãªã)"
#: extmod/ulab/code/linalg/linalg.c
msgid "arguments must be ndarrays"
@@ -1878,7 +1875,7 @@ msgstr ""
#: py/objarray.c shared-bindings/nvm/ByteArray.c
msgid "array/bytes required on right side"
-msgstr ""
+msgstr "å³è¾ºã«ã¯array/bytesãŒå¿…è¦"
#: extmod/ulab/code/numerical/numerical.c
msgid "attempt to get argmin/argmax of an empty sequence"
@@ -1886,7 +1883,7 @@ msgstr ""
#: py/objstr.c
msgid "attributes not supported yet"
-msgstr ""
+msgstr "属性ã¯ã¾ã ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
#: extmod/ulab/code/numerical/numerical.c
msgid "axis must be -1, 0, None, or 1"
@@ -1898,7 +1895,7 @@ msgstr "axis㯠-1, 0, 1 ã®ã„ãšã‚Œã‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: extmod/ulab/code/numerical/numerical.c
msgid "axis must be None, 0, or 1"
-msgstr "axis㯠None, 0, 1 ã®ã„ãšã‚Œã‹ãŒå¿…è¦ã§ã™"
+msgstr "axis㯠None, 0, 1 ã®ã„ãšã‚Œã‹"
#: py/builtinevex.c
msgid "bad compile mode"
@@ -1910,11 +1907,11 @@ msgstr ""
#: py/objstr.c
msgid "bad format string"
-msgstr ""
+msgstr "䏿­£ãªæ›¸å¼åŒ–文字列"
#: py/binary.c
msgid "bad typecode"
-msgstr "typecodeãŒä¸æ­£"
+msgstr "䏿­£ãªtypecode"
#: py/emitnative.c
msgid "binary op %q not implemented"
@@ -1922,7 +1919,7 @@ msgstr ""
#: shared-bindings/busio/UART.c
msgid "bits must be 7, 8 or 9"
-msgstr ""
+msgstr "bitsã¯7, 8, 9ã®ã„ãšã‚Œã‹ãŒå¿…è¦"
#: shared-bindings/audiomixer/Mixer.c
msgid "bits_per_sample must be 8 or 16"
@@ -1959,7 +1956,7 @@ msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "byteorder is not a string"
-msgstr ""
+msgstr "byteorderãŒæ–‡å­—列ã§ã¯ã‚りã¾ã›ã‚“"
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "bytes > 8 bits not supported"
@@ -1967,15 +1964,15 @@ msgstr ""
#: py/objstr.c
msgid "bytes value out of range"
-msgstr ""
+msgstr "範囲外ã®ãƒã‚¤ãƒˆå€¤"
#: ports/atmel-samd/bindings/samd/Clock.c ports/atmel-samd/common-hal/rtc/RTC.c
msgid "calibration is out of range"
-msgstr ""
+msgstr "キャリブレーションãŒç¯„囲外"
#: ports/atmel-samd/bindings/samd/Clock.c
msgid "calibration is read only"
-msgstr ""
+msgstr "calibrationã¯èª­ã¿è¾¼ã¿å°‚用"
#: ports/atmel-samd/common-hal/rtc/RTC.c
msgid "calibration value out of range +/-127"
@@ -1995,24 +1992,24 @@ msgstr ""
#: py/objtype.c
msgid "can't add special method to already-subclassed class"
-msgstr ""
+msgstr "サブクラス化済ã¿ã®ã‚¯ãƒ©ã‚¹ã«ç‰¹æ®Šãƒ¡ã‚½ãƒƒãƒ‰ã‚’追加ã§ãã¾ã›ã‚“"
#: py/compile.c
msgid "can't assign to expression"
-msgstr ""
+msgstr "å¼ã«ã¯ä»£å…¥ã§ãã¾ã›ã‚“"
#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c
#: shared-module/_pixelbuf/PixelBuf.c
msgid "can't convert %q to %q"
-msgstr ""
+msgstr "%qã‚’%qã«å¤‰æ›ã§ãã¾ã›ã‚“"
#: py/objstr.c
msgid "can't convert '%q' object to %q implicitly"
-msgstr ""
+msgstr "オブジェクト '%q' ã‚’ %q ã«æš—é»™ã«å¤‰æ›ã§ãã¾ã›ã‚“"
#: py/obj.c
msgid "can't convert to %q"
-msgstr ""
+msgstr "%q ã«å¤‰æ›ã§ãã¾ã›ã‚“"
#: py/objstr.c
msgid "can't convert to str implicitly"
@@ -2020,7 +2017,7 @@ msgstr ""
#: py/compile.c
msgid "can't declare nonlocal in outer code"
-msgstr ""
+msgstr "外å´ã®ã‚³ãƒ¼ãƒ‰ã§nonlocalã¯ä½¿ãˆã¾ã›ã‚“"
#: py/compile.c
msgid "can't delete expression"
@@ -2032,15 +2029,15 @@ msgstr ""
#: py/objcomplex.c
msgid "can't do truncated division of a complex number"
-msgstr ""
+msgstr "複素数ã®åˆ‡ã‚Šæ¨ã¦é™¤ç®—ã¯ã§ãã¾ã›ã‚“"
#: py/compile.c
msgid "can't have multiple **x"
-msgstr ""
+msgstr "複数㮠**x ã¯æŒã¦ã¾ã›ã‚“"
#: py/compile.c
msgid "can't have multiple *x"
-msgstr ""
+msgstr "複数㮠*x ã¯æŒã¦ã¾ã›ã‚“"
#: py/emitnative.c
msgid "can't implicitly convert '%q' to 'bool'"
@@ -2090,7 +2087,7 @@ msgstr ""
#: py/objstr.c
msgid ""
"can't switch from manual field specification to automatic field numbering"
-msgstr ""
+msgstr "手動ã¨è‡ªå‹•ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰æŒ‡å®šã¯æ··åœ¨ã§ãã¾ã›ã‚“"
#: py/objtype.c
msgid "cannot create '%q' instances"
@@ -2106,11 +2103,11 @@ msgstr ""
#: py/builtinimport.c
msgid "cannot perform relative import"
-msgstr ""
+msgstr "相対インãƒãƒ¼ãƒˆã¯ã§ãã¾ã›ã‚“"
#: extmod/ulab/code/ndarray.c
msgid "cannot reshape array (incompatible input/output shape)"
-msgstr ""
+msgstr "入力/出力シェイプãŒäº’æ›ã§ãªãreshapeã§ãã¾ã›ã‚“"
#: py/emitnative.c
msgid "casting"
@@ -2138,7 +2135,7 @@ msgstr ""
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be a buffer, tuple, list, or int"
-msgstr ""
+msgstr "カラーãƒãƒƒãƒ•ã‚¡ã¯buffer, tuple, list, int ã®ã„ãšã‚Œã‹ã§ã™"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be a bytearray or array of type 'b' or 'B'"
@@ -2146,7 +2143,7 @@ msgstr ""
#: shared-bindings/displayio/Palette.c
msgid "color must be between 0x000000 and 0xffffff"
-msgstr ""
+msgstr "色ã¯0x000000ã‹ã‚‰0xffffffã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: shared-bindings/displayio/ColorConverter.c
msgid "color should be an int"
@@ -2154,7 +2151,7 @@ msgstr ""
#: py/objcomplex.c
msgid "complex division by zero"
-msgstr ""
+msgstr "複素数ゼロ除算"
#: py/objfloat.c py/parsenum.c
msgid "complex values not supported"
@@ -2162,7 +2159,7 @@ msgstr ""
#: extmod/moduzlib.c
msgid "compression header"
-msgstr ""
+msgstr "圧縮ヘッダー"
#: py/parse.c
msgid "constant must be an integer"
@@ -2174,11 +2171,11 @@ msgstr ""
#: extmod/ulab/code/filter/filter.c
msgid "convolve arguments must be linear arrays"
-msgstr ""
+msgstr "convolve引数ã«ã¯1次元arrayãŒå¿…è¦"
#: extmod/ulab/code/filter/filter.c
msgid "convolve arguments must be ndarrays"
-msgstr ""
+msgstr "convolve引数ã«ã¯ndarrayãŒå¿…è¦"
#: extmod/ulab/code/filter/filter.c
msgid "convolve arguments must not be empty"
@@ -2190,7 +2187,7 @@ msgstr ""
#: extmod/ulab/code/poly/poly.c
msgid "could not invert Vandermonde matrix"
-msgstr ""
+msgstr "ヴァンデルモンド行列ã®é€†è¡Œåˆ—を求ã‚られã¾ã›ã‚“"
#: shared-module/sdcardio/SDCard.c
msgid "couldn't determine SD card version"
@@ -2214,7 +2211,7 @@ msgstr ""
#: py/compile.c
msgid "default 'except' must be last"
-msgstr ""
+msgstr "デフォルトã®exceptã¯æœ€å¾Œã«ç½®ãå¿…è¦ãŒã‚りã¾ã™"
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
@@ -2223,11 +2220,11 @@ msgstr ""
#: shared-bindings/audiobusio/PDMIn.c
msgid "destination buffer must be an array of type 'H' for bit_depth = 16"
-msgstr ""
+msgstr "bit_depath = 16 用ã®ãƒãƒƒãƒ•ã‚¡ã«ã¯ã‚¿ã‚¤ãƒ—'H'ã®arrayãŒå¿…è¦"
#: shared-bindings/audiobusio/PDMIn.c
msgid "destination_length must be an int >= 0"
-msgstr ""
+msgstr "desitination_lengthã«ã¯æ­£ã®æ•´æ•°ãŒå¿…è¦"
#: py/objdict.c
msgid "dict update sequence has wrong length"
@@ -2235,7 +2232,7 @@ msgstr ""
#: extmod/ulab/code/numerical/numerical.c
msgid "diff argument must be an ndarray"
-msgstr ""
+msgstr "引数ã«ã¯ndarrayãŒå¿…è¦"
#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c
#: shared-bindings/math/__init__.c
@@ -2325,7 +2322,7 @@ msgstr "f-string: '}'ãŒå¿…è¦"
#: py/parse.c
msgid "f-string: single '}' is not allowed"
-msgstr "f-string: 1ã¤ã ã‘ã® '}' ã¯è¨±ã•れã¾ã›ã‚“"
+msgstr "f-string: 1ã¤ã ã‘ã®'}'ã¯è¨±ã•れã¾ã›ã‚“"
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
#: shared-bindings/displayio/OnDiskBitmap.c
@@ -2334,7 +2331,7 @@ msgstr "fileã«ã¯ãƒã‚¤ãƒˆãƒ¢ãƒ¼ãƒ‰ã§é–‹ã‹ã‚ŒãŸãƒ•ァイルãŒå¿…è¦"
#: shared-bindings/storage/__init__.c
msgid "filesystem must provide mount method"
-msgstr ""
+msgstr "filesystemã«ã¯mountメソッドãŒå¿…è¦"
#: extmod/ulab/code/vector/vectorise.c
msgid "first argument must be a callable"
@@ -2374,7 +2371,7 @@ msgstr ""
#: py/objstr.c
msgid "format requires a dict"
-msgstr ""
+msgstr "formatã«ã¯dictãŒå¿…è¦"
#: py/objdeque.c
msgid "full"
@@ -2399,7 +2396,7 @@ msgstr ""
#: extmod/ulab/code/compare/compare.c
msgid "function is implemented for scalars and ndarrays only"
-msgstr ""
+msgstr "スカラ値ãŠã‚ˆã³ndarrayã®ã¿ã‚’å—ã‘å–りã¾ã™"
#: py/argcheck.c
#, c-format
@@ -2427,7 +2424,7 @@ msgstr ""
#: shared-bindings/time/__init__.c
msgid "function takes exactly 9 arguments"
-msgstr "ã“ã®é–¢æ•°ã¯ã¡ã‚‡ã†ã©9個ã®å¼•æ•°ã‚’ã¨ã‚Šã¾ã™"
+msgstr "関数ã¯ã¡ã‚‡ã†ã©9個ã®å¼•æ•°ã‚’ã¨ã‚Šã¾ã™"
#: py/objgenerator.c
msgid "generator already executing"
@@ -2443,7 +2440,7 @@ msgstr ""
#: extmod/moduheapq.c
msgid "heap must be a list"
-msgstr ""
+msgstr "heapã«ã¯ãƒªã‚¹ãƒˆãŒå¿…è¦"
#: py/compile.c
msgid "identifier redefined as global"
@@ -2488,7 +2485,7 @@ msgstr ""
#: py/compile.c
msgid "inline assembler must be a function"
-msgstr ""
+msgstr "インラインアセンブラã¯é–¢æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: extmod/ulab/code/ulab_create.c
msgid "input argument must be an integer or a 2-tuple"
@@ -2496,7 +2493,7 @@ msgstr ""
#: extmod/ulab/code/fft/fft.c
msgid "input array length must be power of 2"
-msgstr "入力 array ã®é•·ã•ã¯2ã®ç´¯ä¹—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "入力arrayé•·ã¯2ã®ç´¯ä¹—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: extmod/ulab/code/poly/poly.c
msgid "input data must be an iterable"
@@ -2508,7 +2505,7 @@ msgstr "入力行列ãŒéžå¯¾ç§°"
#: extmod/ulab/code/linalg/linalg.c
msgid "input matrix is singular"
-msgstr ""
+msgstr "入力ãŒéžæ­£å‰‡è¡Œåˆ—"
#: extmod/ulab/code/linalg/linalg.c
msgid "input must be square matrix"
@@ -2516,7 +2513,7 @@ msgstr ""
#: extmod/ulab/code/numerical/numerical.c
msgid "input must be tuple, list, range, or ndarray"
-msgstr ""
+msgstr "入力ã¯tuple, list, range, ndarrayã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: extmod/ulab/code/poly/poly.c
msgid "input vectors must be of equal length"
@@ -2524,7 +2521,7 @@ msgstr ""
#: py/parsenum.c
msgid "int() arg 2 must be >= 2 and <= 36"
-msgstr "int() ã®2番目ã®å¼•数㯠2 以上 36 以下ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "int()ã®ç¬¬2引数ã¯2以上36以下ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: py/objstr.c
msgid "integer required"
@@ -2537,7 +2534,7 @@ msgstr ""
#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
-msgstr ""
+msgstr "intervalã¯%s-%sã®ç¯„囲ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: lib/netutils/netutils.c
msgid "invalid arguments"
@@ -2565,7 +2562,7 @@ msgstr "䏿­£ãªéµ"
#: py/compile.c
msgid "invalid micropython decorator"
-msgstr ""
+msgstr "䏿­£ãªmicropythonデコレータ"
#: shared-bindings/random/__init__.c
msgid "invalid step"
@@ -2590,7 +2587,7 @@ msgstr "æ•°å­—ã¨ã—ã¦ä¸æ­£ãªæ§‹æ–‡"
#: py/objtype.c
msgid "issubclass() arg 1 must be a class"
-msgstr "issubclass()ã®1ã¤ç›®ã®å¼•æ•°ã¯ã‚¯ãƒ©ã‚¹ã§ã™"
+msgstr "issubclass()ã®ç¬¬1引数ã¯ã‚¯ãƒ©ã‚¹ãŒå¿…è¦"
#: py/objtype.c
msgid "issubclass() arg 2 must be a class or a tuple of classes"
@@ -2598,19 +2595,19 @@ msgstr ""
#: extmod/ulab/code/ndarray.c
msgid "iterables are not of the same length"
-msgstr "イテレートå¯èƒ½ãªã‚ªãƒ–ジェクトãŒåŒã˜é•·ã•ã§ã¯ã‚りã¾ã›ã‚“"
+msgstr "iterableãŒåŒã˜é•·ã•ã§ã¯ã‚りã¾ã›ã‚“"
#: extmod/ulab/code/linalg/linalg.c
msgid "iterations did not converge"
-msgstr ""
+msgstr "åŽæŸã—ã¾ã›ã‚“"
#: py/objstr.c
msgid "join expects a list of str/bytes objects consistent with self object"
-msgstr ""
+msgstr "joinã«ã¯ã€str/bytes(ã®ã†ã¡è‡ªèº«ã¨ä¸€è‡´ã—ãŸåž‹ã®ï¼‰ãƒªã‚¹ãƒˆãŒå¿…è¦"
#: py/argcheck.c
msgid "keyword argument(s) not yet implemented - use normal args instead"
-msgstr ""
+msgstr "キーワード引数ã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“。通常ã®å¼•数を使ã£ã¦ãã ã•ã„。"
#: py/bc.c
msgid "keywords must be strings"
@@ -2618,7 +2615,7 @@ msgstr "ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã¯æ–‡å­—列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: py/emitinlinethumb.c py/emitinlinextensa.c
msgid "label '%q' not defined"
-msgstr ""
+msgstr "ラベル'%q'ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
#: py/compile.c
msgid "label redefined"
@@ -2721,11 +2718,11 @@ msgstr ""
#: extmod/ulab/code/numerical/numerical.c
msgid "n must be between 0, and 9"
-msgstr "nã¯0ã‹ã‚‰9ã¾ã§ã§ã™"
+msgstr "nã¯0ã‹ã‚‰9ã¾ã§"
#: py/runtime.c
msgid "name '%q' is not defined"
-msgstr "åå‰'%q'ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
+msgstr "åå‰ '%q' ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
#: py/runtime.c
msgid "name not defined"
@@ -2733,7 +2730,7 @@ msgstr "åå‰ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
#: py/compile.c
msgid "name reused for argument"
-msgstr "åå‰ãŒå¼•æ•°ã§å†åˆ©ç”¨ã•れã¦ã„ã¾ã™"
+msgstr "引数ã§åå‰ãŒå†åˆ©ç”¨ã•れã¦ã„ã¾ã™"
#: py/emitnative.c
msgid "native yield"
@@ -2742,7 +2739,7 @@ msgstr ""
#: py/runtime.c
#, c-format
msgid "need more than %d values to unpack"
-msgstr ""
+msgstr "アンパックã™ã‚‹å€¤ã¯%d個ã§ã¯è¶³ã‚Šã¾ã›ã‚“"
#: py/objint_longlong.c py/objint_mpz.c py/runtime.c
msgid "negative power with no float support"
@@ -2766,7 +2763,7 @@ msgstr "利用å¯èƒ½ãªNICãŒã‚りã¾ã›ã‚“"
#: py/compile.c
msgid "no binding for nonlocal found"
-msgstr ""
+msgstr "nonlocalã®å¯¾è±¡ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
#: py/builtinimport.c
msgid "no module named '%q'"
@@ -2783,7 +2780,7 @@ msgstr "SDカードã‹ã‚‰ã®å¿œç­”ãŒã‚りã¾ã›ã‚“"
#: py/runtime.c
msgid "no such attribute"
-msgstr "ãã®ã‚ˆã†ãªå±žæ€§ã¯ã‚りã¾ã›ã‚“"
+msgstr "指定ã®å±žæ€§ã¯ã‚りã¾ã›ã‚“"
#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
@@ -2791,7 +2788,7 @@ msgstr ""
#: py/compile.c
msgid "non-default argument follows default argument"
-msgstr ""
+msgstr "デフォルト引数ã®å¾Œã«é€šå¸¸ã®å¼•æ•°ã¯ç½®ã‘ã¾ã›ã‚“"
#: extmod/modubinascii.c
msgid "non-hex digit found"
@@ -2815,11 +2812,11 @@ msgstr ""
#: py/objstr.c
msgid "not enough arguments for format string"
-msgstr ""
+msgstr "書å¼åŒ–文字列ã¸ã®å¼•æ•°ãŒè¶³ã‚Šã¾ã›ã‚“"
#: extmod/ulab/code/poly/poly.c
msgid "number of arguments must be 2, or 3"
-msgstr "å¼•æ•°ã®æ•°ã¯2個ã¾ãŸã¯3個ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "引数ã¯2個ã¾ãŸã¯3個ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: extmod/ulab/code/ulab_create.c
msgid "number of points must be at least 2"
@@ -2847,7 +2844,7 @@ msgstr "オブジェクトã¯è¦ç´ ã®å–得をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“"
#: py/runtime.c
msgid "object not an iterator"
-msgstr "オブジェクトã¯ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ã§ã¯ã‚りã¾ã›ã‚“"
+msgstr "オブジェクトãŒã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ã§ã¯ã‚りã¾ã›ã‚“"
#: py/objtype.c py/runtime.c
msgid "object not callable"
@@ -2863,7 +2860,7 @@ msgstr "オブジェクトã¯ã‚¤ãƒ†ãƒ¬ãƒ¼ãƒˆã§ãã¾ã›ã‚“"
#: py/obj.c
msgid "object of type '%q' has no len()"
-msgstr ""
+msgstr "オブジェクト(型 '%q')ã¯len()ã‚’æŒã¡ã¾ã›ã‚“"
#: py/obj.c
msgid "object with buffer protocol required"
@@ -2879,7 +2876,7 @@ msgstr ""
#: ports/nrf/common-hal/audiobusio/PDMIn.c
msgid "only bit_depth=16 is supported"
-msgstr ""
+msgstr "bit_depth=16ã®ã¿ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™"
#: ports/nrf/common-hal/audiobusio/PDMIn.c
msgid "only sample_rate=16000 is supported"
@@ -2912,9 +2909,17 @@ msgstr "ord()ã¯1文字をå—ã‘å–りã¾ã™"
msgid "ord() expected a character, but string of length %d found"
msgstr "ord()ã¯1æ–‡å­—ã‚’è¦æ±‚ã—ã¾ã™ãŒã€é•·ã• %d ã®æ–‡å­—列ãŒä¸Žãˆã‚‰ã‚Œã¾ã—ãŸ"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr "ソースãŒç¯„囲外"
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
-msgstr "long int をマシン㮠word ã«å¤‰æ›ã™ã‚‹éš›ã«ã‚ªãƒ¼ãƒãƒ¼ãƒ•ローã—ã¾ã—ãŸ"
+msgstr "long intをマシンã®wordã«å¤‰æ›ã™ã‚‹éš›ã«ã‚ªãƒ¼ãƒãƒ¼ãƒ•ローã—ã¾ã—ãŸ"
#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c
msgid "palette must be 32 bytes long"
@@ -2922,7 +2927,7 @@ msgstr "パレットã®é•·ã•ã¯32ãƒã‚¤ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: shared-bindings/displayio/Palette.c
msgid "palette_index should be an int"
-msgstr "palette_indexã¯æ•´æ•°ã§ã™"
+msgstr "palette_indexã«ã¯æ•´æ•°ãŒå¿…è¦"
#: py/compile.c
msgid "parameter annotation must be an identifier"
@@ -2966,7 +2971,7 @@ msgstr "pow()ã®3ã¤ç›®ã®å¼•æ•°ã¯0ã«ã§ãã¾ã›ã‚“"
#: py/objint_mpz.c
msgid "pow() with 3 arguments requires integers"
-msgstr "pow()ã®3番目ã®å¼•æ•°ã«ã¯æ•´æ•°ãŒå¿…è¦"
+msgstr "pow()ã®ç¬¬3引数ã«ã¯æ•´æ•°ãŒå¿…è¦"
#: extmod/modutimeq.c
msgid "queue overflow"
@@ -2974,7 +2979,7 @@ msgstr "キューãŒã‚ªãƒ¼ãƒãƒ¼ãƒ•ローã—ã¾ã—ãŸ"
#: py/parse.c
msgid "raw f-strings are not implemented"
-msgstr ""
+msgstr "raw f-文字列ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“"
#: extmod/ulab/code/fft/fft.c
msgid "real and imaginary parts must be of equal length"
@@ -2987,7 +2992,7 @@ msgstr "相対インãƒãƒ¼ãƒˆ"
#: py/obj.c
#, c-format
msgid "requested length %d but object has length %d"
-msgstr "é•·ã•%dãŒå¿…è¦ã€‚オブジェクトã®é•·ã•ã¯%d"
+msgstr "å¿…è¦ãªé•·ã•ã¯%dã§ã™ãŒã‚ªãƒ–ジェクトã®é•·ã•ã¯%d"
#: py/compile.c
msgid "return annotation must be an identifier"
@@ -3019,9 +3024,7 @@ msgstr "rsplit(None,n)"
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
-msgstr ""
-"sample_source ãƒãƒƒãƒ•ã‚¡ã¯ã€bytearray ã¾ãŸã¯ 'h', 'H', 'b', 'B'åž‹ã®arrayã§ãªã‘"
-"れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "sample_source ãƒãƒƒãƒ•ã‚¡ã«ã¯ bytearray ã¾ãŸã¯ 'h','H','b','B'åž‹ã®arrayãŒå¿…è¦"
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "sampling rate out of range"
@@ -3037,7 +3040,7 @@ msgstr "スクリプトã®ã‚³ãƒ³ãƒ‘イルã¯éžã‚µãƒãƒ¼ãƒˆ"
#: extmod/ulab/code/ndarray.c
msgid "shape must be a 2-tuple"
-msgstr "shape㯠2値ã®ã‚¿ãƒ—ルã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "shapeã¯2値ã®ã‚¿ãƒ—ルã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: py/objstr.c
msgid "sign not allowed in string format specifier"
@@ -3091,6 +3094,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr ""
@@ -3101,11 +3108,11 @@ msgstr ""
#: shared-bindings/random/__init__.c
msgid "step must be non-zero"
-msgstr ""
+msgstr "stepã¯éžã‚¼ãƒ­å€¤ãŒå¿…è¦"
#: shared-bindings/busio/UART.c
msgid "stop must be 1 or 2"
-msgstr "stopã¯1ã¾ãŸã¯2ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "stopã¯1ã¾ãŸã¯2ã®ã„ãšã‚Œã‹"
#: shared-bindings/random/__init__.c
msgid "stop not reachable from start"
@@ -3117,11 +3124,11 @@ msgstr "ストリームæ“作ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
#: py/objstrunicode.c
msgid "string indices must be integers, not %q"
-msgstr ""
+msgstr "文字列ã®ã‚¤ãƒ³ãƒ‡ã‚¯ã‚¹ã«ã¯æ•´æ•°ãŒå¿…è¦ï¼ˆ%qã§ãªã)"
#: py/stream.c
msgid "string not supported; use bytes or bytearray"
-msgstr ""
+msgstr "文字列ã§ã¯ãªãbytesã¾ãŸã¯bytesarrayãŒå¿…è¦"
#: extmod/moductypes.c
msgid "struct: cannot index"
@@ -3137,7 +3144,7 @@ msgstr "部分文字列ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
#: py/compile.c
msgid "super() can't find self"
-msgstr ""
+msgstr "super()ãŒselfを見ã¤ã‘られã¾ã›ã‚“"
#: extmod/modujson.c
msgid "syntax error in JSON"
@@ -3149,7 +3156,7 @@ msgstr "uctypedãƒ‡ã‚£ã‚¹ã‚¯ãƒªãƒ—ã‚¿ã®æ§‹æ–‡ã‚¨ãƒ©ãƒ¼"
#: shared-bindings/touchio/TouchIn.c
msgid "threshold must be in the range 0-65536"
-msgstr "threshouldã¯0ã‹ã‚‰65536ã¾ã§ã§ã™"
+msgstr "threshouldã¯0ã‹ã‚‰65536ã¾ã§"
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
@@ -3157,7 +3164,7 @@ msgstr "time.struct_time()ã¯9è¦ç´ ã®ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã‚’å—ã‘å–りã¾ã™"
#: ports/nrf/common-hal/watchdog/WatchDogTimer.c
msgid "timeout duration exceeded the maximum supported value"
-msgstr ""
+msgstr "タイムアウト長ãŒã‚µãƒãƒ¼ãƒˆã•れる最大値を超ãˆã¦ã„ã¾ã™"
#: shared-bindings/busio/UART.c
msgid "timeout must be 0.0-100.0 seconds"
@@ -3177,11 +3184,11 @@ msgstr "v2カードã®å¾…機ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ"
#: shared-bindings/time/__init__.c
msgid "timestamp out of range for platform time_t"
-msgstr ""
+msgstr "timestampãŒãƒ—ラットフォームã®time_tã®ç¯„囲外"
#: shared-module/struct/__init__.c
msgid "too many arguments provided with the given format"
-msgstr ""
+msgstr "指定ã•ã‚ŒãŸæ›¸å¼ã«å¯¾ã—ã¦å¼•æ•°ãŒå¤šã™ãŽã¾ã™"
#: extmod/ulab/code/ndarray.c
msgid "too many indices"
@@ -3190,11 +3197,11 @@ msgstr "インデクスãŒå¤šã™ãŽã¾ã™"
#: py/runtime.c
#, c-format
msgid "too many values to unpack (expected %d)"
-msgstr ""
+msgstr "アンパックã™ã‚‹å€¤ãŒå¤šã™ãŽã¾ã™ (%d個を期待)"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays of equal length"
-msgstr ""
+msgstr "trapzã¯åŒã˜é•·ã•ã®1次元arrayã«å¯¾ã—ã¦å®šç¾©ã•れã¦ã„ã¾ã™"
#: extmod/ulab/code/linalg/linalg.c
msgid "tuple index out of range"
@@ -3207,7 +3214,7 @@ msgstr "タプル/リストã®é•·ã•ãŒæ­£ã—ãã‚りã¾ã›ã‚“"
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
#: shared-bindings/busio/UART.c
msgid "tx and rx cannot both be None"
-msgstr "txã¨rxã®ä¸¡æ–¹ã‚’Noneã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+msgstr "txã¨rxを両方ã¨ã‚‚Noneã«ã§ãã¾ã›ã‚“"
#: py/objtype.c
msgid "type '%q' is not an acceptable base type"
@@ -3223,7 +3230,7 @@ msgstr ""
#: py/objtype.c
msgid "type takes 1 or 3 arguments"
-msgstr "typeã¯1ã¤ã¾ãŸã¯3ã¤ã®å¼•æ•°ã‚’ã¨ã‚Šã¾ã™"
+msgstr "typeã¯1ã¤ã‹3ã¤ã®å¼•æ•°ã‚’ã¨ã‚Šã¾ã™"
#: py/objint_longlong.c
msgid "ulonglong too large"
@@ -3260,7 +3267,7 @@ msgstr ""
#: py/objstr.c
msgid "unknown format code '%c' for object of type '%q'"
-msgstr ""
+msgstr "åž‹'%q'ã®ã‚ªãƒ–ジェクトã«å¯¾ã™ã‚‹ä¸æ˜Žãªæ›¸å¼ã‚³ãƒ¼ãƒ‰'%c'"
#: py/compile.c
msgid "unknown type"
@@ -3308,12 +3315,12 @@ msgstr "演算å­ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„åž‹"
#: py/runtime.c
msgid "unsupported types for %q: '%q', '%q'"
-msgstr ""
+msgstr "%qã§ã‚µãƒãƒ¼ãƒˆã•れãªã„åž‹: '%q', '%q'"
#: py/objint.c
#, c-format
msgid "value must fit in %d byte(s)"
-msgstr "値㯠%d ãƒã‚¤ãƒˆã«åŽã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "値ã¯%dãƒã‚¤ãƒˆã«åŽã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
@@ -3333,11 +3340,11 @@ msgstr ""
#: extmod/ulab/code/linalg/linalg.c
msgid "wrong argument type"
-msgstr "引数ã®åž‹ãŒæ­£ã—ãã‚りã¾ã›ã‚“"
+msgstr "引数ã®åž‹ãŒä¸æ­£"
#: extmod/ulab/code/ndarray.c
msgid "wrong index type"
-msgstr "インデクスã®åž‹ãŒä¸æ­£ã§ã™"
+msgstr "インデクスã®åž‹ãŒä¸æ­£"
#: extmod/ulab/code/vector/vectorise.c
msgid "wrong input type"
@@ -3349,7 +3356,7 @@ msgstr ""
#: py/runtime.c
msgid "wrong number of values to unpack"
-msgstr ""
+msgstr "アンパックã™ã‚‹å€¤ã®å€‹æ•°ãŒä¸æ­£ã§ã™"
#: extmod/ulab/code/ndarray.c
msgid "wrong operand type"
@@ -3365,15 +3372,15 @@ msgstr ""
#: shared-bindings/displayio/Shape.c
msgid "y should be an int"
-msgstr "yã¯æ•´æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgstr "yã¯æ•´æ•°ãŒå¿…è¦"
#: shared-module/displayio/Shape.c
msgid "y value out of bounds"
-msgstr ""
+msgstr "yãŒç¯„囲外"
#: py/objrange.c
msgid "zero step"
-msgstr ""
+msgstr "ステップãŒ0"
#: extmod/ulab/code/filter/filter.c
msgid "zi must be an ndarray"
@@ -3381,7 +3388,7 @@ msgstr "ziã¯ndarrayã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: extmod/ulab/code/filter/filter.c
msgid "zi must be of float type"
-msgstr "ziã¯float値ãŒå¿…è¦ã§ã™"
+msgstr "ziã¯float値ãŒå¿…è¦"
#: extmod/ulab/code/filter/filter.c
msgid "zi must be of shape (n_section, 2)"
diff --git a/locale/ko.po b/locale/ko.po
index ecf539946..a4e088bc4 100644
--- a/locale/ko.po
+++ b/locale/ko.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2019-05-06 14:22-0700\n"
"Last-Translator: \n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -302,7 +302,7 @@ msgstr ""
msgid "All sync event channels in use"
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "í•€ì˜ ëª¨ë“  타ì´ë¨¸ê°€ 사용 중입니다"
@@ -314,7 +314,7 @@ msgstr "í•€ì˜ ëª¨ë“  타ì´ë¨¸ê°€ 사용 중입니다"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "모든 타ì´ë¨¸ê°€ 사용 중입니다"
@@ -492,6 +492,10 @@ msgstr ""
msgid "Can't set CCCD on local Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -554,7 +558,7 @@ msgstr ""
msgid "Cannot unambiguously get sizeof scalar"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
@@ -623,23 +627,23 @@ msgstr ""
msgid "Could not initialize UART"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr ""
@@ -647,7 +651,7 @@ msgstr ""
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr ""
@@ -744,8 +748,8 @@ msgstr ""
msgid "Error in regex"
msgstr "Regexì— ì˜¤ë¥˜ê°€ 있습니다."
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -756,10 +760,18 @@ msgstr "%q ì´ ì˜ˆìƒë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "Expected a Characteristic"
msgstr "특성(Characteristic)ì´ ì˜ˆìƒë˜ì—ˆìŠµë‹ˆë‹¤."
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -838,7 +850,7 @@ msgstr ""
msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
@@ -940,9 +952,9 @@ msgstr ""
msgid "Invalid DAC pin supplied"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr ""
@@ -982,7 +994,7 @@ msgstr "파ì¼ì´ 유효하지 않습니다"
msgid "Invalid format chunk size"
msgstr "í˜•ì‹ ì²­í¬ í¬ê¸°ê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr ""
@@ -1000,8 +1012,8 @@ msgid "Invalid phase"
msgstr "단계가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "í•€ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤"
@@ -1025,7 +1037,7 @@ msgstr "오른쪽 ì±„ë„ í•€ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤"
msgid "Invalid pins"
msgstr "í•€ì´ ìœ íš¨í•˜ì§€ 않습니다"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr ""
@@ -1207,7 +1219,7 @@ msgstr ""
msgid "No long integer support"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@@ -1245,6 +1257,10 @@ msgstr ""
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1275,12 +1291,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1335,8 +1351,8 @@ msgstr ""
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1351,10 +1367,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr ""
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr ""
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr ""
@@ -1566,7 +1578,7 @@ msgstr ""
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2456,6 +2468,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr ""
@@ -2648,6 +2664,10 @@ msgstr ""
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2882,6 +2902,14 @@ msgstr ""
msgid "ord() expected a character, but string of length %d found"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr ""
@@ -3059,6 +3087,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr ""
diff --git a/locale/nl.po b/locale/nl.po
index 313359668..9cce2523e 100644
--- a/locale/nl.po
+++ b/locale/nl.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2020-08-10 19:59+0000\n"
"Last-Translator: _fonzlate <vooralfred@gmail.com>\n"
"Language-Team: none\n"
@@ -308,7 +308,7 @@ msgstr "Alle event kanalen zijn in gebruik"
msgid "All sync event channels in use"
msgstr "Alle sync event kanalen zijn in gebruik"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Alle timers voor deze pin zijn in gebruik"
@@ -320,7 +320,7 @@ msgstr "Alle timers voor deze pin zijn in gebruik"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Alle timers zijn in gebruik"
@@ -500,6 +500,10 @@ msgstr "Roep super().__init__() aan voor toegang native object."
msgid "Can't set CCCD on local Characteristic"
msgstr "Kan CCCD niet toewijzen aan lokaal Characteristic"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -564,7 +568,7 @@ msgstr "Kan niet overdragen zonder MOSI en MISO pinnen."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "Kan niet ondubbelzinning sizeof scalar verkrijgen"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr "Kan de frequentie van een timer die al in gebruik is niet variëren"
@@ -637,23 +641,23 @@ msgstr "Kan SDCard niet initialiseren"
msgid "Could not initialize UART"
msgstr "Kan UART niet initialiseren"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "Kan kanaal niet initialiseren"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "Kan timer niet initialiseren"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "Kan kanaal niet her-initialiseren"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "Kan timer niet her-initialiseren"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "Kan PWM niet herstarten"
@@ -663,7 +667,7 @@ msgstr "Kan PWM niet herstarten"
msgid "Could not set address"
msgstr "Kan PWM niet starten"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "Kan PWM niet starten"
@@ -760,8 +764,8 @@ msgstr "EXTINT kanaal al in gebruik"
msgid "Error in regex"
msgstr "Fout in regex"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -772,10 +776,18 @@ msgstr "Verwacht een %q"
msgid "Expected a Characteristic"
msgstr "Verwachtte een Characteristic"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Verwachtte een Service"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -855,7 +867,7 @@ msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
"De vastgelegde frequentie is boven de capaciteit. Vastleggen gepauzeerd."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
"Frequentie moet overeenkomen met bestaande PWMOut bij gebruik van deze timer"
@@ -962,9 +974,9 @@ msgstr "Ongeldig BMP bestand"
msgid "Invalid DAC pin supplied"
msgstr "Ongeldige DAC pin opgegeven"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Ongeldige PWM frequentie"
@@ -1004,7 +1016,7 @@ msgstr "Ongeldig bestand"
msgid "Invalid format chunk size"
msgstr "Ongeldig formaat stuk grootte"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "Ongeldige frequentie opgegeven"
@@ -1022,8 +1034,8 @@ msgid "Invalid phase"
msgstr "Ongeldige fase"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Ongeldige pin"
@@ -1047,7 +1059,7 @@ msgstr "Ongeldige pin voor rechter kanaal"
msgid "Invalid pins"
msgstr "Ongeldige pinnen"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "Ongeldige pinnen voor PWMOut"
@@ -1229,7 +1241,7 @@ msgstr "Een sleutel was niet gespecificeerd"
msgid "No long integer support"
msgstr "Geen lange integer ondersteuning"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "Geen timers meer beschikbaar op deze pin."
@@ -1267,6 +1279,10 @@ msgstr "Wordt niet afgespeeld"
msgid "Not running saved code.\n"
msgstr "Opgeslagen code wordt niet uitgevoerd.\n"
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1303,13 +1319,13 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "Oversample moet een meervoud van 8 zijn."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
"PWM duty_cycle moet tussen 0 en 65535 inclusief zijn (16 bit resolutie)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1369,8 +1385,8 @@ msgstr "Polygon heeft op zijn minst 3 punten nodig"
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1387,10 +1403,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr "Pull niet gebruikt wanneer de richting output is."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr "PulseOut niet ondersteund door deze chip"
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr "RNG DeInit Fout"
@@ -1611,7 +1623,7 @@ msgstr "Tile breedte moet exact de bitmap breedte verdelen"
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr "Time-out is te lang. Maximale time-out lengte is %d seconden"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2518,6 +2530,10 @@ msgstr "indices moeten integers, segmenten (slices) of Boolean lijsten zijn"
msgid "initial values must be iterable"
msgstr "oorspronkelijke waarden moeten itereerbaar zijn"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "inline assembler moet een functie zijn"
@@ -2713,6 +2729,10 @@ msgstr "matrix is niet positief-definiet"
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr "max_length moet 0-%d zijn als fixed_length %s is"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "maximale recursiediepte overschreden"
@@ -2947,6 +2967,14 @@ msgstr "ord verwacht een teken (char)"
msgid "ord() expected a character, but string of length %d found"
msgstr "ord() verwacht een teken (char) maar vond een string van lengte %d"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "overloop bij converteren van long int naar machine word"
@@ -3127,6 +3155,10 @@ msgstr "sos[:, 3] moeten allemaal 1 zijn"
msgid "sosfilt requires iterable arguments"
msgstr "sosfilt vereist itereerbare argumenten"
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr "start/stop indices"
@@ -3423,6 +3455,9 @@ msgstr "zi moet van type float zijn"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi moet vorm (n_section, 2) hebben"
+#~ msgid "PulseOut not supported on this chip"
+#~ msgstr "PulseOut niet ondersteund door deze chip"
+
#~ msgid "tuple/list required on RHS"
#~ msgstr "tuple of lijst vereist op RHS"
diff --git a/locale/pl.po b/locale/pl.po
index 6c52062d9..b072629cd 100644
--- a/locale/pl.po
+++ b/locale/pl.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@@ -302,7 +302,7 @@ msgstr "Wszystkie kanały zdarzeń w użyciu"
msgid "All sync event channels in use"
msgstr "Wszystkie kanały zdarzeń synchronizacji w użyciu"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Wszystkie timery tej nóżki w użyciu"
@@ -314,7 +314,7 @@ msgstr "Wszystkie timery tej nóżki w użyciu"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Wszystkie timery w użyciu"
@@ -492,6 +492,10 @@ msgstr ""
msgid "Can't set CCCD on local Characteristic"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -554,7 +558,7 @@ msgstr "Nie można przesyłać bez nóżek MOSI i MISO."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "Wielkość skalara jest niejednoznaczna"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr ""
@@ -623,23 +627,23 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Ustawienie UART nie powiodło się"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr ""
@@ -647,7 +651,7 @@ msgstr ""
msgid "Could not set address"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr ""
@@ -744,8 +748,8 @@ msgstr "Kanał EXTINT w użyciu"
msgid "Error in regex"
msgstr "Błąd w regex"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -756,10 +760,18 @@ msgstr "Oczekiwano %q"
msgid "Expected a Characteristic"
msgstr "Oczekiwano charakterystyki"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -838,7 +850,7 @@ msgstr ""
msgid "Frequency captured is above capability. Capture Paused."
msgstr "Uzyskana częstotliwość jest niemożliwa. Spauzowano."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
@@ -942,9 +954,9 @@ msgstr "Zły BMP"
msgid "Invalid DAC pin supplied"
msgstr ""
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Zła częstotliwość PWM"
@@ -984,7 +996,7 @@ msgstr "Zły plik"
msgid "Invalid format chunk size"
msgstr "Zła wielkość fragmentu formatu"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr ""
@@ -1002,8 +1014,8 @@ msgid "Invalid phase"
msgstr "Zła faza"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Zła nóżka"
@@ -1027,7 +1039,7 @@ msgstr "Zła nóżka dla prawego kanału"
msgid "Invalid pins"
msgstr "Złe nóżki"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr ""
@@ -1209,7 +1221,7 @@ msgstr ""
msgid "No long integer support"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@@ -1247,6 +1259,10 @@ msgstr "Nic nie jest odtwarzane"
msgid "Not running saved code.\n"
msgstr ""
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1277,12 +1293,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "Nadpróbkowanie musi być wielokrotnością 8."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr "duty_cycle musi być pomiędzy 0 a 65535 włącznie (rozdzielczość 16 bit)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr "Nie można zmienić częstotliwości PWM gdy variable_frequency=False."
@@ -1337,8 +1353,8 @@ msgstr ""
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1353,10 +1369,6 @@ msgstr "Dowolny klawisz aby uruchomić konsolę. CTRL-D aby przeładować."
msgid "Pull not used when direction is output."
msgstr "Podciągnięcie nieużywane w trybie wyjścia."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr ""
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr ""
@@ -1568,7 +1580,7 @@ msgstr "Szerokość bitmapy musi być wielokrotnością szerokości kafelka"
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2461,6 +2473,10 @@ msgstr ""
msgid "initial values must be iterable"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "wtrącony asembler musi być funkcją"
@@ -2653,6 +2669,10 @@ msgstr ""
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr ""
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "przekroczono dozwoloną głębokość rekurencji"
@@ -2887,6 +2907,14 @@ msgstr "ord oczekuje znaku"
msgid "ord() expected a character, but string of length %d found"
msgstr "ord() oczekuje znaku, a jest łańcuch od długości %d"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "przepełnienie przy konwersji long in to słowa maszynowego"
@@ -3066,6 +3094,10 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr "początkowe/końcowe indeksy"
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index 9fb4142c4..e407756d0 100644
--- a/locale/pt_BR.po
+++ b/locale/pt_BR.po
@@ -5,8 +5,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
-"PO-Revision-Date: 2020-08-21 18:19+0000\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
+"PO-Revision-Date: 2020-08-31 00:37+0000\n"
"Last-Translator: Wellington Terumi Uemura <wellingtonuemura@gmail.com>\n"
"Language-Team: \n"
"Language: pt_BR\n"
@@ -312,7 +312,7 @@ msgstr "Todos os canais de eventos em uso"
msgid "All sync event channels in use"
msgstr "Todos os canais dos eventos de sincronização em uso"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Todos os temporizadores para este pino estão em uso"
@@ -324,7 +324,7 @@ msgstr "Todos os temporizadores para este pino estão em uso"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Todos os temporizadores em uso"
@@ -506,6 +506,10 @@ msgstr "Chame super().__init__() antes de acessar o objeto nativo."
msgid "Can't set CCCD on local Characteristic"
msgstr "Não é possível definir o CCCD com a característica local"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -571,7 +575,7 @@ msgstr "Não é possível transferir sem os pinos MOSI e MISO."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "Não é possível obter inequivocamente o tamanho do escalar"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr "Não é possível variar a frequência em um timer que já esteja em uso"
@@ -644,23 +648,23 @@ msgstr "Não foi possível inicializar o SDCard"
msgid "Could not initialize UART"
msgstr "Não foi possível inicializar o UART"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "Não foi possível inicializar o canal"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "Não foi possível inicializar o temporizador"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "Não foi possível reiniciar o canal"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "Não foi possível reiniciar o temporizador"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "Não foi possível reiniciar o PWM"
@@ -668,7 +672,7 @@ msgstr "Não foi possível reiniciar o PWM"
msgid "Could not set address"
msgstr "Não foi possível definir o endereço"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "Não foi possível iniciar o PWM"
@@ -765,8 +769,8 @@ msgstr "Canal EXTINT em uso"
msgid "Error in regex"
msgstr "Erro no regex"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -777,10 +781,18 @@ msgstr "Esperado um"
msgid "Expected a Characteristic"
msgstr "Uma característica é necessária"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Esperava um Serviço"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -860,7 +872,7 @@ msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
"A frequência capturada está acima da capacidade. A captura está em pausa."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr ""
"A frequência deve coincidir com o PWMOut existente usando este temporizador"
@@ -965,9 +977,9 @@ msgstr "Arquivo BMP inválido"
msgid "Invalid DAC pin supplied"
msgstr "O pino DAC informado é inválido"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Frequência PWM inválida"
@@ -1007,7 +1019,7 @@ msgstr "Arquivo inválido"
msgid "Invalid format chunk size"
msgstr "Tamanho do pedaço de formato inválido"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "A frequência informada é inválida"
@@ -1025,8 +1037,8 @@ msgid "Invalid phase"
msgstr "Fase Inválida"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Pino inválido"
@@ -1050,7 +1062,7 @@ msgstr "Pino inválido para canal direito"
msgid "Invalid pins"
msgstr "Pinos inválidos"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "Os pinos para o PWMOut são inválidos"
@@ -1232,7 +1244,7 @@ msgstr "Nenhuma chave foi definida"
msgid "No long integer support"
msgstr "Não há compatibilidade com inteiro longo"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "Não há mais temporizadores disponíveis neste pino."
@@ -1270,6 +1282,10 @@ msgstr "Não está jogando"
msgid "Not running saved code.\n"
msgstr "O código salvo não está em execução.\n"
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1305,14 +1321,14 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "A superamostragem deve ser um múltiplo de 8."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
"O duty_cycle do PWM deve estar entre 0 e inclusive 65535 (com resolução de "
"16 bits)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1372,11 +1388,11 @@ msgstr "O Polígono precisa de pelo menos 3 pontos"
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
-"A porta não aceita pinos ou frequência. "
-"Em vez disso, Construa e encaminhe um PWMOut Carrier"
+"A porta não aceita pinos ou frequência. Em vez disso, construa e passe um "
+"PWMOut Carrier"
#: shared-bindings/_bleio/Adapter.c
msgid "Prefix buffer must be on the heap"
@@ -1393,10 +1409,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr "O Pull não foi usado quando a direção for gerada."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr "O PulseOut não é compatível neste CI"
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr "Erro DeInit RNG"
@@ -1619,7 +1631,7 @@ msgstr ""
"O tempo limite é long demais: O comprimento máximo do tempo limite é de %d "
"segundos"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2533,6 +2545,10 @@ msgstr "os índices devem ser números inteiros, fatias ou listas booleanas"
msgid "initial values must be iterable"
msgstr "os valores iniciais devem ser iteráveis"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "o assembler em linha deve ser uma função"
@@ -2728,6 +2744,10 @@ msgstr "a matriz não é definitiva positiva"
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr "o max_length deve ser 0-%d quando Fixed_length for %s"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "a recursão máxima da profundidade foi excedida"
@@ -2967,6 +2987,14 @@ msgstr ""
"o ord() esperava um caractere, porém a sequência do comprimento %d foi "
"encontrada"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr "fora do alcance da fonte"
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr "fora do alcance do alvo"
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr ""
@@ -3148,6 +3176,10 @@ msgstr "sos[:, 3] deve ser um em todos"
msgid "sosfilt requires iterable arguments"
msgstr "o sosfilt requer que os argumentos sejam iteráveis"
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr "a paleta de origem é muito grande"
+
#: py/objstr.c
msgid "start/end indices"
msgstr "os índices de início/fim"
@@ -3444,6 +3476,18 @@ msgstr "zi deve ser de um tipo float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi deve estar na forma (n_section, 2)"
+#~ msgid "PulseOut not supported on this chip"
+#~ msgstr "O PulseOut não é compatível neste CI"
+
+#~ msgid ""
+#~ "Port does not accept pins or "
+#~ "frequency. Construct and pass a "
+#~ "PWMOut Carrier instead"
+#~ msgstr ""
+#~ "A porta não aceita pinos ou "
+#~ "frequência. Em vez disso, Construa e "
+#~ "encaminhe um PWMOut Carrier"
+
#~ msgid "tuple/list required on RHS"
#~ msgstr "a tupla/lista necessária no RHS"
diff --git a/locale/sv.po b/locale/sv.po
index df205b109..9b9a52dac 100644
--- a/locale/sv.po
+++ b/locale/sv.po
@@ -5,16 +5,16 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
-"PO-Revision-Date: 2020-07-25 20:58+0000\n"
-"Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
+"PO-Revision-Date: 2020-08-30 20:02+0000\n"
+"Last-Translator: Jeff Epler <jepler@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.2.1-dev\n"
#: main.c
msgid ""
@@ -82,7 +82,7 @@ msgstr "Index %q ligger utanför intervallet"
#: py/obj.c
msgid "%q indices must be integers, not %q"
-msgstr ""
+msgstr "%q index måste vara heltal, inte %q"
#: shared-bindings/vectorio/Polygon.c
msgid "%q list must be a list"
@@ -122,39 +122,39 @@ msgstr "'%q' argument krävs"
#: py/runtime.c
msgid "'%q' object cannot assign attribute '%q'"
-msgstr ""
+msgstr "Objektet '%q' kan inte tilldela attributet '%q'"
#: py/proto.c
msgid "'%q' object does not support '%q'"
-msgstr ""
+msgstr "Objektet '%q' stöder inte '%q'"
#: py/obj.c
msgid "'%q' object does not support item assignment"
-msgstr ""
+msgstr "Objektet '%q' stöder inte tilldelning"
#: py/obj.c
msgid "'%q' object does not support item deletion"
-msgstr ""
+msgstr "Objektet '%q' stöder inte borttagning av objekt"
#: py/runtime.c
msgid "'%q' object has no attribute '%q'"
-msgstr ""
+msgstr "Objektet '%q' har inget attribut '%q'"
#: py/runtime.c
msgid "'%q' object is not an iterator"
-msgstr ""
+msgstr "Objektet '%q' är inte en iterator"
#: py/objtype.c py/runtime.c
msgid "'%q' object is not callable"
-msgstr ""
+msgstr "Objektet '%q' kan inte anropas"
#: py/runtime.c
msgid "'%q' object is not iterable"
-msgstr ""
+msgstr "Objektet '%q' är inte itererbart"
#: py/obj.c
msgid "'%q' object is not subscriptable"
-msgstr ""
+msgstr "Objektet '%q' är inte indexbar"
#: py/emitinlinethumb.c py/emitinlinextensa.c
#, c-format
@@ -224,7 +224,7 @@ msgstr "'await' utanför funktion"
#: py/compile.c
msgid "'await', 'async for' or 'async with' outside async function"
-msgstr ""
+msgstr "'await', 'async for' eller 'async with' utanför asynk-funktion"
#: py/compile.c
msgid "'break' outside loop"
@@ -308,7 +308,7 @@ msgstr "Alla händelsekanaler används"
msgid "All sync event channels in use"
msgstr "Alla händelsekanaler används"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Alla timers för denna pinne är i bruk"
@@ -320,7 +320,7 @@ msgstr "Alla timers för denna pinne är i bruk"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "Alla timers används"
@@ -457,7 +457,7 @@ msgstr "Buffertlängd måste vara en multipel av 512"
#: ports/stm/common-hal/sdioio/SDCard.c
msgid "Buffer must be a multiple of 512 bytes"
-msgstr ""
+msgstr "Bufferten måste vara en multipel av 512 byte"
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
@@ -498,6 +498,10 @@ msgstr "Anropa super().__init__() innan du använder det ursprungliga objektet."
msgid "Can't set CCCD on local Characteristic"
msgstr "Kan inte ställa in CCCD på lokal karaktäristik"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -562,7 +566,7 @@ msgstr "Kan inte överföra utan MOSI- och MISO-pinnar."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "Kan inte entydigt få sizeof scalar"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr "Det går inte att ändra frekvensen på en timer som redan används"
@@ -635,31 +639,31 @@ msgstr "Kan inte initiera SD-kort"
msgid "Could not initialize UART"
msgstr "Det gick inte att initiera UART"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "Det gick inte att initiera kanalen"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "Det gick inte att initialisera timern"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "Det gick inte att återinitiera kanalen"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "Det gick inte att återinitiera timern"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "Det gick inte att starta om PWM"
#: shared-bindings/_bleio/Adapter.c
msgid "Could not set address"
-msgstr ""
+msgstr "Kan inte ange adress"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "Det gick inte att starta PWM"
@@ -756,8 +760,8 @@ msgstr "EXTINT-kanalen används redan"
msgid "Error in regex"
msgstr "Fel i regex"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -768,10 +772,18 @@ msgstr "Förväntade %q"
msgid "Expected a Characteristic"
msgstr "Förväntade en karaktäristik"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Förväntade en tjänst"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -844,13 +856,13 @@ msgstr "Filen finns redan"
#: shared-module/framebufferio/FramebufferDisplay.c
#, c-format
msgid "Framebuffer requires %d bytes"
-msgstr ""
+msgstr "Framebuffer kräver %d byte"
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
msgid "Frequency captured is above capability. Capture Paused."
msgstr "Infångningsfrekvens är för hög. Infångning pausad."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr "Frekvensen måste matcha befintlig PWMOut med denna timer"
@@ -888,7 +900,7 @@ msgstr "I2C init-fel"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
-msgstr ""
+msgstr "I2SOut är inte tillgängligt"
#: shared-bindings/aesio/aes.c
#, c-format
@@ -940,7 +952,7 @@ msgstr "Ogiltig %q-pinne"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/stm/common-hal/busio/UART.c ports/stm/common-hal/sdioio/SDCard.c
msgid "Invalid %q pin selection"
-msgstr ""
+msgstr "Ogiltigt val av %q pinne"
#: ports/stm/common-hal/analogio/AnalogIn.c
msgid "Invalid ADC Unit value"
@@ -954,9 +966,9 @@ msgstr "Ogiltig BMP-fil"
msgid "Invalid DAC pin supplied"
msgstr "Ogiltig DAC-pinne angiven"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Ogiltig PWM-frekvens"
@@ -996,7 +1008,7 @@ msgstr "Felaktig fil"
msgid "Invalid format chunk size"
msgstr "Ogiltig formatsegmentstorlek"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "Ogiltig frekvens angiven"
@@ -1014,8 +1026,8 @@ msgid "Invalid phase"
msgstr "Ogiltig fas"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Ogiltig pinne"
@@ -1039,7 +1051,7 @@ msgstr "Ogiltig pinne för höger kanal"
msgid "Invalid pins"
msgstr "Ogiltiga pinnar"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "Ogiltiga pinnar för PWMOut"
@@ -1222,7 +1234,7 @@ msgstr "Ingen nyckel angavs"
msgid "No long integer support"
msgstr "Inget stöd för långt heltal"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "Inga fler timers tillgängliga på denna pinne."
@@ -1258,6 +1270,10 @@ msgstr "Ingen uppspelning"
#: main.c
msgid "Not running saved code.\n"
+msgstr "Kör inte sparad kod.\n"
+
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
msgstr ""
#: shared-bindings/util.c
@@ -1295,12 +1311,12 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "Översampling måste vara multipel av 8."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr "PWM duty_cykel måste vara mellan 0 och 65535 (16 bitars upplösning)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
@@ -1360,8 +1376,8 @@ msgstr "Polygonen behöver minst 3 punkter"
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1377,10 +1393,6 @@ msgstr ""
msgid "Pull not used when direction is output."
msgstr "Pull används inte när riktningen är output."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr "PulseIn stöds inte av detta chip"
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr "RNG DeInit-fel"
@@ -1442,7 +1454,7 @@ msgstr "Radvärdet måste vara digitalio.DigitalInOut"
#: main.c
msgid "Running in safe mode! "
-msgstr ""
+msgstr "Kör i säkert läge! "
#: shared-module/sdcardio/SDCard.c
msgid "SD card CSD format not supported"
@@ -1456,12 +1468,12 @@ msgstr "SDA eller SCL behöver en pullup"
#: ports/stm/common-hal/sdioio/SDCard.c
#, c-format
msgid "SDIO GetCardInfo Error %d"
-msgstr ""
+msgstr "SDIO GetCardInfo-fel %d"
#: ports/stm/common-hal/sdioio/SDCard.c
#, c-format
msgid "SDIO Init Error %d"
-msgstr ""
+msgstr "SDIO Init-fel %d"
#: ports/stm/common-hal/busio/SPI.c
msgid "SPI Init Error"
@@ -1600,7 +1612,7 @@ msgstr "Tile-bredd måste vara jämnt delbar med bredd på bitmap"
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr "Åtgärden tog för lång tid: Max väntetid är %d sekunder"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -1831,7 +1843,7 @@ msgstr "__init __ () ska returnera None"
#: py/objtype.c
msgid "__init__() should return None, not '%q'"
-msgstr ""
+msgstr "__init__() ska returnera None, inte '%q'"
#: py/objobject.c
msgid "__new__ arg must be a user-type"
@@ -1876,7 +1888,7 @@ msgstr "argumentet har fel typ"
#: extmod/ulab/code/linalg/linalg.c
msgid "argument must be ndarray"
-msgstr ""
+msgstr "argument måste vara ndarray"
#: py/argcheck.c shared-bindings/_stage/__init__.c
#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c
@@ -2019,7 +2031,7 @@ msgstr "kan inte tilldela uttryck"
#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c
#: shared-module/_pixelbuf/PixelBuf.c
msgid "can't convert %q to %q"
-msgstr ""
+msgstr "kan inte konvertera %q till %q"
#: py/objstr.c
msgid "can't convert '%q' object to %q implicitly"
@@ -2027,7 +2039,7 @@ msgstr "kan inte konvertera '%q' objekt implicit till %q"
#: py/obj.c
msgid "can't convert to %q"
-msgstr ""
+msgstr "kan inte konvertera till %q"
#: py/objstr.c
msgid "can't convert to str implicitly"
@@ -2504,6 +2516,10 @@ msgstr "index måste vara heltal, slices, eller Boolean-listor"
msgid "initial values must be iterable"
msgstr "initialvärden måste vara iterable"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "inline assembler måste vara en funktion"
@@ -2699,6 +2715,10 @@ msgstr "matrisen är inte positiv bestämd"
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr "max_length måste vara 0-%d när fixed_length är %s"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "maximal rekursionsdjup överskriden"
@@ -2848,7 +2868,7 @@ msgstr "antal punkter måste vara minst 2"
#: py/obj.c
msgid "object '%q' is not a tuple or list"
-msgstr ""
+msgstr "objektet '%q' är inte en tuple eller list"
#: py/obj.c
msgid "object does not support item assignment"
@@ -2884,7 +2904,7 @@ msgstr "objektet är inte iterable"
#: py/obj.c
msgid "object of type '%q' has no len()"
-msgstr ""
+msgstr "objekt av typen '%q' har inte len()"
#: py/obj.c
msgid "object with buffer protocol required"
@@ -2933,6 +2953,14 @@ msgstr "ord förväntar sig ett tecken"
msgid "ord() expected a character, but string of length %d found"
msgstr "ord() förväntade sig ett tecken, men en sträng med längden %d hittades"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "Konvertering av long int till machine word överskred maxvärde"
@@ -2980,7 +3008,7 @@ msgstr "polygon kan endast registreras i en förälder"
#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c
#: shared-bindings/ps2io/Ps2.c
msgid "pop from empty %q"
-msgstr ""
+msgstr "pop från tom %q"
#: py/objint_mpz.c
msgid "pow() 3rd argument cannot be 0"
@@ -3113,6 +3141,10 @@ msgstr "sos[:, 3] måste vara ettor"
msgid "sosfilt requires iterable arguments"
msgstr "sosfilt kräver iterable argument"
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr "start-/slutindex"
@@ -3139,7 +3171,7 @@ msgstr "stream-åtgärd stöds inte"
#: py/objstrunicode.c
msgid "string indices must be integers, not %q"
-msgstr ""
+msgstr "strängindex måste vara heltal, inte %q"
#: py/stream.c
msgid "string not supported; use bytes or bytearray"
@@ -3216,7 +3248,7 @@ msgstr "för många värden att packa upp (förväntat %d)"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays of equal length"
-msgstr ""
+msgstr "trapz är definierad för 1D-matriser med samma längd"
#: extmod/ulab/code/linalg/linalg.c
msgid "tuple index out of range"
@@ -3282,7 +3314,7 @@ msgstr "okänd konverteringsspecificerare %c"
#: py/objstr.c
msgid "unknown format code '%c' for object of type '%q'"
-msgstr ""
+msgstr "okänd formatkod '%c' för objekt av typ '%q'"
#: py/compile.c
msgid "unknown type"
@@ -3322,7 +3354,7 @@ msgstr "Formattecknet '%c' (0x%x) stöds inte vid index %d"
#: py/runtime.c
msgid "unsupported type for %q: '%q'"
-msgstr ""
+msgstr "typen %q stöder inte '%q'"
#: py/runtime.c
msgid "unsupported type for operator"
@@ -3330,7 +3362,7 @@ msgstr "typ stöds inte för operatören"
#: py/runtime.c
msgid "unsupported types for %q: '%q', '%q'"
-msgstr ""
+msgstr "typen %q stöder inte '%q', '%q'"
#: py/objint.c
#, c-format
@@ -3343,7 +3375,7 @@ msgstr "value_count måste vara > 0"
#: extmod/ulab/code/linalg/linalg.c
msgid "vectors must have same lengths"
-msgstr ""
+msgstr "vektorer måste ha samma längd"
#: shared-bindings/watchdog/WatchDogTimer.c
msgid "watchdog timeout must be greater than 0"
@@ -3409,6 +3441,9 @@ msgstr "zi måste vara av typ float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi måste vara i formen (n_section, 2)"
+#~ msgid "PulseOut not supported on this chip"
+#~ msgstr "PulseIn stöds inte av detta chip"
+
#~ msgid "tuple/list required on RHS"
#~ msgstr "tupel/lista krävs för RHS"
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index 725491f5b..56f9bae8c 100644
--- a/locale/zh_Latn_pinyin.po
+++ b/locale/zh_Latn_pinyin.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-18 11:19-0400\n"
+"POT-Creation-Date: 2020-08-30 14:38-0400\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@@ -309,7 +309,7 @@ msgstr "SuÇ’yÇ’u shÇyòng de shìjiàn píndào"
msgid "All sync event channels in use"
msgstr "SuÇ’yÇ’u tóngbù shìjiàn píndào shÇyòng"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "CÇ yÇn jiÇŽo de suÇ’yÇ’u jìshí qì zhèngzài shÇyòng"
@@ -321,7 +321,7 @@ msgstr "CÇ yÇn jiÇŽo de suÇ’yÇ’u jìshí qì zhèngzài shÇyòng"
#: ports/cxd56/common-hal/pulseio/PulseOut.c
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
-#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c
+#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
msgid "All timers in use"
msgstr "SuÇ’yÇ’u jìshí qì shÇyòng"
@@ -499,6 +499,10 @@ msgstr "Zài fǎngwèn běn jī wùjiàn zhīqián diàoyòng super().__init__()
msgid "Can't set CCCD on local Characteristic"
msgstr "WúfÇŽ jiÄng CCCD shèzhì wéi bÄ›ndì tèzhÄ“ng"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Cannot create a new Adapter; use _bleio.adapter;"
+msgstr ""
+
#: shared-bindings/displayio/Bitmap.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
@@ -561,7 +565,7 @@ msgstr "Méiyǒu MOSI/MISO jiù wúfǎ zhuǎnyí."
msgid "Cannot unambiguously get sizeof scalar"
msgstr "WúfÇŽ míngquè de huòdé biÄoliàng de dàxiÇŽo"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr "WúfÇŽ gÄ“nggÇŽi yÇ zài shÇyòng de jìshí qì shàng de pínlÇœ"
@@ -632,23 +636,23 @@ msgstr "wú fÇŽ chÅ« shÇ huà SDCard"
msgid "Could not initialize UART"
msgstr "WúfÇŽ chÅ«shÇhuà UART"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize channel"
msgstr "WúfÇŽ chÅ«shÇhuà píndào"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not initialize timer"
msgstr "WúfÇŽ chÅ«shÇhuà jìshí qì"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init channel"
msgstr "WúfÇŽ chóngxÄ«n chÅ«shÇhuà píndào"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not re-init timer"
msgstr "WúfÇŽ chóngxÄ«n qÇdòng jìshí qì"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not restart PWM"
msgstr "WúfÇŽ chóngqÇ PWM"
@@ -656,7 +660,7 @@ msgstr "WúfÇŽ chóngqÇ PWM"
msgid "Could not set address"
msgstr "wú fÇŽ shè zhì dì zhÇ"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Could not start PWM"
msgstr "WúfÇŽ qÇdòng PWM"
@@ -753,8 +757,8 @@ msgstr "EXTINT píndào yÇjÄ«ng shÇyòng"
msgid "Error in regex"
msgstr "Zhèngzé biǎodá shì cuòwù"
-#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c
-#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
+#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@@ -765,10 +769,18 @@ msgstr "Yùqí %q"
msgid "Expected a Characteristic"
msgstr "Yùqí de tèdiǎn"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a DigitalInOut"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Yùqí fúwù"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected a UART"
+msgstr ""
+
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
@@ -847,7 +859,7 @@ msgstr "zhÄ“n huÇŽn chÅng qÅ« xÅ« yào %d zì jié"
msgid "Frequency captured is above capability. Capture Paused."
msgstr "PínlÇœ bÇ”huò gÄo yú nénglì. BÇ”huò zàntíng."
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Frequency must match existing PWMOut using this timer"
msgstr "PínlÇœ bìxÅ« yÇ” shÇyòng cÇ jìshí qì de xiàn yÇ’u PWMOut xiÄng pÇpèi"
@@ -951,9 +963,9 @@ msgstr "Wúxiào de BMP wénjiàn"
msgid "Invalid DAC pin supplied"
msgstr "Tí gÅng liÇŽo wúxiào de DAC yÇn jiÇŽo"
-#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
-#: ports/cxd56/common-hal/pulseio/PWMOut.c
-#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+#: ports/atmel-samd/common-hal/pwmio/PWMOut.c
+#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr "Wúxiào de PWM pínlǜ"
@@ -993,7 +1005,7 @@ msgstr "Wúxiào de wénjiàn"
msgid "Invalid format chunk size"
msgstr "Géshì kuài dàxiǎo wúxiào"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid frequency supplied"
msgstr "TígÅng de pínlÇœ wúxiào"
@@ -1011,8 +1023,8 @@ msgid "Invalid phase"
msgstr "Jiēduàn wúxiào"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
-#: ports/atmel-samd/common-hal/touchio/TouchIn.c
-#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c
+#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid pin"
msgstr "Wúxiào de yÇn jiÇŽo"
@@ -1036,7 +1048,7 @@ msgstr "Yòuxián tÅngdào yÇn jiÇŽo wúxiào"
msgid "Invalid pins"
msgstr "Wúxiào de yÇn jiÇŽo"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "Invalid pins for PWMOut"
msgstr "PWMOut de yÇn jiÇŽo wú xiào"
@@ -1218,7 +1230,7 @@ msgstr "Wèi zhÇdìng mì yào"
msgid "No long integer support"
msgstr "Méiyǒu zhǎng zhěngshù zhīchí"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "GÄi yÇn jiÇŽo shàng méiyÇ’u kÄ›yòng de dìngshí qì."
@@ -1256,6 +1268,10 @@ msgstr "Wèi bòfàng"
msgid "Not running saved code.\n"
msgstr "MéiyÇ’u yùnxíng yÇ bÇŽocún de dàimÇŽ.\n"
+#: shared-bindings/_bleio/__init__.c
+msgid "Not settable"
+msgstr ""
+
#: shared-bindings/util.c
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
@@ -1291,13 +1307,13 @@ msgstr ""
msgid "Oversample must be multiple of 8."
msgstr "Guò cǎiyàng bìxū shì 8 de bèishù."
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
msgstr ""
"PWM yìwù zhÅuqí bìxÅ« jiè yú 0 zhì 65535 de bÄoróng xìng (16 wèi fÄ“nbiàn lÇœ)"
-#: shared-bindings/pulseio/PWMOut.c
+#: shared-bindings/pwmio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr "DÄng biànliàng_pínlÇœ shì False zài jiànzhú shí PWM pínlÇœ bùkÄ› xiÄ›."
@@ -1355,8 +1371,8 @@ msgstr "DuÅbiÄnxíng zhìshÇŽo xÅ«yào 3 diÇŽn"
#: ports/nrf/common-hal/pulseio/PulseOut.c
#: ports/stm/common-hal/pulseio/PulseOut.c
msgid ""
-"Port does not accept pins or frequency. "
-"Construct and pass a PWMOut Carrier instead"
+"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
+"instead"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
@@ -1371,10 +1387,6 @@ msgstr "Àn xià rènhé jiàn jìnrù REPL. ShÇyòng CTRL-D chóngxÄ«n jiÄzà
msgid "Pull not used when direction is output."
msgstr "FÄngxiàng shÅ«chÅ« shí Pull méiyÇ’u shÇyòng."
-#: ports/stm/ref/pulseout-pre-timeralloc.c
-msgid "PulseOut not supported on this chip"
-msgstr ""
-
#: ports/stm/common-hal/os/__init__.c
msgid "RNG DeInit Error"
msgstr "RNG qÇ”xiÄo chÅ«shÇhuà cuòwù"
@@ -1593,7 +1605,7 @@ msgstr "Píng pÅ« kuÄndù bìxÅ« huàfÄ“n wèi tú kuÄndù"
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr "ChÄoshí shíjiÄn tài zhÇŽng: Zuìdà chÄoshí shíjiÄn wèi%d miÇŽo"
-#: ports/stm/common-hal/pulseio/PWMOut.c
+#: ports/stm/common-hal/pwmio/PWMOut.c
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
@@ -2496,6 +2508,10 @@ msgstr "suÇ’yÇn bìxÅ« shì zhÄ›ngshù, qiÄ“piàn huò bù'Ä›r zhí lièbiÇŽo"
msgid "initial values must be iterable"
msgstr "chÅ«shÇ zhí bìxÅ« shì kÄ› diédài de"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "initial_value length is wrong"
+msgstr ""
+
#: py/compile.c
msgid "inline assembler must be a function"
msgstr "nèi lián jíhé bìxū shì yīgè hánshù"
@@ -2689,6 +2705,10 @@ msgstr "jǔzhèn bùshì zhèngdìng de"
msgid "max_length must be 0-%d when fixed_length is %s"
msgstr "DÄng gùdìng chángdù wèi %s shí, zuìdà chángdù bìxÅ« wèi 0-%d"
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+msgid "max_length must be > 0"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "chÄochÅ« zuìdà dìguÄ« shÄ“ndù"
@@ -2924,6 +2944,14 @@ msgstr "ord yùqí zìfú"
msgid "ord() expected a character, but string of length %d found"
msgstr "ord() yùqí zìfú, dàn chángdù zìfú chuàn %d"
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of source"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "out of range of target"
+msgstr ""
+
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
msgstr "chÄo gÄo zhuÇŽnhuàn zhÇŽng zhÄ›ng shùzì shí"
@@ -3103,6 +3131,10 @@ msgstr "sos [:, 3] yÄ«nggÄi quán shì"
msgid "sosfilt requires iterable arguments"
msgstr "sosfilt xÅ«yào diédài cÄnshù"
+#: shared-bindings/displayio/Bitmap.c
+msgid "source palette too large"
+msgstr ""
+
#: py/objstr.c
msgid "start/end indices"
msgstr "kÄishÇ/jiéshù zhÇshù"
diff --git a/main.c b/main.c
index 3a14df0fa..5b719dc4b 100755
--- a/main.c
+++ b/main.c
@@ -105,6 +105,12 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
static size_t PLACE_IN_DTCM_BSS(_pystack[CIRCUITPY_PYSTACK_SIZE / sizeof(size_t)]);
#endif
+static void reset_devices(void) {
+#if CIRCUITPY_BLEIO_HCI
+ bleio_reset();
+#endif
+}
+
void start_mp(supervisor_allocation* heap) {
reset_status_led();
autoreload_stop();
@@ -206,6 +212,8 @@ bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec_result
}
void cleanup_after_vm(supervisor_allocation* heap) {
+ // Reset port-independent devices, like CIRCUITPY_BLEIO_HCI.
+ reset_devices();
// Turn off the display and flush the fileystem before the heap disappears.
#if CIRCUITPY_DISPLAYIO
reset_displays();
@@ -466,6 +474,8 @@ int __attribute__((used)) main(void) {
// Reset everything and prep MicroPython to run boot.py.
reset_port();
+ // Port-independent devices, like CIRCUITPY_BLEIO_HCI.
+ reset_devices();
reset_board();
// Turn on autoreload by default but before boot.py in case it wants to change it.
diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile
index 30487ae3e..489f3a7af 100644
--- a/ports/atmel-samd/Makefile
+++ b/ports/atmel-samd/Makefile
@@ -107,12 +107,12 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAME5X -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_
endif
# option to override default optimization level, set in boards/$(BOARD)/mpconfigboard.mk
-CFLAGS += $(OPTIMIZATION_FLAGS) -DNDEBUG
+CFLAGS += $(OPTIMIZATION_FLAGS)
$(echo PERIPHERALS_CHIP_FAMILY=$(PERIPHERALS_CHIP_FAMILY))
#Debugging/Optimization
ifeq ($(DEBUG), 1)
- CFLAGS += -ggdb
+ CFLAGS += -ggdb3 -Og
# You may want to disable -flto if it interferes with debugging.
CFLAGS += -flto -flto-partition=none
# You may want to enable these flags to make setting breakpoints easier.
@@ -121,6 +121,7 @@ ifeq ($(DEBUG), 1)
CFLAGS += -DENABLE_MICRO_TRACE_BUFFER
endif
else
+ CFLAGS += -DNDEBUG
# -finline-limit can shrink the image size.
# -finline-limit=80 or so is similar to not having it on.
# There is no simple default value, though.
@@ -257,9 +258,11 @@ SRC_ASF += \
$(BUILD)/asf4/$(CHIP_FAMILY)/hpl/sdhc/hpl_sdhc.o: CFLAGS += -Wno-cast-align
endif
+$(BUILD)/asf4/$(CHIP_FAMILY)/hpl/sercom/hpl_sercom.o: CFLAGS += -Wno-maybe-uninitialized
+
SRC_ASF := $(addprefix asf4/$(CHIP_FAMILY)/, $(SRC_ASF))
-SRC_C = \
+SRC_C += \
audio_dma.c \
background.c \
bindings/samd/Clock.c \
diff --git a/ports/atmel-samd/boards/blm_badge/pins.c b/ports/atmel-samd/boards/blm_badge/pins.c
index af1b69358..6e7d8da75 100644
--- a/ports/atmel-samd/boards/blm_badge/pins.c
+++ b/ports/atmel-samd/boards/blm_badge/pins.c
@@ -39,5 +39,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PA03) },
{ MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA03) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/matrixportal_m4/board.c b/ports/atmel-samd/boards/matrixportal_m4/board.c
new file mode 100644
index 000000000..2d4f30239
--- /dev/null
+++ b/ports/atmel-samd/boards/matrixportal_m4/board.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.h b/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.h
new file mode 100644
index 000000000..0368d577b
--- /dev/null
+++ b/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.h
@@ -0,0 +1,30 @@
+#define MICROPY_HW_BOARD_NAME "Adafruit Matrix Portal M4"
+#define MICROPY_HW_MCU_NAME "samd51j19"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+#define MICROPY_HW_LED_STATUS (&pin_PA14)
+
+#define MICROPY_HW_NEOPIXEL (&pin_PA23)
+
+// These are pins not to reset.
+// QSPI Data pins, PA23 is NeoPixel
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 | PA23)
+// QSPI CS, QSPI SCK
+#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PB03)
+#define DEFAULT_I2C_BUS_SDA (&pin_PB02)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA16)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA19)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA17)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA01)
+#define DEFAULT_UART_BUS_TX (&pin_PA00)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.mk b/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.mk
new file mode 100644
index 000000000..44b28acbc
--- /dev/null
+++ b/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.mk
@@ -0,0 +1,12 @@
+USB_VID = 0x239A
+USB_PID = 0x80CA
+USB_PRODUCT = "Matrix Portal M4"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 3
+EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
+LONGINT_IMPL = MPZ
diff --git a/ports/atmel-samd/boards/matrixportal_m4/pins.c b/ports/atmel-samd/boards/matrixportal_m4/pins.c
new file mode 100644
index 000000000..34865597b
--- /dev/null
+++ b/ports/atmel-samd/boards/matrixportal_m4/pins.c
@@ -0,0 +1,61 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA07) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX),MP_ROM_PTR(&pin_PA00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX),MP_ROM_PTR(&pin_PA01) },
+
+ // ESP control
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PB17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PA20) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_PA22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_PA21) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RTS), MP_ROM_PTR(&pin_PA18) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_PA12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_PA13) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB30) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB31) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PA23) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA16) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA19) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA17) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R1),MP_ROM_PTR(&pin_PB00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G1),MP_ROM_PTR(&pin_PB01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B1),MP_ROM_PTR(&pin_PB02) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R2),MP_ROM_PTR(&pin_PB03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G2),MP_ROM_PTR(&pin_PB04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B2),MP_ROM_PTR(&pin_PB05) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRA),MP_ROM_PTR(&pin_PB07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRB),MP_ROM_PTR(&pin_PB08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRC),MP_ROM_PTR(&pin_PB09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRD),MP_ROM_PTR(&pin_PB15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRE),MP_ROM_PTR(&pin_PB13) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_CLK),MP_ROM_PTR(&pin_PB06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_LAT),MP_ROM_PTR(&pin_PB14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_OE),MP_ROM_PTR(&pin_PB12) },
+
+ { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA27) },
+
+ // Grounded when closed.
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_UP),MP_ROM_PTR(&pin_PB22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_DOWN),MP_ROM_PTR(&pin_PB23) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_L),MP_ROM_PTR(&pin_PA14) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
index 4895cda77..e999629c3 100644
--- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
@@ -6,6 +6,10 @@ USB_MANUFACTURER = "Adafruit Industries LLC"
CHIP_VARIANT = SAMD51J19A
CHIP_FAMILY = samd51
+# Support _bleio via the on-board ESP32 module.
+CIRCUITPY_BLEIO = 1
+CIRCUITPY_BLEIO_HCI = 1
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
diff --git a/ports/esp32s2/boards/electroniccats_bastwifi/board.c b/ports/esp32s2/boards/electroniccats_bastwifi/board.c
new file mode 100644
index 000000000..9f708874b
--- /dev/null
+++ b/ports/esp32s2/boards/electroniccats_bastwifi/board.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+#include "shared-bindings/microcontroller/Pin.h"
+
+void board_init(void) {
+ // USB
+ common_hal_never_reset_pin(&pin_GPIO19);
+ common_hal_never_reset_pin(&pin_GPIO20);
+
+ // Debug UART
+ common_hal_never_reset_pin(&pin_GPIO43);
+ common_hal_never_reset_pin(&pin_GPIO44);
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h b/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h
new file mode 100644
index 000000000..ed3f23a3c
--- /dev/null
+++ b/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "BastWiFi"
+#define MICROPY_HW_MCU_NAME "ESP32S2"
+
+#define AUTORESET_DELAY_MS 500
diff --git a/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.mk b/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.mk
new file mode 100644
index 000000000..6a6ae7937
--- /dev/null
+++ b/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.mk
@@ -0,0 +1,19 @@
+USB_VID = 0x1209
+USB_PID = 0xBAB0
+USB_PRODUCT = "Bast WiFi"
+USB_MANUFACTURER = "ElectronicCats"
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = MPZ
+
+# The default queue depth of 16 overflows on release builds,
+# so increase it to 32.
+CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32
+
+CIRCUITPY_NEOPIXEL_WRITE = 0
+
+CIRCUITPY_ESP_FLASH_MODE=dio
+CIRCUITPY_ESP_FLASH_FREQ=40m
+CIRCUITPY_ESP_FLASH_SIZE=4MB
+
+CIRCUITPY_MODULE=wrover
diff --git a/ports/esp32s2/boards/electroniccats_bastwifi/pins.c b/ports/esp32s2/boards/electroniccats_bastwifi/pins.c
new file mode 100644
index 000000000..2f9987b0e
--- /dev/null
+++ b/ports/esp32s2/boards/electroniccats_bastwifi/pins.c
@@ -0,0 +1,64 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) },
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) },
+ { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) },
+ { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) },
+ { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) },
+ { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) },
+ { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) },
+ { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) },
+ { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) },
+ { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) },
+ { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) },
+ { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) },
+ { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) },
+ { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) },
+ { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) },
+ { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) },
+ { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO15) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO16) },
+ { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) },
+
+
+ { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) },
+ { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) },
+ { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) },
+ { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) },
+ { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) },
+ { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) },
+ { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) },
+ { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) },
+ { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) },
+ { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO37) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO35) },
+ { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO11) },
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO14) },
+ { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) },
+ { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) },
+ { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) },
+ { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) },
+ { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) },
+ { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) },
+ { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) },
+ { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) },
+ { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/esp32s2/boards/electroniccats_bastwifi/sdkconfig b/ports/esp32s2/boards/electroniccats_bastwifi/sdkconfig
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ports/esp32s2/boards/electroniccats_bastwifi/sdkconfig
diff --git a/ports/esp32s2/boards/espressif_kaluga_1/board.c b/ports/esp32s2/boards/espressif_kaluga_1/board.c
new file mode 100644
index 000000000..9f708874b
--- /dev/null
+++ b/ports/esp32s2/boards/espressif_kaluga_1/board.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+#include "shared-bindings/microcontroller/Pin.h"
+
+void board_init(void) {
+ // USB
+ common_hal_never_reset_pin(&pin_GPIO19);
+ common_hal_never_reset_pin(&pin_GPIO20);
+
+ // Debug UART
+ common_hal_never_reset_pin(&pin_GPIO43);
+ common_hal_never_reset_pin(&pin_GPIO44);
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h
new file mode 100644
index 000000000..84d15ffc2
--- /dev/null
+++ b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "Kaluga 1"
+#define MICROPY_HW_MCU_NAME "ESP32S2"
+
+#define MICROPY_HW_NEOPIXEL (&pin_GPIO45)
+
+#define AUTORESET_DELAY_MS 500
diff --git a/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk
new file mode 100644
index 000000000..ba85e46ef
--- /dev/null
+++ b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk
@@ -0,0 +1,17 @@
+USB_VID = 0x239A
+USB_PID = 0x80C8
+USB_PRODUCT = "Kaluga 1"
+USB_MANUFACTURER = "Espressif"
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = MPZ
+
+# The default queue depth of 16 overflows on release builds,
+# so increase it to 32.
+CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32
+
+CIRCUITPY_ESP_FLASH_MODE=dio
+CIRCUITPY_ESP_FLASH_FREQ=40m
+CIRCUITPY_ESP_FLASH_SIZE=4MB
+
+CIRCUITPY_MODULE=wrover
diff --git a/ports/esp32s2/boards/espressif_kaluga_1/pins.c b/ports/esp32s2/boards/espressif_kaluga_1/pins.c
new file mode 100644
index 000000000..c1657d6c0
--- /dev/null
+++ b/ports/esp32s2/boards/espressif_kaluga_1/pins.c
@@ -0,0 +1,125 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) },
+ { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) },
+ { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) },
+ { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) },
+ { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) },
+ { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) },
+ { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) },
+ { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) },
+ { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) },
+ { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) },
+ { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) },
+ { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) },
+ { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) },
+ { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) },
+ { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) },
+ { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) },
+
+
+ { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) },
+ { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) },
+ { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) },
+ { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) },
+ { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) },
+ { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) },
+ { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) },
+ { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) },
+ { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) },
+ { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) },
+ { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) },
+ { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) },
+ { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) },
+ { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) },
+ { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) },
+ { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) },
+ { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) },
+ { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) },
+ { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) },
+
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO45) },
+
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_XCLK), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_PCLK), MP_ROM_PTR(&pin_GPIO33) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_HREF), MP_ROM_PTR(&pin_GPIO3) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_VSYNC), MP_ROM_PTR(&pin_GPIO2) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_SIOD), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_SIOC), MP_ROM_PTR(&pin_GPIO7) },
+
+
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_D2), MP_ROM_PTR(&pin_GPIO46) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_D3), MP_ROM_PTR(&pin_GPIO45) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_D4), MP_ROM_PTR(&pin_GPIO41) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_D5), MP_ROM_PTR(&pin_GPIO42) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_D6), MP_ROM_PTR(&pin_GPIO39) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_D7), MP_ROM_PTR(&pin_GPIO40) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_D8), MP_ROM_PTR(&pin_GPIO21) },
+ { MP_ROM_QSTR(MP_QSTR_CAMERA_D9), MP_ROM_PTR(&pin_GPIO38) },
+
+
+ { MP_ROM_QSTR(MP_QSTR_TOUCH1), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH2), MP_ROM_PTR(&pin_GPIO2) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH3), MP_ROM_PTR(&pin_GPIO3) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH4), MP_ROM_PTR(&pin_GPIO4) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH5), MP_ROM_PTR(&pin_GPIO5) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH6), MP_ROM_PTR(&pin_GPIO6) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH7), MP_ROM_PTR(&pin_GPIO7) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH8), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH9), MP_ROM_PTR(&pin_GPIO9) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH10), MP_ROM_PTR(&pin_GPIO10) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH11), MP_ROM_PTR(&pin_GPIO11) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH12), MP_ROM_PTR(&pin_GPIO12) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH13), MP_ROM_PTR(&pin_GPIO13) },
+ { MP_ROM_QSTR(MP_QSTR_TOUCH14), MP_ROM_PTR(&pin_GPIO14) },
+
+ // LED FPC
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO7) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_BT_ARRAY_ADC), MP_ROM_PTR(&pin_GPIO6) },
+
+ // 3.2 inch LCD FPC
+ { MP_ROM_QSTR(MP_QSTR_LCD_TP_MISO), MP_ROM_PTR(&pin_GPIO42) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_TP_MOSI), MP_ROM_PTR(&pin_GPIO40) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_TP_SCK), MP_ROM_PTR(&pin_GPIO38) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_TP_CS), MP_ROM_PTR(&pin_GPIO33) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_TP_IRQ), MP_ROM_PTR(&pin_GPIO2) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_TP_BUSY), MP_ROM_PTR(&pin_GPIO4) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_BL_CTR), MP_ROM_PTR(&pin_GPIO6) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO9) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO11) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_D_C), MP_ROM_PTR(&pin_GPIO13) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO15) },
+ { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO16) },
+
+ // Audio
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SPI_MISO), MP_ROM_PTR(&pin_GPIO42) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SPI_MOSI), MP_ROM_PTR(&pin_GPIO40) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SPI_SCK), MP_ROM_PTR(&pin_GPIO38) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SPI_CS), MP_ROM_PTR(&pin_GPIO33) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_BT_ADC), MP_ROM_PTR(&pin_GPIO6) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SCL), MP_ROM_PTR(&pin_GPIO7) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_SDA), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S0_MCLK), MP_ROM_PTR(&pin_GPIO41) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S0_BCLK), MP_ROM_PTR(&pin_GPIO39) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S0_LRCK), MP_ROM_PTR(&pin_GPIO21) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S0_SDI), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S0_SDO), MP_ROM_PTR(&pin_GPIO3) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_RST), MP_ROM_PTR(&pin_GPIO5) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_WAKE_INT), MP_ROM_PTR(&pin_GPIO34) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S1_MCLK), MP_ROM_PTR(&pin_GPIO35) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_PA_CTRL), MP_ROM_PTR(&pin_GPIO10) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S1_SDI), MP_ROM_PTR(&pin_GPIO46) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S1_SDO), MP_ROM_PTR(&pin_GPIO12) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S1_LRCK_DAC1), MP_ROM_PTR(&pin_GPIO17) },
+ { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S1_BCLK_DAC2), MP_ROM_PTR(&pin_GPIO18) },
+
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/esp32s2/boards/espressif_kaluga_1/sdkconfig b/ports/esp32s2/boards/espressif_kaluga_1/sdkconfig
new file mode 100644
index 000000000..9d8bbde96
--- /dev/null
+++ b/ports/esp32s2/boards/espressif_kaluga_1/sdkconfig
@@ -0,0 +1,33 @@
+CONFIG_ESP32S2_SPIRAM_SUPPORT=y
+
+#
+# SPI RAM config
+#
+# CONFIG_SPIRAM_TYPE_AUTO is not set
+CONFIG_SPIRAM_TYPE_ESPPSRAM16=y
+# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
+# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
+CONFIG_SPIRAM_SIZE=2097152
+
+#
+# PSRAM clock and cs IO for ESP32S2
+#
+CONFIG_DEFAULT_PSRAM_CLK_IO=30
+CONFIG_DEFAULT_PSRAM_CS_IO=26
+# end of PSRAM clock and cs IO for ESP32S2
+
+# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
+# CONFIG_SPIRAM_RODATA is not set
+# CONFIG_SPIRAM_SPEED_80M is not set
+CONFIG_SPIRAM_SPEED_40M=y
+# CONFIG_SPIRAM_SPEED_26M is not set
+# CONFIG_SPIRAM_SPEED_20M is not set
+CONFIG_SPIRAM=y
+CONFIG_SPIRAM_BOOT_INIT=y
+# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
+CONFIG_SPIRAM_USE_MEMMAP=y
+# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
+# CONFIG_SPIRAM_USE_MALLOC is not set
+CONFIG_SPIRAM_MEMTEST=y
+# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
+# end of SPI RAM config
diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c
index e410ac3b4..67c6f3468 100644
--- a/ports/nrf/bluetooth/ble_drv.c
+++ b/ports/nrf/bluetooth/ble_drv.c
@@ -39,6 +39,7 @@
#include "py/mpstate.h"
#include "supervisor/shared/bluetooth.h"
+#include "supervisor/bluetooth.h"
nrf_nvic_state_t nrf_nvic_state = { 0 };
diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c
index 4df26f33a..537f43f23 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.c
+++ b/ports/nrf/common-hal/_bleio/Adapter.c
@@ -354,6 +354,8 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
if (enabled) {
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
bleio_connection_internal_t *connection = &bleio_connections[i];
+ // Reset connection.
+ bleio_connection_clear(connection);
connection->conn_handle = BLE_CONN_HANDLE_INVALID;
}
bleio_adapter_reset_name(self);
@@ -589,6 +591,7 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
bleio_connection_internal_t *connection = &bleio_connections[i];
if (connection->conn_handle == conn_handle) {
+ connection->is_central = true;
return bleio_connection_new_from_internal(connection);
}
}
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c
index d507cecca..57c481448 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.c
+++ b/ports/nrf/common-hal/_bleio/Characteristic.c
@@ -90,7 +90,8 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
self->props = props;
self->read_perm = read_perm;
self->write_perm = write_perm;
- self->descriptor_list = NULL;
+ self->initial_value = mp_obj_new_bytes(initial_value_bufinfo->buf, initial_value_bufinfo->len);
+ self->descriptor_list = mp_obj_new_list(0, NULL);
const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX;
if (max_length < 0 || max_length > max_length_max) {
@@ -105,14 +106,10 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
} else {
common_hal_bleio_service_add_characteristic(self->service, self, initial_value_bufinfo);
}
-
- if (initial_value_bufinfo != NULL) {
- common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo);
- }
}
-bleio_descriptor_obj_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) {
- return self->descriptor_list;
+mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self) {
+ return mp_obj_new_tuple(self->descriptor_list->len, self->descriptor_list->items);
}
bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self) {
@@ -124,7 +121,6 @@ size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *sel
if (self->handle != BLE_GATT_HANDLE_INVALID) {
uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
if (common_hal_bleio_service_get_is_remote(self->service)) {
- // self->value is set by evt handler.
return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len);
} else {
// conn_handle is ignored for non-system attributes.
@@ -205,7 +201,7 @@ void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *
bleio_attribute_gatts_set_security_mode(&desc_attr_md.write_perm, descriptor->write_perm);
mp_buffer_info_t desc_value_bufinfo;
- mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ);
+ mp_get_buffer_raise(descriptor->initial_value, &desc_value_bufinfo, MP_BUFFER_READ);
ble_gatts_attr_t desc_attr = {
.p_uuid = &desc_uuid,
@@ -218,8 +214,8 @@ void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *
check_nrf_error(sd_ble_gatts_descriptor_add(self->handle, &desc_attr, &descriptor->handle));
- descriptor->next = self->descriptor_list;
- self->descriptor_list = descriptor;
+ mp_obj_list_append(MP_OBJ_FROM_PTR(self->descriptor_list),
+ MP_OBJ_FROM_PTR(descriptor));
}
void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) {
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.h b/ports/nrf/common-hal/_bleio/Characteristic.h
index bb8f28495..382fd4a81 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.h
+++ b/ports/nrf/common-hal/_bleio/Characteristic.h
@@ -39,14 +39,14 @@ typedef struct _bleio_characteristic_obj {
// Will be MP_OBJ_NULL before being assigned to a Service.
bleio_service_obj_t *service;
bleio_uuid_obj_t *uuid;
- mp_obj_t value;
+ mp_obj_t initial_value;
uint16_t max_length;
bool fixed_length;
uint16_t handle;
bleio_characteristic_properties_t props;
bleio_attribute_security_mode_t read_perm;
bleio_attribute_security_mode_t write_perm;
- bleio_descriptor_obj_t *descriptor_list;
+ mp_obj_list_t *descriptor_list;
uint16_t user_desc_handle;
uint16_t cccd_handle;
uint16_t sccd_handle;
diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c
index 00c1acd4d..4f747bf97 100644
--- a/ports/nrf/common-hal/_bleio/Connection.c
+++ b/ports/nrf/common-hal/_bleio/Connection.c
@@ -325,10 +325,11 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
}
void bleio_connection_clear(bleio_connection_internal_t *self) {
- self->remote_service_list = NULL;
+ mp_obj_list_clear(MP_OBJ_FROM_PTR(self->remote_service_list));
self->conn_handle = BLE_CONN_HANDLE_INVALID;
self->pair_status = PAIR_NOT_PAIRED;
+ self->is_central = false;
bonding_clear_keys(&self->bonding_keys);
}
@@ -452,8 +453,6 @@ STATIC bool discover_next_descriptors(bleio_connection_internal_t* connection, b
}
STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_connection_internal_t* connection) {
- bleio_service_obj_t* tail = connection->remote_service_list;
-
for (size_t i = 0; i < response->count; ++i) {
ble_gattc_service_t *gattc_service = &response->services[i];
@@ -481,12 +480,10 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res
service->uuid = NULL;
}
- service->next = tail;
- tail = service;
+ mp_obj_list_append(MP_OBJ_FROM_PTR(connection->remote_service_list),
+ MP_OBJ_FROM_PTR(service));
}
- connection->remote_service_list = tail;
-
if (response->count > 0) {
m_discovery_successful = true;
}
@@ -526,9 +523,10 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio
characteristic, m_char_discovery_service, gattc_char->handle_value, uuid,
props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc
- NULL);
+ mp_const_empty_bytes);
- mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
+ mp_obj_list_append(MP_OBJ_FROM_PTR(m_char_discovery_service->characteristic_list),
+ MP_OBJ_FROM_PTR(characteristic));
}
if (response->count > 0) {
@@ -584,7 +582,8 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio
GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes);
descriptor->handle = gattc_desc->handle;
- mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
+ mp_obj_list_append(MP_OBJ_FROM_PTR(m_desc_discovery_characteristic->descriptor_list),
+ MP_OBJ_FROM_PTR(descriptor));
}
if (response->count > 0) {
@@ -625,7 +624,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
ble_drv_add_event_handler(discovery_on_ble_evt, self);
// Start over with an empty list.
- self->remote_service_list = NULL;
+ self->remote_service_list = mp_obj_new_list(0, NULL);
if (service_uuids_whitelist == mp_const_none) {
// List of service UUID's not given, so discover all available services.
@@ -637,7 +636,9 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
// Get the most recently discovered service, and then ask for services
// whose handles start after the last attribute handle inside that service.
- const bleio_service_obj_t *service = self->remote_service_list;
+ // There must be at least one if discover_next_services() returned true.
+ const bleio_service_obj_t *service =
+ self->remote_service_list->items[self->remote_service_list->len - 1];
next_service_start_handle = service->end_handle + 1;
}
} else {
@@ -661,11 +662,10 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
}
- bleio_service_obj_t *service = self->remote_service_list;
- while (service != NULL) {
+ for (size_t i = 0; i < self->remote_service_list->len; i++) {
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(self->remote_service_list->items[i]);
// Skip the service if it had an unknown (unregistered) UUID.
if (service->uuid == NULL) {
- service = service->next;
continue;
}
@@ -677,9 +677,9 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
while (next_char_start_handle <= service->end_handle &&
discover_next_characteristics(self, service, next_char_start_handle)) {
-
// Get the most recently discovered characteristic, and then ask for characteristics
// whose handles start after the last attribute handle inside that characteristic.
+ // There must be at least one if discover_next_characteristics() returned true.
const bleio_characteristic_obj_t *characteristic =
MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]);
@@ -717,24 +717,26 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
next_desc_start_handle, next_desc_end_handle)) {
// Get the most recently discovered descriptor, and then ask for descriptors
// whose handles start after that descriptor's handle.
- const bleio_descriptor_obj_t *descriptor = characteristic->descriptor_list;
+ // There must be at least one if discover_next_descriptors() returned true.
+ const bleio_descriptor_obj_t *descriptor =
+ characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1];
next_desc_start_handle = descriptor->handle + 1;
}
}
- service = service->next;
}
// This event handler is no longer needed.
ble_drv_remove_event_handler(discovery_on_ble_evt, self);
-
}
mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) {
discover_remote_services(self->connection, service_uuids_whitelist);
bleio_connection_ensure_connected(self);
// Convert to a tuple and then clear the list so the callee will take ownership.
- mp_obj_tuple_t *services_tuple = service_linked_list_to_tuple(self->connection->remote_service_list);
- self->connection->remote_service_list = NULL;
+ mp_obj_tuple_t *services_tuple =
+ mp_obj_new_tuple(self->connection->remote_service_list->len,
+ self->connection->remote_service_list->items);
+ mp_obj_list_clear(MP_OBJ_FROM_PTR(self->connection->remote_service_list));
return services_tuple;
}
diff --git a/ports/nrf/common-hal/_bleio/Connection.h b/ports/nrf/common-hal/_bleio/Connection.h
index b051e5c51..180b2727c 100644
--- a/ports/nrf/common-hal/_bleio/Connection.h
+++ b/ports/nrf/common-hal/_bleio/Connection.h
@@ -53,7 +53,7 @@ typedef struct {
uint16_t conn_handle;
bool is_central;
// Remote services discovered when this peripheral is acting as a client.
- bleio_service_obj_t *remote_service_list;
+ mp_obj_list_t *remote_service_list;
// The advertising data and scan response buffers are held by us, not by the SD, so we must
// maintain them and not change it. If we need to change the contents during advertising,
// there are tricks to get the SD to notice (see DevZone - TBS).
@@ -67,7 +67,7 @@ typedef struct {
ble_gap_conn_params_t conn_params;
volatile bool conn_params_updating;
uint16_t mtu;
- // Request that CCCD values for this conenction be saved, using sys_attr values.
+ // Request that CCCD values for this connection be saved, using sys_attr values.
volatile bool do_bond_cccds;
// Request that security key info for this connection be saved.
volatile bool do_bond_keys;
@@ -83,6 +83,7 @@ typedef struct {
uint8_t disconnect_reason;
} bleio_connection_obj_t;
+void bleio_connection_clear(bleio_connection_internal_t *self);
bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in);
uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self);
diff --git a/ports/nrf/common-hal/_bleio/Descriptor.c b/ports/nrf/common-hal/_bleio/Descriptor.c
index faf50c658..9e9110723 100644
--- a/ports/nrf/common-hal/_bleio/Descriptor.c
+++ b/ports/nrf/common-hal/_bleio/Descriptor.c
@@ -39,6 +39,7 @@ void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_c
self->handle = BLE_GATT_HANDLE_INVALID;
self->read_perm = read_perm;
self->write_perm = write_perm;
+ self->initial_value = mp_obj_new_bytes(initial_value_bufinfo->buf, initial_value_bufinfo->len);
const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX;
if (max_length < 0 || max_length > max_length_max) {
@@ -47,8 +48,6 @@ void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_c
}
self->max_length = max_length;
self->fixed_length = fixed_length;
-
- common_hal_bleio_descriptor_set_value(self, initial_value_bufinfo);
}
bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) {
@@ -81,8 +80,6 @@ void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buff
mp_raise_ValueError(translate("Value length > max_length"));
}
- self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
-
// Do GATT operations only if this descriptor has been registered.
if (self->handle != BLE_GATT_HANDLE_INVALID) {
uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection);
diff --git a/ports/nrf/common-hal/_bleio/Descriptor.h b/ports/nrf/common-hal/_bleio/Descriptor.h
index c70547c08..4d6ac2543 100644
--- a/ports/nrf/common-hal/_bleio/Descriptor.h
+++ b/ports/nrf/common-hal/_bleio/Descriptor.h
@@ -41,13 +41,12 @@ typedef struct _bleio_descriptor_obj {
// Will be MP_OBJ_NULL before being assigned to a Characteristic.
struct _bleio_characteristic_obj *characteristic;
bleio_uuid_obj_t *uuid;
- mp_obj_t value;
+ mp_obj_t initial_value;
uint16_t max_length;
bool fixed_length;
uint16_t handle;
bleio_attribute_security_mode_t read_perm;
bleio_attribute_security_mode_t write_perm;
- struct _bleio_descriptor_obj* next;
} bleio_descriptor_obj_t;
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H
diff --git a/ports/nrf/common-hal/_bleio/Service.c b/ports/nrf/common-hal/_bleio/Service.c
index 19288f747..3159d3392 100644
--- a/ports/nrf/common-hal/_bleio/Service.c
+++ b/ports/nrf/common-hal/_bleio/Service.c
@@ -73,8 +73,8 @@ bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) {
return self->uuid;
}
-mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self) {
- return self->characteristic_list;
+mp_obj_tuple_t *common_hal_bleio_service_get_characteristics(bleio_service_obj_t *self) {
+ return mp_obj_new_tuple(self->characteristic_list->len, self->characteristic_list->items);
}
bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) {
@@ -124,11 +124,14 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
char_attr_md.rd_auth = true;
#endif
+ mp_buffer_info_t char_value_bufinfo;
+ mp_get_buffer_raise(characteristic->initial_value, &char_value_bufinfo, MP_BUFFER_READ);
+
ble_gatts_attr_t char_attr = {
.p_uuid = &char_uuid,
.p_attr_md = &char_attr_md,
- .init_len = 0,
- .p_value = NULL,
+ .init_len = char_value_bufinfo.len,
+ .p_value = char_value_bufinfo.buf,
.init_offs = 0,
.max_len = characteristic->max_length,
};
diff --git a/ports/nrf/common-hal/_bleio/Service.h b/ports/nrf/common-hal/_bleio/Service.h
index 6ee9fe63d..00f611dd9 100644
--- a/ports/nrf/common-hal/_bleio/Service.h
+++ b/ports/nrf/common-hal/_bleio/Service.h
@@ -46,7 +46,6 @@ typedef struct bleio_service_obj {
// Range of attribute handles of this remote service.
uint16_t start_handle;
uint16_t end_handle;
- struct bleio_service_obj* next;
} bleio_service_obj_t;
void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection);
diff --git a/ports/nrf/common-hal/_bleio/UUID.c b/ports/nrf/common-hal/_bleio/UUID.c
index 6a3d64305..0c79e980e 100644
--- a/ports/nrf/common-hal/_bleio/UUID.c
+++ b/ports/nrf/common-hal/_bleio/UUID.c
@@ -40,7 +40,7 @@
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
// the 16-bit part goes. Those 16 bits are passed in uuid16.
-void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[]) {
+void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]) {
self->nrf_ble_uuid.uuid = uuid16;
if (uuid128 == NULL) {
self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c
index 23d7397c7..496c9429f 100644
--- a/ports/nrf/common-hal/_bleio/__init__.c
+++ b/ports/nrf/common-hal/_bleio/__init__.c
@@ -39,6 +39,7 @@
#include "supervisor/shared/bluetooth.h"
#include "common-hal/_bleio/__init__.h"
+#include "common-hal/_bleio/bonding.h"
void check_nrf_error(uint32_t err_code) {
if (err_code == NRF_SUCCESS) {
@@ -243,6 +244,10 @@ void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buff
}
+void bleio_background(void) {
+ bonding_background();
+}
+
void common_hal_bleio_gc_collect(void) {
bleio_adapter_gc_collect(&common_hal_bleio_adapter_obj);
}
diff --git a/ports/nrf/common-hal/_bleio/__init__.h b/ports/nrf/common-hal/_bleio/__init__.h
index 6881c90e6..97f82ece3 100644
--- a/ports/nrf/common-hal/_bleio/__init__.h
+++ b/ports/nrf/common-hal/_bleio/__init__.h
@@ -27,6 +27,7 @@
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
+void bleio_background(void);
void bleio_reset(void);
typedef struct {
diff --git a/ports/nrf/supervisor/bluetooth.c b/ports/nrf/supervisor/bluetooth.c
new file mode 100644
index 000000000..8d89d6272
--- /dev/null
+++ b/ports/nrf/supervisor/bluetooth.c
@@ -0,0 +1,81 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "supervisor/shared/bluetooth.h"
+#include "supervisor/bluetooth.h"
+
+// This happens in an interrupt so we need to be quick.
+bool supervisor_bluetooth_hook(ble_evt_t *ble_evt) {
+#if CIRCUITPY_BLE_FILE_SERVICE
+ // Catch writes to filename or contents. Length is read-only.
+
+ bool done = false;
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_CONNECTED:
+ // We run our background task even if it wasn't us connected to because we may want to
+ // advertise if the user code stopped advertising.
+ run_ble_background = true;
+ break;
+ case BLE_GAP_EVT_DISCONNECTED:
+ run_ble_background = true;
+ break;
+ case BLE_GATTS_EVT_WRITE: {
+ // A client wrote to a characteristic.
+
+ ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
+ // Event handle must match the handle for my characteristic.
+ if (evt_write->handle == supervisor_ble_contents_characteristic.handle) {
+ // Handle events
+ //write_to_ringbuf(self, evt_write->data, evt_write->len);
+ // First packet includes a uint16_t le for length at the start.
+ uint16_t current_length = ((uint16_t*) current_command)[0];
+ memcpy(((uint8_t*) current_command) + current_offset, evt_write->data, evt_write->len);
+ current_offset += evt_write->len;
+ current_length = ((uint16_t*) current_command)[0];
+ if (current_offset == current_length) {
+ run_ble_background = true;
+ done = true;
+ }
+ } else if (evt_write->handle == supervisor_ble_filename_characteristic.handle) {
+ new_filename = true;
+ run_ble_background = true;
+ done = true;
+ } else {
+ return done;
+ }
+ break;
+ }
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
+ }
+ return done;
+#else
+ return false;
+#endif
+}
diff --git a/ports/nrf/supervisor/bluetooth.h b/ports/nrf/supervisor/bluetooth.h
new file mode 100644
index 000000000..425de07e4
--- /dev/null
+++ b/ports/nrf/supervisor/bluetooth.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_NRF_SUPERVISOR_BLUETOOTH_H
+#define MICROPY_INCLUDED_NRF_SUPERVISOR_BLUETOOTH_H
+
+#include <stdbool.h>
+
+#include "ble.h"
+
+bool supervisor_bluetooth_hook(ble_evt_t *ble_evt);
+
+#endif // MICROPY_INCLUDED_NRF_SUPERVISOR_BLUETOOTH_H
diff --git a/ports/stm/boards/meowbit_v121/board.c b/ports/stm/boards/meowbit_v121/board.c
index 812a8c208..b74f13516 100644
--- a/ports/stm/boards/meowbit_v121/board.c
+++ b/ports/stm/boards/meowbit_v121/board.c
@@ -106,7 +106,7 @@ void board_init(void) {
&pin_PB03,
NO_BRIGHTNESS_COMMAND,
1.0f, // brightness (ignored)
- true, // auto_brightness
+ false, // auto_brightness
false, // single_byte_bounds
false, // data_as_commands
true, // auto_refresh
diff --git a/ports/stm/boards/meowbit_v121/mpconfigboard.h b/ports/stm/boards/meowbit_v121/mpconfigboard.h
index 106f25b15..be9f2a75f 100644
--- a/ports/stm/boards/meowbit_v121/mpconfigboard.h
+++ b/ports/stm/boards/meowbit_v121/mpconfigboard.h
@@ -36,8 +36,7 @@
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000)
#define HSE_VALUE ((uint32_t)12000000U)
-#define LSE_VALUE ((uint32_t)32000U)
-#define BOARD_HAS_LOW_SPEED_CRYSTAL (1)
+#define BOARD_HAS_LOW_SPEED_CRYSTAL (0)
#define BOARD_NO_VBUS_SENSE (1)
#define BOARD_VTOR_DEFER (1) //Leave VTOR relocation to bootloader
diff --git a/ports/stm/boards/meowbit_v121/mpconfigboard.mk b/ports/stm/boards/meowbit_v121/mpconfigboard.mk
index a63818301..16ffb2022 100644
--- a/ports/stm/boards/meowbit_v121/mpconfigboard.mk
+++ b/ports/stm/boards/meowbit_v121/mpconfigboard.mk
@@ -18,5 +18,5 @@ OPTIMIZATION_FLAGS = -Os
LD_COMMON = boards/common_default.ld
LD_FILE = boards/STM32F401xe_boot.ld
-# use for internal flash
+# For debugging - also comment BOOTLOADER_OFFSET and BOARD_VTOR_DEFER
# LD_FILE = boards/STM32F401xe_fs.ld
diff --git a/ports/stm/common-hal/pwmio/PWMOut.c b/ports/stm/common-hal/pwmio/PWMOut.c
index 5427a39c7..85427185e 100644
--- a/ports/stm/common-hal/pwmio/PWMOut.c
+++ b/ports/stm/common-hal/pwmio/PWMOut.c
@@ -239,13 +239,14 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t* self) {
HAL_TIM_PWM_Stop(&self->handle, self->channel);
}
reset_pin_number(self->tim->pin->port,self->tim->pin->number);
- self->tim = NULL;
//if reserved timer has no active channels, we can disable it
if (!reserved_tim[self->tim->tim_index - 1]) {
tim_frequencies[self->tim->tim_index - 1] = 0x00;
stm_peripherals_timer_free(self->handle.Instance);
}
+
+ self->tim = NULL;
}
void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t* self, uint16_t duty) {
diff --git a/ports/stm/mpconfigport.mk b/ports/stm/mpconfigport.mk
index 19f9ffa44..b827aa48b 100644
--- a/ports/stm/mpconfigport.mk
+++ b/ports/stm/mpconfigport.mk
@@ -7,6 +7,7 @@ ifeq ($(MCU_VARIANT),STM32F405xx)
CIRCUITPY_FRAMEBUFFERIO ?= 1
CIRCUITPY_RGBMATRIX ?= 1
CIRCUITPY_SDIOIO ?= 1
+ USB_NUM_EP = 4
endif
ifeq ($(MCU_SERIES),F4)
diff --git a/ports/stm/peripherals/stm32f4/clocks.c b/ports/stm/peripherals/stm32f4/clocks.c
index 7a16812b3..c2d0a452a 100644
--- a/ports/stm/peripherals/stm32f4/clocks.c
+++ b/ports/stm/peripherals/stm32f4/clocks.c
@@ -49,7 +49,6 @@ void stm32_peripherals_clocks_init(void) {
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
- bool lse_failure = false;
// Set voltage scaling in accordance with system clock speed
__HAL_RCC_PWR_CLK_ENABLE();
@@ -76,15 +75,9 @@ void stm32_peripherals_clocks_init(void) {
#endif
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
- // Failure likely means a LSE issue - attempt to swap to LSI, and set to crash
- RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
- RCC_OscInitStruct.OscillatorType |= RCC_OSCILLATORTYPE_LSI;
- RCC_OscInitStruct.LSIState = RCC_LSI_ON;
- if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
- // No HSE means no USB, so just fail forever
- while(1);
- }
- lse_failure = true;
+ // Clock issues are too problematic to even attempt recovery.
+ // If you end up here, check whether your LSE settings match your board.
+ while(1);
}
// Configure bus clock sources and divisors
@@ -113,8 +106,4 @@ void stm32_peripherals_clocks_init(void) {
#endif
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
-
- if (lse_failure) {
- reset_into_safe_mode(HARD_CRASH); //TODO: make safe mode category CLOCK_FAULT?
- }
}
diff --git a/ports/stm/peripherals/stm32f7/clocks.c b/ports/stm/peripherals/stm32f7/clocks.c
index 93016f682..f13088782 100644
--- a/ports/stm/peripherals/stm32f7/clocks.c
+++ b/ports/stm/peripherals/stm32f7/clocks.c
@@ -40,7 +40,6 @@ void stm32_peripherals_clocks_init(void) {
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
- bool lse_failure = false;
// Configure LSE Drive
HAL_PWR_EnableBkUpAccess();
@@ -68,15 +67,9 @@ void stm32_peripherals_clocks_init(void) {
RCC_OscInitStruct.PLL.PLLQ = CPY_CLK_PLLQ;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
- // Failure likely means a LSE issue - attempt to swap to LSI, and set to crash
- RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
- RCC_OscInitStruct.OscillatorType |= RCC_OSCILLATORTYPE_LSI;
- RCC_OscInitStruct.LSIState = RCC_LSI_ON;
- if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
- // No HSE means no USB, so just fail forever
- while(1);
- }
- lse_failure = true;
+ // Clock issues are too problematic to even attempt recovery.
+ // If you end up here, check whether your LSE settings match your board.
+ while(1);
}
/* Activate the OverDrive to reach the 216 MHz Frequency */
@@ -111,8 +104,4 @@ void stm32_peripherals_clocks_init(void) {
#endif
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
-
- if (lse_failure) {
- reset_into_safe_mode(HARD_CRASH); //TODO: make safe mode category CLOCK_FAULT?
- }
}
diff --git a/ports/stm/peripherals/stm32h7/clocks.c b/ports/stm/peripherals/stm32h7/clocks.c
index 0e4e79f9f..a088f78bf 100644
--- a/ports/stm/peripherals/stm32h7/clocks.c
+++ b/ports/stm/peripherals/stm32h7/clocks.c
@@ -37,7 +37,6 @@ void stm32_peripherals_clocks_init(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
- bool lse_failure = false;
// Set voltage scaling in accordance with system clock speed
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
@@ -73,15 +72,9 @@ void stm32_peripherals_clocks_init(void) {
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
- // Failure likely means a LSE issue - attempt to swap to LSI, and set to crash
- RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
- RCC_OscInitStruct.OscillatorType |= RCC_OSCILLATORTYPE_LSI;
- RCC_OscInitStruct.LSIState = RCC_LSI_ON;
- if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
- // No HSE means no USB, so just fail forever
- while(1);
- }
- lse_failure = true;
+ // Clock issues are too problematic to even attempt recovery.
+ // If you end up here, check whether your LSE settings match your board.
+ while(1);
}
// Configure bus clock sources and divisors
@@ -116,8 +109,4 @@ void stm32_peripherals_clocks_init(void) {
// Enable USB Voltage detector
HAL_PWREx_EnableUSBVoltageDetector();
-
- if (lse_failure) {
- reset_into_safe_mode(HARD_CRASH); //TODO: make safe mode category CLOCK_FAULT?
- }
}
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 597819f55..47ffab519 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -488,7 +488,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
// afterwards.
gc_collect();
}
- if (outer_module_obj != MP_OBJ_NULL) {
+ if (outer_module_obj != MP_OBJ_NULL && VERIFY_PTR(outer_module_obj) ) {
qstr s = qstr_from_strn(mod_str + last, i - last);
mp_store_attr(outer_module_obj, s, module_obj);
// The above store can cause a dictionary rehash and new allocation. So,
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index 07fad3272..04e38d81e 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -359,6 +359,15 @@ SRC_COMMON_HAL_ALL = \
wifi/ScannedNetworks.c \
wifi/__init__.c \
+ifeq ($(CIRCUITPY_BLEIO_HCI),1)
+# Helper code for _bleio HCI.
+SRC_C += \
+ common-hal/_bleio/att.c \
+ common-hal/_bleio/hci.c \
+
+endif
+
+
SRC_COMMON_HAL = $(filter $(SRC_PATTERNS), $(SRC_COMMON_HAL_ALL))
# These don't have corresponding files in each port but are still located in
@@ -462,7 +471,7 @@ SRC_SHARED_MODULE_ALL = \
SRC_SHARED_MODULE = $(filter $(SRC_PATTERNS), $(SRC_SHARED_MODULE_ALL))
# Use the native touchio if requested. This flag is set conditionally in, say, mpconfigport.h.
-# The presence of common-hal/touchio/* # does not imply it's available for all chips in a port,
+# The presence of common-hal/touchio/* does not imply it's available for all chips in a port,
# so there is an explicit flag. For example, SAMD21 touchio is native, but SAMD51 is not.
ifeq ($(CIRCUITPY_TOUCHIO_USE_NATIVE),1)
SRC_COMMON_HAL_ALL += \
@@ -473,6 +482,14 @@ SRC_SHARED_MODULE_ALL += \
touchio/TouchIn.c \
touchio/__init__.c
endif
+
+# If supporting _bleio via HCI, make devices/ble_hci/common-hal/_bleio be includable,
+# and use C source files in devices/ble_hci/common-hal.
+ifeq ($(CIRCUITPY_BLEIO_HCI),1)
+INC += -I$(TOP)/devices/ble_hci
+DEVICES_MODULES += $(TOP)/devices/ble_hci
+endif
+
ifeq ($(CIRCUITPY_AUDIOMP3),1)
SRC_MOD += $(addprefix lib/mp3/src/, \
bitstream.c \
@@ -506,6 +523,11 @@ $(filter $(SRC_PATTERNS), \
displayio/display_core.c \
)
+SRC_COMMON_HAL_INTERNAL = \
+$(filter $(SRC_PATTERNS), \
+ _bleio/ \
+)
+
ifeq ($(INTERNAL_LIBM),1)
SRC_LIBM = \
$(addprefix lib/,\
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index ca2f60508..a2da9c42f 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -80,6 +80,10 @@ CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO)
CIRCUITPY_BLEIO ?= 0
CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO)
+# _bleio can be supported on most any board via HCI
+CIRCUITPY_BLEIO_HCI ?= 0
+CFLAGS += -DCIRCUITPY_BLEIO_HCI=$(CIRCUITPY_BLEIO_HCI)
+
CIRCUITPY_BOARD ?= 1
CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD)
diff --git a/py/misc.h b/py/misc.h
index 944c0a716..6ed256e70 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -120,6 +120,8 @@ size_t m_get_peak_bytes_allocated(void);
// align ptr to the nearest multiple of "alignment"
#define MP_ALIGN(ptr, alignment) (void*)(((uintptr_t)(ptr) + ((alignment) - 1)) & ~((alignment) - 1))
+#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))
+
/** unichar / UTF-8 *********************************************/
#if MICROPY_PY_BUILTINS_STR_UNICODE
diff --git a/py/mkrules.mk b/py/mkrules.mk
index 13a73b90e..0b3ecc0e1 100644
--- a/py/mkrules.mk
+++ b/py/mkrules.mk
@@ -42,7 +42,7 @@ $(Q)$(CC) $(CFLAGS) -c -MD -o $@ $<
$(RM) -f $(@:.o=.d)
endef
-vpath %.c . $(TOP) $(USER_C_MODULES)
+vpath %.c . $(TOP) $(USER_C_MODULES) $(DEVICES_MODULES)
$(BUILD)/%.o: %.c
$(call compile_c)
@@ -56,8 +56,7 @@ $(BUILD)/%.o: %.c
QSTR_GEN_EXTRA_CFLAGS += -I$(BUILD)/tmp
-vpath %.c . $(TOP) $(USER_C_MODULES)
-
+vpath %.c . $(TOP) $(USER_C_MODULES) $(DEVICES_MODULES)
$(BUILD)/%.pp: %.c
$(STEPECHO) "PreProcess $<"
$(Q)$(CC) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $<
diff --git a/py/obj.h b/py/obj.h
index c5ef74ef3..805b26e48 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -303,7 +303,7 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t;
(mp_obj_t)&mp_const_none_obj, \
(mp_obj_t)&mp_const_none_obj}, }
-// These macros are used to define constant map/dict objects
+// These macros are used to define constant or mutable map/dict objects
// You can put "static" in front of the definition to make it local
#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;
}, \
}
+#define MP_DEFINE_MUTABLE_MAP(map_name, table_name) \
+ mp_map_t map_name = { \
+ .all_keys_are_qstrs = 1, \
+ .is_fixed = 1, \
+ .is_ordered = 1, \
+ .used = MP_ARRAY_SIZE(table_name), \
+ .alloc = MP_ARRAY_SIZE(table_name), \
+ .table = table_name, \
+ }
+
+#define MP_DEFINE_MUTABLE_DICT(dict_name, table_name) \
+ mp_obj_dict_t dict_name = { \
+ .base = {&mp_type_dict}, \
+ .map = { \
+ .all_keys_are_qstrs = 1, \
+ .is_fixed = 1, \
+ .is_ordered = 1, \
+ .used = MP_ARRAY_SIZE(table_name), \
+ .alloc = MP_ARRAY_SIZE(table_name), \
+ .table = table_name, \
+ }, \
+ }
+
// These macros are used to declare and define constant staticmethond and classmethod objects
// You can put "static" in front of the definitions to make them local
diff --git a/py/py.mk b/py/py.mk
index c5073d0f0..49fb0acaf 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -19,7 +19,7 @@ endif
QSTR_GLOBAL_DEPENDENCIES += $(PY_SRC)/mpconfig.h mpconfigport.h
# some code is performance bottleneck and compiled with other optimization options
-CSUPEROPT = -O3
+_CSUPEROPT = -O3
# this sets the config file for FatFs
CFLAGS_MOD += -DFFCONF_H=\"lib/oofatfs/ffconf.h\"
diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c
index 3ffe65be3..682177093 100644
--- a/shared-bindings/_bleio/Adapter.c
+++ b/shared-bindings/_bleio/Adapter.c
@@ -48,29 +48,76 @@
#define WINDOW_DEFAULT (0.1f)
//| class Adapter:
-//| """BLE adapter
-//|
-//| The Adapter manages the discovery and connection to other nearby Bluetooth Low Energy devices.
+//| """
+//| The BLE Adapter object manages the discovery and connection to other nearby Bluetooth Low Energy devices.
//| This part of the Bluetooth Low Energy Specification is known as Generic Access Profile (GAP).
//|
//| Discovery of other devices happens during a scanning process that listens for small packets of
//| information, known as advertisements, that are broadcast unencrypted. The advertising packets
//| have two different uses. The first is to broadcast a small piece of data to anyone who cares and
-//| and nothing more. These are known as Beacons. The second class of advertisement is to promote
+//| and nothing more. These are known as beacons. The second class of advertisement is to promote
//| additional functionality available after the devices establish a connection. For example, a
-//| BLE keyboard may advertise that it can provide key information, but not what the key info is.
+//| BLE heart rate monitor would advertise that it provides the standard BLE Heart Rate Service.
//|
-//| The built-in BLE adapter can do both parts of this process: it can scan for other device
+//| The Adapter can do both parts of this process: it can scan for other device
//| advertisements and it can advertise its own data. Furthermore, Adapters can accept incoming
//| connections and also initiate connections."""
//|
-//| def __init__(self) -> None:
-//| """You cannot create an instance of `_bleio.Adapter`.
-//| Use `_bleio.adapter` to access the sole instance available."""
+//| def __init__(self, *, uart: busio.UART, rts: digitalio.DigitalInOut, cts: digitalio.DigitalInOut) -> None:
+//| """On boards that do not have native BLE, you can use an HCI co-processor.
+//| Pass the uart and pins used to communicate with the co-processor, such as an Adafruit AirLift.
+//| The co-processor must have been reset and put into BLE mode beforehand
+//| by the appropriate pin manipulation.
+//| The ``uart``, ``rts``, and ``cts`` objects are used to
+//| communicate with the HCI co-processor in HCI mode.
+//| The `Adapter` object is enabled during this call.
+//|
+//| After instantiating an Adapter, call `_bleio.set_adapter()` to set `_bleio.adapter`
+//|
+//| On boards with native BLE, you cannot create an instance of `_bleio.Adapter`;
+//| this constructor will raise `NotImplementedError`.
+//| Use `_bleio.adapter` to access the sole instance already available.
+//| """
//| ...
//|
+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) {
+#if CIRCUITPY_BLEIO_HCI
+ bleio_adapter_obj_t *self = common_hal_bleio_allocate_adapter_or_raise();
+ enum { ARG_uart, ARG_rts, ARG_cts };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_uart, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ busio_uart_obj_t *uart = args[ARG_uart].u_obj;
+ if (!MP_OBJ_IS_TYPE(uart, &busio_uart_type)) {
+ mp_raise_ValueError(translate("Expected a UART"));
+ }
+
+ digitalio_digitalinout_obj_t *rts = args[ARG_rts].u_obj;
+ digitalio_digitalinout_obj_t *cts = args[ARG_cts].u_obj;
+ if (!MP_OBJ_IS_TYPE(rts, &digitalio_digitalinout_type) ||
+ !MP_OBJ_IS_TYPE(cts, &digitalio_digitalinout_type)) {
+ mp_raise_ValueError(translate("Expected a DigitalInOut"));
+ }
+
+ // Will enable the adapter.
+ common_hal_bleio_adapter_construct_hci_uart(self, uart, rts, cts);
+
+ return MP_OBJ_FROM_PTR(self);
+#else
+ mp_raise_NotImplementedError(translate("Cannot create a new Adapter; use _bleio.adapter;"));
+ return mp_const_none;
+#endif // CIRCUITPY_BLEIO_HCI
+}
+
+//|
//| enabled: bool
//| """State of the BLE adapter."""
//|
@@ -362,7 +409,7 @@ const mp_obj_property_t bleio_adapter_connections_obj = {
//| """Attempts a connection to the device with the given address.
//|
//| :param Address address: The address of the peripheral to connect to
-//| :param float timeout: Try to connect for timeout seconds."""
+//| :param float/int timeout: Try to connect for timeout seconds."""
//| ...
//|
STATIC mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -426,5 +473,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_adapter_locals_dict, bleio_adapter_locals_dict
const mp_obj_type_t bleio_adapter_type = {
.base = { &mp_type_type },
.name = MP_QSTR_Adapter,
+ .make_new = bleio_adapter_make_new,
.locals_dict = (mp_obj_t)&bleio_adapter_locals_dict,
};
diff --git a/shared-bindings/_bleio/Adapter.h b/shared-bindings/_bleio/Adapter.h
index c56dbb01c..ac7e216d8 100644
--- a/shared-bindings/_bleio/Adapter.h
+++ b/shared-bindings/_bleio/Adapter.h
@@ -37,6 +37,10 @@
extern const mp_obj_type_t bleio_adapter_type;
+#if CIRCUITPY_BLEIO_HCI
+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);
+#endif // CIRCUITPY_BLEIO_HCI
+
extern bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self);
extern bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self);
extern void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled);
diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c
index dbbacb7d5..5e384a44c 100644
--- a/shared-bindings/_bleio/Characteristic.c
+++ b/shared-bindings/_bleio/Characteristic.c
@@ -109,11 +109,14 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int;
common_hal_bleio_attribute_security_mode_check_valid(write_perm);
- const mp_int_t max_length = args[ARG_max_length].u_int;
+ const mp_int_t max_length_int = args[ARG_max_length].u_int;
+ if (max_length_int <= 0) {
+ mp_raise_ValueError(translate("max_length must be > 0"));
+ }
+ const size_t max_length = (size_t) max_length_int;
const bool fixed_length = args[ARG_fixed_length].u_bool;
mp_obj_t initial_value = args[ARG_initial_value].u_obj;
- // Length will be validated in common_hal.
mp_buffer_info_t initial_value_bufinfo;
if (initial_value == mp_const_none) {
if (fixed_length && max_length > 0) {
@@ -122,7 +125,12 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
initial_value = mp_const_empty_bytes;
}
}
+
mp_get_buffer_raise(initial_value, &initial_value_bufinfo, MP_BUFFER_READ);
+ if (initial_value_bufinfo.len > max_length ||
+ (fixed_length && initial_value_bufinfo.len != max_length)) {
+ mp_raise_ValueError(translate("initial_value length is wrong"));
+ }
bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
characteristic->base.type = &bleio_characteristic_type;
@@ -212,26 +220,14 @@ const mp_obj_property_t bleio_characteristic_value_obj = {
};
//| descriptors: Descriptor
-//| """A tuple of :py:class:`Descriptor` that describe this characteristic. (read-only)"""
+//| """A tuple of :py:class:`Descriptor` objects related to this characteristic. (read-only)"""
//|
STATIC mp_obj_t bleio_characteristic_get_descriptors(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
// Return list as a tuple so user won't be able to change it.
- bleio_descriptor_obj_t *descriptors = common_hal_bleio_characteristic_get_descriptor_list(self);
- bleio_descriptor_obj_t *head = descriptors;
- size_t len = 0;
- while (head != NULL) {
- len++;
- head = head->next;
- }
- mp_obj_tuple_t * t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
- head = descriptors;
- for (size_t i = len - 1; i >= 0; i--) {
- t->items[i] = MP_OBJ_FROM_PTR(head);
- head = head->next;
- }
- return MP_OBJ_FROM_PTR(t);
+ return MP_OBJ_FROM_PTR(common_hal_bleio_characteristic_get_descriptors(self));
}
+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_descriptors_obj, bleio_characteristic_get_descriptors);
const mp_obj_property_t bleio_characteristic_descriptors_obj = {
diff --git a/shared-bindings/_bleio/Characteristic.h b/shared-bindings/_bleio/Characteristic.h
index c4356fd4b..e28d61e1f 100644
--- a/shared-bindings/_bleio/Characteristic.h
+++ b/shared-bindings/_bleio/Characteristic.h
@@ -36,14 +36,14 @@
extern const mp_obj_type_t bleio_characteristic_type;
-extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo);
-extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len);
-extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self);
-extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
-extern bleio_descriptor_obj_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self);
+extern mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self);
extern bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self);
+extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
+extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len);
extern void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor);
+extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo);
extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate);
+extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
diff --git a/shared-bindings/_bleio/Connection.c b/shared-bindings/_bleio/Connection.c
index 5d1b63bdd..b5eeaa906 100644
--- a/shared-bindings/_bleio/Connection.c
+++ b/shared-bindings/_bleio/Connection.c
@@ -31,7 +31,6 @@
#include <string.h>
#include <stdio.h>
-#include "ble_drv.h"
#include "py/objarray.h"
#include "py/objproperty.h"
#include "py/objstr.h"
diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c
index 97422f163..c313007c6 100644
--- a/shared-bindings/_bleio/Descriptor.c
+++ b/shared-bindings/_bleio/Descriptor.c
@@ -100,11 +100,14 @@ STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o
const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int;
common_hal_bleio_attribute_security_mode_check_valid(write_perm);
- const mp_int_t max_length = args[ARG_max_length].u_int;
+ const mp_int_t max_length_int = args[ARG_max_length].u_int;
+ if (max_length_int <= 0) {
+ mp_raise_ValueError(translate("max_length must be > 0"));
+ }
+ const size_t max_length = (size_t) max_length_int;
const bool fixed_length = args[ARG_fixed_length].u_bool;
mp_obj_t initial_value = args[ARG_initial_value].u_obj;
- // Length will be validated in common_hal.
mp_buffer_info_t initial_value_bufinfo;
if (initial_value == mp_const_none) {
if (fixed_length && max_length > 0) {
@@ -114,6 +117,10 @@ STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o
}
}
mp_get_buffer_raise(initial_value, &initial_value_bufinfo, MP_BUFFER_READ);
+ if (initial_value_bufinfo.len > max_length ||
+ (fixed_length && initial_value_bufinfo.len != max_length)) {
+ mp_raise_ValueError(translate("initial_value length is wrong"));
+ }
bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
descriptor->base.type = &bleio_descriptor_type;
diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c
index f410b1798..2ddf1a712 100644
--- a/shared-bindings/_bleio/Service.c
+++ b/shared-bindings/_bleio/Service.c
@@ -79,9 +79,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
//|
STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
- // Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *char_list = common_hal_bleio_service_get_characteristic_list(self);
- return mp_obj_new_tuple(char_list->len, char_list->items);
+ return MP_OBJ_FROM_PTR(common_hal_bleio_service_get_characteristics(self));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics);
@@ -151,7 +149,7 @@ STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) },
{ MP_ROM_QSTR(MP_QSTR_secondary), MP_ROM_PTR(&bleio_service_secondary_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) },
- { MP_ROM_QSTR(MP_QSTR_remote), MP_ROM_PTR(&bleio_service_remote_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remote), MP_ROM_PTR(&bleio_service_remote_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table);
@@ -173,21 +171,3 @@ const mp_obj_type_t bleio_service_type = {
.print = bleio_service_print,
.locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict
};
-
-// Helper for classes that store lists of services.
-mp_obj_tuple_t* service_linked_list_to_tuple(bleio_service_obj_t * services) {
- // Return list as a tuple so user won't be able to change it.
- bleio_service_obj_t *head = services;
- size_t len = 0;
- while (head != NULL) {
- len++;
- head = head->next;
- }
- mp_obj_tuple_t * t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
- head = services;
- for (int32_t i = len - 1; i >= 0; i--) {
- t->items[i] = MP_OBJ_FROM_PTR(head);
- head = head->next;
- }
- return t;
-}
diff --git a/shared-bindings/_bleio/Service.h b/shared-bindings/_bleio/Service.h
index 3af427f95..44d11f60d 100644
--- a/shared-bindings/_bleio/Service.h
+++ b/shared-bindings/_bleio/Service.h
@@ -41,11 +41,9 @@ extern uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, b
extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary);
extern void common_hal_bleio_service_from_remote_service(bleio_service_obj_t *self, bleio_connection_obj_t* connection, bleio_uuid_obj_t *uuid, bool is_secondary);
extern bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self);
-extern mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self);
+extern mp_obj_tuple_t *common_hal_bleio_service_get_characteristics(bleio_service_obj_t *self);
extern bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self);
extern bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self);
extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *initial_value_bufinfo);
-mp_obj_tuple_t* service_linked_list_to_tuple(bleio_service_obj_t * services);
-
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c
index 18eda0b33..fe045f385 100644
--- a/shared-bindings/_bleio/UUID.c
+++ b/shared-bindings/_bleio/UUID.c
@@ -283,7 +283,7 @@ void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
mp_printf(print, "UUID(0x%04x)", common_hal_bleio_uuid_get_uuid16(self));
} else {
uint8_t uuid128[16];
- (void) common_hal_bleio_uuid_get_uuid128(self, uuid128);
+ common_hal_bleio_uuid_get_uuid128(self, uuid128);
mp_printf(print, "UUID('"
"%02x%02x%02x%02x-"
"%02x%02x-"
diff --git a/shared-bindings/_bleio/UUID.h b/shared-bindings/_bleio/UUID.h
index 1490737a7..b10cce67f 100644
--- a/shared-bindings/_bleio/UUID.h
+++ b/shared-bindings/_bleio/UUID.h
@@ -34,9 +34,9 @@ void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
extern const mp_obj_type_t bleio_uuid_type;
-extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[]);
+extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]);
extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self);
-extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
+extern void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self);
void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf);
diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c
index ee9c4bf4a..3d9084dd5 100644
--- a/shared-bindings/_bleio/__init__.c
+++ b/shared-bindings/_bleio/__init__.c
@@ -108,43 +108,95 @@ NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* fmt, ...)
// Called when _bleio is imported.
STATIC mp_obj_t bleio___init__(void) {
+// HCI cannot be enabled on import, because we need to setup the HCI adapter first.
+#if !CIRCUITPY_BLEIO_HCI
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true);
+#endif
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(bleio___init___obj, bleio___init__);
+// Need a forward reference due to mutual references.
+#if CIRCUITPY_BLEIO_HCI
+STATIC mp_obj_dict_t bleio_module_globals;
+#endif
+
+//| def set_adapter(adapter: Optional[_bleio.Adapter]) -> None:
+//| """Set the adapter to use for BLE, such as when using an HCI adapter.
+//| Raises `NotImplementedError` when the adapter is a singleton and cannot be set."""
+//| ...
+//|
+mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj) {
+#if CIRCUITPY_BLEIO_HCI
+ if (adapter_obj != mp_const_none && !MP_OBJ_IS_TYPE(adapter_obj, &bleio_adapter_type)) {
+ mp_raise_TypeError_varg(translate("Expected a %q"), bleio_adapter_type.name);
+ }
+
+ // Equivalent of:
+ // bleio.adapter = adapter_obj
+ mp_map_elem_t *elem = mp_map_lookup(&bleio_module_globals.map, MP_ROM_QSTR(MP_QSTR_adapter), MP_MAP_LOOKUP);
+ if (elem) {
+ elem->value = adapter_obj;
+ }
+#else
+ mp_raise_NotImplementedError(translate("Not settable"));
+#endif
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_set_adapter_obj, bleio_set_adapter);
+
+#if CIRCUITPY_BLEIO_HCI
+// Make the module dictionary be in RAM, so that _bleio.adapter can be set.
+// Use a local macro to define how table entries should be converted.
+#define OBJ_FROM_PTR MP_OBJ_FROM_PTR
+STATIC mp_map_elem_t bleio_module_globals_table[] = {
+#else
+#define OBJ_FROM_PTR MP_ROM_PTR
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
+#endif
// Name must be the first entry so that the exception printing below is correct.
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__bleio) },
- { MP_ROM_QSTR(MP_QSTR_Adapter), MP_ROM_PTR(&bleio_adapter_type) },
- { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) },
- { MP_ROM_QSTR(MP_QSTR_Attribute), MP_ROM_PTR(&bleio_attribute_type) },
- { MP_ROM_QSTR(MP_QSTR_Connection), MP_ROM_PTR(&bleio_connection_type) },
- { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
- { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) },
- { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
- { MP_ROM_QSTR(MP_QSTR_PacketBuffer), MP_ROM_PTR(&bleio_packet_buffer_type) },
- { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
- { MP_ROM_QSTR(MP_QSTR_ScanResults), MP_ROM_PTR(&bleio_scanresults_type) },
- { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) },
- { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) },
-
- // Properties
+ { MP_ROM_QSTR(MP_QSTR_Adapter), OBJ_FROM_PTR(&bleio_adapter_type) },
+ { MP_ROM_QSTR(MP_QSTR_Address), OBJ_FROM_PTR(&bleio_address_type) },
+ { MP_ROM_QSTR(MP_QSTR_Attribute), OBJ_FROM_PTR(&bleio_attribute_type) },
+ { MP_ROM_QSTR(MP_QSTR_Connection), OBJ_FROM_PTR(&bleio_connection_type) },
+ { MP_ROM_QSTR(MP_QSTR_Characteristic), OBJ_FROM_PTR(&bleio_characteristic_type) },
+ { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), OBJ_FROM_PTR(&bleio_characteristic_buffer_type) },
+ { MP_ROM_QSTR(MP_QSTR_Descriptor), OBJ_FROM_PTR(&bleio_descriptor_type) },
+ { MP_ROM_QSTR(MP_QSTR_PacketBuffer), OBJ_FROM_PTR(&bleio_packet_buffer_type) },
+ { MP_ROM_QSTR(MP_QSTR_ScanEntry), OBJ_FROM_PTR(&bleio_scanentry_type) },
+ { MP_ROM_QSTR(MP_QSTR_ScanResults), OBJ_FROM_PTR(&bleio_scanresults_type) },
+ { MP_ROM_QSTR(MP_QSTR_Service), OBJ_FROM_PTR(&bleio_service_type) },
+ { MP_ROM_QSTR(MP_QSTR_UUID), OBJ_FROM_PTR(&bleio_uuid_type) },
+
+#if CIRCUITPY_BLEIO_HCI
+ // For HCI, _bleio.adapter is settable, and starts as None.
+ { MP_ROM_QSTR(MP_QSTR_adapter), mp_const_none },
+ { MP_ROM_QSTR(MP_QSTR_set_adapter), (mp_obj_t) &bleio_set_adapter_obj },
+#else
+ // For non-HCI _bleio.adapter is a fixed singleton, and is not settable.
+ // _bleio.set_adapter will raise NotImplementedError.
{ MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) },
+ { MP_ROM_QSTR(MP_QSTR_set_adapter), MP_ROM_PTR(&bleio_set_adapter_obj) },
+#endif
// Errors
- { MP_ROM_QSTR(MP_QSTR_BluetoothError), MP_ROM_PTR(&mp_type_bleio_BluetoothError) },
- { MP_ROM_QSTR(MP_QSTR_ConnectionError), MP_ROM_PTR(&mp_type_bleio_ConnectionError) },
- { MP_ROM_QSTR(MP_QSTR_RoleError), MP_ROM_PTR(&mp_type_bleio_RoleError) },
- { MP_ROM_QSTR(MP_QSTR_SecurityError), MP_ROM_PTR(&mp_type_bleio_SecurityError) },
+ { MP_ROM_QSTR(MP_QSTR_BluetoothError), OBJ_FROM_PTR(&mp_type_bleio_BluetoothError) },
+ { MP_ROM_QSTR(MP_QSTR_ConnectionError), OBJ_FROM_PTR(&mp_type_bleio_ConnectionError) },
+ { MP_ROM_QSTR(MP_QSTR_RoleError), OBJ_FROM_PTR(&mp_type_bleio_RoleError) },
+ { MP_ROM_QSTR(MP_QSTR_SecurityError), OBJ_FROM_PTR(&mp_type_bleio_SecurityError) },
// Initialization
- { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&bleio___init___obj) },
-
+ { MP_ROM_QSTR(MP_QSTR___init__), OBJ_FROM_PTR(&bleio___init___obj) },
};
+#if CIRCUITPY_BLEIO_HCI
+// Module dict is mutable to allow setting _bleio.adapter.
+STATIC MP_DEFINE_MUTABLE_DICT(bleio_module_globals, bleio_module_globals_table);
+#else
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);
+#endif
void bleio_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS;
diff --git a/shared-bindings/_bleio/__init__.h b/shared-bindings/_bleio/__init__.h
index 5256bdaa0..588b1f197 100644
--- a/shared-bindings/_bleio/__init__.h
+++ b/shared-bindings/_bleio/__init__.h
@@ -55,15 +55,17 @@ extern const mp_obj_type_t mp_type_bleio_ConnectionError;
extern const mp_obj_type_t mp_type_bleio_RoleError;
extern const mp_obj_type_t mp_type_bleio_SecurityError;
+extern mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj);
+
NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t* msg, ...);
NORETURN void mp_raise_bleio_ConnectionError(const compressed_string_t* msg, ...);
NORETURN void mp_raise_bleio_RoleError(const compressed_string_t* msg);
NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* msg, ...);
+bleio_adapter_obj_t *common_hal_bleio_allocate_adapter_or_raise(void);
void common_hal_bleio_check_connected(uint16_t conn_handle);
uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
-mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device);
void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist);
size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len);
diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c
index c4fbdab2e..f36aeed18 100644
--- a/shared-bindings/displayio/Display.c
+++ b/shared-bindings/displayio/Display.c
@@ -215,28 +215,33 @@ STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in)
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show);
-//| def refresh(self, *, target_frames_per_second: int = 60, minimum_frames_per_second: int = 1) -> bool:
+//| def refresh(self, *, target_frames_per_second: Optional[int] = None, minimum_frames_per_second: int = 1) -> bool:
//| """When auto refresh is off, waits for the target frame rate and then refreshes the display,
//| returning True. If the call has taken too long since the last refresh call for the given
//| target frame rate, then the refresh returns False immediately without updating the screen to
//| hopefully help getting caught up.
//|
//| If the time since the last successful refresh is below the minimum frame rate, then an
-//| exception will be raised. Set minimum_frames_per_second to 0 to disable.
+//| exception will be raised. Set ``minimum_frames_per_second`` to 0 to disable.
+//|
+//| When auto refresh is off, ``display.refresh()`` or ``display.refresh(target_frames_per_second=None)``
+//| will update the display immediately.
//|
//| When auto refresh is on, updates the display immediately. (The display will also update
//| without calls to this.)
//|
//| :param int target_frames_per_second: How many times a second `refresh` should be called and the screen updated.
+//| Set to `None` for immediate refresh.
//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second."""
//| ...
//|
STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_target_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 60} },
+ { MP_QSTR_target_frames_per_second, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
{ MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
};
+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -246,8 +251,18 @@ STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos
if (minimum_frames_per_second > 0) {
maximum_ms_per_real_frame = 1000 / minimum_frames_per_second;
}
- return mp_obj_new_bool(common_hal_displayio_display_refresh(self, 1000 / args[ARG_target_frames_per_second].u_int, maximum_ms_per_real_frame));
+
+ uint32_t target_ms_per_frame;
+ if (args[ARG_target_frames_per_second].u_obj == mp_const_none) {
+ target_ms_per_frame = 0xffffffff;
+ }
+ else {
+ target_ms_per_frame = 1000 / mp_obj_get_int(args[ARG_target_frames_per_second].u_obj);
+ }
+
+ return mp_obj_new_bool(common_hal_displayio_display_refresh(self, target_ms_per_frame, maximum_ms_per_real_frame));
}
+
MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_refresh_obj, 1, displayio_display_obj_refresh);
//| auto_refresh: bool
diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c
index 9cfc0d409..e4683af92 100644
--- a/shared-bindings/rgbmatrix/RGBMatrix.c
+++ b/shared-bindings/rgbmatrix/RGBMatrix.c
@@ -252,7 +252,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_deinit(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(rgbmatrix_rgbmatrix_deinit_obj, rgbmatrix_rgbmatrix_deinit);
static void check_for_deinit(rgbmatrix_rgbmatrix_obj_t *self) {
- if (!self->core.rgbPins) {
+ if (!self->protomatter.rgbPins) {
raise_deinited_error();
}
}
diff --git a/shared-bindings/rgbmatrix/RGBMatrix.h b/shared-bindings/rgbmatrix/RGBMatrix.h
index 027f817bb..1dc5a406c 100644
--- a/shared-bindings/rgbmatrix/RGBMatrix.h
+++ b/shared-bindings/rgbmatrix/RGBMatrix.h
@@ -24,29 +24,12 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_RGBMATRIX_RGBMATRIX_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_RGBMATRIX_RGBMATRIX_H
+#pragma once
#include "shared-module/rgbmatrix/RGBMatrix.h"
#include "lib/protomatter/core.h"
extern const mp_obj_type_t rgbmatrix_RGBMatrix_type;
-typedef struct {
- mp_obj_base_t base;
- mp_obj_t framebuffer;
- mp_buffer_info_t bufinfo;
- Protomatter_core core;
- void *timer;
- uint16_t bufsize, width;
- uint8_t rgb_pins[30];
- uint8_t addr_pins[10];
- uint8_t clock_pin, latch_pin, oe_pin;
- uint8_t rgb_count, addr_count;
- uint8_t bit_depth;
- bool core_is_initialized;
- bool paused;
- bool doublebuffer;
-} rgbmatrix_rgbmatrix_obj_t;
void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void* timer);
void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t*);
@@ -57,5 +40,3 @@ bool common_hal_rgbmatrix_rgbmatrix_get_paused(rgbmatrix_rgbmatrix_obj_t* self);
void common_hal_rgbmatrix_rgbmatrix_refresh(rgbmatrix_rgbmatrix_obj_t* self);
int common_hal_rgbmatrix_rgbmatrix_get_width(rgbmatrix_rgbmatrix_obj_t* self);
int common_hal_rgbmatrix_rgbmatrix_get_height(rgbmatrix_rgbmatrix_obj_t* self);
-
-#endif
diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c
index e61086f84..d88a0db48 100644
--- a/shared-bindings/usb_midi/__init__.c
+++ b/shared-bindings/usb_midi/__init__.c
@@ -51,17 +51,7 @@ mp_map_elem_t usb_midi_module_globals_table[] = {
};
// This isn't const so we can set ports dynamically.
-mp_obj_dict_t usb_midi_module_globals = {
- .base = {&mp_type_dict},
- .map = {
- .all_keys_are_qstrs = 1,
- .is_fixed = 1,
- .is_ordered = 1,
- .used = MP_ARRAY_SIZE(usb_midi_module_globals_table),
- .alloc = MP_ARRAY_SIZE(usb_midi_module_globals_table),
- .table = usb_midi_module_globals_table,
- },
-};
+MP_DEFINE_MUTABLE_DICT(usb_midi_module_globals, usb_midi_module_globals_table);
const mp_obj_module_t usb_midi_module = {
.base = { &mp_type_module },
diff --git a/shared-module/_bleio/Characteristic.h b/shared-module/_bleio/Characteristic.h
index 409a57c76..7776b1fa5 100644
--- a/shared-module/_bleio/Characteristic.h
+++ b/shared-module/_bleio/Characteristic.h
@@ -27,6 +27,9 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
+// These are not the Bluetooth spec values. They are what is used by the Nordic SoftDevice.
+// The bit values are in different positions.
+
typedef enum {
CHAR_PROP_NONE = 0,
CHAR_PROP_BROADCAST = 1u << 0,
@@ -40,4 +43,14 @@ typedef enum {
} bleio_characteristic_properties_enum_t;
typedef uint8_t bleio_characteristic_properties_t;
+// Bluetooth spec property values
+#define BT_GATT_CHRC_BROADCAST 0x01
+#define BT_GATT_CHRC_READ 0x02
+#define BT_GATT_CHRC_WRITE_WITHOUT_RESP 0x04
+#define BT_GATT_CHRC_WRITE 0x08
+#define BT_GATT_CHRC_NOTIFY 0x10
+#define BT_GATT_CHRC_INDICATE 0x20
+#define BT_GATT_CHRC_AUTH 0x40
+#define BT_GATT_CHRC_EXT_PROP 0x80
+
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index 4f92f249f..021159c0d 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -352,7 +352,7 @@ uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self
bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) {
- if (!self->auto_refresh && !self->first_manual_refresh) {
+ if (!self->auto_refresh && !self->first_manual_refresh && (target_ms_per_frame != 0xffffffff) ) {
uint64_t current_time = supervisor_ticks_ms64();
uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh;
// Test to see if the real frame time is below our minimum.
diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c
index 6b5346877..5163c3a7b 100644
--- a/shared-module/framebufferio/FramebufferDisplay.c
+++ b/shared-module/framebufferio/FramebufferDisplay.c
@@ -66,7 +66,7 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu
ram_height,
0,
0,
- rotation,
+ 0, // rotation
depth,
fb_getter_default(get_grayscale, (depth < 8)),
fb_getter_default(get_pixels_in_byte_share_row, false),
@@ -92,6 +92,10 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu
self->native_frames_per_second = fb_getter_default(get_native_frames_per_second, 60);
self->native_ms_per_frame = 1000 / self->native_frames_per_second;
+ if (rotation != 0) {
+ common_hal_framebufferio_framebufferdisplay_set_rotation(self, rotation);
+ }
+
supervisor_start_terminal(self->core.width, self->core.height);
// Set the group after initialization otherwise we may send pixels while we delay in
diff --git a/shared-module/rgbmatrix/RGBMatrix.c b/shared-module/rgbmatrix/RGBMatrix.c
index 6dad91679..3007ca4db 100644
--- a/shared-module/rgbmatrix/RGBMatrix.c
+++ b/shared-module/rgbmatrix/RGBMatrix.c
@@ -66,9 +66,9 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i
}
void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self, mp_obj_t framebuffer) {
+ common_hal_rgbmatrix_timer_disable(self->timer);
if (framebuffer) {
self->framebuffer = framebuffer;
- framebuffer = mp_obj_new_bytearray_of_zeros(self->bufsize);
mp_get_buffer_raise(self->framebuffer, &self->bufinfo, MP_BUFFER_READ);
if (mp_get_buffer(self->framebuffer, &self->bufinfo, MP_BUFFER_RW)) {
self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW;
@@ -79,17 +79,18 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self,
mp_get_index(mp_obj_get_type(self->framebuffer), self->bufinfo.len, MP_OBJ_NEW_SMALL_INT(self->bufsize-1), false);
} else {
_PM_FREE(self->bufinfo.buf);
- _PM_FREE(self->core.rgbPins);
- _PM_FREE(self->core.addr);
- _PM_FREE(self->core.screenData);
+ _PM_FREE(self->protomatter.rgbPins);
+ _PM_FREE(self->protomatter.addr);
+ _PM_FREE(self->protomatter.screenData);
self->framebuffer = NULL;
- self->bufinfo.buf = _PM_allocator_impl(self->bufsize);
+ self->bufinfo.buf = common_hal_rgbmatrix_allocator_impl(self->bufsize);
self->bufinfo.len = self->bufsize;
self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW;
}
- ProtomatterStatus stat = _PM_init(&self->core,
+ memset(&self->protomatter, 0, sizeof(self->protomatter));
+ ProtomatterStatus stat = _PM_init(&self->protomatter,
self->width, self->bit_depth,
self->rgb_count/6, self->rgb_pins,
self->addr_count, self->addr_pins,
@@ -97,18 +98,21 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self,
self->doublebuffer, self->timer);
if (stat == PROTOMATTER_OK) {
- _PM_protoPtr = &self->core;
+ _PM_protoPtr = &self->protomatter;
common_hal_mcu_disable_interrupts();
common_hal_rgbmatrix_timer_enable(self->timer);
- stat = _PM_begin(&self->core);
- _PM_convert_565(&self->core, self->bufinfo.buf, self->width);
+ stat = _PM_begin(&self->protomatter);
+
+ if (stat == PROTOMATTER_OK) {
+ _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width);
+ }
common_hal_mcu_enable_interrupts();
- _PM_swapbuffer_maybe(&self->core);
+ if (stat == PROTOMATTER_OK) {
+ _PM_swapbuffer_maybe(&self->protomatter);
+ }
}
if (stat != PROTOMATTER_OK) {
- // XXX this deinit() actually makes crashy-crashy
- // can trigger it by sending inappropriate pins
common_hal_rgbmatrix_rgbmatrix_deinit(self);
switch (stat) {
case PROTOMATTER_ERR_PINS:
@@ -117,7 +121,9 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self,
case PROTOMATTER_ERR_ARG:
mp_raise_ValueError(translate("Invalid argument"));
break;
- case PROTOMATTER_ERR_MALLOC: /// should have already been signaled as NLR
+ case PROTOMATTER_ERR_MALLOC:
+ mp_raise_msg(&mp_type_MemoryError, NULL);
+ break;
default:
mp_raise_msg_varg(&mp_type_RuntimeError,
translate("Internal error #%d"), (int)stat);
@@ -126,7 +132,6 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self,
}
self->paused = 0;
-
}
STATIC void free_pin(uint8_t *pin) {
@@ -148,7 +153,7 @@ void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t* self) {
self->timer = 0;
}
- if (_PM_protoPtr == &self->core) {
+ if (_PM_protoPtr == &self->protomatter) {
_PM_protoPtr = NULL;
}
@@ -158,10 +163,10 @@ void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t* self) {
free_pin(&self->latch_pin);
free_pin(&self->oe_pin);
- if (self->core.rgbPins) {
- _PM_free(&self->core);
+ if (self->protomatter.rgbPins) {
+ _PM_free(&self->protomatter);
}
- memset(&self->core, 0, sizeof(self->core));
+ memset(&self->protomatter, 0, sizeof(self->protomatter));
// If it was supervisor-allocated, it is supervisor-freed and the pointer
// is zeroed, otherwise the pointer is just zeroed
@@ -175,16 +180,16 @@ void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t* self) {
void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t* self) {
gc_collect_ptr(self->framebuffer);
- gc_collect_ptr(self->core.rgbPins);
- gc_collect_ptr(self->core.addr);
- gc_collect_ptr(self->core.screenData);
+ gc_collect_ptr(self->protomatter.rgbPins);
+ gc_collect_ptr(self->protomatter.addr);
+ gc_collect_ptr(self->protomatter.screenData);
}
void common_hal_rgbmatrix_rgbmatrix_set_paused(rgbmatrix_rgbmatrix_obj_t* self, bool paused) {
if (paused && !self->paused) {
- _PM_stop(&self->core);
+ _PM_stop(&self->protomatter);
} else if (!paused && self->paused) {
- _PM_resume(&self->core);
+ _PM_resume(&self->protomatter);
}
self->paused = paused;
}
@@ -194,8 +199,8 @@ bool common_hal_rgbmatrix_rgbmatrix_get_paused(rgbmatrix_rgbmatrix_obj_t* self)
}
void common_hal_rgbmatrix_rgbmatrix_refresh(rgbmatrix_rgbmatrix_obj_t* self) {
- _PM_convert_565(&self->core, self->bufinfo.buf, self->width);
- _PM_swapbuffer_maybe(&self->core);
+ _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width);
+ _PM_swapbuffer_maybe(&self->protomatter);
}
int common_hal_rgbmatrix_rgbmatrix_get_width(rgbmatrix_rgbmatrix_obj_t* self) {
@@ -206,3 +211,20 @@ int common_hal_rgbmatrix_rgbmatrix_get_height(rgbmatrix_rgbmatrix_obj_t* self) {
int computed_height = (self->rgb_count / 3) << (self->addr_count);
return computed_height;
}
+
+void *common_hal_rgbmatrix_allocator_impl(size_t sz) {
+ if (gc_alloc_possible()) {
+ return m_malloc_maybe(sz + sizeof(void*), true);
+ } else {
+ supervisor_allocation *allocation = allocate_memory(align32_size(sz), false);
+ return allocation ? allocation->ptr : NULL;
+ }
+}
+
+void common_hal_rgbmatrix_free_impl(void *ptr_in) {
+ supervisor_allocation *allocation = allocation_from_ptr(ptr_in);
+
+ if (allocation) {
+ free_memory(allocation);
+ }
+}
diff --git a/shared-module/rgbmatrix/RGBMatrix.h b/shared-module/rgbmatrix/RGBMatrix.h
index e69de29bb..19d7d5f2e 100644
--- a/shared-module/rgbmatrix/RGBMatrix.h
+++ b/shared-module/rgbmatrix/RGBMatrix.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Jeff Epler for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "lib/protomatter/core.h"
+
+extern const mp_obj_type_t rgbmatrix_RGBMatrix_type;
+typedef struct {
+ mp_obj_base_t base;
+ mp_obj_t framebuffer;
+ mp_buffer_info_t bufinfo;
+ Protomatter_core protomatter;
+ void *timer;
+ uint16_t bufsize, width;
+ uint8_t rgb_pins[30];
+ uint8_t addr_pins[10];
+ uint8_t clock_pin, latch_pin, oe_pin;
+ uint8_t rgb_count, addr_count;
+ uint8_t bit_depth;
+ bool core_is_initialized;
+ bool paused;
+ bool doublebuffer;
+} rgbmatrix_rgbmatrix_obj_t;
diff --git a/shared-module/rgbmatrix/allocator.h b/shared-module/rgbmatrix/allocator.h
index 5e6f0b41d..323fa5ec0 100644
--- a/shared-module/rgbmatrix/allocator.h
+++ b/shared-module/rgbmatrix/allocator.h
@@ -1,29 +1,37 @@
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_RGBMATRIX_ALLOCATOR_H
-#define MICROPY_INCLUDED_SHARED_MODULE_RGBMATRIX_ALLOCATOR_H
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Jeff Epler for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
#include <stdbool.h>
#include "py/gc.h"
#include "py/misc.h"
#include "supervisor/memory.h"
-#define _PM_ALLOCATOR _PM_allocator_impl
-#define _PM_FREE(x) (_PM_free_impl((x)), (x)=NULL, (void)0)
-
-static inline void *_PM_allocator_impl(size_t sz) {
- if (gc_alloc_possible()) {
- return m_malloc(sz + sizeof(void*), true);
- } else {
- supervisor_allocation *allocation = allocate_memory(align32_size(sz), false);
- return allocation ? allocation->ptr : NULL;
- }
-}
-
-static inline void _PM_free_impl(void *ptr_in) {
- supervisor_allocation *allocation = allocation_from_ptr(ptr_in);
-
- if (allocation) {
- free_memory(allocation);
- }
-}
-
-#endif
+#define _PM_ALLOCATOR common_hal_rgbmatrix_allocator_impl
+#define _PM_FREE(x) (common_hal_rgbmatrix_free_impl((x)), (x)=NULL, (void)0)
+extern void *common_hal_rgbmatrix_allocator_impl(size_t sz);
+extern void common_hal_rgbmatrix_free_impl(void *);
diff --git a/supervisor/shared/bluetooth.c b/supervisor/shared/bluetooth.c
index 98d0fab38..56bf32117 100644
--- a/supervisor/shared/bluetooth.c
+++ b/supervisor/shared/bluetooth.c
@@ -24,6 +24,15 @@
* THE SOFTWARE.
*/
+#if !CIRCUITPY_BLE_FILE_SERVICE
+void supervisor_start_bluetooth(void) {
+}
+
+void supervisor_bluetooth_background(void) {
+}
+
+#else
+
#include <string.h>
#include "extmod/vfs.h"
@@ -41,6 +50,8 @@
#include "py/mpstate.h"
+
+
bleio_service_obj_t supervisor_ble_service;
bleio_uuid_obj_t supervisor_ble_service_uuid;
bleio_characteristic_obj_t supervisor_ble_version_characteristic;
@@ -63,10 +74,7 @@ mp_obj_t service_list_items[1];
mp_obj_list_t characteristic_list;
mp_obj_t characteristic_list_items[4];
-void supervisor_bluetooth_start_advertising(void) {
- #if !CIRCUITPY_BLE_FILE_SERVICE
- return;
- #endif
+STATIC void supervisor_bluetooth_start_advertising(void) {
bool is_connected = common_hal_bleio_adapter_get_connected(&common_hal_bleio_adapter_obj);
if (is_connected) {
return;
@@ -83,10 +91,6 @@ void supervisor_bluetooth_start_advertising(void) {
}
void supervisor_start_bluetooth(void) {
- #if !CIRCUITPY_BLE_FILE_SERVICE
- return;
- #endif
-
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true);
supervisor_ble_service_uuid.base.type = &bleio_uuid_type;
@@ -177,7 +181,7 @@ volatile bool new_filename;
volatile bool run_ble_background;
bool was_connected;
-void update_file_length(void) {
+STATIC void update_file_length(void) {
int32_t file_length = -1;
mp_buffer_info_t bufinfo;
bufinfo.buf = &file_length;
@@ -188,7 +192,7 @@ void update_file_length(void) {
common_hal_bleio_characteristic_set_value(&supervisor_ble_length_characteristic, &bufinfo);
}
-void open_current_file(void) {
+STATIC void open_current_file(void) {
if (active_file.obj.fs != 0) {
return;
}
@@ -203,7 +207,7 @@ void open_current_file(void) {
update_file_length();
}
-void close_current_file(void) {
+STATIC void close_current_file(void) {
f_close(&active_file);
}
@@ -211,9 +215,6 @@ uint32_t current_command[1024 / sizeof(uint32_t)];
volatile size_t current_offset;
void supervisor_bluetooth_background(void) {
- #if !CIRCUITPY_BLE_FILE_SERVICE
- return;
- #endif
if (!run_ble_background) {
return;
}
@@ -305,54 +306,4 @@ void supervisor_bluetooth_background(void) {
}
}
-// This happens in an interrupt so we need to be quick.
-bool supervisor_bluetooth_hook(ble_evt_t *ble_evt) {
- #if !CIRCUITPY_BLE_FILE_SERVICE
- return false;
- #endif
- // Catch writes to filename or contents. Length is read-only.
-
- bool done = false;
- switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED:
- // We run our background task even if it wasn't us connected to because we may want to
- // advertise if the user code stopped advertising.
- run_ble_background = true;
- break;
- case BLE_GAP_EVT_DISCONNECTED:
- run_ble_background = true;
- break;
- case BLE_GATTS_EVT_WRITE: {
- // A client wrote to a characteristic.
-
- ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
- // Event handle must match the handle for my characteristic.
- if (evt_write->handle == supervisor_ble_contents_characteristic.handle) {
- // Handle events
- //write_to_ringbuf(self, evt_write->data, evt_write->len);
- // First packet includes a uint16_t le for length at the start.
- uint16_t current_length = ((uint16_t*) current_command)[0];
- memcpy(((uint8_t*) current_command) + current_offset, evt_write->data, evt_write->len);
- current_offset += evt_write->len;
- current_length = ((uint16_t*) current_command)[0];
- if (current_offset == current_length) {
- run_ble_background = true;
- done = true;
- }
- } else if (evt_write->handle == supervisor_ble_filename_characteristic.handle) {
- new_filename = true;
- run_ble_background = true;
- done = true;
- } else {
- return done;
- }
- break;
- }
-
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
- break;
- }
- return done;
-}
+#endif // #else
diff --git a/supervisor/shared/bluetooth.h b/supervisor/shared/bluetooth.h
index 1fb6a879a..55f9c86fa 100644
--- a/supervisor/shared/bluetooth.h
+++ b/supervisor/shared/bluetooth.h
@@ -27,8 +27,7 @@
#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H
#define MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H
-void supervisor_start_bluetooth(void);
-bool supervisor_bluetooth_hook(ble_evt_t *ble_evt);
void supervisor_bluetooth_background(void);
+void supervisor_start_bluetooth(void);
-#endif
+#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H
diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c
index 634720d0a..afb3f3a9a 100644
--- a/supervisor/shared/display.c
+++ b/supervisor/shared/display.c
@@ -65,10 +65,14 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
if (width_in_tiles < 80) {
scale = 1;
}
+
width_in_tiles = (width_px - blinka_bitmap.width * scale) / (grid->tile_width * scale);
+ if (width_in_tiles < 1) {
+ width_in_tiles = 1;
+ }
uint16_t height_in_tiles = height_px / (grid->tile_height * scale);
uint16_t remaining_pixels = height_px % (grid->tile_height * scale);
- if (remaining_pixels > 0) {
+ if (height_in_tiles < 1 || remaining_pixels > 0) {
height_in_tiles += 1;
}
@@ -94,6 +98,8 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
}
grid->width_in_tiles = width_in_tiles;
grid->height_in_tiles = height_in_tiles;
+ assert(width_in_tiles > 0);
+ assert(height_in_tiles > 0);
grid->pixel_width = width_in_tiles * grid->tile_width;
grid->pixel_height = height_in_tiles * grid->tile_height;
grid->tiles = tiles;
diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c
index f26e1e79d..91ffa307d 100644
--- a/supervisor/shared/tick.c
+++ b/supervisor/shared/tick.c
@@ -37,7 +37,7 @@
#if CIRCUITPY_BLEIO
#include "supervisor/shared/bluetooth.h"
-#include "common-hal/_bleio/bonding.h"
+#include "common-hal/_bleio/__init__.h"
#endif
#if CIRCUITPY_DISPLAYIO
@@ -87,7 +87,7 @@ void supervisor_background_tasks(void *unused) {
#if CIRCUITPY_BLEIO
supervisor_bluetooth_background();
- bonding_background();
+ bleio_background();
#endif
port_background_task();
diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk
index c876a11cc..e81c51a88 100644
--- a/supervisor/supervisor.mk
+++ b/supervisor/supervisor.mk
@@ -34,7 +34,7 @@ endif
CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM)
ifeq ($(CIRCUITPY_BLEIO),1)
- SRC_SUPERVISOR += supervisor/shared/bluetooth.c
+ SRC_SUPERVISOR += supervisor/shared/bluetooth.c supervisor/bluetooth.c
endif
# Choose which flash filesystem impl to use.
diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py
index baee8cad7..15bf2daa0 100644
--- a/tools/gen_usb_descriptor.py
+++ b/tools/gen_usb_descriptor.py
@@ -382,8 +382,8 @@ if args.max_ep != 0:
for interface in interfaces:
for subdescriptor in interface.subdescriptors:
endpoint_address = getattr(subdescriptor, 'bEndpointAddress', 0) & 0x7f
- if endpoint_address > args.max_ep:
- raise ValueError("Endpoint address %d of %s may not exceed %d" % (endpoint_address & 0x7f, interface.description, args.max_ep))
+ if endpoint_address >= args.max_ep:
+ raise ValueError("Endpoint address %d of %s must be less than %d" % (endpoint_address & 0x7f, interface.description, args.max_ep))
else:
print("Unable to check whether maximum number of endpoints is respected", file=sys.stderr)