From 31cc71f7fb0ddfc152c0927d60e9e573340ebf1f Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 15 Nov 2018 17:00:12 -0500 Subject: [PATCH 001/153] WIP: bleio revisions --- ports/nrf/Makefile | 3 +- ports/nrf/common-hal/bleio/Service.c | 5 +- ports/nrf/common-hal/bleio/UUID.c | 115 +++++-------------- ports/nrf/common-hal/bleio/UUID.h | 9 +- shared-bindings/bleio/Characteristic.c | 12 +- shared-bindings/bleio/Service.c | 8 +- shared-bindings/bleio/UUID.c | 151 ++++++++++++++++--------- shared-bindings/bleio/UUID.h | 6 +- shared-bindings/bleio/UUIDType.c | 75 ------------ shared-bindings/bleio/UUIDType.h | 46 -------- shared-bindings/bleio/__init__.c | 3 - 11 files changed, 149 insertions(+), 284 deletions(-) delete mode 100644 shared-bindings/bleio/UUIDType.c delete mode 100644 shared-bindings/bleio/UUIDType.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 8d0d6d000ff81..a622522a4a334 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -193,8 +193,7 @@ SRC_BINDINGS_ENUMS += \ bleio/Address.c \ bleio/AddressType.c \ bleio/AdvertisementData.c \ - bleio/ScanEntry.c \ - bleio/UUIDType.c + bleio/ScanEntry.c endif SRC_SHARED_MODULE = \ diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index c17c1690470cd..6866837a19a31 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -53,7 +53,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei ble_uuid_t uuid = { .type = BLE_UUID_TYPE_BLE, - .uuid = characteristic->uuid->value[0] | (characteristic->uuid->value[1] << 8), + .uuid = characteristic->uuid->uuid16; }; if (characteristic->uuid->type == UUID_TYPE_128BIT) @@ -79,8 +79,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei uint32_t err_code; err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to add characteristic, status: 0x%08lX"), err_code)); + mp_raise_OSError(translate("Could not add characteristic")); } characteristic->user_desc_handle = handles.user_desc_handle; diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c index 9a2e101ea56f5..a54de5e31bd3b 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -25,100 +25,47 @@ * THE SOFTWARE. */ -#include "ble.h" -#include "ble_drv.h" -#include "common-hal/bleio/UUID.h" -#include "nrf_error.h" -#include "py/objstr.h" +#include + #include "py/runtime.h" +#include "common-hal/bleio/UUID.h" #include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/UUID.h" - -#define UUID_STR_16BIT_LEN 6 -#define UUID_STR_128BIT_LEN 36 - -static uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { - return unichar_xdigit_value(nibble1) | - (unichar_xdigit_value(nibble2) << 4); -} - -void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uuid) { - if (MP_OBJ_IS_INT(*uuid)) { - self->type = UUID_TYPE_16BIT; - - self->value[1] = (mp_obj_get_int(*uuid) >> 8) & 0xFF; - self->value[0] = (mp_obj_get_int(*uuid) >> 0) & 0xFF; - return; - } - - if (MP_OBJ_IS_STR(*uuid)) { - GET_STR_DATA_LEN(*uuid, str_data, str_len); - - if (str_len == UUID_STR_16BIT_LEN) { - self->type = UUID_TYPE_16BIT; - - self->value[0] = xdigit_8b_value(str_data[5], str_data[4]); - self->value[1] = xdigit_8b_value(str_data[3], str_data[2]); - } else if (str_len == UUID_STR_128BIT_LEN) { - self->type = UUID_TYPE_128BIT; - ble_uuid128_t vs_uuid; - vs_uuid.uuid128[0] = xdigit_8b_value(str_data[35], str_data[34]); - vs_uuid.uuid128[1] = xdigit_8b_value(str_data[33], str_data[32]); - vs_uuid.uuid128[2] = xdigit_8b_value(str_data[31], str_data[30]); - vs_uuid.uuid128[3] = xdigit_8b_value(str_data[29], str_data[28]); - vs_uuid.uuid128[4] = xdigit_8b_value(str_data[27], str_data[26]); - vs_uuid.uuid128[5] = xdigit_8b_value(str_data[25], str_data[24]); - - // 23 '-' - vs_uuid.uuid128[6] = xdigit_8b_value(str_data[22], str_data[21]); - vs_uuid.uuid128[7] = xdigit_8b_value(str_data[20], str_data[19]); - - // 18 '-' - vs_uuid.uuid128[8] = xdigit_8b_value(str_data[17], str_data[16]); - vs_uuid.uuid128[9] = xdigit_8b_value(str_data[15], str_data[14]); - - // 13 '-' - vs_uuid.uuid128[10] = xdigit_8b_value(str_data[12], str_data[11]); - vs_uuid.uuid128[11] = xdigit_8b_value(str_data[10], str_data[9]); - - // 8 '-' - self->value[0] = xdigit_8b_value(str_data[7], str_data[6]); - self->value[1] = xdigit_8b_value(str_data[5], str_data[4]); - - vs_uuid.uuid128[14] = xdigit_8b_value(str_data[3], str_data[2]); - vs_uuid.uuid128[15] = xdigit_8b_value(str_data[1], str_data[0]); - - common_hal_bleio_adapter_set_enabled(true); - - const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->uuid_vs_idx); - if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to add Vendor Specific UUID, status: 0x%08lX"), err_code)); - } - - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID string length"))); - } +#include "ble.h" +#include "ble_drv.h" +#include "nrf_error.h" - return; +// 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, uint8_t uuid128[]) { + self->uuid16 = uuid16; + self->uuid_vs_idx = 0; + if (uuid128 != NULL) { + ble_uuid128_t vs_uuid; + memcpy(vs_uuid.uuid128, uuid128, sizeof(vs_uuid.uuid128)); + + // Register this vendor-specific UUID. Bytes 12 and 13 will be zero. + common_hal_bleio_adapter_set_enabled(true); + const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->uuid_vs_idx); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError(&mp_type_OSError, translate("Could not register Vendor-Specific UUID")); } - - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); } void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print) { - if (self->type == UUID_TYPE_16BIT) { - mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ")", - self->value[1], self->value[0]); + if (self->uuid_vs_idx != 0) { + mp_printf(print, "UUID(uuid16: 0x%04x, Vendor-Specific index: " HEX2_FMT ")", + self->uuid16, self->uuid_vs_idx); } else { - mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ", VS idx: " HEX2_FMT ")", - self->value[1], self->value[0], self->uuid_vs_idx); + mp_printf(print, "UUID16(0x%04x)", self->uuid16); } } -bleio_uuid_type_t common_hal_bleio_uuid_get_type(bleio_uuid_obj_t *self) { - return self->type; +bool common_hal_bleio_uuid_get_vendor_specific(bleio_uuid_obj_t *self) { + return self->uuid_vs_idx != 0; +} + +uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) { + return self->uuid16; } diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/bleio/UUID.h index cb0fddcfd7a39..77f8fc5d195a7 100644 --- a/ports/nrf/common-hal/bleio/UUID.h +++ b/ports/nrf/common-hal/bleio/UUID.h @@ -28,13 +28,16 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H -#include "shared-bindings/bleio/UUIDType.h" +#include "py/obj.h" typedef struct { mp_obj_base_t base; - bleio_uuid_type_t type; + // If non-zero, `uuid_vs_idx` is an index into the SoftDevice's table of registered vendor-specific UUID's. + // If zero, `value` is a 16-bit Bluetooth SIG UUID, which would convert to this 128-bit UUID. + // 0000xxxx-0000-1000-8000-00805F9B34FB uint8_t uuid_vs_idx; - uint8_t value[2]; + // The 16-bit part of the UUID. This replaces bytes 12 and 13 in the registered 128-bit UUID. + uint16_t uuid16; } bleio_uuid_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 369f3f991dba2..2dd1d4270c673 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -80,18 +80,19 @@ //| .. attribute:: write //| -//| A `bool` specifying if the characteristic allows writting to its value. +//| A `bool` specifying if the characteristic allows writing to its value. //| //| .. attribute:: write_no_resp //| -//| A `bool` specifying if the characteristic allows writting to its value without response. +//| A `bool` specifying if the characteristic allows writing to its value without response. //| STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "Characteristic(uuid: 0x"HEX2_FMT""HEX2_FMT" handle: 0x" HEX2_FMT ")", - self->uuid->value[1], self->uuid->value[0], self->handle); + mp_printf(print, "Characteristic("); + common_hal_bleio_uuid_print(print, self->uuid); + mp_printf(print, ")"); } STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { @@ -121,8 +122,7 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { self->uuid = MP_OBJ_TO_PTR(uuid); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); + mp_raise_ValueError(translate("Expected a UUID")); } common_hal_bleio_characteristic_construct(self); diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 2d09cbc3c8054..727350215f80b 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -66,8 +66,9 @@ STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "Service(uuid: 0x"HEX2_FMT""HEX2_FMT")", - self->uuid->value[1], self->uuid->value[0]); + mp_printf(print, "Service("); + common_hal_bleio_uuid_print(print, self->uuid); + mp_print(print, ")"); } STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { @@ -101,8 +102,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { self->uuid = MP_OBJ_TO_PTR(uuid); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); + mp_raise_ValueError(translate("Expected a UUID or None")); } return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 7cef9a26fe18d..33d280304ca4a 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -5,6 +5,7 @@ * * Copyright (c) 2017 Glenn Ruben Bakke * Copyright (c) 2018 Artur Pacholec + * 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 @@ -29,47 +30,38 @@ #include "py/runtime.h" #include "shared-bindings/bleio/UUID.h" +// Including hyphens. +#define UUID128_STR_LEN 36 +// Number of bytes +#define UUID128_BYTE_LEN 32 + +STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { + return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4); +} + + //| .. currentmodule:: bleio //| -//| :class:`UUID` -- BLE UUID +//| :class:`UUID16` -- BLE UUID16 //| ========================================================= //| -//| Encapsulates both 16-bit and 128-bit UUIDs. Can be used for services, -//| characteristics, descriptors and more. +//| A 16-bit or 128-bit UUID. Can be used for services, characteristics, descriptors and more. //| //| .. class:: UUID(uuid) //| -//| Create a new UUID object encapsulating the uuid value. -//| The value itself can be one of: +//| Create a new UUID or UUID object encapsulating the uuid value. +//| The value can be one of: //| -//| - a `int` value in range of 0 to 0xFFFF -//| - a `str` value in the format of '0xXXXX' for 16-bit or 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' for 128-bit +//| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID) +//| - a `str` value in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', where the X's are hex digits. +//| (128 bit UUID) //| //| :param int/str uuid: The uuid to encapsulate //| -//| .. method:: __len__() -//| -//| Returns the uuid length in bits -//| -//| This allows you to: -//| -//| uuid = bleio.UUID(0x1801) -//| print(len(uuid)) -//| - -//| .. attribute:: type -//| -//| The UUID type. One of: -//| -//| - `bleio.UUIDType.TYPE_16BIT` -//| - `bleio.UUIDType.TYPE_128BIT` -//| STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); - bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); - self->base.type = &bleio_uuid_type; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); @@ -84,20 +76,55 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si const mp_obj_t uuid = args[ARG_uuid].u_obj; - common_hal_bleio_uuid_construct(self, &uuid); - - return MP_OBJ_FROM_PTR(self); -} - -STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) { - bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); - - const bleio_uuid_type_t type = common_hal_bleio_uuid_get_type(self); - const uint8_t len = (type == UUID_TYPE_16BIT) ? 16 : 128; - switch (op) { - case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); - case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); - default: return MP_OBJ_NULL; // op not supported + if (MP_OBJ_IS_INT(uuid)) { + mp_int_t uuid16 = mp_obj_get_int(uuid); + if (uuid16 < 0 || uuid16 > 0xffff) { + mp_raise_ValueError(translate("Integer UUID not in range 0 to 0xffff")); + } + + // This is a 16-bit Bluetooth SIG UUID. NULL means no 128-bit value. + common_hal_bleio_uuid_construct(self, uuid16, NULL); + + } else if (MP_OBJ_IS_STR(uuid)) { + uint8_t uuid128[UUID128_BYTE_LEN]; + GET_STR_DATA_LEN(uuid, str, str_len); + if (str_len == UUID128_STR_LEN && + str[8] == '-' && str[13] == '-' && str[18] == '-' && str[23] == '-') { + size_t str_index = UUID128_STR_LEN - 1; + size_t uuid128_index = 0; + bool error = false; + + // Loop until fewer than two characters left. + while (str_index >= 1 && uuid128_index < UUID128_BYTE_LEN) { + if (str[str_index] == '-') { + // Skip hyphen separators. + str--; + continue; + } + + if (!unichar_isxdigit(str[str_index]) || + !unichar_isxdigit(str[str_index-1])) { + error = true; + break; + } + + uuid128[uuid128_index] = xdigit_8b_value(str[str_index], + str[str_index-1]); + uuid128_index += 1; + str_index -= 2; + } + // Check for correct number of hex digits and no parsing errors. + if (!error && uuid128_index == UUID128_BYTE_LEN && str_index == -1) { + uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12]; + uuid128[12] = 0; + uuid128[13] = 0; + common_hal_bleio_uuid_construct(self, uuid16, uuid128); + return MP_OBJ_FROM_PTR(self); + } + } + mp_raise_ValueError(translate("UUID string must be of the form xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); + } else { + mp_raise_ValueError(translate("UUID value is not int or string")); } } @@ -107,31 +134,46 @@ STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print common_hal_bleio_uuid_print(self, print); } -STATIC mp_obj_t bleio_uuid_get_type(mp_obj_t self_in) { +//| .. attribute:: uuid16 +//| +//| The 16-bit part of the UUID. (read-only) +//| +STATIC void bleio_uuid_get_uuid16(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self)); +} - const bleio_uuid_type_t type = common_hal_bleio_uuid_get_type(self); - if (type == UUID_TYPE_16BIT) { - return (mp_obj_t)&bleio_uuidtype_16bit_obj; - } +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid16_obj, bleio_uuid_get_uuid16); - if (type == UUID_TYPE_128BIT) { - return (mp_obj_t)&bleio_uuidtype_128bit_obj; - } +const mp_obj_property_t bleio_uuid16_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_uuid16_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; - return (mp_obj_t)&mp_const_none_obj; +//| .. attribute:: vendor_specific +//| +//| True if this UUID represents a 128-bit vendor-specific UUID. +//| False if this UUID represents a 16-bit Bluetooth SIG assigned UUID. (read-only) +//| +STATIC mp_obj_t bleio_uuid_get_vendor_specific(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_bleio_uuid_get_vendor_specific(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_type_obj, bleio_uuid_get_type); -const mp_obj_property_t bleio_uuid_type_obj = { +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_vendor_specific_obj, bleio_uuid_get_vendor_specific); + +const mp_obj_property_t bleio_uuid_vendor_specific_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&bleio_uuid_get_type_obj, + .proxy = {(mp_obj_t)&bleio_uuid_get_vendor_specific_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_uuid_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid16_obj) }, + { MP_ROM_QSTR(MP_QSTR_vendor_specific), MP_ROM_PTR(&bleio_uuid_vendor_specific_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table); @@ -141,6 +183,5 @@ const mp_obj_type_t bleio_uuid_type = { .name = MP_QSTR_UUID, .print = bleio_uuid_print, .make_new = bleio_uuid_make_new, - .unary_op = bleio_uuid_unary_op, - .locals_dict = (mp_obj_dict_t*)&bleio_uuid_locals_dict + .locals_dict = (mp_obj_dict_t*)&bleio_uuid_locals_dict, }; diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h index d6fcbac1b49b2..e27058516efa1 100644 --- a/shared-bindings/bleio/UUID.h +++ b/shared-bindings/bleio/UUID.h @@ -28,12 +28,12 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H #include "common-hal/bleio/UUID.h" -#include "shared-bindings/bleio/UUIDType.h" extern const mp_obj_type_t bleio_uuid_type; -extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uuid); +extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, uint8_t uuid128[]); extern void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print); -extern bleio_uuid_type_t common_hal_bleio_uuid_get_type(bleio_uuid_obj_t *self); +extern bool common_hal_bleio_uuid_get_vendor_specific(bleio_uuid_obj_t *self); +extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H diff --git a/shared-bindings/bleio/UUIDType.c b/shared-bindings/bleio/UUIDType.c deleted file mode 100644 index e36d1f06d21a7..0000000000000 --- a/shared-bindings/bleio/UUIDType.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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/UUIDType.h" - -//| .. currentmodule:: bleio -//| -//| :class:`UUIDType` -- defines the type of a BLE UUID -//| ============================================================= -//| -//| .. class:: bleio.UUIDType -//| -//| Enum-like class to define the type of a BLE UUID. -//| -//| .. data:: TYPE_16BIT -//| -//| The UUID is 16-bit -//| -//| .. data:: TYPE_128BIT -//| -//| The UUID is 128-bit -//| -const mp_obj_type_t bleio_uuidtype_type; - -const bleio_uuidtype_obj_t bleio_uuidtype_16bit_obj = { - { &bleio_uuidtype_type }, -}; - -const bleio_uuidtype_obj_t bleio_uuidtype_128bit_obj = { - { &bleio_uuidtype_type }, -}; - -STATIC const mp_rom_map_elem_t bleio_uuidtype_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_TYPE_16BIT), MP_ROM_PTR(&bleio_uuidtype_16bit_obj) }, - { MP_ROM_QSTR(MP_QSTR_TYPE_128BIT), MP_ROM_PTR(&bleio_uuidtype_128bit_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(bleio_uuidtype_locals_dict, bleio_uuidtype_locals_dict_table); - -STATIC void bleio_uuidtype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr type = MP_QSTR_TYPE_128BIT; - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_uuidtype_16bit_obj)) { - type = MP_QSTR_TYPE_16BIT; - } - mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_UUIDType, type); -} - -const mp_obj_type_t bleio_uuidtype_type = { - { &mp_type_type }, - .name = MP_QSTR_UUIDType, - .print = bleio_uuidtype_print, - .locals_dict = (mp_obj_t)&bleio_uuidtype_locals_dict, -}; diff --git a/shared-bindings/bleio/UUIDType.h b/shared-bindings/bleio/UUIDType.h deleted file mode 100644 index 87bbf9b53178c..0000000000000 --- a/shared-bindings/bleio/UUIDType.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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_SHARED_BINDINGS_BLEIO_UUIDTYPE_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H - -#include "py/obj.h" - -typedef enum { - UUID_TYPE_16BIT, - UUID_TYPE_128BIT -} bleio_uuid_type_t; - -extern const mp_obj_type_t bleio_uuidtype_type; - -typedef struct { - mp_obj_base_t base; -} bleio_uuidtype_obj_t; - -extern const bleio_uuidtype_obj_t bleio_uuidtype_16bit_obj; -extern const bleio_uuidtype_obj_t bleio_uuidtype_128bit_obj; - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 98099422c9ab3..46822603f58d7 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -36,7 +36,6 @@ #include "shared-bindings/bleio/Scanner.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" -#include "shared-bindings/bleio/UUIDType.h" //| :mod:`bleio` --- Bluetooth Low Energy functionality //| ================================================================ @@ -63,7 +62,6 @@ //| Scanner //| Service //| UUID -//| UUIDType //| //| .. attribute:: adapter //| @@ -89,7 +87,6 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { // Enum-like Classes. { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) }, - { MP_ROM_QSTR(MP_QSTR_UUIDType), MP_ROM_PTR(&bleio_uuidtype_type) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); From 1763ffe2450fa07c74db225cc5ef3a6e2feb669b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 20 Nov 2018 23:04:58 -0500 Subject: [PATCH 002/153] More UUID work; use mp_raise for exceptions --- ports/nrf/common-hal/bleio/Adapter.c | 15 ++-- ports/nrf/common-hal/bleio/Characteristic.c | 20 ++--- ports/nrf/common-hal/bleio/Descriptor.c | 11 ++- ports/nrf/common-hal/bleio/Device.c | 90 +++++++------------ ports/nrf/common-hal/bleio/Scanner.c | 8 +- ports/nrf/common-hal/bleio/Service.c | 13 +-- ports/nrf/common-hal/bleio/UUID.c | 32 +++++-- ports/nrf/common-hal/bleio/UUID.h | 5 ++ .../common-hal/microcontroller/Processor.c | 5 +- py/runtime.c | 3 + py/runtime.h | 1 + shared-bindings/bleio/Address.c | 49 ++++++---- shared-bindings/bleio/Characteristic.c | 11 +-- shared-bindings/bleio/Descriptor.c | 14 +-- shared-bindings/bleio/Descriptor.h | 2 +- shared-bindings/bleio/Service.c | 11 +-- shared-bindings/bleio/UUID.c | 54 ++++++++--- shared-bindings/bleio/UUID.h | 3 +- 18 files changed, 186 insertions(+), 161 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index 985e262e49fec..318502e955628 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -33,12 +33,12 @@ #include "nrfx_power.h" #include "nrf_nvic.h" #include "nrf_sdm.h" -#include "py/nlr.h" +#include "py/runtime.h" #include "shared-bindings/bleio/Adapter.h" STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AssertionError, - translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc)); + mp_raise_msg_varg(&mp_type_AssertionError, + translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc); } STATIC uint32_t ble_stack_enable(void) { @@ -121,8 +121,7 @@ void common_hal_bleio_adapter_set_enabled(bool enabled) { } if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to change softdevice state, error: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to change softdevice state")); } } @@ -131,8 +130,7 @@ bool common_hal_bleio_adapter_get_enabled(void) { const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to get softdevice state, error: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to get softdevice state")); } return is_enabled; @@ -151,8 +149,7 @@ void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { #endif if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to get local address, error: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to get local address")); } address->type = local_address.addr_type; diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 246c35005784f..002d145c7a506 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -30,7 +30,7 @@ #include "ble_drv.h" #include "ble_gatts.h" #include "nrf_soc.h" -#include "py/nlr.h" +#include "py/runtime.h" #include "shared-module/bleio/Characteristic.h" static volatile bleio_characteristic_obj_t *m_read_characteristic; @@ -48,8 +48,7 @@ STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to write gatts value, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to write gatts value")); } } @@ -72,8 +71,7 @@ STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_i const uint32_t err_code = sd_ble_gatts_hvx(device->conn_handle, &hvx_params); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to notify attribute value, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to notify attribute value")); } m_tx_in_progress += 1; @@ -87,8 +85,7 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to read attribute value, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to read attribute value")); } while (m_read_characteristic != NULL) { @@ -115,15 +112,13 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in err_code = sd_mutex_acquire(m_write_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to acquire mutex")); } } err_code = sd_ble_gattc_write(device->conn_handle, &write_params); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to write attribute value, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to write attribute value")); } while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -134,8 +129,7 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in err_code = sd_mutex_release(m_write_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } } diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c index 9b61345fa8216..c6b95832c4155 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.c +++ b/ports/nrf/common-hal/bleio/Descriptor.c @@ -26,20 +26,23 @@ */ #include "common-hal/bleio/Descriptor.h" +#include "shared-bindings/bleio/UUID.h" void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid) { + // TODO: set handle ??? self->uuid = uuid; } void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print) { - mp_printf(print, "Descriptor(uuid: 0x" HEX2_FMT HEX2_FMT ")", - self->uuid->value[1], self->uuid->value[0]); + mp_printf(print, "Descriptor(uuid="); + common_hal_bleio_uuid_print(self->uuid, print); + mp_printf(print, ", handle=%0x", self->handle); } mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) { return self->handle; } -mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { - return self->uuid->value[0] | (self->uuid->value[1] << 8); +mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { + return MP_OBJ_FROM_PTR(self->uuid); } diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 2c000ae2e162c..10592d65affd9 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -77,8 +77,7 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta #define ADD_FIELD(field, len) \ do { \ if (byte_pos + (len) > BLE_GAP_ADV_MAX_SIZE) { \ - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, \ - translate("Can not fit data into the advertisment packet"))); \ + mp_raise_ValueError(translate("Data too large for the advertisement packet")); \ } \ adv_data[byte_pos] = (field); \ byte_pos += (len); \ @@ -110,8 +109,7 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta ADD_FIELD(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE, BLE_AD_TYPE_FLAGS_DATA_SIZE); } else { if (byte_pos + raw_data->len > BLE_GAP_ADV_MAX_SIZE) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not fit data into the advertisment packet"))); + mp_raise_ValueError(translate("Data too large for the advertisement packet")); } memcpy(&adv_data[byte_pos], raw_data->buf, raw_data->len); @@ -130,12 +128,13 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta continue; } - if (service->uuid->type == UUID_TYPE_16BIT) { + switch (common_hal_bleio_uuid_get_size(service->uuid)) { + case 16: has_16bit_services = true; - } - - if (service->uuid->type == UUID_TYPE_128BIT) { + break; + case 128: has_128bit_services = true; + break; } } @@ -152,13 +151,12 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); uint8_t encoded_size = 0; - if ((service->uuid->type != UUID_TYPE_16BIT) || service->is_secondary) { + if (common_hal_bleio_uuid_get_size(service->uuid) != 16 || service->is_secondary) { continue; } ble_uuid_t uuid; - uuid.type = BLE_UUID_TYPE_BLE; - uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); if (err_code != NRF_SUCCESS) { @@ -185,13 +183,12 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); uint8_t encoded_size = 0; - if ((service->uuid->type != UUID_TYPE_128BIT) || service->is_secondary) { + if (common_hal_bleio_uuid_get_size(service->uuid) != 16 || service->is_secondary) { continue; } ble_uuid_t uuid; - uuid.type = service->uuid->uuid_vs_idx; - uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); if (err_code != NRF_SUCCESS) { @@ -262,14 +259,12 @@ STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to discover serivices, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to discover services")); } err_code = sd_mutex_acquire(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to acquire mutex")); } while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -280,8 +275,7 @@ STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } return m_discovery_successful; @@ -303,8 +297,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o err_code = sd_mutex_acquire(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to acquire mutex")); } while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -315,8 +308,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } return m_discovery_successful; @@ -324,7 +316,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_device_obj_t *device) { for (size_t i = 0; i < response->count; ++i) { - const ble_gattc_service_t *gattc_service = &response->services[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; @@ -335,10 +327,7 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res service->handle = gattc_service->handle_range.start_handle; bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - uuid->type = (gattc_service->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; - uuid->value[0] = gattc_service->uuid.uuid & 0xFF; - uuid->value[1] = gattc_service->uuid.uuid >> 8; + bleio_uuid_construct_from_nrf_uuid(uuid, &gattc_service->uuid); service->uuid = uuid; mp_obj_list_append(device->service_list, service); @@ -350,23 +339,20 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res const uint32_t err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } } STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_device_obj_t *device) { for (size_t i = 0; i < response->count; ++i) { - const ble_gattc_char_t *gattc_char = &response->chars[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 = m_new_obj(bleio_uuid_obj_t); uuid->base.type = &bleio_uuid_type; - uuid->type = (gattc_char->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; - uuid->value[0] = gattc_char->uuid.uuid & 0xFF; - uuid->value[1] = gattc_char->uuid.uuid >> 8; + bleio_uuid_construct_from_nrf_uuid(uuid, &gattc_char->uuid); characteristic->uuid = uuid; characteristic->props.broadcast = gattc_char->char_props.broadcast; @@ -387,8 +373,7 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio const uint32_t err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to release mutex, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to release mutex")); } } @@ -399,8 +384,7 @@ STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t * #if (BLUETOOTH_SD == 140) err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to continue scanning, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to continue scanning")); } #endif return; @@ -432,8 +416,7 @@ STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t * #endif if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to connect, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to connect:")); } } @@ -491,14 +474,8 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *device_in) { } void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service) { - ble_uuid_t uuid = { - .type = BLE_UUID_TYPE_BLE, - .uuid = service->uuid->value[0] | (service->uuid->value[1] << 8) - }; - - if (service->uuid->type == UUID_TYPE_128BIT) { - uuid.type = service->uuid->uuid_vs_idx; - } + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; if (service->is_secondary) { @@ -509,8 +486,7 @@ void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_servi const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to add service, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to add service")); } const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); @@ -527,8 +503,7 @@ void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool const uint32_t err_code = set_advertisement_data(device, connectable, raw_data); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to start advertisment, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to start advertising")); } } @@ -545,8 +520,7 @@ void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device) { #endif if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to stop advertisment, status: 0x%08lX"), err_code)); + mp_raise_OSError_msg(translate("Failed to stop advertising")); } } @@ -571,8 +545,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { #endif if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to start scanning, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to start scanning")); } while (device->conn_handle == BLE_CONN_HANDLE_INVALID) { @@ -588,8 +561,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { err_code = sd_mutex_new(m_discovery_mutex); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to create mutex, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to create mutex")); } } diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c index e56c1860c28fe..fd997a6d3c9ca 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -30,7 +30,7 @@ #include "ble_drv.h" #include "ble_gap.h" #include "py/mphal.h" -#include "py/nlr.h" +#include "py/runtime.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" @@ -72,8 +72,7 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) { #if (BLUETOOTH_SD == 140) const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to continue scanning, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to continue scanning")); } #endif } @@ -99,8 +98,7 @@ void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout) #endif if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Failed to start scanning, status: 0x%0xlX"), err_code)); + mp_raise_OSError_msg(translate("Failed to start scanning")); } if (timeout > 0) { diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 6866837a19a31..8ad81c015ee65 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -26,7 +26,7 @@ #include "ble_drv.h" #include "ble.h" -#include "py/nlr.h" +#include "py/runtime.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/Adapter.h" @@ -51,13 +51,8 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei char_md.p_cccd_md = &cccd_md; } - ble_uuid_t uuid = { - .type = BLE_UUID_TYPE_BLE, - .uuid = characteristic->uuid->uuid16; - }; - - if (characteristic->uuid->type == UUID_TYPE_128BIT) - uuid.type = characteristic->uuid->uuid_vs_idx; + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_uuid(characteristic->uuid, &uuid); ble_gatts_attr_md_t attr_md = { .vloc = BLE_GATTS_VLOC_STACK, @@ -79,7 +74,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei uint32_t err_code; err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); if (err_code != NRF_SUCCESS) { - mp_raise_OSError(translate("Could not add characteristic")); + mp_raise_OSError_msg(translate("Could not add characteristic")); } characteristic->user_desc_handle = handles.user_desc_handle; diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c index a54de5e31bd3b..133ffe25bcf71 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -49,23 +49,45 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, ui common_hal_bleio_adapter_set_enabled(true); const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->uuid_vs_idx); if (err_code != NRF_SUCCESS) { - mp_raise_OSError(&mp_type_OSError, translate("Could not register Vendor-Specific UUID")); + mp_raise_OSError_msg(translate("Could not register Vendor-Specific UUID")); + } } } void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print) { if (self->uuid_vs_idx != 0) { - mp_printf(print, "UUID(uuid16: 0x%04x, Vendor-Specific index: " HEX2_FMT ")", + mp_printf(print, "UUID(uuid16=0x%04x, uuid128_handle=" HEX2_FMT ")", self->uuid16, self->uuid_vs_idx); } else { - mp_printf(print, "UUID16(0x%04x)", self->uuid16); + mp_printf(print, "UUID(0x%04x)", self->uuid16); } } -bool common_hal_bleio_uuid_get_vendor_specific(bleio_uuid_obj_t *self) { - return self->uuid_vs_idx != 0; +uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) { + return self->uuid_vs_idx != 0 ? 128 : 16; } uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) { return self->uuid16; } + +// Returns 0 if there is no handle, otherwise returns a non-zero index. +uint32_t common_hal_bleio_uuid_get_uuid128_handle(bleio_uuid_obj_t *self) { + return self->uuid_vs_idx; +} + + +void bleio_uuid_construct_from_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid) { + if (nrf_uuid->type == BLE_UUID_TYPE_UNKNOWN) { + mp_raise_RuntimeError(translate("Unexpected nrfx uuid type")); + } + + self->uuid16 = nrf_uuid->uuid; + self->uuid_vs_idx = nrf_uuid->type == BLE_UUID_TYPE_BLE ? 0 : nrf_uuid->type; +} + +// Fill in a ble_uuid_t from my values. +void bleio_uuid_convert_to_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid) { + nrf_uuid->uuid = self->uuid16; + nrf_uuid->type = self->uuid_vs_idx == 0 ? BLE_UUID_TYPE_BLE : self->uuid_vs_idx; +} diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/bleio/UUID.h index 77f8fc5d195a7..f0d32ede28875 100644 --- a/ports/nrf/common-hal/bleio/UUID.h +++ b/ports/nrf/common-hal/bleio/UUID.h @@ -30,6 +30,8 @@ #include "py/obj.h" +#include "ble.h" + typedef struct { mp_obj_base_t base; // If non-zero, `uuid_vs_idx` is an index into the SoftDevice's table of registered vendor-specific UUID's. @@ -40,4 +42,7 @@ typedef struct { uint16_t uuid16; } bleio_uuid_obj_t; +void bleio_uuid_construct_from_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); +void bleio_uuid_convert_to_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); + #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index e4d9439c9919a..836020d1590d9 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -45,10 +45,7 @@ float common_hal_mcu_processor_get_temperature(void) { if (sd_en) { uint32_t err_code = sd_temp_get(&temp); if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not get temperature. status: 0x%02x"), (uint16_t)err_code)); - - return 0; + mp_raise_OSError_msg(translate("Cannot get temperature")); } } #endif diff --git a/py/runtime.c b/py/runtime.c index 3d7a97f58bda5..339978dadfe88 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1599,6 +1599,9 @@ NORETURN void mp_raise_OSError(int errno_) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_))); } +NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_OSError, msg); +} NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); diff --git a/py/runtime.h b/py/runtime.h index 9c7ffc02f5bab..54f6a3270b7b8 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -158,6 +158,7 @@ NORETURN void mp_raise_RuntimeError(const compressed_string_t *msg); NORETURN void mp_raise_ImportError(const compressed_string_t *msg); NORETURN void mp_raise_IndexError(const compressed_string_t *msg); NORETURN void mp_raise_OSError(int errno_); +NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg); NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg); NORETURN void mp_raise_recursion_depth(void); diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index ec23ff2071229..d4c24e4e2ce31 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -33,8 +33,12 @@ #include "shared-bindings/bleio/Address.h" #include "shared-module/bleio/Address.h" -#define ADDRESS_LONG_LEN 17 // XX:XX:XX:XX:XX:XX -#define ADDRESS_SHORT_LEN 12 // XXXXXXXXXXXX +#define ADDRESS_BYTE_LEN 12 + +STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { + return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4); +} + //| .. currentmodule:: bleio //| @@ -49,7 +53,7 @@ //| Create a new Address object encapsulating the address value. //| The value itself can be one of: //| -//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX' +//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX:XX' (12 hex digits) //| - a `bytes` or `bytearray` containing 6 bytes //| - another Address object //| @@ -85,26 +89,41 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t address = args[ARG_address].u_obj; if (MP_OBJ_IS_STR(address)) { - GET_STR_DATA_LEN(address, str_data, str_len); - const bool is_long = (str_len == ADDRESS_LONG_LEN); - const bool is_short = (str_len == ADDRESS_SHORT_LEN); + GET_STR_DATA_LEN(address, str, str_len); + + size_t value_index = 0; + size_t str_index = str_len; + bool error = false; + + // Loop until fewer than two characters left. + while (str_index >= 1 && value_index < sizeof(self->value)) { + if (str[str_index] == ':') { + // Skip colon separators. + str_index--; + continue; + } - if (is_long || is_short) { - size_t i = str_len - 1; - for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { - self->value[b] = unichar_xdigit_value(str_data[i]) | - unichar_xdigit_value(str_data[i - 1]) << 4; + if (!unichar_isxdigit(str[str_index]) || + !unichar_isxdigit(str[str_index-1])) { + error = true; + break; + } - i -= is_long ? 3 : 2; + self->value[value_index] = xdigit_8b_value(str[str_index], + str[str_index-1]); + value_index += 1; + str_index -= 2; } - } else { - mp_raise_ValueError(translate("Wrong address length")); + // Check for correct number of hex digits and no parsing errors. + if (error || value_index != ADDRESS_BYTE_LEN || str_index != -1) { + mp_raise_ValueError_varg(translate("Address is not %d bytes long or is in wrong format"), + ADDRESS_BYTE_LEN); } } else if (MP_OBJ_IS_TYPE(address, &mp_type_bytearray) || MP_OBJ_IS_TYPE(address, &mp_type_bytes)) { mp_buffer_info_t buf_info; mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); if (buf_info.len != BLEIO_ADDRESS_BYTES) { - mp_raise_ValueError(translate("Wrong number of bytes provided")); + mp_raise_ValueError_varg(translate("Address must be %d bytes long"), BLEIO_ADDRESS_BYTES); } for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 2dd1d4270c673..4b4a4a924598f 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -91,7 +91,7 @@ STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "Characteristic("); - common_hal_bleio_uuid_print(print, self->uuid); + common_hal_bleio_uuid_print(self->uuid, print); mp_printf(print, ")"); } @@ -115,16 +115,11 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t const mp_obj_t uuid = args[ARG_uuid].u_obj; - if (uuid == mp_const_none) { - return MP_OBJ_FROM_PTR(self); - } - - if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { - self->uuid = MP_OBJ_TO_PTR(uuid); - } else { + if (!MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { mp_raise_ValueError(translate("Expected a UUID")); } + self->uuid = MP_OBJ_TO_PTR(uuid); common_hal_bleio_characteristic_construct(self); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index df32a00e7c73e..d58bbd27562dd 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -61,7 +61,6 @@ enum { //| .. class:: Descriptor(uuid) //| //| Create a new descriptor object with the UUID uuid. -//| The value can be either of type `bleio.UUID` or any value allowed by the `bleio.UUID` constructor. //| .. attribute:: handle //| @@ -90,13 +89,11 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar const mp_obj_t uuid_arg = args[ARG_uuid].u_obj; - bleio_uuid_obj_t *uuid; - if (MP_OBJ_IS_TYPE(uuid_arg, &bleio_uuid_type)) { - uuid = MP_OBJ_TO_PTR(uuid_arg); - } else { - uuid = MP_OBJ_TO_PTR(bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_arg)); + if (!MP_OBJ_IS_TYPE(uuid_arg, &bleio_uuid_type)) { + mp_raise_ValueError(translate("Expected a UUID")); } + bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_arg); common_hal_bleio_descriptor_construct(self, uuid); return MP_OBJ_FROM_PTR(self); @@ -104,7 +101,6 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_bleio_descriptor_print(self, print); } @@ -124,9 +120,7 @@ const mp_obj_property_t bleio_descriptor_handle_obj = { STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); - const mp_obj_t uuid = mp_obj_new_int(common_hal_bleio_descriptor_get_uuid(self)); - - return bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid); + return common_hal_bleio_descriptor_get_uuid(self); } MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_uuid_obj, bleio_descriptor_get_uuid); diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h index 85310d304f275..bef91061bd58f 100644 --- a/shared-bindings/bleio/Descriptor.h +++ b/shared-bindings/bleio/Descriptor.h @@ -35,6 +35,6 @@ extern const mp_obj_type_t bleio_descriptor_type; extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid); extern void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print); extern mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self); -extern mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); +extern mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 727350215f80b..275a61eeca1c4 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -67,8 +67,8 @@ STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_pr bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "Service("); - common_hal_bleio_uuid_print(print, self->uuid); - mp_print(print, ")"); + common_hal_bleio_uuid_print(self->uuid, print); + mp_printf(print, ")"); } STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { @@ -112,9 +112,10 @@ STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t char bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in); - if (self->uuid->type == UUID_TYPE_128BIT) { - characteristic->uuid->type = UUID_TYPE_128BIT; - characteristic->uuid->uuid_vs_idx = self->uuid->uuid_vs_idx; + if (common_hal_bleio_uuid_get_uuid128_handle(self->uuid) != + common_hal_bleio_uuid_get_uuid128_handle(characteristic->uuid)) { + // The descriptor base UUID doesn't match the characteristic base UUID. + mp_raise_ValueError(translate("Characteristic UUID doesn't match Descriptor UUID")); } characteristic->service = self; diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 33d280304ca4a..a326518e68109 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -27,6 +27,7 @@ */ #include "py/objproperty.h" +#include "py/objstr.h" #include "py/runtime.h" #include "shared-bindings/bleio/UUID.h" @@ -63,6 +64,9 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); + self->base.type = type; + mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); @@ -98,7 +102,7 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si while (str_index >= 1 && uuid128_index < UUID128_BYTE_LEN) { if (str[str_index] == '-') { // Skip hyphen separators. - str--; + str_index--; continue; } @@ -126,6 +130,8 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si } else { mp_raise_ValueError(translate("UUID value is not int or string")); } + // Unreachable. + return mp_const_none; } STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { @@ -138,42 +144,64 @@ STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print //| //| The 16-bit part of the UUID. (read-only) //| -STATIC void bleio_uuid_get_uuid16(mp_obj_t self_in) { +STATIC mp_obj_t bleio_uuid_get_uuid16(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self)); } MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid16_obj, bleio_uuid_get_uuid16); -const mp_obj_property_t bleio_uuid16_obj = { +const mp_obj_property_t bleio_uuid_uuid16_obj = { .base.type = &mp_type_property, .proxy = {(mp_obj_t)&bleio_uuid_get_uuid16_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; -//| .. attribute:: vendor_specific +//| .. attribute:: uuid128_handle +//| +//| An opaque handle representing the 128-bit UUID. (read-only) +//| Returns None if this is a 16-bit UUID. +//| +STATIC mp_obj_t bleio_uuid_get_uuid128_handle(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint32_t handle = common_hal_bleio_uuid_get_uuid128_handle(self); + return handle == 0 ? mp_const_none : MP_OBJ_NEW_SMALL_INT(handle); +} + +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid128_handle_obj, bleio_uuid_get_uuid128_handle); + +const mp_obj_property_t bleio_uuid_uuid128_handle_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_uuid128_handle_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: size //| -//| True if this UUID represents a 128-bit vendor-specific UUID. -//| False if this UUID represents a 16-bit Bluetooth SIG assigned UUID. (read-only) +//| Returns 128 if this UUID represents a 128-bit vendor-specific UUID. +//| Returns 16 if this UUID represents a 16-bit Bluetooth SIG assigned UUID. (read-only) +//| 32-bit UUIDs are not currently supported. //| -STATIC mp_obj_t bleio_uuid_get_vendor_specific(mp_obj_t self_in) { +STATIC mp_obj_t bleio_uuid_get_size(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(common_hal_bleio_uuid_get_vendor_specific(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_size(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_vendor_specific_obj, bleio_uuid_get_vendor_specific); +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_size_obj, bleio_uuid_get_size); -const mp_obj_property_t bleio_uuid_vendor_specific_obj = { +const mp_obj_property_t bleio_uuid_size_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&bleio_uuid_get_vendor_specific_obj, + .proxy = {(mp_obj_t)&bleio_uuid_get_size_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid16_obj) }, - { MP_ROM_QSTR(MP_QSTR_vendor_specific), MP_ROM_PTR(&bleio_uuid_vendor_specific_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid_uuid16_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid128_handle), MP_ROM_PTR(&bleio_uuid_uuid128_handle_obj) }, + { MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&bleio_uuid_size_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table); diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h index e27058516efa1..79810dc973bd3 100644 --- a/shared-bindings/bleio/UUID.h +++ b/shared-bindings/bleio/UUID.h @@ -33,7 +33,8 @@ 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, uint8_t uuid128[]); extern void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print); -extern bool common_hal_bleio_uuid_get_vendor_specific(bleio_uuid_obj_t *self); extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self); +extern uint32_t common_hal_bleio_uuid_get_uuid128_handle(bleio_uuid_obj_t *self); +extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H From 3164b16196e437c544d03059f2475bfed0a15f30 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 26 Nov 2018 21:09:17 -0500 Subject: [PATCH 003/153] WIP: debug; add hash and __eq__ to UUID --- ports/nrf/common-hal/bleio/Descriptor.c | 6 - ports/nrf/common-hal/bleio/Device.c | 10 +- ports/nrf/common-hal/bleio/Service.c | 2 +- ports/nrf/common-hal/bleio/UUID.c | 59 +++++----- ports/nrf/common-hal/bleio/UUID.h | 16 +-- shared-bindings/bleio/Characteristic.c | 2 +- shared-bindings/bleio/Descriptor.c | 4 +- shared-bindings/bleio/Descriptor.h | 1 - shared-bindings/bleio/Service.c | 6 +- shared-bindings/bleio/UUID.c | 149 +++++++++++++++++++----- shared-bindings/bleio/UUID.h | 6 +- 11 files changed, 176 insertions(+), 85 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c index c6b95832c4155..8282be8f2d8a8 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.c +++ b/ports/nrf/common-hal/bleio/Descriptor.c @@ -33,12 +33,6 @@ void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_u self->uuid = uuid; } -void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print) { - mp_printf(print, "Descriptor(uuid="); - common_hal_bleio_uuid_print(self->uuid, print); - mp_printf(print, ", handle=%0x", self->handle); -} - mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) { return self->handle; } diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 10592d65affd9..454f0b602c6d3 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -156,7 +156,7 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta } ble_uuid_t uuid; - bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); + bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid); err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); if (err_code != NRF_SUCCESS) { @@ -188,7 +188,7 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta } ble_uuid_t uuid; - bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); + bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid); err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); if (err_code != NRF_SUCCESS) { @@ -327,7 +327,7 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res service->handle = gattc_service->handle_range.start_handle; bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - bleio_uuid_construct_from_nrf_uuid(uuid, &gattc_service->uuid); + bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); service->uuid = uuid; mp_obj_list_append(device->service_list, service); @@ -352,7 +352,7 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); uuid->base.type = &bleio_uuid_type; - bleio_uuid_construct_from_nrf_uuid(uuid, &gattc_char->uuid); + bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); characteristic->uuid = uuid; characteristic->props.broadcast = gattc_char->char_props.broadcast; @@ -475,7 +475,7 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *device_in) { void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service) { ble_uuid_t uuid; - bleio_uuid_convert_to_nrf_uuid(service->uuid, &uuid); + bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid); uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; if (service->is_secondary) { diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 8ad81c015ee65..5189fb94582f1 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -52,7 +52,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei } ble_uuid_t uuid; - bleio_uuid_convert_to_nrf_uuid(characteristic->uuid, &uuid); + bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &uuid); ble_gatts_attr_md_t attr_md = { .vloc = BLE_GATTS_VLOC_STACK, diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c index 133ffe25bcf71..8aad85ce304de 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -39,55 +39,60 @@ // 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, uint8_t uuid128[]) { - self->uuid16 = uuid16; - self->uuid_vs_idx = 0; - if (uuid128 != NULL) { + common_hal_bleio_adapter_set_enabled(true); + + self->nrf_ble_uuid.uuid = uuid16; + if (uuid128 == NULL) { + self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE; + } else { ble_uuid128_t vs_uuid; memcpy(vs_uuid.uuid128, uuid128, sizeof(vs_uuid.uuid128)); // Register this vendor-specific UUID. Bytes 12 and 13 will be zero. - common_hal_bleio_adapter_set_enabled(true); - const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->uuid_vs_idx); + const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->nrf_ble_uuid.type); if (err_code != NRF_SUCCESS) { mp_raise_OSError_msg(translate("Could not register Vendor-Specific UUID")); } } } -void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print) { - if (self->uuid_vs_idx != 0) { - mp_printf(print, "UUID(uuid16=0x%04x, uuid128_handle=" HEX2_FMT ")", - self->uuid16, self->uuid_vs_idx); - } else { - mp_printf(print, "UUID(0x%04x)", self->uuid16); - } -} - uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) { - return self->uuid_vs_idx != 0 ? 128 : 16; + return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 16 : 128; } uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) { - return self->uuid16; + return self->nrf_ble_uuid.uuid; } -// Returns 0 if there is no handle, otherwise returns a non-zero index. -uint32_t common_hal_bleio_uuid_get_uuid128_handle(bleio_uuid_obj_t *self) { - return self->uuid_vs_idx; +// True if uuid128 has been successfully filled in. +bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) { + uint8_t length; + const uint32_t err_code = sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128); + + if (err_code != NRF_SUCCESS) { + mp_raise_RuntimeError(translate("Could not decode ble_uuid")); + } + // If not 16 bytes, this is not a 128-bit UUID, so return. + return length == 16; } +// Returns 0 if this is a 16-bit UUID, otherwise returns a non-zero index +// into the 128-bit uuid registration table. +uint32_t common_hal_bleio_uuid_get_uuid128_reference(bleio_uuid_obj_t *self) { + return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 0 : self->nrf_ble_uuid.type; +} -void bleio_uuid_construct_from_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid) { - if (nrf_uuid->type == BLE_UUID_TYPE_UNKNOWN) { + +void bleio_uuid_construct_from_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_ble_uuid) { + if (nrf_ble_uuid->type == BLE_UUID_TYPE_UNKNOWN) { mp_raise_RuntimeError(translate("Unexpected nrfx uuid type")); } - - self->uuid16 = nrf_uuid->uuid; - self->uuid_vs_idx = nrf_uuid->type == BLE_UUID_TYPE_BLE ? 0 : nrf_uuid->type; + self->nrf_ble_uuid.uuid = nrf_ble_uuid->uuid; + self->nrf_ble_uuid.type = nrf_ble_uuid->type; } // Fill in a ble_uuid_t from my values. -void bleio_uuid_convert_to_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid) { - nrf_uuid->uuid = self->uuid16; - nrf_uuid->type = self->uuid_vs_idx == 0 ? BLE_UUID_TYPE_BLE : self->uuid_vs_idx; +void bleio_uuid_convert_to_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_ble_uuid) { + nrf_ble_uuid->uuid = self->nrf_ble_uuid.uuid; + nrf_ble_uuid->type = self->nrf_ble_uuid.type; } diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/bleio/UUID.h index f0d32ede28875..b464093ea1848 100644 --- a/ports/nrf/common-hal/bleio/UUID.h +++ b/ports/nrf/common-hal/bleio/UUID.h @@ -34,15 +34,15 @@ typedef struct { mp_obj_base_t base; - // If non-zero, `uuid_vs_idx` is an index into the SoftDevice's table of registered vendor-specific UUID's. - // If zero, `value` is a 16-bit Bluetooth SIG UUID, which would convert to this 128-bit UUID. - // 0000xxxx-0000-1000-8000-00805F9B34FB - uint8_t uuid_vs_idx; - // The 16-bit part of the UUID. This replaces bytes 12 and 13 in the registered 128-bit UUID. - uint16_t uuid16; + // Use the native way of storing UUID's: + // - ble_uuid_t.uuid is a 16-bit uuid. + // - ble_uuid_t.type is BLE_UUID_TYPE_BLE if it's a 16-bit Bluetooth SIG UUID. + // or is BLE_UUID_TYPE_VENDOR_BEGIN and higher, which indexes into a table of registered + // 128-bit UUIDs. + ble_uuid_t nrf_ble_uuid; } bleio_uuid_obj_t; -void bleio_uuid_construct_from_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); -void bleio_uuid_convert_to_nrf_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); +void bleio_uuid_construct_from_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); +void bleio_uuid_convert_to_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 4b4a4a924598f..68d70700f5de1 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -91,7 +91,7 @@ STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "Characteristic("); - common_hal_bleio_uuid_print(self->uuid, print); + bleio_uuid_print(print, self->uuid, kind); mp_printf(print, ")"); } diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index d58bbd27562dd..3d6423314f972 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -101,7 +101,9 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_bleio_descriptor_print(self, print); + mp_printf(print, "Descriptor(uuid="); + bleio_uuid_print(print, self->uuid, kind); + mp_printf(print, ", handle=%04x", common_hal_bleio_descriptor_get_handle(self)); } STATIC mp_obj_t bleio_descriptor_get_handle(mp_obj_t self_in) { diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h index bef91061bd58f..f47378ee16f36 100644 --- a/shared-bindings/bleio/Descriptor.h +++ b/shared-bindings/bleio/Descriptor.h @@ -33,7 +33,6 @@ extern const mp_obj_type_t bleio_descriptor_type; extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid); -extern void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print); extern mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self); extern mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 275a61eeca1c4..0326d6ba71b3c 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -67,7 +67,7 @@ STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_pr bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "Service("); - common_hal_bleio_uuid_print(self->uuid, print); + bleio_uuid_print(print, self->uuid, kind); mp_printf(print, ")"); } @@ -112,8 +112,8 @@ STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t char bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in); - if (common_hal_bleio_uuid_get_uuid128_handle(self->uuid) != - common_hal_bleio_uuid_get_uuid128_handle(characteristic->uuid)) { + if (common_hal_bleio_uuid_get_uuid128_reference(self->uuid) != + common_hal_bleio_uuid_get_uuid128_reference(characteristic->uuid)) { // The descriptor base UUID doesn't match the characteristic base UUID. mp_raise_ValueError(translate("Characteristic UUID doesn't match Descriptor UUID")); } diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index a326518e68109..472014a4c5ecb 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -34,7 +34,7 @@ // Including hyphens. #define UUID128_STR_LEN 36 // Number of bytes -#define UUID128_BYTE_LEN 32 +#define UUID128_BYTE_LEN 16 STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4); @@ -43,13 +43,13 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { //| .. currentmodule:: bleio //| -//| :class:`UUID16` -- BLE UUID16 +//| :class:`UUID` -- BLE UUID //| ========================================================= //| //| A 16-bit or 128-bit UUID. Can be used for services, characteristics, descriptors and more. //| -//| .. class:: UUID(uuid) +//| .. class:: UUID(value, *, base_uuid=None) //| //| Create a new UUID or UUID object encapsulating the uuid value. //| The value can be one of: @@ -57,8 +57,9 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { //| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID) //| - a `str` value in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', where the X's are hex digits. //| (128 bit UUID) +//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID) //| -//| :param int/str uuid: The uuid to encapsulate +//| :param int/str/buffer value: The uuid value to encapsulate //| STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { @@ -70,31 +71,45 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_uuid }; + enum { ARG_value, ARG_base_uuid }; static const mp_arg_t allowed_args[] = { - { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_base_uuid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; 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); - const mp_obj_t uuid = args[ARG_uuid].u_obj; + const mp_obj_t value = args[ARG_value].u_obj; + const mp_obj_t base_uuid = args[ARG_base_uuid].u_obj; + uint8_t uuid128[16]; - if (MP_OBJ_IS_INT(uuid)) { - mp_int_t uuid16 = mp_obj_get_int(uuid); + if (base_uuid != mp_const_none) { + if (MP_OBJ_IS_TYPE(base_uuid, &bleio_uuid_type)) { + if (!common_hal_bleio_uuid_get_uuid128(base_uuid, uuid128)) { + mp_raise_ValueError(translate("base_uuid is not 128 bits")); + } + } else { + mp_raise_ValueError(translate("base_uuid is not a UUID")); + } + } + + if (MP_OBJ_IS_INT(value)) { + mp_int_t uuid16 = mp_obj_get_int(value); if (uuid16 < 0 || uuid16 > 0xffff) { - mp_raise_ValueError(translate("Integer UUID not in range 0 to 0xffff")); + mp_raise_ValueError(translate("UUID integer value not in range 0 to 0xffff")); } - // This is a 16-bit Bluetooth SIG UUID. NULL means no 128-bit value. - common_hal_bleio_uuid_construct(self, uuid16, NULL); + // If a base_uuid was supplied, merge the uuid16 into it. Otherwise + // it's a 16-bit Bluetooth SIG UUID. NULL means no 128-bit value. + common_hal_bleio_uuid_construct(self, uuid16, base_uuid == mp_const_none ? NULL : uuid128); - } else if (MP_OBJ_IS_STR(uuid)) { + } else if (MP_OBJ_IS_STR(value)) { uint8_t uuid128[UUID128_BYTE_LEN]; - GET_STR_DATA_LEN(uuid, str, str_len); + GET_STR_DATA_LEN(value, str, str_len); if (str_len == UUID128_STR_LEN && str[8] == '-' && str[13] == '-' && str[18] == '-' && str[23] == '-') { - size_t str_index = UUID128_STR_LEN - 1; + int str_index = UUID128_STR_LEN - 1; size_t uuid128_index = 0; bool error = false; @@ -123,21 +138,27 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si uuid128[12] = 0; uuid128[13] = 0; common_hal_bleio_uuid_construct(self, uuid16, uuid128); - return MP_OBJ_FROM_PTR(self); + } else { + mp_raise_ValueError(translate("UUID string must be of the form xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); } } - mp_raise_ValueError(translate("UUID string must be of the form xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); } else { mp_raise_ValueError(translate("UUID value is not int or string")); } - // Unreachable. - return mp_const_none; + + return MP_OBJ_FROM_PTR(self); } -STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { +void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_bleio_uuid_print(self, print); + if (common_hal_bleio_uuid_get_size(self) == 128) { + mp_printf(print, "UUID(uuid16=0x%04x, uuid128_reference=0x%02x)", + common_hal_bleio_uuid_get_uuid16(self), + common_hal_bleio_uuid_get_uuid128_reference(self)); + } else { + mp_printf(print, "UUID(0x%04x)", common_hal_bleio_uuid_get_uuid16(self)); + } } //| .. attribute:: uuid16 @@ -158,22 +179,46 @@ const mp_obj_property_t bleio_uuid_uuid16_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| .. attribute:: uuid128_handle +//| .. attribute:: uuid128 +//| +//| The 128-bit value of the UUID, return as a bytes(). +//| Throws AttributeError if this is a 16-bit UUID. (read-only) //| -//| An opaque handle representing the 128-bit UUID. (read-only) +STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + + uint8_t uuid128[16]; + if (!common_hal_bleio_uuid_get_uuid128(self, uuid128)) { + mp_raise_AttributeError(translate("not a 128-bit UUID")); + } + return mp_obj_new_bytes(uuid128, 16); +} + +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid128_obj, bleio_uuid_get_uuid128); + +const mp_obj_property_t bleio_uuid_uuid128_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_uuid128_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: uuid128_reference +//| +//| An opaque reference representing the 128-bit UUID. (read-only) //| Returns None if this is a 16-bit UUID. //| -STATIC mp_obj_t bleio_uuid_get_uuid128_handle(mp_obj_t self_in) { +STATIC mp_obj_t bleio_uuid_get_uuid128_reference(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint32_t handle = common_hal_bleio_uuid_get_uuid128_handle(self); - return handle == 0 ? mp_const_none : MP_OBJ_NEW_SMALL_INT(handle); + uint32_t reference = common_hal_bleio_uuid_get_uuid128_reference(self); + return reference == 0 ? mp_const_none : MP_OBJ_NEW_SMALL_INT(reference); } -MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid128_handle_obj, bleio_uuid_get_uuid128_handle); +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid128_reference_obj, bleio_uuid_get_uuid128_reference); -const mp_obj_property_t bleio_uuid_uuid128_handle_obj = { +const mp_obj_property_t bleio_uuid_uuid128_reference_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&bleio_uuid_get_uuid128_handle_obj, + .proxy = {(mp_obj_t)&bleio_uuid_get_uuid128_reference_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; @@ -200,16 +245,60 @@ const mp_obj_property_t bleio_uuid_size_obj = { STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid_uuid16_obj) }, - { MP_ROM_QSTR(MP_QSTR_uuid128_handle), MP_ROM_PTR(&bleio_uuid_uuid128_handle_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid128), MP_ROM_PTR(&bleio_uuid_uuid128_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid128_reference), MP_ROM_PTR(&bleio_uuid_uuid128_reference_obj) }, { MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&bleio_uuid_size_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table); +STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + switch (op) { + case MP_UNARY_OP_HASH: + if (common_hal_bleio_uuid_get_size(self) == 16) { + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self)); + } else { + union { + uint8_t uuid128_bytes[16]; + uint16_t uuid128_uint16[8]; + } uuid128; + common_hal_bleio_uuid_get_uuid128(self, uuid128.uuid128_bytes); + int hash = 0; + for (size_t i = 0; i < MP_ARRAY_SIZE(uuid128.uuid128_uint16); i++) { + hash += uuid128.uuid128_uint16[i]; + } + return MP_OBJ_NEW_SMALL_INT(hash); + } + default: + return MP_OBJ_NULL; // op not supported + } +} + +STATIC mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + switch (op) { + // Two UUID's are equal if their uuid16 values and uuid128 references match. + case MP_BINARY_OP_EQUAL: + if (MP_OBJ_IS_TYPE(rhs_in, &bleio_uuid_type)) { + return mp_obj_new_bool( + common_hal_bleio_uuid_get_uuid16(lhs_in) == common_hal_bleio_uuid_get_uuid16(rhs_in) && + common_hal_bleio_uuid_get_uuid128_reference(lhs_in) == + common_hal_bleio_uuid_get_uuid128_reference(rhs_in)); + } else { + return mp_const_false; + } + + default: + return MP_OBJ_NULL; // op not supported + } +} + const mp_obj_type_t bleio_uuid_type = { { &mp_type_type }, .name = MP_QSTR_UUID, .print = bleio_uuid_print, .make_new = bleio_uuid_make_new, + .unary_op = bleio_uuid_unary_op, + .binary_op = bleio_uuid_binary_op, .locals_dict = (mp_obj_dict_t*)&bleio_uuid_locals_dict, }; diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h index 79810dc973bd3..aef2c1e29ebb7 100644 --- a/shared-bindings/bleio/UUID.h +++ b/shared-bindings/bleio/UUID.h @@ -29,12 +29,14 @@ #include "common-hal/bleio/UUID.h" +void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); + 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, uint8_t uuid128[]); -extern void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print); extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self); -extern uint32_t common_hal_bleio_uuid_get_uuid128_handle(bleio_uuid_obj_t *self); +extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]); +extern uint32_t common_hal_bleio_uuid_get_uuid128_reference(bleio_uuid_obj_t *self); extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H From f67814fc97d0846d570876f0e1bf79745873d56d Mon Sep 17 00:00:00 2001 From: jimblom Date: Fri, 30 Nov 2018 13:57:22 -0700 Subject: [PATCH 004/153] Adding SparkFun nRF52840 Mini board support. --- .../boards/sparkfun_nrf52840_mini/README.md | 48 +++++++ .../nrf/boards/sparkfun_nrf52840_mini/board.c | 38 ++++++ .../sparkfun_nrf52840_mini/mpconfigboard.h | 68 ++++++++++ .../sparkfun_nrf52840_mini/mpconfigboard.mk | 25 ++++ .../nrf/boards/sparkfun_nrf52840_mini/pins.c | 117 ++++++++++++++++++ 5 files changed, 296 insertions(+) create mode 100644 ports/nrf/boards/sparkfun_nrf52840_mini/README.md create mode 100644 ports/nrf/boards/sparkfun_nrf52840_mini/board.c create mode 100644 ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h create mode 100644 ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk create mode 100644 ports/nrf/boards/sparkfun_nrf52840_mini/pins.c diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/README.md b/ports/nrf/boards/sparkfun_nrf52840_mini/README.md new file mode 100644 index 0000000000000..f80f1c27ca602 --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/README.md @@ -0,0 +1,48 @@ +# SparkFun Pro nRF52840 Mini Breakout + +The [SparkFun Pro nRF52840 Mini](https://www.sparkfun.com/products/15025) small breakout board for Raytac's MDBT50Q-P1M module, which features an nRF52840. It breaks out as many pins as it can in an Arduino Pro Mini footprint. Also included on the board are a qwiic (I2C) connector, LiPo battery charger, and on/off switch. + +Note: the SparkFun Pro nRF52840 Mini Breakout does not include a QSPI external flash. Any Python code will need to be stored on the internal flash filesystem. + +## CircuitPython Pin Defs + +CircuitPython pin definitions try to follow those of the [Arduino Pro Mini](https://www.sparkfun.com/products/11113), which the footprint is based on. + +This can be somewhat confusing, especially around the analog pins. Here's a quick pin-map: + + + + + + + + + + + + + + + + + + + + + + +
Board pin labelDigital Pin ReferenceAdditional Pin CapabilitiesPin/Port Reference
17D1TXP0_17
15D0RXP0_15
8SDAP0_08
11SCLP0_11
19D3P0_19
20D4P0_20
21D5P0_21
22D6P0_22
23D7P0_23
9D8P0_09
10D9P0_10
2D10A0P0_02
3D11MOSI, A1P0_03
31D12MISO, A7P0_31
30D13SCK, A6P0_31
29A5P0_29
28A4P0_28
5A3P0_05
4A2P0_04
+ +If a pin isn't defined as D0, D1, etc., standard port/pin references should work -- e.g. `P0_17` is pin 17, `P0_02` is pin 2, etc. + +## Bootloader Notes + +The nRF52840 Mini ships with a slightly modified (i.e pin defs and USB defs) version of the Adafruit nRF52 bootloader, which supports UF2 and CDC bootloading. + +## Hardware Reference + +The nRF52840 Mini hardware layout is open source: + +* [Schematic](https://cdn.sparkfun.com/assets/learn_tutorials/8/2/0/nrf52840-breakout-mdbt50q-v10.pdf) +* [Eagle Files](https://cdn.sparkfun.com/assets/learn_tutorials/8/2/0/nrf52840-breakout-mdbt50q-v10.zip) +* [Hookup Guide](https://learn.sparkfun.com/tutorials/sparkfun-pro-nrf52840-mini-hookup-guide) \ No newline at end of file diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/board.c b/ports/nrf/boards/sparkfun_nrf52840_mini/board.c new file mode 100644 index 0000000000000..4421970eefe4d --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 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" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h new file mode 100644 index 0000000000000..353a0ad8fd3d4 --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h @@ -0,0 +1,68 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "SparkFun Pro nRF52840 Mini" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "SFE_NRF52840_Mini" + +#define PORT_HEAP_SIZE (128 * 1024) +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_11) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_08) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_30) +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_03) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_31) + +#define DEFAULT_UART_BUS_RX (&pin_P0_15) +#define DEFAULT_UART_BUS_TX (&pin_P0_17) + +/* Note: Flash chip is not provided on SparkFun nRF52840 Mini. + * Leaving this as a reminder for future/similar versions of the board. */ +// Flash operation mode is determined by MICROPY_QSPI_DATAn pin configuration. +// A pin config is valid if it is defined and its value is not 0xFF. +// Quad mode: If all DATA0 --> DATA3 are valid +// Dual mode: If DATA0 and DATA1 are valid while either DATA2 and/or DATA3 are invalid +// Single mode: If only DATA0 is valid +/*#ifdef QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 17) +#endif + +#ifdef SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_20 +#define SPI_FLASH_MISO_PIN &pin_P0_21 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_17 +#endif*/ + diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk new file mode 100644 index 0000000000000..d4819c855bbd0 --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk @@ -0,0 +1,25 @@ +USB_VID = 0x1B4F +USB_PID = 0x5289 +USB_PRODUCT = "SFE_nRF52840_Mini" +USB_MANUFACTURER = "SparkFun Electronics" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 0 +EXTERNAL_FLASH_DEVICE_COUNT = 0 +EXTERNAL_FLASH_DEVICES = diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c new file mode 100644 index 0000000000000..2ea80389d4b29 --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c @@ -0,0 +1,117 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, + { MP_ROM_QSTR(MP_QSTR_P0_01), MP_ROM_PTR(&pin_P0_01) }, + + { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, + + { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_03) }, + + { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, + + { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, + + { MP_ROM_QSTR(MP_QSTR_P0_07), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_07) }, + + { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, + + { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_09) }, + + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, + + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_P0_13) }, + + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, + + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_17) }, + + // RESET { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, + + { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_19) }, + + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P0_20) }, + + { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_21) }, + + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_22) }, + + { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_23) }, + + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, + + { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_28) }, + + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, + + { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_30) }, + + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_31) }, + + // Nothing connected to anything on P1 port + { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From 09316b35d7b838d735d76639cca462c088d3d18d Mon Sep 17 00:00:00 2001 From: jimblom Date: Fri, 30 Nov 2018 14:58:36 -0700 Subject: [PATCH 005/153] remove non-broken-out nrf pins. re-organize pins.c list. --- .../nrf/boards/sparkfun_nrf52840_mini/pins.c | 149 +++++------------- 1 file changed, 42 insertions(+), 107 deletions(-) diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c index 2ea80389d4b29..210b1703260b5 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c @@ -3,113 +3,48 @@ #include "board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, - { MP_ROM_QSTR(MP_QSTR_P0_01), MP_ROM_PTR(&pin_P0_01) }, - - { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, - { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_02) }, - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, - - { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_03) }, - - { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, - - { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_05) }, - - { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, - - { MP_ROM_QSTR(MP_QSTR_P0_07), MP_ROM_PTR(&pin_P0_07) }, - { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_07) }, - - { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, - - { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_09) }, - - { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_10) }, - - { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, - - { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, - - { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, - { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_P0_13) }, - - { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, - - { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_15) }, - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P1_15) }, - - { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, - - { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_17) }, - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_17) }, - - // RESET { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, - - { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_19) }, - - { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, - { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P0_20) }, - - { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_21) }, - - { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_22) }, - - { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, - { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_23) }, - - { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, - { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, - { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, - { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, - - { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_28) }, - - { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, - - { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_30) }, - - { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_31) }, - - // Nothing connected to anything on P1 port - { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, - { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, - { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, - { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, - { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, - { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, - { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, - { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, - { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, - { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, - { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, - { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, - { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, - { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, - { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, - { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P1_15) }, // D1/TX + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_17) }, // D0/RX + // D2 on qwiic gap + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_19) }, // D3 + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P0_20) }, // D4 + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_21) }, // D5 + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_22) }, // D6 + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_23) }, // D7 + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_09) }, // D8 + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_10) }, // D9 + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_02) }, // D10 + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_03) }, // D11 + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_31) }, // D12 + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_30) }, // D13 + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_P0_29) }, // D14 + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_P0_28) }, // D15 + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_P0_05) }, // D16 + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_P0_04) }, // D17 + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, // A0 + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, // A1 + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, // A2 + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_05) }, // A3 + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_28) }, // A4 + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, // A5 + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, // A6 + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, // A7 + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, // 8 - SDA + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, // 11 - SCL + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_31) }, // 31 - MISO + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_03) }, // 3 - MOSI + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_30) }, // 30 - SCK + + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_07) }, // 7 - Blue LED + + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_P0_13) }, // 13 - Button + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_15) }, // 15 - UART RX + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_17) }, // 17 - UART TX { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; From 3d597aae92069e2f1057163143e928f2981f3d65 Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Sun, 2 Dec 2018 18:07:19 -0600 Subject: [PATCH 006/153] Added MKR Zero board definition. --- README.rst | 4 +- ports/atmel-samd/README.rst | 91 ++++++++++--------- .../atmel-samd/boards/arduino_mkrzero/board.c | 40 ++++++++ .../boards/arduino_mkrzero/mpconfigboard.h | 24 +++++ .../boards/arduino_mkrzero/mpconfigboard.mk | 11 +++ .../atmel-samd/boards/arduino_mkrzero/pins.c | 46 ++++++++++ 6 files changed, 172 insertions(+), 44 deletions(-) create mode 100644 ports/atmel-samd/boards/arduino_mkrzero/board.c create mode 100644 ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/arduino_mkrzero/pins.c diff --git a/README.rst b/README.rst index 138dbfea79d25..76c7315dc4851 100644 --- a/README.rst +++ b/README.rst @@ -60,13 +60,13 @@ Other supported using the `Adafruit CircuitPython SD library `__) - `Arduino Zero `__ +- `Arduino MKR Zero ` "Third-party" or "non-Adafruit" boards ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - `Electronic Cats Meow Meow `__ -- `Electronic Cats CatWAN USB Stick `__ - +- `Electronic Cats CatWAN USB Stick ` Download -------- diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 0c1026644d7ca..649a142e1d9ee 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -2,9 +2,16 @@ SAMD21x18 ========= This port brings MicroPython to SAMD21x18 based development boards under the name -CircuitPython. Supported boards include the Adafruit CircuitPlayground Express, -Adafruit Feather M0 Express, Adafruit Metro M0 Express, Arduino Zero, Adafruit -Feather M0 Basic and Adafruit M0 Bluefruit LE. +CircuitPython. Supported boards include: + +- Adafruit CircuitPlayground Express +- Adafruit Feather M0 Basic +- Adafruit Feather M0 Express +- Adafruit Metro M0 Express +- Adafruit M0 Bluefruit LE +- Arduino Zero +- Arduino MKR Zero + Pinout ------ @@ -15,51 +22,51 @@ different names. The table below matches the pin order in and omits the pins only available on the largest package because all supported boards use smaller version. -===================== =============== =========================== ====================== ================ ================== ========================= ================ ================ +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ `microcontroller.pin` `board` ---------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -Datasheet arduino_zero circuitplayground_express feather_m0_adalogger feather_m0_basic feather_m0_express gemma_m0 metro_m0_express trinket_m0 -===================== =============== =========================== ====================== ================ ================== ========================= ================ ================ -PA00 ``ACCELEROMETER_SDA`` ``APA102_MOSI`` ``APA102_MOSI`` -PA01 ``ACCELEROMETER_SCL`` ``APA102_SCK`` ``APA102_SCK`` -PA02 ``A0`` ``A0`` / ``SPEAKER`` ``A0`` ``A0`` ``A0`` ``A0`` / ``D1`` ``A0`` ``D1`` / ``A0`` +--------------------- ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Datasheet arduino_mkrzero arduino_zero circuitplayground_express feather_m0_adalogger feather_m0_basic feather_m0_express gemma_m0 metro_m0_express trinket_m0 +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ +PA00 ``ACCELEROMETER_SDA`` ``APA102_MOSI`` ``APA102_MOSI`` +PA01 ``ACCELEROMETER_SCL`` ``APA102_SCK`` ``APA102_SCK`` +PA02 ``A0`` ``A0`` ``A0`` / ``SPEAKER`` ``A0`` ``A0`` ``A0`` ``A0`` / ``D1`` ``A0`` ``D1`` / ``A0`` PA03 -PB08 ``A1`` ``A7`` / ``TX`` ``A1`` ``A1`` ``A1`` ``A1`` -PB09 ``A2`` ``A6`` / ``RX`` ``A2`` ``A2`` ``A2`` ``A2`` -PA04 ``A3`` ``IR_PROXIMITY`` ``A3`` ``A3`` ``A3`` ``D0`` / ``TX`` / ``SDA`` ``A3`` -PA05 ``A4`` ``A1`` ``A4`` ``A4`` ``A4`` ``D2`` / ``RX`` / ``SCL`` ``A4`` -PA06 ``D8`` ``A2`` ``D8`` / ``GREEN_LED`` ``NEOPIXEL`` ``D8`` ``D4`` / ``TX`` -PA07 ``D9`` ``A3`` ``D9`` ``D9`` ``D9`` ``D9`` ``D3`` / ``RX`` -PA08 ``D4`` ``MICROPHONE_DO`` ``D4`` / ``SD_CS`` ``D4`` ``D0`` / ``SDA`` -PA09 ``D3`` ``TEMPERATURE`` / ``A9`` ``D3`` ``D2`` / ``SCL`` -PA10 ``D1`` / ``TX`` ``MICROPHONE_SCK`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D13`` -PA11 ``D0`` / ``RX`` ``LIGHT`` / ``A8`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` -PB10 ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` -PB11 ``SCK`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` -PA12 ``MISO`` ``REMOTEIN`` / ``IR_RX`` ``MISO`` ``MISO`` ``MISO`` ``MISO`` -PA13 ``ACCELEROMETER_INTERRUPT`` ``FLASH_CS`` -PA14 ``D2`` ``BUTTON_B`` / ``D5`` ``D2`` -PA15 ``D5`` ``SLIDE_SWITCH`` / ``D7`` ``D5`` ``D5`` ``D5`` ``D5`` -PA16 ``D11`` ``MISO`` ``D11`` ``D11`` ``D11`` ``D11`` -PA17 ``D13`` ``D13`` ``D13`` / ``RED_LED`` ``D13`` ``D13`` ``D13`` -PA18 ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` -PA19 ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` -PA20 ``D6`` ``MOSI`` ``D6`` ``D6`` ``D6`` ``D6`` -PA21 ``D7`` ``SCK`` ``D7`` / ``SD_CD`` ``D7`` -PA22 ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` -PA23 ``SCL`` ``REMOTEOUT`` / ``IR_TX`` ``SCL`` ``SCL`` ``SCL`` ``L`` / ``D13`` ``SCL`` +PB08 ``L`` ``A1`` ``A7`` / ``TX`` ``A1`` ``A1`` ``A1`` ``A1`` +PB09 ``BATTERY`` ``A2`` ``A6`` / ``RX`` ``A2`` ``A2`` ``A2`` ``A2`` +PA04 ``A3`` ``A3`` ``IR_PROXIMITY`` ``A3`` ``A3`` ``A3`` ``D0`` / ``TX`` / ``SDA`` ``A3`` +PA05 ``A4`` ``A4`` ``A1`` ``A4`` ``A4`` ``A4`` ``D2`` / ``RX`` / ``SCL`` ``A4`` +PA06 ``A5`` ``D8`` ``A2`` ``D8`` / ``GREEN_LED`` ``NEOPIXEL`` ``D8`` ``D4`` / ``TX`` +PA07 ``A6`` ``D9`` ``A3`` ``D9`` ``D9`` ``D9`` ``D9`` ``D3`` / ``RX`` +PA08 ``D11`` / ``SDA`` ``D4`` ``MICROPHONE_DO`` ``D4`` / ``SD_CS`` ``D4`` ``D0`` / ``SDA`` +PA09 ``D12`` / ``SCL`` ``D3`` ``TEMPERATURE`` / ``A9`` ``D3`` ``D2`` / ``SCL`` +PA10 ``D2`` ``D1`` / ``TX`` ``MICROPHONE_SCK`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D13`` +PA11 ``D3`` ``D0`` / ``RX`` ``LIGHT`` / ``A8`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` +PB10 ``D4`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` +PB11 ``D5`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` +PA12 ``SD_MOSI`` ``MISO`` ``REMOTEIN`` / ``IR_RX`` ``MISO`` ``MISO`` ``MISO`` ``MISO`` +PA13 ``SD_SCK`` ``ACCELEROMETER_INTERRUPT`` ``FLASH_CS`` +PA14 ``SD_CS`` ``D2`` ``BUTTON_B`` / ``D5`` ``D2`` +PA15 ``SD_MISO`` ``D5`` ``SLIDE_SWITCH`` / ``D7`` ``D5`` ``D5`` ``D5`` ``D5`` +PA16 ``D8`` / ``MOSI`` ``D11`` ``MISO`` ``D11`` ``D11`` ``D11`` ``D11`` +PA17 ``D9`` / ``SCK`` ``D13`` ``D13`` ``D13`` / ``RED_LED`` ``D13`` ``D13`` ``D13`` +PA18 ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` +PA19 ``D10`` / ``MISO`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` +PA20 ``D6`` ``D6`` ``MOSI`` ``D6`` ``D6`` ``D6`` ``D6`` +PA21 ``D7`` ``D7`` ``SCK`` ``D7`` / ``SD_CD`` ``D7`` +PA22 ``D0`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` +PA23 ``D1`` ``SCL`` ``REMOTEOUT`` / ``IR_TX`` ``SCL`` ``SCL`` ``SCL`` ``L`` / ``D13`` ``SCL`` PA24 PA25 -PB22 ``FLASH_CS`` -PB23 ``NEOPIXEL`` / ``D8`` -PA27 -PA28 ``BUTTON_A`` / ``D4`` +PB22 ``D14`` / ``TX`` ``FLASH_CS`` +PB23 ``D13`` / ``RX`` ``NEOPIXEL`` / ``D8`` +PA27 ``SD_CD`` +PA28 ``BUTTON_A`` / ``D4`` PA29 -PA30 ``SPEAKER_ENABLE`` ``NEOPIXEL`` +PA30 ``SPEAKER_ENABLE`` ``NEOPIXEL`` PA31 -PB02 ``A5`` ``A5`` / ``SDA`` ``A5`` ``A5`` ``A5`` ``A5`` -PB03 ``A4`` / ``SCL`` -===================== =============== =========================== ====================== ================ ================== ========================= ================ ================ +PB02 ``A1`` ``A5`` ``A5`` / ``SDA`` ``A5`` ``A5`` ``A5`` ``A5`` +PB03 ``A2`` ``A4`` / ``SCL`` +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ Here is a table about which pins can do what in CircuitPython terms. However, just because something is listed, doesn't mean it will always work. Existing use diff --git a/ports/atmel-samd/boards/arduino_mkrzero/board.c b/ports/atmel-samd/boards/arduino_mkrzero/board.c new file mode 100644 index 0000000000000..770bc825938cd --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkrzero/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 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 "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/arduino_mkrzero/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.h new file mode 100644 index 0000000000000..d98da4d1491f5 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.h @@ -0,0 +1,24 @@ +#define MICROPY_HW_BOARD_NAME "Arduino MKR Zero" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA19) + +#define DEFAULT_UART_BUS_RX (&pin_PB23) +#define DEFAULT_UART_BUS_TX (&pin_PB22) + +// 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/arduino_mkrzero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk new file mode 100644 index 0000000000000..3093512891911 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk @@ -0,0 +1,11 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x8035 +USB_PRODUCT = "Arduino MKRZero" +USB_MANUFACTURER = "Arduino" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/arduino_mkrzero/pins.c b/ports/atmel-samd/boards/arduino_mkrzero/pins.c new file mode 100644 index 0000000000000..e06400f35c75c --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkrzero/pins.c @@ -0,0 +1,46 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB09) }, + { 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); From a7a24096f469b1ee95242d4e7f58929cad3699ed Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 7 Dec 2018 16:52:47 -0500 Subject: [PATCH 007/153] bleio WIP: redo for more immutability; use sd_* routines for internal flash write --- ports/nrf/common-hal/bleio/Characteristic.c | 2 +- ports/nrf/common-hal/bleio/Device.c | 2 +- ports/nrf/common-hal/bleio/Service.c | 2 +- ports/nrf/supervisor/internal_flash.c | 44 ++++- shared-bindings/bleio/Characteristic.c | 191 ++++++++------------ shared-bindings/bleio/Service.c | 88 ++++----- shared-module/bleio/Characteristic.h | 2 +- 7 files changed, 153 insertions(+), 178 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 002d145c7a506..5a0025d1c0170 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -107,7 +107,7 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in .len = bufinfo->len, }; - if (characteristic->props.write_wo_resp) { + if (characteristic->props.write_no_response) { write_params.write_op = BLE_GATT_OP_WRITE_CMD; err_code = sd_mutex_acquire(m_write_mutex); diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 454f0b602c6d3..50c738abeea04 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -360,7 +360,7 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio characteristic->props.notify = gattc_char->char_props.notify; characteristic->props.read = gattc_char->char_props.read; characteristic->props.write = gattc_char->char_props.write; - characteristic->props.write_wo_resp = gattc_char->char_props.write_wo_resp; + characteristic->props.write_no_response = gattc_char->char_props.write_wo_resp; characteristic->handle = gattc_char->handle_value; characteristic->service = m_char_discovery_service; diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 5189fb94582f1..29d96e8277efa 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -34,7 +34,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei ble_gatts_char_md_t char_md = { .char_props.broadcast = characteristic->props.broadcast, .char_props.read = characteristic->props.read, - .char_props.write_wo_resp = characteristic->props.write_wo_resp, + .char_props.write_wo_resp = characteristic->props.write_no_response, .char_props.write = characteristic->props.write, .char_props.notify = characteristic->props.notify, .char_props.indicate = characteristic->props.indicate, diff --git a/ports/nrf/supervisor/internal_flash.c b/ports/nrf/supervisor/internal_flash.c index a648afa173353..ad7a8d0815494 100644 --- a/ports/nrf/supervisor/internal_flash.c +++ b/ports/nrf/supervisor/internal_flash.c @@ -70,16 +70,52 @@ uint32_t supervisor_flash_get_block_count(void) { return ((uint32_t) __fatfs_flash_length) / FILESYSTEM_BLOCK_SIZE ; } -// TODO support flashing with SD enabled +#ifdef BLUETOOTH_SD +STATIC bool wait_for_flash_operation() { + do { + sd_app_evt_wait(); + uint32 evt_id; + uint32_t result = sd_evt_get(&evt_id); + if (result == NRF_SUCCESS) { + switch (evt_id) { + case NRF_EVT_FLASH_OPERATION_SUCCESS: + return true; + + case NRF_EVT_FLASH_OPERATION_ERROR: + return false; + + default: + // Some other event. Wait for a flash event. + continue; + } + } + return false; + } while (true); +} +#endif + void supervisor_flash_flush(void) { if (_flash_page_addr == NO_CACHE) return; // Skip if data is the same if (memcmp(_flash_cache, (void *)_flash_page_addr, FL_PAGE_SZ) != 0) { -// _is_flashing = true; + +#ifdef BLUETOOTH_SD + uint8_t sd_en = 0; + (void) sd_softdevice_is_enabled(&sd_en); + + if (sd_en) { + sd_flash_page_erase(_flash_page_addr / FL_PAGE_SZ); + wait_for_flash_operation(); // TODO: handle error return. + sd_flash_write(_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t)); + wait_for_flash_operation(); + } else { +#endif nrf_nvmc_page_erase(_flash_page_addr); nrf_nvmc_write_words(_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t)); +#ifdef BLUETOOTH_SD } +#endif _flash_page_addr = NO_CACHE; } @@ -101,10 +137,6 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32 if (page_addr != _flash_page_addr) { supervisor_flash_flush(); - // writing previous cached data, skip current data until flashing is done - // tinyusb stack will invoke write_block() with the same parameters later on - // if ( _is_flashing ) return; - _flash_page_addr = page_addr; memcpy(_flash_cache, (void *)page_addr, FL_PAGE_SZ); } diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 68d70700f5de1..4fb71de4704a3 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -38,63 +38,13 @@ //| Stores information about a BLE service characteristic and allows to read //| and write the characteristic's value. //| - -//| .. class:: Characteristic(uuid) -//| -//| Create a new Characteristic object identified by the specified UUID. -//| -//| :param bleio.UUID uuid: The uuid of the characteristic -//| - -//| .. attribute:: broadcast -//| -//| A `bool` specifying if the characteristic allows broadcasting its value. -//| - -//| .. attribute:: indicate -//| -//| A `bool` specifying if the characteristic allows indicating its value. -//| - -//| .. attribute:: notify -//| -//| A `bool` specifying if the characteristic allows notifying its value. -//| - -//| .. attribute:: read -//| -//| A `bool` specifying if the characteristic allows reading its value. -//| - -//| .. attribute:: uuid -//| -//| The UUID of this characteristic. (read-only) -//| - -//| .. attribute:: value -//| -//| The value of this characteristic. The value can be written to if the `write` property allows it. -//| If the `read` property allows it, the value can be read. If the `notify` property is set, writting -//| to the value will generate a BLE notification. -//| - -//| .. attribute:: write //| -//| A `bool` specifying if the characteristic allows writing to its value. +//| .. class:: Characteristic(uuid, *, broadcast=False, indicate=False, notify=False, read=False, write=False, write_no_response=False) //| - -//| .. attribute:: write_no_resp +//| Create a new Characteristic object identified by the specified UUID. //| -//| A `bool` specifying if the characteristic allows writing to its value without response. +//| :param bleio.UUID uuid: The uuid of the characteristic (read_only) //| -STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_printf(print, "Characteristic("); - bleio_uuid_print(print, self->uuid, kind); - mp_printf(print, ")"); -} - STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); @@ -105,9 +55,15 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_uuid }; + enum { ARG_uuid, ARG_broadcast, ARG_indicate, ARG_notify, ARG_read, ARG_write, ARG_write_no_response }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_uuid, MP_ARG_REQUIRED| MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_broadcast, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_indicate, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_notify, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_read, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_write, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_write_no_response, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -120,34 +76,49 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t } self->uuid = MP_OBJ_TO_PTR(uuid); + + self->props.broadcast = args[ARG_broadcast].u_bool; + self->props.indicate = args[ARG_indicate].u_bool; + self->props.notify = args[ARG_notify].u_bool; + self->props.read = args[ARG_read].u_bool; + self->props.write = args[ARG_write].u_bool; + self->props.write_no_response = args[ARG_write_no_response].u_bool; + common_hal_bleio_characteristic_construct(self); return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) { +STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(self->props.broadcast); + mp_printf(print, "Characteristic("); + bleio_uuid_print(print, self->uuid, kind); + mp_printf(print, ")"); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast); -STATIC mp_obj_t bleio_characteristic_set_broadcast(mp_obj_t self_in, mp_obj_t broadcast_in) { +//| .. attribute:: broadcast +//| +//| A `bool` specifying if the characteristic allows broadcasting its value. (read-only) +//| +STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - self->props.broadcast = mp_obj_is_true(broadcast_in); - - return mp_const_none; + return mp_obj_new_bool(self->props.broadcast); } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_broadcast_obj, bleio_characteristic_set_broadcast); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast); const mp_obj_property_t bleio_characteristic_broadcast_obj = { .base.type = &mp_type_property, .proxy = { (mp_obj_t)&bleio_characteristic_get_broadcast_obj, - (mp_obj_t)&bleio_characteristic_set_broadcast_obj, + (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: indicate +//| +//| A `bool` specifying if the characteristic allows indicating its value. (read-only) +//| STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -155,22 +126,18 @@ STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_indicate); -STATIC mp_obj_t bleio_characteristic_set_indicate(mp_obj_t self_in, mp_obj_t indicate_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->props.indicate = mp_obj_is_true(indicate_in); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_indicate_obj, bleio_characteristic_set_indicate); const mp_obj_property_t bleio_characteristic_indicate_obj = { .base.type = &mp_type_property, .proxy = { (mp_obj_t)&bleio_characteristic_get_indicate_obj, - (mp_obj_t)&bleio_characteristic_set_indicate_obj, + (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: notify +//| +//| A `bool` specifying if the characteristic allows notifying its value. (read-only) +//| STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -178,22 +145,17 @@ STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify); -STATIC mp_obj_t bleio_characteristic_set_notify(mp_obj_t self_in, mp_obj_t notify_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->props.notify = mp_obj_is_true(notify_in); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_notify_obj, bleio_characteristic_set_notify); - const mp_obj_property_t bleio_characteristic_notify_obj = { .base.type = &mp_type_property, .proxy = { (mp_obj_t)&bleio_characteristic_get_notify_obj, - (mp_obj_t)&bleio_characteristic_set_notify_obj, + (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: read +//| +//| A `bool` specifying if the characteristic allows reading its value. (read-only) +//| STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -201,22 +163,17 @@ STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read); -STATIC mp_obj_t bleio_characteristic_set_read(mp_obj_t self_in, mp_obj_t read_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->props.read = mp_obj_is_true(read_in); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_read_obj, bleio_characteristic_set_read); - const mp_obj_property_t bleio_characteristic_read_obj = { .base.type = &mp_type_property, .proxy = { (mp_obj_t)&bleio_characteristic_get_read_obj, - (mp_obj_t)&bleio_characteristic_set_read_obj, + (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: write +//| +//| A `bool` specifying if the characteristic allows writing to its value. (read-only) +//| STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -224,45 +181,35 @@ STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_write); -STATIC mp_obj_t bleio_characteristic_set_write(mp_obj_t self_in, mp_obj_t write_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->props.write = mp_obj_is_true(write_in); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_write_obj, bleio_characteristic_set_write); - const mp_obj_property_t bleio_characteristic_write_obj = { .base.type = &mp_type_property, .proxy = { (mp_obj_t)&bleio_characteristic_get_write_obj, - (mp_obj_t)&bleio_characteristic_set_write_obj, + (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; -STATIC mp_obj_t bleio_characteristic_get_write_wo_resp(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(self->props.write_wo_resp); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_wo_resp_obj, bleio_characteristic_get_write_wo_resp); - -STATIC mp_obj_t bleio_characteristic_set_write_wo_resp(mp_obj_t self_in, mp_obj_t write_wo_resp_in) { +//| .. attribute:: write_no_response +//| +//| A `bool` specifying if the characteristic allows writing to its value without response. (read-only) +//| +STATIC mp_obj_t bleio_characteristic_get_write_no_response(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - self->props.write_wo_resp = mp_obj_is_true(write_wo_resp_in); - - return mp_const_none; + return mp_obj_new_bool(self->props.write_no_response); } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_write_wo_resp_obj, bleio_characteristic_set_write_wo_resp); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_no_response_obj, bleio_characteristic_get_write_no_response); -const mp_obj_property_t bleio_characteristic_write_wo_resp_obj = { +const mp_obj_property_t bleio_characteristic_write_no_response_obj = { .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_write_wo_resp_obj, - (mp_obj_t)&bleio_characteristic_set_write_wo_resp_obj, + .proxy = { (mp_obj_t)&bleio_characteristic_get_write_no_response_obj, + (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: uuid +//| +//| The UUID of this characteristic. (read-only) +//| STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -277,6 +224,12 @@ const mp_obj_property_t bleio_characteristic_uuid_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: value +//| +//| The value of this characteristic. The value can be written to if the `write` property allows it. +//| If the `read` property allows it, the value can be read. If the `notify` property is set, writing +//| to the value will generate a BLE notification. +//| STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -313,7 +266,7 @@ STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_characteristic_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_wo_resp), MP_ROM_PTR(&bleio_characteristic_write_wo_resp_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_no_response), MP_ROM_PTR(&bleio_characteristic_write_no_response_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table); diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 0326d6ba71b3c..129a1d0b73f5b 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -27,6 +27,7 @@ #include "py/objproperty.h" #include "py/runtime.h" +#include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" @@ -38,7 +39,7 @@ //| Stores information about a BLE service and its characteristics. //| -//| .. class:: Service(uuid, secondary=False) +//| .. class:: Service(uuid, characteristics, *, secondary=False) //| //| Create a new Service object identified by the specified UUID. //| To mark the service as secondary, pass `True` as :py:data:`secondary`. @@ -47,22 +48,6 @@ //| :param bool secondary: If the service is a secondary one //| -//| .. method:: add_characteristic(characteristic) -//| -//| Appends the :py:data:`characteristic` to the list of this service's characteristics. -//| -//| :param bleio.Characteristic characteristic: the characteristic to append -//| - -//| .. attribute:: characteristics -//| -//| A `list` of `bleio.Characteristic` that are offered by this service. (read-only) -//| - -//| .. attribute:: uuid -//| -//| The UUID of this service. (read-only) -//| STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -72,19 +57,20 @@ STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_pr } STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); + mp_arg_check_num(n_args, n_kw, 2, 3, true); bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); + self->char_list = mp_obj_new_list(0, NULL); self->base.type = &bleio_service_type; self->device = NULL; - self->char_list = mp_obj_new_list(0, NULL); self->handle = 0xFFFF; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_uuid, ARG_secondary }; + enum { ARG_uuid, ARG_characteristics, ARG_secondary }; static const mp_arg_t allowed_args[] = { - { ARG_uuid, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_characteristics, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; @@ -95,41 +81,42 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t uuid = args[ARG_uuid].u_obj; - if (uuid == mp_const_none) { - return MP_OBJ_FROM_PTR(self); + if (!MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { + mp_raise_ValueError(translate("Expected a UUID")); } - if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { - self->uuid = MP_OBJ_TO_PTR(uuid); - } else { - mp_raise_ValueError(translate("Expected a UUID or None")); + self->uuid = MP_OBJ_TO_PTR(uuid); + + // If characteristics is not an iterable, an exception will be thrown. + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(args[ARG_characteristics].u_obj, &iter_buf); + mp_obj_t characteristic; + + while ((characteristic = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) { + mp_raise_ValueError(translate("characteristics includes an object that is not a Characteristic")); + } + bleio_characteristic_obj_t *characteristic_ptr = MP_OBJ_TO_PTR(characteristic); + if (common_hal_bleio_uuid_get_uuid128_reference(uuid) != + common_hal_bleio_uuid_get_uuid128_reference(characteristic_ptr->uuid)) { + // The descriptor base UUID doesn't match the characteristic base UUID. + mp_raise_ValueError(translate("Characteristic UUID doesn't match Service UUID")); + } + characteristic_ptr->service = self; + mp_obj_list_append(self->char_list, characteristic); } - return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t characteristic_in) { - bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); - bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in); - - if (common_hal_bleio_uuid_get_uuid128_reference(self->uuid) != - common_hal_bleio_uuid_get_uuid128_reference(characteristic->uuid)) { - // The descriptor base UUID doesn't match the characteristic base UUID. - mp_raise_ValueError(translate("Characteristic UUID doesn't match Descriptor UUID")); - } - - characteristic->service = self; - - mp_obj_list_append(self->char_list, characteristic); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_service_add_characteristic_obj, bleio_service_add_characteristic); - +//| .. attribute:: characteristics +//| +//| A `list` of `bleio.Characteristic` that are offered by this service. (read-only) +//| 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 self->char_list; + // Return list as a tuple so user won't be able to change it. + mp_obj_list_t *char_list = MP_OBJ_TO_PTR(self->char_list); + return mp_obj_new_tuple(char_list->len, char_list->items); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics); @@ -140,6 +127,10 @@ const mp_obj_property_t bleio_service_characteristics_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: uuid +//| +//| The UUID of this service. (read-only) +//| STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) { bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -155,7 +146,6 @@ const mp_obj_property_t bleio_service_uuid_obj = { }; STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_add_characteristic), MP_ROM_PTR(&bleio_service_add_characteristic_obj) }, { MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) }, { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) }, }; diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h index 94c43f81e07e8..977ec8197653e 100644 --- a/shared-module/bleio/Characteristic.h +++ b/shared-module/bleio/Characteristic.h @@ -39,7 +39,7 @@ typedef struct { struct { bool broadcast : 1; bool read : 1; - bool write_wo_resp : 1; + bool write_no_response : 1; bool write : 1; bool notify : 1; bool indicate : 1; From 52dbbcb23fae800a56a0fcd0357c3e1bcd083318 Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Sat, 8 Dec 2018 16:47:17 -0600 Subject: [PATCH 008/153] Added board test suite --- tests/board_test_suite/README.rst | 56 +++++ tests/board_test_suite/doc/test_jib.png | Bin 0 -> 168217 bytes tests/board_test_suite/doc/test_jig.fzz | Bin 0 -> 7586 bytes tests/board_test_suite/doc/test_jig_bb.png | Bin 0 -> 149724 bytes .../lib/adafruit_bus_device/__init__.py | 0 .../lib/adafruit_bus_device/i2c_device.mpy | Bin 0 -> 1707 bytes .../lib/adafruit_bus_device/spi_device.mpy | Bin 0 -> 1250 bytes .../board_test_suite/lib/adafruit_sdcard.mpy | Bin 0 -> 5349 bytes tests/board_test_suite/lib/gpio_test.mpy | Bin 0 -> 2036 bytes tests/board_test_suite/lib/i2c_test.mpy | Bin 0 -> 2420 bytes tests/board_test_suite/lib/led_test.mpy | Bin 0 -> 1765 bytes tests/board_test_suite/lib/sd_cd_test.mpy | Bin 0 -> 1342 bytes tests/board_test_suite/lib/sd_test.mpy | Bin 0 -> 2256 bytes tests/board_test_suite/lib/spi_test.mpy | Bin 0 -> 3232 bytes tests/board_test_suite/lib/uart_test.mpy | Bin 0 -> 1446 bytes .../lib/voltage_monitor_test.mpy | Bin 0 -> 1423 bytes tests/board_test_suite/main.py | 235 ++++++++++++++++++ tests/board_test_suite/mpy-cross | Bin 0 -> 194960 bytes tests/board_test_suite/source/gpio_test.py | 154 ++++++++++++ tests/board_test_suite/source/i2c_test.py | 191 ++++++++++++++ tests/board_test_suite/source/led_test.py | 142 +++++++++++ tests/board_test_suite/source/sd_cd_test.py | 110 ++++++++ tests/board_test_suite/source/sd_test.py | 157 ++++++++++++ tests/board_test_suite/source/spi_test.py | 232 +++++++++++++++++ tests/board_test_suite/source/uart_test.py | 121 +++++++++ .../source/voltage_monitor_test.py | 111 +++++++++ 26 files changed, 1509 insertions(+) create mode 100644 tests/board_test_suite/README.rst create mode 100644 tests/board_test_suite/doc/test_jib.png create mode 100644 tests/board_test_suite/doc/test_jig.fzz create mode 100644 tests/board_test_suite/doc/test_jig_bb.png create mode 100644 tests/board_test_suite/lib/adafruit_bus_device/__init__.py create mode 100644 tests/board_test_suite/lib/adafruit_bus_device/i2c_device.mpy create mode 100644 tests/board_test_suite/lib/adafruit_bus_device/spi_device.mpy create mode 100644 tests/board_test_suite/lib/adafruit_sdcard.mpy create mode 100644 tests/board_test_suite/lib/gpio_test.mpy create mode 100644 tests/board_test_suite/lib/i2c_test.mpy create mode 100644 tests/board_test_suite/lib/led_test.mpy create mode 100644 tests/board_test_suite/lib/sd_cd_test.mpy create mode 100644 tests/board_test_suite/lib/sd_test.mpy create mode 100644 tests/board_test_suite/lib/spi_test.mpy create mode 100644 tests/board_test_suite/lib/uart_test.mpy create mode 100644 tests/board_test_suite/lib/voltage_monitor_test.mpy create mode 100644 tests/board_test_suite/main.py create mode 100644 tests/board_test_suite/mpy-cross create mode 100644 tests/board_test_suite/source/gpio_test.py create mode 100644 tests/board_test_suite/source/i2c_test.py create mode 100644 tests/board_test_suite/source/led_test.py create mode 100644 tests/board_test_suite/source/sd_cd_test.py create mode 100644 tests/board_test_suite/source/sd_test.py create mode 100644 tests/board_test_suite/source/spi_test.py create mode 100644 tests/board_test_suite/source/uart_test.py create mode 100644 tests/board_test_suite/source/voltage_monitor_test.py diff --git a/tests/board_test_suite/README.rst b/tests/board_test_suite/README.rst new file mode 100644 index 0000000000000..7fed9d35b1d54 --- /dev/null +++ b/tests/board_test_suite/README.rst @@ -0,0 +1,56 @@ + +Introduction +============ + +Board test suite for CircuitPython. Run these tests to ensure that a CircuitPython port was created correctly, individual pin mappings are correct, and buses (e.g. SPI) work. + +Tests can be run individually. Copy code found in each *_test.py* module (found in *source* directory) to main.py in your CIRCUITPYTHON device drive. + +Alternatively, tests can be imported as modules. Copy the *lib* directory to CIRCUITPYTHON device drive and import the test in your own code. Each test can be run with the `run_test(pins)` function. + +The *main.py* example shows how to call tests from within a script. *main.py* runs the following tests: + + * LED Test + * GPIO Test + * Voltage Monitor Test + * UART Test + * SPI Test + * I2C Test + +Dependencies +============= + +This test suite depends on: + +* `Adafruit CircuitPython `_ +* `SD Card `_ +* `Bus Device `_ + +Please ensure all dependencies are available on the CircuitPython filesystem. +This is easily achieved by downloading +`the Adafruit library and driver bundle `_. + +Usage Example +============= + +You will need the following components: + +* Multimeter +* LED +* 1x 330 Ohm resistor +* 2x 4.7k Ohm resistor +* Microchip 25AA040A SPI EEPROM +* Microchip AT24HC04B I2C EEPROM +* Breadboard +* Wires + +Connect the components as shown to your board. + +![Test jig Fritzing diagram](doc/test_jig.png) + +Copy the *lib* folder to the CIRCUITPYTHON drive. Copy *main.py* to the root directory of your CIRCUITPYTHON drive. Open a Serial terminal and connect to the board. Follow the directions given to run through the tests. + +Building +======== + +Individual test modules can be built with the mpy-cross cross-compiler. This is required to save RAM space if you plan to run more than one test at a time. See [the mpy-cross directory in circuitpython](https://github.com/adafruit/circuitpython/tree/master/mpy-cross) to learn more. diff --git a/tests/board_test_suite/doc/test_jib.png b/tests/board_test_suite/doc/test_jib.png new file mode 100644 index 0000000000000000000000000000000000000000..22dd927b2946acd3d4abb2a2e6e59dd9147a0c26 GIT binary patch literal 168217 zcmY(q1yoeu7dAWy(j_G&NT+~ENee?GFm#uIbV;|8LnAFEB@NQuA_xM~-5>(e-QO91 z|Mz{@H){zpbLZT1_T6Xi=Xv%%a1|vP987Xd2n2#7Cks`DKv3);5M(*@2jHETNt&YI z7lxy(&N~PMixBY-3GykO6ugP%BKKMfZ511x_yK8YiBcE@@)RNmeWmU(`!~bagGeKD zU-|S}@1xQv28N4l2LuDf)7`j}tYP(`%o8VLw`nr``4OR^p{qXO?dTV)=+*NYZ!?6N zw#)an!?ap+*&>-~KQnW!&XGP9e~N)3`&9g+pPc*EZQ1snlLTxld3#%lX-lasD^wCwce!7r+Z;0FiF z@*D6g2C+_Fax=!^%=Ft}Vc&J0aV!XA83x{cDoZEhEDdQ~wL0K{KoA3TFgw%#!S}&# zdI$-S0XGU@e-$Ne@BLUGd<8L33IQcXNAt2S1mZyiKJ7eVup|hu@2rAA4w%8;oSg|( zh2A1O%lL2oeFH3!{(UFbwV$V|d4$e2)!`4>HVu)@a!oDbWg=!~&}_k{rKQ!K3npV0 z!M)+tP9lv$7-;^gl6&CyU>d*OY|w429VvFmLbE%kZjI$Pf3=6WeBjzd?hTdw7op>p z-`wS@4_@{aX~xW-mgg}jbE-k3S%|RAUf9=PC+XRf;jjiDf|-%laoF;?Q&xAz{n80a zi;~?ZZ-G+Su>>9#+FI~L%6EbZ7&8kd&rEJo$iM!8OQZ8yPlersNF5Vl$v^17rKfNd zVv#(iWL?X!E!>ruxP>uU9|D5}Q11P}alpgoZ$Qptg|e+N1?j&;?#TVD`p+D^I7OVV z;vvpHHE>PoA(|Pt?Eslq`TtDs)c+M23(`k5MLxsUkG(d7O7$@D12DOG-AQanRr3p4 zPCVp*7eCNdO7-K|{?AOhC)db6DgA^9F~l-Jq_fSVzDkLrtqG&XeE4q(Q23a*7ljHV z#8{^>U%T7mJK=d@PsC#djM15ynfdwjqE?uJfympT^iQ8YISS0r&U#%OtV~X79*T`v z@?bsYC@m^_o~o!>a=QK_J{0!}W@tAoZ7}`im?cl$zem=C3S%Z}N&j~Hu8;`fE>%kD zqdSrv$q)#cRw?^o3C#;Or#JPR(!@ zY>kgR>Pu-U`mFap1>L<&^MMXMoK9@OC5oh~L{>Ov-{-+aK zU1CK=MKg`>-nzQ-(wHr^`JSGh`n4}v@|0^=<`frO?@X4xcsq2{!|4~-!j@%2AcgMK zyih;yJb~#F|D|^nNePPA%pn@XmdxnrZhi=WE(#+Sg^Quue|!bMdmqn{0uh*Hfr*K6nZMZgW=zs*6rwhLqpRk`z^;q#Tq4of`W{SDdM|qZiYsC@(GSp8#VGKz!A8-7BD7J zAf$3;*63_|jZT*9tY>Q6*F;D33#P%Q8~uq2$sA?nDWXS$=ov=_~3^Y-q4 zo6E||^y=+-(*`9x8#Xh&(P{MRY~gIMpjfc~ISra>va_>GOG|Te>FiwLi-`1X(XDxb?E87fb+fuv`Z3PLAy^-mBli|R`_ zQ|3i;`?XN}5_RpXaX}LP1(*0vkV$z!m_03-8u{lmk#(w^4d7liRjTqQ+CR+g3?f3ibyse~=LQzyZ4%mpx?^#0};%BDR&G4V)Zc6OEkN19=)8H*&T z;r46}k5V9ZCy~ot0}*`sFn#-to3Wfgs2O3@LSEk#yZ3zk`n8_kTonJJY{90ho15tA zxEk298_7nCHCAIb6|Ic=;_DELrs&{*yss-dam9fM)gUP zw9$O8cs@NawS(`D9$iPSvsV7sAr#2d%>|5A6bNL-Gn0Cp@$+u(=J39+((3os9Yr6o zP2Oz|MK#-BfVeVfalAcI(vv(y7nG2g2-dw4i=H61ff9HpXF4*DGHu-O{Py@58tKWf10H@Q?&^X>4z8}lFqq_W{Tuk>bAO-2dHa=!XUgu3pa*?CgP0y#{0HN5@(BK6~?xLT-Pgn0p zCJ;K4jr=@;`{4;61YF3I#xf%uTKx~mnsRgKQ^a~-FyGYbzGfUtU{N#e`BGdQ z9>#(7-2d)|*Jjd^=M!`%M(ucop$zOrV7cPrZ6>kH9~FM5B@O;nmLoY$|6T=Ie!6+n z6)i{ocJ&K&raj?ISw2V0oq;$wIR9=5*+W4*&6Ei=$>S04v%fmk7K6Zj+;?Y*Ck6`G z`h0Isr{H&Ifq0_Y;1dvSGQGBo8W`Wr+0{RiAg7?X)XMa`+Cprl?hqV@_FK2VSpXS` z-K^k^Hv|R3oEpy;y*G!mj5IaRhJ^Nie&SUyo5v7s~8T zSH8JE+ie+cxx3l{Iiju2(Cl@~?p!@TAK&D}gzwqRTM%e{HWIZwQb9t*6TMg#yIT_@ zknp>|UcwTyzr8wjxrO6U@U>k2PFrzIY11$;xV_q`7|sylr^H?IzrU4Ju&>pfsxWGQ zJDdrE>-|N{y>_$PGkWX3j;2jW0L=tb0|1)=kzYNJe}hmVH?Qrp@J^zSP+9m8q(giO zaL2%_E3d%LuU@Ct)idn+vow!@LjjNb@&eMm;`ruGZubgTsv>yLMR18OM)+u4O<79k z8*s`k!S}eKYrxZ-1t`I80^2qJm1c$EAjOl$roGEA;BF3!lzIUm)<)0HUY+h3dGGSd zj{gb(I4OYMm;7%wQ-j*s*mw=sHI|Ov^~-1?$Wt8fsEv5}`5k6!w!jw8eR0^easUDy zwfEoWO=el>gM)+Mk$Ihr$P{_OgmNeaT`a+#@IK#*x{3$+;~^G_Fjx-=L0L1lhHXAC zeMKm7{SP|PVnohT9I1>|sr)Wh@)eRN$H#?1U^Mc-t!+4cmBan;JHTau`O1z=mcz0S zLQuu);zm6ZT&%6F`}_O5RvaZICCTe4z(zhqRs&OTno?ChVe)HludIAtzvo0=OCZGs zLg{l@9+ah`dd zmM+vE3qUbFA_$YNpgwf(S9;xVb^PPV;5mvZW9v{y0|-orodmf;QTsp?W%ir`8!2A< z{IebeBKr><`I5t`P-H#?;JkNXC~L)k_P@dKUlc~}jD@)rV6zhPU|_oq{s?n=Rr9~W zelh(Si@hRH#8?k(pS^N{|)DG~(Uk3kx}=GcPNXXPv3{n=S7OFD$tJn?DNkf_a>*j-9w0!_uwNjGK^ z{Lx9oD+Hi(buF#5!QUeXuUBA@^{=nY9U-hXrz{h9_DL=xp`!`Eswp=_Lw*$Yfvt}~ z3ficNl2-|At2~8Yf|O|f+VJdXe%~{Zq(VYa67j6j7lr95?a8WH&VQ~ykexG}?25aQ zPyK1M!hea5pd?)3*w*wo;^qYcCgG0)>^I8IafJQj>i+SO+}Y1nnpt`0$047aLlkBq zO}ymnSkC{L3>Wz+%M=c)_cyDjzAPs>5O$k&ok_?oW&wcr!k7W<;tnCm>DK>Pl5@xB5Y?=Z zfsD~VW1p#!J7iT$Z4cP6_5LksJ>?b7K4koBgIe(|@d*szhgaqQ*pjh|DQY6aRl>}k zg1qk|7g0!nsd=^0irZ_1Ap%CsRV25R@R=YT_-vD0{lq^p5sb^&5y#qWC;lW8r3n`j zkR4aDa>SNGjF@3S$}96-$oQ`Y!fycgMfmaR(`jkLi4b4nDkP$}X2y|kad@7v7ZgGb zfi!;5`A5xA6DLr4r>_uUIZ~;e+^ezc-BWZL5U+cqpGZy&@|8F5HAzK~AlMOI=Vw%n zth|~HFeS)3rbVI?h$1akV~pdYwvyQ@EvJ)uY+B_(fWWB67yf--*g5tuz*!`2Sn!h9 zfK7xTH(awg)_o^dUqdsOl|VF}2zy@gS1iB#Ke}YBGE)L}I^b$W&WSq~5C7vd0k3f6 z)iT@^u)!PyV3wLM3p5Ux|B(+;qLY95YsOr2rs98Z2E?(z0?ky&vf7yzRpo6T(>-}| zx7JJdn6t{jz}A8DF?y^@7_5XWD&)toRwPAlBt=1nkd~%)*fu~rWc(!~MgMnjb^C3? z-iPg%->V&r*2h_f?3LSI(i|N*_e7G-nh&U}efjK$1nF4*F=5H|KX%q3%UAebLEU0= zAI{@FswcofdDe0q?LWoAaz*rb=Hjr4`c9?U48xin0*S<~mX|BxURD2ZDFJa$VUiXq z-G$0T=b_Z7i+*Xf+Nf<=8}W=}cX#_5FDyRygXHypjo5@8ZstX6go^f=yHGhOb~%o& z_5LzzJ{XI|pCL68UqYMj>`65K#C)UY`2rKQ5Xl4{1R`CmgA<|&_Z|ntEDz-+$i9G% zp3}1n?1!xALT^+!RRaM*)eIUaw&d!n-5SsEWdF_;e3?rR8vg-y? zdTx~TT9x^L#ZbDArsi+AW<5PUfQBgQv4IQlkYd9{$r0q(7=?WN>keVh_0s+BW&1sU zITnN1NZ-aMp*`bgNqrjwaSF)-?P6ZYft?4+_j##8k5BOdqx@D{1ucPodiMY0ksTG? z{*x3AEtPJ&vkh~WJme8Qrd*`xG&@rj{=2nPLHkLGiMK0w{@S(Hi4xiPZB)3S^>%Y- z2i3uy1P&IWqUtb4i#MQ`kVra3&6wn9>zLUva(y7N6~(G&Hah&O=P#CGWqA)&fW@|TN{OfSXNMdnmQ^2HHo zp#W(pB(VeF=kU|wSnU2->{t!|F^7Jk3Ntx5c@BN}-4B4V41ErJz$3sCVVxsI%0Maeip;}h4P8_kk*;4jza@iW)-nMREGBPr{ z?`Nx^j1?{euCYtOXB#F|>i`Hid6Wf^F2LXTZT5hpmg-2N&(v6{l|o^HLPCI4G`Q|e z0<155HvPs$HeBgZWK(MR+x^8>K+RnRD0K{boedDe6#;KLYN9K$$^-q1Hu9_O55qkrOAfE;;oLxf>89hClbBKWY0ZAmw|IQO=D?4TNZ6~7&L9yMTc!UxF zfK&ONj1**gu@-yS+1Vi*2_v&663queq%&UOsN@JPHaydSTU+bO-b>Y@j8Y_idFL;A z-&1FOV)WfTVSoA6Qk~uHFbVf*S8xmTkwln8HlSay61DK3y6kOuVv+i7>^?9Z-^%1~59Hf0-V@5T zdZr+trnQ6A8x;FYuMW8SM*H1PyWd4Owe%qAPvSy(yQMafP5J0UX09fB>!+wvs?;Im zEi68PD@s%7D8ihr-%gBzq@%-eo*6iYLGJ|KU@6o83+1P-T(gJjh zt!X6zO2ji+us=tm_Br?^iPw72g$4h;fZ+*bge*Yj3X6Q*=bb_&vOU(K_*bteX!0bx z=slalJc0Ul-#=SxQ>M8Cl#93Ase6rpuk1C3+SdWaV9LSO_AeN)||dg~UwL>d?}8nx$Tr&i9%|00aeiLQ?T)N)WPaPrTu@=u(QDFewfk(iOv$H=B@6)wW(%~Xd{Xs-Av zO-Mg(OA^sOx@XG54_P5lwm7g|2ye~<@!8BW(L*w|@CoI3FVZoPlHyAEpGX}}Xc=i} zX-#2JFVOVsIkeWgY^nN9h*rdiJGXMgDMc`z=aLa9K7H> z#-B)Z3?4V2fkhGvRh~PzMmF*zbFEgx93nxdhm{>~wtAm$=NUW%AS?Erk`$^x>SveL zXsi)A_t9RrMMUaAh!wLkOvQE!O}u;GfyAIrlV^$A?)w3C#vk}TP$YpMd|4oNyA{FN zCIDm!urS`e?$RoioIfuroJ$zHb2}{K3ST`5AtytXLWgUYy;l|^7K}ITPq4AsISs9y zd2oHsV0j8;B4Y0IiCiO$@yt|U+57C{w935JFk%CB~x(r%%CZue74?Vki2~< zOV$ENda~$6<>lo?MR2bN4(%LKGs5qFD@yc%-HT2moqGuMTK-f;_eIaQ^UZaJKwZ!% z(F9|-jO0ko?89EN!cfj-kYtH?3xCS17oWfCsblV@g$3a+?JX$MJMX$T>c=h9l5L(| z;Zc&>!fAuPW@L1}=~c-`f*7AzCVoqMPuxnTcb<+b2wdjb*|Vk^WP{(YXk8du!EI6p zeo#U-x(4Ax@b^xynu2Z4VC@O=B#5}<=wVp;l61U~iwA^O(uKAf1%?`Dmf zP-3-wy!ROB8NXuumfxeT+JAN4=)c};j=`@2Xzb3S00=7q_y9>JHK3|$YS#H&I&WM3 zBh{)5@)tYHIFdNOKCjjhcDJ3=E-dKZ=W7uYGJad&zL;vSaw%%1p@~G)b|6J!HS&VM zk8Ob%4zLIikUYxNO!(T5hlDVLO@ZDC()noaOUh^w?=zqn0S&!rVb9=J%OTtpsO!pN zw>&iKsc$nqf&3pl9KfA6I4p8b>B~3)oa_`N(*pOncEzI~tUVRpo*jG1MIGEEuK2}8N*Zt{KmytPYAp4?S zZRrA)sJ|aG*7up+zxfKl5Gp?ax<62Sc0)#!#!XOMS?L7ytzqHgpJU2mh?MZ33Hv$BS8n^;v-~*<#wnKn*uW#=Vsy8AaO;zmw`D1Bk2Sj(iv_Y3Z zfa&iZw_gMwD1S;z(<;@jw439rp1A>-u^s%#$jI<(&zkyLS64@Uvy7(Gti6Pecnkrr z@}I)!rav=JWxiJsDQ*$Ivv~cwd)XrtZ|7eTYt&xm#_!NO-OyttIG#ya^zLFUg5+6F zNxC~wrEgEh+V5}o2^SW=Nz!5EZvf0~V`mrTd&ANCh>dUgO^iq#2uEmC9tbFGQJqSj z(7gggB0Pk|*82qKdOcp*+QtUtjZWa}2#rSxXbxwH8G|GOvw1^*WhtvZ%cWl&96eP8@Z%*biMb%Y|gyUlJ+U`3Zm^21g0(%^lsKhzEl)HY^c1OCu%8eelagdEiI8Nk=z zwXgvOpZ6nMtG4F#c*BPzuKrJQ3V`O*!BWXX`iTR#2@~%=d}B^LIrL98_53#-HLyc7Fc%o^%EQu>k!+>+TSao^G>M4FUS@GF&Q9#`mBY5#3)ExbfrhZr=E;Lge$ zu%rKa0TO2#eMm#XgV!1q<;H`KoLi;4+efYH-GwOs-!~cvf=vqN&2LhkUwVn$m-MVO zm{yzABgT8mB!XG;=DqD_=Y_pIRAM&RZp8wv>U-s^yEAcm>!bDd$l|}Ge>wGFy1FUJ zz4zApySoidlZ`|I(cM1~)mNkt6Em&Hm=BEAy~k&&-&Q{EI5-mX^A^N`U!CyBOIbV6 zJJ-9w!?~FoZ!{$OEERAXCyI&LzxDQ+ZT~FG=KpTV{%cD@Ywg^t^>I`4n*EO|TjoWt z09&rGcw$gvN8a6);$O1u@`FH*uf)sc)upjnDgk zIEfq)wlzAldP#5J#i-GYjFdBFP4g{CyfYG8pg!fBeCiFWAK3NeU zfa6O%crV^O&?Axa@2Z#wPdDi?QF(bti7=~;UE7`x)HNYU(7E6>H?j z#u^T4h{>M{lO(%$jS{JP4M1N6n8>5EDiK2PkULVEqoRKx-XO6My|=b;;njZwNaK^n zJjjLR7^|@0W5%fy$v#WgBExQhR#Hy=cD~FPyJDea?0gC<`nrbj``8Jpi5ZN<2a?}n z?vB-q2~O|trpAYcF47VcN?&(>MyDYe*byM9Ec9Amqs6{wBQ%*t?+xk>dcCq$FP~bf zn#J_i?1YawX^q2UzKtj=YrykXKjqB?x%2@og_%$$-b6x{`P<1^KRSk#S!B$}qtWwT`N@@= zo_4?eKL2G|P~FnsYn{6LC8_xr4H7bxTW7n~We5oz^yl%7FNWThx>3ogyhOzD0w$RM z-EkIdg%Gw}PvYn0x*WEakgk>gx4HaB5c&!_O^^v`p!Anf_>vZxE3f+K>l7uUrKKMm z>6)+UE?kdfp}7ULJt#9TH)SXg*$=+D8|H!*t%tE5+a$lZYfIrKgBe6n zubW}#j^IlOkSS=peZOwcxLKqG*6jr>3OHGqNoc^wU}zqyI_&G%((gl8C& zc7p5(MMBbfLEwrL{RSo9RDx!s{gwjvpPz<22Al*)kz9o*k-=CfDeUapPsJ1D@Azj% zas@OIHzG9zl?ha>9B2U4JVV;N0K_ouq({P7+7|T#N}1md|2ea;{IB@623dLnI8-2d zz*s!V`~?+Pwb4tp9=f2f>}fLuxIxfB*bF-?5Qee!>c?N$&<)K{mz?j7=wBngjm6fP z)IKuo6b(4LYFA`dGq-m+RTMmugba=iAtk6XH>4h@GOU=|Kj$x|*kV(gS5s$AG_24n znZS-e(m0Z(mq5-OKQX8;KO8SqXU$M57_l5>HlZgt^bq!IzfU+LqE-Rq?9?k!K2f^E zQ9u!yZ|l>QaHn30W{Inyfd%sRsaL+S(zr35xpbCFj+-rW1eEpzZyg#v%O1E@g;}>5!u0Q0)t|&b4UK1f=UK~gpX*})DCFa@abq0&(JKH*mAKN zw~k(GF{~Kg#0r++StdFs%2!Qw>nNl&;~p6u+k*w2h=j{4tp~-vPuR8Y_s(%5O8ycqV1>0`_L$E~fC_nFXGgM14pgd)^)S`_$St9AbX-d6*cE}xMw`&@-nZ%lg!kc4s;j-)?iGP@VXE_mX=u_Yg_{5+ zlR6W@Lq(xD!iSWH@bn^*RQFkCX_E+HI^o>UpN;7mjykLyIGZjl2(NxYu-j!C7xui$ zGu;e@cr!F>6a5E>xDqc1&}jzP2g1X{=?w|DcXvg)D7O?&Q$(He>p#|MNJ&YlmSZ?k zZaNA?vqUrCfR2m2^oEzwJ6l^TLbNa>D;|kH^(FQAAM_jF2A$FeE!M7a;14DrZih!i zpq+lpD2A4KpD37Myp^^fAtC}oW+t@t6^V@RhR)y84<8=D4H(h}rC*D}7)nnxhs=MI zW23SlA-@k;urC<&$q|%9Z+zt!s8kR?UA?unl?~nsusV4Z+$SjHiYG!em3tG1KHwCD zPu3k9h_>dH@awZSqnEzI_aEOhiup;g-vKi-#FHiT3n0-w+PI9i3AHtykm0;#&xg7R zX5bu!WGk<)uA0J;cHM*=h`LkyXoucZ&lEz!#;rx;@&#fBEpoMXq#k_v)Ta)CKClpu z+x+ocE}@l1c0IDDZ`De5t%&S9Vt<2@H{9TCS7d~Tgs1I(;5?V_Vo`0W63BV3^;-djmq2-*cto;P=96A_`A$@Rga)(-0GUp<$urNUNil2Qzmpw`3 zi%1Otfke*s%6aA$Rc(>H!$v*PlKgBt917Un0?e0FH*@+;jd<1~w~Ib71lg)P|E7uotCf8Nu`5^&0?tgOt<&E--RFcexWau!TfdedjA zp^N1kyn6gxB0IKw1s_%Ygjp$Fz-fED2((0{h80Put*DlUrx_JlJ<)~}+Cx6wwHzOxFwK)C=#?KJ- zo!xTL+-6mf#h~UIPAnMP`WAXhiQ8M=W#GeL>siiFN1(}GVNAx?1^wyvZj^%bLPz}M zvw8zt>Fde0-k2;Qccm?LB`!r~(}-Eu-S4q+_#Zd>$97I>k+wEe+uXIc%6=Yix@P

L|GDoL-yH45dgx!lDLPsf?lGl@q6fFP!p#*nwNri0?oQOi~c21T4 zD0aoIdF!jNk%U9@IcV{4BD}XD9-b@P^x|d1SF+Y>K%Xv@l{9H>vTZ$I%ky61~(~b)Y#ABSxE1`F7M(1mF z7PN;}r3ga7H84o~x@d0q%Wk3C7Kk!#E-to9ZLMWxgBI1U?(X$9HQHs9Giz_pi?4Mb z%&NdqTpIOHuGnxq&i>9k5pvUSaO||Mbpr}1FK?rMdFt;}9|e_V7JLW!C%7{8Eopcj zz`1~sZrJ4V0}SZqmMQ4UN`yI)I3b5OJvR0RrhO406HN*D!tlmGvK`-CBAb>{rZ7wL zfQ^FnC1L%DjpCLCG8`Q(H+&#s&HhdED3h*KzY(DHv$l1>X)}a9M=g1jey06V7j)2S zOAdkFdU1l0UUEQLRyrroxRdD|N6~_yTGm3)I)Eb08eHJy^ zEhE7o#YPR@wJa)g0mbIt80va$cFmGnApPa%=jY_)=<6s6DQf1sDnd(Ha8Mq&WQyQ0 z*ALV?EctDZvy@DL3_hGC<_|1VT+G_uIebpl-*}X;XZT0xv3A*!vZzVx7jn+?t`Cs-M=%{z&_2*&9$|sM;imx zy~A!c^SD7z6@-L@K<_SfEy*@$b5qU` z>_M{~oOq9KL7*U8B5as#;EWdIW|Q*N7t1%rIQvAX*H zCTO0knz4mdC?pgziIt1a`A6$86V0}I*U#<#KChnIA#V5au)AxrWbnC9-gmba+{y|= zTlX(N(cGJ>uV`)-Dt4%}nd0yw`XduDWlbL2PTK|^Nah{+*w|P#_}^jXApvsurrFiw zYO*B!u16e1*dvuJCWCmPT{nti&aN1uMM#n~(TE6JF14vTEd_ZX-oV5cqK!HZ&VXdw_ zhJ;aC|GUf0)Yt1k{i`9o1WI6({CY@8NL)f6Bp_}LM%g>ULg;@pNPYRZ!d373zTe%X zN7>|NI|rEh`}gk+6d)aa$n4)LQlmE(pd_g~0sVnt*EgZLGBKl5`6%nkMKzoR^;u3Q ze?|)Lpg93ByU~^I&^3ETk!5^Y^|+&{%BY#cwce>%m-0%i3E_Gt{-&lbbl+KD+aBNDy)Op z{FX0{f}DJHGL%jxTJ~piVSNZgT+bsvl7T81!-|oEr6vCF3|TZ-3L}rni;sOi$+st4 zV@}>Hhz3%Q(r?hZx!spZeaMz^*GjVm%Du!>pvSpEpM%A!tEx1Cq!F}4`Q)#2&6&s729;VF7b<^~wagTK!0b`gYA znuDcHoJ?37g%G6T{c&q1v?J4yfW!Yf3OKXHjoHUpF_a!@?N;u~)uaw=j7IJ&5Hi5z ze>SgJ$88{8LI@k{>)pT6b3=^RJrWcdn@fIkaLarIbod0-H@o<&y2d90KT%#oS69BCCTP9+Sc+o=Cle}i z&Y9gy9aB9xcb|}44E0sLa}N$8Mg9&oe?f}fRZ;3(NFbunmY0{uRiRSxkw>z%f*?eJ z7*{GMU}Iy0uXeD=kwAi{2c!Ab!-o&M2>QLu;9hA5sp`v87PJw51Wns=5j4TzReGKCDDUIPkE(V?9f}Ox)GGEL0jh<=OL?u{ zam0;T#wkQpXh_6ukSNH@H_%2WIY#>bbgb>8MH*8uE7PRVN|8~eMTT(uA5oU$k?`?> z6CY0Xk8mTBrTYKWvatXk0UE!O%NL3l7Lf<0+8}5+y#B<)GQuLn$r*#s%_7W_9{`v4 zSa6*haV`IdnsAX=pqNT~qhV&R=p`FhD3j?hw&k++J&K|MYQTJnbDQ1J(D3!EO1~D# zR@GR&Y%yg#rN=DU2i1(PKPAYj2gw-adHevUr9KQ4 z!eih0E-yu_8 z&nvLGl5!Eun6Zs+)){Y0)Gm=Cc)88S^x8}w@Jiao3?3_jEca1D&(&{mIBOl3u^WT) zcBqG!qu}jjwhe4%Cuz$#hNi{>T~l!>q4@&eOv;RG2n2$!>P_`c82kwH0HSnYaw z@?LS6dYJnYf#|f~S>O4Q0oaP3n_hD2eR5*WFTxc5a~Uvy4wYUsfaXm8R@0G&G=hpN zy_>yuQmd$o2(=^VQLmi3S$DoHt6%Kr|GA1p7Z>(*qZxFaym{QGS~3BO(1fTz`*idK zNI^B$(DRGKUhi)G631VWJQ|qw>CR1M{0}pjP?m$t=3rW{{{~P{WH&?h40W4j?LIoZ zc2&5kGrr<@mTg$k4#r$dnLeEY^)0DexCe$+$Li{8`(;`?e8B?r&I3HAYF(Qb|6#a* zREV#&J#k>&$rnVV(N5-9>GVN+0N3icafWy4`bs zk=8em%sK2qt3Y3T0E7SB`2}iL%n9Ln2Ge=82;bDF3OKETV+{1a zGZLVgqP|x_7=%@PacIs7HrCdw;r;II*9L;knMo@8zkx&d9NTLXTq4eSjYFyWv1ma< z^$X#hOrz!x-ocR>FZj%`gClA3)yQOW&>MG#-4mtyF&jSYd$)5|o#FO;sUxoLaZ7EL z89C0dS^^1*BqF#ie`-goOc!**uzO*$SwsNZyNW~>QVF&$;9;P@%5S5exOqWoX>fS> zek8_ET}|zsv{OhOk{ois8F$I3JaQ6Se}PiQ?8r#xl9ZahzR#3_yN0IbthpPx<0t=5 z7h&!C9QDl4cs}dA$>cVd_x2VtSP#cX6hA?w547KjE~_t%zh9bQHJ7Gt?|(_N9=&m7 zT6Y1QueNg5mJeXw#r^XF8kqBC31x5U#&3JidIO*t{#8@>l9ZH`DdwNKq@Y%yWKeIv z@bLCwn+e}lS#P1iC!0mM+_drUoDWwIk;r0*QIK^gGbi!m0f=fOF+!`6NMiy~j1;#SHBW z+4U8aolN9k?uOP@R%FsKx-A}+HdPV$t7Rty5-z)fqyF^a_|8)b?t@rEX+)VkJt7QS zJf^LN%2Ol-1;6E1>IIVsEVa9FJVg0uDqK7qA@ypas z3|q{xe~;5V;Cqy~p(B>;oSbh-L;P*L9Gj+go-CXHRd0eLJ)=qrcH=Ap;8_Bi=`>*qD>Ms4Yn z^|Q0Ox_A{jt>;`cK|FDrXCn1otr9-B=3YIOI!o;A*-QHcPZ$L^q1s(mcUE%9);#1* zN5uD`qFEKWxj@3Ho&imYK}a^OwW~I0OcEpWr8@1I_@)v_>r+BWs5V|6b_r`zOmTZTl%i-H(_egqnvFndk? z;{~5;3|~t~NM~*kfs{XfF%eB((bjCY%Kg^TJ$$IKsoOPlXfaPB1p1 z;9cK_bD5?>7B>x*ifMK4ITa{ajL_GqvOH9rmCs*?snTzcEh$D%KqUHJYuzP`=dQ}D z&+p0RRQUM*@v4|gbD2ajIQwcUC1vE0UB3Cb+<>alj-@qVGD6khEl9?&sIYg z)khQFq{bZ=SnI-yqLNzCsgm|?G8o#T>pH$ucVsa+` z#^{{WLa6h>;VYqz{G!}``)^ZVyG6D#U{nE=B!C9sfx(bj#c~roJx%CdtjP$= zA@Ec$g-V@vpwp~9Ykv|3?Lm!fMlL`rxb_i+s|}NdY&D;|D=m%2Iibqp#e;LNTS%82 z8L}ApMv+8k9Rv@7X)b-*YAWpeb@gi9mjOF$L5qi8BUK+ZqD82)H9dzc95o{_GyGEf!RcF!{yF+nSi+dF`HSjgY{GV*u_Wi49os^fYLjs z;7cfFiDqnXm?X;QYnEJ|8Oq8J3NIn66{*YTbDyyRG=>-2U4$CB16r7*IhfuDu!|Xa z_dcmQa{dHKHymb8T&2oaVZOldBjWp3#m)q(UD0$LkKfdOyhDp#B<#7j_Py8_n&SL& zZjtxNU3UFF;lvgZ_n_D_eDplsE^J2bEO#(t`wpHXj!gp3WqLdD7jv|9ao}J{M=tj= z3=LO5z7XJwDs~DuG)S3JIrq5=Ya(~5B4d0d`+$?a03}r)rmT;6h>1Wng@-ucB`VC8 z;u7csRV$95(42RhNQ@b*&#|e{hemnvUg5N^P&1%C_d`tt8ugiB^QTkQ z6)oHc&@X7_M2ya;cJds_W2c{AfQlWxv-;vlKuu5$ubj~9RmLL-GOjA^+h1QUc(RRN zV(FRvQ>#tvajKy?K{Yis^sOdZnCt`c)M3;~0YEmbE*M9uqgCx=g_D1(5XKjX1{E{1 zbd+JIdHkQKaWPLy+BY*n2P4q57+h9^ynYb$;?=)@&c?wxd_T8Th1_4-=uDkPFNhTxR|>BFk1giI3P(s}r`{Vz$aH`Gcny7j$R%Rnn_llpT{=j9Hh zrL22)YJMfxZX87W_QQv>I@L8V-i9r@hFfb^>88;;}iZCn!g93>h8ui;(B! z8&XohGSay;@(j5u_`x4g9_VxRjoddal=gJ#mOUy-+}WaGS0D}H!cG>?x>EdUiz|GL zEo6a>i}P=_xiav8&cgKALWDOwmIYl5O^4DpT3UB!yX4g`??||Hmd4Trq8;_~O4vqc zN*2ErPZr0pXow7k?xRD&;y=|y`gA9&Rug@)guS5*e z@#mEJ5f^DJb@YpGOXP8e*D{!t*!NjEj> zR7LL{=pzFs$XFl#>AoWkS)sn?7r$Vl=+C9PO(i*jd9e>z6bF&v$)ab+$eW=IOM#Sx zGZ@+Seu_*Y3`8xajAwj`wVy=Yxz!lf+nuGYYp2o3qRN~1&-5Ejr|Xr4`mU4MSWMb) zcRNJR9iP`*(8N`L)f@|*8`T{YYvL&(NEJ=t4Yc~${J*k(pIi(<>Npc+WH^+TDyDby zn0M>b16Z|T$qbACPdt{VBfy9RO+xth&^Qn!rasj zFZpY72JB#onjoJJmOU1q4jy?@bd(lDho|_<$e>ncDPF6avA9CkD}o_EJX6?{yOlAObA`9$WO7tKMOrMz^yC>3ftBM%}G{~u9b0Tspi|Bcd(G)hY>ol?@h^dj9L4U$TCmvncRCH~ zpB$iGxeF@Ar)OsuUhU^X1Xw8EUS1(NVSZHmxd3Gqua4St^yeix&i{4vXY7t%^?*w* zHXdDXZ})uW8{Zm*FE2N+uR@wmT^!c?hQ>11ULHoYCL-kx`B;hk9*Z}kW%S}dkXC8v zK4v(jepd^w@O1WlB%l1tgbm|CXXVt~As@%4vNE|{Mwn-~v`W*lA%g z+M#1UM3fgnY7<5)q9Hk?c)@XDVX2hYG_4O^tSl^~WlD1@BrK`VH}-bKNFTYe2#L2y zwE)!=eEr9uY4Fj6@m3Jlwe<}^CHvKD-nx)meVlhAI#hT%Y0eF`LDxzBG;i-CM`uel zO(Bn#v7M)7V89AG_ud){Jl7s^iQGkTUW9KxfK;RSZ93?oj$1D3!_)AlEA|>Ht8bse ztSD~Rd7krt@ElZ})?p1%U$!j)NJ6oK2V@gvW#PY{;m_Ji4jEY1&@7XG)@d_3GJft) zq)H$;gnjyKy0s}QQSKJ7!`A%SoLd=wFdnFZ0{<2V=K^}?kYtTtU# z3QRsNM0DegjJl?z7;W8tnjr+~@gq<`Ko+N4Wp&e%kdWYGJQbdAOE%{SMkA6bmSJaQ zO{Vph-(*!X2S9bf4cN4I`Au_}*yu6GDdQoi?iE{crH#HzCwG|pG;{cAE$s+%<(=4t zNJkzUOaqkNS7tj$|I8IVo=)doW&5lT1OldK%)rq5dv(N!0byNpKUjH@p|swP8oS}; zl`subAP3EuN_)$>j}6z+>B&gQkS*e}VVPZ8Ql^j6v;HMo zETjkKiPZMy))sbK>fQC%S{w9|b4T#i%-RyUZJXJ>xL*ft{%PA!Q15WQEamSRipdNi z@yM0P!9q54BSjwOLK$}`?Z=B;k{qqKq!d()1V*`UFrK>o=#cW^VWyQcTU*GM_EF2%=awU82J zX~*{8wa2P#1!1YNix`TCCDkq8&}-1wwZBRhOoE~IjyZ>SweP5%BS!Wf9nol~S*2|Y z6Y24VLHnycdsgdn=C=Arq4dHJ~;(~?H@pWkvpt!^mcInZ1I zA~*zR48*Se2Q6+-IahM>ma(z$0p{x9zon59QrbYU|8v;qq*Ft-OP&|pgU z5zLo|xxPn5f<4K3zO$blIym8cKEI{=j; z!VnDRixeO6=xKFw*3`tIo`7z}ZqO(L4I}rrZwc#VHr{RIRCegSf$1nn(o1Cw1qT9D z3n-DKIkj1}-8S5Uj|Hd_U?A<$b5kI#BD&@6*VNWJ+S(5V3)dK)L$Y+Geaaxy_0iAw% zS=9T+KJLqm`*ebPT+(|2n=C{2xo{aOe949LHyVXzPcq}g)@#)?A{xfq+uQwL+@zpn zU$+0*aF9a0cFZ+Ld&ZoTvd)$Vfb!dHMN40=Z`~bCsIkrBCfb^!rmV-?bE2cm)nco&YwAjyLlzuGmcuP$K#X6rsG@ z{nXd!I$o;pauC`m=%ya*?Fm{5$k8io;=N4OPDW9fAp2qnMtEOp@7i(a{ohW;i}Dxl zwQJtErSZ_>H#kU-d)zb}((bP&`~fK;^q+${#THcY{%wsn^qOnx_AgrIO$-{dgUV@3I$*jf%FBXn4b@Txu5{JjD`LD>Zfs9%B|{CS$da>mIj??gN@NqQ6Q?4 zr=7v!65+`f@pc2y0-yy0#;;rJEtt$e1jvLN>HN-?j{gCcRQH?+6zGkN}`9BNs>cY4Jd% z>?1e;TBxqh$!xi=qwUpVRB-=#^%39&(i?r!OO?DaNri+>kR0qprD(QnhJnA zS4Q3nkyX2}2fPSa-pa}b*PIMm-U7)go7G4kAgKa`besepAQ;or+{uyT(Ew#qncYq7 z89^{_RzF52hWbyrWr*~yx%oV1qEDvLc=gXOD1f5R4-?wPX6?@!(*aWpo)asS>Y-Jku2&SdGK`8tzPrD_ZYK$XN_??`*`2eK z(eMZ=vtEvsvX6HF_$i;zx3YEO)$W7d&tgiAhi7DVf4LC{#8lXRn5^}LKIou?r`(S~ z?OrS;TFiq%daS>4o$3?}U`BwonpKm_S`rd09f3Y|+YDO&<8|A8rEERAe$VSTC+<*%K0VvaFG+YT_ zJq6S52;j7|#iR;=Y*1Ow5S8yaOjT7?gN?$3wspy24TUn!%7Z{xr>7~>zFtT4YBNbg zf3rYo696Y-7+rwUiB}}hYkSI{pqeKtV(@@Tg;Dl%aKQGe!M#O#dkOj9wax5pPQ0bP z>JBaeZ|M7Gw0@BjcM`Vj$x_B(R)I!bZ7+f%hox@Q=nmwQu^s1eWN`9)3wdW_?! z#37%w~+*lA%;4Up4xlW zF(VwN%jja(y99zsiR2h3-eC;(KO7Fh8R`n=e%b)>(totg$A|H^@8LfLh$&d+pktC7 ztuauWaeEdw=n9}h=lFsnBM_YM*G>2t8v=edND0yoc6N%NWWHQT$6izKMP@@xq@;SC z=(!Q7H?Y2)6%{M(7j0|^z5hbZGx^HZz(67{S)MUg>k z;a^UZc`u&6S1EmkO7P{U3F&|td^bX+T0L#R_>50QToba^hLfQr+Zmykax8Tf5N6zQ zbeZF6?^MNIMTidh5$@J1a%kz+x@5vR`38;V)Fj)66p<Cjm$m~| zL9lR_^WK?PD*gGWQpPicMR)Qsmac~5mrHX9{pR-&l7)9dITCi0Hg6lU=<$zH=COBP z>|k^E()X5d*RW1)60{pRPF^54G_ghUfz-#Mg*%hM*%A8Go|No0X9PXGuLeB9#ZtBlpWd@LM*cEeXFna)4_ z5R#pxSUdtYn`wgi{5?!kcnJPg%*@^|5;fk0t2P3%<`ECtKfix}Ng7vt{(ujzkxor_ zhq1xG)ymL<njt)Asq|Fu~{e~yBJ0xj|rN%{JY@09e$YiU|n`(G<&fVRV@v&ABt8Ui7<#=HL~+umKu> zr0zULQxGi3&jfl5fP!17J}iASZ^j2(G|cV2@QXPmNwV zD{18IGxXN0&>(&WW>13Vf`X!=Au{`QO0 zPz-<8sK}T!JP<>+0rR%*68@9Vc)Dr|#4+Caerho=%C+WcH{uXUi2mgJD0+a-z?qJN zLzPrbIN>UwQeAU^K-YevIAtjEF^)Fv=+^1FB$N$4Y`#8I{N0#!n$}8+_F4OYv@5cl z=>sO3x(~q@3t$`DGs0Rix;q|9~!FyVji13Y9i{T4n18M-E%Ij)^t$s{Q@4O2?(L!=vWWqi_A;-X+6Gf#O(eg~R0$aY6s4{&gHN zn_lv-27uAB4H@_0p?#2Bfjz|J;hTdFL^McIX#8CaE1(f>Faq(jr~ zadItT`Qa6*AD$JX5J<|vG66JS5<8Pg0b2e-qnXy8NdHsVKG2AXJ34a}$}zs|A!$hM z(6oPn#P2E3QD7?OuIl4b28fi^x*t)vh!ZTDC2Rw5T#K3dx0pAhl0)>AOw_eIZ~Qx| z#$UaN!}-KqDU&_yWxBYy_-SSm9RzHN^dEx|?I0nqqJYxSr_Y~l{c*xjlZZqIoxzr= zDzJ#U?@&1K`SZXcEQs2nKfWwT2H^wKwSVB;-o)UeP~JJ56}$Q zkb418tw25&)Tt6Vy=hdL&L5fa&-%_N^Y=TFC)dP(vXaB=OJ&nv_w5HyoxStM<-HSG zBUVB@-Efv;hoI?AW=8yh+h1({A9(&>Mp9Tn_{&3Z3M4}CKc~+?%x|}_B){d0Tqm=+ zw8d{U#stTS^3c@kePULm8HHDooW7VdAmA|1EOl&J3ln^9j)fI7zgBeqCIx*}htJ3R zw~lwm^=vIbT53gq#KgorYWd0T`*MM{fzCVBhM{tQvacL=WF}Y;`4~ZM@yLj&D#X$A z3`gwN+8bU@K^Y!0+GGIPG7kAoaFV2Af?e7im(w=Qk(0hY?q`iq;* zskXel3H$<39p@ns$!|YS0d2ed=yliy`EPiy>nYPFQ&e4=^Jv2d080@8oX``=FqXeh zLa|=2qf``R?Hd7FJ5YuwE9n8*3;;84)6!V`K% zQ>*)NThaJBk(gM&`Wp!G{D2zDHQGxvCN%b~seYRM@pJ%XK z!J`G@FsU5IvD37Sgr_2Ze!Rvzo$I{2$arqvxr!>P!NPkVxgvFI^Tc?Chlf{dvHVytc!`6cLvEB^WjN*YRj9Uc!!>cc zh&Y?>LKGuxZc^@rJT`VgSTd7bj>--XzjpT#U(3={nm+xr$DF0c4Leql5F`nKoG)dL znQ@XH`oBI~^V%+Bb^Rd9o656!qaXYg4f*}-`-jC?w@#MtCZb6X+&cK{Gm3(0!U?RzW3a~`(vBTw6)ZsR2^1J$%sU} zEvpT&nL{u|Sm(VEd`TF_Sdje}D#Y>>JQe_&%d|I}`;SmBC+8UvhAF`!Z^>R_aQEti zs)PRzEo-~)(|8=_jtPxB{$9m8>W1-jp7R!IHWGr#k-cjHOpz~obXfWL_$+}wg;DL= zcmTv45zM03uU~^4skk_V8coF1w{BTDH&`+(>%iI=E4-I;>hTXVotKogF9~|aLb6fg z>E>U3FS<7rd;$-20^%qeP1DorVW#H~Gi6&cY#C)+eXgS%GP1i{PK^fkP>_0xr`N>O ztQ{ZMv5tZlc$I&m^WeDzf2AJfRw6bwGEzw_&ULB`&BklCO;COt9xB`}`Gx5EuVPK- za`bC!teCcI2pi`t`%@~;{^u4fCHydg`qnQBj}U}L3Pi0_OyFAcmiqOQ4z0(b zu{YQ7Hs+-WrSZLoUWi_t6nD?yH<48Mgx|hT^61t=o2M%`P28WDye0o{+06w75}iZ2 zbkH!-u5Gr_~ zyHd#{-jjST1=Xc!`E#A8`Xgt;*XJm`Qgdl*1>*VpKsN2i+fzD)4>9XSUvfoQq6(?e z_GJ0=>@vr$e9q2Rl%nHHZ8A&q{Qm4^*KPffGxR?A#2|UNyUS@WP8J7re1B?d_wWac ze)%>z#(yT9=R&O3qpggCKK^d-%%>%K2uzOL1SuLjSk<`Y%(}fu=641OylHw~>H2Gh z^pbe&LH&NMhZn%}2P8z^oL@Lo*j*Z-$hr+fS5p+k{|*kMt3@$|yow2gCIYI7v*?O` zI%tnYQB>g&oIHURa`KkD3q)*A-u|6WHRz#HBUAQ%GBZ<9dcJJY;BG{7RkQ+#0xR(c zl6`1mgAOZ_M0sT;B#I7Nm1sg1;F;NxyhqQF0L5;Ryjm+dn63sPRR4U{CKIFCwA=PSEXSo3FKb1 zG%o;uh#}PTbQ20xiUIdWWKGhKMg~@A)@wdOhDnCcj!&FGhfXs2p)wPj=Iauz-xI4! z&y@eL05UK&_v3tUe`DJcLsxQNLRq1SbkGX}5g8bgL|0iABnlFhJz`P%5}Nq52}LLD z7{@|4R$(4P_j!mrX#y=7US%al=#Q=!U3plzJqiK@a2)d=v{?jZG!qb-*Cr-o)>K3* zt#PN8A>*11X^On0pB(LJOFQa6uxuc=GHe)n-TlxRuR^!bRcTygT{B4z`{kO`+g)yd z=)@pRH1D%iYz1Tzda6~XTgc9oI!-dS&WsI)LkwQM>g62k4n|ep?*b|Rfm^HSfi$0E zm^lp&){Lusy06~QJbhC3im3y7fzmWZviONN&lS!Y!zSovhQ<9*4 z#fXk4ne;us4~CJVpUhk3ZKc+=wt9!%Zvu@$fUeZ3);crGm}Nob{P(Df8xbj`70DNL z82d|P_2g8TG}N>U(1;woSpd&R?9Bfi3^oNc@RX|vC(b|_ugS~ge+QMtX8~rO)$a0` zz}%n0^lHdvb2eDj%ggXLN_tvlQxk}K0YOFcJkSKi$0Yv$Zyb(aWKw6U z3AH-kdhEezn_6hwWLwE$+PLUCqy@?)dU{b*2@?1VH{Bs8Iqsnrm0nAfN#i(DYiqCv$?sNS zfJ$+{Z;1JrnP%9QX1vo=OtFuO{0L4?nad!|AtiOi>gfsX39TOE;^Zv-A*X3nhoMVr zL0A450p9WLa9~f~WHvc9`Koab5t(k)`hq@nQWkli zg)4i|X?WNv(v4jgeUH2Tu5|ydtPtz$QsA;%qRaVY5ETgX>z`)7V^CAcLy0mI-gQ&; zyh23q@^UfI5@hV_>gsBuquC%TBPG2$hxxpE@9nuJY)RtCsQ9BB)Eo{o|whYM-}l{1yJ{)3vooLn0a$|zWss@9^XGlDXE~* zhN$67xiwzj2u`Y)5msfY|BVFj<2NjW8uz6fjb%%(w`@uDubFf3jh$*?A8&)L_kYL7 zWw{b*9QRmm^n5P-9-kva>|vCmZD!sxDzS*n35tpTU5Jy@@_G5)Oj%j%tyyAZMO#$Z zHvlr92t60?T(4Koa#2jrqf*!Wd!O#3n0M&Ya_F;Saf zi``bTX?@AvRsYoZcA|W^Y@xV=Tdpa4I6`{vJ&8>063M z$v6BYOt2$T(sovULi6xI!aQFF1qLRB#bxsQ`_(ilB`R$mGY^vwHB?0nU&)l^=f^W# z(6`ojhN0h@eEll2Zo}G3u72_Rj~s2n<;K?8w#7FJkE(W&yZlhPvlD93Ti(I`6jw>` zDISg(CRvAvfI3q8p}0Zb$=#+o76(I!jVA(MVLGC ze=|5RK~=4pmK(~=CDT>FLp#QJVS(Zsh8_dO>+SLz&%Utgn2FRaLENm}Kz9%TdQ#iJSJ1pa1t6)1Qbkler|Cn?2oe-trMO&GnDw zt8ipSDdJ2FqCmp`P`*EDEieLfdmkgHCVXt_iaoaI*{g2UIfx>Sj&%#3gsvK*OD>5& zF_)qE9f~aR7y*yCubrbmuVi z{AY6S^WrMsJu>G`Wzwz9#wepxGxx1Xit=rZk!|U(w>; zYUx`c+bAqj7YUYl z!LT2cf>C@^SSe5Y6H%O~NK`YSVWR-8j2~F*K(!`tP+xfq1#0$@B8bPtuJ3>m`_GY} zziBCK%bcjRx@kWThRu)|9Te)Mrlr;~ij30SmA{rxJ%YZZXDg%`8Jmj~f?ST_$Nt~^ zZkEy7fC&uuRZ0C$y5?QQBKU~-UE1`2o7osIRVWuCmp0?Y+6nZ(VHzWNSOi!779PC) zE0FQxzf(Z~!2nL?3535Pq&+Sc{lBvn$pnXZxQL((r6eES&metJUk33Xek8Be3!wO; z@IpxHhoi9%R~H#H8;Nvfh+pSQ=d21Ik1`#9!XIS!-ZGYbJWz#y*47tf%grVUW2ZuD zG|0q_*zsg1eh!@;;MDp+H22*mun;mOFP%uIo2a2l&jez)@R`WGA*?_MngJ^cTF(F{ zukyy@4C3<25!s?b>LEBQ3x*7cow(gv-ImN>Nq%Tih|v{Q*yPfAp0#WK?Qr zLaxX3vTS^lEiLBhG9d!)@13e=ZJS6rHK0QZg@BjM1S?!Kk4k9Oc4Y~Y9gO>umaFf7=Y+5ky^> z5V5lJkxR)G_5^&4%<}q#gu-<*cZtCFruj-5nkjTl18~1Q$GXl=x9-O*l+1ly>CeC< zhpTc2CXl%ZRNx{abER&X)n~Q{4LIa+ik+KfxG!cn@$&5{$si|UmA_?JcUB-k2q@E< zXA3|ON1lJmgVSITGy%cKS)_=CM`2u+Ev>D3isGS}P^It>B@$wwurRY=VqjhjvJqn{ z&+sb0%=xnXstnv`Yd!+W+}q)h!t#+yW&wo$?+1yjr~`xbaU&n&m`^;~EG({rkt9HD zX=hq6dT@BKhaM_P`J*!?kSi(R@BKD4Jnt)iBZ-`iRKC9h-GH1vs_-@3!bK>jkb1RIdYO8d z8==ecBmK)jxE>o_#kfV!kQkDL$uGBCR?+a@K#N3GkfaR3hiM@|t-8cUH_=HKOhBqo zr0f&n@F73-yw3u*dJGriW5SmWpHO};^?}D)#W?V^kXkhEI>5kD~_$ym!p-qaOa9b=I^R}B)3Fdq&F zI|8?dIoIFzZ0f|cWt1O&QAwm@ib}M|$R*Fm3<|JFv`W_0$fh9O6$2U-E>nEZpot6I zlCc&=Q{}yTtX({8T%6nKahcxG39FafxnIM1a;?6dPVoUc-1+-hTU4Ua&bs>7cdNxO z)ZG>cUMFOA?T?e>MSt?5I}hesF_p;XJ=v4~Bdq#lftD&r?PrHer0~P2A8<(H=mNCR z92GonCEIdn>%$O@lZ+ayzI^rnK9A$B6j43FCsGJqj}(Eu<)6%}S6DL=zwSx|#@m z301sA-vx}SUMw}*^X~t-Ldxwt>W>sem{;BJ9SW_?#!|M}DvFUEN+BvBnwaQLw*>kB zYh4)_X=_ey+oM=W6r!*1+4jWX@a`E_?1o1ysGtB41gGg3KOgaXY1{pMC#EfeLWu11 zCkO#ETL7<9SsDBHcFiQdPKR8jZ189Q*)=EUc2itWx=^-=>wv-xQA$c? z4no#1{e@yt>D7LiU_ifu{`(nDIx@j4BCnKicUP4l;Jddq-^T;`U0~ao?@kn~%v1D`! zJk1v`$Opk5K^6wnm=)t2aQ$(!Z)>1NN}5&}x9%xA0B0&3+~f&332E_&c^?aeHTDszF;fXG6WM@41nNGM=!I{;>fDSS4qM6AU1yyKn6~_P^Y>wMIZ{N&wOGG#R zlnv-QTZVIELbusAuHLf6W@cmovj;kulFkRHrn)S~_Y){rA^kwe7ZPe4^#&nk1_~Hm zS14&h4zCLRcWd^DhAo^eI`$mr9VbZf1)MQ>bgM^{*`GUsP67{ntE8K3xhBsInF0II*wp3A%7ot^Nf_A?z65Y~|%aEhg6jr_kX?QUg zQ|;$9op9oCI_}?b67$w0v6R(Rmi0?Op z3i?xUZ3r$4GQZXs%PM0YIc|0(Hps9-vCgb1uLA2Le99WGjcxQHM^%l`f@T;9f{DrF zNqfqK4*sMNa%bPVq>(+eF#G6CZe=Y|rDdmVn1j(JZk!jgadGo_dv`-nh3W;_vPL4^ znkY3^O!I0{Vz;m^RWGLn5fPI%lsz?G4QC> zcf;v+w6zrzLt4?Ta10#W>j!&PaDH%=a*4CDGM~o1@Bj1H1N6N|M+bdH4HP`XTJr;F zhruB2bxte!GA1_@8_S2viYZY|LK#9N7L~BrK(5~SxpxGi zGBOM1E9U9-(M6>qb26U&{W3gGNurshJ2&g)8Mq6UA9U*waGl2>9*T-51Q~+I9_@Tt zY-<8uHs>FxNW;f}?&_NlE zR3ieNnf^jJJyY8#9g8zrBDjWU)d-==UTz-FUwI#g|GJDcNtZid5V1ZCdh9Ooh`mI( zmu?p0t!`7q=~7jaxvppP@R^>PahxJLNX=e2HKA=YlbgAFuk0N(YxoU&MhCY1CfeZL>3ml$bdK>p%2e;oHCXz<1T=WyY# zFNc2%?52$O%CER{AmmH<=UWHD*H-SmcKdX1ySd}+<_jI@Bqz2IR;362Nlsj`JO3^n z0joRc!$pXQhydv7jlF&LStsv-r!N_u$OMDdfcPUL^3eY>T`mGnUfu>kdj9f71>|y; z^vCNDg@k_(`x48*IPMi;TP^AxK}4&KY~KI=f`w&Ya=KGg`gq2IkDX%CwSqol(z0a0 z3OXh9xTWr6|9`o*mM!rWq)mXC%^D;#*3QYP=8ylE1A`y>Oo*jo##GCJ{5wMj>*Y2| z-}v=uMsHSBBg?|h2c@%8;*RArtLTTLpmNC&mRtdrKXLoG3L8%nh~m+*Y$Ne+H2#-+ zmX0fo4`ca}U6%_xQicX{MdzPN?%w)oeO&wIR;~Mman|POHEPiPiL8d^ z1?m9;(j*#%F=Mv!+}i);h1D83T$ra9Yf4yYtZMl0{;N=$jA5|67-YCC;ipWw-G(L7 zMHZGrFo01PG_y1*Cz2ErT?m0D$^!8;w4n4wA{ZVLG|}?c0aMgtDsUDx+CNfBJD+utVlcBIgbp+-OLRK?ih4KQ1YZm%u7+s^ivyK@LuIVfyjR+a#s( zO5o@MyGkB1SNlCvtdtmVyut{VJbm-r^1fpr0q8VHsUG zq5xo}OY=0nh9&@c$riy73;NBR1;`y5UoPRv5x}`Uw;7>{$2c?e8ie%tk#(%kRDpC# zj*1mZNHY-}?B-4axd4&`UTIy*J)}?oNlxhchr(Igcg+R>`NcysNHEQN;L=PQHXOi7 zj&s)L3@skF1OP3vkOkq1@Lp31JQv7j2pfFK!M$|}pg?q^f4Q~R$DeVSVeyx+fU`%t%esdQ?k`5Ht}56&0642v|g<(Gr)HKM2$7HI#$qMr~~^0Q7FeiN%Ul z1DKO(x;Ql+8d6RK^pH zztapc(zK|v!PIlXZ)j<@Q#se9)&ycV1b`%zThW3%WD{EI%q=S?2Y?h)8}>4=fx$ts zA~8j`o}nT67D?bYivH5hgs>lO4~0gKTS}3@0pD8S<^!?_Jw5%dDHkD}CUGVUTRwu4 z_)M4z4Jq-7~_J1;%eE zzvg4(CU!}c90=G28q0zQjey|=umwrCTl+tM0#d>ia2D)C9gY*d-UYzp_0DydW=ij0 z_2E>0-(PwP6qJ?i03%b6tF5#PRAYeY2G%Vi051wGFuzv$vAYf{C^s_zc+iy(x`^t4 zM8U+4B4163Bcq0e(tMVeFd5oMZ%}(o1j~hxYQ($<>#>ioe4d&f ztwZfGRT3vDH7FhjQRlZcAxnVQ4QtpD#5;?CeVDifp9NZQFq}Ji@Q+;|kWxk~FP)iK ztv&V-hCCr1g`;jF)?vwIiq|fJ##T|KlsJqq8O^@utSfvP>H7jyBC=?O>tu=sq0Fk7 z4iL@q@bh~7jXfYF-_1=;-BNytTNm8MRwP&nkZWmv%FjoD4IO-TOLA>7Fce2&p=B{( zCn-Es`L0?_o!qrEKT(7!Xi8mpPXq>9QxmC0h(sb?-h`D3nz0;Z9IDJvAtd(w`;1Yf z4iRBWTm>YQPg@}3Bu68d{7S4`D6@wkO?)>AeXh!7{3j6?aefZVw6sHJ9#vYhvqS^yGH|-CHI;K5bQ1W5QkmNA3hY%l)VF9zl~w zf6`J?GURZNaV{7tQ>(|fBfDxk*tJQ5-ap>h*Z{b4CjE+J1_l4p!42qqInv|6yHmev zEQwQYKv@GUE+)iJ!Ta6luG4S31#BeL*+##?1Ca9(1Ga$d70|;i#rm2bIgJ%}R}iD8 z%42L@kE6QJT~P}bmuW%38l0BKzI zl1K&Zp$Ik?2w|a(P)R(P=j&ce;?x15*{C!V^mzC0@l5@v*2klug?0X)CjAj2d{^ckz3 zMk@*xm0p`e2>|5o#7N}#t3qY13F&^P`JIdxa zExFVCJ(nfPpTYl|b+kkGl!10_vBc34-I2@j*YgDV@FFS9`42sss5l_;QXIeqyVhGF zSW*eORcvic4X@)bQ|)rmL=WIM2INY+;Q(X4N2F~4+%+(&E!I7AHw4a9`qUr|tv>u_ zWRxYbHQU-*O2+}S`75qd(h{A;5=RvX2;pquwS=|2Hor7Au|p+Sd(v#@_3|eEY_F^c zd;hK~gn%$nyGG}*!#(GAvUm>(2lc?AMwaO;eQEeSh##lT`R>LOtTh%}rGV+=;~KmH zVow{DxDO^UK@8J$2LZs_0EW1zsHkkjqrk))`0c0}8P#w&g_$Zn^@b7R>f;1A1#%|^ z3=4a$dfq|a5hm1)&RSsWy~5BHtCoi)s{)Yyk^lYQ@88pbO$xBT0|>tcJOa_~WXW%T z=7!)8cHO{v=IZtiq@|$G3YJ-$Pb#ovCxLABp=%R>5(3M%BVaB8o)h3Z0?e7+T+OUk zCMXk-3G}Ki{D%ej)XRnKo6rG#Pk>j5t^oOO4`CLqD&TSZzVziK^Ow%}_btoqtsg!_ zZ#02rgQXVWSU+igpsUvzTXQNVgx^I>>@2o>yQ`|kL85>#V<)iP%F4_<{{yxibxco} zq7J}{m?=|biBdN-eDDha`YijHKY%N(^g-Rz-8c|AgHibM_V%_;|GMR8&4YAFLfbk2}{pDb7=iRl^7k0Nu{R$-?!s~5VnD%er(zopQ z_f2)@F(7M2Pq#G$9*^^{+yH-&hCic#G7H?mC_PpmRny}k0YpbqDZn%QCi#QQCB+G{ zGB^(BG?HwlI0b@SMUnQXb{2052q`!bayW^ji3kbPc{RYV0*pQ5R|QuujTb%5R`tom z9A#iSsmSb;N4uR*o5z%w7vQWvbKU?4D%3j;ya>Mg?36W} z{492Z*Ghl%8x9Um$H~Amy-^`f&g1Q&W43#zH+-^xQs&%jp1c8=-41!{t*Fm2=o7gj zf3sHFN^XHL)AH=>J77>_P2mD(btSi&PNH}(`^a;OKTJYk&E}Im8*385Zvs2%k2Dn^ zzprNDq4|o@yz~tSgMuhlQxm9-o&chcZNcJ0G%-Ja1>82QA7OvZiHyHE`A`V)2j*c7 z=EZ)U{=hc}=;W+i4)8Z*#?YA?(%+9e`T=eaS#`=1pgC2%D(kqrsI`08@EH_m8AGZ* zBmrM>s;8OXuRT3HE;;* z&&TW+T#=El>(fQ4Mg49rF*(}u(VIVhJOf;{2U~7nm{=*&2SALcYFKuK50sh*c}{(r ztj|LLLh|s*07$qD*|iW-iszEa2KVI4tROypSQ1!6tNbD8p+9D3T!H=EeyF{=l?(f3 z+Ztw(cHn*P$I{)fXAa++oB>SnH66a7%jOWc^d!*My(4-vV$nl$2yPM}X#0O&*iL-e za(RHSA_P1*>!1*ntW}idE`Uh}xIZ8fA5kLuuAod(%J-+f<24{m?biC=ez=>dCQ%af zf{Ti*fhYJ$`*X+DO0%mKytc2i$7D#HHeqpe>LhVZfAN=|5{5E=H3_%VFDmIjBe+>yuEvn)s1jO(M`Pwbpqe?p5rD zk>?gs?*xnx7=Ig0t?&r}=9vd@C3mIWG-u;(ThF^YX9S;XrJw@~(EkWN4|yGdNb{B7 zgd5GDiwj_I zB+;2t(51Mk$pgrsxqg@4tNzNmq|KZrI&vHa3i`FbfmCYw{F`9JM(fGD82?_|4r8(A z9&=9KC1-Wg=qw*aLYX(Y>bj_jT#8U@^&STK)GAzO8?x)hb1KjYTh0~0?FLG)PZTNr zcul?4X-=v5A0dFyo8g3tuMEsPhP8Cl%1Eri^B zDx9K^7orq)&GECzuuv{)EtBM`AQzeWG-v6=zY^d) zcodhMhGWUSn-9QJ4jWblN`Y^C$O97T_M&^*h9?Pts5Tuh7U-NBuPLKxYR(dTZfs;^ z&29*(vJ&t*x9;f?1bn#;du22r;n3-kG`kNLl|6m)J_YN-)(0!GmJs_($h@j-8hT+o zHi^P~Y?)ou>1wnZIqb&Y6DNW!Y#x}}0g1SU#YNzr2{_S!B;bD>46>sKyFh?`p1b)e zc6So@2mv^C{X96h9ai-_?dR~DG8b;EuEuUT^w`N(PLHbAxJ&Tx$cgTM?3|NeH!}uP z!IQSIpf{VNPTcvZ1J=GASzcv3t4!(dKw5San<&_`e>&NgT|(E zQiRop=h&@sqlKDgDKm-Z0Gn>K4?#u<*;T9fNazf0(3L-Un<}IL0P>&TA4v&PvD=i) z7oQ3JaA@Sq6858(K^%o&TUp`%AS5OxCLxlmhT$CS5b8%M=9JK-eboSr6hac>=b}&E zeW&4q@BUr~D>?*f2tc<`)n8f)D03a<$w?Wcg z4wir~?j1le(FYa52?X`Pk`9pCd*dr=J31))O0e7dxD**LVZ+z*aNPNa)-+~VGs8>} zjV{1lUF#IHdM+OVqt}D!LI{I5Ka3DL+!&Awl=Sf8q*{Dl@huF*$1FLhTCQ1VenU%I z%953T)7ffNj!IYO{MlR?SgQux*^)&$tHlDBi6mXkh$S|h@FL^}1WvBMTz&*bZ_diy zx0mLr1%cbNG~-Xg`o)8VU!I_ZSg(W6CkdeP*CSov*~eOy%?xwKyqA7j(WnQQnF5e- znL0YV8)}+$QA!eYPeu5^1W=r@#|bk_)a+46;~`z+K89&|*VAH_L`fzU=d(@BXII-stRD*Lp9h!~CF5dyeGk`sfXfh;UJ zw+{GHWZ1EBa8Ox>(G(yGD1}r_lo@Dg5sS^sMo%~FGouB8VHK?edI=kh&7elbG9zh~ zyQ3UZmAAKc;YA?yC~mMQ4SmpgxX>!hw4o07a4Lgymv@()IC|^V&;owK{(do;7FNhf zYvw-sCksx7khAUa83I|_Cj>Nhqkn*Bbew$pm`3k){u5ipm~}4yJ0D-}VsmBCio8a4 zVfd!FvYdel1{d&*ocfYXH!Ka3OnB~Ou?&y`fk-kyUG8qKGSGF!EJfc*{`P7I5PJ`_ z-6!@@r3AnW6%}C>3>_Z2r?-G5e^+~dT??WF{vS@krc#WE56-T4hd=^#VXosd;9P+K z`w_yzKL@4%%?WT*Tm>en(B>}~`V}va+IZ$CPsXIzJ$(;@g0B0cvG3`NIOjvOR{{)O z$6rJ&;xH(Fv$Dnk^!u#ihSXGI-^Wx*9rQA=r^P55gUz>xw#`rZG$0|*l`ZYBRmYFi z?svA*jB~fn_?opWSEl{@II(=3`+AS-l+a91v_@yY{%+l0?Yl5`&u!XOfHZ8tkNH+VGfa@EFd9RL2KNJV%Y#QRA0I4XUg&~MfZ@+JUc1~~SVH}mlSN7Q=< zQr*9CN1mGzeay! zF6^^8+L#2GHdA9H%&8%LiRkWA8`_KG4d-6&!}cU3BD&a%xNFwp|HR#WA5>~j|BmO%?RvrILyMDlF6VDMenqI~M4f|}fU+q#h2w7d99=z<|Valn>bPbpNAnh=H`MB!N zHQmrtQyQggE_{)B@}_HHNTqB@jjSvm@;>0?MJXx>EoOThC56LICic`P#<8;HPc(PM z$YQ9f8;h!LGliy62wd>{1l+P^_+5!ef6EcCQAzueFU|ij^H0gBeIo1aIvGb1$B;^;rn<|?9{GHbB7kso32J=jbDDXn zobgMWlz4B-nD%iEJQ1c&p{2uc)LQXJ;;?s>1#k_b650m_2d~XdzTDKZP;5Kt=I?pg zaza6Udx^JxzDB&_aT!=5fGqGY!y`Gn6Fb<0|IScYL(rta^-AyS{}qZLixX(=wSpI! z{J!0#R(e|G8nkJ;|MDYbYijOR>b6qxwQ6u~fUSUGpoS+vGn?l(Zs&I{`R;wXa!q0g zKnLhz3y$xvp&nEo=U%Mm{&3Eb?OQ{EZMMbf!2KW2-_Qrs@pbtMFB1<=KPEC zY&@uFg^)F$&V*@a-ifIsq@U{^XffOsj1L-hxYS14#0X5Bz3Nr47fx zz$n=Urpt6b^ZD1Cu5o`Q-O!rjSKoF1;e7p_5NO5TbrmzdFJYg!ximI2mO&yk{Yvy% z1Y;yRQ5DR%UE9w8fVTwLu|Uz+3JuHVqgj7X>!8g@Qzx-=}|2GQmQqvfSfZhd|!whQ${5ExV3g^X2*O))nQ zf}G}!-gucZk@o^`pZ$RlR+GcS@q2A2KVrZFg%sNgFig`APR5NMY`60{qd`dYPZ6S4 zAo})Doxf$`+qVi%wV$7_2N7FdFg5}qCwqAw}95@XAPB?(|M+y0l? zx;}fvj;Lvi;2=N0Q@}BWnV{RZm^yw(6{|Twe)?g~)&v*DxLG?j_ z^gGzLu>!_>zw0W4ARYP%f6HO=hZiCAaE<^);4D{60 z{^)Ng1kWf82_x6IzNhmTV_sTOwob1evAtINApEn9|MQ=ChJ>-zqlJvf5tsVH1XR}N z57R!ht*idm5PSINQC^q3&-gOwX|LyhSTtw4uRl0hUsDf)J5o8j0+&awFa%s3LdYVu zN=RME=QW>Po-BQ|kycap&*3r7%>i$SpaKf1)4ymL-?z_VwLCE%5s@jPnznNmgy*Vb zF7<62zE47EDVZaF3?k!?J_$BU1PT#Y-LtwUHhB#{&ae!BzMQ3*%PYmN%wi^B!F;6r z81a?TMDf>X%9XF@vdg^XE^js01Gm_&0->&<3Q0%j;1qYmAAvAXzI$;fLouisU9WQ0 zeJDDN>%DXSR<{TO!E~G5-Rk~e3rfVj=32@lA%CXMcR>sKVwbs5bG&mcqDDk$-6_hu ziOvNaK&lk&WG7zriwfcnCwj_}F@b$nist=m?5y=42PK%I6M4yFKsCrJY%E$x;c-Tp zs)}&V!KNjcwW%*6#488y*l%69l{tdv$wRh6v#tGz6r3kqrYo_FgloLN_1CoSWz^fu z&roZou?!Ga{%t3k2y6z$?Oc-&e}h0kN66@?PUUoy-+`^XOAw+R9(ysTnLY4-xeHn4 z_?efmKY}sPcF~ImYU29@h&|}5+@XwtI{a(6D?mq2o;DJkTcR>XG<2g@sOKhRV$f_vlYWMX1mHJ9h7x9B;xNqZLp4`H2- zQ(ERQ;EPiLXR=xTV2I)9li7d_HUd7B6&E&=kOeuYU4e_3Cus@$X++k+ zmc-VM!^kv4U$S%+Wy)--jmM@6no;lDlKIZC24Jax?YR_l*PYQ`uTfIL|6N| zOTr>mN*RkzXp~yaHH0OTJwl($_v?nUDkWWkjp0vmm&`}A?yJ6`6C*?<9NpnX)vPrN ziP)@im{B8vxy&tzp8sq^Dyhk6kTKoJuvj^~;m`RyAhhAM@uiNgRM{M|thrygq(R06 z%uH*2w8olMm883r@(-8jEm!gwobJ+g&0n4~%m-2+Neii?P7=Uky1%2zuOsk5srDO% zCIiHR*TZ>-847hEn6Bc`NUD_r4V_wwVp25m4+Nh)1ng8KBP~a)%6Kzd>mYN(Gb+eZOZ$M zZzU6w;ln`UqEipUjC)hQ-VI*KSCVgkZlF*j2*#b_D|!Nu$>cWu zee2nYysmfkCcbgH$nMSbM^tPXySIgFqHLR1>RXsE(*;fm&#RUF;3cvYxqFj(|y84tDqKXSbgIa68Cr&#VdEU*S&zX;OeYP{Y#XWJ+Ljn zi=Zh=Oph#VSzLjMg`~&&R#%{awvTtyLf6auSOv{DiJ!s@u1GMU4mgeu_TinoDwy4@ zE(txk!vqbBVeC7ZjeKOM&YzMRsS@I*lj z(pebAgOLZ+V5Mns@zVmPTvmv7&*3{IZS!|8mhXP3tJ_{^I$nxk_*VTeq8L`{zYs|N z6w0w=R;sD9homB#LHg|0+LM6Q)|uF6Y0a8u^B7x5f!-3BSvlIttX)s}v6ige-GvtB zT^y(HO*s&oDCpQIit>VEMZxHrt-FxsI4I!P@&A*e8a>l=yl+iO$V>bJF_P0(Z*<#- zbI?PWI_#dr#j2u?hD6dGY44;*r|kReAnxpJm3Q?8;j}E$C`ohkmj+S|8tbF7Wdkgx z;e%UT>E!U&k?tMM@hs9jaV=z#!UqoLd>zayh&2*Tm3?nXVFr1sUK zfx<@8c!*N!im_OqKPYM%1mY10YQ^Nw-r`m$5-Z-qVj34Nw>U0H2p@W($VLi2UC)r; ztUjW&eL#s$F=mGX9!Z&RR^l>#EwNy8=gF81t)i-mijMvn9dmpEC5lItgf*7`S{H_C zP_?|=%OP^t^`!>#g8eCkCZ6UvKE4pCM+Z5Tt$*J;j4+fza1&7z%T|n_sN#4G*v;KJ z_$-8es9?_lU4!fv^VL_{_46Ksu;{|12s(#FspEOi?d|O( zm9C#2B4T2lt*_BTo4=EK$*ch1+aK>N00sj4^4Q482;2&^c-WvZpZofiGaAr17<y7@u-Rbyn)jK@IAKp(nf6${xK-sk?buXFKY1is) zwsFl9xBS}NU#G#5=UDHA5(Ua&62gl2gP|c9sPOPkBU}&VX3|;{P4T$%Nr*e6$}DhQ zMWZRw71C8ktCMJn2jnRKq;?8^)?okMfrsU#jVqQm8!C$2Xfeh`WhK^$VV(8QZV_A$ zBeXEfN*uoyc1A4$qXdB~geSB{xOdaXY12 z<2x(nAWq2D#$~})dHH}Bq)eNpE2)B+6~wGt@wUbMe;wDaOk3=}3Q#;BzC0TSBc*#% z`)H#QOH2dR79bkVujShfZbLf;Iw{}1evaH&3vUr% z*7+Z8^a5!F&OdtKSK_o#=Qw=~J0gsuzf79k5z`>+8}?1j@1JgaGn$g~Qn-|=UgMMr zs15;L&tVOSnzBJ&!A9{r#hvvE)?+kI&{kx3ntqm><6<5YG`L z!&lFfLIzp(oV;wrw2{%oE{$*#U`E( z*nOt;cChqP_*eVkqvd`N@%mHB!|KfoC8Boy}`EZ|c%(yAWLdeOFT6;+wvo&Xd>OUo=cS@5M*oltr;I zFya{yPgJMhrnrU|Q{tvGE*1QKvO#81&(5{`#OYo36YrXH_*B`>H6$bSC>}-mbKv-GvQAF>}je z<7a4-7QYXwp5IukeBj_TCyLezp#XVt&gKq>C2@5?RgX-Tb&u!qmn&bgb5$OyB`K)p z7rH!+8rR||Vx|NBlf*lH%yG7Uhx@yws|#DAZ|i4_g(^9h`YCpXp5+GJ^Ny~po&kSJLBBH)0vb{ zIqkqk=^H^_(6^K=*7jLU+=*O6rRMgJgm|0+XZ2NzkD1tyk>uYNZlXG|B^J$%bl0e_ zDxIvPkymB=t_E6mF*G*Yx5gEdko0V+zjiY+Ffe*so7Dfg_cH}3|Ej*oWVTCwPDZv8 z8W;@a@2qAd9(+$-Ez`{63-x;U^PZ4#pBu#%ErGFtLHzQe96+7$F@daGu=+ef*Fc0k zMv*zmY}*4$Vwlt`74FX|KqQ;Cwv3McM--$L0Q;ozBRHwI;ciXM=KQ+q;COZ`Du8V&>*+M-I7sWUqVpGI>ll+THw%7gVL-4%7RtmoEbYL5A=h zS#t#&KrqQ$SXD!!v^giBa5&e3uM2;J_#9dy<&P*dwQ>nx4#L(WtxJwQA(ba7nP+qJ zGferdt5qFy$q-*7*0{^&4og&%yWHg>xM_>R5tNwZmPhI76?qGxWd)c)uOxuWlCRc< zSfl*#p-z;Bo`9q8R*l(;Q%F;TS#+^|{hV{{tRS*Rb-$Q~N}lPZKH}{p_)AUpKYWfY z3-Qx&u+IyTdqC^oZM}~ois;<-ew^0?v9~qvMkPs65Si9!CZy1Z55+(YvcB^0ujh5k z1YvF|-GOQrMIB30kRsZ?OU&Pa|J)L&ipt`Wc2F(L^ffQGAGo2o59Cef2ZFCP{P|SJ zPELGl@_B(g8PCnb17si4RMq5_&7R)kt3-pkM#_@5lcRjD>*M0m#p2A!PK1e#*ntNZ+$ zAx`M0&h*ZGRAH>A7ZVI2qRWAACZHrmahiA|s7Eg4neGgs9W`}`45M4B1OX)?#NeK9 zMIJT}4kARfvAn7ZNs{xsjjobQwFYBXt$YS3T_tY#27GwWhkt>28N~5L>HzNuNN!Lo zvPmw@wSXBs8=E*7#?V{CaJd-C{b&8ST*hg{e`tQ zH4(Y6=s`<97MkqmE^xK0k6nTv)G# z`jj7G0Xwy)M>{+pnUcdD{o~+Nm*`7-I?c~+Ue)B`Uz=`Tc1dq>c@wuio?zey=A1Wo zCiy2taYloU`S`3os(-E3ZcAZc}Xbj|V5zl9Tn zbg%~ECm%^9#KnPQYyq|gu%Gk%kqysOspuca^B?gZ0Y?)>%1)3${9*3vi_>(70wS{@ z#>0+JRQ`;gV4P5QVhWy%x+G;~x22^k;+nfj<=T8uQe(HDj=sz!E%18K{%sa+4F#s$ zD$sgvBgMV^)_#NWy#kZ`0$Zo*v1(pO+GrZE^n!)jJq!(QnD^nc(1g}&sP~oGcU(74 zhm_RbWm&4(WpTbo#{@j-_GG}nljC~KX|t7T`%YO+^f~L`Z!rG&Vrs*);)DuRU2?Se z_Z4t5cZtu!KxGCuFmr-7um4Dp9wINUTL%V8U0maiW>(Y*|1L;LSfKIgIyR<1DNZlA zuQ02QSyvxQ{;ga7WC<2H2lbSJbeo#`f^rC%hk3UiiDN3?fYCNW!)fK?$?xtSw}bI0 z*_RZ%{LnH<^`*1oyOU^^)Ox-NhGcYmwT_bu+XnJ4+9y?RQuGND`HXnLOUAudz!?pz zX4zr{RXp&)Q{@ICTzsmR;8{ygJ7m3NDCs?5e2Hh)P(0mbxzwQ zT_tZD47fUz;EqMTqS!~}a^}7xp31|U-LnlzODy2*q-6P+c&+-roSb+fbnx<9IQZAz z`dh{t85*YR`oO)ve?N(}Uk2|n_KG0{CER_KfR!EeSUkgPV}Z&krMQ;`?%g8J=qf+K zKz&`^WZgbU9;)Z{2qevoOU%#m;I^?_(nf6^|ASDh1D+N2YXG*up9We1+oFW8^{%<6 z_|F;FIR3#f42n^k+U8fw;yJ&LP~hgb_#ddrsOkZDDzJNgZ;ZVGx@V=m_mlKTOFzgd zKO2O-C8E9Uc6PFFC#4t{mn}s;EAG3cwyn!Wo5m~0LMNG3Tm+}A~Gei;4-)WCZNnr{QaZK%;MtZ zaoc5(jSY%1a%^mjyP~1s!v{ka*xpugKG~9g zHKrJdOc(khxC%!=>p2Bnyp95G9IW-~_7Sk(^!4@ahQd$3`lLU4=FFV&HeSE&bm}D< zOT79PEQ{RS+yD(}$9P|Q?r`dma#3a{OmHu}!s*whWJGxQdof>S ztXHi#(vR+;w$dUMZGKM~lCc5nFi(+Xj|i|OKS%ZC*FGPfwp~)RorL|#uuOqApvrkp zbXyF(1FW&IWk<4|c};?l$O$?Em>=);`6 zZERVt!h|L~Ud{#_tZ`NdIiLM$eN!|w<*?0|n22I+$7FGGVy&efv{DzOT)rh#-FqQ8 z^N^vJW1s&Zs5est#=gn@&+mA%d-tfSY-MOt+B~ccb!zANnuNqdC60_OZ0wY6Y?wR^ zHgj*(_gScLQ8kijQ4TI`a=jb$c0>9&D7UHk7@bfN^jCP6B_*X-LpW&>1}}3OHo(C3 zZko>NRsHB@S`W1 z6+|SeC;*Jvs$|P69Uxl6PD{79Xx zuq%PE11$~f#QXTZybCt%(JgL8&lZjP6~hjQT%Vv>*C)o@lD1aD z@}~|_zP-D;8VVPOt^w2!+?Ipe%srgk7waAUa~af4nmeeXP;LE{Nd*^igV*bZ7iOh> zekGkPZVmfmT?ASFoyKX?c=K0L@Ndk^z6NEY7vty|*xrY->^`7~C^JWYPr`2wjlh_H zq!6At8Yo<39^)6BL%D;6UKYrY04Sd$;=Zv(}_leN4l+{M?MNQ4P`Fgw%g1BYz#-x8I zUv}Xss<`!C#D;S9?6i-$yt>-`OSXiXL!UeCNJ7sK78aK2N{a;A5ic*EFQ&1pkH;Fl z8mYtOnBJ@H{XN?BX!-^V54}n-qP*UVK&z2SHGa80ZfWA}{Ys_JSVSd3$wDbpa&2z@Z7u^O~8qVDShev{-AVTE-OEu zDK#&7WXw0G_t&EI`iX*zSlRF|d7=6N`>`2Hi9$a$4<*xAsm>X0^8095`Sv zb|Fr+X}co*j`1}A=irN8H5(l=puevmDEQ1&7;Cnun;-4_O!(|%k8NkF{T;serTw^c zd|gmb(1j)`&3EO~r%#}Keg82*!=_oyquiuXIsI&km9<8$eeT{$B+!X^x2Fb&FZ>pE zQYZ99hzvFB_NR5+DBskVJmwjpj>Em4(DU>xNvot21OL3K+gg?lUyp%3rGMQG6A`GC zEA)v=Y>z#<0Eku9g+iY)6*!2WPTM!)bBbw^6NKsN>0x~c;qMlUdu3bb#45ANnU`$3 z;&mGXVQAuQ9sycDlkE0NJc0)}h<1%ZzNC9ld27)dTm`DW2UqO#Pk9|ZiOI=7ge8}b zs27x;U+r})E%ZWNbUuIk+_*dw%8dO9Hf!47LoJ#_knoE&R(!hg_3+&ZM4^A?J+1A z`pHsB3D=}uzCj3vK^D<0J~oDoNbTPWj7d6{H)m{Khwo6sx?dM^DN*NO}Gbx z>I5cs!50U)EJ9u_hW&auc+A{R<{+&ErJgc7(zsDMN1J&N<0ePVkZtGilf8c|O}da| zxual+$63Akd+>_Bo@QOtq>fTbKbMeJ@yPf5xHYyN61+b{gD-yGhAfW=EZawq`mcRk z`Sq(XnYNc0v4la!-qK%C`x;`Q_&c!>Ye)ViCUjML<{D#WFa=xI`~OMi7_O=ieeN&D>;G5xL%-MmlRL@Ll0cUtfd& zk%KSfS>0er+V&3U!ez$*=E0Il8sUpU#yT z_hR!#Gt;{o+`msM8d}gwq7jL1`@ULWUDjNe5+twoy5ek* zwbr6~vcqz6|G?YO^k@9Htn5PEyg`{>au*71Vbw?;rgt99%GeWj!Vj;c#*VN_&~heTz4T<|*qj(I)z@=o z_9A1QnHk-`l>ztn;~YQs;!4!<*Aq$&u;m2VR7Zp}5Dz7Oh7@^m`5Wu%lJH>(3JC!x zO$TNEB|U{AuMkPAlzmdnXa_WF^BS8dIhmYa{kMX;@X~m0YU9zc*?dyK`82Ek)DcMS zOUuQu;XrLG`rryC<5RKQhjbvU(j;<>hKd3e`bMCG-Suw=hUB$ZFdo5f6~OYZgcB$y zfsN5GAJiZKYa1}@6T8H~IR;Sv2HeQjyBkWXg`+23r1w;&T4@O31B+D?qTI1={i(<`}E3G8o%Ju_{%+1gDIWVnniFvcuKqGU(i4{3#7%tnU0(sI5yaf$Rr>w4I@*M&|YFUv|XCjwE^OM}OnHh*)WgBZ@(%C@PG0ZZImJ0^3*c_y07HC9uj}q~0Hb8;Zf+ z6&f-=V-M}gZTBBtdwXuy)<51E*OK#@%{^<{^rEe>$kOjE zk+V)pAv%5>#>A}AKfvx6hQiCBE<>S!SPL9C!=-)4i5%IQ5M?9^>k3i(p&2YEXom5_ zggfDb<{dwn6>OR@rG|gen+QHQKcRb%>niu++tJik?_3B8^D^@a)RX8mf`<ooKnUn~?FoWo^fycVQ}^O!(Eh-{6j>UyUPd?p1_6x- zEXtbf<6E<}@aba`l97h^T8YZ>YAcmN+m7P59_k z^t~PN)-xT9j+?R*_RGec;_)ET0OD8%mE|HV>^K-DdmtrpyC}Mo<~AAxz`D_ zrz@}S^g2hE74nr_-etpZ?^=5%#i-^T&?lBFlpW)HeUug_uoiWbsf0_p^)!1ad!>mO zqwwaO+o>ilYTyreO?%uP0MKhijH=4*b>eaZkl7^YZtQIJE6r4dvj9^|#}V$gabda} z+8s@iA-DEj<^ynF4k?MhG{RJ2{4JiN9-zEd6s4#3>cA)EUS1EcgA8HEpW#IKo0h&V zMYEspMHHjp60NA}TSGaUesStqh*Eu}z9Nn&B+#)t`SQ^nL;p#tL)n68%s11pVZmM- zol^ep$*fogtZkPH&o4Vu9nBNjMusPy+V1uoJ>|R@h)D-fZvq_5<`+j z&Mm6%&qj4HtOPisfB3E!1sL-{Pe+y3r-mZvb=MKOuI=`P=ZiL52=p9pCvOtpy6&ast32+5o0Mi2Iq48r7O0>Td%GtB!Aq{LFSAB9S!EzHxg$U) zq7*9Yts!ryhJdmV1Np~-fb?toH_u}6+Sz%YOi4LIST=-<+&nq36?E0K3bcib1U5q% z@dzUFQXOBHil$_~5qOFthTGql6S6G+QyN6|Q3XbP>0;D0KX_>R3dy9Ps>-y$4jifMZ~2>bB(sJ<0h@-X==aZ6w9^t!fH`cZXK zru4lcAK&4;s@>;zLT8=Wy+ly4Zp4s4#;DH4rf1r4hEz;K;N9~#C>UUm@3Tn&gzudK zy-z|QO(c(d4Z$P&-+i{VncAHhh$Jkw31qxnd|}LeO*mJCbYcFdC-JFlK4A5!GnNEe z+ABm4H(V_5n)Z>yl(0eQ3WXGHFV2k2yO3uxd6B$;?=QjS;cV~mj`R)m`vdnRAN_yU zk(6Lf@QKkK7bbdg`9?3iJkb-HX!&m3(EQOE&QV{0(rNEJK$jw`Q`A7q=Q8SZ56ZrCwJN#udSVN0q7mYPLN!B;E?|4 zA&w1Yabk=NX$Bt~GB%SPTSg^CJo4T2W@iAdEb=>BFSe1_kNqZ7eod4vL9X7Iov_<} znZlV&R@VkKV-gEyhcfM^aaa`*QhO}h^4cfXf4dsvbs4=$>)ekc${KD$LibwpSdt|PxxT{-abz5n{3NH#VFrENDe|8PqIJce7$ z9`hlQeGS@F>eq;OE$`vEtT@w1em^0hnnDsw7*u@TG==>5 z!OSZY)%!SX%K`n^GC#Afw5_;bq4mkyle!yUzyE>w)MZlLqS5H%W)!WMCVOLBlYEqv zpVV)KiM>CSGCBYqh{P{XRayk|tGofmfOd^EKy?4!aTH#;NEy#1y|91xk9JnL>i=*7 zaDBGFDk5kr%_Dsx7J`!P=ex&FZn90n7KDcON?xb>r`9=?Y34bfTE{48t9B)Hc-4cy zEwkl2yE2EY>}31EqvV_E|9iP!QEFMCzTURh4IScZi`xQxA;*1z6AMh4`qi(q9MD+P z%_4oe8!y8cI^KRYBBbm1H+#vgdvfE|PQBEn7$Rh<;z~!t4+Cd8Mg4n9*Rx~?`uemh z3du0b%Is^vVrN3V%t#mgvGg?4bdL+-zlwY~2;6lKSjkoD)*TH}B>gK7g_ubbJp!?J zwz%fiX0UtKmDz30#m!BlECXspeSI(G#S}>s!8iV@|Gf=7{#;x|6`Rn+?~8R{HfLXC z$Hu~dwd(u}Lca(HJbRKaO_J&&3#(l0GeRgiCLJ;n>T6D@hwD_V&7s#H(PHe%GSdK2 zVpKex`iFv2hfkOP7@V)k*0lh5uo-)5hU(y|1x}p`Co!+^*hnR<_fiU`|oduVy zZSRzRGRNRMf`W46UV!3`AP@n(7zpZAoIwbXwtfQ3T!S9Il^`hD>P&!zYWOxzMC-SI%h0MV!ew3tnpfMy zp{iLYu&|m!KnhLnuoyw)1_@?&j`ho-^u$CYH>2h_46wV$o+Ds zd3pVW8zJ)m%&^Zd_Vnl={(Qj&lANkZW_ORTU_KKyog0c^#%vD(Im@qC1zA0OnSUO) zU?AWMxFaFFF?U#b-0MWywpIdqo~eweW%0^snlF-wkVywk4UO0|A5w)CZB8;GadPGe zEQh+U)kujmVS`s%FA@_iYiF&C@L4@htSWE6BKplYMXiN|RT)sNtf5sS430h)Wo+6Q z<@Dy=BYzJ3q@TVNVvy#GkOB-_E!w=nZ3z;Omw(6D*7|`Q0mOL{5)!n%P<8_84z1+e zJ?4IA>f>|VpTf~O7@>CrLr`qQ`}%q@Vc}9;hvbb?s^uiw=gSRCOID5dMwy!3#FZuT z=J9{<41%b67Eba)Me`-puMV|!&#)1QwGZB%#|Li$5i%)n-q_`Fa&f6Pib3=$bQ@3> zwbNtlWiQRgexd@;4ns$$EH>e~@fXAd!K4Vw2Ju%`8Ah)xYG?1+GdJTSGWuDuLuG${ z8Qwikh>h)QoRMK{7trwVsQJBQlsoK0kc}zEhu0PX?}`XX-eiMJ*@0g6mIu4`+v|}b z+BZJaW@jcR7mS=n6|C+1e%Tnt9MqKAAiE)^i7o5av;aK~t4%MFxRliAns>BO^DbhY z0z?t=61y-tt!<>5L4dCDPe$1I_I=HVsT#iq78&U2(`j(6DcLCrdlYQKt>7o91SBMk zC6c(J;TH1*WG8_3OBY#`X0=R+>KuJ?RsENiLp#0nHpu*pr8pwlMrd3;n*w;YrMs^FJUY23wzE ztyeddWen7Ux^Lest5bdn8q244cASAmeAXG8ZsMu2H?I*94IEW99N;22*Bd0_X=rIt z`4Z9P``VH)WO2QF9b153;GSylP|a3pWbzfKdv;f(GVTrE7mV){ARJTIAHcCcudP@Q z@RZk+TyP11<4b;;Uci}Rug_l>E-~aaA+=!G} z9O-}0Cvir@n`jmnyJORW!vAY^$I=5fCc5DRq2YJ0K9||YCUXU<(#Kx*d9Di(Ov4~F zN`q3T<7K)BbAS{*o6gC7m6g)MvMTlaS~e2IY*8I)q*UHjD|~dAO7OtdWUnT@M}d@_ zEo52ChK-);3lG;}pBm!fQJ>Cqm2b-fM2N@#u8l-F7@mPc4)MiBLnK(JyaY+qT_NjLuUKRDy}cehpCHb> z;Bpz3Iv_;kRaWwIa6E<)J>&6G`Ey3O(|9P|9nU z=ZwBm^k7T4ju9lCJ8H*zY(28Ql*N%d@XPPp?lE8tDg6`9+e*9eG%1*GU%SG>1{ujX zm>5tz2~fJpB=kNMpzIsPqHRMlM-P6)lqr7V`?XxL!rl1(VM`-}1%_S;uOl14Z$vubq?HKumCCzUDrVjn+hle-}YfN~^oz@H!g@B3OjhtwZ$Ct|D z@)i7k6R1NrCu16zb>)MBnL-@h$mWrnHGhK^ZiQZlD@C9#ac7c|7>p2>gvlqp82=5u ze=p3YklytmU%T(u0UIl;iX7EX1)^W^i@Pu0aXoLzmSc|a8V_zV>Xi5nnP>hhz)+5|D=~-PJ-BV zRw+s!=Iht5gH=3CNt?@b2JK+c-$G=c{Sga35IY&%*l;K0ios|Biyq5UY0Z(f!~fFdCttpl}6E1PJMt z+R$O#rlx}epWDs`0hD{u76>5Qt~lM3X_Ys9=V8G%D<-bHGo!}oaknQp)*ts@?X?n! z^CA8BXIt{=nYfuk(u)_zpl15DvhrOTT#b|Igy!clm#2ALr}CF0;K9t>9O&=&J6Vd* z)7AZ60xNP4@k0lPo3pn%hj{n6`RX^vS#rV8qSLtsZgXQu2L;3xQ~2L!KxkHofBZf4 zM~pST;|78)F%H~nW>Yu#HVF``e-HmoUQEJ8Sb2F?eXuNn@XEA9vKJr_II`+5qILvF zLofoy|5RLkr>>$Bd3z-C9r#36RP1zwT}2?E4gn+`{F?F`gvbbzUfuE9u&XwcPFq}D z3_jVj5@&rVOwE1sCiv-0KiqvbP|`mkoXe!S8C4)ID2VAK#-?`f-Y{4he)nqZw$23B z0(vq(>rI83Ba|Hw5)>k^dS#mE8R}&S4D}cjWPla)y!My)m)&D5Nm29JZ(8(y-~DpF zzg*Jn*_DBWX1Fkxso6O>7r^*VPfbDU7z0xKGRzx2 zir}RE{yB(1K&GMPr{@4)71|QMQuJbe=neQHdKmwlK7U#eCoZeN$Ibl~PKiP|_kCBPq$KlZH`z$`BEj04t*#BlI`FdCc^hYqF2$*y z+lwb)BTm51gydo!vNb=tFDpfW!T)FhsCr86(7G)+ao`*UrYis=f|QksYY*ffP+Y+Z zeF45Ze`klE!s8?PXdqSn1>YN8hnh9cl-ca89BJ=E8Ae9GlD|`r3YSK$1SnY#YsK>z z@xaUH0n~%H{tdq1Zvzq$+MngY1A2csoBL`yWC962l@hJl+miM2m4xNsjS0+&%O0^- zjCTm!*|?sbh?9sFDTet6gjeMa{#;mmQ@)B&(1G+&Yw*_+Ydh7%hAnq1_$R_X3m4yw zonS4%Q}*@D4YfDLuZsm;sT6fkPqv>kW>4ngh$-mH3V2Ll7U}0U4tF^{q#|UgLeYqaPW+b~<=-2CyoK7FgQ4Yqp>)1lo{cg;`YU zb+~8txG4$a*%c9txdUxp>ti6gNm?wh|9i5(45NC$aK$Jlbjb3DpuPS@!^Fr`jr~43 znMAyR|9(jE`oW(Aygis&uvYRy5u9(I^<9naA#8z1VD6-VW?DQ2AE6)+@SvE?HFpmX zh!G)Ul-_(9{_4|^g}yo0wzz=Qs}y`^e<9HHPkme5YkfH5b~+8jc&;g~khB{deE0AB zy1FAszzx1U4o+a_>{9?5dNAiR8B0*jyVU<<=N`@p3sK2bU=wUD>RsMPzm?LHRlf@` z-~#`IAXpW3)Z^3oT$}fC{W+MEmS`nqvA$!tLwRiK+7iZW5^nWp7nYF4Hn@q*N)w}E zdn%=>+SNH4)97#)O5vUs*C1`255 zuM~8XEXyKf*h@gVyYr2qXFaLf_dD8c4Alps=_GW&(Ma{$o#S_D%nOd+Kn{lz@CVCp zP(dl5B#hee@bfD_`38n{D})SpPZ0BIs~(MDB$WoD9F1J*h23Kar*DD%rtR{4w-9?= zjM_?J8fw`G!RJqEX9JHm48kU7z~2uZ8E5BhSV23VkeN*!f4af|RuDU&bpe?i_`S`8 z1%o%ow>?R7HN~BvSa!Xe?h(h zp&l)w!v}?L<`8`)ziCXV-HF2rp21Q9am55UvxJ>}{fPKwC82VR#Ct!3-T%hy8B7Rk zGDvzmL5*amb~7_=Ar68%g8YLt#H#M(-w8`IPl229BT|Am%xOe;&DyMdYKn|c(S^*g z=9NDzqDw+T0IN%ZH6uKQ2`*ersO~nt=pV3PcRaS`Lx=YMP&CgZntYb{8f8V9M`Q2- z;)7uf0yH4tj>N>oe0u-#hp5_H(OAqHo`AKHe3*wCRaDiD5pc@nl*93~3lppz|D%Ea z$ibm61Zcf^g?oRGkB^tDDG+%}IAVxAjAr}-O^HR^C9-;lj(VYesRU~lL_3V~IwF2P z|MVS}^46nr*Cn4Q8Jp%wI_W^lUggd);5C}JJ-zcyvY(i$SW$@|gzQcj=v?bYnOPM6r%z_tBbja$R=g3y1%sb3@O`L8$A>b7IL>=YnKOaWgce-s z{DLhKc!`YLWG#;qIRxK>sTt6CNb5*z;yWDC=g>?cpQ8@seD^JaZs6nBDEBzd%+J$G zmv*_&!?fr@;JzXoy)hD7>R*@~^OaCp7$s<}0KOvpD(r4*LqHX{oXpRg^}k%wsdVs( z<~3_@g99Rp2(`+9u~kH;4%~|{#Dpm4bDG5yT&t2F-@gMp$Mk=OBsoEUW`UfiLU6XG zd^g(s%~Net(M5btEUi*o&EbbA8>)n0$zl*r61;2Z8HV zo)Ktt{)>(~?G=X64uewC8`JZQDGl=Kuwc2I{jB*Y;9X5-$~ zHX32gL30mJPa%RfguAf`pglLinQy@P*EW#wbgQuKbxIhUa9{oMOBI57@utViiKdSq z=|2Y|F+a?H&3>-uqLK{Xb7%$H2x9?IbUw-+uPG+Yon4!qTUek|R8TAgn!c|jIIhTk zZjgm?dhyXlOAhx$|e=;^&usB`p_A*gV#>r+HHcQTM&L7ZS?NV z8~k-nJQYf;jsTNJ)zQ^e+h&PI

bw?l2}_e-%B6Ffa@IVmCA^R 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 literal 0 HcmV?d00001 diff --git a/tests/board_test_suite/doc/test_jig_bb.png b/tests/board_test_suite/doc/test_jig_bb.png new file mode 100644 index 0000000000000000000000000000000000000000..89ec28dbeb3b777992de208720881d21a9f4eb0b GIT binary patch literal 149724 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 BtknPj literal 0 HcmV?d00001 diff --git a/tests/board_test_suite/lib/adafruit_bus_device/__init__.py b/tests/board_test_suite/lib/adafruit_bus_device/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/board_test_suite/lib/adafruit_bus_device/i2c_device.mpy b/tests/board_test_suite/lib/adafruit_bus_device/i2c_device.mpy new file mode 100644 index 0000000000000000000000000000000000000000..f33d4d495fe9dbe2647a0db93faede76ead9364e GIT binary patch literal 1707 zcma)6-*4Mg6h1djnxtE^q-&jwrimeL3e%JzOHrh0+EUg^@W24I8V^OfapLR6B8@xy zdRrdQ97K6Q;++>>c;qQbyYdHs;J<)>Vt{ypbM2V0sc4Dh==lCP-#Op;KEE%;$~Pns zzm*1L$VhIts(S!`%UPmcA$d@9L}?Rwl^8K~mE;anw~lPX>$BUh>xOPRp2ca$bE&}| zSzT7QwC*gd9S;*)O{+C8QTm8Eu4NA>O;PHwW1G_Sd)nRI;L1EA#BKFBKXz}{>klm6 z^E$PzeN>NN>N^qMUCZer?uSF(!=&$cZkVZtmsmV#1mGWXx^FH`!^)BE8GJZcS)PnvR=Zde0uCmuW4Q`+`8b-C{F zq=?wSNLhn$VF?3#kGtGHz8V~+yvGK}a+n}Zaho$Ipq@Pu$zf@fTaf@~E*HeWZ?%=m zTh+%(W&8fe?`|PW4e%!=nV8W0^J(iNxRZfNDNm+($&6{cjobd)MH7B&Hhk^Q8WcZ+ zkwJc(l&+EKX|R87wx9L2;zP*Cr+*ma6SCJJ{!Z|>o12tg!{pk|WL#Y%({XiOs48lG z0YbSmqlX)@@S+sP01_Z-J|(w!k^y5s1>716%w*hk3ce1G}A-uGB=bjcft3=+yU z6DpVLhT$;RjX~UHee;5y4!Fg8wt~V{!Yhi-mD#PE%GQ&uG{j;6mo`v(qkaD}GCAH{ zBgo8nbDc~I(+4pP8;vIO>PAHkFLv@$tuU*#Sne>alz{DUwokuTIgZy0l9t1D>lo4yb=?4^5 z!z!m}z*F?!8QSj|y6+s#_k;PBq&2GkxKtt&`FA*#zk#!0{Y#>aOB-a0i_dWJ-28$d zzZaQcfrk5RAmNkj>8{SXBd8b8`b=VTQwdeQM9G5o49QOfK9(ZS{ws(1Itiz`EUb=` zHJOt}lh2~Xz69>Ybyv{y1QnVQw*R(rBlLPOfxzz1pNdF#M^o5W0XZElt;@Y6FTvj4@jO9XvFWv(egNxt(1X{Wyf$8SW}!kgrk%sg+sV$n{r%qCCEwW0f)DX=v5cb7OVt+T zCkXu#1(0HpLQ))ZH4qcf7?TnZUk%<}*Bf@5+?!PzO4GD8itDz88)QRMNzpR2L0B-l zfl{GVs6;T{Af~119gKq*o5avD4lP%oKK70bBLHi$MX6!kDHhi>+Oq2fRbMZjq$xf) z$@fSzRhGBfr7d>pL)+@#RA7gyeh)=RKos_J&fLsSPw5=r*)WL9Kx7%C^0>OWQ%Vh-%s)3%fWsVO1+~SH^1Kcv0Y-Cn9^CMv?TBz>Nn@vc1AHq<37@VZ25Y_i{o@aTfw;nD|EegnzqiYNd8 literal 0 HcmV?d00001 diff --git a/tests/board_test_suite/lib/adafruit_sdcard.mpy b/tests/board_test_suite/lib/adafruit_sdcard.mpy new file mode 100644 index 0000000000000000000000000000000000000000..03f65fa63fb0cf6a05906fa196a582521f30da5d GIT binary patch literal 5349 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 DGa*eK literal 0 HcmV?d00001 diff --git a/tests/board_test_suite/lib/i2c_test.mpy b/tests/board_test_suite/lib/i2c_test.mpy new file mode 100644 index 0000000000000000000000000000000000000000..201d2c97438eda619809e0adb2decb497b55dfc3 GIT binary patch literal 2420 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 literal 0 HcmV?d00001 diff --git a/tests/board_test_suite/lib/spi_test.mpy b/tests/board_test_suite/lib/spi_test.mpy new file mode 100644 index 0000000000000000000000000000000000000000..d07d186859f8930677d136f60107a03e8dd113da GIT binary patch literal 3232 zcmai1OK%(36~2cLk+iLbqNI@>j;N75qA1y7Bsw$!IVeDjOu{;nC{nTtsK8{z8A^kY zGsMg=sTP5Td3a%&QpwXCX~SU_OyZ9K`W6C-KfFUX91A562!xAC8*V+nm>+9QbiMGr%*zTm^mtm{))6qp$BlQ8z+7aTtY4|xt+ z{4{*T&%nq0b@+tm;ZuGV9`JFn_&FGB9q|c!oCjtB_yu5Y0Dl9RMc{A31S!H*(aR@c z0;uHUGce(ylAm9J=mbQsK{N`{NhtcRibMPzcsIb`hbTvw82K(UWJT|TL{cNW!8huf z)U3%rju=`~ugI?%4Mi|z!%Q{~{d=0IOU@XQlzqh%Yl_yD{CiD9(VTHe7gb5CyOYmU z>asJeZIlbcbP$S#bzwcbmiMg{${WLU=s@1`>b)!Y+W|be)aBK3M-AQ0Zs&wjb}K); zzP%=tiv?jTU*0OelFt`Q8xF8jDwo22dSNTyyP=fN=6dy=Qm)XemvZG&uf9{tuSa?f z7K*~%!q#XHw3hv;kj>>vZLE-57224um@Su`;mvH}9UmRM>#t=!>)Eg%%MD$t3zX~+ zM8#zK09`R*AsR1Il1m@4Zxd$w5k`qMDj>aKIg(`vXV;-jt_e1ZZ4q zP4nXy8 zZK7;~`j%$k{xauxBF81g@6kJ$g&IQ*6ZrZeb{IhWyL%!4<%FDrriDaUhT9i{a>(}Ss zpHUVUml_N4#7t%W^>_lOg~UvKpTDOjXy&~j>_5pP31UyFaNLd&2{LAj{R^4!OOV2u z$->#oiJ_N{HW8rnU0U|pQHZSq`x#*)a3*=G@D(DHd6;|?9>;SKc}%l;3}SD&drl<} zb~9)HG0LyH@(G^(1inra>q+cwECrc=A3cc`fcXiqQ^4EI0IBe8X~Jr9ZQl ze$S3WtOypHfU4&Yu7YV&_56{3;}WpP;@g@Z|C5&m`ZA=a@#r7WFiU zK83$Y?^x^#U6i~psFf{x>UnG0n(kOaub*4fopT}Q+>~YSdiH16+$9GNTCKk>-}?4; z@hFvg65B@4Qcp9NEp`EHu4$y+=!ogC{Y@@Yc5lKajbm)9?Q%OH?0hxFFujIsUcnk9 z>xNu06-}jpzo8@KjKNh+RdI=PK}Bse&2I0#l5_fTLEUJYfqmH&O;f+ns&k6&SRdNh z-YRZy;dvKu)7)5;Qr#i1jVbt=tD$a^6F+{Jd#zM}3s z*!L7lXY1e+;j9Hp*d10vJ%%0J8HXfUQ5Cb>*Buy}dVu&EifRPwnxP0N1?!5TQ6XSd z-lOwS#h{b1*uGhjTT?2!Ryj}_Tq>Q-F1@~#<($_AhYWCZA!)=oQ{&77nOiM$c%0Kz zTXPR2jjKgkaygmC65Wb-fh;uTq%lRG94n3~tyz;e?3cJ)uQ#!2;vN0}4c8nCIV|U# zq{)VDp)Q)017l=evn^APxT@AvrIru7B7P$GX+`_>VqA+aD|7LAtXS`Q*k96OBjL{% zn4z==VfGT{SAaFHtX v^(;#(++>gtAS95%e=U%MO@clK$d|`EW9fe#?Ou9=mI1tt#-OJ+o?Q4Jx@gIz literal 0 HcmV?d00001 diff --git a/tests/board_test_suite/lib/uart_test.mpy b/tests/board_test_suite/lib/uart_test.mpy new file mode 100644 index 0000000000000000000000000000000000000000..ecb47c908d404661fc99c16422452db5eb6a714e GIT binary patch literal 1446 zcmZ{kO>7%Q6vyZ7`ZEbF{^+KO*Xxb6a_mTPTNl?-R3Ww@MMlJO97h=Cu-SNLlP&hH z*0C@u8Z1L_6k(i0bY;f7$wYc~!8Tbg=&^mg#PYE_M;$0f%GwuVziHg6bFt2=@M|4 zL7Ihl_bHO*;9F@PzL64S__@Rbmjo#ZoB)yloCs115|mb(;9inT~3^ii;gL*Z$PMYpJ$2Zaa=)`FCj>uvJsDTBDAs z)u(H9rBW&@WqEy#sn(~fXT$Ik?CVjCO)2^urS}pSuqCy#;U3wD$+ki&I@b33LY)W}6qrR^j#GMgnvrDcC^d zBVl2z<2e?5O~Y|n2fH(d>0;Z#4cD+t>hQO1;_@42yW@I%_~ryRF4RcvPRnq~cyA@_M9Y>)RT617 zQMWp#CWR3Kgu+GgE_}I6_}f7D-dUYN4+toI4c?CzULI^u-K6Kxuv+c&SCy(nmM`^u z)5F&#TA*ydwVbxn*Nnw~ zUQswXeKgT=Z3di+aUq`CpKS@}f AoB#j- literal 0 HcmV?d00001 diff --git a/tests/board_test_suite/lib/voltage_monitor_test.mpy b/tests/board_test_suite/lib/voltage_monitor_test.mpy new file mode 100644 index 0000000000000000000000000000000000000000..b04c848b970e4a40f938cd2b8b5282cc926e1c38 GIT binary patch literal 1423 zcmaKs&2QsG6u{>>X%ZFoBWZEkts7>Ao6Sa$ij*i)wE}settz$YS13Xea^3Z~G1#8S zGl>)-v}vWiBXQvm;KXUuB5~nBfg69p-uBLg6#`BOX6$s!vKwsq&GUORZ|wJe^EMO8 ztDb`7HC;nlxZN%<*u~=N1O35N8KJ)i*>(=}9EfoW^eMZ!q832ao&wla5oYIi;IcD_eFZXFTRr-939 zXmY}MrPH4{q*iFhGGhgnM~__kR7u}8n$4Bn4`=tcHk!uTin+PfSZ{9an%nCQvtewm z>`fXCV`FR0++A6{605>+JD0IEjP%RW?=cm zG=(DHO*6JD3cL27eVxQoW$7e!6(K-qUV|(gU+>$C#W&qzb+J}uVpEL@KqP zk@hQkXhY#!sc6$+gCm~vVf}2NJw_svUm~@N>=URC*WS&cAB6Gr(pLNBzA&gu$d3Gm z@J~VECTL$HEeEHz;=qq*^H)Jr;kOel4}bptQxxDeD13#!ao~xn!xORgtgrwMs@A@f z;Y3Y@%qzk!$3#9Ur$}`|jzv*4^%gv;rw7^$47Zh*HX9AK>(M8t%a_9Bhr zYMb<2#uJS2m)(Gqkdb@brGYezujfQ36q6GqumL}>!{k#mGDZZ;dXPRM+~PbOk<_!i zE*VQj95S?j7d-JWZUgjbmU9+mNNlof_ONnYn7v6u0DCh7s{y6B=J5j#lyXd0alKbWrlalbWrN1}g^`kk?j IPb@G019&5)u>b%7 literal 0 HcmV?d00001 diff --git a/tests/board_test_suite/main.py b/tests/board_test_suite/main.py new file mode 100644 index 0000000000000..1c472f1ff6b22 --- /dev/null +++ b/tests/board_test_suite/main.py @@ -0,0 +1,235 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Shawn Hymel 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. +""" +`board_test_suite` +==================================================== +CircuitPython board hardware test suite + +* Author(s): Shawn Hymel +* Date: December 8, 2018 + +Implementation Notes +-------------------- +Run this to test various input/output abilities of a board. Tests the following: + +* Onboard LEDs +* GPIO output +* Onboard battery voltage monitor +* SPI +* I2C + +You will need the following components: + +* Multimeter +* LED +* 1x 330 Ohm resistor +* 2x 4.7k Ohm resistor +* Microchip 25AA040A SPI EEPROM +* Microchip AT24HC04B I2C EEPROM +* Breadboard +* Wires + +Copy lib directory to CIRCUITPYTHON drive. Copy the contents of this file to +main.py in root of CIRCUITPYTHON. Open Serial terminal to board and follow +prompts given. +""" + +import board + +import led_test +import gpio_test +import voltage_monitor_test +import uart_test +import spi_test +import i2c_test + +# Constants +UART_TX_PIN_NAME = 'TX' +UART_RX_PIN_NAME = 'RX' +UART_BAUD_RATE = 9600 +SPI_MOSI_PIN_NAME = 'MOSI' +SPI_MISO_PIN_NAME = 'MISO' +SPI_SCK_PIN_NAME = 'SCK' +SPI_CS_PIN_NAME = 'D2' +I2C_SDA_PIN_NAME = 'SDA' +I2C_SCL_PIN_NAME = 'SCL' + +# Results dictionary +test_results = {} + +# Save tested pins +pins_tested = [] + +# Print welcome message +print() +print(" .... ") +print(" #@@%%%%%%&@@/ ") +print(" (&@%%%%%%%%%%%%%@& ") +print(" .(@&%%%@* *&%%%%%%@. ") +print(" ,@@&&%%%%%%%%//@%,/ /&%%%%%%@ ") +print(" %@%%%&%%%%%%%#(@@@&&%%%%%%%%@* ") +print(" @&%%&%%%%%%%%%%%%%%%%%%%%%%@/ ") +print(" &@@&%%%%&&&%%%%%%%%%%%%%%@, ") +print(" ,/ &@&&%%%%%%%%%%%%%%%%%@ ") +print(" ,* *@&%%%%%%%%%%%%# ") +print(" ( @%%%%%%%%%%%@ ") +print(" , @%%%%%%%%%%&@ ") +print(" #&%%%%%%%%%%@. ") +print(" #@###%%%%%%%@/ ") +print(" (@##(%%%%%%%@% ") +print(" /@###(#%%%%%&@ ") +print(" #@####%%%%%%%@ ") +print(" (@###(%%%%%%%@, ") +print(" .@##(((#%%%%%&( .,,. ") +print(" ,@#####%%%%%%%@ ,%@@%%%%%%%&@% ") +print(" ,#&@####(%%%%%%%@@@@@&%%%%%%%%%%%###& ") +print(" @%%@%####(#%%%%%&@%%%%%%%%%%%%%%##/((@@@@&* ") +print(" (##@%#####%%%%%%%@(#%%%(/####(/####(%@%%%%%%@/ ") +print(" (@&%@@###(#%%%%%%@&/####(/#####/#&@@&%%%%%%%##@ ") +print(" #@%%%%@#####(#%%%%%%@@@@@@@@@@@@@&%%%%%%%%%%%%#/(@@@@@/ ") +print(" @%(/#@%######%%%%%%%@%%%%%%%%%%%%%%%%%%%%%(/(###@%%%%%%@% ") +print(" .@@#(#@#####(#%%%%%%&@###//#####/#####/(####/#%@&%%%%%%%%&& ") +print(" /@%%&@@@(#((((#%%%%%%&@###((#####/#####((##%@@&%%%%%%%%%%%/@. ") +print(" ,@%%%%%%#####%%%%%%%%@@@@&&&&&&&%&@@@@@@&%%%%%%%%%%%%%%%##@, ") +print(" %%%%%%%%@######(%%%%%%%@&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#/(#&& ") +print(" (@###/(%@##((##(%%%%%%%%@%%%%%%%%%%%%%%%%%%%%%%%%%##%###/(&& ") +print(" ,@@%@%##((#%@#######%%%%%%%%@&%%%%##%%%%##%%%%#/#####((####(@* ") +print(" *&(, %@@%##%@#######(%%%%%%%%@#/#####((#####(#####(/#&@&. ") +print(" .@###((#%%%%%%%%%&@@###((#####(###%@@&, ") +print(" #@#(#######%&@@&* .*#&@@@@@@@%(, ") +print(" .,,,.. ") +print() +print("**********************************************************************") +print("* Welcome to the CircuitPython board test suite! *") +print("* Follow the directions to run each test. *") +print("**********************************************************************") +print() + +# List out all the pins available to us +pins = [p for p in dir(board)] +print("All pins found:", end=' ') + +# Print pins +for p in pins: + print(p, end=' ') +print('\n') + +# Run LED test +print("@)}---^----- LED TEST -----^---{(@") +print() +result = led_test.run_test(pins) +test_results["LED Test"] = result[0] +pins_tested.append(result[1]) +print() +print(result[0]) +print() + +# Run GPIO test +print("@)}---^----- GPIO TEST -----^---{(@") +print() +result = gpio_test.run_test(pins) +test_results["GPIO Test"] = result[0] +pins_tested.append(result[1]) +print() +print(result[0]) +print() + +# Run voltage monitor test +print("@)}---^----- VOLTAGE MONITOR TEST -----^---{(@") +print() +result = voltage_monitor_test.run_test(pins) +test_results["Voltage Monitor Test"] = result[0] +pins_tested.append(result[1]) +print() +print(result[0]) +print() + +# Run UART test +print("@)}---^----- UART TEST -----^---{(@") +print() +result = uart_test.run_test(pins, UART_TX_PIN_NAME, UART_RX_PIN_NAME, UART_BAUD_RATE) +test_results["UART Test"] = result[0] +pins_tested.append(result[1]) +print() +print(result[0]) +print() + +# Run SPI test +print("@)}---^----- SPI TEST -----^---{(@") +print() +result = spi_test.run_test( pins, + mosi_pin=SPI_MOSI_PIN_NAME, + miso_pin=SPI_MISO_PIN_NAME, + sck_pin=SPI_SCK_PIN_NAME, + cs_pin=SPI_CS_PIN_NAME) +test_results["SPI Test"] = result[0] +pins_tested.append(result[1]) +print() +print(result[0]) +print() + +# Run I2C test +print("@)}---^----- I2C TEST -----^---{(@") +print() +result = i2c_test.run_test(pins, sda_pin=I2C_SDA_PIN_NAME, scl_pin=I2C_SCL_PIN_NAME) +test_results["I2C Test"] = result[0] +pins_tested.append(result[1]) +print() +print(result[0]) +print() + +# Print out test results +print("@)}---^----- TEST RESULTS -----^---{(@") +print() + +# Find appropriate spaces for printing test results +num_spaces = 0 +for key in test_results: + if len(key) > num_spaces: + num_spaces = len(key) + +# Print test results +for key in test_results: + print(key + ":", end=' ') + for i in range(num_spaces - len(key)): + print(end=' ') + print(test_results[key]) +print() + +# Figure out which pins were tested and not tested +tested = [] +for sublist in pins_tested: + for p in sublist: + tested.append(p) +not_tested = list(set(pins).difference(set(tested))) + +# Print tested pins +print("The following pins were tested:", end=' ') +for p in tested: + print(p, end=' ') +print('\n') + +# Print pins not tested +print("The following pins were NOT tested:", end=' ') +for p in not_tested: + print(p, end=' ') +print('\n') \ No newline at end of file diff --git a/tests/board_test_suite/mpy-cross b/tests/board_test_suite/mpy-cross new file mode 100644 index 0000000000000000000000000000000000000000..8dbdb9ab9dcd320549d19e38ef8506d0a96ec629 GIT binary patch literal 194960 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 z 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 timestamp + LED_ON_DELAY_TIME: + led_state = False + timestamp = time.monotonic() + else: + if time.monotonic() > timestamp + LED_OFF_DELAY_TIME: + led_state = True + timestamp = time.monotonic() + for gpio in gpios: + gpio.value = led_state + if supervisor.runtime.serial_bytes_available: + answer = input() + if answer == 'y': + return True + else: + return False + break + +def run_test(pins): + + # Create a list of analog GPIO pins + analog_pins = [p for p in pins if p[0] == 'A' and _is_number(p[1])] + + # Create a list of digital GPIO + digital_pins = [p for p in pins if p[0] == 'D' and _is_number(p[1])] + + # Toggle LEDs if we find any + gpio_pins = analog_pins + digital_pins + if gpio_pins: + + # Create a list of IO objects for us to toggle + gpios = [digitalio.DigitalInOut(getattr(board, p)) for p in gpio_pins] + + # Print out the LEDs found + print("GPIO pins found:", end=' ') + for p in gpio_pins: + print(p, end=' ') + print('\n') + + # Set all IO to output + for gpio in gpios: + gpio.direction = digitalio.Direction.OUTPUT + + # Toggle pins while waiting for user to verify LEDs blinking + result = _toggle_wait(gpios) + + # Release pins + _deinit_pins(gpios) + + if result: + return PASS, gpio_pins + else: + return FAIL, gpio_pins + + else: + print("No GPIO pins found") + return NA, [] + +def _main(): + + # List out all the pins available to us + pins = [p for p in dir(board)] + print() + print("All pins found:", end=' ') + + # Print pins + for p in pins: + print(p, end=' ') + print('\n') + + # Run test + result = run_test(pins) + print() + print(result[0]) + print("Pins tested: " + str(result[1])) + +# Execute only if run as main.py or code.py +if __name__ == "__main__": + _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/i2c_test.py b/tests/board_test_suite/source/i2c_test.py new file mode 100644 index 0000000000000..ef8d5f07f0de2 --- /dev/null +++ b/tests/board_test_suite/source/i2c_test.py @@ -0,0 +1,191 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Shawn Hymel 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. +""" +`i2c_test` +==================================================== +I2C Test Module + +* Author(s): Shawn Hymel +* Date: December 8, 2018 + +Implementation Notes +-------------------- +Performs random writes and reads to I2C EEPROM. + +Requires Microchip AT24HC04B I2C EEPROM. + +Run this script as its own main.py to individually run the test, or compile +with mpy-cross and call from separate test script. +""" + +import board +import busio +import random +import time + +# Constants +SDA_PIN_NAME = 'SDA' +SCL_PIN_NAME = 'SCL' +NUM_I2C_TESTS = 10 # Number of times to write and read EEPROM values +EEPROM_I2C_MAX_ADDR = 255 # Self-imposed max memory address + +# Microchip AT24HC04B EEPROM I2C address +EEPROM_I2C_ADDR = 0x50 + +# Test result strings +PASS = "PASS" +FAIL = "FAIL" +NA = "N/A" + +# Open comms to I2C EEPROM by trying a write to memory address +def _eeprom_i2c_wait(i2c, i2c_addr, mem_addr, timeout = 1.0): + + # Try to access the I2C EEPROM (it becomes unresonsive during a write) + timestamp = time.monotonic() + while time.monotonic() < timestamp + timeout: + try: + i2c.writeto(i2c_addr, bytearray([mem_addr]), end=1, stop=False) + return True + except: + pass + + return False + +# Write to address. Returns status (True for successful write, False otherwise) +def _eeprom_i2c_write_byte(i2c, i2c_addr, mem_addr, mem_data, timeout = 1.0): + + # Make sure address is only one byte: + if mem_addr > 255: + return False + + # Make sure data is only one byte: + if mem_data > 255: + return False + + # Write data to memory at given address + try: + i2c.writeto(i2c_addr, bytearray([mem_addr, mem_data])) + except: + return False + + return True + +# Read from address. Returns tuple [status, result] +def _eeprom_i2c_read_byte(i2c, i2c_addr, mem_addr, timeout = 1.0): + + # Make sure address is only one byte: + if mem_addr > 255: + return False, bytearray() + + # Try writing to address (EEPROM is unresponsive while writing) + if _eeprom_i2c_wait(i2c, i2c_addr, mem_addr, timeout) == False: + return False, bytearray() + + # Finish the read + buf = bytearray(1) + i2c.readfrom_into(i2c_addr, buf) + + return True, buf + +def run_test(pins, sda_pin=SDA_PIN_NAME, scl_pin=SCL_PIN_NAME): + + # Write values to I2C EEPROM and verify the values match + if list(set(pins).intersection(set([sda_pin, scl_pin]))): + + # Tell user to connect EEPROM chip + print("Connect a Microchip AT24HC04B EEPROM I2C chip. " + + "Press enter to continue.") + input() + + # Set up I2C + i2c = busio.I2C(getattr(board, scl_pin), getattr(board, sda_pin)) + + # Wait for I2C lock + while not i2c.try_lock(): + pass + + # Pick a random address, write to it, read from it, and see if they match + pass_test = True + for i in range(NUM_I2C_TESTS): + + # Randomly pick an address and a data value (one byte) + mem_addr = random.randint(0, EEPROM_I2C_MAX_ADDR) + mem_data = random.randint(0, 255) + print("Address:\t" + hex(mem_addr)) + print("Writing:\t" + hex(mem_data)) + + # Try writing this random value to the random address + result = _eeprom_i2c_write_byte(i2c, EEPROM_I2C_ADDR, mem_addr, mem_data) + if result == False: + print("FAIL: I2C could not communicate") + pass_test = False + break + + # Try reading the written value back from EEPROM + result = _eeprom_i2c_read_byte(i2c, EEPROM_I2C_ADDR, mem_addr) + print("Read:\t\t" + hex(result[1][0])) + print() + if result[0] == False: + print("FAIL: I2C could not communicate") + pass_test = False + break + + # Compare the read value to the original value + if result[1][0] != mem_data: + print("FAIL: Data does not match") + pass_test = False + break + + # Release I2C pins + i2c.deinit() + + # Store results + if pass_test: + return PASS, [sda_pin, scl_pin] + else: + return FAIL, [sda_pin, scl_pin] + + else: + print("No I2C pins found") + return NA, [] + +def _main(): + + # List out all the pins available to us + pins = [p for p in dir(board)] + print() + print("All pins found:", end=' ') + + # Print pins + for p in pins: + print(p, end=' ') + print('\n') + + # Run test + result = run_test(pins) + print() + print(result[0]) + print("Pins tested: " + str(result[1])) + +# Execute only if run as main.py or code.py +if __name__ == "__main__": + _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/led_test.py b/tests/board_test_suite/source/led_test.py new file mode 100644 index 0000000000000..57e7b8b6c2156 --- /dev/null +++ b/tests/board_test_suite/source/led_test.py @@ -0,0 +1,142 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Shawn Hymel 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. +""" +`led_test` +==================================================== +LED Test Module + +* Author(s): Shawn Hymel +* Date: December 8, 2018 + +Implementation Notes +-------------------- +Toggles all available onboard LEDs. You will need to manually verify their +operation by watching them. + +Run this script as its own main.py to individually run the test, or compile +with mpy-cross and call from separate test script. +""" + +import board +import digitalio +import supervisor +import time + +# Constants +LED_ON_DELAY_TIME = 0.2 # Seconds +LED_OFF_DELAY_TIME = 0.2 # Seconds +LED_PIN_NAMES = ['L', 'LED', 'RED_LED', 'GREEN_LED', 'BLUE_LED'] + +# Test result strings +PASS = "PASS" +FAIL = "FAIL" +NA = "N/A" + +# Release pins +def _deinit_pins(gpios): + for g in gpios: + g.deinit() + +# Toggle IO pins while waiting for answer +def _toggle_wait(gpios): + + global test_results + + timestamp = time.monotonic() + led_state = False + print("Are the pins listed above toggling? [y/n]") + while True: + if led_state: + if time.monotonic() > timestamp + LED_ON_DELAY_TIME: + led_state = False + timestamp = time.monotonic() + else: + if time.monotonic() > timestamp + LED_OFF_DELAY_TIME: + led_state = True + timestamp = time.monotonic() + for gpio in gpios: + gpio.value = led_state + if supervisor.runtime.serial_bytes_available: + answer = input() + if answer == 'y': + return True + else: + return False + break + +def run_test(pins): + + # Look for pins with LED names + led_pins = list(set(pins).intersection(set(LED_PIN_NAMES))) + + # Toggle LEDs if we find any + if led_pins: + + # Print out the LEDs found + print("LEDs found:", end=' ') + for p in led_pins: + print(p, end=' ') + print('\n') + + # Create a list of IO objects for us to toggle + leds = [digitalio.DigitalInOut(getattr(board, p)) for p in led_pins] + + # Set all LEDs to output + for led in leds: + led.direction = digitalio.Direction.OUTPUT + + # Blink LEDs and wait for user to verify test + result = _toggle_wait(leds) + + # Release pins + _deinit_pins(leds) + + if result: + return PASS, led_pins + else: + return FAIL, led_pins + + else: + print("No LED pins found") + return NA, [] + +def _main(): + + # List out all the pins available to us + pins = [p for p in dir(board)] + print() + print("All pins found:", end=' ') + + # Print pins + for p in pins: + print(p, end=' ') + print('\n') + + # Run test + result = run_test(pins) + print() + print(result[0]) + print("Pins tested: " + str(result[1])) + +# Execute only if run as main.py or code.py +if __name__ == "__main__": + _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/sd_cd_test.py b/tests/board_test_suite/source/sd_cd_test.py new file mode 100644 index 0000000000000..cee1fd7ba2cc5 --- /dev/null +++ b/tests/board_test_suite/source/sd_cd_test.py @@ -0,0 +1,110 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Shawn Hymel 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. +""" +`sd_cd_test` +==================================================== +SD CD Test Module + +* Author(s): Shawn Hymel +* Date: December 8, 2018 + +Implementation Notes +-------------------- +Reports the output of an SD card's chip detect (CD) pin. + +Requires SD card. + +Run this script as its own main.py to individually run the test, or compile +with mpy-cross and call from separate test script. +""" + +import board +import digitalio + +# Constants +SD_CD_PIN_NAME = 'SD_CD' + +# Test result strings +PASS = "PASS" +FAIL = "FAIL" +NA = "N/A" + +def run_test(pins, cd_pin=SD_CD_PIN_NAME): + + # Ask user to insert and remove SD card + if list(set(pins).intersection(set([cd_pin]))): + + # Configure CD pin as input with pullup + cd = digitalio.DigitalInOut(getattr(board, cd_pin)) + cd.direction = digitalio.Direction.INPUT + cd.pull = digitalio.Pull.UP + + # Tell user to insert SD card + print("Connect " + cd_pin + " to CD pin on SD card holder.") + print("Insert SD card into holder.") + print("Press enter to continue.") + input() + + # Make sure we see that the pin is low + if cd.value == True: + print("Error: Card not detected") + return FAIL, [cd_pin] + + # Tell user to remove SD card + print("Card detected. Remove card and press enter to continue.") + input() + + # Make sure we see that the pin is high + if cd.value == False: + print("Error: Card detected") + return FAIL, [cd_pin] + + # Test passed + print("Card removed") + return PASS, [cd_pin] + + else: + print("No CD pin found") + return NA, [] + + +def _main(): + + # List out all the pins available to us + pins = [p for p in dir(board)] + print() + print("All pins found:", end=' ') + + # Print pins + for p in pins: + print(p, end=' ') + print('\n') + + # Run test + result = run_test(pins) + print() + print(result[0]) + print("Pins tested: " + str(result[1])) + +# Execute only if run as main.py or code.py +if __name__ == "__main__": + _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/sd_test.py b/tests/board_test_suite/source/sd_test.py new file mode 100644 index 0000000000000..47f4510f7c0f2 --- /dev/null +++ b/tests/board_test_suite/source/sd_test.py @@ -0,0 +1,157 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Shawn Hymel 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. +""" +`sd_test` +==================================================== +SD Test Module + +* Author(s): Shawn Hymel +* Date: December 8, 2018 + +Implementation Notes +-------------------- +Performs random writes and reads to SD card over SPI. + +Requires SD card. + +Requires adafruit_sdcard.mpy and adafruit_bus_device modules. + +Run this script as its own main.py to individually run the test, or compile +with mpy-cross and call from separate test script. +""" + +import adafruit_sdcard +import board +import busio +import digitalio +import storage +import random + +# Constants +MOSI_PIN_NAME = 'SD_MOSI' +MISO_PIN_NAME = 'SD_MISO' +SCK_PIN_NAME = 'SD_SCK' +CS_PIN_NAME = 'SD_CS' +FILENAME = "test.txt" # File that will be written to +BAUD_RATE = 100000 # Bits per second +NUM_UART_BYTES = 40 # Number of bytes to transmit over UART +ASCII_MIN = 0x21 # '!' Lowest ASCII char in random range (inclusive) +ASCII_MAX = 0x7E # '~' Highest ASCII char in random range (inclusive) + +# Test result strings +PASS = "PASS" +FAIL = "FAIL" +NA = "N/A" + +def run_test( pins, + mosi_pin=MOSI_PIN_NAME, + miso_pin=MISO_PIN_NAME, + sck_pin=SCK_PIN_NAME, + cs_pin=CS_PIN_NAME, + filename=FILENAME): + + # Write characters to file on SD card and verify they were written + if list(set(pins).intersection(set([mosi_pin, miso_pin, sck_pin]))): + + # Tell user to connect SD card + print("Insert SD card into holder and connect SPI lines to holder.") + print("Connect " + cs_pin + " to the CS (CD/DAT3) pin on the SD " + + "card holder.") + print("WARNING: " + filename + " will be created or overwritten.") + print("Press enter to continue.") + input() + + # Configure CS pin + cs = digitalio.DigitalInOut(getattr(board, cs_pin)) + cs.direction = digitalio.Direction.OUTPUT + cs.value = True + + # Set up SPI + spi = busio.SPI(getattr(board, sck_pin), + MOSI=getattr(board, mosi_pin), + MISO=getattr(board, miso_pin)) + + # Try to connect to the card and mount the filesystem + try: + sdcard = adafruit_sdcard.SDCard(spi, cs) + vfs = storage.VfsFat(sdcard) + storage.mount(vfs, "/sd") + except: + print("Could not mount SD card") + return FAIL, [mosi_pin, miso_pin, sck_pin] + + # Generate test string + test_str = "" + for i in range(NUM_UART_BYTES): + test_str += chr(random.randint(ASCII_MIN, ASCII_MAX)) + + # Write test string to a text file on the card + try: + with open("/sd/" + filename, "w") as f: + print("Writing:\t" + test_str) + f.write(test_str) + except: + print("Could not write to SD card") + return FAIL, [mosi_pin, miso_pin, sck_pin] + + # Read from test file on the card + read_str = "" + try: + with open("/sd/" + filename, "r") as f: + lines = f.readlines() + for line in lines: + read_str += line + print("Read:\t\t" + read_str) + except: + print("Could not read from SD card") + return FAIL, [mosi_pin, miso_pin, sck_pin] + + # Release SPI + spi.deinit() + + # Compare strings + if read_str == test_str: + return PASS, [mosi_pin, miso_pin, sck_pin] + else: + return FAIL, [mosi_pin, miso_pin, sck_pin] + +def _main(): + + # List out all the pins available to us + pins = [p for p in dir(board)] + print() + print("All pins found:", end=' ') + + # Print pins + for p in pins: + print(p, end=' ') + print('\n') + + # Run test + result = run_test(pins) + print() + print(result[0]) + print("Pins tested: " + str(result[1])) + +# Execute only if run as main.py or code.py +if __name__ == "__main__": + _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/spi_test.py b/tests/board_test_suite/source/spi_test.py new file mode 100644 index 0000000000000..9d508af9c8b6d --- /dev/null +++ b/tests/board_test_suite/source/spi_test.py @@ -0,0 +1,232 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Shawn Hymel 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. +""" +`spi_test` +==================================================== +SPI Test Module + +* Author(s): Shawn Hymel +* Date: December 8, 2018 + +Implementation Notes +-------------------- +Performs random writes and reads to SPI EEPROM. + +Requires Microchip 25AA040A SPI EEPROM. + +Run this script as its own main.py to individually run the test, or compile +with mpy-cross and call from separate test script. +""" + +import board +import digitalio +import busio +import random +import time + +# Constants +MOSI_PIN_NAME = 'MOSI' +MISO_PIN_NAME = 'MISO' +SCK_PIN_NAME = 'SCK' +CS_PIN_NAME = 'D2' +BAUD_RATE = 100000 # Bits per second +NUM_SPI_TESTS = 10 # Number of times to write and read EEPROM values + +# Microchip 25AA040A EEPROM SPI commands and bits +EEPROM_SPI_WRSR = 0x01 +EEPROM_SPI_WRITE = 0x02 +EEPROM_SPI_READ = 0x03 +EEPROM_SPI_WRDI = 0x04 +EEPROM_SPI_RDSR = 0x05 +EEPROM_SPI_WREN = 0x06 +EEPROM_SPI_WIP_BIT = 0 +EEPROM_SPI_MAX_ADDR = 255 # Self-imposed max memory address +EEPROM_I2C_MAX_ADDR = 255 # Self-imposed max memory address + +# Test result strings +PASS = "PASS" +FAIL = "FAIL" +NA = "N/A" + +# Wait for WIP bit to go low +def _eeprom_spi_wait(spi, cs, timeout = 1.0): + + # Continually read from STATUS register + timestamp = time.monotonic() + while time.monotonic() < timestamp + timeout: + + # Perfrom RDSR operation + cs.value = False + result = bytearray(1) + spi.write(bytearray([EEPROM_SPI_RDSR])) + spi.readinto(result) + cs.value = True + + # Mask out and compare WIP bit + if (result[0] & (1 << EEPROM_SPI_WIP_BIT)) == 0: + return True + + return False + +# Write to address. Returns status (True for successful write, False otherwise) +def _eeprom_spi_write_byte(spi, cs, address, data, timeout = 1.0): + + # Make sure address is only one byte: + if address > 255: + return False + + # Make sure data is only one byte: + if data > 255: + return False + + # Wait for WIP to be low + if _eeprom_spi_wait(spi, cs, timeout) == False: + return False + + # Enable writing + cs.value = False + spi.write(bytearray([EEPROM_SPI_WREN])) + cs.value = True + + # Write to address + cs.value = False + spi.write(bytearray([EEPROM_SPI_WRITE, address, data])) + cs.value = True + + return True + +# Read from address. Returns tuple [status, result] +def _eeprom_spi_read_byte(spi, cs, address, timeout = 1.0): + + # Make sure address is only one byte: + if address > 255: + return False, bytearray() + + # Wait for WIP to be low + if _eeprom_spi_wait(spi, cs, timeout) == False: + return False, bytearray() + + # Read byte from address + cs.value = False + result = bytearray(1) + spi.write(bytearray([EEPROM_SPI_READ, address])) + spi.readinto(result) + cs.value = True + + return True, result + +def run_test( pins, + mosi_pin=MOSI_PIN_NAME, + miso_pin=MISO_PIN_NAME, + sck_pin=SCK_PIN_NAME, + cs_pin=CS_PIN_NAME): + + # Write values to SPI EEPROM and verify the values match + if list(set(pins).intersection(set([mosi_pin, miso_pin, sck_pin]))): + + # Tell user to connect EEPROM chip + print("Connect a Microchip 25AA040A EEPROM SPI chip.") + print("Connect " + cs_pin + " to the CS pin on the 25AA040.") + print("Press enter to continue.") + input() + + # Configure CS pin + cs = digitalio.DigitalInOut(getattr(board, cs_pin)) + cs.direction = digitalio.Direction.OUTPUT + cs.value = True + + # Set up SPI + spi = busio.SPI(getattr(board, sck_pin), + MOSI=getattr(board, mosi_pin), + MISO=getattr(board, miso_pin)) + + # Wait for SPI lock + while not spi.try_lock(): + pass + spi.configure(baudrate=BAUD_RATE, phase=0, polarity=0) + + # Pick a random address, write to it, read from it, and see if they match + pass_test = True + for i in range(NUM_SPI_TESTS): + + # Randomly pick an address and a data value (one byte) + mem_addr = random.randint(0, EEPROM_SPI_MAX_ADDR) + mem_data = random.randint(0, 255) + print("Address:\t" + hex(mem_addr)) + print("Writing:\t" + hex(mem_data)) + + # Try writing this random value to the random address + result = _eeprom_spi_write_byte(spi, cs, mem_addr, mem_data) + if result == False: + print("FAIL: SPI could not communicate") + pass_test = False + break + + # Try reading the written value back from EEPRom + result = _eeprom_spi_read_byte(spi, cs, mem_addr) + print("Read:\t\t" + hex(result[1][0])) + print() + if result[0] == False: + print("FAIL: SPI could not communicate") + pass_test = False + break + + # Compare the read value to the original value + if result[1][0] != mem_data: + print("FAIL: Data does not match") + pass_test = False + break + + # Release SPI pins + spi.deinit() + + # Return results + if pass_test: + return PASS, [mosi_pin, miso_pin, sck_pin] + else: + return FAIL, [mosi_pin, miso_pin, sck_pin] + + else: + print("No SPI pins found") + return NA, [] + +def _main(): + + # List out all the pins available to us + pins = [p for p in dir(board)] + print() + print("All pins found:", end=' ') + + # Print pins + for p in pins: + print(p, end=' ') + print('\n') + + # Run test + result = run_test(pins) + print() + print(result[0]) + print("Pins tested: " + str(result[1])) + +# Execute only if run as main.py or code.py +if __name__ == "__main__": + _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/uart_test.py b/tests/board_test_suite/source/uart_test.py new file mode 100644 index 0000000000000..1478a37386faa --- /dev/null +++ b/tests/board_test_suite/source/uart_test.py @@ -0,0 +1,121 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Shawn Hymel 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. +""" +`uart_test` +==================================================== +UART Test Module + +* Author(s): Shawn Hymel +* Date: December 8, 2018 + +Implementation Notes +-------------------- +Performs random writes and reads across UART. + +You will need to connect a loopback wire from TX to RX on your board. + +Run this script as its own main.py to individually run the test, or compile +with mpy-cross and call from separate test script. +""" + +import board +import busio +import random + +# Constants +TX_PIN_NAME = 'TX' +RX_PIN_NAME = 'RX' +BAUD_RATE = 9600 +NUM_UART_BYTES = 40 # Number of bytes to transmit over UART +ASCII_MIN = 0x21 # '!' Lowest ASCII char in random range (inclusive) +ASCII_MAX = 0x7E # '~' Highest ASCII char in random range (inclusive) + +# Test result strings +PASS = "PASS" +FAIL = "FAIL" +NA = "N/A" + +def run_test(pins, tx_pin=TX_PIN_NAME, rx_pin=RX_PIN_NAME, baud_rate=BAUD_RATE): + + # Echo some values over the UART + if list(set(pins).intersection(set([tx_pin, rx_pin]))): + + # Tell user to create loopback connection + print("Connect a wire from TX to RX. Press enter to continue.") + input() + + # Initialize UART + uart = busio.UART(getattr(board, tx_pin), + getattr(board, rx_pin), + baudrate=baud_rate) + uart.reset_input_buffer() + + # Generate test string + test_str = "" + for i in range(NUM_UART_BYTES): + test_str += chr(random.randint(ASCII_MIN, ASCII_MAX)) + + # Transmit test string + uart.write(test_str) + print("Transmitting:\t" + test_str) + + # Wait for received string + data = uart.read(len(test_str)) + recv_str = '' + if data is not None: + recv_str = ''.join([chr(b) for b in data]) + print("Received:\t" + recv_str) + + # Release UART pins + uart.deinit() + + # Compare strings + if recv_str == test_str: + return PASS, [tx_pin, rx_pin] + else: + return FAIL, [tx_pin, rx_pin] + + else: + print("No UART pins found") + return NA, [] + +def _main(): + + # List out all the pins available to us + pins = [p for p in dir(board)] + print() + print("All pins found:", end=' ') + + # Print pins + for p in pins: + print(p, end=' ') + print('\n') + + # Run test + result = run_test(pins) + print() + print(result[0]) + print("Pins tested: " + str(result[1])) + +# Execute only if run as main.py or code.py +if __name__ == "__main__": + _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/voltage_monitor_test.py b/tests/board_test_suite/source/voltage_monitor_test.py new file mode 100644 index 0000000000000..8cc742cf25668 --- /dev/null +++ b/tests/board_test_suite/source/voltage_monitor_test.py @@ -0,0 +1,111 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Shawn Hymel 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. +""" +`voltage_monitor_test` +==================================================== +Voltage Monitor Test Module + +* Author(s): Shawn Hymel +* Date: December 8, 2018 + +Implementation Notes +-------------------- +Prints out the measured voltage on any onboard voltage/battery monitor pins. +Note that these pins sometimes have an onboard voltage divider to decrease +the voltage. + +Requires multimeter + +Run this script as its own main.py to individually run the test, or compile +with mpy-cross and call from separate test script. +""" + +import board +import analogio + +# Constants +VOLTAGE_MONITOR_PIN_NAMES = ['VOLTAGE_MONITOR', 'BATTERY'] +ANALOG_REF = 3.3 # Reference analog voltage +ANALOGIN_BITS = 16 # ADC resolution (bits) for CircuitPython + +# Test result strings +PASS = "PASS" +FAIL = "FAIL" +NA = "N/A" + +def run_test(pins): + + # Look for pins with battery monitoring names + monitor_pins = list(set(pins).intersection(set(VOLTAGE_MONITOR_PIN_NAMES))) + + # Print out voltage found on these pins + if monitor_pins: + + # Print out the monitor pins found + print("Voltage monitor pins found:", end=' ') + for p in monitor_pins: + print(p, end=' ') + print('\n') + + # Print out the voltage found on each pin + for p in monitor_pins: + monitor = analogio.AnalogIn(getattr(board, p)) + voltage = (monitor.value * ANALOG_REF) / (2**ANALOGIN_BITS) + print(p + ": {:.2f}".format(voltage) + " V") + monitor.deinit() + print() + + # Ask the user to check these voltages + print("Use a multimeter to verify these voltages.") + print("Note that some battery monitor pins might have onboard " + + "voltage dividers.") + print("Do the values look reasonable? [y/n]") + if input() == 'y': + return PASS, monitor_pins + else: + return FAIL, monitor_pins + + else: + print("No battery monitor pins found") + return NA, [] + +def _main(): + + # List out all the pins available to us + pins = [p for p in dir(board)] + print() + print("All pins found:", end=' ') + + # Print pins + for p in pins: + print(p, end=' ') + print('\n') + + # Run test + result = run_test(pins) + print() + print(result[0]) + print("Pins tested: " + str(result[1])) + +# Execute only if run as main.py or code.py +if __name__ == "__main__": + _main() \ No newline at end of file From 9d6d94b5f5b4699eecfa82c341761f5e48362745 Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Sat, 8 Dec 2018 16:48:26 -0600 Subject: [PATCH 009/153] Renamed image --- .../doc/{test_jib.png => test_jig.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/board_test_suite/doc/{test_jib.png => test_jig.png} (100%) diff --git a/tests/board_test_suite/doc/test_jib.png b/tests/board_test_suite/doc/test_jig.png similarity index 100% rename from tests/board_test_suite/doc/test_jib.png rename to tests/board_test_suite/doc/test_jig.png From 7d6ceeac5634e338c5d960c59bf4345860a61bbf Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Sat, 8 Dec 2018 16:58:51 -0600 Subject: [PATCH 010/153] Renamed doc to docs and updated README with rst. --- tests/board_test_suite/README.rst | 5 +++-- tests/board_test_suite/{doc => docs}/test_jig.fzz | Bin tests/board_test_suite/{doc => docs}/test_jig.png | Bin .../board_test_suite/{doc => docs}/test_jig_bb.png | Bin 4 files changed, 3 insertions(+), 2 deletions(-) rename tests/board_test_suite/{doc => docs}/test_jig.fzz (100%) rename tests/board_test_suite/{doc => docs}/test_jig.png (100%) rename tests/board_test_suite/{doc => docs}/test_jig_bb.png (100%) diff --git a/tests/board_test_suite/README.rst b/tests/board_test_suite/README.rst index 7fed9d35b1d54..ccf008d6313a0 100644 --- a/tests/board_test_suite/README.rst +++ b/tests/board_test_suite/README.rst @@ -46,11 +46,12 @@ You will need the following components: Connect the components as shown to your board. -![Test jig Fritzing diagram](doc/test_jig.png) +.. image:: docs/test_jig.png + :alt: Test jig Fritzing diagram Copy the *lib* folder to the CIRCUITPYTHON drive. Copy *main.py* to the root directory of your CIRCUITPYTHON drive. Open a Serial terminal and connect to the board. Follow the directions given to run through the tests. Building ======== -Individual test modules can be built with the mpy-cross cross-compiler. This is required to save RAM space if you plan to run more than one test at a time. See [the mpy-cross directory in circuitpython](https://github.com/adafruit/circuitpython/tree/master/mpy-cross) to learn more. +Individual test modules can be built with the mpy-cross cross-compiler. This is required to save RAM space if you plan to run more than one test at a time. See `the mpy-cross directory in circuitpython `_ to learn more. diff --git a/tests/board_test_suite/doc/test_jig.fzz b/tests/board_test_suite/docs/test_jig.fzz similarity index 100% rename from tests/board_test_suite/doc/test_jig.fzz rename to tests/board_test_suite/docs/test_jig.fzz diff --git a/tests/board_test_suite/doc/test_jig.png b/tests/board_test_suite/docs/test_jig.png similarity index 100% rename from tests/board_test_suite/doc/test_jig.png rename to tests/board_test_suite/docs/test_jig.png diff --git a/tests/board_test_suite/doc/test_jig_bb.png b/tests/board_test_suite/docs/test_jig_bb.png similarity index 100% rename from tests/board_test_suite/doc/test_jig_bb.png rename to tests/board_test_suite/docs/test_jig_bb.png From a3f46a3ccb362c26722cb5af960dfcd87f1ba4ea Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Sat, 8 Dec 2018 17:00:04 -0600 Subject: [PATCH 011/153] Removed mpy-cross binary --- tests/board_test_suite/mpy-cross | Bin 194960 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/board_test_suite/mpy-cross diff --git a/tests/board_test_suite/mpy-cross b/tests/board_test_suite/mpy-cross deleted file mode 100644 index 8dbdb9ab9dcd320549d19e38ef8506d0a96ec629..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 194960 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 z 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 Date: Sat, 8 Dec 2018 17:40:46 -0600 Subject: [PATCH 012/153] Added SD_CD pin definition --- ports/atmel-samd/boards/arduino_mkrzero/pins.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/atmel-samd/boards/arduino_mkrzero/pins.c b/ports/atmel-samd/boards/arduino_mkrzero/pins.c index e06400f35c75c..3ffd37fa6e415 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/pins.c +++ b/ports/atmel-samd/boards/arduino_mkrzero/pins.c @@ -36,6 +36,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA12) }, { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA15) }, { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_SD_CD), MP_ROM_PTR(&pin_PA27) }, { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PB08) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB09) }, { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB09) }, From f8ded46ad69ebba2de5b791bde16c50c4d2b1d1b Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Sat, 8 Dec 2018 17:42:42 -0600 Subject: [PATCH 013/153] Merged field in pin table in README. --- ports/atmel-samd/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 649a142e1d9ee..1ff2a0e80b29c 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -24,7 +24,7 @@ boards use smaller version. ===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ `microcontroller.pin` `board` ---------------------- ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Datasheet arduino_mkrzero arduino_zero circuitplayground_express feather_m0_adalogger feather_m0_basic feather_m0_express gemma_m0 metro_m0_express trinket_m0 ===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ PA00 ``ACCELEROMETER_SDA`` ``APA102_MOSI`` ``APA102_MOSI`` From a90343022acd9fc067abab3ac9840f97d0ee97ce Mon Sep 17 00:00:00 2001 From: Jerry Needell Date: Mon, 10 Dec 2018 16:35:40 -0500 Subject: [PATCH 014/153] enble MICROPYTHON_CPYTHON_COMPAT - fix mpconfigport.h to allow and enable a few more items for compatiblilty with other builds --- ports/nrf/mpconfigport.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 86f5af20ae532..db384d5102cb3 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -74,16 +74,16 @@ #define mp_builtin_open_obj mp_vfs_open_obj #endif -#define MICROPY_CPYTHON_COMPAT (0) +#define MICROPY_CPYTHON_COMPAT (1) #define MICROPY_STREAMS_NON_BLOCK (1) #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_USE_INTERNAL_ERRNO (0) #define MICROPY_PY_FUNCTION_ATTRS (1) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) -#define MICROPY_PY_BUILTINS_STR_CENTER (0) -#define MICROPY_PY_BUILTINS_STR_PARTITION (0) -#define MICROPY_PY_BUILTINS_STR_SPLITLINES (0) +#define MICROPY_PY_BUILTINS_STR_CENTER (1) +#define MICROPY_PY_BUILTINS_STR_PARTITION (1) +#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1) #define MICROPY_PY_BUILTINS_MEMORYVIEW (1) #define MICROPY_PY_BUILTINS_FROZENSET (1) #define MICROPY_PY_BUILTINS_EXECFILE (0) @@ -155,6 +155,7 @@ typedef long mp_off_t; #define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) #define mp_type_fileio mp_type_vfs_fat_fileio +#define mp_type_textio mp_type_vfs_fat_textio // extra built in modules to add to the list of known ones From 8fc72e897817630abc1ed1a7ecace44035d3879c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 10 Dec 2018 20:32:19 -0800 Subject: [PATCH 015/153] Add SPI and I2C to SparkFun nRF52840 mini definition and add it to Travis. --- .travis.yml | 2 +- ports/nrf/boards/sparkfun_nrf52840_mini/pins.c | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 202052e6c02e1..fad428949bbc9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ git: # that SDK is shortest and add it there. In the case of major re-organizations, # just try to make the builds "about equal in run time" env: - - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon" TRAVIS_SDK=arm:nrf:esp8266 + - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf:esp8266 - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300" TRAVIS_SDK=arm diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c index 210b1703260b5..5c50f55c7c656 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c @@ -13,7 +13,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_23) }, // D7 { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_09) }, // D8 { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_10) }, // D9 - + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_02) }, // D10 { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_03) }, // D11 { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_31) }, // D12 @@ -22,7 +22,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_P0_28) }, // D15 { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_P0_05) }, // D16 { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_P0_04) }, // D17 - + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, // A0 { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, // A1 { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, // A2 @@ -31,22 +31,25 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, // A5 { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, // A6 { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, // A7 - + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, // 8 - SDA { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, // 11 - SCL - + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_31) }, // 31 - MISO { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_03) }, // 3 - MOSI { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_30) }, // 30 - SCK - + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_07) }, // 7 - Blue LED - + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_P0_13) }, // 13 - Button - + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_15) }, // 15 - UART RX { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_17) }, // 17 - UART TX { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_QWIIC), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From a9d2bfada4485a807ad76b3d37e0e19209234da5 Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Tue, 11 Dec 2018 12:33:11 -0600 Subject: [PATCH 016/153] Removed test suite. Fixed links in main README. --- .travis.yml | 2 +- README.rst | 6 +- tests/board_test_suite/README.rst | 57 ----- tests/board_test_suite/docs/test_jig.fzz | Bin 7586 -> 0 bytes tests/board_test_suite/docs/test_jig.png | Bin 168217 -> 0 bytes tests/board_test_suite/docs/test_jig_bb.png | Bin 149724 -> 0 bytes .../lib/adafruit_bus_device/__init__.py | 0 .../lib/adafruit_bus_device/i2c_device.mpy | Bin 1707 -> 0 bytes .../lib/adafruit_bus_device/spi_device.mpy | Bin 1250 -> 0 bytes .../board_test_suite/lib/adafruit_sdcard.mpy | Bin 5349 -> 0 bytes tests/board_test_suite/lib/gpio_test.mpy | Bin 2036 -> 0 bytes tests/board_test_suite/lib/i2c_test.mpy | Bin 2420 -> 0 bytes tests/board_test_suite/lib/led_test.mpy | Bin 1765 -> 0 bytes tests/board_test_suite/lib/sd_cd_test.mpy | Bin 1342 -> 0 bytes tests/board_test_suite/lib/sd_test.mpy | Bin 2256 -> 0 bytes tests/board_test_suite/lib/spi_test.mpy | Bin 3232 -> 0 bytes tests/board_test_suite/lib/uart_test.mpy | Bin 1446 -> 0 bytes .../lib/voltage_monitor_test.mpy | Bin 1423 -> 0 bytes tests/board_test_suite/main.py | 235 ------------------ tests/board_test_suite/source/gpio_test.py | 154 ------------ tests/board_test_suite/source/i2c_test.py | 191 -------------- tests/board_test_suite/source/led_test.py | 142 ----------- tests/board_test_suite/source/sd_cd_test.py | 110 -------- tests/board_test_suite/source/sd_test.py | 157 ------------ tests/board_test_suite/source/spi_test.py | 232 ----------------- tests/board_test_suite/source/uart_test.py | 121 --------- .../source/voltage_monitor_test.py | 111 --------- 27 files changed, 5 insertions(+), 1513 deletions(-) delete mode 100644 tests/board_test_suite/README.rst delete mode 100644 tests/board_test_suite/docs/test_jig.fzz delete mode 100644 tests/board_test_suite/docs/test_jig.png delete mode 100644 tests/board_test_suite/docs/test_jig_bb.png delete mode 100644 tests/board_test_suite/lib/adafruit_bus_device/__init__.py delete mode 100644 tests/board_test_suite/lib/adafruit_bus_device/i2c_device.mpy delete mode 100644 tests/board_test_suite/lib/adafruit_bus_device/spi_device.mpy delete mode 100644 tests/board_test_suite/lib/adafruit_sdcard.mpy delete mode 100644 tests/board_test_suite/lib/gpio_test.mpy delete mode 100644 tests/board_test_suite/lib/i2c_test.mpy delete mode 100644 tests/board_test_suite/lib/led_test.mpy delete mode 100644 tests/board_test_suite/lib/sd_cd_test.mpy delete mode 100644 tests/board_test_suite/lib/sd_test.mpy delete mode 100644 tests/board_test_suite/lib/spi_test.mpy delete mode 100644 tests/board_test_suite/lib/uart_test.mpy delete mode 100644 tests/board_test_suite/lib/voltage_monitor_test.mpy delete mode 100644 tests/board_test_suite/main.py delete mode 100644 tests/board_test_suite/source/gpio_test.py delete mode 100644 tests/board_test_suite/source/i2c_test.py delete mode 100644 tests/board_test_suite/source/led_test.py delete mode 100644 tests/board_test_suite/source/sd_cd_test.py delete mode 100644 tests/board_test_suite/source/sd_test.py delete mode 100644 tests/board_test_suite/source/spi_test.py delete mode 100644 tests/board_test_suite/source/uart_test.py delete mode 100644 tests/board_test_suite/source/voltage_monitor_test.py diff --git a/.travis.yml b/.travis.yml index 13e97b72993ae..eaa22d8e9d25c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ env: - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express grandcentral_m4_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express makerdiary_nrf52840_mdk" TRAVIS_SDK=arm:nrf:esp8266 - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300" TRAVIS_SDK=arm + - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick" TRAVIS_SDK=arm addons: diff --git a/README.rst b/README.rst index 76c7315dc4851..ca529de627c69 100644 --- a/README.rst +++ b/README.rst @@ -60,13 +60,15 @@ Other supported using the `Adafruit CircuitPython SD library `__) - `Arduino Zero `__ -- `Arduino MKR Zero ` +- `Arduino MKR Zero `__ (MicroSD card + supported using the `Adafruit CircuitPython SD + library `__) "Third-party" or "non-Adafruit" boards ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - `Electronic Cats Meow Meow `__ -- `Electronic Cats CatWAN USB Stick ` +- `Electronic Cats CatWAN USB Stick `__ Download -------- diff --git a/tests/board_test_suite/README.rst b/tests/board_test_suite/README.rst deleted file mode 100644 index ccf008d6313a0..0000000000000 --- a/tests/board_test_suite/README.rst +++ /dev/null @@ -1,57 +0,0 @@ - -Introduction -============ - -Board test suite for CircuitPython. Run these tests to ensure that a CircuitPython port was created correctly, individual pin mappings are correct, and buses (e.g. SPI) work. - -Tests can be run individually. Copy code found in each *_test.py* module (found in *source* directory) to main.py in your CIRCUITPYTHON device drive. - -Alternatively, tests can be imported as modules. Copy the *lib* directory to CIRCUITPYTHON device drive and import the test in your own code. Each test can be run with the `run_test(pins)` function. - -The *main.py* example shows how to call tests from within a script. *main.py* runs the following tests: - - * LED Test - * GPIO Test - * Voltage Monitor Test - * UART Test - * SPI Test - * I2C Test - -Dependencies -============= - -This test suite depends on: - -* `Adafruit CircuitPython `_ -* `SD Card `_ -* `Bus Device `_ - -Please ensure all dependencies are available on the CircuitPython filesystem. -This is easily achieved by downloading -`the Adafruit library and driver bundle `_. - -Usage Example -============= - -You will need the following components: - -* Multimeter -* LED -* 1x 330 Ohm resistor -* 2x 4.7k Ohm resistor -* Microchip 25AA040A SPI EEPROM -* Microchip AT24HC04B I2C EEPROM -* Breadboard -* Wires - -Connect the components as shown to your board. - -.. image:: docs/test_jig.png - :alt: Test jig Fritzing diagram - -Copy the *lib* folder to the CIRCUITPYTHON drive. Copy *main.py* to the root directory of your CIRCUITPYTHON drive. Open a Serial terminal and connect to the board. Follow the directions given to run through the tests. - -Building -======== - -Individual test modules can be built with the mpy-cross cross-compiler. This is required to save RAM space if you plan to run more than one test at a time. See `the mpy-cross directory in circuitpython `_ to learn more. diff --git a/tests/board_test_suite/docs/test_jig.fzz b/tests/board_test_suite/docs/test_jig.fzz deleted file mode 100644 index e97a8402450233268ca719eaebf58edac4f0e627..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7586 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 diff --git a/tests/board_test_suite/docs/test_jig.png b/tests/board_test_suite/docs/test_jig.png deleted file mode 100644 index 22dd927b2946acd3d4abb2a2e6e59dd9147a0c26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168217 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

bw?l2}_e-%B6Ffa@IVmCA^R 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 BtknPj diff --git a/tests/board_test_suite/lib/adafruit_bus_device/__init__.py b/tests/board_test_suite/lib/adafruit_bus_device/__init__.py deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/tests/board_test_suite/lib/adafruit_bus_device/i2c_device.mpy b/tests/board_test_suite/lib/adafruit_bus_device/i2c_device.mpy deleted file mode 100644 index f33d4d495fe9dbe2647a0db93faede76ead9364e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1707 zcma)6-*4Mg6h1djnxtE^q-&jwrimeL3e%JzOHrh0+EUg^@W24I8V^OfapLR6B8@xy zdRrdQ97K6Q;++>>c;qQbyYdHs;J<)>Vt{ypbM2V0sc4Dh==lCP-#Op;KEE%;$~Pns zzm*1L$VhIts(S!`%UPmcA$d@9L}?Rwl^8K~mE;anw~lPX>$BUh>xOPRp2ca$bE&}| zSzT7QwC*gd9S;*)O{+C8QTm8Eu4NA>O;PHwW1G_Sd)nRI;L1EA#BKFBKXz}{>klm6 z^E$PzeN>NN>N^qMUCZer?uSF(!=&$cZkVZtmsmV#1mGWXx^FH`!^)BE8GJZcS)PnvR=Zde0uCmuW4Q`+`8b-C{F zq=?wSNLhn$VF?3#kGtGHz8V~+yvGK}a+n}Zaho$Ipq@Pu$zf@fTaf@~E*HeWZ?%=m zTh+%(W&8fe?`|PW4e%!=nV8W0^J(iNxRZfNDNm+($&6{cjobd)MH7B&Hhk^Q8WcZ+ zkwJc(l&+EKX|R87wx9L2;zP*Cr+*ma6SCJJ{!Z|>o12tg!{pk|WL#Y%({XiOs48lG z0YbSmqlX)@@S+sP01_Z-J|(w!k^y5s1>716%w*hk3ce1G}A-uGB=bjcft3=+yU z6DpVLhT$;RjX~UHee;5y4!Fg8wt~V{!Yhi-mD#PE%GQ&uG{j;6mo`v(qkaD}GCAH{ zBgo8nbDc~I(+4pP8;vIO>PAHkFLv@$tuU*#Sne>alz{DUwokuTIgZy0l9t1D>lo4yb=?4^5 z!z!m}z*F?!8QSj|y6+s#_k;PBq&2GkxKtt&`FA*#zk#!0{Y#>aOB-a0i_dWJ-28$d zzZaQcfrk5RAmNkj>8{SXBd8b8`b=VTQwdeQM9G5o49QOfK9(ZS{ws(1Itiz`EUb=` zHJOt}lh2~Xz69>Ybyv{y1QnVQw*R(rBlLPOfxzz1pNdF#M^o5W0XZElt;@Y6FTvj4@jO9XvFWv(egNxt(1X{Wyf$8SW}!kgrk%sg+sV$n{r%qCCEwW0f)DX=v5cb7OVt+T zCkXu#1(0HpLQ))ZH4qcf7?TnZUk%<}*Bf@5+?!PzO4GD8itDz88)QRMNzpR2L0B-l zfl{GVs6;T{Af~119gKq*o5avD4lP%oKK70bBLHi$MX6!kDHhi>+Oq2fRbMZjq$xf) z$@fSzRhGBfr7d>pL)+@#RA7gyeh)=RKos_J&fLsSPw5=r*)WL9Kx7%C^0>OWQ%Vh-%s)3%fWsVO1+~SH^1Kcv0Y-Cn9^CMv?TBz>Nn@vc1AHq<37@VZ25Y_i{o@aTfw;nD|EegnzqiYNd8 diff --git a/tests/board_test_suite/lib/adafruit_sdcard.mpy b/tests/board_test_suite/lib/adafruit_sdcard.mpy deleted file mode 100644 index 03f65fa63fb0cf6a05906fa196a582521f30da5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5349 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 DGa*eK diff --git a/tests/board_test_suite/lib/i2c_test.mpy b/tests/board_test_suite/lib/i2c_test.mpy deleted file mode 100644 index 201d2c97438eda619809e0adb2decb497b55dfc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2420 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 diff --git a/tests/board_test_suite/lib/spi_test.mpy b/tests/board_test_suite/lib/spi_test.mpy deleted file mode 100644 index d07d186859f8930677d136f60107a03e8dd113da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3232 zcmai1OK%(36~2cLk+iLbqNI@>j;N75qA1y7Bsw$!IVeDjOu{;nC{nTtsK8{z8A^kY zGsMg=sTP5Td3a%&QpwXCX~SU_OyZ9K`W6C-KfFUX91A562!xAC8*V+nm>+9QbiMGr%*zTm^mtm{))6qp$BlQ8z+7aTtY4|xt+ z{4{*T&%nq0b@+tm;ZuGV9`JFn_&FGB9q|c!oCjtB_yu5Y0Dl9RMc{A31S!H*(aR@c z0;uHUGce(ylAm9J=mbQsK{N`{NhtcRibMPzcsIb`hbTvw82K(UWJT|TL{cNW!8huf z)U3%rju=`~ugI?%4Mi|z!%Q{~{d=0IOU@XQlzqh%Yl_yD{CiD9(VTHe7gb5CyOYmU z>asJeZIlbcbP$S#bzwcbmiMg{${WLU=s@1`>b)!Y+W|be)aBK3M-AQ0Zs&wjb}K); zzP%=tiv?jTU*0OelFt`Q8xF8jDwo22dSNTyyP=fN=6dy=Qm)XemvZG&uf9{tuSa?f z7K*~%!q#XHw3hv;kj>>vZLE-57224um@Su`;mvH}9UmRM>#t=!>)Eg%%MD$t3zX~+ zM8#zK09`R*AsR1Il1m@4Zxd$w5k`qMDj>aKIg(`vXV;-jt_e1ZZ4q zP4nXy8 zZK7;~`j%$k{xauxBF81g@6kJ$g&IQ*6ZrZeb{IhWyL%!4<%FDrriDaUhT9i{a>(}Ss zpHUVUml_N4#7t%W^>_lOg~UvKpTDOjXy&~j>_5pP31UyFaNLd&2{LAj{R^4!OOV2u z$->#oiJ_N{HW8rnU0U|pQHZSq`x#*)a3*=G@D(DHd6;|?9>;SKc}%l;3}SD&drl<} zb~9)HG0LyH@(G^(1inra>q+cwECrc=A3cc`fcXiqQ^4EI0IBe8X~Jr9ZQl ze$S3WtOypHfU4&Yu7YV&_56{3;}WpP;@g@Z|C5&m`ZA=a@#r7WFiU zK83$Y?^x^#U6i~psFf{x>UnG0n(kOaub*4fopT}Q+>~YSdiH16+$9GNTCKk>-}?4; z@hFvg65B@4Qcp9NEp`EHu4$y+=!ogC{Y@@Yc5lKajbm)9?Q%OH?0hxFFujIsUcnk9 z>xNu06-}jpzo8@KjKNh+RdI=PK}Bse&2I0#l5_fTLEUJYfqmH&O;f+ns&k6&SRdNh z-YRZy;dvKu)7)5;Qr#i1jVbt=tD$a^6F+{Jd#zM}3s z*!L7lXY1e+;j9Hp*d10vJ%%0J8HXfUQ5Cb>*Buy}dVu&EifRPwnxP0N1?!5TQ6XSd z-lOwS#h{b1*uGhjTT?2!Ryj}_Tq>Q-F1@~#<($_AhYWCZA!)=oQ{&77nOiM$c%0Kz zTXPR2jjKgkaygmC65Wb-fh;uTq%lRG94n3~tyz;e?3cJ)uQ#!2;vN0}4c8nCIV|U# zq{)VDp)Q)017l=evn^APxT@AvrIru7B7P$GX+`_>VqA+aD|7LAtXS`Q*k96OBjL{% zn4z==VfGT{SAaFHtX v^(;#(++>gtAS95%e=U%MO@clK$d|`EW9fe#?Ou9=mI1tt#-OJ+o?Q4Jx@gIz diff --git a/tests/board_test_suite/lib/uart_test.mpy b/tests/board_test_suite/lib/uart_test.mpy deleted file mode 100644 index ecb47c908d404661fc99c16422452db5eb6a714e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1446 zcmZ{kO>7%Q6vyZ7`ZEbF{^+KO*Xxb6a_mTPTNl?-R3Ww@MMlJO97h=Cu-SNLlP&hH z*0C@u8Z1L_6k(i0bY;f7$wYc~!8Tbg=&^mg#PYE_M;$0f%GwuVziHg6bFt2=@M|4 zL7Ihl_bHO*;9F@PzL64S__@Rbmjo#ZoB)yloCs115|mb(;9inT~3^ii;gL*Z$PMYpJ$2Zaa=)`FCj>uvJsDTBDAs z)u(H9rBW&@WqEy#sn(~fXT$Ik?CVjCO)2^urS}pSuqCy#;U3wD$+ki&I@b33LY)W}6qrR^j#GMgnvrDcC^d zBVl2z<2e?5O~Y|n2fH(d>0;Z#4cD+t>hQO1;_@42yW@I%_~ryRF4RcvPRnq~cyA@_M9Y>)RT617 zQMWp#CWR3Kgu+GgE_}I6_}f7D-dUYN4+toI4c?CzULI^u-K6Kxuv+c&SCy(nmM`^u z)5F&#TA*ydwVbxn*Nnw~ zUQswXeKgT=Z3di+aUq`CpKS@}f AoB#j- diff --git a/tests/board_test_suite/lib/voltage_monitor_test.mpy b/tests/board_test_suite/lib/voltage_monitor_test.mpy deleted file mode 100644 index b04c848b970e4a40f938cd2b8b5282cc926e1c38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1423 zcmaKs&2QsG6u{>>X%ZFoBWZEkts7>Ao6Sa$ij*i)wE}settz$YS13Xea^3Z~G1#8S zGl>)-v}vWiBXQvm;KXUuB5~nBfg69p-uBLg6#`BOX6$s!vKwsq&GUORZ|wJe^EMO8 ztDb`7HC;nlxZN%<*u~=N1O35N8KJ)i*>(=}9EfoW^eMZ!q832ao&wla5oYIi;IcD_eFZXFTRr-939 zXmY}MrPH4{q*iFhGGhgnM~__kR7u}8n$4Bn4`=tcHk!uTin+PfSZ{9an%nCQvtewm z>`fXCV`FR0++A6{605>+JD0IEjP%RW?=cm zG=(DHO*6JD3cL27eVxQoW$7e!6(K-qUV|(gU+>$C#W&qzb+J}uVpEL@KqP zk@hQkXhY#!sc6$+gCm~vVf}2NJw_svUm~@N>=URC*WS&cAB6Gr(pLNBzA&gu$d3Gm z@J~VECTL$HEeEHz;=qq*^H)Jr;kOel4}bptQxxDeD13#!ao~xn!xORgtgrwMs@A@f z;Y3Y@%qzk!$3#9Ur$}`|jzv*4^%gv;rw7^$47Zh*HX9AK>(M8t%a_9Bhr zYMb<2#uJS2m)(Gqkdb@brGYezujfQ36q6GqumL}>!{k#mGDZZ;dXPRM+~PbOk<_!i zE*VQj95S?j7d-JWZUgjbmU9+mNNlof_ONnYn7v6u0DCh7s{y6B=J5j#lyXd0alKbWrlalbWrN1}g^`kk?j IPb@G019&5)u>b%7 diff --git a/tests/board_test_suite/main.py b/tests/board_test_suite/main.py deleted file mode 100644 index 1c472f1ff6b22..0000000000000 --- a/tests/board_test_suite/main.py +++ /dev/null @@ -1,235 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`board_test_suite` -==================================================== -CircuitPython board hardware test suite - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Run this to test various input/output abilities of a board. Tests the following: - -* Onboard LEDs -* GPIO output -* Onboard battery voltage monitor -* SPI -* I2C - -You will need the following components: - -* Multimeter -* LED -* 1x 330 Ohm resistor -* 2x 4.7k Ohm resistor -* Microchip 25AA040A SPI EEPROM -* Microchip AT24HC04B I2C EEPROM -* Breadboard -* Wires - -Copy lib directory to CIRCUITPYTHON drive. Copy the contents of this file to -main.py in root of CIRCUITPYTHON. Open Serial terminal to board and follow -prompts given. -""" - -import board - -import led_test -import gpio_test -import voltage_monitor_test -import uart_test -import spi_test -import i2c_test - -# Constants -UART_TX_PIN_NAME = 'TX' -UART_RX_PIN_NAME = 'RX' -UART_BAUD_RATE = 9600 -SPI_MOSI_PIN_NAME = 'MOSI' -SPI_MISO_PIN_NAME = 'MISO' -SPI_SCK_PIN_NAME = 'SCK' -SPI_CS_PIN_NAME = 'D2' -I2C_SDA_PIN_NAME = 'SDA' -I2C_SCL_PIN_NAME = 'SCL' - -# Results dictionary -test_results = {} - -# Save tested pins -pins_tested = [] - -# Print welcome message -print() -print(" .... ") -print(" #@@%%%%%%&@@/ ") -print(" (&@%%%%%%%%%%%%%@& ") -print(" .(@&%%%@* *&%%%%%%@. ") -print(" ,@@&&%%%%%%%%//@%,/ /&%%%%%%@ ") -print(" %@%%%&%%%%%%%#(@@@&&%%%%%%%%@* ") -print(" @&%%&%%%%%%%%%%%%%%%%%%%%%%@/ ") -print(" &@@&%%%%&&&%%%%%%%%%%%%%%@, ") -print(" ,/ &@&&%%%%%%%%%%%%%%%%%@ ") -print(" ,* *@&%%%%%%%%%%%%# ") -print(" ( @%%%%%%%%%%%@ ") -print(" , @%%%%%%%%%%&@ ") -print(" #&%%%%%%%%%%@. ") -print(" #@###%%%%%%%@/ ") -print(" (@##(%%%%%%%@% ") -print(" /@###(#%%%%%&@ ") -print(" #@####%%%%%%%@ ") -print(" (@###(%%%%%%%@, ") -print(" .@##(((#%%%%%&( .,,. ") -print(" ,@#####%%%%%%%@ ,%@@%%%%%%%&@% ") -print(" ,#&@####(%%%%%%%@@@@@&%%%%%%%%%%%###& ") -print(" @%%@%####(#%%%%%&@%%%%%%%%%%%%%%##/((@@@@&* ") -print(" (##@%#####%%%%%%%@(#%%%(/####(/####(%@%%%%%%@/ ") -print(" (@&%@@###(#%%%%%%@&/####(/#####/#&@@&%%%%%%%##@ ") -print(" #@%%%%@#####(#%%%%%%@@@@@@@@@@@@@&%%%%%%%%%%%%#/(@@@@@/ ") -print(" @%(/#@%######%%%%%%%@%%%%%%%%%%%%%%%%%%%%%(/(###@%%%%%%@% ") -print(" .@@#(#@#####(#%%%%%%&@###//#####/#####/(####/#%@&%%%%%%%%&& ") -print(" /@%%&@@@(#((((#%%%%%%&@###((#####/#####((##%@@&%%%%%%%%%%%/@. ") -print(" ,@%%%%%%#####%%%%%%%%@@@@&&&&&&&%&@@@@@@&%%%%%%%%%%%%%%%##@, ") -print(" %%%%%%%%@######(%%%%%%%@&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#/(#&& ") -print(" (@###/(%@##((##(%%%%%%%%@%%%%%%%%%%%%%%%%%%%%%%%%%##%###/(&& ") -print(" ,@@%@%##((#%@#######%%%%%%%%@&%%%%##%%%%##%%%%#/#####((####(@* ") -print(" *&(, %@@%##%@#######(%%%%%%%%@#/#####((#####(#####(/#&@&. ") -print(" .@###((#%%%%%%%%%&@@###((#####(###%@@&, ") -print(" #@#(#######%&@@&* .*#&@@@@@@@%(, ") -print(" .,,,.. ") -print() -print("**********************************************************************") -print("* Welcome to the CircuitPython board test suite! *") -print("* Follow the directions to run each test. *") -print("**********************************************************************") -print() - -# List out all the pins available to us -pins = [p for p in dir(board)] -print("All pins found:", end=' ') - -# Print pins -for p in pins: - print(p, end=' ') -print('\n') - -# Run LED test -print("@)}---^----- LED TEST -----^---{(@") -print() -result = led_test.run_test(pins) -test_results["LED Test"] = result[0] -pins_tested.append(result[1]) -print() -print(result[0]) -print() - -# Run GPIO test -print("@)}---^----- GPIO TEST -----^---{(@") -print() -result = gpio_test.run_test(pins) -test_results["GPIO Test"] = result[0] -pins_tested.append(result[1]) -print() -print(result[0]) -print() - -# Run voltage monitor test -print("@)}---^----- VOLTAGE MONITOR TEST -----^---{(@") -print() -result = voltage_monitor_test.run_test(pins) -test_results["Voltage Monitor Test"] = result[0] -pins_tested.append(result[1]) -print() -print(result[0]) -print() - -# Run UART test -print("@)}---^----- UART TEST -----^---{(@") -print() -result = uart_test.run_test(pins, UART_TX_PIN_NAME, UART_RX_PIN_NAME, UART_BAUD_RATE) -test_results["UART Test"] = result[0] -pins_tested.append(result[1]) -print() -print(result[0]) -print() - -# Run SPI test -print("@)}---^----- SPI TEST -----^---{(@") -print() -result = spi_test.run_test( pins, - mosi_pin=SPI_MOSI_PIN_NAME, - miso_pin=SPI_MISO_PIN_NAME, - sck_pin=SPI_SCK_PIN_NAME, - cs_pin=SPI_CS_PIN_NAME) -test_results["SPI Test"] = result[0] -pins_tested.append(result[1]) -print() -print(result[0]) -print() - -# Run I2C test -print("@)}---^----- I2C TEST -----^---{(@") -print() -result = i2c_test.run_test(pins, sda_pin=I2C_SDA_PIN_NAME, scl_pin=I2C_SCL_PIN_NAME) -test_results["I2C Test"] = result[0] -pins_tested.append(result[1]) -print() -print(result[0]) -print() - -# Print out test results -print("@)}---^----- TEST RESULTS -----^---{(@") -print() - -# Find appropriate spaces for printing test results -num_spaces = 0 -for key in test_results: - if len(key) > num_spaces: - num_spaces = len(key) - -# Print test results -for key in test_results: - print(key + ":", end=' ') - for i in range(num_spaces - len(key)): - print(end=' ') - print(test_results[key]) -print() - -# Figure out which pins were tested and not tested -tested = [] -for sublist in pins_tested: - for p in sublist: - tested.append(p) -not_tested = list(set(pins).difference(set(tested))) - -# Print tested pins -print("The following pins were tested:", end=' ') -for p in tested: - print(p, end=' ') -print('\n') - -# Print pins not tested -print("The following pins were NOT tested:", end=' ') -for p in not_tested: - print(p, end=' ') -print('\n') \ No newline at end of file diff --git a/tests/board_test_suite/source/gpio_test.py b/tests/board_test_suite/source/gpio_test.py deleted file mode 100644 index eb88a1d2e0e34..0000000000000 --- a/tests/board_test_suite/source/gpio_test.py +++ /dev/null @@ -1,154 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`gpio_test` -==================================================== -GPIO Test Module - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Toggles all available GPIO on a board. Verify their operation with an LED, -multimeter, another microcontroller, etc. - -Run this script as its own main.py to individually run the test, or compile -with mpy-cross and call from separate test script. -""" - -import board -import digitalio -import supervisor -import time - -# Constants -LED_ON_DELAY_TIME = 0.2 # Seconds -LED_OFF_DELAY_TIME = 0.2 # Seconds -LED_PIN_NAMES = ['L', 'LED', 'RED_LED', 'GREEN_LED', 'BLUE_LED'] - -# Test result strings -PASS = "PASS" -FAIL = "FAIL" -NA = "N/A" - -# Determine if given value is a number -def _is_number(s): - try: - float(s) - return True - except ValueError: - return False - -# Release pins -def _deinit_pins(gpios): - for g in gpios: - g.deinit() - -# Toggle IO pins while waiting for answer -def _toggle_wait(gpios): - - global test_results - - timestamp = time.monotonic() - led_state = False - print("Are the pins listed above toggling? [y/n]") - while True: - if led_state: - if time.monotonic() > timestamp + LED_ON_DELAY_TIME: - led_state = False - timestamp = time.monotonic() - else: - if time.monotonic() > timestamp + LED_OFF_DELAY_TIME: - led_state = True - timestamp = time.monotonic() - for gpio in gpios: - gpio.value = led_state - if supervisor.runtime.serial_bytes_available: - answer = input() - if answer == 'y': - return True - else: - return False - break - -def run_test(pins): - - # Create a list of analog GPIO pins - analog_pins = [p for p in pins if p[0] == 'A' and _is_number(p[1])] - - # Create a list of digital GPIO - digital_pins = [p for p in pins if p[0] == 'D' and _is_number(p[1])] - - # Toggle LEDs if we find any - gpio_pins = analog_pins + digital_pins - if gpio_pins: - - # Create a list of IO objects for us to toggle - gpios = [digitalio.DigitalInOut(getattr(board, p)) for p in gpio_pins] - - # Print out the LEDs found - print("GPIO pins found:", end=' ') - for p in gpio_pins: - print(p, end=' ') - print('\n') - - # Set all IO to output - for gpio in gpios: - gpio.direction = digitalio.Direction.OUTPUT - - # Toggle pins while waiting for user to verify LEDs blinking - result = _toggle_wait(gpios) - - # Release pins - _deinit_pins(gpios) - - if result: - return PASS, gpio_pins - else: - return FAIL, gpio_pins - - else: - print("No GPIO pins found") - return NA, [] - -def _main(): - - # List out all the pins available to us - pins = [p for p in dir(board)] - print() - print("All pins found:", end=' ') - - # Print pins - for p in pins: - print(p, end=' ') - print('\n') - - # Run test - result = run_test(pins) - print() - print(result[0]) - print("Pins tested: " + str(result[1])) - -# Execute only if run as main.py or code.py -if __name__ == "__main__": - _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/i2c_test.py b/tests/board_test_suite/source/i2c_test.py deleted file mode 100644 index ef8d5f07f0de2..0000000000000 --- a/tests/board_test_suite/source/i2c_test.py +++ /dev/null @@ -1,191 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`i2c_test` -==================================================== -I2C Test Module - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Performs random writes and reads to I2C EEPROM. - -Requires Microchip AT24HC04B I2C EEPROM. - -Run this script as its own main.py to individually run the test, or compile -with mpy-cross and call from separate test script. -""" - -import board -import busio -import random -import time - -# Constants -SDA_PIN_NAME = 'SDA' -SCL_PIN_NAME = 'SCL' -NUM_I2C_TESTS = 10 # Number of times to write and read EEPROM values -EEPROM_I2C_MAX_ADDR = 255 # Self-imposed max memory address - -# Microchip AT24HC04B EEPROM I2C address -EEPROM_I2C_ADDR = 0x50 - -# Test result strings -PASS = "PASS" -FAIL = "FAIL" -NA = "N/A" - -# Open comms to I2C EEPROM by trying a write to memory address -def _eeprom_i2c_wait(i2c, i2c_addr, mem_addr, timeout = 1.0): - - # Try to access the I2C EEPROM (it becomes unresonsive during a write) - timestamp = time.monotonic() - while time.monotonic() < timestamp + timeout: - try: - i2c.writeto(i2c_addr, bytearray([mem_addr]), end=1, stop=False) - return True - except: - pass - - return False - -# Write to address. Returns status (True for successful write, False otherwise) -def _eeprom_i2c_write_byte(i2c, i2c_addr, mem_addr, mem_data, timeout = 1.0): - - # Make sure address is only one byte: - if mem_addr > 255: - return False - - # Make sure data is only one byte: - if mem_data > 255: - return False - - # Write data to memory at given address - try: - i2c.writeto(i2c_addr, bytearray([mem_addr, mem_data])) - except: - return False - - return True - -# Read from address. Returns tuple [status, result] -def _eeprom_i2c_read_byte(i2c, i2c_addr, mem_addr, timeout = 1.0): - - # Make sure address is only one byte: - if mem_addr > 255: - return False, bytearray() - - # Try writing to address (EEPROM is unresponsive while writing) - if _eeprom_i2c_wait(i2c, i2c_addr, mem_addr, timeout) == False: - return False, bytearray() - - # Finish the read - buf = bytearray(1) - i2c.readfrom_into(i2c_addr, buf) - - return True, buf - -def run_test(pins, sda_pin=SDA_PIN_NAME, scl_pin=SCL_PIN_NAME): - - # Write values to I2C EEPROM and verify the values match - if list(set(pins).intersection(set([sda_pin, scl_pin]))): - - # Tell user to connect EEPROM chip - print("Connect a Microchip AT24HC04B EEPROM I2C chip. " + - "Press enter to continue.") - input() - - # Set up I2C - i2c = busio.I2C(getattr(board, scl_pin), getattr(board, sda_pin)) - - # Wait for I2C lock - while not i2c.try_lock(): - pass - - # Pick a random address, write to it, read from it, and see if they match - pass_test = True - for i in range(NUM_I2C_TESTS): - - # Randomly pick an address and a data value (one byte) - mem_addr = random.randint(0, EEPROM_I2C_MAX_ADDR) - mem_data = random.randint(0, 255) - print("Address:\t" + hex(mem_addr)) - print("Writing:\t" + hex(mem_data)) - - # Try writing this random value to the random address - result = _eeprom_i2c_write_byte(i2c, EEPROM_I2C_ADDR, mem_addr, mem_data) - if result == False: - print("FAIL: I2C could not communicate") - pass_test = False - break - - # Try reading the written value back from EEPROM - result = _eeprom_i2c_read_byte(i2c, EEPROM_I2C_ADDR, mem_addr) - print("Read:\t\t" + hex(result[1][0])) - print() - if result[0] == False: - print("FAIL: I2C could not communicate") - pass_test = False - break - - # Compare the read value to the original value - if result[1][0] != mem_data: - print("FAIL: Data does not match") - pass_test = False - break - - # Release I2C pins - i2c.deinit() - - # Store results - if pass_test: - return PASS, [sda_pin, scl_pin] - else: - return FAIL, [sda_pin, scl_pin] - - else: - print("No I2C pins found") - return NA, [] - -def _main(): - - # List out all the pins available to us - pins = [p for p in dir(board)] - print() - print("All pins found:", end=' ') - - # Print pins - for p in pins: - print(p, end=' ') - print('\n') - - # Run test - result = run_test(pins) - print() - print(result[0]) - print("Pins tested: " + str(result[1])) - -# Execute only if run as main.py or code.py -if __name__ == "__main__": - _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/led_test.py b/tests/board_test_suite/source/led_test.py deleted file mode 100644 index 57e7b8b6c2156..0000000000000 --- a/tests/board_test_suite/source/led_test.py +++ /dev/null @@ -1,142 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`led_test` -==================================================== -LED Test Module - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Toggles all available onboard LEDs. You will need to manually verify their -operation by watching them. - -Run this script as its own main.py to individually run the test, or compile -with mpy-cross and call from separate test script. -""" - -import board -import digitalio -import supervisor -import time - -# Constants -LED_ON_DELAY_TIME = 0.2 # Seconds -LED_OFF_DELAY_TIME = 0.2 # Seconds -LED_PIN_NAMES = ['L', 'LED', 'RED_LED', 'GREEN_LED', 'BLUE_LED'] - -# Test result strings -PASS = "PASS" -FAIL = "FAIL" -NA = "N/A" - -# Release pins -def _deinit_pins(gpios): - for g in gpios: - g.deinit() - -# Toggle IO pins while waiting for answer -def _toggle_wait(gpios): - - global test_results - - timestamp = time.monotonic() - led_state = False - print("Are the pins listed above toggling? [y/n]") - while True: - if led_state: - if time.monotonic() > timestamp + LED_ON_DELAY_TIME: - led_state = False - timestamp = time.monotonic() - else: - if time.monotonic() > timestamp + LED_OFF_DELAY_TIME: - led_state = True - timestamp = time.monotonic() - for gpio in gpios: - gpio.value = led_state - if supervisor.runtime.serial_bytes_available: - answer = input() - if answer == 'y': - return True - else: - return False - break - -def run_test(pins): - - # Look for pins with LED names - led_pins = list(set(pins).intersection(set(LED_PIN_NAMES))) - - # Toggle LEDs if we find any - if led_pins: - - # Print out the LEDs found - print("LEDs found:", end=' ') - for p in led_pins: - print(p, end=' ') - print('\n') - - # Create a list of IO objects for us to toggle - leds = [digitalio.DigitalInOut(getattr(board, p)) for p in led_pins] - - # Set all LEDs to output - for led in leds: - led.direction = digitalio.Direction.OUTPUT - - # Blink LEDs and wait for user to verify test - result = _toggle_wait(leds) - - # Release pins - _deinit_pins(leds) - - if result: - return PASS, led_pins - else: - return FAIL, led_pins - - else: - print("No LED pins found") - return NA, [] - -def _main(): - - # List out all the pins available to us - pins = [p for p in dir(board)] - print() - print("All pins found:", end=' ') - - # Print pins - for p in pins: - print(p, end=' ') - print('\n') - - # Run test - result = run_test(pins) - print() - print(result[0]) - print("Pins tested: " + str(result[1])) - -# Execute only if run as main.py or code.py -if __name__ == "__main__": - _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/sd_cd_test.py b/tests/board_test_suite/source/sd_cd_test.py deleted file mode 100644 index cee1fd7ba2cc5..0000000000000 --- a/tests/board_test_suite/source/sd_cd_test.py +++ /dev/null @@ -1,110 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`sd_cd_test` -==================================================== -SD CD Test Module - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Reports the output of an SD card's chip detect (CD) pin. - -Requires SD card. - -Run this script as its own main.py to individually run the test, or compile -with mpy-cross and call from separate test script. -""" - -import board -import digitalio - -# Constants -SD_CD_PIN_NAME = 'SD_CD' - -# Test result strings -PASS = "PASS" -FAIL = "FAIL" -NA = "N/A" - -def run_test(pins, cd_pin=SD_CD_PIN_NAME): - - # Ask user to insert and remove SD card - if list(set(pins).intersection(set([cd_pin]))): - - # Configure CD pin as input with pullup - cd = digitalio.DigitalInOut(getattr(board, cd_pin)) - cd.direction = digitalio.Direction.INPUT - cd.pull = digitalio.Pull.UP - - # Tell user to insert SD card - print("Connect " + cd_pin + " to CD pin on SD card holder.") - print("Insert SD card into holder.") - print("Press enter to continue.") - input() - - # Make sure we see that the pin is low - if cd.value == True: - print("Error: Card not detected") - return FAIL, [cd_pin] - - # Tell user to remove SD card - print("Card detected. Remove card and press enter to continue.") - input() - - # Make sure we see that the pin is high - if cd.value == False: - print("Error: Card detected") - return FAIL, [cd_pin] - - # Test passed - print("Card removed") - return PASS, [cd_pin] - - else: - print("No CD pin found") - return NA, [] - - -def _main(): - - # List out all the pins available to us - pins = [p for p in dir(board)] - print() - print("All pins found:", end=' ') - - # Print pins - for p in pins: - print(p, end=' ') - print('\n') - - # Run test - result = run_test(pins) - print() - print(result[0]) - print("Pins tested: " + str(result[1])) - -# Execute only if run as main.py or code.py -if __name__ == "__main__": - _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/sd_test.py b/tests/board_test_suite/source/sd_test.py deleted file mode 100644 index 47f4510f7c0f2..0000000000000 --- a/tests/board_test_suite/source/sd_test.py +++ /dev/null @@ -1,157 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`sd_test` -==================================================== -SD Test Module - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Performs random writes and reads to SD card over SPI. - -Requires SD card. - -Requires adafruit_sdcard.mpy and adafruit_bus_device modules. - -Run this script as its own main.py to individually run the test, or compile -with mpy-cross and call from separate test script. -""" - -import adafruit_sdcard -import board -import busio -import digitalio -import storage -import random - -# Constants -MOSI_PIN_NAME = 'SD_MOSI' -MISO_PIN_NAME = 'SD_MISO' -SCK_PIN_NAME = 'SD_SCK' -CS_PIN_NAME = 'SD_CS' -FILENAME = "test.txt" # File that will be written to -BAUD_RATE = 100000 # Bits per second -NUM_UART_BYTES = 40 # Number of bytes to transmit over UART -ASCII_MIN = 0x21 # '!' Lowest ASCII char in random range (inclusive) -ASCII_MAX = 0x7E # '~' Highest ASCII char in random range (inclusive) - -# Test result strings -PASS = "PASS" -FAIL = "FAIL" -NA = "N/A" - -def run_test( pins, - mosi_pin=MOSI_PIN_NAME, - miso_pin=MISO_PIN_NAME, - sck_pin=SCK_PIN_NAME, - cs_pin=CS_PIN_NAME, - filename=FILENAME): - - # Write characters to file on SD card and verify they were written - if list(set(pins).intersection(set([mosi_pin, miso_pin, sck_pin]))): - - # Tell user to connect SD card - print("Insert SD card into holder and connect SPI lines to holder.") - print("Connect " + cs_pin + " to the CS (CD/DAT3) pin on the SD " + - "card holder.") - print("WARNING: " + filename + " will be created or overwritten.") - print("Press enter to continue.") - input() - - # Configure CS pin - cs = digitalio.DigitalInOut(getattr(board, cs_pin)) - cs.direction = digitalio.Direction.OUTPUT - cs.value = True - - # Set up SPI - spi = busio.SPI(getattr(board, sck_pin), - MOSI=getattr(board, mosi_pin), - MISO=getattr(board, miso_pin)) - - # Try to connect to the card and mount the filesystem - try: - sdcard = adafruit_sdcard.SDCard(spi, cs) - vfs = storage.VfsFat(sdcard) - storage.mount(vfs, "/sd") - except: - print("Could not mount SD card") - return FAIL, [mosi_pin, miso_pin, sck_pin] - - # Generate test string - test_str = "" - for i in range(NUM_UART_BYTES): - test_str += chr(random.randint(ASCII_MIN, ASCII_MAX)) - - # Write test string to a text file on the card - try: - with open("/sd/" + filename, "w") as f: - print("Writing:\t" + test_str) - f.write(test_str) - except: - print("Could not write to SD card") - return FAIL, [mosi_pin, miso_pin, sck_pin] - - # Read from test file on the card - read_str = "" - try: - with open("/sd/" + filename, "r") as f: - lines = f.readlines() - for line in lines: - read_str += line - print("Read:\t\t" + read_str) - except: - print("Could not read from SD card") - return FAIL, [mosi_pin, miso_pin, sck_pin] - - # Release SPI - spi.deinit() - - # Compare strings - if read_str == test_str: - return PASS, [mosi_pin, miso_pin, sck_pin] - else: - return FAIL, [mosi_pin, miso_pin, sck_pin] - -def _main(): - - # List out all the pins available to us - pins = [p for p in dir(board)] - print() - print("All pins found:", end=' ') - - # Print pins - for p in pins: - print(p, end=' ') - print('\n') - - # Run test - result = run_test(pins) - print() - print(result[0]) - print("Pins tested: " + str(result[1])) - -# Execute only if run as main.py or code.py -if __name__ == "__main__": - _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/spi_test.py b/tests/board_test_suite/source/spi_test.py deleted file mode 100644 index 9d508af9c8b6d..0000000000000 --- a/tests/board_test_suite/source/spi_test.py +++ /dev/null @@ -1,232 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`spi_test` -==================================================== -SPI Test Module - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Performs random writes and reads to SPI EEPROM. - -Requires Microchip 25AA040A SPI EEPROM. - -Run this script as its own main.py to individually run the test, or compile -with mpy-cross and call from separate test script. -""" - -import board -import digitalio -import busio -import random -import time - -# Constants -MOSI_PIN_NAME = 'MOSI' -MISO_PIN_NAME = 'MISO' -SCK_PIN_NAME = 'SCK' -CS_PIN_NAME = 'D2' -BAUD_RATE = 100000 # Bits per second -NUM_SPI_TESTS = 10 # Number of times to write and read EEPROM values - -# Microchip 25AA040A EEPROM SPI commands and bits -EEPROM_SPI_WRSR = 0x01 -EEPROM_SPI_WRITE = 0x02 -EEPROM_SPI_READ = 0x03 -EEPROM_SPI_WRDI = 0x04 -EEPROM_SPI_RDSR = 0x05 -EEPROM_SPI_WREN = 0x06 -EEPROM_SPI_WIP_BIT = 0 -EEPROM_SPI_MAX_ADDR = 255 # Self-imposed max memory address -EEPROM_I2C_MAX_ADDR = 255 # Self-imposed max memory address - -# Test result strings -PASS = "PASS" -FAIL = "FAIL" -NA = "N/A" - -# Wait for WIP bit to go low -def _eeprom_spi_wait(spi, cs, timeout = 1.0): - - # Continually read from STATUS register - timestamp = time.monotonic() - while time.monotonic() < timestamp + timeout: - - # Perfrom RDSR operation - cs.value = False - result = bytearray(1) - spi.write(bytearray([EEPROM_SPI_RDSR])) - spi.readinto(result) - cs.value = True - - # Mask out and compare WIP bit - if (result[0] & (1 << EEPROM_SPI_WIP_BIT)) == 0: - return True - - return False - -# Write to address. Returns status (True for successful write, False otherwise) -def _eeprom_spi_write_byte(spi, cs, address, data, timeout = 1.0): - - # Make sure address is only one byte: - if address > 255: - return False - - # Make sure data is only one byte: - if data > 255: - return False - - # Wait for WIP to be low - if _eeprom_spi_wait(spi, cs, timeout) == False: - return False - - # Enable writing - cs.value = False - spi.write(bytearray([EEPROM_SPI_WREN])) - cs.value = True - - # Write to address - cs.value = False - spi.write(bytearray([EEPROM_SPI_WRITE, address, data])) - cs.value = True - - return True - -# Read from address. Returns tuple [status, result] -def _eeprom_spi_read_byte(spi, cs, address, timeout = 1.0): - - # Make sure address is only one byte: - if address > 255: - return False, bytearray() - - # Wait for WIP to be low - if _eeprom_spi_wait(spi, cs, timeout) == False: - return False, bytearray() - - # Read byte from address - cs.value = False - result = bytearray(1) - spi.write(bytearray([EEPROM_SPI_READ, address])) - spi.readinto(result) - cs.value = True - - return True, result - -def run_test( pins, - mosi_pin=MOSI_PIN_NAME, - miso_pin=MISO_PIN_NAME, - sck_pin=SCK_PIN_NAME, - cs_pin=CS_PIN_NAME): - - # Write values to SPI EEPROM and verify the values match - if list(set(pins).intersection(set([mosi_pin, miso_pin, sck_pin]))): - - # Tell user to connect EEPROM chip - print("Connect a Microchip 25AA040A EEPROM SPI chip.") - print("Connect " + cs_pin + " to the CS pin on the 25AA040.") - print("Press enter to continue.") - input() - - # Configure CS pin - cs = digitalio.DigitalInOut(getattr(board, cs_pin)) - cs.direction = digitalio.Direction.OUTPUT - cs.value = True - - # Set up SPI - spi = busio.SPI(getattr(board, sck_pin), - MOSI=getattr(board, mosi_pin), - MISO=getattr(board, miso_pin)) - - # Wait for SPI lock - while not spi.try_lock(): - pass - spi.configure(baudrate=BAUD_RATE, phase=0, polarity=0) - - # Pick a random address, write to it, read from it, and see if they match - pass_test = True - for i in range(NUM_SPI_TESTS): - - # Randomly pick an address and a data value (one byte) - mem_addr = random.randint(0, EEPROM_SPI_MAX_ADDR) - mem_data = random.randint(0, 255) - print("Address:\t" + hex(mem_addr)) - print("Writing:\t" + hex(mem_data)) - - # Try writing this random value to the random address - result = _eeprom_spi_write_byte(spi, cs, mem_addr, mem_data) - if result == False: - print("FAIL: SPI could not communicate") - pass_test = False - break - - # Try reading the written value back from EEPRom - result = _eeprom_spi_read_byte(spi, cs, mem_addr) - print("Read:\t\t" + hex(result[1][0])) - print() - if result[0] == False: - print("FAIL: SPI could not communicate") - pass_test = False - break - - # Compare the read value to the original value - if result[1][0] != mem_data: - print("FAIL: Data does not match") - pass_test = False - break - - # Release SPI pins - spi.deinit() - - # Return results - if pass_test: - return PASS, [mosi_pin, miso_pin, sck_pin] - else: - return FAIL, [mosi_pin, miso_pin, sck_pin] - - else: - print("No SPI pins found") - return NA, [] - -def _main(): - - # List out all the pins available to us - pins = [p for p in dir(board)] - print() - print("All pins found:", end=' ') - - # Print pins - for p in pins: - print(p, end=' ') - print('\n') - - # Run test - result = run_test(pins) - print() - print(result[0]) - print("Pins tested: " + str(result[1])) - -# Execute only if run as main.py or code.py -if __name__ == "__main__": - _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/uart_test.py b/tests/board_test_suite/source/uart_test.py deleted file mode 100644 index 1478a37386faa..0000000000000 --- a/tests/board_test_suite/source/uart_test.py +++ /dev/null @@ -1,121 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`uart_test` -==================================================== -UART Test Module - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Performs random writes and reads across UART. - -You will need to connect a loopback wire from TX to RX on your board. - -Run this script as its own main.py to individually run the test, or compile -with mpy-cross and call from separate test script. -""" - -import board -import busio -import random - -# Constants -TX_PIN_NAME = 'TX' -RX_PIN_NAME = 'RX' -BAUD_RATE = 9600 -NUM_UART_BYTES = 40 # Number of bytes to transmit over UART -ASCII_MIN = 0x21 # '!' Lowest ASCII char in random range (inclusive) -ASCII_MAX = 0x7E # '~' Highest ASCII char in random range (inclusive) - -# Test result strings -PASS = "PASS" -FAIL = "FAIL" -NA = "N/A" - -def run_test(pins, tx_pin=TX_PIN_NAME, rx_pin=RX_PIN_NAME, baud_rate=BAUD_RATE): - - # Echo some values over the UART - if list(set(pins).intersection(set([tx_pin, rx_pin]))): - - # Tell user to create loopback connection - print("Connect a wire from TX to RX. Press enter to continue.") - input() - - # Initialize UART - uart = busio.UART(getattr(board, tx_pin), - getattr(board, rx_pin), - baudrate=baud_rate) - uart.reset_input_buffer() - - # Generate test string - test_str = "" - for i in range(NUM_UART_BYTES): - test_str += chr(random.randint(ASCII_MIN, ASCII_MAX)) - - # Transmit test string - uart.write(test_str) - print("Transmitting:\t" + test_str) - - # Wait for received string - data = uart.read(len(test_str)) - recv_str = '' - if data is not None: - recv_str = ''.join([chr(b) for b in data]) - print("Received:\t" + recv_str) - - # Release UART pins - uart.deinit() - - # Compare strings - if recv_str == test_str: - return PASS, [tx_pin, rx_pin] - else: - return FAIL, [tx_pin, rx_pin] - - else: - print("No UART pins found") - return NA, [] - -def _main(): - - # List out all the pins available to us - pins = [p for p in dir(board)] - print() - print("All pins found:", end=' ') - - # Print pins - for p in pins: - print(p, end=' ') - print('\n') - - # Run test - result = run_test(pins) - print() - print(result[0]) - print("Pins tested: " + str(result[1])) - -# Execute only if run as main.py or code.py -if __name__ == "__main__": - _main() \ No newline at end of file diff --git a/tests/board_test_suite/source/voltage_monitor_test.py b/tests/board_test_suite/source/voltage_monitor_test.py deleted file mode 100644 index 8cc742cf25668..0000000000000 --- a/tests/board_test_suite/source/voltage_monitor_test.py +++ /dev/null @@ -1,111 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Shawn Hymel 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. -""" -`voltage_monitor_test` -==================================================== -Voltage Monitor Test Module - -* Author(s): Shawn Hymel -* Date: December 8, 2018 - -Implementation Notes --------------------- -Prints out the measured voltage on any onboard voltage/battery monitor pins. -Note that these pins sometimes have an onboard voltage divider to decrease -the voltage. - -Requires multimeter - -Run this script as its own main.py to individually run the test, or compile -with mpy-cross and call from separate test script. -""" - -import board -import analogio - -# Constants -VOLTAGE_MONITOR_PIN_NAMES = ['VOLTAGE_MONITOR', 'BATTERY'] -ANALOG_REF = 3.3 # Reference analog voltage -ANALOGIN_BITS = 16 # ADC resolution (bits) for CircuitPython - -# Test result strings -PASS = "PASS" -FAIL = "FAIL" -NA = "N/A" - -def run_test(pins): - - # Look for pins with battery monitoring names - monitor_pins = list(set(pins).intersection(set(VOLTAGE_MONITOR_PIN_NAMES))) - - # Print out voltage found on these pins - if monitor_pins: - - # Print out the monitor pins found - print("Voltage monitor pins found:", end=' ') - for p in monitor_pins: - print(p, end=' ') - print('\n') - - # Print out the voltage found on each pin - for p in monitor_pins: - monitor = analogio.AnalogIn(getattr(board, p)) - voltage = (monitor.value * ANALOG_REF) / (2**ANALOGIN_BITS) - print(p + ": {:.2f}".format(voltage) + " V") - monitor.deinit() - print() - - # Ask the user to check these voltages - print("Use a multimeter to verify these voltages.") - print("Note that some battery monitor pins might have onboard " + - "voltage dividers.") - print("Do the values look reasonable? [y/n]") - if input() == 'y': - return PASS, monitor_pins - else: - return FAIL, monitor_pins - - else: - print("No battery monitor pins found") - return NA, [] - -def _main(): - - # List out all the pins available to us - pins = [p for p in dir(board)] - print() - print("All pins found:", end=' ') - - # Print pins - for p in pins: - print(p, end=' ') - print('\n') - - # Run test - result = run_test(pins) - print() - print(result[0]) - print("Pins tested: " + str(result[1])) - -# Execute only if run as main.py or code.py -if __name__ == "__main__": - _main() \ No newline at end of file From b1c882a26b171352a5ee653c4889f41731d41ba7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 11 Dec 2018 11:51:07 -0800 Subject: [PATCH 017/153] Default nrf boards to UF2 --- tools/build_board_info.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/build_board_info.py b/tools/build_board_info.py index eb9f28d901895..379cf55c4d51b 100644 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -21,24 +21,29 @@ # Default extensions extension_by_port = { - "nrf": BIN, + "nrf": UF2, "esp8266": BIN, "atmel-samd": UF2, } # Per board overrides extension_by_board = { - "feather_nrf52832": BIN, + # samd "arduino_mkr1300": BIN, "arduino_zero": BIN, "feather_m0_adalogger": BIN_UF2, "feather_m0_basic": BIN_UF2, "feather_m0_rfm69": BIN, "feather_m0_rfm9x": BIN, + + # nrf52832 + "feather_nrf52832": BIN, + "pca10040": BIN, + + # nRF52840 dev kits that may not have UF2 bootloaders, "makerdiary_nrf52840_mdk": HEX, - "particle_argon": UF2, - "particle_boron": UF2, - "particle_xenon": UF2 + "pca10056": BIN_UF2, + "pca10059": BIN_UF2 } def get_languages(): From 29f9794dcfeea9fb572d51751cdfdb37c9ac9afc Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 11 Dec 2018 11:57:52 -0800 Subject: [PATCH 018/153] Curly brace change to make it more consistent And to queue Travis --- ports/atmel-samd/boards/arduino_mkrzero/board.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/arduino_mkrzero/board.c b/ports/atmel-samd/boards/arduino_mkrzero/board.c index 770bc825938cd..0f60736a24006 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/board.c +++ b/ports/atmel-samd/boards/arduino_mkrzero/board.c @@ -28,8 +28,7 @@ #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" -void board_init(void) -{ +void board_init(void) { } bool board_requests_safe_mode(void) { From 1361391ed9e8cfbb8b4198117adf3d1d7d35fb31 Mon Sep 17 00:00:00 2001 From: TG-Techie <39284876+TG-Techie@users.noreply.github.com> Date: Wed, 12 Dec 2018 08:51:16 -0500 Subject: [PATCH 019/153] the logo dir's contents don't match readme description --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ca529de627c69..4fe979e490c44 100644 --- a/README.rst +++ b/README.rst @@ -209,7 +209,7 @@ amongst ports including CircuitPython: - ``extmod`` Shared C code used in multiple ports' modules. - ``lib`` Shared core C code including externally developed libraries such as FATFS. -- ``logo`` The MicroPython logo. +- ``logo`` The CircuitPython logo. - ``mpy-cross`` A cross compiler that converts Python files to byte code prior to being run in MicroPython. Useful for reducing library size. From 87073b4fbed938c92b0dfeb70c38fc5f94d1d7c6 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 12 Dec 2018 11:58:46 -0500 Subject: [PATCH 020/153] Update badge to travis-ci.com --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index ca529de627c69..a7516778e8d2e 100644 --- a/README.rst +++ b/README.rst @@ -68,7 +68,7 @@ Other ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - `Electronic Cats Meow Meow `__ -- `Electronic Cats CatWAN USB Stick `__ +- `Electronic Cats CatWAN USB Stick `__ Download -------- @@ -264,7 +264,7 @@ project. `⬆ back to top <#adafruit-circuitpython>`__ -.. |Build Status| image:: https://travis-ci.org/adafruit/circuitpython.svg?branch=master +.. |Build Status| image:: https://travis-ci.com/adafruit/circuitpython.svg?branch=master :target: https://travis-ci.org/adafruit/circuitpython .. |Doc Status| image:: https://readthedocs.org/projects/circuitpython/badge/?version=latest :target: http://circuitpython.readthedocs.io/ From e136222ae23b4a504838f2b413ba29865a73227c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 13 Dec 2018 23:48:53 +0700 Subject: [PATCH 021/153] use rbuf for busio uart --- ports/nrf/common-hal/busio/UART.c | 108 ++++++++++++++++-------------- ports/nrf/common-hal/busio/UART.h | 5 +- 2 files changed, 60 insertions(+), 53 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 70641bd79bd29..294957fd30fe1 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -52,21 +52,40 @@ static uint32_t get_nrf_baud (uint32_t baudrate); +static uint16_t ringbuf_count(ringbuf_t *r) +{ + volatile int count = r->iput - r->iget; + if ( count < 0 ) { + count += r->size; + } + + return (uint16_t) count; +} + +static void ringbuf_clear(ringbuf_t *r) +{ + r->iput = r->iget = 0; +} + static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) { busio_uart_obj_t* self = (busio_uart_obj_t*) context; switch ( event->type ) { case NRFX_UARTE_EVT_RX_DONE: - self->rx_count = event->data.rxtx.bytes; + for(uint8_t i=0; i < event->data.rxtx.bytes; i++) { + ringbuf_put(&self->rbuf, event->data.rxtx.p_data[i]); + } + + // keep receiving + _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, &self->rx_char, 1)); break; case NRFX_UARTE_EVT_TX_DONE: + // nothing to do break; case NRFX_UARTE_EVT_ERROR: - if ( self->rx_count == -1 ) { - self->rx_count = 0; - } + // Handle error break; default: @@ -110,12 +129,15 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, // Init buffer for rx if ( rx != mp_const_none ) { - self->buffer = (uint8_t *) gc_alloc(receiver_buffer_size, false, false); - if ( !self->buffer ) { + self->rbuf.buf = (uint8_t *) gc_alloc(receiver_buffer_size, false, false); + + if ( !self->rbuf.buf ) { nrfx_uarte_uninit(&self->uarte); mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); } - self->bufsize = receiver_buffer_size; + + self->rbuf.size = receiver_buffer_size; + self->rbuf.iget = self->rbuf.iput = 0; self->rx_pin_number = rx->number; claim_pin(rx); @@ -131,9 +153,8 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, self->baudrate = baudrate; self->timeout_ms = timeout * 1000; - // queue 1-byte transfer for rx_characters_available() - self->rx_count = -1; - _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1)); + // Initial wait for incoming byte + _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, &self->rx_char, 1)); } bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { @@ -147,7 +168,10 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { reset_pin_number(self->rx_pin_number); self->tx_pin_number = NO_PIN; self->rx_pin_number = NO_PIN; - gc_free(self->buffer); + + gc_free(self->rbuf.buf); + self->rbuf.size = 0; + self->rbuf.iput = self->rbuf.iget = 0; } } @@ -157,48 +181,33 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t mp_raise_ValueError(translate("No RX pin")); } - size_t remain = len; + size_t rx_bytes = 0; uint64_t start_ticks = ticks_ms; - while ( 1 ) { - // Wait for on-going transfer to complete - while ( (self->rx_count == -1) && (ticks_ms - start_ticks < self->timeout_ms) ) { + // Wait for all bytes received or timeout + while ( (ringbuf_count(&self->rbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP; - // Allow user to break out of a timeout with a KeyboardInterrupt. - if (mp_hal_is_interrupted()) { - return 0; - } -#endif - } - - // copy received data - if ( self->rx_count > 0 ) { - memcpy(data, self->buffer, self->rx_count); - data += self->rx_count; - remain -= self->rx_count; - - self->rx_count = 0; + MICROPY_VM_HOOK_LOOP ; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if ( mp_hal_is_interrupted() ) { + return 0; } +#endif + } - // exit if complete or time up - if ( !remain || !(ticks_ms - start_ticks < self->timeout_ms) ) { - break; - } + // prevent conflict with uart irq + NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte.p_reg)); - // prepare next receiving - const size_t cnt = MIN(self->bufsize, remain); - self->rx_count = -1; - _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, cnt)); + // copy received data + rx_bytes = ringbuf_count(&self->rbuf); + rx_bytes = MIN(rx_bytes, len); + for ( uint16_t i = 0; i < rx_bytes; i++ ) { + data[i] = ringbuf_get(&self->rbuf); } - // queue 1-byte transfer for rx_characters_available() - if ( self->rx_count == 0 ) { - self->rx_count = -1; - _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1)); - } + NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte.p_reg)); - return len - remain; + return rx_bytes; } // Write characters. @@ -258,15 +267,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat } uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { - return (self->rx_count > 0) ? self->rx_count : 0; + return ringbuf_count(&self->rbuf); } void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { - // Discard received byte, and queue 1-byte transfer for rx_characters_available() - if ( self->rx_count > 0 ) { - self->rx_count = -1; - _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1)); - } + // prevent conflict with uart irq + NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte.p_reg)); + ringbuf_clear(&self->rbuf); + NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte.p_reg)); } bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index e7543d6b1e69e..a8081dc1e6d1a 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -41,9 +41,8 @@ typedef struct { uint32_t baudrate; uint32_t timeout_ms; - uint8_t* buffer; - uint32_t bufsize; - volatile int32_t rx_count; + ringbuf_t rbuf; + uint8_t rx_char; // EasyDMA buf uint8_t tx_pin_number; uint8_t rx_pin_number; From b37b2fa7e72a6a8d04af90b1c8ae52fcf1980350 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 13 Dec 2018 23:56:06 +0700 Subject: [PATCH 022/153] overwrite old data if fifo is full --- ports/nrf/common-hal/busio/UART.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 294957fd30fe1..a291af5788727 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -73,7 +73,11 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) switch ( event->type ) { case NRFX_UARTE_EVT_RX_DONE: for(uint8_t i=0; i < event->data.rxtx.bytes; i++) { - ringbuf_put(&self->rbuf, event->data.rxtx.p_data[i]); + if ( ringbuf_put(&self->rbuf, event->data.rxtx.p_data[i]) < 0 ) { + // if full overwrite old data + (void) ringbuf_get(&self->rbuf); + ringbuf_put(&self->rbuf, event->data.rxtx.p_data[i]); + } } // keep receiving From 67522666737eb9c264b815ed0b33d3f0b0687652 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 18 Dec 2018 22:05:17 +0700 Subject: [PATCH 023/153] added pulsein using gpiote (gpio interrupt) --- ports/nrf/Makefile | 1 + ports/nrf/common-hal/pulseio/PulseIn.c | 218 +++++++++++++++++++++++-- ports/nrf/common-hal/pulseio/PulseIn.h | 6 +- ports/nrf/nrfx_config.h | 5 + ports/nrf/supervisor/port.c | 2 + 5 files changed, 219 insertions(+), 13 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index b8d186621f867..ca9583df7e085 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -101,6 +101,7 @@ SRC_NRFX = $(addprefix nrfx/,\ drivers/src/nrfx_timer.c \ drivers/src/nrfx_twim.c \ drivers/src/nrfx_uarte.c \ + drivers/src/nrfx_gpiote.c \ ) ifdef EXTERNAL_FLASH_DEVICES diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c index 3d6d266af3002..fa05de148ce21 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.c +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -27,6 +27,7 @@ #include "common-hal/pulseio/PulseIn.h" #include +#include #include "py/mpconfig.h" #include "py/gc.h" @@ -35,50 +36,245 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/pulseio/PulseIn.h" +#include "tick.h" +#include "nrfx_gpiote.h" + +// obj array to map pin -> self since nrfx hide the mapping +static pulseio_pulsein_obj_t* _objs[GPIOTE_CH_NUM]; + +// return index of the object in array +static int _find_pulsein_obj(pulseio_pulsein_obj_t* obj) { + for(int i = 0; i < NRFX_ARRAY_SIZE(_objs); i++ ) { + if ( _objs[i] == obj) { + return i; + } + } + + return -1; +} + +static void _pulsein_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { + // Grab the current time first. + uint32_t current_us; + uint64_t current_ms; + current_tick(¤t_ms, ¤t_us); + + pulseio_pulsein_obj_t* self = NULL; + for(int i = 0; i < NRFX_ARRAY_SIZE(_objs); i++ ) { + if ( _objs[i] && _objs[i]->pin == pin ) { + self = _objs[i]; + break; + } + } + + if ( !self ) return; + + if (self->first_edge) { + // first pulse is opposite state from idle + bool state = nrf_gpio_pin_read(self->pin); + if ( self->idle_state != state ) { + self->first_edge = false; + } + }else { + uint32_t ms_diff = current_ms - self->last_ms; + uint16_t us_diff = current_us - self->last_us; + uint32_t total_diff = us_diff; + + if (self->last_us > current_us) { + total_diff = 1000 + current_us - self->last_us; + if (ms_diff > 1) { + total_diff += (ms_diff - 1) * 1000; + } + } else { + total_diff += ms_diff * 1000; + } + uint16_t duration = 0xffff; + if (total_diff < duration) { + duration = total_diff; + } + + uint16_t i = (self->start + self->len) % self->maxlen; + self->buffer[i] = duration; + if (self->len < self->maxlen) { + self->len++; + } else { + self->start++; + } + } + + self->last_ms = current_ms; + self->last_us = current_us; +} + void pulsein_reset(void) { + if ( nrfx_gpiote_is_init() ) { + nrfx_gpiote_uninit(); + } + nrfx_gpiote_init(); + memset(_objs, 0, sizeof(_objs)); } void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { - mp_raise_NotImplementedError(NULL); + int idx = _find_pulsein_obj(NULL); + if ( idx < 0 ) { + mp_raise_NotImplementedError(NULL); + } + _objs[idx] = self; + + self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false); + if (self->buffer == NULL) { + mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t)); + } + + self->pin = pin->number; + self->maxlen = maxlen; + self->idle_state = idle_state; + self->start = 0; + self->len = 0; + self->first_edge = true; + self->paused = false; + self->last_us = 0; + self->last_ms = 0; + + claim_pin(pin); + + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_NOPULL, // idle_state ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_PULLUP, + .is_watcher = false, // nrf_gpio_cfg_watcher vs nrf_gpio_cfg_input + .hi_accuracy = true, + .skip_gpio_setup = false + }; + nrfx_gpiote_in_init(self->pin, &cfg, _pulsein_handler); + nrfx_gpiote_in_event_enable(self->pin, true); } bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { - return 1; + return self->pin == NO_PIN; } void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + return; + } + + nrfx_gpiote_in_event_disable(self->pin); + nrfx_gpiote_in_uninit(self->pin); + + // mark local array as invalid + int idx = _find_pulsein_obj(self); + if ( idx < 0 ) { + mp_raise_NotImplementedError(NULL); + } + _objs[idx] = NULL; + reset_pin_number(self->pin); + self->pin = NO_PIN; } void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { - + nrfx_gpiote_in_event_disable(self->pin); + self->paused = true; } void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration) { + // Make sure we're paused. + if ( !self->paused ) { + common_hal_pulseio_pulsein_pause(self); + } + + // Send the trigger pulse. + if (trigger_duration > 0) { + nrfx_gpiote_in_uninit(self->pin); + + nrf_gpio_cfg_output(self->pin); + nrf_gpio_pin_write(self->pin, !self->idle_state); + common_hal_mcu_delay_us((uint32_t)trigger_duration); + nrf_gpio_pin_write(self->pin, self->idle_state); + + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_NOPULL, // idle_state ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_PULLUP, + .is_watcher = false, // nrf_gpio_cfg_watcher vs nrf_gpio_cfg_input + .hi_accuracy = true, + .skip_gpio_setup = false + }; + nrfx_gpiote_in_init(self->pin, &cfg, _pulsein_handler); + } + + self->first_edge = true; + self->paused = false; + self->last_ms = 0; + self->last_us = 0; + nrfx_gpiote_in_event_enable(self->pin, true); } void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) { + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + self->start = 0; + self->len = 0; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } +} + +uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) { + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + + if (index < 0) { + index += self->len; + } + if (index < 0 || index >= self->len) { + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + mp_raise_IndexError(translate("index out of range")); + } + uint16_t value = self->buffer[(self->start + index) % self->maxlen]; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + + return value; } uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) { - return 0; + if (self->len == 0) { + mp_raise_IndexError(translate("pop from an empty PulseIn")); + } + + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + + uint16_t value = self->buffer[self->start]; + self->start = (self->start + 1) % self->maxlen; + self->len--; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + + return value; } uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { - return 0xadaf; + return self->maxlen; } bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) { - return false; + return self->paused; } uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { - return 0xadaf; -} - -uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) { - return 0xadaf; + return self->len; } diff --git a/ports/nrf/common-hal/pulseio/PulseIn.h b/ports/nrf/common-hal/pulseio/PulseIn.h index 666f5a164822a..a029129ac6ecd 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.h +++ b/ports/nrf/common-hal/pulseio/PulseIn.h @@ -33,7 +33,7 @@ typedef struct { mp_obj_base_t base; - uint8_t channel; + uint8_t pin; uint16_t* buffer; uint16_t maxlen; @@ -41,7 +41,9 @@ typedef struct { volatile uint16_t start; volatile uint16_t len; volatile bool first_edge; - uint16_t ticks_per_ms; + bool paused; + volatile uint64_t last_ms; + volatile uint16_t last_us; } pulseio_pulsein_obj_t; void pulsein_reset(void); diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index 1d3085e2b8e14..8676bd7f801af 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -84,4 +84,9 @@ #define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7 +// GPIO interrupt +#define NRFX_GPIOTE_ENABLED 1 +#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1 +#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 7 + #endif // NRFX_CONFIG_H__ diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index ece5bae297074..2e25c7d15129f 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -42,6 +42,7 @@ #include "common-hal/busio/SPI.h" #include "common-hal/pulseio/PWMOut.h" #include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PulseIn.h" #include "tick.h" static void power_warning_handler(void) { @@ -84,6 +85,7 @@ void reset_port(void) { spi_reset(); pwmout_reset(); pulseout_reset(); + pulsein_reset(); timers_reset(); reset_all_pins(); From a9f0b31a15b36e1fd184a318f4d0320df31de54d Mon Sep 17 00:00:00 2001 From: "Limor \"Ladyada\" Fried" Date: Wed, 19 Dec 2018 13:25:18 -0500 Subject: [PATCH 024/153] Update README.rst https://github.com/adafruit/circuitpython/issues/1410 --- ports/atmel-samd/README.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 1ff2a0e80b29c..6037c7d3b1c7a 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -170,13 +170,7 @@ These commands should be executed from the root directory of the repository Build commands are run from the ``circuitpython/ports/atmel-samd`` directory. -To build for the Arduino Zero: - -.. code-block:: shell - - make - -To build for other boards you must change it by setting ``BOARD``. For example: +To build for a given board you must specify it by setting ``BOARD``. For example: .. code-block:: shell From 5f3a259827a1c6d1e4292aa5a6198305e88abfef Mon Sep 17 00:00:00 2001 From: Carl Karsten Date: Thu, 20 Dec 2018 18:44:39 -0600 Subject: [PATCH 025/153] Sync with micropython. closes #1414 --- tools/tinytest-codegen.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index 7f14db4ba67c1..7a48f8a9a7406 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -23,7 +23,7 @@ def chew_filename(t): def script_to_map(test_file): r = {"name": chew_filename(test_file)["func"]} - with open(t) as test: + with open(test_file, "rb") as test: script = test.readlines() # Test for import skip_if and inject it into the test as needed. @@ -39,7 +39,11 @@ def script_to_map(test_file): continue script.insert(index + total_lines, "\t" + line) total_lines += 1 - r['script'] = escape(''.join(script)) + r['script'] = escape(b''.join(script)) + + with open(test_file + ".exp", "rb") as f: + r["output"] = escape(f.read()) + return r test_function = ( From bce6d124af6531f2d6ad6835546eaa471d0657a0 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 20 Dec 2018 21:28:36 -0500 Subject: [PATCH 026/153] Don't check for corrupt heap too early; Fix QSPI timing --- ports/nrf/supervisor/qspi_flash.c | 20 +++++++++++--------- supervisor/shared/stack.c | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index 048db06f20f77..4738607bff5b5 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -40,15 +40,13 @@ bool spi_flash_command(uint8_t command) { nrf_qspi_cinstr_conf_t cinstr_cfg = { - .opcode = 0, - .length = 0, + .opcode = command, + .length = 1, .io2_level = true, .io3_level = true, .wipwait = false, .wren = false }; - cinstr_cfg.opcode = command; - cinstr_cfg.length = 1; nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); return true; } @@ -91,8 +89,7 @@ bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { } bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) { - nrfx_qspi_read(data, length, address); - return true; + return nrfx_qspi_read(data, length, address) == NRFX_SUCCESS; } void spi_flash_init(void) { @@ -115,7 +112,7 @@ void spi_flash_init(void) { .dpmconfig = false }, .phy_if = { - .sck_freq = NRF_QSPI_FREQ_32MDIV16, // Start at a slow 2mhz and speed up once we know what we're talking to. + .sck_freq = NRF_QSPI_FREQ_32MDIV16, // Start at a slow 2MHz and speed up once we know what we're talking to. .sck_delay = 10, // min time CS must stay high before going low again. in unit of 62.5 ns .spi_mode = NRF_QSPI_MODE_0, .dpmen = false @@ -145,7 +142,7 @@ void spi_flash_init_device(const external_flash_device* device) { // Switch to single output line if the device doesn't support quad programs. if (!device->supports_qspi_writes) { NRF_QSPI->IFCONFIG0 &= ~QSPI_IFCONFIG0_WRITEOC_Msk; - NRF_QSPI->IFCONFIG0 |= QSPI_IFCONFIG0_WRITEOC_PP; + NRF_QSPI->IFCONFIG0 |= QSPI_IFCONFIG0_WRITEOC_PP << QSPI_IFCONFIG0_WRITEOC_Pos; } // Speed up as much as we can. @@ -153,6 +150,11 @@ void spi_flash_init_device(const external_flash_device* device) { while (32000000 / (sckfreq + 1) > device->max_clock_speed_mhz * 1000000 && sckfreq < 16) { sckfreq += 1; } + // No more than 16 MHz. At 32 MHz GD25Q16C doesn't work reliably on Feather 52840, even though + // it should work up to 104 MHz. + // sckfreq = 0 is 32 Mhz + // sckfreq = 1 is 16 MHz, etc. + sckfreq = MAX(1, sckfreq); NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_SCKFREQ_Msk; - NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKDELAY_Pos; + NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_Pos; } diff --git a/supervisor/shared/stack.c b/supervisor/shared/stack.c index 71e239c0a156b..311fa31b2260e 100755 --- a/supervisor/shared/stack.c +++ b/supervisor/shared/stack.c @@ -56,7 +56,7 @@ void allocate_stack(void) { } inline bool stack_ok(void) { - return *stack_alloc->ptr == STACK_CANARY_VALUE; + return stack_alloc == NULL || *stack_alloc->ptr == STACK_CANARY_VALUE; } inline void assert_heap_ok(void) { From e312b93cb07becba7fd36c54fb7321efed684046 Mon Sep 17 00:00:00 2001 From: eighthree Date: Thu, 20 Dec 2018 22:12:38 -0800 Subject: [PATCH 027/153] Update Tagalog translations - Modified changed strings - Added new translations --- locale/fil.po | 264 +++++++++++++++++++++++--------------------------- 1 file changed, 123 insertions(+), 141 deletions(-) diff --git a/locale/fil.po b/locale/fil.po index c171975b69196..c1a564cdf534f 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-12-06 17:04-0800\n" -"PO-Revision-Date: 2018-08-30 23:04-0700\n" +"PO-Revision-Date: 2018-12-19 01:30-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" "Language: fil\n" @@ -323,7 +323,7 @@ msgstr "Lahat ng event channels ginagamit" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" -msgstr "" +msgstr "Sample rate ay masyadong mataas. Ito ay dapat hindi hiigit sa %d" #: ports/atmel-samd/common-hal/busio/I2C.c:71 msgid "Not enough pins available" @@ -653,49 +653,49 @@ msgstr "Hindi supportado ang AnalogOut" #: ports/nrf/common-hal/bleio/Adapter.c:41 #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" -msgstr "" +msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX" #: ports/nrf/common-hal/bleio/Adapter.c:125 #, c-format msgid "Failed to change softdevice state, error: 0x%08lX" -msgstr "" +msgstr "Nabigo sa pagbago ng softdevice state, error: 0x%08lX" #: ports/nrf/common-hal/bleio/Adapter.c:135 #, c-format msgid "Failed to get softdevice state, error: 0x%08lX" -msgstr "" +msgstr "Nabigo sa pagkuha ng softdevice state, error: 0x%08lX" #: ports/nrf/common-hal/bleio/Adapter.c:155 #, c-format msgid "Failed to get local address, error: 0x%08lX" -msgstr "" +msgstr "Nabigo sa pagkuha ng local na address, , error: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:52 -#, fuzzy, c-format +#, c-format msgid "Failed to write gatts value, status: 0x%08lX" -msgstr "Hindi maisulat ang attribute value. status: 0x%02x" +msgstr "Hindi maisulat ang gatts value, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:76 -#, fuzzy, c-format +#, c-format msgid "Failed to notify attribute value, status: 0x%08lX" -msgstr "Hindi mabalitaan ang attribute value. status: 0x%02x" +msgstr "Hindi mabalitaan ang attribute value, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:91 -#, fuzzy, c-format +#, c-format msgid "Failed to read attribute value, status: 0x%08lX" -msgstr "Hindi mabasa ang value ng attribute. status: 0x%02x" +msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:119 #: ports/nrf/common-hal/bleio/Device.c:272 #: ports/nrf/common-hal/bleio/Device.c:307 #, c-format msgid "Failed to acquire mutex, status: 0x%08lX" -msgstr "" +msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:126 -#, fuzzy, c-format +#, c-format msgid "Failed to write attribute value, status: 0x%08lX" -msgstr "Hindi maisulat ang attribute value. status: 0x%02x" +msgstr "Hindi maisulat ang attribute value, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:138 #: ports/nrf/common-hal/bleio/Device.c:284 @@ -704,65 +704,64 @@ msgstr "Hindi maisulat ang attribute value. status: 0x%02x" #: ports/nrf/common-hal/bleio/Device.c:391 #, c-format msgid "Failed to release mutex, status: 0x%08lX" -msgstr "" +msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:81 #: ports/nrf/common-hal/bleio/Device.c:114 -#, fuzzy msgid "Can not fit data into the advertisment packet" -msgstr "Hindi makasya ang data sa loob ng advertisement packet." +msgstr "Hindi makasya ang data sa loob ng advertisement packet" #: ports/nrf/common-hal/bleio/Device.c:266 #, c-format msgid "Failed to discover serivices, status: 0x%08lX" -msgstr "" +msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:403 #: ports/nrf/common-hal/bleio/Scanner.c:76 -#, fuzzy, c-format +#, c-format msgid "Failed to continue scanning, status: 0x%0xlX" -msgstr "Hindi masimulaan mag i-scan. status: 0x%02x" +msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX" #: ports/nrf/common-hal/bleio/Device.c:436 -#, fuzzy, c-format +#, c-format msgid "Failed to connect, status: 0x%08lX" -msgstr "Hindi makaconnect. status: 0x%02x" +msgstr "Hindi makaconnect, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:513 -#, fuzzy, c-format +#, c-format msgid "Failed to add service, status: 0x%08lX" -msgstr "Hindi mahinto ang advertisement. status: 0x%02x" +msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:531 -#, fuzzy, c-format +#, c-format msgid "Failed to start advertisment, status: 0x%08lX" -msgstr "Hindi masimulaan ang advertisement. status 0x%02x" +msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:549 -#, fuzzy, c-format +#, c-format msgid "Failed to stop advertisment, status: 0x%08lX" -msgstr "Hindi mahinto ang advertisement. status: 0x%02x" +msgstr "Hindi mahinto ang advertisement, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:575 #: ports/nrf/common-hal/bleio/Scanner.c:103 -#, fuzzy, c-format +#, c-format msgid "Failed to start scanning, status: 0x%0xlX" -msgstr "Hindi masimulaan mag i-scan. status: 0x%02x" +msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX" #: ports/nrf/common-hal/bleio/Device.c:592 -#, fuzzy, c-format +#, c-format msgid "Failed to create mutex, status: 0x%0xlX" -msgstr "Hindi mabasa ang value ng attribute. status: 0x%02x" +msgstr "Hindi matagumpay ang pagbuo ng mutex, status: 0x%0xlX" #: ports/nrf/common-hal/bleio/Service.c:83 #, c-format msgid "Failed to add characteristic, status: 0x%08lX" -msgstr "" +msgstr "Nabigo sa paglagay ng characteristic, status: 0x%08lX" #: ports/nrf/common-hal/bleio/UUID.c:97 -#, fuzzy, c-format +#, c-format msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" -msgstr "Hindi maaaring magdagdag ng Vendor Specific na 128-bit UUID." +msgstr "Hindi matagumpay ang paglagay ng Vender Specific UUID, status: 0x%08lX" #: ports/nrf/common-hal/bleio/UUID.c:102 msgid "Invalid UUID string length" @@ -775,29 +774,25 @@ msgid "Invalid UUID parameter" msgstr "Mali ang UUID parameter" #: ports/nrf/common-hal/busio/I2C.c:96 -#, fuzzy msgid "All I2C peripherals are in use" -msgstr "Lahat ng timer ginagamit" +msgstr "Lahat ng I2C peripherals ginagamit" #: ports/nrf/common-hal/busio/SPI.c:133 -#, fuzzy msgid "All SPI peripherals are in use" -msgstr "Lahat ng timer ginagamit" +msgstr "Lahat ng SPI peripherals ay ginagamit" #: ports/nrf/common-hal/busio/UART.c:49 #, c-format msgid "error = 0x%08lX" -msgstr "" +msgstr "error = 0x%08lX" #: ports/nrf/common-hal/busio/UART.c:87 -#, fuzzy msgid "Invalid buffer size" -msgstr "mali ang buffer length" +msgstr "Mali ang buffer size" #: ports/nrf/common-hal/busio/UART.c:91 -#, fuzzy msgid "Odd parity is not supported" -msgstr "hindi sinusuportahan ang bytes > 8 bits" +msgstr "Odd na parity ay hindi supportado" #: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 #: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 @@ -805,7 +800,7 @@ msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 #: ports/nrf/common-hal/busio/UART.c:376 msgid "busio.UART not available" -msgstr "" +msgstr "busio.UART hindi available" #: ports/nrf/common-hal/microcontroller/Processor.c:49 #, c-format @@ -813,9 +808,8 @@ msgid "Can not get temperature. status: 0x%02x" msgstr "Hindi makuha ang temperatura. status 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 -#, fuzzy msgid "All PWM peripherals are in use" -msgstr "Lahat ng timer ginagamit" +msgstr "Lahat ng PWM peripherals ay ginagamit" #: ports/unix/modffi.c:138 msgid "Unknown type" @@ -923,9 +917,8 @@ msgid "bad compile mode" msgstr "masamang mode ng compile" #: py/builtinhelp.c:137 -#, fuzzy msgid "Plus any modules on the filesystem\n" -msgstr "Hindi ma-remount ang filesystem" +msgstr "Kasama ang kung ano pang modules na sa filesystem\n" #: py/builtinhelp.c:183 #, c-format @@ -936,6 +929,12 @@ msgid "" "\n" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +"Mabuhay sa Adafruit CircuitPython %s!\n" +"\n" +"Mangyaring bisitahin ang learn.adafruit.com/category/circuitpython para sa " +"project guides.\n" +"\n" +"Para makita ang listahan ng modules, `help(“modules”)`.\n" #: py/builtinimport.c:336 msgid "cannot perform relative import" @@ -1099,19 +1098,17 @@ msgid "'data' requires integer arguments" msgstr "'data' kailangan ng integer arguments" #: py/emitinlinethumb.c:102 -#, fuzzy msgid "can only have up to 4 parameters to Thumb assembly" -msgstr "maaari lamang magkaroon ng hanggang 4 na parameter sa Xtensa assembly" +msgstr "maaari lamang magkaroon ng hanggang 4 na parameter sa Thumb assembly" #: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 -#, fuzzy msgid "parameters must be registers in sequence r0 to r3" -msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence a2 hanggang a5" +msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence r0 hanggang r3" #: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 -#, fuzzy, c-format +#, c-format msgid "'%s' expects at most r%d" -msgstr "Inaasahan ng '%s' ang isang rehistro" +msgstr "Inaasahan ng '%s' ang hangang r%d" #: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 #, c-format @@ -1119,19 +1116,19 @@ msgid "'%s' expects a register" msgstr "Inaasahan ng '%s' ang isang rehistro" #: py/emitinlinethumb.c:211 -#, fuzzy, c-format +#, c-format msgid "'%s' expects a special register" -msgstr "Inaasahan ng '%s' ang isang rehistro" +msgstr "Inaasahan ng '%s' ang isang espesyal na register" #: py/emitinlinethumb.c:239 -#, fuzzy, c-format +#, c-format msgid "'%s' expects an FPU register" -msgstr "Inaasahan ng '%s' ang isang rehistro" +msgstr "Inaasahan ng '%s' ang isang FPU register" #: py/emitinlinethumb.c:292 -#, fuzzy, c-format +#, c-format msgid "'%s' expects {r0, r1, ...}" -msgstr "Inaasahan ng '%s' ang isang rehistro" +msgstr "Inaasahan ng '%s' ay {r0, r1, …}" #: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format @@ -1139,14 +1136,14 @@ msgid "'%s' expects an integer" msgstr "Inaasahan ng '%s' ang isang integer" #: py/emitinlinethumb.c:304 -#, fuzzy, c-format +#, c-format msgid "'%s' integer 0x%x does not fit in mask 0x%x" -msgstr "'%s' integer %d ay wala sa sakop ng %d..%d" +msgstr "'%s' integer 0x%x ay wala sa mask na sakop ng 0x%x" #: py/emitinlinethumb.c:328 -#, fuzzy, c-format +#, c-format msgid "'%s' expects an address of the form [a, b]" -msgstr "Inaasahan ng '%s' ang isang rehistro" +msgstr "Inaasahan ng '%s' ang isang address sa [a, b]" #: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format @@ -1158,14 +1155,13 @@ msgid "label '%q' not defined" msgstr "label '%d' kailangan na i-define" #: py/emitinlinethumb.c:806 -#, fuzzy, c-format +#, c-format msgid "unsupported Thumb instruction '%s' with %d arguments" -msgstr "hindi sinusuportahan ang instruction ng Xtensa '%s' sa %d argumento" +msgstr "hindi sinusuportahan ang thumb instruktion '%s' sa %d argumento" #: py/emitinlinethumb.c:810 -#, fuzzy msgid "branch not in range" -msgstr "chr() arg wala sa sakop ng range(256)" +msgstr "branch wala sa range" #: py/emitinlinextensa.c:86 msgid "can only have up to 4 parameters to Xtensa assembly" @@ -1976,11 +1972,11 @@ msgstr "stream operation hindi sinusuportahan" #: py/stream.c:254 msgid "string not supported; use bytes or bytearray" -msgstr "" +msgstr "string hindi supportado; gumamit ng bytes o kaya bytearray" #: py/stream.c:289 msgid "length argument not allowed for this type" -msgstr "" +msgstr "length argument ay walang pahintulot sa ganitong type" #: py/vm.c:255 msgid "local variable referenced before assignment" @@ -2062,24 +2058,20 @@ msgstr "" "para sa bit_depth = 8" #: shared-bindings/audioio/Mixer.c:94 -#, fuzzy msgid "Invalid voice count" -msgstr "Mali ang tipo ng serbisyo" +msgstr "Maling bilang ng voice" #: shared-bindings/audioio/Mixer.c:99 -#, fuzzy msgid "Invalid channel count" -msgstr "Maling argumento" +msgstr "Maling bilang ng channel" #: shared-bindings/audioio/Mixer.c:103 -#, fuzzy msgid "Sample rate must be positive" -msgstr "Dapat aktibo ang STA" +msgstr "Sample rate ay dapat positibo" #: shared-bindings/audioio/Mixer.c:107 -#, fuzzy msgid "bits_per_sample must be 8 or 16" -msgstr "bits ay dapat 7, 8 o 9" +msgstr "bits_per_sample ay dapat 8 o 16" #: shared-bindings/audioio/RawSample.c:98 msgid "" @@ -2125,28 +2117,27 @@ msgstr "aarehas na haba dapat ang buffer slices" #: shared-bindings/bleio/Address.c:101 msgid "Wrong address length" -msgstr "" +msgstr "Mali ang address length" #: shared-bindings/bleio/Address.c:107 -#, fuzzy msgid "Wrong number of bytes provided" -msgstr "mali ang bilang ng argumento" +msgstr "Mali ang bilang ng bytes" #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" -msgstr "" +msgstr "Hindi maarang maglagay ng service sa Central mode" #: shared-bindings/bleio/Device.c:226 msgid "Can't connect in Peripheral mode" -msgstr "" +msgstr "Hindi maconnect sa Peripheral mode" #: shared-bindings/bleio/Device.c:256 msgid "Can't change the name in Central mode" -msgstr "" +msgstr "Hindi mapalitan ang pangalan sa Central mode" #: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 msgid "Can't advertise in Central mode" -msgstr "" +msgstr "Hindi ma advertise habang nasa Central mode" #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." @@ -2162,7 +2153,7 @@ msgstr "stop dapat 1 o 2" #: shared-bindings/busio/UART.c:123 msgid "timeout >100 (units are now seconds, not msecs)" -msgstr "" +msgstr "timeout >100 (units ay seconds, hindi na msecs)" #: shared-bindings/digitalio/DigitalInOut.c:211 msgid "Invalid direction." @@ -2187,76 +2178,62 @@ msgid "Unsupported pull value." msgstr "Hindi suportado ang pull value." #: shared-bindings/displayio/Bitmap.c:84 -#, fuzzy msgid "y should be an int" -msgstr "Haba ay dapat int" +msgstr "y ay dapat int" #: shared-bindings/displayio/Bitmap.c:89 -#, fuzzy msgid "row buffer must be a bytearray or array of type 'b' or 'B'" -msgstr "" -"ang sample_source buffer ay dapat na isang bytearray o array ng uri na 'h', " -"'H', 'b' o'B'" +msgstr "ang row buffer ay dapat bytearray o array na type ‘b’ or ‘B’" #: shared-bindings/displayio/Bitmap.c:94 -#, fuzzy msgid "row data must be a buffer" -msgstr "constant ay dapat na integer" +msgstr "row data ay dapat na buffer" #: shared-bindings/displayio/ColorConverter.c:72 -#, fuzzy msgid "color should be an int" -msgstr "Haba ay dapat int" +msgstr "color ay dapat na int" #: shared-bindings/displayio/FourWire.c:55 #: shared-bindings/displayio/FourWire.c:64 msgid "displayio is a work in progress" -msgstr "" +msgstr "displayio ay nasa gitna ng konstruksiyon" #: shared-bindings/displayio/Group.c:65 -#, fuzzy msgid "Group must have size at least 1" -msgstr "Buffer dapat ay hindi baba sa 1 na haba" +msgstr "Group dapat ay hindi baba sa 1 na haba" #: shared-bindings/displayio/Palette.c:96 -#, fuzzy msgid "color buffer must be a bytearray or array of type 'b' or 'B'" -msgstr "" -"ang sample_source buffer ay dapat na isang bytearray o array ng uri na 'h', " -"'H', 'b' o'B'" +msgstr "ang color buffer ay dapat bytearray o array na type ‘b’ or ‘B’" #: shared-bindings/displayio/Palette.c:102 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" -msgstr "" +msgstr "color buffer ay dapat na 3 bytes (RGB) o 4 bytes (RGB + pad byte)" #: shared-bindings/displayio/Palette.c:106 -#, fuzzy msgid "color must be between 0x000000 and 0xffffff" -msgstr "Sa gitna ng 0 o 255 dapat ang bytes." +msgstr "color ay dapat mula sa 0x000000 hangang 0xffffff" #: shared-bindings/displayio/Palette.c:110 -#, fuzzy msgid "color buffer must be a buffer or int" -msgstr "buffer ay dapat bytes-like object" +msgstr "color buffer ay dapat buffer or int" #: shared-bindings/displayio/Palette.c:123 #: shared-bindings/displayio/Palette.c:137 msgid "palette_index should be an int" -msgstr "" +msgstr "palette_index ay dapat na int" #: shared-bindings/displayio/Sprite.c:48 -#, fuzzy msgid "position must be 2-tuple" -msgstr "stop dapat 1 o 2" +msgstr "position ay dapat 2-tuple" #: shared-bindings/displayio/Sprite.c:97 -#, fuzzy msgid "unsupported bitmap type" -msgstr "Hindi supportadong baudrate" +msgstr "Hindi supportadong tipo ng bitmap" #: shared-bindings/displayio/Sprite.c:162 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" -msgstr "" +msgstr "pixel_shader ay dapat displayio.Palette o displayio.ColorConverter" #: shared-bindings/gamepad/GamePad.c:100 msgid "too many arguments" @@ -2322,11 +2299,10 @@ msgid "" msgstr "PWM duty_cycle ay dapat sa loob ng 0 at 65535 (16 bit resolution)" #: shared-bindings/pulseio/PWMOut.c:195 -#, fuzzy msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" -"PWM frequency hindi maisulat kapag variable_frequency ay False sa pag buo." +"PWM frequency hindi writable kapag variable_frequency ay False sa pag buo." #: shared-bindings/pulseio/PulseIn.c:275 msgid "Cannot delete values" @@ -2375,7 +2351,7 @@ msgstr "RTC calibration ay hindi supportado ng board na ito" #: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:81 msgid "no available NIC" -msgstr "" +msgstr "walang magagamit na NIC" #: shared-bindings/storage/__init__.c:77 msgid "filesystem must provide mount method" @@ -2434,23 +2410,23 @@ msgstr "Hindi ma-iallocate ang second buffer" #: shared-module/audioio/Mixer.c:82 msgid "Voice index too high" -msgstr "" +msgstr "Index ng Voice ay masyadong mataas" #: shared-module/audioio/Mixer.c:85 msgid "The sample's sample rate does not match the mixer's" -msgstr "" +msgstr "Ang sample rate ng sample ay hindi tugma sa mixer" #: shared-module/audioio/Mixer.c:88 msgid "The sample's channel count does not match the mixer's" -msgstr "" +msgstr "Ang channel count ng sample ay hindi tugma sa mixer" #: shared-module/audioio/Mixer.c:91 msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" +msgstr "Ang bits_per_sample ng sample ay hindi tugma sa mixer" #: shared-module/audioio/Mixer.c:100 msgid "The sample's signedness does not match the mixer's" -msgstr "" +msgstr "Ang signedness ng sample hindi tugma sa mixer" #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" @@ -2502,35 +2478,33 @@ msgstr "Hindi maaaring ilipat kapag walang MOSI at MISO pin." #: shared-module/displayio/Bitmap.c:49 msgid "Only bit maps of 8 bit color or less are supported" -msgstr "" +msgstr "Tanging bit maps na may 8 bit color o mas mababa ang supportado" #: shared-module/displayio/Bitmap.c:69 msgid "row must be packed and word aligned" -msgstr "" +msgstr "row ay dapat packed at ang word nakahanay" #: shared-module/displayio/Group.c:39 msgid "Group full" -msgstr "" +msgstr "Puno ang group" #: shared-module/displayio/Group.c:48 -#, fuzzy msgid "Group empty" -msgstr "walang laman" +msgstr "Walang laman ang group" #: shared-module/displayio/OnDiskBitmap.c:49 -#, fuzzy msgid "Invalid BMP file" -msgstr "Mali ang file" +msgstr "Mali ang BMP file" #: shared-module/displayio/OnDiskBitmap.c:59 #, c-format msgid "Only Windows format, uncompressed BMP supported %d" -msgstr "" +msgstr "Tanging Windows format, uncompressed BMP lamang ang supportado %d" #: shared-module/displayio/OnDiskBitmap.c:64 #, c-format msgid "Only true color (24 bpp or higher) BMP supported %x" -msgstr "" +msgstr "Dapat true color (24 bpp o mas mataas) BMP lamang ang supportado %x" #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." @@ -2566,12 +2540,9 @@ msgid "To exit, please reset the board without " msgstr "Para lumabas, paki-reset ang board na wala ang " #: supervisor/shared/safe_mode.c:107 -#, fuzzy msgid "" "You are running in safe mode which means something unanticipated happened.\n" -msgstr "" -"Ikaw ay tumatakbo sa safe mode, ang ibig sabihin nito ay may masamang " -"nangyari.\n" +msgstr "Ikaw ay tumatakbo sa safe mode dahil may masamang nangyari.\n" #: supervisor/shared/safe_mode.c:109 msgid "" @@ -2579,21 +2550,24 @@ msgid "" "Please file an issue at https://github.com/adafruit/circuitpython/issues\n" " with the contents of your CIRCUITPY drive and this message:\n" msgstr "" +"Mukhang ang core CircuitPython code nag crash. Ay!\n" +"Maaring mag file ng issue sa https://github.com/adafruit/circuitpython/" +"issues\n" +"kasama ng laman ng iyong CIRCUITPY drive at ang message na ito:\n" #: supervisor/shared/safe_mode.c:111 msgid "Crash into the HardFault_Handler.\n" -msgstr "" +msgstr "Nagcrash sa HardFault_Handler.\n" #: supervisor/shared/safe_mode.c:113 msgid "MicroPython NLR jump failed. Likely memory corruption.\n" -msgstr "" +msgstr "CircuitPython NLR jump nabigo. Maaring memory corruption.\n" #: supervisor/shared/safe_mode.c:115 msgid "MicroPython fatal error.\n" -msgstr "" +msgstr "CircuitPython fatal na pagkakamali.\n" #: supervisor/shared/safe_mode.c:118 -#, fuzzy msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -2602,6 +2576,7 @@ msgid "" msgstr "" "Ang kapangyarihan ng mikrokontroller ay bumaba. Mangyaring suriin ang power " "supply \n" +"pindutin ang reset (pagkatapos i-eject ang CIRCUITPY).\n" #: supervisor/shared/safe_mode.c:120 msgid "" @@ -2611,12 +2586,19 @@ msgid "" "If you didn't change the stack, then file an issue here with the contents of " "your CIRCUITPY drive:\n" msgstr "" +"Ang CircuitPython heap ay na corrupt dahil ang stack ay maliit.\n" +"Maaring i-increase ang stack size limit at i-press ang reset (pagkatapos i-" +"eject ang CIRCUITPY.\n" +"Kung hindi mo pinalitan ang stack, mag file ng issue dito kasama ng laman ng " +"CIRCUITPY drive:\n" #: supervisor/shared/safe_mode.c:123 msgid "" "The reset button was pressed while booting CircuitPython. Press again to " "exit safe mode.\n" msgstr "" +"Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " +"ulit para lumabas sa safe mode.\n" #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" From 9c26c5829e13483a17593cbf2d10ce7a04ef9658 Mon Sep 17 00:00:00 2001 From: eighthree Date: Thu, 20 Dec 2018 22:16:42 -0800 Subject: [PATCH 028/153] Update fil.po Minor word change --- locale/fil.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locale/fil.po b/locale/fil.po index c1a564cdf534f..4c5598978f4b7 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-12-06 17:04-0800\n" -"PO-Revision-Date: 2018-12-19 01:30-0800\n" +"PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" "Language: fil\n" @@ -182,7 +182,7 @@ msgstr "BABALA: Ang pangalan ng file ay may dalawang extension\n" #: main.c:244 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -"Pindutin ang anumang key upang ipasok ang REPL. Gamitin ang CTRL-D upang i-" +"Pindutin ang anumang key upang pumasok sa REPL. Gamitin ang CTRL-D upang i-" "reload." #: main.c:407 From 0dfe2dbff02dd3d8b6392f74df3717c362174e27 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 21 Dec 2018 12:30:54 -0500 Subject: [PATCH 029/153] return error status on more routines; minor simplification of freq setting --- ports/nrf/supervisor/qspi_flash.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index 4738607bff5b5..51a9ec032969c 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -60,8 +60,8 @@ bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) .wipwait = false, .wren = false }; - nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, response); - return true; + return nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, response) == NRFX_SUCCESS; + } bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { @@ -73,8 +73,7 @@ bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { .wipwait = false, .wren = false // We do this manually. }; - nrfx_qspi_cinstr_xfer(&cinstr_cfg, data, NULL); - return true; + return nrfx_qspi_cinstr_xfer(&cinstr_cfg, data, NULL) == NRFX_SUCCESS; } bool spi_flash_sector_command(uint8_t command, uint32_t address) { @@ -146,15 +145,14 @@ void spi_flash_init_device(const external_flash_device* device) { } // Speed up as much as we can. - uint8_t sckfreq = 0; + // Start at 16 MHz and go down. + // At 32 MHz GD25Q16C doesn't work reliably on Feather 52840, even though it should work up to 104 MHz. + // sckfreq = 0 is 32 Mhz + // sckfreq = 1 is 16 MHz, etc. + uint8_t sckfreq = 1; while (32000000 / (sckfreq + 1) > device->max_clock_speed_mhz * 1000000 && sckfreq < 16) { sckfreq += 1; } - // No more than 16 MHz. At 32 MHz GD25Q16C doesn't work reliably on Feather 52840, even though - // it should work up to 104 MHz. - // sckfreq = 0 is 32 Mhz - // sckfreq = 1 is 16 MHz, etc. - sckfreq = MAX(1, sckfreq); NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_SCKFREQ_Msk; NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_Pos; } From 0b35227bf5d7cd51de8fd141b06e6e16c1fac1b4 Mon Sep 17 00:00:00 2001 From: Pierrick C Date: Wed, 26 Dec 2018 18:54:37 +0100 Subject: [PATCH 030/153] Updated fr.po --- locale/fr.po | 364 ++++++++++++++++++++++++++------------------------- 1 file changed, 189 insertions(+), 175 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index badf45555dbca..9236fb8aa1fba 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 17:04-0800\n" -"PO-Revision-Date: 2018-08-14 11:01+0200\n" +"POT-Creation-Date: 2018-12-26 17:29+0100\n" +"PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" "Language: fr\n" @@ -100,7 +100,7 @@ msgstr "'heap' vide" #: extmod/modujson.c:281 msgid "syntax error in JSON" -msgstr "erreur de syntaxe dans le JSON" +msgstr "erreur de syntaxe JSON" #: extmod/modure.c:161 msgid "Splitting with sub-captures" @@ -148,7 +148,7 @@ msgstr "arguments invalides" #: lib/utils/pyexec.c:97 py/builtinimport.c:251 msgid "script compilation not supported" -msgstr "compilation du script non supporté" +msgstr "compilation de script non supporté" #: main.c:150 msgid " output:\n" @@ -193,11 +193,11 @@ msgstr "Tous les canaux d'événements de synchro sont utilisés" #: ports/atmel-samd/bindings/samd/Clock.c:135 msgid "calibration is read only" -msgstr "la calibration est en lecture seule" +msgstr "calibration en lecture seule" #: ports/atmel-samd/bindings/samd/Clock.c:137 msgid "calibration is out of range" -msgstr "la calibration est hors gamme" +msgstr "calibration hors gamme" #: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 msgid "No default I2C bus" @@ -222,7 +222,7 @@ msgstr "Pas de DAC sur la puce" #: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56 msgid "AnalogOut not supported on given pin" -msgstr "AnalogOut n'est pas supporté sur cette broche" +msgstr "AnalogOut n'est pas supporté sur la broche indiquée" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 @@ -231,7 +231,7 @@ msgstr "Broche invalide pour 'bit clock'" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 msgid "Bit clock and word select must share a clock unit" -msgstr "'bit clock' et 'word select' doivent partagé une horloge" +msgstr "'bit clock' et 'word select' doivent partager une horloge" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 @@ -304,7 +304,7 @@ msgstr "Broche invalide pour le canal droit" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" -msgstr "On ne peut mettre les deux canaux sur la même broche" +msgstr "Les 2 canaux de sortie ne peuvent être sur la même broche" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 @@ -320,7 +320,7 @@ msgstr "Tous les canaux d'événements sont utilisés" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" -msgstr "" +msgstr "Taux d'échantillonage trop élevé. Doit être inf. à %d" #: ports/atmel-samd/common-hal/busio/I2C.c:71 msgid "Not enough pins available" @@ -332,7 +332,7 @@ msgstr "Pas assez de broches disponibles" #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" -msgstr "Broche invalide" +msgstr "Broches invalides" #: ports/atmel-samd/common-hal/busio/I2C.c:101 msgid "SDA or SCL needs a pull up" @@ -347,12 +347,12 @@ msgid "bytes > 8 bits not supported" msgstr "octets > 8 bits non supporté" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:83 +#: ports/nrf/common-hal/busio/UART.c:106 msgid "tx and rx cannot both be None" -msgstr "TX et RX ne peuvent être None tous les deux" +msgstr "tx et rx ne peuvent être None tous les deux" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:116 +#: ports/nrf/common-hal/busio/UART.c:140 msgid "Failed to allocate RX buffer" msgstr "Echec de l'allocation du tampon RX" @@ -361,19 +361,19 @@ msgid "Could not initialize UART" msgstr "L'UART n'a pu être initialisé" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:157 +#: ports/nrf/common-hal/busio/UART.c:185 msgid "No RX pin" msgstr "Pas de broche RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:207 +#: ports/nrf/common-hal/busio/UART.c:220 msgid "No TX pin" msgstr "Pas de broche TX" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 #: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" -msgstr "Ne peux être tirer ('pull') en mode 'output'" +msgstr "Ne peux être tiré ('pull') en mode 'output'" #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 @@ -450,7 +450,7 @@ msgstr "Broche invalide pour le SPI" #: ports/esp8266/common-hal/busio/UART.c:45 msgid "Only tx supported on UART1 (GPIO2)." -msgstr "Seul le TX est supporté sur l'UART1 (GPIO2)." +msgstr "Seul le tx est supporté sur l'UART1 (GPIO2)." #: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 msgid "invalid data bits" @@ -487,7 +487,7 @@ msgstr "La fréquence de PWM minimale est 1Hz" #, c-format msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." msgstr "" -"Les fréquences multiples de PWM ne sont pas supportées. Déjà réglé à %dHz" +"Les fréquences de PWM multiples ne sont pas supportées. PWM réglé à %dHz" #: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 #, c-format @@ -534,7 +534,7 @@ msgstr "broche invalide" #: ports/esp8266/machine_pin.c:389 msgid "pin does not have IRQ capabilities" -msgstr "la broche n'a pas de capacité d'interruption (IRQ)" +msgstr "la broche ne supporte pas les interruptions (IRQ)" #: ports/esp8266/machine_rtc.c:185 msgid "buffer too long" @@ -614,15 +614,15 @@ msgstr "wifi_set_ip_info() a échoué" #: ports/esp8266/modnetwork.c:319 msgid "either pos or kw args are allowed" -msgstr "seuls les arguments 'pos' ou 'kw' sont autorisés" +msgstr "soit 'pos', soit 'kw' est permis en argument" #: ports/esp8266/modnetwork.c:329 msgid "can't get STA config" -msgstr "impossible de récupérer de la config de 'STA'" +msgstr "impossible de récupérer la config de 'STA'" #: ports/esp8266/modnetwork.c:331 msgid "can't get AP config" -msgstr "impossible de récupérer de la config de 'AP'" +msgstr "impossible de récupérer la config de 'AP'" #: ports/esp8266/modnetwork.c:346 msgid "invalid buffer length" @@ -656,44 +656,44 @@ msgstr "" #: ports/nrf/common-hal/bleio/Adapter.c:125 #, c-format msgid "Failed to change softdevice state, error: 0x%08lX" -msgstr "" +msgstr "Echec de la modification de l'état du périph., erreur: 0x%08lX" #: ports/nrf/common-hal/bleio/Adapter.c:135 #, c-format msgid "Failed to get softdevice state, error: 0x%08lX" -msgstr "" +msgstr "Echec de l'obtention de l'état du périph., erreur: 0x%08lX" #: ports/nrf/common-hal/bleio/Adapter.c:155 #, c-format msgid "Failed to get local address, error: 0x%08lX" -msgstr "" +msgstr "Echec de l'obtention de l'adresse locale, erreur: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:52 #, fuzzy, c-format msgid "Failed to write gatts value, status: 0x%08lX" -msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" +msgstr "Impossible d'écrire la valeur de gatts. status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:76 #, fuzzy, c-format msgid "Failed to notify attribute value, status: 0x%08lX" -msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%02x" +msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:91 #, fuzzy, c-format msgid "Failed to read attribute value, status: 0x%08lX" -msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x" +msgstr "Impossible de lire la valeur de l'attribut. status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:119 #: ports/nrf/common-hal/bleio/Device.c:272 #: ports/nrf/common-hal/bleio/Device.c:307 #, c-format msgid "Failed to acquire mutex, status: 0x%08lX" -msgstr "" +msgstr "Echec de l'obtention de mutex, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:126 #, fuzzy, c-format msgid "Failed to write attribute value, status: 0x%08lX" -msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" +msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%08lX" #: ports/nrf/common-hal/bleio/Characteristic.c:138 #: ports/nrf/common-hal/bleio/Device.c:284 @@ -702,7 +702,7 @@ msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" #: ports/nrf/common-hal/bleio/Device.c:391 #, c-format msgid "Failed to release mutex, status: 0x%08lX" -msgstr "" +msgstr "Impossible de libérer mutex, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:81 #: ports/nrf/common-hal/bleio/Device.c:114 @@ -711,55 +711,55 @@ msgstr "" #: ports/nrf/common-hal/bleio/Device.c:266 #, c-format -msgid "Failed to discover serivices, status: 0x%08lX" -msgstr "" +msgid "Failed to discover services, status: 0x%08lX" +msgstr "Echec de la découverte de services, statut: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:403 #: ports/nrf/common-hal/bleio/Scanner.c:76 #, fuzzy, c-format msgid "Failed to continue scanning, status: 0x%0xlX" -msgstr "Impossible de commencer à scanner. status: 0x%02x" +msgstr "Impossible de commencer à scanner. statut: 0x%0xlX" #: ports/nrf/common-hal/bleio/Device.c:436 #, fuzzy, c-format msgid "Failed to connect, status: 0x%08lX" -msgstr "Connection impossible. status: 0x%02x" +msgstr "Connection impossible. statut: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:513 #, c-format msgid "Failed to add service, status: 0x%08lX" -msgstr "" +msgstr "Echec de l'ajout de service, statut: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:531 -#, fuzzy, c-format +#, c-format msgid "Failed to start advertisment, status: 0x%08lX" -msgstr "Impossible de commencer à scanner. status: 0x%02x" +msgstr "" #: ports/nrf/common-hal/bleio/Device.c:549 -#, c-format +#, fuzzy, c-format msgid "Failed to stop advertisment, status: 0x%08lX" -msgstr "" +msgstr "Echec de l'ajout de service, statut: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:575 #: ports/nrf/common-hal/bleio/Scanner.c:103 #, fuzzy, c-format msgid "Failed to start scanning, status: 0x%0xlX" -msgstr "Impossible de commencer à scanner. status: 0x%02x" +msgstr "Impossible de commencer à scanner, statut: 0x%0xlX" #: ports/nrf/common-hal/bleio/Device.c:592 #, fuzzy, c-format msgid "Failed to create mutex, status: 0x%0xlX" -msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x" +msgstr "Echec de la création de mutex, statut: 0x%0xlX" #: ports/nrf/common-hal/bleio/Service.c:83 #, c-format msgid "Failed to add characteristic, status: 0x%08lX" -msgstr "" +msgstr "Echec de l'ajout de caractéristique, statut: 0x%08lX" #: ports/nrf/common-hal/bleio/UUID.c:97 #, fuzzy, c-format msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" -msgstr "Impossible d'ajouter l'UUID 128bits Vendor Specific" +msgstr "Echec de l'ajout de l'UUID Vendor Specific, , statut: 0x%08lX" #: ports/nrf/common-hal/bleio/UUID.c:102 msgid "Invalid UUID string length" @@ -774,33 +774,33 @@ msgstr "Paramètre UUID invalide" #: ports/nrf/common-hal/busio/I2C.c:96 #, fuzzy msgid "All I2C peripherals are in use" -msgstr "Tous les timers sont utilisés" +msgstr "Tous les périphériques I2C sont utilisés" #: ports/nrf/common-hal/busio/SPI.c:133 #, fuzzy msgid "All SPI peripherals are in use" -msgstr "Tous les timers sont utilisés" +msgstr "Tous les périphériques SPI sont utilisés" #: ports/nrf/common-hal/busio/UART.c:49 #, c-format msgid "error = 0x%08lX" -msgstr "" +msgstr "erreur = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:87 +#: ports/nrf/common-hal/busio/UART.c:110 #, fuzzy msgid "Invalid buffer size" msgstr "longueur de tampon invalide" -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:114 #, fuzzy msgid "Odd parity is not supported" -msgstr "octets > 8 bits non supporté" +msgstr "parité impaire non supportée" -#: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 -#: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 -#: ports/nrf/common-hal/busio/UART.c:354 ports/nrf/common-hal/busio/UART.c:359 -#: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 -#: ports/nrf/common-hal/busio/UART.c:376 +#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 +#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 +#: ports/nrf/common-hal/busio/UART.c:388 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART n'est pas disponible" @@ -813,7 +813,7 @@ msgstr "Impossible de lire la température. status: 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 #, fuzzy msgid "All PWM peripherals are in use" -msgstr "Tous les timers sont utilisés" +msgstr "Tous les périphériques PWM sont utilisés" #: ports/unix/modffi.c:138 msgid "Unknown type" @@ -829,7 +829,7 @@ msgstr "" #: ports/unix/modffi.c:413 msgid "Don't know how to pass object to native function" -msgstr "Ne sais pas comment passer un objet à une fonction native" +msgstr "Ne sais pas comment passer l'objet à une fonction native" #: ports/unix/modusocket.c:474 #, c-format @@ -918,9 +918,8 @@ msgid "bad compile mode" msgstr "mauvais mode de compilation" #: py/builtinhelp.c:137 -#, fuzzy msgid "Plus any modules on the filesystem\n" -msgstr "Impossible de remonter le système de fichiers" +msgstr "" #: py/builtinhelp.c:183 #, c-format @@ -931,6 +930,11 @@ msgid "" "\n" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +"Bienvenue sur Adafruit CircuitPython %s!\n" +"\n" +"Vistez learn.adafruit.com/category/circuitpython pour des guides.\n" +"\n" +"Pour lister les modules inclus, tapez `help(\"modules\")`.\n" #: py/builtinimport.c:336 msgid "cannot perform relative import" @@ -958,7 +962,8 @@ msgstr "*x multiple dans l'assignement" #: py/compile.c:642 msgid "non-default argument follows default argument" -msgstr "un argument sans valeur par défaut suit un argument avec défaut" +msgstr "" +"un argument sans valeur par défaut suit un argument avec valeur par défaut" #: py/compile.c:771 py/compile.c:789 msgid "invalid micropython decorator" @@ -998,7 +1003,7 @@ msgstr "ne peut déclarer de nonlocal dans un code externe" #: py/compile.c:1542 msgid "default 'except' must be last" -msgstr "l''except' par défaut doit être le dernier" +msgstr "l''except' par défaut doit être en dernier" #: py/compile.c:2095 msgid "*x must be assignment target" @@ -1039,7 +1044,7 @@ msgstr "couple clef:valeur attendu pour un objet dict" #: py/compile.c:2475 msgid "expecting just a value for set" -msgstr "une simple valeur est attendu pour set" +msgstr "une simple valeur est attendue pour set" #: py/compile.c:2600 msgid "'yield' outside function" @@ -1063,7 +1068,7 @@ msgstr "l'annotation de return doit être un identifiant" #: py/compile.c:3097 msgid "inline assembler must be a function" -msgstr "l'assembleur en ligne doit être une fonction" +msgstr "l'assembleur doit être une fonction" #: py/compile.c:3134 msgid "unknown type" @@ -1095,12 +1100,12 @@ msgstr "'data' nécessite des arguments entiers" #: py/emitinlinethumb.c:102 msgid "can only have up to 4 parameters to Thumb assembly" -msgstr "" +msgstr "il peut y avoir jusqu'à 4 paramètres pour Thumb assembly" #: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 #, fuzzy msgid "parameters must be registers in sequence r0 to r3" -msgstr "les paramètres doivent être des registres dans la séquence a2 à a5" +msgstr "les paramètres doivent être des registres dans la séquence r0 à r3" #: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 #, fuzzy, c-format @@ -1115,17 +1120,17 @@ msgstr "'%s' attend un registre" #: py/emitinlinethumb.c:211 #, fuzzy, c-format msgid "'%s' expects a special register" -msgstr "'%s' attend un registre" +msgstr "'%s' attend un registre special" #: py/emitinlinethumb.c:239 #, fuzzy, c-format msgid "'%s' expects an FPU register" -msgstr "'%s' attend un registre" +msgstr "'%s' attend un registre FPU" #: py/emitinlinethumb.c:292 #, fuzzy, c-format msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' attend un registre" +msgstr "'%s' attend {r0, r1, ...}" #: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format @@ -1135,12 +1140,12 @@ msgstr "'%s' attend un entier" #: py/emitinlinethumb.c:304 #, fuzzy, c-format msgid "'%s' integer 0x%x does not fit in mask 0x%x" -msgstr "'%s' l'entier %d n'est pas dans la gamme %d..%d" +msgstr "'%s' l'entier 0x%x ne correspond pas au masque 0x%x" #: py/emitinlinethumb.c:328 #, fuzzy, c-format msgid "'%s' expects an address of the form [a, b]" -msgstr "'%s' attend un registre" +msgstr "'%s' attend une adresse de la forme [a, b]" #: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format @@ -1154,7 +1159,7 @@ msgstr "label '%q' non supporté" #: py/emitinlinethumb.c:806 #, fuzzy, c-format msgid "unsupported Thumb instruction '%s' with %d arguments" -msgstr "instruction Xtensa '%s' non supportée avec %d arguments" +msgstr "instruction Thumb '%s' non supportée avec %d arguments" #: py/emitinlinethumb.c:810 #, fuzzy @@ -1163,7 +1168,7 @@ msgstr "argument de chr() hors de la gamme range(256)" #: py/emitinlinextensa.c:86 msgid "can only have up to 4 parameters to Xtensa assembly" -msgstr "" +msgstr "Maximum 4 paramètres pour l'assembleur Xtensa" #: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 msgid "parameters must be registers in sequence a2 to a5" @@ -1193,7 +1198,7 @@ msgstr "conversion en objet" #: py/emitnative.c:921 msgid "local '%q' used before type known" -msgstr "'%q' local utilisé avant d'en connaitre le type" +msgstr "variable locale '%q' utilisée avant d'en connaitre le type" #: py/emitnative.c:1118 py/emitnative.c:1156 msgid "can't load from '%q'" @@ -1213,7 +1218,7 @@ msgstr "impossible de stocker '%q'" #: py/emitnative.c:1358 py/emitnative.c:1419 msgid "can't store to '%q'" -msgstr "imposible de stocker vers '%q'" +msgstr "impossible de stocker vers '%q'" #: py/emitnative.c:1369 msgid "can't store with '%q' index" @@ -1253,7 +1258,7 @@ msgstr "native yield" #: py/lexer.c:345 msgid "unicode name escapes" -msgstr "échappement pour nom unicode" +msgstr "échappements de nom unicode" #: py/modbuiltins.c:162 msgid "chr() arg not in range(0x110000)" @@ -1349,12 +1354,12 @@ msgstr ", dans %q\n" #: py/obj.c:259 msgid "can't convert to int" -msgstr "ne peut convertir en entier int" +msgstr "ne peut convertir en entier (int)" #: py/obj.c:262 #, c-format msgid "can't convert %s to int" -msgstr "ne peut convertir %s en entier int" +msgstr "ne peut convertir %s en entier (int)" #: py/obj.c:322 msgid "can't convert to float" @@ -1459,7 +1464,7 @@ msgstr "tableau/octets requis à droite" #: py/objcomplex.c:203 msgid "can't do truncated division of a complex number" -msgstr "on ne peut pas faire de division tronquée d'un nombre complexe" +msgstr "on ne peut pas faire de division tronquée de nombres complexes" #: py/objcomplex.c:209 msgid "complex division by zero" @@ -1492,7 +1497,7 @@ msgstr "valeurs complexes non supportées" #: py/objgenerator.c:108 msgid "can't send non-None value to a just-started generator" msgstr "" -"on ne peut envoyer une valeur différente de None à un générateur fraîchement " +"on ne peut envoyer une valeur autre que None à un générateur fraîchement " "démarré" #: py/objgenerator.c:126 @@ -1521,7 +1526,7 @@ msgstr "nombre flottant trop grand" #: py/objint.c:328 msgid "long int not supported in this build" -msgstr "entier long non supporté dans cette build" +msgstr "entiers longs non supportés dans cette build" #: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 msgid "small int overflow" @@ -1601,7 +1606,7 @@ msgstr "join attend une liste d'objets str/bytes cohérent avec l'objet self" #: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744 msgid "empty separator" -msgstr "separateur vide" +msgstr "séparateur vide" #: py/objstr.c:641 msgid "rsplit(None,n)" @@ -1668,7 +1673,7 @@ msgstr "" #: py/objstr.c:1171 msgid "invalid format specifier" -msgstr "spécificationde format invalide" +msgstr "spécification de format invalide" #: py/objstr.c:1192 msgid "sign not allowed in string format specifier" @@ -1711,7 +1716,7 @@ msgstr "format incomplet" #: py/objstr.c:1490 msgid "not enough arguments for format string" -msgstr "pas assez d'argument pour la chaîne de format" +msgstr "pas assez d'arguments pour la chaîne de format" #: py/objstr.c:1500 #, c-format @@ -1819,7 +1824,7 @@ msgstr "l'argument 1 de issubclass() doit être une classe" #: py/parse.c:726 msgid "constant must be an integer" -msgstr "les constantes doivent être des entiers" +msgstr "une constante doit être un entier" #: py/parse.c:868 msgid "Unable to init parser" @@ -1835,7 +1840,7 @@ msgstr "la désindentation ne correspond à aucune indentation" #: py/parsenum.c:60 msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "l'argument 2 de int() doit être >=2 et <=32" +msgstr "l'argument 2 de int() doit être >=2 et <=36" #: py/parsenum.c:151 msgid "invalid syntax for integer" @@ -1859,7 +1864,7 @@ msgid "" "Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" "mpy-update for more info." msgstr "" -"Fichier .mpy incompatible. Merci de mettre à jour tous les .mpy. Voir http://" +"Fichier .mpy incompatible. Merci de mettre à jour tous les .mpy. Voirhttp://" "adafru.it/mpy-update pour plus d'informations." #: py/persistentcode.c:326 @@ -1940,7 +1945,7 @@ msgstr "l'objet '%s' n'est pas un itérateur" #: py/runtime.c:1401 msgid "exceptions must derive from BaseException" -msgstr "les exception doivent dériver de BaseException" +msgstr "les exceptions doivent dériver de BaseException" #: py/runtime.c:1430 msgid "cannot import name %q" @@ -1970,10 +1975,11 @@ msgstr "opération de flux non supportée" #: py/stream.c:254 msgid "string not supported; use bytes or bytearray" msgstr "" +"chaîne de carac. non supportée; utilisez des bytes ou un tableau de bytes" #: py/stream.c:289 msgid "length argument not allowed for this type" -msgstr "" +msgstr "argument lenght non permis pour ce type" #: py/vm.c:255 msgid "local variable referenced before assignment" @@ -1981,7 +1987,7 @@ msgstr "variable locale référencée avant d'être assignée" #: py/vm.c:1142 msgid "no active exception to reraise" -msgstr "aucune exception active a relevé" +msgstr "aucune exception active à relever" #: py/vm.c:1284 msgid "byte code not implemented" @@ -2010,13 +2016,12 @@ msgstr "tampon de caractères trop petit" #: shared-bindings/analogio/AnalogOut.c:118 msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" -"AnalogOut est seulement 16 bits. Les valeurs doivent être inférieures à " -"65536." +"AnalogOut est seulement 16 bits. Les valeurs doivent être inf. à 65536." #: shared-bindings/audiobusio/I2SOut.c:225 #: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" -msgstr "En pause" +msgstr "Ne joue pas" #: shared-bindings/audiobusio/PDMIn.c:124 msgid "Bit depth must be multiple of 8." @@ -2032,11 +2037,11 @@ msgstr "Le délais au démarrage du micro doit être entre 0.0 et 1.0" #: shared-bindings/audiobusio/PDMIn.c:193 msgid "destination_length must be an int >= 0" -msgstr "destination_length doit être un int >= 0" +msgstr "destination_length doit être un entier >= 0" #: shared-bindings/audiobusio/PDMIn.c:199 msgid "Cannot record to a file" -msgstr "impossible d'enregistrer vers un fichier" +msgstr "Impossible d'enregistrer vers un fichier" #: shared-bindings/audiobusio/PDMIn.c:202 msgid "Destination capacity is smaller than destination_length." @@ -2059,19 +2064,18 @@ msgid "Invalid voice count" msgstr "Type de service invalide" #: shared-bindings/audioio/Mixer.c:99 -#, fuzzy msgid "Invalid channel count" -msgstr "Argument invalide" +msgstr "" #: shared-bindings/audioio/Mixer.c:103 #, fuzzy msgid "Sample rate must be positive" -msgstr "'STA' doit être actif" +msgstr "le taux d'échantillonage doit être positif" #: shared-bindings/audioio/Mixer.c:107 #, fuzzy msgid "bits_per_sample must be 8 or 16" -msgstr "bits doivent être 7, 8 ou 9" +msgstr "bits doivent être 8 ou 16" #: shared-bindings/audioio/RawSample.c:98 msgid "" @@ -2088,7 +2092,7 @@ msgstr "le tampon doit être un objet bytes-like" #: shared-bindings/audioio/WaveFile.c:78 #: shared-bindings/displayio/OnDiskBitmap.c:85 msgid "file must be a file opened in byte mode" -msgstr "le fichier doit être un fichier ouvert en mode byte" +msgstr "le fichier doit être un fichier ouvert en mode 'byte'" #: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 #: shared-bindings/busio/SPI.c:133 @@ -2117,24 +2121,24 @@ msgstr "les slices de tampon doivent être de longueurs égales" #: shared-bindings/bleio/Address.c:101 msgid "Wrong address length" -msgstr "" +msgstr "Mauvaise longueur d'adresse" #: shared-bindings/bleio/Address.c:107 #, fuzzy msgid "Wrong number of bytes provided" -msgstr "mauvais nombres d'arguments" +msgstr "mauvais nombre d'octets fourni'" #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" -msgstr "" +msgstr "Impossible d'ajouter des service en mode Central" #: shared-bindings/bleio/Device.c:226 msgid "Can't connect in Peripheral mode" -msgstr "" +msgstr "Impossible de se connecter en mode Peripheral" #: shared-bindings/bleio/Device.c:256 msgid "Can't change the name in Central mode" -msgstr "" +msgstr "Modification du nom impossible en mode Central" #: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 msgid "Can't advertise in Central mode" @@ -2154,7 +2158,7 @@ msgstr "stop doit être 1 ou 2" #: shared-bindings/busio/UART.c:123 msgid "timeout >100 (units are now seconds, not msecs)" -msgstr "" +msgstr "timeout >100 (exprimé en secondes, pas en ms)" #: shared-bindings/digitalio/DigitalInOut.c:211 msgid "Invalid direction." @@ -2162,43 +2166,42 @@ msgstr "Direction invalide" #: shared-bindings/digitalio/DigitalInOut.c:240 msgid "Cannot set value when direction is input." -msgstr "Impossible d'affecter une valeur quand la direction est input." +msgstr "Impossible d'affecter une valeur quand la direction est 'input'." #: shared-bindings/digitalio/DigitalInOut.c:266 #: shared-bindings/digitalio/DigitalInOut.c:281 msgid "Drive mode not used when direction is input." -msgstr "Le mode Drive n'est pas utilisé quand la direction est 'input'" +msgstr "Le mode Drive n'est pas utilisé quand la direction est 'input'." #: shared-bindings/digitalio/DigitalInOut.c:314 #: shared-bindings/digitalio/DigitalInOut.c:331 msgid "Pull not used when direction is output." -msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'" +msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'." #: shared-bindings/digitalio/DigitalInOut.c:340 msgid "Unsupported pull value." -msgstr "Valeur de 'pull' non supportée" +msgstr "Valeur de tirage 'pull' non supportée." #: shared-bindings/displayio/Bitmap.c:84 #, fuzzy msgid "y should be an int" -msgstr "La longueur doit être entière" +msgstr "y doit être un entier (int)" #: shared-bindings/displayio/Bitmap.c:89 #, fuzzy msgid "row buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -"le tampon de sample_source doit être un bytearray ou un tableau de type " -"'h','H', 'b' ou 'B'" +"le tampon de ligne doit être un bytearray ou un tableau de type 'b' ou 'B'" #: shared-bindings/displayio/Bitmap.c:94 #, fuzzy msgid "row data must be a buffer" -msgstr "les constantes doivent être des entiers" +msgstr "les données de ligne doivent être un tampon" #: shared-bindings/displayio/ColorConverter.c:72 #, fuzzy msgid "color should be an int" -msgstr "La longueur doit être entière" +msgstr "la couleur doit être un entier (int)" #: shared-bindings/displayio/FourWire.c:55 #: shared-bindings/displayio/FourWire.c:64 @@ -2214,44 +2217,42 @@ msgstr "Le tampon doit être de longueur au moins 1" #, fuzzy msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -"le tampon de sample_source doit être un bytearray ou un tableau de type " -"'h','H', 'b' ou 'B'" +"le tampon de couleur doit être un bytearray ou un tableau de type 'b' ou 'B'" #: shared-bindings/displayio/Palette.c:102 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" -msgstr "" -"Le tampon couleur doit avoir 3 octets (RVB) ou 4 octets (RVB + octet de " -"padding)" +msgstr "le tampon de couleur doit faire 3 octets (RVB) ou 4 (RVB + pad byte)" #: shared-bindings/displayio/Palette.c:106 #, fuzzy msgid "color must be between 0x000000 and 0xffffff" -msgstr "Les octets 'bytes' doivent être entre 0 et 255" +msgstr "la couleur doit être entre 0x000000 et 0xffffff" #: shared-bindings/displayio/Palette.c:110 #, fuzzy msgid "color buffer must be a buffer or int" -msgstr "le tampon doit être un objet bytes-like" +msgstr "le tampon de couleur doit être un tampon ou un entier" #: shared-bindings/displayio/Palette.c:123 #: shared-bindings/displayio/Palette.c:137 #, fuzzy msgid "palette_index should be an int" -msgstr "Les valeurs du tableau doivent être des octets simples 'bytes'" +msgstr "palette_index devrait être un entier (int)'" #: shared-bindings/displayio/Sprite.c:48 #, fuzzy msgid "position must be 2-tuple" -msgstr "stop doit être 1 ou 2" +msgstr "position doit être un 2-tuple" #: shared-bindings/displayio/Sprite.c:97 #, fuzzy msgid "unsupported bitmap type" -msgstr "Débit non supporté" +msgstr "type de bitmap non supporté" #: shared-bindings/displayio/Sprite.c:162 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" +"pixel_shader doit être un objet displayio.Palette ou displayio.ColorConverter" #: shared-bindings/gamepad/GamePad.c:100 msgid "too many arguments" @@ -2259,7 +2260,7 @@ msgstr "trop d'arguments" #: shared-bindings/gamepad/GamePad.c:104 msgid "expected a DigitalInOut" -msgstr "un objet DigitalInOut attendu" +msgstr "objet DigitalInOut attendu" #: shared-bindings/i2cslave/I2CSlave.c:98 #, fuzzy @@ -2268,11 +2269,11 @@ msgstr "ne peut convertir %s en entier int" #: shared-bindings/i2cslave/I2CSlave.c:101 msgid "address out of bounds" -msgstr "Adresse hors limite" +msgstr "adresse hors limites" #: shared-bindings/i2cslave/I2CSlave.c:107 msgid "addresses is empty" -msgstr "Adresses est vide" +msgstr "adresses vides" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 @@ -2298,11 +2299,11 @@ msgstr "Slice et valeur de tailles différentes" #: shared-bindings/nvm/ByteArray.c:104 msgid "Array values should be single bytes." -msgstr "Les valeurs du tableau doivent être des octets simples 'bytes'" +msgstr "Les valeurs du tableau doivent être des octets simples 'bytes'." #: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141 msgid "Unable to write to nvm." -msgstr "Impossible d'écrire sur la nvm" +msgstr "Impossible d'écrire sur la nvm." #: shared-bindings/nvm/ByteArray.c:137 msgid "Bytes must be between 0 and 255." @@ -2325,7 +2326,7 @@ msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" "La fréquence de PWM n'est pas modifiable quand variable_frequency est False " -"à laconstruction." +"à la construction." #: shared-bindings/pulseio/PulseIn.c:275 msgid "Cannot delete values" @@ -2349,7 +2350,7 @@ msgstr "Le tableau doit contenir des halfwords (type 'H')" #: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100 msgid "stop not reachable from start" -msgstr "stop n'est pas accessible de start" +msgstr "stop n'est pas accessible au démarrage" #: shared-bindings/random/__init__.c:111 msgid "step must be non-zero" @@ -2411,7 +2412,7 @@ msgstr "la fonction prend exactement 9 arguments" #: shared-bindings/time/__init__.c:239 shared-bindings/time/__init__.c:272 msgid "timestamp out of range for platform time_t" -msgstr "timestamp hors gamme pour la plateforme time_t" +msgstr "timestamp hors gamme pour time_t de la plateforme" #: shared-bindings/touchio/TouchIn.c:173 msgid "threshold must be in the range 0-65536" @@ -2438,19 +2439,19 @@ msgstr "Index de la voix trop grand" #: shared-module/audioio/Mixer.c:85 msgid "The sample's sample rate does not match the mixer's" -msgstr "" +msgstr "L'échantillonage de l'échantillon ne correspond pas à celui du mixer" #: shared-module/audioio/Mixer.c:88 msgid "The sample's channel count does not match the mixer's" -msgstr "" +msgstr "Le canal de l'échantillon ne correspond pas à celui du mixer" #: shared-module/audioio/Mixer.c:91 msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "Le bits_per_sample de l'échantillon ne correspond pas au mixer" +msgstr "Le bits_per_sample de l'échantillon ne correspond pas à celui du mixer" #: shared-module/audioio/Mixer.c:100 msgid "The sample's signedness does not match the mixer's" -msgstr "L'échantillon non signé ne correspond pas au mixer" +msgstr "Le signe de l'échantillon ne correspond pas au mixer" #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" @@ -2502,7 +2503,7 @@ msgstr "Pas de transfert sans broches MOSI et MISO" #: shared-module/displayio/Bitmap.c:49 msgid "Only bit maps of 8 bit color or less are supported" -msgstr "Seul les mappings en couleur 8 bits (ou moins) sont supportés" +msgstr "Seules les bitmaps de 8bits par couleur ou moins sont supportées" #: shared-module/displayio/Bitmap.c:69 msgid "row must be packed and word aligned" @@ -2510,7 +2511,7 @@ msgstr "" #: shared-module/displayio/Group.c:39 msgid "Group full" -msgstr "Group complet" +msgstr "Groupe plein" #: shared-module/displayio/Group.c:48 #, fuzzy @@ -2525,12 +2526,12 @@ msgstr "Fichier invalide" #: shared-module/displayio/OnDiskBitmap.c:59 #, c-format msgid "Only Windows format, uncompressed BMP supported %d" -msgstr "Seul le format Windows, BMP non compressé, est supporté %d" +msgstr "Seul les BMP non-compressé au format Windows sont supportés %d" #: shared-module/displayio/OnDiskBitmap.c:64 #, c-format msgid "Only true color (24 bpp or higher) BMP supported %x" -msgstr "Seul les BMP 'true color' (24 bpp ou plus) sont supportés %x" +msgstr "Seul les BMP 24bits ou plus sont supportés %x" #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." @@ -2570,8 +2571,7 @@ msgstr "Pour quitter, redémarrez la carte SVP sans " msgid "" "You are running in safe mode which means something unanticipated happened.\n" msgstr "" -"Vous êtes en mode sans-échec ce qui signifie que quelque chose demauvais est " -"arrivé.\n" +"Vous êtes en mode sans-échec ce qui signifie qu'un imprévu est survenu.\n" #: supervisor/shared/safe_mode.c:109 msgid "" @@ -2579,6 +2579,10 @@ msgid "" "Please file an issue at https://github.com/adafruit/circuitpython/issues\n" " with the contents of your CIRCUITPY drive and this message:\n" msgstr "" +"On dirait que notre code CircuitPython a durement planté. Oups !\n" +"Merci de remplir un ticket sur https://github.com/adafruit/circuitpython/" +"issues\n" +"avec le contenu de votre lecteur CIRCUITPY et ce message:\n" #: supervisor/shared/safe_mode.c:111 msgid "Crash into the HardFault_Handler.\n" @@ -2590,7 +2594,7 @@ msgstr "" #: supervisor/shared/safe_mode.c:115 msgid "MicroPython fatal error.\n" -msgstr "" +msgstr "Erreur fatale de MicroPython.\n" #: supervisor/shared/safe_mode.c:118 #, fuzzy @@ -2602,6 +2606,8 @@ msgid "" msgstr "" "L'alimentation du microcontroleur a chuté. Merci de vérifier que votre " "alimentation fournit\n" +"suffisamment de puissance pour l'ensemble du circuit et appuyez sur " +"'reset' (après avoir éjecter CIRCUITPY).\n" #: supervisor/shared/safe_mode.c:120 msgid "" @@ -2611,36 +2617,37 @@ msgid "" "If you didn't change the stack, then file an issue here with the contents of " "your CIRCUITPY drive:\n" msgstr "" +"La pile de CircuitPython a été corrompue parce que la pile était trop " +"petite.\n" +"Augmentez la limite de taille de la pile et appuyez sur 'reset' (après avoir " +"éjecter CIRCUITPY).\n" +"Si vous n'avez pas modifié la pile, merci de remplir un ticket avec le " +"contenu de votre lecteur CIRCUITPY :\n" #: supervisor/shared/safe_mode.c:123 msgid "" "The reset button was pressed while booting CircuitPython. Press again to " "exit safe mode.\n" msgstr "" +"Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " +"Appuyer denouveau pour quitter de le mode sans-échec.\n" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" - -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" - -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2649,19 +2656,26 @@ msgstr "" #~ "assez de puissance pour l'ensemble du circuit et appuyez sur " #~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size est une puissance de deux" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "palettre doit être displayio.Palette" +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" From 5c776db9b113d5a0a70f8e8458c11d22772f9e3a Mon Sep 17 00:00:00 2001 From: Pierrick C Date: Wed, 26 Dec 2018 20:50:24 +0100 Subject: [PATCH 031/153] make translate --- locale/circuitpython.pot | 24 +++++----- locale/de_DE.po | 80 ++++++++++++++++----------------- locale/en_US.po | 24 +++++----- locale/es.po | 96 ++++++++++++++++++++-------------------- locale/fil.po | 96 ++++++++++++++++++++-------------------- locale/fr.po | 68 ++++++++++++++-------------- locale/it_IT.po | 86 +++++++++++++++++------------------ locale/pt_BR.po | 62 +++++++++++++------------- 8 files changed, 268 insertions(+), 268 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a8883c8d77928..92e1813025bdc 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: 2018-12-06 17:04-0800\n" +"POT-Creation-Date: 2018-12-26 20:49+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:83 +#: ports/nrf/common-hal/busio/UART.c:106 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:116 +#: ports/nrf/common-hal/busio/UART.c:140 msgid "Failed to allocate RX buffer" msgstr "" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:157 +#: ports/nrf/common-hal/busio/UART.c:185 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:207 +#: ports/nrf/common-hal/busio/UART.c:220 msgid "No TX pin" msgstr "" @@ -779,19 +779,19 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:87 +#: ports/nrf/common-hal/busio/UART.c:110 msgid "Invalid buffer size" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:114 msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 -#: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 -#: ports/nrf/common-hal/busio/UART.c:354 ports/nrf/common-hal/busio/UART.c:359 -#: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 -#: ports/nrf/common-hal/busio/UART.c:376 +#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 +#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 +#: ports/nrf/common-hal/busio/UART.c:388 msgid "busio.UART not available" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 05c5ae72d005a..e9f81e0b13c84 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 17:04-0800\n" +"POT-Creation-Date: 2018-12-26 20:49+0100\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -350,12 +350,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:83 +#: ports/nrf/common-hal/busio/UART.c:106 msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:116 +#: ports/nrf/common-hal/busio/UART.c:140 msgid "Failed to allocate RX buffer" msgstr "Konnte keinen RX Buffer allozieren" @@ -364,12 +364,12 @@ msgid "Could not initialize UART" msgstr "Konnte UART nicht initialisieren" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:157 +#: ports/nrf/common-hal/busio/UART.c:185 msgid "No RX pin" msgstr "Kein RX Pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:207 +#: ports/nrf/common-hal/busio/UART.c:220 msgid "No TX pin" msgstr "Kein TX Pin" @@ -789,21 +789,21 @@ msgstr "Alle timer werden benutzt" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:87 +#: ports/nrf/common-hal/busio/UART.c:110 #, fuzzy msgid "Invalid buffer size" msgstr "ungültiger dupterm index" -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:114 #, fuzzy msgid "Odd parity is not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" -#: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 -#: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 -#: ports/nrf/common-hal/busio/UART.c:354 ports/nrf/common-hal/busio/UART.c:359 -#: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 -#: ports/nrf/common-hal/busio/UART.c:376 +#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 +#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 +#: ports/nrf/common-hal/busio/UART.c:388 msgid "busio.UART not available" msgstr "" @@ -2571,28 +2571,20 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" - -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" - -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Kann PPCP Parameter nicht setzen." #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2601,17 +2593,25 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Kann PPCP Parameter nicht setzen." +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" diff --git a/locale/en_US.po b/locale/en_US.po index c7808713896a0..119dde3d68cec 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 17:04-0800\n" +"POT-Creation-Date: 2018-12-26 20:49+0100\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:83 +#: ports/nrf/common-hal/busio/UART.c:106 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:116 +#: ports/nrf/common-hal/busio/UART.c:140 msgid "Failed to allocate RX buffer" msgstr "" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:157 +#: ports/nrf/common-hal/busio/UART.c:185 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:207 +#: ports/nrf/common-hal/busio/UART.c:220 msgid "No TX pin" msgstr "" @@ -779,19 +779,19 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:87 +#: ports/nrf/common-hal/busio/UART.c:110 msgid "Invalid buffer size" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:114 msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 -#: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 -#: ports/nrf/common-hal/busio/UART.c:354 ports/nrf/common-hal/busio/UART.c:359 -#: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 -#: ports/nrf/common-hal/busio/UART.c:376 +#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 +#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 +#: ports/nrf/common-hal/busio/UART.c:388 msgid "busio.UART not available" msgstr "" diff --git a/locale/es.po b/locale/es.po index 0251a9d83af74..29c69d49c2535 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 17:04-0800\n" +"POT-Creation-Date: 2018-12-26 20:49+0100\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -352,12 +352,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits no soportados" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:83 +#: ports/nrf/common-hal/busio/UART.c:106 msgid "tx and rx cannot both be None" msgstr "Ambos tx y rx no pueden ser None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:116 +#: ports/nrf/common-hal/busio/UART.c:140 msgid "Failed to allocate RX buffer" msgstr "Ha fallado la asignación del buffer RX" @@ -366,12 +366,12 @@ msgid "Could not initialize UART" msgstr "No se puede inicializar la UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:157 +#: ports/nrf/common-hal/busio/UART.c:185 msgid "No RX pin" msgstr "Sin pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:207 +#: ports/nrf/common-hal/busio/UART.c:220 msgid "No TX pin" msgstr "Sin pin TX" @@ -787,19 +787,19 @@ msgstr "Todos los timers están siendo usados" msgid "error = 0x%08lX" msgstr "error = 0x%08lx" -#: ports/nrf/common-hal/busio/UART.c:87 +#: ports/nrf/common-hal/busio/UART.c:110 msgid "Invalid buffer size" msgstr "Tamaño de buffer inválido" -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:114 msgid "Odd parity is not supported" msgstr "Paridad impar no soportada" -#: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 -#: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 -#: ports/nrf/common-hal/busio/UART.c:354 ports/nrf/common-hal/busio/UART.c:359 -#: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 -#: ports/nrf/common-hal/busio/UART.c:376 +#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 +#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 +#: ports/nrf/common-hal/busio/UART.c:388 msgid "busio.UART not available" msgstr "busio.UART no disponible" @@ -2585,53 +2585,53 @@ msgid "" "exit safe mode.\n" msgstr "" -#, fuzzy -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " -#~ "unidad de almacenamiento CIRCUITPY:\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "suficiente poder para todo el circuito y presiona reset (después de " -#~ "expulsar CIRCUITPY).\n" +#~ msgid "Can not add Characteristic." +#~ msgstr "No se puede agregar la Característica." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "No se pueden establecer los parámetros PPCP." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "No se puede codificar el UUID, para revisar la longitud." -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Baud rate demasiado alto para este periférico SPI" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" #~ msgid "Can not add Service." #~ msgstr "No se puede agregar el Servicio." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de Servicio inválido" +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." -#~ msgid "Can not add Characteristic." -#~ msgstr "No se puede agregar la Característica." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "suficiente poder para todo el circuito y presiona reset (después de " +#~ "expulsar CIRCUITPY).\n" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" + +#, fuzzy +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " +#~ "unidad de almacenamiento CIRCUITPY:\n" diff --git a/locale/fil.po b/locale/fil.po index 4c5598978f4b7..53ca5d22a9a3b 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 17:04-0800\n" +"POT-Creation-Date: 2018-12-26 20:49+0100\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -350,12 +350,12 @@ msgid "bytes > 8 bits not supported" msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:83 +#: ports/nrf/common-hal/busio/UART.c:106 msgid "tx and rx cannot both be None" msgstr "tx at rx hindi pwedeng parehas na None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:116 +#: ports/nrf/common-hal/busio/UART.c:140 msgid "Failed to allocate RX buffer" msgstr "Nabigong ilaan ang RX buffer" @@ -364,12 +364,12 @@ msgid "Could not initialize UART" msgstr "Hindi ma-initialize ang UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:157 +#: ports/nrf/common-hal/busio/UART.c:185 msgid "No RX pin" msgstr "Walang RX pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:207 +#: ports/nrf/common-hal/busio/UART.c:220 msgid "No TX pin" msgstr "Walang TX pin" @@ -786,19 +786,19 @@ msgstr "Lahat ng SPI peripherals ay ginagamit" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:87 +#: ports/nrf/common-hal/busio/UART.c:110 msgid "Invalid buffer size" msgstr "Mali ang buffer size" -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:114 msgid "Odd parity is not supported" msgstr "Odd na parity ay hindi supportado" -#: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 -#: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 -#: ports/nrf/common-hal/busio/UART.c:354 ports/nrf/common-hal/busio/UART.c:359 -#: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 -#: ports/nrf/common-hal/busio/UART.c:376 +#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 +#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 +#: ports/nrf/common-hal/busio/UART.c:388 msgid "busio.UART not available" msgstr "busio.UART hindi available" @@ -2600,53 +2600,53 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " -#~ "drive:\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " -#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" +#~ msgid "Can not add Characteristic." +#~ msgstr "Hindi mabasa and Characteristic." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Hindi ma-set ang PPCP parameters." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "ang palette ay dapat 32 bytes ang haba" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" #~ msgid "Can not add Service." #~ msgstr "Hindi maidaragdag ang serbisyo." -#~ msgid "Invalid Service type" -#~ msgstr "Mali ang tipo ng serbisyo" +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "ang palette ay dapat 32 bytes ang haba" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." -#~ msgid "Can not add Characteristic." -#~ msgstr "Hindi mabasa and Characteristic." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " +#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " +#~ "drive:\n" diff --git a/locale/fr.po b/locale/fr.po index 9236fb8aa1fba..61781fe5bd359 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: 2018-12-26 17:29+0100\n" +"POT-Creation-Date: 2018-12-26 20:49+0100\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -710,8 +710,8 @@ msgid "Can not fit data into the advertisment packet" msgstr "" #: ports/nrf/common-hal/bleio/Device.c:266 -#, c-format -msgid "Failed to discover services, status: 0x%08lX" +#, fuzzy, c-format +msgid "Failed to discover serivices, status: 0x%08lX" msgstr "Echec de la découverte de services, statut: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:403 @@ -2632,22 +2632,29 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer denouveau pour quitter de le mode sans-échec.\n" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être une displayio.Palette" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size doit être une puissance de 2" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." + +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2656,26 +2663,19 @@ msgstr "" #~ "assez de puissance pour l'ensemble du circuit et appuyez sur " #~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" - -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" diff --git a/locale/it_IT.po b/locale/it_IT.po index e9a970b85adeb..4cb328319d408 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 17:04-0800\n" +"POT-Creation-Date: 2018-12-26 20:49+0100\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -351,12 +351,12 @@ msgid "bytes > 8 bits not supported" msgstr "byte > 8 bit non supportati" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:83 +#: ports/nrf/common-hal/busio/UART.c:106 msgid "tx and rx cannot both be None" msgstr "tx e rx non possono essere entrambi None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:116 +#: ports/nrf/common-hal/busio/UART.c:140 msgid "Failed to allocate RX buffer" msgstr "Impossibile allocare buffer RX" @@ -365,12 +365,12 @@ msgid "Could not initialize UART" msgstr "Impossibile inizializzare l'UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:157 +#: ports/nrf/common-hal/busio/UART.c:185 msgid "No RX pin" msgstr "Nessun pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:207 +#: ports/nrf/common-hal/busio/UART.c:220 msgid "No TX pin" msgstr "Nessun pin TX" @@ -787,21 +787,21 @@ msgstr "Tutte le periferiche SPI sono in uso" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:87 +#: ports/nrf/common-hal/busio/UART.c:110 #, fuzzy msgid "Invalid buffer size" msgstr "lunghezza del buffer non valida" -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:114 #, fuzzy msgid "Odd parity is not supported" msgstr "operazione I2C non supportata" -#: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 -#: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 -#: ports/nrf/common-hal/busio/UART.c:354 ports/nrf/common-hal/busio/UART.c:359 -#: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 -#: ports/nrf/common-hal/busio/UART.c:376 +#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 +#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 +#: ports/nrf/common-hal/busio/UART.c:388 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART non ancora implementato" @@ -2601,31 +2601,20 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " -#~ "Whoops!\n" - -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " -#~ "CIRCUITPY:\n" - -#~ msgid "Can not add Service." -#~ msgstr "Non è possibile aggiungere Service." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." -#~ msgid "Can not add Characteristic." -#~ msgstr "Non è possibile aggiungere Characteristic." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2634,17 +2623,28 @@ msgstr "" #~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " #~ "espulso CIRCUITPY).\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossibile applicare i parametri GAP." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo di servizio non valido" +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " +#~ "CIRCUITPY:\n" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " +#~ "Whoops!\n" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 7a0cf64862833..1b35b48247537 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 17:04-0800\n" +"POT-Creation-Date: 2018-12-26 20:49+0100\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits não suportado" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:83 +#: ports/nrf/common-hal/busio/UART.c:106 msgid "tx and rx cannot both be None" msgstr "TX e RX não podem ser ambos" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:116 +#: ports/nrf/common-hal/busio/UART.c:140 msgid "Failed to allocate RX buffer" msgstr "Falha ao alocar buffer RX" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "Não foi possível inicializar o UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:157 +#: ports/nrf/common-hal/busio/UART.c:185 msgid "No RX pin" msgstr "Nenhum pino RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:207 +#: ports/nrf/common-hal/busio/UART.c:220 msgid "No TX pin" msgstr "Nenhum pino TX" @@ -780,21 +780,21 @@ msgstr "Todos os periféricos SPI estão em uso" msgid "error = 0x%08lX" msgstr "erro = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:87 +#: ports/nrf/common-hal/busio/UART.c:110 #, fuzzy msgid "Invalid buffer size" msgstr "Arquivo inválido" -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:114 #, fuzzy msgid "Odd parity is not supported" msgstr "I2C operação não suportada" -#: ports/nrf/common-hal/busio/UART.c:334 ports/nrf/common-hal/busio/UART.c:338 -#: ports/nrf/common-hal/busio/UART.c:343 ports/nrf/common-hal/busio/UART.c:348 -#: ports/nrf/common-hal/busio/UART.c:354 ports/nrf/common-hal/busio/UART.c:359 -#: ports/nrf/common-hal/busio/UART.c:364 ports/nrf/common-hal/busio/UART.c:368 -#: ports/nrf/common-hal/busio/UART.c:376 +#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 +#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 +#: ports/nrf/common-hal/busio/UART.c:388 msgid "busio.UART not available" msgstr "busio.UART não disponível" @@ -2557,32 +2557,32 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Can not add Service." -#~ msgstr "Não é possível adicionar o serviço." - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possível adicionar Característica." -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" #~ msgid "Cannot apply GAP parameters." #~ msgstr "Não é possível aplicar parâmetros GAP." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Can not add Characteristic." -#~ msgstr "Não é possível adicionar Característica." +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" + +#~ msgid "Can not add Service." +#~ msgstr "Não é possível adicionar o serviço." From 4167bf5b241eec4e5a04c36d7f7c66d43a8bb921 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 27 Dec 2018 00:04:04 -0500 Subject: [PATCH 032/153] wip: advertising works, but not connection --- docs/drivers.rst | 2 +- ports/atmel-samd/Makefile | 7 +- ports/nrf/Makefile | 14 ++-- ports/nrf/common-hal/bleio/Characteristic.c | 76 ++++++++++------- ports/nrf/common-hal/bleio/Scanner.c | 4 +- ports/nrf/common-hal/bleio/Service.c | 93 ++++++++++++--------- ports/nrf/common-hal/bleio/UUID.c | 4 +- ports/nrf/common-hal/bleio/__init__.c | 24 ++++++ py/runtime.c | 8 ++ py/runtime.h | 1 + shared-bindings/bleio/Address.c | 2 +- shared-bindings/bleio/Descriptor.c | 10 +-- shared-bindings/bleio/Device.c | 2 +- shared-bindings/bleio/Service.c | 20 ++--- shared-bindings/bleio/Service.h | 3 +- shared-bindings/bleio/__init__.c | 4 +- shared-module/bleio/Service.h | 4 +- 17 files changed, 163 insertions(+), 115 deletions(-) diff --git a/docs/drivers.rst b/docs/drivers.rst index 119706d33c618..fcd94bc3b8f1f 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -213,7 +213,7 @@ These provide functionality similar to `analogio`, `digitalio`, `pulseio`, and ` Adafruit SeeSaw ADS1x15 Analog-to-Digital Converter - Crickit Robotics Boards < + Crickit Robotics Boards DS2413 OneWire GPIO Expander FocalTech Capacitive Touch MCP230xx GPIO Expander diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 9a31eb42aeb25..91795ab01b516 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -81,9 +81,10 @@ BASE_CFLAGS = \ -DCIRCUITPY_SAFE_RESTART_WORD=0xDEADBEEF \ --param max-inline-insns-single=500 - # Use these flags to debug build times and header includes. - # -ftime-report - # -H +# Use these flags to debug build times and header includes. +# -ftime-report +# -H + # NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt. ifeq ($(CHIP_FAMILY), samd21) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 8491e54a2ab9c..c427cdd2659c0 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -79,12 +79,14 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_C #Debugging/Optimization ifeq ($(DEBUG), 1) -#ASMFLAGS += -g -gtabs+ -CFLAGS += -O1 -ggdb -LDFLAGS += -O1 + #ASMFLAGS += -g -gtabs+ + CFLAGS += -O1 -ggdb + LDFLAGS += -O1 + # You may want to enable these flags to make setting breakpoints easier. + CFLAGS += -fno-inline -fno-ipa-sra else -CFLAGS += -Os -DNDEBUG -LDFLAGS += -Os + CFLAGS += -Os -DNDEBUG + LDFLAGS += -Os endif LIBM_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-file-name=libm.a) @@ -172,7 +174,7 @@ SRC_COMMON_HAL += \ bleio/Adapter.c \ bleio/Characteristic.c \ bleio/Descriptor.c \ - bleio/Device.c \ + bleio/LocalPeripheral.c \ bleio/Scanner.c \ bleio/Service.c \ bleio/UUID.c diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 5a0025d1c0170..17656c26943b1 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -30,16 +30,19 @@ #include "ble_drv.h" #include "ble_gatts.h" #include "nrf_soc.h" + #include "py/runtime.h" +#include "common-hal/bleio/__init__.h" #include "shared-module/bleio/Characteristic.h" -static volatile bleio_characteristic_obj_t *m_read_characteristic; -static volatile uint8_t m_tx_in_progress; -static nrf_mutex_t *m_write_mutex; + +STATIC volatile bleio_characteristic_obj_t *m_read_characteristic; +STATIC volatile uint8_t m_tx_in_progress; +STATIC nrf_mutex_t *m_write_mutex; + STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - bleio_device_obj_t *device = characteristic->service->device; - const uint16_t conn_handle = device->conn_handle; + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); ble_gatts_value_t gatts_value = { .p_value = bufinfo->buf, @@ -48,17 +51,17 @@ STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to write gatts value")); + mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code); } } STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - bleio_device_obj_t *device = characteristic->service->device; uint16_t hvx_len = bufinfo->len; ble_gatts_hvx_params_t hvx_params = { .handle = characteristic->handle, .type = BLE_GATT_HVX_NOTIFICATION, + .offset = 0, .p_len = &hvx_len, .p_data = bufinfo->buf, }; @@ -69,25 +72,26 @@ STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_i #endif } - const uint32_t err_code = sd_ble_gatts_hvx(device->conn_handle, &hvx_params); + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); + const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to notify attribute value")); + mp_raise_OSError_msg_varg(translate("Failed to notify attribute value, err %0x04x"), err_code); } m_tx_in_progress += 1; } STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { - bleio_service_obj_t *service = characteristic->service; - bleio_device_obj_t *device = service->device; + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); m_read_characteristic = characteristic; - const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); + const uint32_t err_code = sd_ble_gattc_read(conn_handle, characteristic->handle, 0); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to read attribute value")); + mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err %0x04x"), err_code); } +// while (m_read_characteristic != NULL) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP @@ -96,7 +100,7 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { } STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - bleio_device_obj_t *device = characteristic->service->device; + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); uint32_t err_code; ble_gattc_write_params_t write_params = { @@ -112,13 +116,13 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in err_code = sd_mutex_acquire(m_write_mutex); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to acquire mutex")); + mp_raise_OSError_msg_varg(translate("Failed to acquire mutex, err 0x%04x"), err_code); } } - err_code = sd_ble_gattc_write(device->conn_handle, &write_params); + err_code = sd_ble_gattc_write(conn_handle, &write_params); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to write attribute value")); + mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code); } while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -129,33 +133,28 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in err_code = sd_mutex_release(m_write_mutex); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to release mutex")); + mp_raise_OSError_msg_varg(translate("Failed to release mutex, err 0x%04x"), err_code); } } STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) { switch (ble_evt->header.evt_id) { -#if (BLE_API_VERSION == 4) case BLE_GATTS_EVT_HVN_TX_COMPLETE: m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; break; -#else - case BLE_EVT_TX_COMPLETE: - m_tx_in_progress -= ble_evt->evt.common_evt.params.tx_complete.count; - break; -#endif case BLE_GATTC_EVT_READ_RSP: { ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data); + // Flag to busy-wait loop that we've read the characteristic. m_read_characteristic = NULL; break; } case BLE_GATTC_EVT_WRITE_RSP: + // Someone else can write now. sd_mutex_release(m_write_mutex); -// m_write_done = true; break; } } @@ -165,21 +164,34 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self) } void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) { - gattc_read(self); + switch (common_hal_bleio_device_get_gatt_role(self->service->device)) { + case GATT_ROLE_CLIENT: + gattc_read(self); + break; + + default: + mp_raise_RuntimeError(translate("bad GATT role")); + break; + } } void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { - const bleio_device_obj_t *device = self->service->device; - - if (device->is_peripheral) { - // TODO: Add indications + switch (common_hal_bleio_device_get_gatt_role(self->service->device)) { + case GATT_ROLE_SERVER: if (self->props.notify) { gatts_notify(self, bufinfo); } else { gatts_write(self, bufinfo); } - } else { + break; + + case GATT_ROLE_CLIENT: + // TODO: Add indications gattc_write(self, bufinfo); - } + break; + default: + mp_raise_RuntimeError(translate("bad GATT role")); + break; + } } diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c index fd997a6d3c9ca..d2e19b5f9f3e8 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -72,7 +72,7 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) { #if (BLUETOOTH_SD == 140) const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to continue scanning")); + mp_raise_OSError_msg_varg(translate("Failed to continue scanning, err 0x%04x"), err_code); } #endif } @@ -98,7 +98,7 @@ void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout) #endif if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Failed to start scanning")); + mp_raise_OSError_msg_varg(translate("Failed to start scanning, err 0x%04x"), err_code); } if (timeout > 0) { diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 29d96e8277efa..e6aab8563cdc1 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -27,58 +27,69 @@ #include "ble_drv.h" #include "ble.h" #include "py/runtime.h" +#include "common-hal/bleio/__init__.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/Adapter.h" -void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) { - ble_gatts_char_md_t char_md = { - .char_props.broadcast = characteristic->props.broadcast, - .char_props.read = characteristic->props.read, - .char_props.write_wo_resp = characteristic->props.write_no_response, - .char_props.write = characteristic->props.write, - .char_props.notify = characteristic->props.notify, - .char_props.indicate = characteristic->props.indicate, - }; +void common_hal_bleio_service_construct(bleio_service_obj_t *self) { +} - ble_gatts_attr_md_t cccd_md = { - .vloc = BLE_GATTS_VLOC_STACK, - }; +// Call this after the Service has been added to the LocalPeripheral. +void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) { + // Add all the characteristics. + const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(self->char_list); + for (size_t char_idx = 0; char_idx < char_list->len; ++char_idx) { + bleio_characteristic_obj_t *characteristic = char_list->items[char_idx]; - if (char_md.char_props.notify || char_md.char_props.indicate) { - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); + ble_gatts_char_md_t char_md = { + .char_props.broadcast = characteristic->props.broadcast, + .char_props.read = characteristic->props.read, + .char_props.write_wo_resp = characteristic->props.write_no_response, + .char_props.write = characteristic->props.write, + .char_props.notify = characteristic->props.notify, + .char_props.indicate = characteristic->props.indicate, + }; - char_md.p_cccd_md = &cccd_md; - } + ble_gatts_attr_md_t cccd_md = { + .vloc = BLE_GATTS_VLOC_STACK, + }; - ble_uuid_t uuid; - bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &uuid); + if (char_md.char_props.notify || char_md.char_props.indicate) { + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); - ble_gatts_attr_md_t attr_md = { - .vloc = BLE_GATTS_VLOC_STACK, - .vlen = 1, - }; + char_md.p_cccd_md = &cccd_md; + } - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &uuid); - ble_gatts_attr_t attr_char_value = { - .p_uuid = &uuid, - .p_attr_md = &attr_md, - .init_len = sizeof(uint8_t), - .max_len = (BLE_GATT_ATT_MTU_DEFAULT - 3), - }; + ble_gatts_attr_md_t attr_md = { + .vloc = BLE_GATTS_VLOC_STACK, + .vlen = 1, + }; - ble_gatts_char_handles_t handles; + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); - uint32_t err_code; - err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Could not add characteristic")); - } + ble_gatts_attr_t attr_char_value = { + .p_uuid = &uuid, + .p_attr_md = &attr_md, + .init_len = sizeof(uint8_t), + .max_len = GATT_MAX_DATA_LENGTH, + }; - characteristic->user_desc_handle = handles.user_desc_handle; - characteristic->cccd_handle = handles.cccd_handle; - characteristic->sccd_handle = handles.sccd_handle; - characteristic->handle = handles.value_handle; + ble_gatts_char_handles_t handles; + + uint32_t err_code; + err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code); + } + + characteristic->user_desc_handle = handles.user_desc_handle; + characteristic->cccd_handle = handles.cccd_handle; + characteristic->sccd_handle = handles.sccd_handle; + characteristic->handle = handles.value_handle; + } } diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c index 8aad85ce304de..23e643433ff13 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -51,7 +51,7 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, ui // Register this vendor-specific UUID. Bytes 12 and 13 will be zero. const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->nrf_ble_uuid.type); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg(translate("Could not register Vendor-Specific UUID")); + mp_raise_OSError_msg_varg(translate("Failed to register Vendor-Specific UUID, err 0x%04x"), err_code); } } } @@ -70,7 +70,7 @@ bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[1 const uint32_t err_code = sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128); if (err_code != NRF_SUCCESS) { - mp_raise_RuntimeError(translate("Could not decode ble_uuid")); + mp_raise_OSError_msg_varg(translate("Could not decode ble_uuid, err 0x%04x"), err_code); } // If not 16 bytes, this is not a 128-bit UUID, so return. return length == 16; diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index 0cc1b71522af6..f795e889b4bcb 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -27,6 +27,8 @@ #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/LocalPeripheral.h" +#include "common-hal/bleio/__init__.h" // The singleton bleio.Adapter object, bound to bleio.adapter // It currently only has properties and no state @@ -35,3 +37,25 @@ const super_adapter_obj_t common_hal_bleio_adapter_obj = { .type = &bleio_adapter_type, }, }; + +gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device) { + if (MP_OBJ_IS_TYPE(device, &bleio_local_peripheral_type)) { + return ((bleio_local_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; +// Does not exist yet. +// } else if (MP_OBJ_IS_TYPE(device, &bleio_local_central_type)) { +// return ((bleio_local_central_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; + } else { + return GATT_ROLE_NONE; + } +} + +uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) { + if (MP_OBJ_IS_TYPE(device, &bleio_local_peripheral_type)) { + return ((bleio_local_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; +// Does not exist yet. +// } else if (MP_OBJ_IS_TYPE(device, &bleio_local_central_type)) { +// return ((bleio_local_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; + } else { + return 0; + } +} diff --git a/py/runtime.c b/py/runtime.c index 339978dadfe88..fb62edf73b4d6 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1603,6 +1603,14 @@ NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg) { mp_raise_msg(&mp_type_OSError, msg); } +NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_OSError, fmt, argptr); + va_end(argptr); + nlr_raise(exception); +} + NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); } diff --git a/py/runtime.h b/py/runtime.h index 54f6a3270b7b8..ece226e7ab3e9 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -159,6 +159,7 @@ NORETURN void mp_raise_ImportError(const compressed_string_t *msg); NORETURN void mp_raise_IndexError(const compressed_string_t *msg); NORETURN void mp_raise_OSError(int errno_); NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg); +NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...); NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg); NORETURN void mp_raise_recursion_depth(void); diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index d4c24e4e2ce31..9109388445d1c 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -80,7 +80,7 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, enum { ARG_address }; static const mp_arg_t allowed_args[] = { - { ARG_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index 3d6423314f972..4022632ad2248 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -81,7 +81,7 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar enum { ARG_uuid }; static const mp_arg_t allowed_args[] = { - { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -99,13 +99,6 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar return MP_OBJ_FROM_PTR(self); } -STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "Descriptor(uuid="); - bleio_uuid_print(print, self->uuid, kind); - mp_printf(print, ", handle=%04x", common_hal_bleio_descriptor_get_handle(self)); -} - STATIC mp_obj_t bleio_descriptor_get_handle(mp_obj_t self_in) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -161,7 +154,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_local const mp_obj_type_t bleio_descriptor_type = { { &mp_type_type }, .name = MP_QSTR_Descriptor, - .print = bleio_descriptor_print, .make_new = bleio_descriptor_make_new, .locals_dict = (mp_obj_dict_t*)&bleio_descriptor_locals_dict }; diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index 94834ef7c013a..cf5eb687370c5 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -171,7 +171,7 @@ STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, enum { ARG_address, ARG_scan_entry }; static const mp_arg_t allowed_args[] = { - { ARG_address, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_address, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_scan_entry, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, }; diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 129a1d0b73f5b..a0673bb2d0c5e 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -45,23 +45,16 @@ //| To mark the service as secondary, pass `True` as :py:data:`secondary`. //| //| :param bleio.UUID uuid: The uuid of the service +//| :param iterable characteristics: the Characteristic objects for this service //| :param bool secondary: If the service is a secondary one //| -STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_printf(print, "Service("); - bleio_uuid_print(print, self->uuid, kind); - mp_printf(print, ")"); -} - STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 2, 3, true); bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); self->char_list = mp_obj_new_list(0, NULL); self->base.type = &bleio_service_type; - self->device = NULL; + self->device = mp_const_none; self->handle = 0xFFFF; mp_map_t kw_args; @@ -69,7 +62,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, enum { ARG_uuid, ARG_characteristics, ARG_secondary }; static const mp_arg_t allowed_args[] = { - { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_characteristics, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; @@ -98,13 +91,17 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, } bleio_characteristic_obj_t *characteristic_ptr = MP_OBJ_TO_PTR(characteristic); if (common_hal_bleio_uuid_get_uuid128_reference(uuid) != - common_hal_bleio_uuid_get_uuid128_reference(characteristic_ptr->uuid)) { + common_hal_bleio_uuid_get_uuid128_reference(characteristic_ptr->uuid)) { // The descriptor base UUID doesn't match the characteristic base UUID. mp_raise_ValueError(translate("Characteristic UUID doesn't match Service UUID")); } characteristic_ptr->service = self; mp_obj_list_append(self->char_list, characteristic); } + + // Do port-specific initialization. + common_hal_bleio_service_construct(self); + return MP_OBJ_FROM_PTR(self); } @@ -155,7 +152,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict const mp_obj_type_t bleio_service_type = { { &mp_type_type }, .name = MP_QSTR_Service, - .print = bleio_service_print, .make_new = bleio_service_make_new, .locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict }; diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h index 77c7518294ccc..389db3b2e99bc 100644 --- a/shared-bindings/bleio/Service.h +++ b/shared-bindings/bleio/Service.h @@ -32,6 +32,7 @@ const mp_obj_type_t bleio_service_type; -extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic); +extern void common_hal_bleio_service_construct(bleio_service_obj_t *self); +extern void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 46822603f58d7..21242e07cb606 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -31,7 +31,7 @@ #include "shared-bindings/bleio/AdvertisementData.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/LocalPeripheral.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" #include "shared-bindings/bleio/Service.h" @@ -76,7 +76,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, - { MP_ROM_QSTR(MP_QSTR_Device), MP_ROM_PTR(&bleio_device_type) }, + { MP_ROM_QSTR(MP_QSTR_LocalPeripheral), MP_ROM_PTR(&bleio_local_peripheral_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, diff --git a/shared-module/bleio/Service.h b/shared-module/bleio/Service.h index ff506d3f3bd41..540749793a58a 100644 --- a/shared-module/bleio/Service.h +++ b/shared-module/bleio/Service.h @@ -28,14 +28,14 @@ #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H #include "common-hal/bleio/UUID.h" -#include "shared-module/bleio/Device.h" typedef struct { mp_obj_base_t base; uint16_t handle; bool is_secondary; bleio_uuid_obj_t *uuid; - bleio_device_obj_t *device; + // May be a LocalPeripheral, RemotePeripheral, etc. + mp_obj_t *device; mp_obj_t char_list; uint16_t start_handle; uint16_t end_handle; From 55084b30efc5066a2aa43943de3d01e3b0277d06 Mon Sep 17 00:00:00 2001 From: Jerry Needell Date: Thu, 27 Dec 2018 09:38:35 -0500 Subject: [PATCH 033/153] remome FRAMEBUF from nrf builds - use QSPI for particle ARGON --- ports/nrf/boards/particle_argon/mpconfigboard.mk | 2 +- ports/nrf/mpconfigport.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/nrf/boards/particle_argon/mpconfigboard.mk b/ports/nrf/boards/particle_argon/mpconfigboard.mk index 07194882130a5..ee30c2be9099d 100644 --- a/ports/nrf/boards/particle_argon/mpconfigboard.mk +++ b/ports/nrf/boards/particle_argon/mpconfigboard.mk @@ -20,6 +20,6 @@ endif NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 -SPI_FLASH_FILESYSTEM = 1 +QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "MX25L3233F" diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index db384d5102cb3..25710cea27927 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -117,7 +117,7 @@ #define MICROPY_PY_UHEAPQ (0) #define MICROPY_PY_UHASHLIB (1) #define MICROPY_PY_STRUCT (0) -#define MICROPY_PY_FRAMEBUF (1) +#define MICROPY_PY_FRAMEBUF (0) #define MICROPY_KBD_EXCEPTION (1) From d092722ae83f03f0da7a77b525037cf279465112 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 28 Dec 2018 00:39:33 +0700 Subject: [PATCH 034/153] fix #1407 keep receiving in case of error --- ports/nrf/common-hal/busio/UART.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index a291af5788727..c200b6e6f8e4a 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -81,7 +81,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) } // keep receiving - _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, &self->rx_char, 1)); + (void) nrfx_uarte_rx(&self->uarte, &self->rx_char, 1); break; case NRFX_UARTE_EVT_TX_DONE: @@ -89,7 +89,11 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) break; case NRFX_UARTE_EVT_ERROR: - // Handle error + // Possible Error source is Overrun, Parity, Framing, Break + // uint32_t errsrc = event->data.error.error_mask; + + // Keep receiving + (void) nrfx_uarte_rx(&self->uarte, &self->rx_char, 1); break; default: From 3ee766bc013aa3b3bb03606f6a0df03d8cf260e5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 28 Dec 2018 01:05:30 +0700 Subject: [PATCH 035/153] put received bytes to fifo when error --- ports/nrf/common-hal/busio/UART.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index c200b6e6f8e4a..912956369c8d9 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -67,18 +67,24 @@ static void ringbuf_clear(ringbuf_t *r) r->iput = r->iget = 0; } +// will overwrite old data +static void ringbuf_put_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize) +{ + for(uint8_t i=0; i < bufsize; i++) { + if ( ringbuf_put(r, buf[i]) < 0 ) { + // if full overwrite old data + (void) ringbuf_get(r); + ringbuf_put(r, buf[i]); + } + } +} + static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) { busio_uart_obj_t* self = (busio_uart_obj_t*) context; switch ( event->type ) { case NRFX_UARTE_EVT_RX_DONE: - for(uint8_t i=0; i < event->data.rxtx.bytes; i++) { - if ( ringbuf_put(&self->rbuf, event->data.rxtx.p_data[i]) < 0 ) { - // if full overwrite old data - (void) ringbuf_get(&self->rbuf); - ringbuf_put(&self->rbuf, event->data.rxtx.p_data[i]); - } - } + ringbuf_put_n(&self->rbuf, event->data.rxtx.p_data, event->data.rxtx.bytes); // keep receiving (void) nrfx_uarte_rx(&self->uarte, &self->rx_char, 1); @@ -92,6 +98,8 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) // Possible Error source is Overrun, Parity, Framing, Break // uint32_t errsrc = event->data.error.error_mask; + ringbuf_put_n(&self->rbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes); + // Keep receiving (void) nrfx_uarte_rx(&self->uarte, &self->rx_char, 1); break; From a8486c6b7e3a4ef9028e4c7d067339c13cbfd885 Mon Sep 17 00:00:00 2001 From: Kattni Date: Thu, 27 Dec 2018 18:05:07 -0600 Subject: [PATCH 036/153] Adding header logo resized --- logo/CircuitPython_Repo_header_logo.png | Bin 0 -> 103853 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 logo/CircuitPython_Repo_header_logo.png diff --git a/logo/CircuitPython_Repo_header_logo.png b/logo/CircuitPython_Repo_header_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6ce287922ab515c71c97f704b80a6626d64d042a GIT binary patch literal 103853 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 Date: Fri, 28 Dec 2018 16:30:11 +0700 Subject: [PATCH 037/153] fix #1422 correct i2c max xfer len (size in bits) --- ports/nrf/common-hal/busio/I2C.c | 52 +++++++++++++++++--------------- ports/nrf/common-hal/busio/I2C.h | 1 - 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c index 4c42e58cdfe32..f2ba65594986d 100644 --- a/ports/nrf/common-hal/busio/I2C.c +++ b/ports/nrf/common-hal/busio/I2C.c @@ -37,19 +37,21 @@ #include "nrfx_spim.h" #include "nrf_gpio.h" +// all TWI instances have the same max size +// 16 bits for 840, 10 bits for 810, 8 bits for 832 +#define I2C_MAX_XFER_LEN ( 1UL << TWIM0_EASYDMA_MAXCNT_SIZE) + STATIC twim_peripheral_t twim_peripherals[] = { #if NRFX_CHECK(NRFX_TWIM0_ENABLED) // SPIM0 and TWIM0 share an address. { .twim = NRFX_TWIM_INSTANCE(0), - .in_use = false, - .max_xfer_size = TWIM0_EASYDMA_MAXCNT_SIZE, + .in_use = false }, #endif #if NRFX_CHECK(NRFX_TWIM1_ENABLED) // SPIM1 and TWIM1 share an address. { .twim = NRFX_TWIM_INSTANCE(1), - .in_use = false, - .max_xfer_size = TWIM1_EASYDMA_MAXCNT_SIZE, + .in_use = false }, #endif }; @@ -198,24 +200,25 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { } uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { - if(len == 0) + if(len == 0) { return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV; + } - const uint32_t max_xfer_size = self->twim_peripheral->max_xfer_size; - const uint32_t parts = len / max_xfer_size; - const uint32_t remainder = len % max_xfer_size; nrfx_err_t err = NRFX_SUCCESS; nrfx_twim_enable(&self->twim_peripheral->twim); - for (uint32_t i = 0; i < parts; ++i) { - err = nrfx_twim_tx(&self->twim_peripheral->twim, addr, data + i * max_xfer_size, max_xfer_size, !stopBit); - if (err != NRFX_SUCCESS) + // break into MAX_XFER_LEN transaction + while ( len ) { + const size_t xact_len = MIN(len, I2C_MAX_XFER_LEN); + + if ( NRFX_SUCCESS != (err = nrfx_twim_tx(&self->twim_peripheral->twim, addr, data, xact_len, !stopBit)) ) { break; - } + } - if ((remainder > 0) && (err == NRFX_SUCCESS)) - err = nrfx_twim_tx(&self->twim_peripheral->twim, addr, data + parts * max_xfer_size, remainder, !stopBit); + len -= xact_len; + data += xact_len; + } nrfx_twim_disable(&self->twim_peripheral->twim); @@ -223,24 +226,25 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const u } uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - if(len == 0) + if(len == 0) { return 0; + } - const uint32_t max_xfer_size = self->twim_peripheral->max_xfer_size; - const uint32_t parts = len / max_xfer_size; - const uint32_t remainder = len % max_xfer_size; nrfx_err_t err = NRFX_SUCCESS; nrfx_twim_enable(&self->twim_peripheral->twim); - for (uint32_t i = 0; i < parts; ++i) { - err = nrfx_twim_rx(&self->twim_peripheral->twim, addr, data + i * max_xfer_size, max_xfer_size); - if (err != NRFX_SUCCESS) + // break into MAX_XFER_LEN transaction + while ( len ) { + const size_t xact_len = MIN(len, I2C_MAX_XFER_LEN); + + if ( NRFX_SUCCESS != (err = nrfx_twim_rx(&self->twim_peripheral->twim, addr, data, xact_len)) ) { break; - } + } - if ((remainder > 0) && (err == NRFX_SUCCESS)) - err = nrfx_twim_rx(&self->twim_peripheral->twim, addr, data + parts * max_xfer_size, remainder); + len -= xact_len; + data += xact_len; + } nrfx_twim_disable(&self->twim_peripheral->twim); diff --git a/ports/nrf/common-hal/busio/I2C.h b/ports/nrf/common-hal/busio/I2C.h index c8ba84418f00c..b75d15f00fdb2 100644 --- a/ports/nrf/common-hal/busio/I2C.h +++ b/ports/nrf/common-hal/busio/I2C.h @@ -34,7 +34,6 @@ typedef struct { nrfx_twim_t twim; bool in_use; - uint8_t max_xfer_size; } twim_peripheral_t; typedef struct { From 6b0d93cea3e03a4eac6da6349defa580d78b4bf1 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 28 Dec 2018 21:14:27 +0700 Subject: [PATCH 038/153] correct i2c max len --- ports/nrf/common-hal/busio/I2C.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c index f2ba65594986d..05106d49059f5 100644 --- a/ports/nrf/common-hal/busio/I2C.c +++ b/ports/nrf/common-hal/busio/I2C.c @@ -39,7 +39,7 @@ // all TWI instances have the same max size // 16 bits for 840, 10 bits for 810, 8 bits for 832 -#define I2C_MAX_XFER_LEN ( 1UL << TWIM0_EASYDMA_MAXCNT_SIZE) +#define I2C_MAX_XFER_LEN ((1UL << TWIM0_EASYDMA_MAXCNT_SIZE) - 1) STATIC twim_peripheral_t twim_peripherals[] = { #if NRFX_CHECK(NRFX_TWIM0_ENABLED) From 715064abebe8a09bd69341f69a19390edbe06fa6 Mon Sep 17 00:00:00 2001 From: Kattni Date: Fri, 28 Dec 2018 12:43:37 -0600 Subject: [PATCH 039/153] Adding MIT license badge --- logo/license-MIT-brightgreen.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 logo/license-MIT-brightgreen.svg diff --git a/logo/license-MIT-brightgreen.svg b/logo/license-MIT-brightgreen.svg new file mode 100644 index 0000000000000..e28c04bbc5623 --- /dev/null +++ b/logo/license-MIT-brightgreen.svg @@ -0,0 +1 @@ + licenselicenseMITMIT \ No newline at end of file From a48a08d3142da47f891b956044ba2fcc6217a22e Mon Sep 17 00:00:00 2001 From: Kattni Date: Fri, 28 Dec 2018 13:43:14 -0600 Subject: [PATCH 040/153] Added header image and license badge --- README.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 65ad662620b52..13672b689ca14 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,9 @@ Adafruit CircuitPython ====================== -|Build Status| |Doc Status| |Discord| +.. image:: https://github.com/adafruit/circuitpython/blob/master/logo/CircuitPython_Repo_header_logo.png + +|Build Status| |Doc Status| |License| |Discord| `Status <#status>`__ \| `Supported Boards <#supported-boards>`__ \| `Download <#download>`__ \| @@ -270,3 +272,5 @@ project. :target: http://circuitpython.readthedocs.io/ .. |Discord| image:: https://img.shields.io/discord/327254708534116352.svg :target: https://discord.gg/nBQh6qu +.. |License| image:: https://github.com/adafruit/circuitpython/blob/master/logo/license-MIT-brightgreen.svg + :target: https://opensource.org/licenses/MIT From 4d1f0ec07be5e9cacaf0072a0f987871b8505ec4 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 28 Dec 2018 22:55:29 -0500 Subject: [PATCH 041/153] Add Broadcaster. Reset correctly on reload. --- ports/nrf/Makefile | 1 + ports/nrf/bluetooth/ble_drv.c | 7 +- ports/nrf/bluetooth/ble_drv.h | 3 + ports/nrf/common-hal/bleio/Adapter.c | 20 +- ports/nrf/common-hal/bleio/Broadcaster.c | 113 +++++++ ports/nrf/common-hal/bleio/Broadcaster.h | 47 +++ ports/nrf/common-hal/bleio/LocalPeripheral.c | 329 +++++++++++++++++++ ports/nrf/common-hal/bleio/LocalPeripheral.h | 64 ++++ ports/nrf/common-hal/bleio/__init__.c | 7 + ports/nrf/common-hal/bleio/__init__.h | 42 +++ ports/nrf/supervisor/port.c | 3 + shared-bindings/bleio/Broadcaster.c | 140 ++++++++ shared-bindings/bleio/Broadcaster.h | 38 +++ shared-bindings/bleio/LocalPeripheral.c | 250 ++++++++++++++ shared-bindings/bleio/LocalPeripheral.h | 39 +++ shared-bindings/bleio/__init__.c | 2 + shared-module/bleio/__init__.h | 38 +++ 17 files changed, 1125 insertions(+), 18 deletions(-) create mode 100644 ports/nrf/common-hal/bleio/Broadcaster.c create mode 100644 ports/nrf/common-hal/bleio/Broadcaster.h create mode 100644 ports/nrf/common-hal/bleio/LocalPeripheral.c create mode 100644 ports/nrf/common-hal/bleio/LocalPeripheral.h create mode 100644 ports/nrf/common-hal/bleio/__init__.h create mode 100644 shared-bindings/bleio/Broadcaster.c create mode 100644 shared-bindings/bleio/Broadcaster.h create mode 100644 shared-bindings/bleio/LocalPeripheral.c create mode 100644 shared-bindings/bleio/LocalPeripheral.h create mode 100644 shared-module/bleio/__init__.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index c427cdd2659c0..58db910c176cc 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -172,6 +172,7 @@ ifneq ($(SD), ) SRC_COMMON_HAL += \ bleio/__init__.c \ bleio/Adapter.c \ + bleio/Broadcaster.c \ bleio/Characteristic.c \ bleio/Descriptor.c \ bleio/LocalPeripheral.c \ diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c index 0b6daf71167fc..41d51cfb4e30e 100644 --- a/ports/nrf/bluetooth/ble_drv.c +++ b/ports/nrf/bluetooth/ble_drv.c @@ -45,7 +45,12 @@ typedef struct event_handler { ble_drv_evt_handler_t func; } event_handler_t; -static event_handler_t *m_event_handlers; +static event_handler_t *m_event_handlers = NULL; + +void ble_drv_reset() { + // Linked-list members will be gc'd. + m_event_handlers = NULL; +} void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { event_handler_t *handler = m_new_ll(event_handler_t, 1); diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h index 0443b41b84a0d..696aff1da144d 100644 --- a/ports/nrf/bluetooth/ble_drv.h +++ b/ports/nrf/bluetooth/ble_drv.h @@ -43,11 +43,14 @@ #define BLE_CONN_CFG_TAG_CUSTOM 1 #define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) +// 0.625 msecs (625 usecs) +#define ADV_INTERVAL_UNIT_FLOAT_SECS (0.000625) #define UNIT_0_625_MS (625) #define UNIT_10_MS (10000) typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*); +void ble_drv_reset(); void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param); #endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index 318502e955628..cd116711eb184 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -44,17 +44,11 @@ STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { STATIC uint32_t ble_stack_enable(void) { nrf_clock_lf_cfg_t clock_config = { .source = NRF_CLOCK_LF_SRC_XTAL, -#if (BLE_API_VERSION == 4) .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM -#else - .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM -#endif }; -#if (BLUETOOTH_SD == 140) // The SD takes over the POWER IRQ and will fail if the IRQ is already in use nrfx_power_uninit(); -#endif uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler); if (err_code != NRF_SUCCESS) @@ -64,17 +58,10 @@ STATIC uint32_t ble_stack_enable(void) { if (err_code != NRF_SUCCESS) return err_code; - uint32_t app_ram_start; -#if (BLE_API_VERSION == 2) - ble_enable_params_t ble_enable_params = { - .gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, - .gap_enable_params.central_conn_count = 1, - .gap_enable_params.periph_conn_count = 1, - }; + // Start with no event handlers, etc. + ble_drv_reset(); - app_ram_start = 0x200039c0; - err_code = sd_ble_enable(&ble_enable_params, &app_ram_start); -#else + uint32_t app_ram_start; app_ram_start = 0x20004000; ble_cfg_t ble_conf; @@ -100,7 +87,6 @@ STATIC uint32_t ble_stack_enable(void) { return err_code; err_code = sd_ble_enable(&app_ram_start); -#endif return err_code; } diff --git a/ports/nrf/common-hal/bleio/Broadcaster.c b/ports/nrf/common-hal/bleio/Broadcaster.c new file mode 100644 index 0000000000000..508ede1d6da4c --- /dev/null +++ b/ports/nrf/common-hal/bleio/Broadcaster.c @@ -0,0 +1,113 @@ +/* + * 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. + */ + +#include + +#include "ble.h" +#include "ble_drv.h" +#include "ble_hci.h" +#include "nrf_soc.h" +#include "py/runtime.h" + +#include "common-hal/bleio/Broadcaster.h" +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/Broadcaster.h" + +static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; + +STATIC void check_data_fit(size_t pos, size_t data_len) { + if (pos + data_len >= BLE_GAP_ADV_SET_DATA_SIZE_MAX) { + mp_raise_ValueError(translate("Data too large for advertisement packet")); + } +} + +void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_float_t interval) { + common_hal_bleio_adapter_set_enabled(true); // TODO -- Do this somewhere else maybe bleio __init__ + const mp_float_t min = BLE_GAP_ADV_INTERVAL_MIN * ADV_INTERVAL_UNIT_FLOAT_SECS; + const mp_float_t max = BLE_GAP_ADV_INTERVAL_MAX * ADV_INTERVAL_UNIT_FLOAT_SECS; + + if (interval < min || interval > max) { + // Would like to print range using the constants above, but vargs would convert to double. + mp_raise_ValueError(translate("interval not in range 0.0020 to 10.24")); + } + self->interval = interval; +} + + +void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *self, mp_buffer_info_t *data) { + size_t adv_data_pos = 0; + uint32_t err_code; + + // Build up advertising packet. + check_data_fit(adv_data_pos, 1 + 1 + 1); + self->adv_data[adv_data_pos++] = 2; + self->adv_data[adv_data_pos++] = BLE_GAP_AD_TYPE_FLAGS; + self->adv_data[adv_data_pos++] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + + // Data is always send as manufacturer-specific data + check_data_fit(adv_data_pos, 1 + 1 + data->len); + self->adv_data[adv_data_pos++] = 1 + data->len; + self->adv_data[adv_data_pos++] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA; + memcpy(&(self->adv_data[adv_data_pos]), data->buf, data->len); + adv_data_pos += data->len; + + ble_gap_adv_params_t m_adv_params = { + .interval = (uint32_t) (self->interval / ADV_INTERVAL_UNIT_FLOAT_SECS), + .properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED, + .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED, + .filter_policy = BLE_GAP_ADV_FP_ANY, + .primary_phy = BLE_GAP_PHY_1MBPS, + }; + + common_hal_bleio_broadcaster_stop_advertising(self); + + const ble_gap_adv_data_t ble_gap_adv_data = { + .adv_data.p_data = self->adv_data, + .adv_data.len = adv_data_pos, + }; + + err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params); + if (err_code == NRF_SUCCESS) { + err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM); + } + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code); + } +} + +void common_hal_bleio_broadcaster_stop_advertising(bleio_broadcaster_obj_t *self) { + + if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) { + return; + } + + const uint32_t err_code = sd_ble_gap_adv_stop(m_adv_handle); + + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { + mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code); + } +} diff --git a/ports/nrf/common-hal/bleio/Broadcaster.h b/ports/nrf/common-hal/bleio/Broadcaster.h new file mode 100644 index 0000000000000..72f93a4431c06 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Broadcaster.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * 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_COMMON_HAL_BLEIO_BROADCASTER_H +#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_BROADCASTER_H + +#include "ble.h" + +#include "shared-module/bleio/__init__.h" +#include "shared-module/bleio/Address.h" + +typedef struct { + mp_obj_base_t base; + // In seconds. + mp_float_t interval; + // The advertising data buffer is held by us, not by the SD, so we must + // maintain it and not change it. If we need to change its contents during advertising, + // there are tricks to get the SD to notice (see DevZone - TBS). + uint8_t adv_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; + +} bleio_broadcaster_obj_t; + +#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_BROADCASTER_H diff --git a/ports/nrf/common-hal/bleio/LocalPeripheral.c b/ports/nrf/common-hal/bleio/LocalPeripheral.c new file mode 100644 index 0000000000000..2a502c8dd13c6 --- /dev/null +++ b/ports/nrf/common-hal/bleio/LocalPeripheral.c @@ -0,0 +1,329 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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 +#include + +#include "ble.h" +#include "ble_drv.h" +#include "ble_hci.h" +#include "nrf_soc.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/LocalPeripheral.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" + +#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) +#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) +#define BLE_SLAVE_LATENCY 0 +#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) + +#define BLE_ADV_LENGTH_FIELD_SIZE 1 +#define BLE_ADV_AD_TYPE_FIELD_SIZE 1 +#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 + +static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; + +STATIC void check_data_fit(size_t pos, size_t data_len) { + if (pos + data_len >= BLE_GAP_ADV_SET_DATA_SIZE_MAX) { + mp_raise_ValueError(translate("Data too large for advertisement packet")); + } +} + +STATIC uint32_t add_services_to_advertisement(bleio_local_peripheral_obj_t *self, size_t* adv_data_pos_p, size_t uuid_len) { + uint32_t uuids_total_size = 0; + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list); + uint32_t err_code = NRF_SUCCESS; + + check_data_fit(*adv_data_pos_p, 1 + 1); + + // Remember where length byte is; fill in later when we know the size. + const size_t length_pos = *adv_data_pos_p; + (*adv_data_pos_p)++; + + self->adv_data[(*adv_data_pos_p)++] = (uuid_len == 16) + ? BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE + : BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE; + + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + uint8_t encoded_size = 0; + + // Skip services of the wrong length and secondary services. + if (common_hal_bleio_uuid_get_size(service->uuid) != uuid_len || service->is_secondary) { + continue; + } + + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid); + + err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &(self->adv_data[*adv_data_pos_p])); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + check_data_fit(*adv_data_pos_p, encoded_size); + uuids_total_size += encoded_size; + (*adv_data_pos_p) += encoded_size; + } + + self->adv_data[length_pos] = 1 + uuids_total_size; // 1 for the field type. + return err_code; +} + + + +STATIC uint32_t set_advertisement_data(bleio_local_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) { + common_hal_bleio_adapter_set_enabled(true); + + size_t adv_data_pos = 0; + uint32_t err_code; + + GET_STR_DATA_LEN(self->name, name_data, name_len); + if (name_len > 0) { + ble_gap_conn_sec_mode_t sec_mode; + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + // We'll add the name after everything else, shortening it if necessary. + err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len); + if (err_code != NRF_SUCCESS) { + return err_code; + } + } + + if (raw_data->len != 0) { + // User-supplied advertising packet. + check_data_fit(adv_data_pos, raw_data->len); + memcpy(&(self->adv_data[adv_data_pos]), raw_data->buf, raw_data->len); + adv_data_pos += raw_data->len; + } else { + // Build up advertising packet. + check_data_fit(adv_data_pos, 1 + 1 + 1); + self->adv_data[adv_data_pos++] = 2; + self->adv_data[adv_data_pos++] = BLE_GAP_AD_TYPE_FLAGS; + self->adv_data[adv_data_pos++] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + + // The 16-bit ids and 128-bit ids are grouped together by length, so find it whether we have + // 16 and/or 128-bit service UUIDs. + + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list); + if (service_list->len > 0) { + bool has_128bit_services = false; + bool has_16bit_services = false; + + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + + if (service->is_secondary) { + continue; + } + + switch (common_hal_bleio_uuid_get_size(service->uuid)) { + case 16: + has_16bit_services = true; + break; + case 128: + has_128bit_services = true; + break; + } + } + + // Add 16-bit service UUID's in a group, then 128-bit service UUID's. + + if (has_16bit_services) { + err_code = add_services_to_advertisement(self, &adv_data_pos, 16); + if (err_code != NRF_SUCCESS) { + return err_code; + } + } + + if (has_128bit_services) { + err_code = add_services_to_advertisement(self, &adv_data_pos, 128); + if (err_code != NRF_SUCCESS) { + return err_code; + } + } + } + + // Always include TX power. + check_data_fit(adv_data_pos, 1 + 1 + 1); + self->adv_data[adv_data_pos++] = 1 + 1; + self->adv_data[adv_data_pos++] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL; + self->adv_data[adv_data_pos++] = 0; // TODO - allow power level to be set later. + + // We need room for at least a one-character name. + check_data_fit(adv_data_pos, 1 + 1 + 1); + + // How big a name can we fit? + size_t bytes_left = BLE_GAP_ADV_SET_DATA_SIZE_MAX - adv_data_pos - 1 - 1; + size_t partial_name_len = MIN(bytes_left, name_len); + self->adv_data[adv_data_pos++] = 1 + partial_name_len; + self->adv_data[adv_data_pos++] = (partial_name_len == name_len) + ? BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME + : BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME; + memcpy(&(self->adv_data[adv_data_pos]), name_data, partial_name_len); + adv_data_pos += partial_name_len; + } // end of advertising packet construction + + static ble_gap_adv_params_t m_adv_params = { + .interval = MSEC_TO_UNITS(1000, UNIT_0_625_MS), + .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED, + .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED, + .filter_policy = BLE_GAP_ADV_FP_ANY, + .primary_phy = BLE_GAP_PHY_1MBPS, + }; + + if (!connectable) { + m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED; + } + + common_hal_bleio_local_peripheral_stop_advertising(self); + + const ble_gap_adv_data_t ble_gap_adv_data = { + .adv_data.p_data = self->adv_data, + .adv_data.len = adv_data_pos, + }; + + err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM); + + return err_code; +} + +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *self_in) { + bleio_local_peripheral_obj_t *self = (bleio_local_peripheral_obj_t*)self_in; + + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_CONNECTED: { + // Central has connected. + ble_gap_conn_params_t conn_params; + self->conn_handle = ble_evt->evt.gap_evt.conn_handle; + sd_ble_gap_ppcp_get(&conn_params); + sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params); + break; + } + + case BLE_GAP_EVT_DISCONNECTED: + // Central has disconnected. + self->conn_handle = BLE_CONN_HANDLE_INVALID; + 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_ADV_SET_TERMINATED: + // Someday may handle timeouts or limit reached. + break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: { + 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_GATTS_EVT_EXCHANGE_MTU_REQUEST: { + sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT); + break; + } + + } +} + + +void common_hal_bleio_local_peripheral_construct(bleio_local_peripheral_obj_t *self) { + common_hal_bleio_adapter_set_enabled(true); // TODO -- Do this somewhere else maybe bleio __init__ + + self->gatt_role = GATT_ROLE_NONE; + self->conn_handle = BLE_CONN_HANDLE_INVALID; + + // Add all the services. + + mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list); + for (size_t service_idx = 0; service_idx < service_list->len; ++service_idx) { + bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[service_idx]); + + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid); + + uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; + if (service->is_secondary) { + service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; + } + + const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to add service, err 0x%04x"), err_code); + } + + // Once the service has been registered, its characteristics can be added. + common_hal_bleio_service_add_all_characteristics(service); + } +} + + +bool common_hal_bleio_local_peripheral_get_connected(bleio_local_peripheral_obj_t *self) { + return self->conn_handle != BLE_CONN_HANDLE_INVALID; +} + +void common_hal_bleio_local_peripheral_start_advertising(bleio_local_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) { + if (connectable) { + ble_drv_add_event_handler(on_ble_evt, self); + } + + const uint32_t err_code = set_advertisement_data(self, connectable, raw_data); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code); + } +} + +void common_hal_bleio_local_peripheral_stop_advertising(bleio_local_peripheral_obj_t *self) { + + if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) + return; + + const uint32_t err_code = sd_ble_gap_adv_stop(m_adv_handle); + + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { + mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code); + } +} diff --git a/ports/nrf/common-hal/bleio/LocalPeripheral.h b/ports/nrf/common-hal/bleio/LocalPeripheral.h new file mode 100644 index 0000000000000..8d84867aef9bb --- /dev/null +++ b/ports/nrf/common-hal/bleio/LocalPeripheral.h @@ -0,0 +1,64 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * 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_COMMON_HAL_BLEIO_LOCALPERIPHERAL_H +#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_LOCALPERIPHERAL_H + +#include + +#include "ble.h" + +#include "shared-module/bleio/__init__.h" +#include "shared-module/bleio/Address.h" + +// typedef struct { +// mp_obj_base_t base; +// bool is_peripheral; +// mp_obj_t name; +// bleio_address_obj_t address; +// volatile uint16_t conn_handle; +// mp_obj_t service_list; +// mp_obj_t notif_handler; +// mp_obj_t conn_handler; +// } bleio_device_obj_t; + +typedef struct { + mp_obj_base_t base; + mp_obj_t name; + gatt_role_t gatt_role; + volatile uint16_t conn_handle; + mp_obj_t service_list; + mp_obj_t notif_handler; + mp_obj_t conn_handler; + // The advertising data buffer is held by us, not by the SD, so we must + // maintain it and not change it. If we need to change its contents during advertising, + // there are tricks to get the SD to notice (see DevZone - TBS). + uint8_t adv_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; + +} bleio_local_peripheral_obj_t; + +#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_LOCALPERIPHERAL_H diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index f795e889b4bcb..5a8a7ff16c2de 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -30,6 +30,13 @@ #include "shared-bindings/bleio/LocalPeripheral.h" #include "common-hal/bleio/__init__.h" +// Turn off BLE on a reset or reload. +void bleio_reset() { + if (common_hal_bleio_adapter_get_enabled()) { + common_hal_bleio_adapter_set_enabled(false); + } +} + // The singleton bleio.Adapter object, bound to bleio.adapter // It currently only has properties and no state const super_adapter_obj_t common_hal_bleio_adapter_obj = { diff --git a/ports/nrf/common-hal/bleio/__init__.h b/ports/nrf/common-hal/bleio/__init__.h new file mode 100644 index 0000000000000..9e044f37c197d --- /dev/null +++ b/ports/nrf/common-hal/bleio/__init__.h @@ -0,0 +1,42 @@ +/* + * 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_COMMON_HAL_BLEIO_INIT_H +#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_INIT_H + +#include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/Adapter.h" + +#include "shared-module/bleio/__init__.h" + +// We assume variable length data. +// 20 bytes max (23 - 3). +#define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3) + +gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device); +uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); + +#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_INIT_H diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index ece5bae297074..cf0434793cbc1 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -38,6 +38,7 @@ #include "shared-module/gamepad/__init__.h" #include "common-hal/microcontroller/Pin.h" +#include "common-hal/bleio/__init__.h" #include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/pulseio/PWMOut.h" @@ -86,6 +87,8 @@ void reset_port(void) { pulseout_reset(); timers_reset(); + bleio_reset(); + reset_all_pins(); } diff --git a/shared-bindings/bleio/Broadcaster.c b/shared-bindings/bleio/Broadcaster.c new file mode 100644 index 0000000000000..e24d157ecf594 --- /dev/null +++ b/shared-bindings/bleio/Broadcaster.c @@ -0,0 +1,140 @@ +/* + * 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. + */ + +#include "ble_drv.h" +#include "py/runtime.h" + +#include "shared-bindings/bleio/Broadcaster.h" + +//| .. currentmodule:: bleio +//| +//| :class:`Broadcaster` -- A GAP Broadcaster +//| ========================================================= +//| +//| Implement a BLE broadcaster which sends data in advertising packets and does not connect. +//| Used for beacons and other one-way data transmission. +//| +//| Usage:: +//| +//| import bleio +//| import time +//| +//| +//| # Broadcast once a second. +//| broadcaster = bleio.Broadcaster(interval=1) +//| i = 0 +//| data = bytearray(1) +//| # Broadcast a byte of data that's incremented once a minute +//| while True: +//| data[0] = i +//| bytearray +//| broadcaster.start_advertising(data) +//| time.sleep(60) +//| i += 1 +//| +//| .. class:: Broadcaster(interval=1) +//| +//| Create a new Broadcaster object. + +//| :param float interval: how often to broadcast +//| + +STATIC mp_obj_t bleio_broadcaster_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, 1, true); + bleio_broadcaster_obj_t *self = m_new_obj(bleio_broadcaster_obj_t); + self->base.type = &bleio_broadcaster_type; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_interval }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_interval, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + }; + + 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); + + mp_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj); + + // Do port-specific initialization. interval will be validated. + common_hal_bleio_broadcaster_construct(self, interval); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: start_advertising(data) +//| +//| Start advertising the given manufacturer-specific data. +//| +//| :param buf data: Send data bytes in advertising packets, labeled as manufacturer-specific data +//| +STATIC mp_obj_t bleio_broadcaster_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_data }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + + 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); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); + + common_hal_bleio_broadcaster_start_advertising(self, &bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_broadcaster_start_advertising_obj, 0, bleio_broadcaster_start_advertising); + +//| .. method:: stop_advertising() +//| +//| Stop sending advertising packets. +STATIC mp_obj_t bleio_broadcaster_stop_advertising(mp_obj_t self_in) { + bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_broadcaster_stop_advertising(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_broadcaster_stop_advertising_obj, bleio_broadcaster_stop_advertising); + +STATIC const mp_rom_map_elem_t bleio_broadcaster_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_broadcaster_start_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_broadcaster_stop_advertising_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_broadcaster_locals_dict, bleio_broadcaster_locals_dict_table); + +const mp_obj_type_t bleio_broadcaster_type = { + { &mp_type_type }, + .name = MP_QSTR_LocalPeripheral, + .make_new = bleio_broadcaster_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_broadcaster_locals_dict +}; diff --git a/shared-bindings/bleio/Broadcaster.h b/shared-bindings/bleio/Broadcaster.h new file mode 100644 index 0000000000000..8aa125af97e36 --- /dev/null +++ b/shared-bindings/bleio/Broadcaster.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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_SHARED_BINDINGS_BLEIO_BROADCASTER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H + +#include "common-hal/bleio/Broadcaster.h" + +extern const mp_obj_type_t bleio_broadcaster_type; + +extern void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_float_t interval); +extern void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *self, mp_buffer_info_t *data); +extern void common_hal_bleio_broadcaster_stop_advertising(bleio_broadcaster_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H diff --git a/shared-bindings/bleio/LocalPeripheral.c b/shared-bindings/bleio/LocalPeripheral.c new file mode 100644 index 0000000000000..a40e0c0435ce2 --- /dev/null +++ b/shared-bindings/bleio/LocalPeripheral.c @@ -0,0 +1,250 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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 +#include + +#include "ble_drv.h" +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" + +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/AddressType.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/LocalPeripheral.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" +#include "shared-module/bleio/AdvertisementData.h" +#include "shared-module/bleio/ScanEntry.h" + +#include "common-hal/bleio/LocalPeripheral.h" + +// TODO: Add unique MAC address part to name +static const char default_name[] = "CIRCUITPY"; + +//| .. currentmodule:: bleio +//| +//| :class:`LocalPeripheral` -- A BLE peripheral device +//| ========================================================= +//| +//| Implement a BLE peripheral which runs locally. +//| Set up using the supplied services, and then allow advertising to be started and stopped. +//| +//| Usage:: +//| +//| import bleio +//| +//| # Create a Characteristic. +//| chara = bleio.Characteristic(bleio.UUID(0x2919), read=True, notify=True) +//| +//| # Create a Service providing that one Characteristic. +//| serv = bleio.Service(bleio.UUID(0x180f), [chara]) +//| +//| # Create a peripheral and start it up. +//| periph = bleio.LocalPeripheral([service]) +//| periph.start_advertising() +//| +//| while not periph.connected(): +//| # Wait for connection. +//| pass +//| +//| .. class:: LocalPeripheral(services, *, name='CIRCUITPY') +//| +//| Create a new LocalPeripheral object. + +//| :param iterable services: the Service objects representing services available from this peripheral. +//| :param str name: The name used when advertising this peripheral +//| + +STATIC mp_obj_t bleio_local_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, 1, true); + bleio_local_peripheral_obj_t *self = m_new_obj(bleio_local_peripheral_obj_t); + self->base.type = &bleio_local_peripheral_type; + self->service_list = mp_obj_new_list(0, NULL); + self->notif_handler = mp_const_none; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_services, ARG_name }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_name, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + }; + + 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); + + // If services is not an iterable, an exception will be thrown. + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(args[ARG_services].u_obj, &iter_buf); + mp_obj_t service; + + while ((service = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + if (!MP_OBJ_IS_TYPE(service, &bleio_service_type)) { + mp_raise_ValueError(translate("services includes an object that is not a Service")); + } + bleio_service_obj_t *service_ptr = MP_OBJ_TO_PTR(service); + service_ptr->device = MP_OBJ_FROM_PTR(self); + mp_obj_list_append(self->service_list, service); + } + + const mp_obj_t name = args[ARG_name].u_obj; + if (name == mp_const_none) { + self->name = mp_obj_new_str(default_name, strlen(default_name)); + } else if (MP_OBJ_IS_STR(name)) { + self->name = name; + } else { + mp_raise_ValueError(translate("name must be a string")); + } + + // Do port-specific initialization. + common_hal_bleio_local_peripheral_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. attribute:: connected +//| +//| True if connected to a BLE Central device. +//| +STATIC mp_obj_t bleio_local_peripheral_get_connected(mp_obj_t self_in) { + bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // Return list as a tuple so user won't be able to change it. + return mp_obj_new_bool(common_hal_bleio_local_peripheral_get_connected(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_local_peripheral_get_connected_obj, bleio_local_peripheral_get_connected); + +const mp_obj_property_t bleio_local_peripheral_connected_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_local_peripheral_get_connected_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: services +//| +//| A `tuple` of `bleio.Service` that are offered by this peripheral. (read-only) +//| +STATIC mp_obj_t bleio_local_peripheral_get_services(mp_obj_t self_in) { + bleio_local_peripheral_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 *service_list = MP_OBJ_TO_PTR(self->service_list); + return mp_obj_new_tuple(service_list->len, service_list->items); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_local_peripheral_get_services_obj, bleio_local_peripheral_get_services); + +const mp_obj_property_t bleio_local_peripheral_services_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_local_peripheral_get_services_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: name +//| +//| The peripheral's name, included when advertising. (read-only) +//| +STATIC mp_obj_t bleio_local_peripheral_get_name(mp_obj_t self_in) { + bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return self->name; +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_local_peripheral_get_name_obj, bleio_local_peripheral_get_name); + +const mp_obj_property_t bleio_local_peripheral_name_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_local_peripheral_get_name_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. method:: start_advertising(*, connectable=True, data=None) +//| +//| Starts advertising the peripheral. The peripheral's name and +//| services are included in the advertisement packets. +//| +//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral. +//| :param buf data: If not None, then send data bytes in advertising packets. +//| +STATIC mp_obj_t bleio_local_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_connectable, ARG_data }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + 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); + + mp_buffer_info_t bufinfo = { 0 }; + if (args[ARG_data].u_obj != mp_const_none) { + mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); + } + + common_hal_bleio_local_peripheral_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_local_peripheral_start_advertising_obj, 0, bleio_local_peripheral_start_advertising); + +//| .. method:: stop_advertising() +//| +//| Stop sending advertising packets. +STATIC mp_obj_t bleio_local_peripheral_stop_advertising(mp_obj_t self_in) { + bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_local_peripheral_stop_advertising(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_local_peripheral_stop_advertising_obj, bleio_local_peripheral_stop_advertising); + +STATIC const mp_rom_map_elem_t bleio_local_peripheral_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_local_peripheral_start_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_local_peripheral_stop_advertising_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_local_peripheral_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_local_peripheral_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_local_peripheral_services_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_local_peripheral_locals_dict, bleio_local_peripheral_locals_dict_table); + +const mp_obj_type_t bleio_local_peripheral_type = { + { &mp_type_type }, + .name = MP_QSTR_LocalPeripheral, + .make_new = bleio_local_peripheral_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_local_peripheral_locals_dict +}; diff --git a/shared-bindings/bleio/LocalPeripheral.h b/shared-bindings/bleio/LocalPeripheral.h new file mode 100644 index 0000000000000..bd6d5cbbbeeef --- /dev/null +++ b/shared-bindings/bleio/LocalPeripheral.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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_SHARED_BINDINGS_BLEIO_LOCALPERIPHERAL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_LOCALPERIPHERAL_H + +#include "common-hal/bleio/LocalPeripheral.h" + +extern const mp_obj_type_t bleio_local_peripheral_type; + +extern void common_hal_bleio_local_peripheral_construct(bleio_local_peripheral_obj_t *self); +extern bool common_hal_bleio_local_peripheral_get_connected(bleio_local_peripheral_obj_t *self); +extern void common_hal_bleio_local_peripheral_start_advertising(bleio_local_peripheral_obj_t *device, bool connectable, mp_buffer_info_t *raw_data); +extern void common_hal_bleio_local_peripheral_stop_advertising(bleio_local_peripheral_obj_t *device); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_LOCALPERIPHERAL_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 21242e07cb606..7e36eaa469c6d 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -29,6 +29,7 @@ #include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/AddressType.h" #include "shared-bindings/bleio/AdvertisementData.h" +#include "shared-bindings/bleio/Broadcaster.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/LocalPeripheral.h" @@ -74,6 +75,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) }, + { MP_ROM_QSTR(MP_QSTR_Broadcaster), MP_ROM_PTR(&bleio_broadcaster_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, { MP_ROM_QSTR(MP_QSTR_LocalPeripheral), MP_ROM_PTR(&bleio_local_peripheral_type) }, diff --git a/shared-module/bleio/__init__.h b/shared-module/bleio/__init__.h new file mode 100644 index 0000000000000..07d14859469b7 --- /dev/null +++ b/shared-module/bleio/__init__.h @@ -0,0 +1,38 @@ +/* + * 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_SHARED_MODULE_BLEIO_INIT_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H + +typedef enum { + GATT_ROLE_NONE, + GATT_ROLE_SERVER, + GATT_ROLE_CLIENT, +} gatt_role_t; + +extern void bleio_reset(void); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H From de7cadb9b2484348aa52addbae76041236682933 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 29 Dec 2018 00:08:04 -0500 Subject: [PATCH 042/153] fix typos in internal_flash.c --- ports/nrf/supervisor/internal_flash.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/nrf/supervisor/internal_flash.c b/ports/nrf/supervisor/internal_flash.c index ad7a8d0815494..5faae8a4e3a73 100644 --- a/ports/nrf/supervisor/internal_flash.c +++ b/ports/nrf/supervisor/internal_flash.c @@ -74,7 +74,7 @@ uint32_t supervisor_flash_get_block_count(void) { STATIC bool wait_for_flash_operation() { do { sd_app_evt_wait(); - uint32 evt_id; + uint32_t evt_id; uint32_t result = sd_evt_get(&evt_id); if (result == NRF_SUCCESS) { switch (evt_id) { @@ -107,7 +107,7 @@ void supervisor_flash_flush(void) { if (sd_en) { sd_flash_page_erase(_flash_page_addr / FL_PAGE_SZ); wait_for_flash_operation(); // TODO: handle error return. - sd_flash_write(_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t)); + sd_flash_write((uint32_t *)_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t)); wait_for_flash_operation(); } else { #endif @@ -118,6 +118,7 @@ void supervisor_flash_flush(void) { #endif _flash_page_addr = NO_CACHE; + } } mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { From ef39e72c7c3c3e68f73f670b7f8b7f08e813be39 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 29 Dec 2018 13:55:10 -0500 Subject: [PATCH 043/153] free event handlers on reset; fix typo in Broadcaster --- ports/nrf/Makefile | 2 +- ports/nrf/bluetooth/ble_drv.c | 7 ++++++- ports/nrf/common-hal/bleio/Service.c | 2 +- ports/nrf/common-hal/bleio/__init__.c | 23 ----------------------- ports/nrf/common-hal/bleio/__init__.h | 1 - shared-bindings/bleio/Broadcaster.c | 2 +- shared-bindings/bleio/__init__.c | 4 ++-- shared-module/bleio/Service.h | 2 +- shared-module/bleio/__init__.h | 6 ------ 9 files changed, 12 insertions(+), 37 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 58db910c176cc..f7e4a29884f29 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -175,7 +175,7 @@ SRC_COMMON_HAL += \ bleio/Broadcaster.c \ bleio/Characteristic.c \ bleio/Descriptor.c \ - bleio/LocalPeripheral.c \ + bleio/Peripheral.c \ bleio/Scanner.c \ bleio/Service.c \ bleio/UUID.c diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c index 41d51cfb4e30e..57a433f7048f7 100644 --- a/ports/nrf/bluetooth/ble_drv.c +++ b/ports/nrf/bluetooth/ble_drv.c @@ -48,7 +48,12 @@ typedef struct event_handler { static event_handler_t *m_event_handlers = NULL; void ble_drv_reset() { - // Linked-list members will be gc'd. + event_handler_t *handler = m_event_handlers; + while (handler != NULL) { + event_handler_t *next = handler->next; + m_free(handler); + handler = next; + } m_event_handlers = NULL; } diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index e6aab8563cdc1..c913c02aea358 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -34,7 +34,7 @@ void common_hal_bleio_service_construct(bleio_service_obj_t *self) { } -// Call this after the Service has been added to the LocalPeripheral. +// Call this after the Service has been added to the Peripheral. void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) { // Add all the characteristics. const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(self->char_list); diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index 5a8a7ff16c2de..9429aaf4478a8 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -27,7 +27,6 @@ #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/LocalPeripheral.h" #include "common-hal/bleio/__init__.h" // Turn off BLE on a reset or reload. @@ -44,25 +43,3 @@ const super_adapter_obj_t common_hal_bleio_adapter_obj = { .type = &bleio_adapter_type, }, }; - -gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device) { - if (MP_OBJ_IS_TYPE(device, &bleio_local_peripheral_type)) { - return ((bleio_local_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; -// Does not exist yet. -// } else if (MP_OBJ_IS_TYPE(device, &bleio_local_central_type)) { -// return ((bleio_local_central_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; - } else { - return GATT_ROLE_NONE; - } -} - -uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) { - if (MP_OBJ_IS_TYPE(device, &bleio_local_peripheral_type)) { - return ((bleio_local_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; -// Does not exist yet. -// } else if (MP_OBJ_IS_TYPE(device, &bleio_local_central_type)) { -// return ((bleio_local_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; - } else { - return 0; - } -} diff --git a/ports/nrf/common-hal/bleio/__init__.h b/ports/nrf/common-hal/bleio/__init__.h index 9e044f37c197d..aed5df5e766a7 100644 --- a/ports/nrf/common-hal/bleio/__init__.h +++ b/ports/nrf/common-hal/bleio/__init__.h @@ -36,7 +36,6 @@ // 20 bytes max (23 - 3). #define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3) -gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device); uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); #endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_INIT_H diff --git a/shared-bindings/bleio/Broadcaster.c b/shared-bindings/bleio/Broadcaster.c index e24d157ecf594..ae4f28b74ad84 100644 --- a/shared-bindings/bleio/Broadcaster.c +++ b/shared-bindings/bleio/Broadcaster.c @@ -134,7 +134,7 @@ STATIC MP_DEFINE_CONST_DICT(bleio_broadcaster_locals_dict, bleio_broadcaster_loc const mp_obj_type_t bleio_broadcaster_type = { { &mp_type_type }, - .name = MP_QSTR_LocalPeripheral, + .name = MP_QSTR_Broadcaster, .make_new = bleio_broadcaster_make_new, .locals_dict = (mp_obj_dict_t*)&bleio_broadcaster_locals_dict }; diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 7e36eaa469c6d..b3590715959fe 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -32,7 +32,7 @@ #include "shared-bindings/bleio/Broadcaster.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/LocalPeripheral.h" +#include "shared-bindings/bleio/PeripheralServer.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" #include "shared-bindings/bleio/Service.h" @@ -78,7 +78,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Broadcaster), MP_ROM_PTR(&bleio_broadcaster_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, - { MP_ROM_QSTR(MP_QSTR_LocalPeripheral), MP_ROM_PTR(&bleio_local_peripheral_type) }, + { MP_ROM_QSTR(MP_QSTR_PeripheralServer), MP_ROM_PTR(&bleio_peripheral_server_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, diff --git a/shared-module/bleio/Service.h b/shared-module/bleio/Service.h index 540749793a58a..7fee57f1d090c 100644 --- a/shared-module/bleio/Service.h +++ b/shared-module/bleio/Service.h @@ -34,7 +34,7 @@ typedef struct { uint16_t handle; bool is_secondary; bleio_uuid_obj_t *uuid; - // May be a LocalPeripheral, RemotePeripheral, etc. + // May be a PeripheralServer, CentralClient, etc. mp_obj_t *device; mp_obj_t char_list; uint16_t start_handle; diff --git a/shared-module/bleio/__init__.h b/shared-module/bleio/__init__.h index 07d14859469b7..f8f0e06606445 100644 --- a/shared-module/bleio/__init__.h +++ b/shared-module/bleio/__init__.h @@ -27,12 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H -typedef enum { - GATT_ROLE_NONE, - GATT_ROLE_SERVER, - GATT_ROLE_CLIENT, -} gatt_role_t; - extern void bleio_reset(void); #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H From 1dc3957e729a7bf4d6476c587f140e3d42fd1bd5 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 30 Dec 2018 22:31:51 -0500 Subject: [PATCH 044/153] LocalPeripheral is now Peripheral; more work on basic GATTS support; UART not working yet --- ports/nrf/common-hal/bleio/Characteristic.c | 84 +++++++++++++++-- .../bleio/{LocalPeripheral.c => Peripheral.c} | 24 ++--- .../bleio/{LocalPeripheral.h => Peripheral.h} | 19 +--- ports/nrf/common-hal/bleio/__init__.c | 23 +++++ ports/nrf/common-hal/bleio/__init__.h | 1 + py/obj.h | 1 + py/objarray.c | 6 ++ shared-bindings/bleio/Characteristic.c | 4 +- shared-bindings/bleio/Characteristic.h | 4 +- .../bleio/{LocalPeripheral.c => Peripheral.c} | 90 +++++++++---------- .../bleio/{LocalPeripheral.h => Peripheral.h} | 19 ++-- shared-bindings/bleio/__init__.c | 4 +- shared-module/bleio/Service.h | 2 +- shared-module/bleio/__init__.h | 6 ++ 14 files changed, 192 insertions(+), 95 deletions(-) rename ports/nrf/common-hal/bleio/{LocalPeripheral.c => Peripheral.c} (91%) rename ports/nrf/common-hal/bleio/{LocalPeripheral.h => Peripheral.h} (79%) rename shared-bindings/bleio/{LocalPeripheral.c => Peripheral.c} (68%) rename shared-bindings/bleio/{LocalPeripheral.h => Peripheral.h} (62%) diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 17656c26943b1..7a32e4928cd19 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -35,13 +35,63 @@ #include "common-hal/bleio/__init__.h" #include "shared-module/bleio/Characteristic.h" - +// TODO - should these be per object?? ***** STATIC volatile bleio_characteristic_obj_t *m_read_characteristic; STATIC volatile uint8_t m_tx_in_progress; STATIC nrf_mutex_t *m_write_mutex; +STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) { + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); + uint16_t cccd; + ble_gatts_value_t value = { + .p_value = (uint8_t*) &cccd, + .len = 2, + }; + + const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, characteristic->cccd_handle, &value); + + + if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) { + // CCCD is not set, so say that neither Notify nor Indicate is enabled. + cccd = 0; + } else if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to read CCD value, err 0x%04x"), err_code); + } + + return cccd; +} + +STATIC void gatts_read(bleio_characteristic_obj_t *characteristic) { + // This might be BLE_CONN_HANDLE_INVALID if we're not conected, but that's OK, because + // we can still read and write the local value. + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); + + mp_buffer_info_t bufinfo; + ble_gatts_value_t gatts_value = { + .p_value = NULL, + .len = 0, + }; + + // Read once to find out what size buffer we need, then read again to fill buffer. + + uint32_t err_code = sd_ble_gatts_value_get(conn_handle, characteristic->handle, &gatts_value); + if (err_code == NRF_SUCCESS) { + characteristic->value_data = mp_obj_new_bytearray_of_zeros(gatts_value.len); + mp_get_buffer_raise(characteristic->value_data, &bufinfo, MP_BUFFER_WRITE); + + // Read again, with the correct size of buffer. + err_code = sd_ble_gatts_value_get(conn_handle, characteristic->handle, &gatts_value); + } + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code); + } +} + STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + // This might be BLE_CONN_HANDLE_INVALID if we're not conected, but that's OK, because + // we can still read and write the local value. const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); ble_gatts_value_t gatts_value = { @@ -55,12 +105,12 @@ STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in } } -STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { +STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo, uint16_t hvx_type) { uint16_t hvx_len = bufinfo->len; ble_gatts_hvx_params_t hvx_params = { .handle = characteristic->handle, - .type = BLE_GATT_HVX_NOTIFICATION, + .type = hvx_type, .offset = 0, .p_len = &hvx_len, .p_data = bufinfo->buf, @@ -163,30 +213,46 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self) ble_drv_add_event_handler(on_ble_evt, NULL); } -void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) { +void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) { switch (common_hal_bleio_device_get_gatt_role(self->service->device)) { case GATT_ROLE_CLIENT: gattc_read(self); break; + case GATT_ROLE_SERVER: + gatts_read(self); + break; + default: mp_raise_RuntimeError(translate("bad GATT role")); break; } } -void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { +void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { + bool sent = false; + uint16_t cccd = 0; + switch (common_hal_bleio_device_get_gatt_role(self->service->device)) { case GATT_ROLE_SERVER: - if (self->props.notify) { - gatts_notify(self, bufinfo); - } else { + if (self->props.notify || self->props.indicate) { + cccd = get_cccd(self); + } + // It's possible that both notify and indicate are set. + if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { + gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION); + sent = true; + } + if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) { + gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION); + sent = true; + } + if (!sent) { gatts_write(self, bufinfo); } break; case GATT_ROLE_CLIENT: - // TODO: Add indications gattc_write(self, bufinfo); break; diff --git a/ports/nrf/common-hal/bleio/LocalPeripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c similarity index 91% rename from ports/nrf/common-hal/bleio/LocalPeripheral.c rename to ports/nrf/common-hal/bleio/Peripheral.c index 2a502c8dd13c6..d2eef596d47f5 100644 --- a/ports/nrf/common-hal/bleio/LocalPeripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2018 Artur Pacholec + * 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 @@ -35,7 +36,7 @@ #include "py/runtime.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/LocalPeripheral.h" +#include "shared-bindings/bleio/Peripheral.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" @@ -56,7 +57,7 @@ STATIC void check_data_fit(size_t pos, size_t data_len) { } } -STATIC uint32_t add_services_to_advertisement(bleio_local_peripheral_obj_t *self, size_t* adv_data_pos_p, size_t uuid_len) { +STATIC uint32_t add_services_to_advertisement(bleio_peripheral_obj_t *self, size_t* adv_data_pos_p, size_t uuid_len) { uint32_t uuids_total_size = 0; const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list); uint32_t err_code = NRF_SUCCESS; @@ -99,7 +100,7 @@ STATIC uint32_t add_services_to_advertisement(bleio_local_peripheral_obj_t *self -STATIC uint32_t set_advertisement_data(bleio_local_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) { +STATIC uint32_t set_advertisement_data(bleio_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) { common_hal_bleio_adapter_set_enabled(true); size_t adv_data_pos = 0; @@ -203,7 +204,7 @@ STATIC uint32_t set_advertisement_data(bleio_local_peripheral_obj_t *self, bool m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED; } - common_hal_bleio_local_peripheral_stop_advertising(self); + common_hal_bleio_peripheral_stop_advertising(self); const ble_gap_adv_data_t ble_gap_adv_data = { .adv_data.p_data = self->adv_data, @@ -221,7 +222,7 @@ STATIC uint32_t set_advertisement_data(bleio_local_peripheral_obj_t *self, bool } STATIC void on_ble_evt(ble_evt_t *ble_evt, void *self_in) { - bleio_local_peripheral_obj_t *self = (bleio_local_peripheral_obj_t*)self_in; + bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in; switch (ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: { @@ -266,14 +267,17 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *self_in) { break; } + default: + mp_printf(&mp_plat_print, "Unhandled event: 0x%04x\n", ble_evt->header.evt_id); + break; } } -void common_hal_bleio_local_peripheral_construct(bleio_local_peripheral_obj_t *self) { +void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self) { common_hal_bleio_adapter_set_enabled(true); // TODO -- Do this somewhere else maybe bleio __init__ - self->gatt_role = GATT_ROLE_NONE; + self->gatt_role = GATT_ROLE_SERVER; self->conn_handle = BLE_CONN_HANDLE_INVALID; // Add all the services. @@ -301,11 +305,11 @@ void common_hal_bleio_local_peripheral_construct(bleio_local_peripheral_obj_t *s } -bool common_hal_bleio_local_peripheral_get_connected(bleio_local_peripheral_obj_t *self) { +bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) { return self->conn_handle != BLE_CONN_HANDLE_INVALID; } -void common_hal_bleio_local_peripheral_start_advertising(bleio_local_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) { +void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) { if (connectable) { ble_drv_add_event_handler(on_ble_evt, self); } @@ -316,7 +320,7 @@ void common_hal_bleio_local_peripheral_start_advertising(bleio_local_peripheral_ } } -void common_hal_bleio_local_peripheral_stop_advertising(bleio_local_peripheral_obj_t *self) { +void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self) { if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) return; diff --git a/ports/nrf/common-hal/bleio/LocalPeripheral.h b/ports/nrf/common-hal/bleio/Peripheral.h similarity index 79% rename from ports/nrf/common-hal/bleio/LocalPeripheral.h rename to ports/nrf/common-hal/bleio/Peripheral.h index 8d84867aef9bb..b255fe9f408a0 100644 --- a/ports/nrf/common-hal/bleio/LocalPeripheral.h +++ b/ports/nrf/common-hal/bleio/Peripheral.h @@ -25,8 +25,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_COMMON_HAL_BLEIO_LOCALPERIPHERAL_H -#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_LOCALPERIPHERAL_H +#ifndef MICROPY_INCLUDED_COMMON_HAL_BLEIO_PERIPHERAL_H +#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_PERIPHERAL_H #include @@ -35,17 +35,6 @@ #include "shared-module/bleio/__init__.h" #include "shared-module/bleio/Address.h" -// typedef struct { -// mp_obj_base_t base; -// bool is_peripheral; -// mp_obj_t name; -// bleio_address_obj_t address; -// volatile uint16_t conn_handle; -// mp_obj_t service_list; -// mp_obj_t notif_handler; -// mp_obj_t conn_handler; -// } bleio_device_obj_t; - typedef struct { mp_obj_base_t base; mp_obj_t name; @@ -59,6 +48,6 @@ typedef struct { // there are tricks to get the SD to notice (see DevZone - TBS). uint8_t adv_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; -} bleio_local_peripheral_obj_t; +} bleio_peripheral_obj_t; -#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_LOCALPERIPHERAL_H +#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_PERIPHERAL_H diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c index 9429aaf4478a8..cfb701019da5b 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/bleio/__init__.c @@ -27,6 +27,7 @@ #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/Peripheral.h" #include "common-hal/bleio/__init__.h" // Turn off BLE on a reset or reload. @@ -43,3 +44,25 @@ const super_adapter_obj_t common_hal_bleio_adapter_obj = { .type = &bleio_adapter_type, }, }; + +gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device) { + if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { + return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; +// Does not exist yet. +// } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { +// return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; + } else { + return GATT_ROLE_NONE; + } +} + +uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) { + if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { + return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; +// Does not exist yet. +// } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { +// return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; + } else { + return 0; + } +} diff --git a/ports/nrf/common-hal/bleio/__init__.h b/ports/nrf/common-hal/bleio/__init__.h index aed5df5e766a7..9e044f37c197d 100644 --- a/ports/nrf/common-hal/bleio/__init__.h +++ b/ports/nrf/common-hal/bleio/__init__.h @@ -36,6 +36,7 @@ // 20 bytes max (23 - 3). #define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3) +gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device); uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); #endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_INIT_H diff --git a/py/obj.h b/py/obj.h index 8b67728730920..ece3b0ee0dd1f 100644 --- a/py/obj.h +++ b/py/obj.h @@ -640,6 +640,7 @@ mp_obj_t mp_obj_new_str_via_qstr(const char* data, size_t len); mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr); mp_obj_t mp_obj_new_bytes(const byte* data, size_t len); mp_obj_t mp_obj_new_bytearray(size_t n, void *items); +mp_obj_t mp_obj_new_bytearray_of_zeros(size_t n); mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items); #if MICROPY_PY_BUILTINS_FLOAT mp_obj_t mp_obj_new_int_from_float(mp_float_t val); diff --git a/py/objarray.c b/py/objarray.c index 69ff6f328f3fd..0c8c7d855620e 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -611,6 +611,12 @@ mp_obj_t mp_obj_new_bytearray(size_t n, void *items) { return MP_OBJ_FROM_PTR(o); } +mp_obj_t mp_obj_new_bytearray_of_zeros(size_t n) { + mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, n); + memset(o->items, 0, n); + return MP_OBJ_FROM_PTR(o); +} + // Create bytearray which references specified memory area mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items) { mp_obj_array_t *o = m_new_obj(mp_obj_array_t); diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 4fb71de4704a3..d6ae4dfe45f39 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -233,7 +233,7 @@ const mp_obj_property_t bleio_characteristic_uuid_obj = { STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_bleio_characteristic_read_value(self); + common_hal_bleio_characteristic_get_value(self); return self->value_data; } @@ -245,7 +245,7 @@ STATIC mp_obj_t bleio_characteristic_set_value(mp_obj_t self_in, mp_obj_t value_ mp_buffer_info_t bufinfo; mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ); - common_hal_bleio_characteristic_write_value(self, &bufinfo); + common_hal_bleio_characteristic_set_value(self, &bufinfo); return mp_const_none; } diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h index 0e99e97ccd8bb..aec60ebbcabad 100644 --- a/shared-bindings/bleio/Characteristic.h +++ b/shared-bindings/bleio/Characteristic.h @@ -32,7 +32,7 @@ extern const mp_obj_type_t bleio_characteristic_type; extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self); -extern void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self); -extern void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); +extern void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self); +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/LocalPeripheral.c b/shared-bindings/bleio/Peripheral.c similarity index 68% rename from shared-bindings/bleio/LocalPeripheral.c rename to shared-bindings/bleio/Peripheral.c index a40e0c0435ce2..1027bbb1ffc20 100644 --- a/shared-bindings/bleio/LocalPeripheral.c +++ b/shared-bindings/bleio/Peripheral.c @@ -37,20 +37,20 @@ #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/AddressType.h" #include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/LocalPeripheral.h" +#include "shared-bindings/bleio/Peripheral.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" #include "shared-module/bleio/AdvertisementData.h" #include "shared-module/bleio/ScanEntry.h" -#include "common-hal/bleio/LocalPeripheral.h" +#include "common-hal/bleio/Peripheral.h" // TODO: Add unique MAC address part to name static const char default_name[] = "CIRCUITPY"; //| .. currentmodule:: bleio //| -//| :class:`LocalPeripheral` -- A BLE peripheral device +//| :class:`Peripheral` -- A BLE peripheral device //| ========================================================= //| //| Implement a BLE peripheral which runs locally. @@ -67,25 +67,25 @@ static const char default_name[] = "CIRCUITPY"; //| serv = bleio.Service(bleio.UUID(0x180f), [chara]) //| //| # Create a peripheral and start it up. -//| periph = bleio.LocalPeripheral([service]) +//| periph = bleio.Peripheral([service]) //| periph.start_advertising() //| //| while not periph.connected(): //| # Wait for connection. //| pass //| -//| .. class:: LocalPeripheral(services, *, name='CIRCUITPY') +//| .. class:: Peripheral(services, *, name='CIRCUITPY') //| -//| Create a new LocalPeripheral object. +//| Create a new Peripheral object. //| :param iterable services: the Service objects representing services available from this peripheral. //| :param str name: The name used when advertising this peripheral //| -STATIC mp_obj_t bleio_local_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { +STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 0, 1, true); - bleio_local_peripheral_obj_t *self = m_new_obj(bleio_local_peripheral_obj_t); - self->base.type = &bleio_local_peripheral_type; + bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t); + self->base.type = &bleio_peripheral_type; self->service_list = mp_obj_new_list(0, NULL); self->notif_handler = mp_const_none; @@ -125,7 +125,7 @@ STATIC mp_obj_t bleio_local_peripheral_make_new(const mp_obj_type_t *type, size_ } // Do port-specific initialization. - common_hal_bleio_local_peripheral_construct(self); + common_hal_bleio_peripheral_construct(self); return MP_OBJ_FROM_PTR(self); } @@ -134,17 +134,17 @@ STATIC mp_obj_t bleio_local_peripheral_make_new(const mp_obj_type_t *type, size_ //| //| True if connected to a BLE Central device. //| -STATIC mp_obj_t bleio_local_peripheral_get_connected(mp_obj_t self_in) { - bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t bleio_peripheral_get_connected(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); // Return list as a tuple so user won't be able to change it. - return mp_obj_new_bool(common_hal_bleio_local_peripheral_get_connected(self)); + return mp_obj_new_bool(common_hal_bleio_peripheral_get_connected(self)); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_local_peripheral_get_connected_obj, bleio_local_peripheral_get_connected); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_connected_obj, bleio_peripheral_get_connected); -const mp_obj_property_t bleio_local_peripheral_connected_obj = { +const mp_obj_property_t bleio_peripheral_connected_obj = { .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_local_peripheral_get_connected_obj, + .proxy = { (mp_obj_t)&bleio_peripheral_get_connected_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; @@ -153,17 +153,17 @@ const mp_obj_property_t bleio_local_peripheral_connected_obj = { //| //| A `tuple` of `bleio.Service` that are offered by this peripheral. (read-only) //| -STATIC mp_obj_t bleio_local_peripheral_get_services(mp_obj_t self_in) { - bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t bleio_peripheral_get_services(mp_obj_t self_in) { + bleio_peripheral_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 *service_list = MP_OBJ_TO_PTR(self->service_list); return mp_obj_new_tuple(service_list->len, service_list->items); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_local_peripheral_get_services_obj, bleio_local_peripheral_get_services); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_services_obj, bleio_peripheral_get_services); -const mp_obj_property_t bleio_local_peripheral_services_obj = { +const mp_obj_property_t bleio_peripheral_services_obj = { .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_local_peripheral_get_services_obj, + .proxy = { (mp_obj_t)&bleio_peripheral_get_services_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; @@ -172,16 +172,16 @@ const mp_obj_property_t bleio_local_peripheral_services_obj = { //| //| The peripheral's name, included when advertising. (read-only) //| -STATIC mp_obj_t bleio_local_peripheral_get_name(mp_obj_t self_in) { - bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t bleio_peripheral_get_name(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); return self->name; } -MP_DEFINE_CONST_FUN_OBJ_1(bleio_local_peripheral_get_name_obj, bleio_local_peripheral_get_name); +MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_name_obj, bleio_peripheral_get_name); -const mp_obj_property_t bleio_local_peripheral_name_obj = { +const mp_obj_property_t bleio_peripheral_name_obj = { .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_local_peripheral_get_name_obj, + .proxy = { (mp_obj_t)&bleio_peripheral_get_name_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; @@ -194,8 +194,8 @@ const mp_obj_property_t bleio_local_peripheral_name_obj = { //| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral. //| :param buf data: If not None, then send data bytes in advertising packets. //| -STATIC mp_obj_t bleio_local_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); +STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); enum { ARG_connectable, ARG_data }; static const mp_arg_t allowed_args[] = { @@ -211,40 +211,40 @@ STATIC mp_obj_t bleio_local_peripheral_start_advertising(mp_uint_t n_args, const mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); } - common_hal_bleio_local_peripheral_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo); + common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_local_peripheral_start_advertising_obj, 0, bleio_local_peripheral_start_advertising); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_start_advertising_obj, 0, bleio_peripheral_start_advertising); //| .. method:: stop_advertising() //| //| Stop sending advertising packets. -STATIC mp_obj_t bleio_local_peripheral_stop_advertising(mp_obj_t self_in) { - bleio_local_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t bleio_peripheral_stop_advertising(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_bleio_local_peripheral_stop_advertising(self); + common_hal_bleio_peripheral_stop_advertising(self); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_local_peripheral_stop_advertising_obj, bleio_local_peripheral_stop_advertising); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_stop_advertising_obj, bleio_peripheral_stop_advertising); -STATIC const mp_rom_map_elem_t bleio_local_peripheral_locals_dict_table[] = { +STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = { // Methods - { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_local_peripheral_start_advertising_obj) }, - { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_local_peripheral_stop_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) }, // Properties - { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_local_peripheral_connected_obj) }, - { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_local_peripheral_name_obj) }, - { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_local_peripheral_services_obj) }, + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) }, }; -STATIC MP_DEFINE_CONST_DICT(bleio_local_peripheral_locals_dict, bleio_local_peripheral_locals_dict_table); +STATIC MP_DEFINE_CONST_DICT(bleio_peripheral_locals_dict, bleio_peripheral_locals_dict_table); -const mp_obj_type_t bleio_local_peripheral_type = { +const mp_obj_type_t bleio_peripheral_type = { { &mp_type_type }, - .name = MP_QSTR_LocalPeripheral, - .make_new = bleio_local_peripheral_make_new, - .locals_dict = (mp_obj_dict_t*)&bleio_local_peripheral_locals_dict + .name = MP_QSTR_Peripheral, + .make_new = bleio_peripheral_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_peripheral_locals_dict }; diff --git a/shared-bindings/bleio/LocalPeripheral.h b/shared-bindings/bleio/Peripheral.h similarity index 62% rename from shared-bindings/bleio/LocalPeripheral.h rename to shared-bindings/bleio/Peripheral.h index bd6d5cbbbeeef..02a5c1ef8e628 100644 --- a/shared-bindings/bleio/LocalPeripheral.h +++ b/shared-bindings/bleio/Peripheral.h @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2018 Artur Pacholec + * 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 @@ -24,16 +25,16 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_LOCALPERIPHERAL_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_LOCALPERIPHERAL_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H -#include "common-hal/bleio/LocalPeripheral.h" +#include "common-hal/bleio/Peripheral.h" -extern const mp_obj_type_t bleio_local_peripheral_type; +extern const mp_obj_type_t bleio_peripheral_type; -extern void common_hal_bleio_local_peripheral_construct(bleio_local_peripheral_obj_t *self); -extern bool common_hal_bleio_local_peripheral_get_connected(bleio_local_peripheral_obj_t *self); -extern void common_hal_bleio_local_peripheral_start_advertising(bleio_local_peripheral_obj_t *device, bool connectable, mp_buffer_info_t *raw_data); -extern void common_hal_bleio_local_peripheral_stop_advertising(bleio_local_peripheral_obj_t *device); +extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self); +extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self); +extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, mp_buffer_info_t *raw_data); +extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_LOCALPERIPHERAL_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index b3590715959fe..d30d599421db4 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -32,7 +32,7 @@ #include "shared-bindings/bleio/Broadcaster.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/PeripheralServer.h" +#include "shared-bindings/bleio/Peripheral.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" #include "shared-bindings/bleio/Service.h" @@ -78,7 +78,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Broadcaster), MP_ROM_PTR(&bleio_broadcaster_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, - { MP_ROM_QSTR(MP_QSTR_PeripheralServer), MP_ROM_PTR(&bleio_peripheral_server_type) }, + { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, diff --git a/shared-module/bleio/Service.h b/shared-module/bleio/Service.h index 7fee57f1d090c..828d4cdc8743a 100644 --- a/shared-module/bleio/Service.h +++ b/shared-module/bleio/Service.h @@ -34,7 +34,7 @@ typedef struct { uint16_t handle; bool is_secondary; bleio_uuid_obj_t *uuid; - // May be a PeripheralServer, CentralClient, etc. + // May be a Peripheral, Central, etc. mp_obj_t *device; mp_obj_t char_list; uint16_t start_handle; diff --git a/shared-module/bleio/__init__.h b/shared-module/bleio/__init__.h index f8f0e06606445..07d14859469b7 100644 --- a/shared-module/bleio/__init__.h +++ b/shared-module/bleio/__init__.h @@ -27,6 +27,12 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H +typedef enum { + GATT_ROLE_NONE, + GATT_ROLE_SERVER, + GATT_ROLE_CLIENT, +} gatt_role_t; + extern void bleio_reset(void); #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H From b6b5ed9c893f1d0ecdad03e18596a5bc33a08883 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 30 Dec 2018 22:49:20 -0500 Subject: [PATCH 045/153] Remove nRF52832 support --- .travis.yml | 2 +- ports/nrf/README.md | 10 +- ports/nrf/bluetooth/bluetooth_common.mk | 10 +- .../s132_nrf52_5.0.0_API-update.diff | 1550 --- .../s132_nrf52_5.0.0_API/doc/ble_api.dox | 3685 ------- .../s132_nrf52_5.0.0_API/include/ble.h | 620 -- .../s132_nrf52_5.0.0_API/include/ble_err.h | 91 - .../s132_nrf52_5.0.0_API/include/ble_gap.h | 2170 ----- .../s132_nrf52_5.0.0_API/include/ble_gatt.h | 223 - .../s132_nrf52_5.0.0_API/include/ble_gattc.h | 702 -- .../s132_nrf52_5.0.0_API/include/ble_gatts.h | 835 -- .../s132_nrf52_5.0.0_API/include/ble_hci.h | 135 - .../s132_nrf52_5.0.0_API/include/ble_l2cap.h | 504 - .../s132_nrf52_5.0.0_API/include/ble_ranges.h | 156 - .../s132_nrf52_5.0.0_API/include/ble_types.h | 215 - .../include/nrf52/nrf_mbr.h | 228 - .../s132_nrf52_5.0.0_API/include/nrf_error.h | 90 - .../include/nrf_error_sdm.h | 70 - .../include/nrf_error_soc.h | 85 - .../s132_nrf52_5.0.0_API/include/nrf_nvic.h | 485 - .../s132_nrf52_5.0.0_API/include/nrf_sdm.h | 355 - .../s132_nrf52_5.0.0_API/include/nrf_soc.h | 931 -- .../s132_nrf52_5.0.0_API/include/nrf_svc.h | 90 - .../s132_nrf52_5.0.0_license-agreement.txt | 35 - .../s132_nrf52_5.0.0_migration-document.pdf | Bin 99118 -> 0 bytes .../s132_nrf52_5.0.0_release-notes.pdf | Bin 35595 -> 0 bytes .../s132_nrf52_5.0.0_softdevice.hex | 8678 ----------------- ports/nrf/boards/feather_nrf52832/README.md | 192 - ports/nrf/boards/feather_nrf52832/board.c | 42 - .../custom_nrf52832_dfu_app_2.0.1.ld | 44 - .../custom_nrf52832_dfu_app_5.0.0.ld | 44 - .../feather_nrf52832/examples/ble_scan.py | 26 - .../feather_nrf52832/examples/blinky.py | 12 - .../feather_nrf52832/examples/i2c_scan.py | 20 - .../feather_nrf52832/examples/pulseio.py | 25 - .../boards/feather_nrf52832/mpconfigboard.h | 47 - .../boards/feather_nrf52832/mpconfigboard.mk | 13 - ports/nrf/boards/feather_nrf52832/pins.c | 47 - ports/nrf/boards/nrf52832_512k_64k.ld | 28 - .../boards/nrf52832_512k_64k_s132_2.0.1.ld | 28 - .../boards/nrf52832_512k_64k_s132_5.0.0.ld | 28 - ports/nrf/boards/pca10040/board.c | 43 - ports/nrf/boards/pca10040/mpconfigboard.h | 39 - ports/nrf/boards/pca10040/mpconfigboard.mk | 15 - ports/nrf/boards/pca10040/pins.c | 44 - ports/nrf/common-hal/board/__init__.c | 3 - .../nrf/common-hal/neopixel_write/__init__.c | 2 +- ports/nrf/peripherals/nrf/nrf52832/pins.c | 65 - ports/nrf/peripherals/nrf/nrf52832/pins.h | 63 - ports/nrf/peripherals/nrf/nrf52832/power.c | 30 - ports/nrf/peripherals/nrf/pins.h | 6 +- shared-bindings/busio/SPI.c | 4 +- shared-bindings/supervisor/Runtime.c | 3 - tools/build_board_info.py | 4 - 54 files changed, 8 insertions(+), 22864 deletions(-) delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API-update.diff delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/doc/ble_api.dox delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_err.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gap.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gatt.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gattc.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gatts.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_hci.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_l2cap.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_ranges.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_types.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf52/nrf_mbr.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error_sdm.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error_soc.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_nvic.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_sdm.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_soc.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_svc.h delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_license-agreement.txt delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_migration-document.pdf delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_release-notes.pdf delete mode 100644 ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_softdevice.hex delete mode 100644 ports/nrf/boards/feather_nrf52832/README.md delete mode 100644 ports/nrf/boards/feather_nrf52832/board.c delete mode 100644 ports/nrf/boards/feather_nrf52832/custom_nrf52832_dfu_app_2.0.1.ld delete mode 100644 ports/nrf/boards/feather_nrf52832/custom_nrf52832_dfu_app_5.0.0.ld delete mode 100644 ports/nrf/boards/feather_nrf52832/examples/ble_scan.py delete mode 100644 ports/nrf/boards/feather_nrf52832/examples/blinky.py delete mode 100644 ports/nrf/boards/feather_nrf52832/examples/i2c_scan.py delete mode 100644 ports/nrf/boards/feather_nrf52832/examples/pulseio.py delete mode 100644 ports/nrf/boards/feather_nrf52832/mpconfigboard.h delete mode 100644 ports/nrf/boards/feather_nrf52832/mpconfigboard.mk delete mode 100644 ports/nrf/boards/feather_nrf52832/pins.c delete mode 100644 ports/nrf/boards/nrf52832_512k_64k.ld delete mode 100644 ports/nrf/boards/nrf52832_512k_64k_s132_2.0.1.ld delete mode 100644 ports/nrf/boards/nrf52832_512k_64k_s132_5.0.0.ld delete mode 100644 ports/nrf/boards/pca10040/board.c delete mode 100644 ports/nrf/boards/pca10040/mpconfigboard.h delete mode 100644 ports/nrf/boards/pca10040/mpconfigboard.mk delete mode 100644 ports/nrf/boards/pca10040/pins.c delete mode 100644 ports/nrf/peripherals/nrf/nrf52832/pins.c delete mode 100644 ports/nrf/peripherals/nrf/nrf52832/pins.h delete mode 100644 ports/nrf/peripherals/nrf/nrf52832/power.c diff --git a/.travis.yml b/.travis.yml index 2eab28a0b8c93..60313b338bb90 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ git: # that SDK is shortest and add it there. In the case of major re-organizations, # just try to make the builds "about equal in run time" env: - - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf:esp8266 + - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf:esp8266 - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm diff --git a/ports/nrf/README.md b/ports/nrf/README.md index 34e58cb78eb9e..c385459c3fc10 100644 --- a/ports/nrf/README.md +++ b/ports/nrf/README.md @@ -22,9 +22,6 @@ This is a port of CircuitPython to the Nordic Semiconductor nRF52 series of chip ## Tested Hardware -* nRF52832 - * [PCA10040](http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52%2Fdita%2Fnrf52%2Fdevelopment%2Fnrf52_dev_kit.html) - * [Adafruit Feather nRF52](https://www.adafruit.com/product/3406) * nRF52840 * [PCA10056](http://www.nordicsemi.com/eng/Products/nRF52840-Preview-DK) @@ -36,7 +33,6 @@ the following links: > **NOTE**: These board specific readmes may be more up to date than the generic board-neutral documentation further down. -* Adafruit [Feather nRF52](boards/feather_nrf52832/README.md): 512KB Flash, 64KB SRAM * Adafruit [Feather nRF52840](boards/feather_nrf52840_express/README.md): 1MB Flash, 256KB SRAM * Nordic PCA10056 see [Feather nRF52840](boards/pca10056/README.md) * MakerDiary NRF52840 MDK see [its README](boards/makerdiary_nrf52840_mdk/README.md) @@ -77,9 +73,7 @@ Note: further tuning of features to include in bluetooth or even setting up the Target Board (BOARD) | Bluetooth Stack (SD) | Bluetooth Support | Flash Util -------------------------|-------------------------|------------------------|------------------------------- -pca10040 | s132 | Peripheral and Scanner | [Segger](#segger-targets) pca10056 | s140 | Peripheral and Scanner | [Segger](#segger-targets) -feather_nrf52832 | s132 | Peripheral and Scanner | [UART DFU](#dfu-targets) feather_nrf52840_express | s140 | Peripheral and Scanner | UF2 bootloader makerdiary_nrf52840_mdk | s140 | Peripheral and Scanner | pyocd or ARM mbed DAPLink @@ -111,8 +105,8 @@ run follow command to install [adafruit-nrfutil](https://github.com/adafruit/Ada Example on how to generate and flash feather_nrf52832 target: - make BOARD=feather_nrf52832 SD=s132 - make BOARD=feather_nrf52832 SD=s132 dfu-gen dfu-flash + make BOARD=feather_nrf52840 SD=s140 + make BOARD=feather_nrf52840 SD=s140 dfu-gen dfu-flash ## Bluetooth LE REPL diff --git a/ports/nrf/bluetooth/bluetooth_common.mk b/ports/nrf/bluetooth/bluetooth_common.mk index 760955200ef68..5d094fcf8ba5e 100644 --- a/ports/nrf/bluetooth/bluetooth_common.mk +++ b/ports/nrf/bluetooth/bluetooth_common.mk @@ -1,12 +1,4 @@ -ifeq ($(SD), s132) - CFLAGS += -DBLUETOOTH_SD=132 - -ifeq ($(SOFTDEV_VERSION), 2.0.1) - CFLAGS += -DBLE_API_VERSION=2 -else ifeq ($(SOFTDEV_VERSION), 5.0.0) - CFLAGS += -DBLE_API_VERSION=4 -endif -else ifeq ($(SD), s140) +ifeq ($(SD), s140) CFLAGS += -DBLUETOOTH_SD=140 CFLAGS += -DBLE_API_VERSION=4 else diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API-update.diff b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API-update.diff deleted file mode 100644 index f9b5fc8f7c6c5..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API-update.diff +++ /dev/null @@ -1,1550 +0,0 @@ -|-----------------------------------------------------------------------------| -| 2 Mbps PHY Support | -|-----------------------------------------------------------------------------| - -//| -//| Bitfield for PHYs used by PHY commands and events below -//| -+/**@defgroup BLE_GAP_PHYS GAP PHYs -+ * @{ */ -+#define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/ -+#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */ -+#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */ -+#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */ -+ -+/**@} */ - - -//| -//| PHY Update event: Notifies the application that the PHY has been changed, or that a PHY update -//| procedure is requested but the PHY is not changed. -//| -//| PHY Update Request event: Notifies the application that the peer has initiated a PHY Update Procedure. -//| Application must respond to this event with a SD_BLE_GAP_PHY_UPDATE command providing its PHY preferences, -//| otherwise the PHY Update procedure will time out. -//| - enum BLE_GAP_EVTS - { - BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ - BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ - BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ -- BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, /**< Data Length Update request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */ -+ BLE_GAP_EVT_PHY_UPDATE_REQUEST, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n See @ref ble_gap_evt_phy_update_request_t. */ -+ BLE_GAP_EVT_PHY_UPDATE, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */ -+ BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, /**< Data Length Update Request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */ - BLE_GAP_EVT_DATA_LENGTH_UPDATE, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */ - }; - - -+/**@brief PHY preferences for TX and RX -+ * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each direction. -+ * @code -+ * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; -+ * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; -+ * @endcode -+ * -+ */ -+typedef struct -+{ -+ uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */ -+ uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */ -+} ble_gap_phys_t; -+ - -+/**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */ -+typedef struct -+{ -+ ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */ -+} ble_gap_evt_phy_update_request_t; -+ -+/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */ -+typedef struct -+{ -+ uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/ -+ uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */ -+ uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */ -+} ble_gap_evt_phy_update_t; - - typedef struct - { - uint16_t conn_handle; /**< Connection Handle on which event occurred. */ - union /**< union alternative identified by evt_id in enclosing struct. */ - { - ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ -- ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report parameters. */ -+ ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */ -+ ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */ -+ ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */ - ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */ - ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */ - } params; /**< Event Parameters. */ - } ble_gap_evt_t; - -//| -//| PHY Update command. Use for initiating or responding to a PHY Update Procedure. -//| Either the master or the slave must call this function for the PHY to be changed. -//| - enum BLE_GAP_SVCS - { - SD_BLE_GAP_CONNECT, /**< Connect. */ - SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */ - SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */ -+ SD_BLE_GAP_PHY_UPDATE, /**< Initiate or respond to a PHY Update Procedure. */ - SD_BLE_GAP_DATA_LENGTH_UPDATE, /**< Initiate or respond to a Data Length Update Procedure. */ - }; - - -+/**@brief Initiate or respond to a PHY Update Procedure -+ * -+ * @details This function is used to initiate or respond to a PHY Update Procedure. It will always generate a -+ * @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed. If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys -+ * is @ref BLE_GAP_PHY_AUTO, then the stack will select a PHY for the respective direction based on the peer's PHY preferences -+ * and the local stack configuration. If the peer does not support the PHY Update Procedure, then the -+ * resulting @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to -+ * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE. -+ * If the PHY procedure was rejected by the peer due to a procedure collision, the status will be -+ * @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION. -+ * If the peer responds to the PHY Update procedure with invalid parameters, the status will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS. -+ * If the PHY procedure was rejected by the peer for a different reason, the status will contain the reason as specified by the peer. -+ * -+ * @events -+ * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.} -+ * @endevents -+ * -+ * @mscs -+ * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE} -+ * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE} -+ * @endmscs -+ * -+ * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested. -+ * @param[in] p_gap_phys Pointer to PHY structure. -+ * -+ * @retval ::NRF_SUCCESS Successfully requested a PHY Update. -+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. -+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. -+ * @retval ::NRF_ERROR_INVALID_PARAM Unsupported PHYs supplied to the call. -+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. -+ * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry. -+ * -+ */ -+SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)); -+ - - -//| -//| New BLE HCI status code -//| -+#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */ - -|-----------------------------------------------------------------------------| -| Connection-Oriented Channels in LE Credit Based Flow Control Mode | -|-----------------------------------------------------------------------------| - -//| -//| New L2CAP specific connection configuration ID -//| - enum BLE_CONN_CFGS - { - BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE, /**< BLE GAP specific connection configuration. */ - BLE_CONN_CFG_GATTC, /**< BLE GATTC specific connection configuration. */ - BLE_CONN_CFG_GATTS, /**< BLE GATTS specific connection configuration. */ - BLE_CONN_CFG_GATT, /**< BLE GATT specific connection configuration. */ -+ BLE_CONN_CFG_L2CAP, /**< BLE L2CAP specific connection configuration. */ - }; - - -//| -//| New L2CAP originated event -//| - typedef struct - { - ble_evt_hdr_t header; /**< Event header. */ - union - { - ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ - ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ - ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ - ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ -+ ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ - } evt; /**< Event union. */ - } ble_evt_t; - - -//| -//| New L2CAP connection configuration -//| - typedef struct - { - uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() - calls to select this configuration when creating a connection. - Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */ - union { - ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */ - ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */ - ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */ - ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */ -+ ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */ - } params; /**< Connection configuration union. */ - } ble_conn_cfg_t; - -//| -//| API additions related to Connection-Oriented Channels -//| -+/**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology -+ * @{ -+ * @details -+ * -+ * L2CAP SDU -+ * - A data unit that the application can send/receive to/from a peer. -+ * -+ * L2CAP PDU -+ * - A data unit that is exchanged between local and remote L2CAP entities. -+ * It consists of L2CAP protocol control information and payload fields. -+ * The payload field can contain an L2CAP SDU or a part of an L2CAP SDU. -+ * -+ * L2CAP MTU -+ * - The maximum length of an L2CAP SDU. -+ * -+ * L2CAP MPS -+ * - The maximum length of an L2CAP PDU payload field. -+ * -+ * Credits -+ * - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer. -+ * @} */ -+ -+/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations -+ * @{ */ -+ -+/**@brief L2CAP API SVC numbers. */ -+enum BLE_L2CAP_SVCS -+{ -+ SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE, /**< Set up an L2CAP channel. */ -+ SD_BLE_L2CAP_CH_RELEASE, /**< Release an L2CAP channel. */ -+ SD_BLE_L2CAP_CH_RX, /**< Receive an SDU on an L2CAP channel. */ -+ SD_BLE_L2CAP_CH_TX, /**< Transmit an SDU on an L2CAP channel. */ -+ SD_BLE_L2CAP_CH_FLOW_CONTROL, /**< Advanced SDU reception flow control. */ -+}; -+ -+/**@brief L2CAP Event IDs. */ -+enum BLE_L2CAP_EVTS -+{ -+ BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE, /**< L2CAP Channel Setup Request event. -+ \n See @ref ble_l2cap_evt_ch_setup_request_t. */ -+ BLE_L2CAP_EVT_CH_SETUP_REFUSED, /**< L2CAP Channel Setup Refused event. -+ \n See @ref ble_l2cap_evt_ch_setup_refused_t. */ -+ BLE_L2CAP_EVT_CH_SETUP, /**< L2CAP Channel Setup Completed event. -+ \n See @ref ble_l2cap_evt_ch_setup_t. */ -+ BLE_L2CAP_EVT_CH_RELEASED, /**< L2CAP Channel Released event. -+ \n No additional event structure applies. */ -+ BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED, /**< L2CAP Channel SDU data buffer released event. -+ \n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */ -+ BLE_L2CAP_EVT_CH_CREDIT, /**< L2CAP Channel Credit received. -+ \n See @ref ble_l2cap_evt_ch_credit_t. */ -+ BLE_L2CAP_EVT_CH_RX, /**< L2CAP Channel SDU received. -+ \n See @ref ble_l2cap_evt_ch_rx_t. */ -+ BLE_L2CAP_EVT_CH_TX, /**< L2CAP Channel SDU transmitted. -+ \n See @ref ble_l2cap_evt_ch_tx_t. */ -+}; -+ -+/** @} */ -+ - /**@addtogroup BLE_L2CAP_DEFINES Defines - * @{ */ - -+/**@brief Maximum number of L2CAP channels per connection. */ -+#define BLE_L2CAP_CH_COUNT_MAX (64) -+ -+/**@brief Minimum L2CAP MTU, in bytes. */ -+#define BLE_L2CAP_MTU_MIN (23) -+ -+/**@brief Minimum L2CAP MPS, in bytes. */ -+#define BLE_L2CAP_MPS_MIN (23) -+ -+/**@brief Invalid CID. */ -+#define BLE_L2CAP_CID_INVALID (0x0000) -+ -+/**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */ -+#define BLE_L2CAP_CREDITS_DEFAULT (1) -+ -+/**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources -+ * @{ */ -+#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */ -+#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */ -+ /** @} */ -+ -+ /** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes -+ * @{ */ -+#define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */ -+#define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */ -+#define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */ -+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */ -+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */ -+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */ -+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */ -+#define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */ -+#define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */ -+#define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */ -+#define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */ -+#define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */ -+/** @} */ -+ -+/** @} */ -+ -+/**@addtogroup BLE_L2CAP_STRUCTURES Structures -+ * @{ */ -+ -+/** -+ * @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set. -+ * -+ * @note These parameters are set per connection, so all L2CAP channels created on this connection -+ * will have the same parameters. -+ * -+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: -+ * - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. -+ * - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. -+ * - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX. -+ * @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high. -+ */ -+typedef struct -+{ -+ uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall -+ be able to receive on L2CAP channels on connections with this -+ configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ -+ uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall -+ be able to transmit on L2CAP channels on connections with this -+ configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ -+ uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per -+ L2CAP channel. The minimum value is one. */ -+ uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission -+ per L2CAP channel. The minimum value is one. */ -+ uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection -+ with this configuration. The default value is zero, the maximum -+ value is @ref BLE_L2CAP_CH_COUNT_MAX. -+ @note if this parameter is set to zero, all other parameters in -+ @ref ble_l2cap_conn_cfg_t are ignored. */ -+} ble_l2cap_conn_cfg_t; -+ -+/**@brief L2CAP channel RX parameters. */ -+typedef struct -+{ -+ uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to -+ receive on this L2CAP channel. -+ - Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */ -+ uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be -+ able to receive on this L2CAP channel. -+ - Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN. -+ - Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */ -+ ble_data_t sdu_buf; /**< SDU data buffer for reception. -+ - If @ref ble_data_t::p_data is non-NULL, initial credits are -+ issued to the peer. -+ - If @ref ble_data_t::p_data is NULL, no initial credits are -+ issued to the peer. */ -+} ble_l2cap_ch_rx_params_t; -+ -+/**@brief L2CAP channel setup parameters. */ -+typedef struct -+{ -+ ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */ -+ uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting -+ setup of an L2CAP channel, ignored otherwise. */ -+ uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES. -+ Used when replying to a setup request of an L2CAP -+ channel, ignored otherwise. */ -+} ble_l2cap_ch_setup_params_t; -+ -+/**@brief L2CAP channel TX parameters. */ -+typedef struct -+{ -+ uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to -+ transmit on this L2CAP channel. */ -+ uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is -+ able to receive on this L2CAP channel. */ -+ uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able -+ to transmit on this L2CAP channel. This is effective tx_mps, -+ selected by the SoftDevice as -+ MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */ -+ uint16_t credits; /**< Initial credits given by the peer. */ -+} ble_l2cap_ch_tx_params_t; -+ -+/**@brief L2CAP Channel Setup Request event. */ -+typedef struct -+{ -+ ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ -+ uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */ -+} ble_l2cap_evt_ch_setup_request_t; -+ -+/**@brief L2CAP Channel Setup Refused event. */ -+typedef struct -+{ -+ uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */ -+ uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */ -+} ble_l2cap_evt_ch_setup_refused_t; -+ -+/**@brief L2CAP Channel Setup Completed event. */ -+typedef struct -+{ -+ ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ -+} ble_l2cap_evt_ch_setup_t; -+ -+/**@brief L2CAP Channel SDU Data Duffer Released event. */ -+typedef struct -+{ -+ ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice -+ returns SDU data buffers supplied by the application, which have -+ not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or -+ @ref BLE_L2CAP_EVT_CH_TX event. */ -+} ble_l2cap_evt_ch_sdu_buf_released_t; -+ -+/**@brief L2CAP Channel Credit received event. */ -+typedef struct -+{ -+ uint16_t credits; /**< Additional credits given by the peer. */ -+} ble_l2cap_evt_ch_credit_t; -+ -+/**@brief L2CAP Channel received SDU event. */ -+typedef struct -+{ -+ uint16_t sdu_len; /**< Total SDU length, in bytes. */ -+ ble_data_t sdu_buf; /**< SDU data buffer. -+ @note If there is not enough space in the buffer -+ (sdu_buf.len < sdu_len) then the rest of the SDU will be -+ silently discarded by the SoftDevice. */ -+} ble_l2cap_evt_ch_rx_t; -+ -+/**@brief L2CAP Channel transmitted SDU event. */ -+typedef struct -+{ -+ ble_data_t sdu_buf; /**< SDU data buffer. */ -+} ble_l2cap_evt_ch_tx_t; -+ -+/**@brief L2CAP event structure. */ -+typedef struct -+{ -+ uint16_t conn_handle; /**< Connection Handle on which the event occured. */ -+ uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or -+ @ref BLE_L2CAP_CID_INVALID if not present. */ -+ union -+ { -+ ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */ -+ ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */ -+ ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */ -+ ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released;/**< L2CAP Channel SDU Data Buffer Released Event Parameters. */ -+ ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */ -+ ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */ -+ ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */ -+ } params; /**< Event Parameters. */ -+} ble_l2cap_evt_t; -+ -+/** @} */ -+ -+/**@addtogroup BLE_L2CAP_FUNCTIONS Functions -+ * @{ */ -+ -+/**@brief Set up an L2CAP channel. -+ * -+ * @details This function is used to: -+ * - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer. -+ * - Reply to a setup request of an L2CAP channel (if called in response to a -+ * @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection -+ * Response packet to a peer. -+ * -+ * @note A call to this function will require the application to keep the SDU data buffer alive -+ * until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or -+ * @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. -+ * -+ * @events -+ * @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.} -+ * @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.} -+ * @endevents -+ * -+ * @mscs -+ * @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC} -+ * @endmscs -+ * -+ * @param[in] conn_handle Connection Handle. -+ * @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel: -+ * - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP -+ * channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST -+ * event when replying to a setup request of an L2CAP channel. -+ * - As output: local_cid for this channel. -+ * @param[in] p_params L2CAP channel parameters. -+ * -+ * @retval ::NRF_SUCCESS Successfully queued request or response for transmission. -+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. -+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. -+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. -+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. -+ * @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link. -+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up). -+ * @retval ::NRF_ERROR_NOT_FOUND CID not found. -+ * @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels, -+ * see @ref ble_l2cap_conn_cfg_t::ch_count. -+ */ -+SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params)); -+ -+/**@brief Release an L2CAP channel. -+ * -+ * @details This sends a Disconnection Request packet to a peer. -+ * -+ * @events -+ * @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.} -+ * @endevents -+ * -+ * @mscs -+ * @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC} -+ * @endmscs -+ * -+ * @param[in] conn_handle Connection Handle. -+ * @param[in] local_cid Local Channel ID of the L2CAP channel. -+ * -+ * @retval ::NRF_SUCCESS Successfully queued request for transmission. -+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. -+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is -+ * in progress for the L2CAP channel). -+ * @retval ::NRF_ERROR_NOT_FOUND CID not found. -+ */ -+SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid)); -+ -+/**@brief Receive an SDU on an L2CAP channel. -+ * -+ * @details This may issue additional credits to the peer using an LE Flow Control Credit packet. -+ * -+ * @note A call to this function will require the application to keep the memory pointed by -+ * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX -+ * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. -+ * -+ * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers -+ * for reception per L2CAP channel. -+ * -+ * @events -+ * @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.} -+ * @endevents -+ * -+ * @mscs -+ * @mmsc{@ref BLE_L2CAP_CH_RX_MSC} -+ * @endmscs -+ * -+ * @param[in] conn_handle Connection Handle. -+ * @param[in] local_cid Local Channel ID of the L2CAP channel. -+ * @param[in] p_sdu_buf Pointer to the SDU data buffer. -+ * -+ * @retval ::NRF_SUCCESS Buffer accepted. -+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. -+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. -+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is -+ * in progress for an L2CAP channel). -+ * @retval ::NRF_ERROR_NOT_FOUND CID not found. -+ * @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a -+ * @ref BLE_L2CAP_EVT_CH_RX event and retry. -+ */ -+SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); -+ -+/**@brief Transmit an SDU on an L2CAP channel. -+ * -+ * @note A call to this function will require the application to keep the memory pointed by -+ * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX -+ * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. -+ * -+ * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for -+ * transmission per L2CAP channel. -+ * -+ * @note The application can keep track of the available credits for transmission by following -+ * the procedure below: -+ * - Store initial credits given by the peer in a variable. -+ * (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) -+ * - Decrement the variable, which stores the currently available credits, by -+ * ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns -+ * @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) -+ * - Increment the variable, which stores the currently available credits, by additional -+ * credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event. -+ * -+ * @events -+ * @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.} -+ * @endevents -+ * -+ * @mscs -+ * @mmsc{@ref BLE_L2CAP_CH_TX_MSC} -+ * @endmscs -+ * -+ * @param[in] conn_handle Connection Handle. -+ * @param[in] local_cid Local Channel ID of the L2CAP channel. -+ * @param[in] p_sdu_buf Pointer to the SDU data buffer. -+ * -+ * @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission. -+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. -+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. -+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is -+ * in progress for the L2CAP channel). -+ * @retval ::NRF_ERROR_NOT_FOUND CID not found. -+ * @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than -+ * @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in -+ * @ref BLE_L2CAP_EVT_CH_SETUP event. -+ * @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a -+ * @ref BLE_L2CAP_EVT_CH_TX event and retry. -+ */ -+SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); -+ -+/**@brief Advanced SDU reception flow control. -+ * -+ * @details Adjust the way the SoftDevice issues credits to the peer. -+ * This may issue additional credits to the peer using an LE Flow Control Credit packet. -+ * -+ * @mscs -+ * @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC} -+ * @endmscs -+ * -+ * @param[in] conn_handle Connection Handle. -+ * @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set -+ * the value that will be used for newly created channels. -+ * @param[in] credits Number of credits that the SoftDevice will make sure the peer has every -+ * time it starts using a new reception buffer. -+ * - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will -+ * use if this function is not called. -+ * - If set to zero, the SoftDevice will stop issuing credits for new reception -+ * buffers the application provides or has provided. SDU reception that is -+ * currently ongoing will be allowed to complete. -+ * @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be -+ * written by the SoftDevice with the number of credits that is or will be -+ * available to the peer. If the value written by the SoftDevice is 0 when -+ * credits parameter was set to 0, the peer will not be able to send more -+ * data until more credits are provided by calling this function again with -+ * credits > 0. This parameter is ignored when local_cid is set to @ref -+ * BLE_L2CAP_CID_INVALID. -+ * -+ * @note Application should take care when setting number of credits higher than default value. In -+ * this case the application must make sure that the SoftDevice always has reception buffers -+ * available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have -+ * such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic -+ * on the connection handle may be stalled until the SoftDevice again has an available -+ * reception buffer. This applies even if the application has used this call to set the -+ * credits back to default, or zero. -+ * -+ * @retval ::NRF_SUCCESS Flow control parameters accepted. -+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. -+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. -+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is -+ * in progress for an L2CAP channel). -+ * @retval ::NRF_ERROR_NOT_FOUND CID not found. -+ */ -+SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits)); -+ - - -//| -//| Data buffer provided to/from the application -//| -+/**@brief Data structure. */ -+typedef struct -+{ -+ uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */ -+ uint16_t len; /**< Length of the data buffer, in bytes. */ -+} ble_data_t; -+ - - - -|-----------------------------------------------------------------------------| -| Network Privacy | -|-----------------------------------------------------------------------------| - -//| -//| Now supporting both network privacy and device privacy. -//| - #define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ - #define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ -+#define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY 0x02 /**< Device will send and accept only private addresses for its own address, -+ and will not accept a peer using identity address as sender address when -+ the peer IRK is exchanged, non-zero and added to the identity list. */ - - --/**@brief Device Privacy. -+/**@brief Privacy. - * - * The privacy feature provides a way for the device to avoid being tracked over a period of time. - * The privacy feature, when enabled, hides the local device identity and replaces it with a private address - * that is automatically refreshed at a specified interval. - * - * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). - * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key, - * and devices can establish connections without revealing their real identities. - * -+ * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY) -+ * are supported. -+ * - * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all - * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. - * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called. - */ - typedef struct - { - uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ - uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ - uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ - ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. - When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. - By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ - } ble_gap_privacy_params_t; - -+#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */ - - -//| -//| Improved documentation for sd_ble_gap_privacy_get -//| - /**@brief Get privacy settings. - * -- * @note The privacy settings returned include the current device irk as well. -+ * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called. -+ * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return. - * -- * @param[in] p_privacy_params Privacy settings. -+ * @param[in,out] p_privacy_params Privacy settings. - * - * @retval ::NRF_SUCCESS Privacy settings read. - * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. - * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. - */ - SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); - -|-----------------------------------------------------------------------------| -| Updates for Bluetooth 5 compliance | -|-----------------------------------------------------------------------------| - -//| -//| BLE_GAP_EVT_TIMEOUT {src: BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST} replaced with BLE_GAP_EVT_AUTH_STATUS {auth_status: BLE_GAP_SEC_STATUS_TIMEOUT} -//| - /**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources - * @{ */ - #define BLE_GAP_TIMEOUT_SRC_ADVERTISING 0x00 /**< Advertising timeout. */ --#define BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST 0x01 /**< Security request timeout. */ --#define BLE_GAP_TIMEOUT_SRC_SCAN 0x02 /**< Scanning timeout. */ --#define BLE_GAP_TIMEOUT_SRC_CONN 0x03 /**< Connection timeout. */ --#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x04 /**< Authenticated payload timeout. */ -+#define BLE_GAP_TIMEOUT_SRC_SCAN 0x01 /**< Scanning timeout. */ -+#define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */ -+#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */ - /**@} */ - - -//| -//| Lowering of the lower limit for advertising interval for non-connectable advertisement. -//| - /**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min - * @{ */ - #define BLE_GAP_ADV_INTERVAL_MIN 0x0020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ --#define BLE_GAP_ADV_NONCON_INTERVAL_MIN 0x00A0 /**< Minimum Advertising interval in 625 us units for non connectable mode, i.e. 100 ms. */ - #define BLE_GAP_ADV_INTERVAL_MAX 0x4000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ - /**@} */ - - -//| -//| Change of definition of LE Security Mode 1 level 4. -//| - /**@brief GAP connection security modes. - * - * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n - * Security Mode 1 Level 1: No security is needed (aka open link).\n - * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n - * Security Mode 1 Level 3: MITM protected encrypted link required.\n -- * Security Mode 1 Level 4: LESC MITM protected encrypted link required.\n -+ * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n - * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n - * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n - */ - typedef struct - { - uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ - uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ - - } ble_gap_conn_sec_mode_t; - -|-----------------------------------------------------------------------------| -| Master boot record | -|-----------------------------------------------------------------------------| - - -//| -//| New API for forwarding all interrupts to a specific address -//| - enum NRF_MBR_COMMANDS - { - SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t*/ - SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ - SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD*/ - SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ -- SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/ -+ SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset @see ::sd_mbr_command_vector_table_base_set_t*/ -+ SD_MBR_COMMAND_RESERVED, -+ SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address @see ::sd_mbr_command_irq_forward_address_set_t*/ - }; - -+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR -+ * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not -+ * change where the MBR starts after reset. -+ * -+ * @retval ::NRF_SUCCESS -+ */ -+typedef struct -+{ -+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ -+} sd_mbr_command_irq_forward_address_set_t; - - typedef struct - { - uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */ - union - { - sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ - sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ - sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ - sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ -+ sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/ - } params; - } sd_mbr_command_t; - - -|-----------------------------------------------------------------------------| -| Removal of Compatibility mode 2 option | -|-----------------------------------------------------------------------------| - - enum BLE_GAP_OPTS - { - BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ - BLE_GAP_OPT_LOCAL_CONN_LATENCY, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ - BLE_GAP_OPT_PASSKEY, /**< Set passkey. @ref ble_gap_opt_passkey_t */ - BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */ - BLE_GAP_OPT_COMPAT_MODE_1, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */ -- BLE_GAP_OPT_COMPAT_MODE_2, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_2_t */ - BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ - BLE_GAP_OPT_SLAVE_LATENCY_DISABLE, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */ - }; - - --/**@brief Compatibility mode 2 option. -- * -- * This can be used with @ref sd_ble_opt_set to enable compatibility mode 2. -- * Compatibility mode 2 is disabled by default. -- * -- * @note Compatibility mode 2 enables interoperability with devices that initiate Feature exchange -- * and version exchange procedure in parallel. -- * -- * @retval ::NRF_SUCCESS Set successfully. -- * @retval ::NRF_ERROR_INVALID_PARAM if enable bit is not set to 1. Currently only enabling is supported. -- * @retval ::NRF_ERROR_INVALID_STATE When any role is running while mode 2 is set. -- */ --typedef struct --{ -- uint8_t enable : 1; /**< Enable compatibility mode 2.*/ --} ble_gap_opt_compat_mode_2_t; -- -- - - - /**@brief Option structure for GAP options. */ - typedef union - { - ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ - ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ - ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ - ble_gap_opt_scan_req_report_t scan_req_report; /**< Parameters for the scan request report option.*/ - ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/ -- ble_gap_opt_compat_mode_2_t compat_mode_2; /**< Parameters for the compatibility mode 2 option.*/ - ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ - ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */ - } ble_gap_opt_t; - /**@} */ - - - -|-----------------------------------------------------------------------------| -| Misc | -|-----------------------------------------------------------------------------| - - -//| -//| Added defines for Authenticated payload timeout -//| -+/**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines. -+ * @{ */ -+#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */ -+#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */ -+/**@} */ - - /**@brief Authenticated payload timeout option. - * -- * This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other than the default of 8 minutes. -+ * This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other -+ * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX. - * - * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated - * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted - * link. - * - * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance - * to reset the timer. In addition the stack will try to prioritize running of LE ping over other - * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects - * on other activities, it is recommended to use high timeout values. - * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. - */ - typedef struct - { - uint16_t conn_handle; /**< Connection Handle */ -- uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit. Maximum is 48 000 (=480 000 ms =8 min). Minimum is 1 (=10 ms). */ -+ uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */ - } ble_gap_opt_auth_payload_timeout_t; - - -//| -//| APIs not returning NRF_ERROR_BUSY anymore. -//| - /**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). - * - * @note Only one advertiser may be active at any time. - * - * @param[in] p_adv_params Pointer to advertising parameters structure. - * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref - * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. If - * @ref ble_gap_adv_params_t::type is @ref BLE_GAP_ADV_TYPE_ADV_NONCONN_IND, - * this is ignored. - * - * @retval ::NRF_SUCCESS The BLE stack has started advertising. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied. - * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. -- * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. - * Stop one or more currently active roles (Central, Peripheral or Observer) and try again - */ - SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params, uint8_t conn_cfg_tag)); - - - /**@brief Initiate the GAP Authentication procedure. - * - * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), - * otherwise in the peripheral role, an SMP Security Request will be sent. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. - * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. - * In the central role, this pointer may be NULL to reject a Security Request. - * - * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. -- * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. - * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. - */ - SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); - - - /**@brief Start scanning (GAP Discovery procedure, Observer Procedure). - * - * @param[in] p_scan_params Pointer to scan parameters structure. - * - * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. -- * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. - * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again - */ - SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params)); - - - /**@brief Create a connection (GAP Link Establishment). - * - * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. - * The scanning procedure will be stopped even if the function returns an error. - * - * @param[in] p_peer_addr Pointer to peer address. If the use_whitelist bit is set in @ref ble_gap_scan_params_t, then this is ignored. -- * If @ref ble_gap_addr_t::addr_id_peer is set then p_peer_addr must be present in the device identity list -- * see @ref sd_ble_gap_device_identities_set. - * @param[in] p_scan_params Pointer to scan parameters structure. - * @param[in] p_conn_params Pointer to desired connection parameters. - * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref - * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. - * - * @retval ::NRF_SUCCESS Successfully initiated connection procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * - Invalid parameter(s) in p_scan_params or p_conn_params. - * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. - * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set. - * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an - * existing locally initiated connect procedure, which must complete before initiating again. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. - * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. -- * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. If another connection is being established -- * wait for the corresponding @ref BLE_GAP_EVT_CONNECTED event before calling again. - * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. - * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again - */ - SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)); - - -//| -//| APIs now also returning NRF_ERROR_BUSY. -//| - - /**@brief Provide a user memory block. - * - * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application. - * - * @mscs -- * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} -+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. -+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending. - */ - SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); - - - /**@brief Reply with GAP security parameters. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * - * @param[in] conn_handle Connection handle. - * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. - * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have - * already been provided during a previous call to @ref sd_ble_gap_authenticate. - * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure - * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application - * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. - * Note that the SoftDevice expects the application to provide memory for storing the - * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key - * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the - * @ref BLE_GAP_EVT_AUTH_STATUS event. - * - * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. -+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. - */ - SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); - - - /**@brief Respond to a Read/Write authorization request. - * - * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. - * - * @mscs - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} - * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} -- * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} -+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. - * - * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond - * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update - * is set to 0. - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. -+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. - * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, - * handle supplied does not match requested handle, - * or invalid data to be written provided by the application. - */ - SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); - - - -//| -//| Flag indicating the establishment of an LE Secure Connection -//| - typedef struct - { - uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ - uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ - uint8_t bonded : 1; /**< Procedure resulted in a bond. */ -+ uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */ - ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ - ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ - ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ - ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ - } ble_gap_evt_auth_status_t; - -//| -//| Stack will no longer return BUSY on sd_ble_gap_conn_param_update unless the procedure is already in progress. -//| - /**@brief Update connection parameters. - * - * @details In the central role this will initiate a Link Layer connection parameter update procedure, - * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for - * the central to perform the procedure. In both cases, and regardless of success or failure, the application - * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. - * - * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, - * the parameters in the PPCP characteristic of the GAP service will be used instead. - * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected - * - * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. -- * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, process pending events and wait for pending procedures to complete and retry. -+ * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ - SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); - - -//| -//| Renamed Defines and structure member related to clock accuracy -//| --/**@defgroup NRF_CLOCK_LF_XTAL_ACCURACY Clock accuracy -+/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy - * @{ */ - --#define NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_500_PPM (1) /**< 500 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_150_PPM (2) /**< 150 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_100_PPM (3) /**< 100 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_75_PPM (4) /**< 75 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_50_PPM (5) /**< 50 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_30_PPM (6) /**< 30 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM (7) /**< 20 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_10_PPM (8) /**< 10 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_5_PPM (9) /**< 5 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_2_PPM (10) /**< 2 ppm */ --#define NRF_CLOCK_LF_XTAL_ACCURACY_1_PPM (11) /**< 1 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */ -+#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */ - - - /**@brief Type representing LFCLK oscillator source. */ - typedef struct - { - uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ - uint8_t rc_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second - units (nRF51: 1-64, nRF52: 1-32). - @note To avoid excessive clock drift, 0.5 degrees Celsius is the - maximum temperature change allowed in one calibration timer - interval. The interval should be selected to ensure this. - - @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. */ - uint8_t rc_temp_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: How often (in number of calibration - intervals) the RC oscillator shall be calibrated if the temperature - hasn't changed. - 0: Always calibrate even if the temperature hasn't changed. - 1: Only calibrate if the temperature has changed (nRF51 only). - 2-33: Check the temperature and only calibrate if it has changed, - however calibration will take place every rc_temp_ctiv - intervals in any case. - - @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. - - @note For nRF52, the application must ensure calibration at least once - every 8 seconds to ensure +/-500 ppm clock stability. The - recommended configuration for NRF_CLOCK_LF_SRC_RC on nRF52 is - rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at - least once every 8 seconds and for temperature changes of 0.5 - degrees Celsius every 4 seconds. See the Product Specification - for the nRF52 device being used for more information.*/ -- uint8_t xtal_accuracy; /**< External crystal clock accuracy used in the LL to compute timing -- windows, see @ref NRF_CLOCK_LF_XTAL_ACCURACY. -- -- @note For the NRF_CLOCK_LF_SRC_RC clock source this parameter is ignored. */ -+ uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing -+ windows, see @ref NRF_CLOCK_LF_ACCURACY.*/ - } nrf_clock_lf_cfg_t; - - -//| -//| Removal of references to nRF51 -//| --#ifdef NRF51 -- #define __NRF_NVIC_ISER_COUNT (1) /**< The number of ISER/ICER registers in the NVIC that are used. */ -- -- /**@brief Interrupts used by the SoftDevice. */ -- #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ -- (1U << POWER_CLOCK_IRQn) \ -- | (1U << RADIO_IRQn) \ -- | (1U << RTC0_IRQn) \ -- | (1U << TIMER0_IRQn) \ -- | (1U << RNG_IRQn) \ -- | (1U << ECB_IRQn) \ -- | (1U << CCM_AAR_IRQn) \ -- | (1U << TEMP_IRQn) \ -- | (1U << __NRF_NVIC_NVMC_IRQn) \ -- | (1U << (uint32_t)SWI5_IRQn) \ -- )) -- -- /**@brief Interrupts available for to application. */ -- #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) --#endif -- --#ifdef NRF52 - #define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ - -- /**@brief Interrupts used by the SoftDevice. */ -+/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */ - #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ - (1U << POWER_CLOCK_IRQn) \ - | (1U << RADIO_IRQn) \ - | (1U << RTC0_IRQn) \ - | (1U << TIMER0_IRQn) \ - | (1U << RNG_IRQn) \ - | (1U << ECB_IRQn) \ - | (1U << CCM_AAR_IRQn) \ - | (1U << TEMP_IRQn) \ - | (1U << __NRF_NVIC_NVMC_IRQn) \ - | (1U << (uint32_t)SWI5_EGU5_IRQn) \ - )) -+ -+/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */ - #define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) - -- /**@brief Interrupts available for to application. */ -+/**@brief Interrupts available for to application, with IRQn in the range 0-31. */ - #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) -+ -+/**@brief Interrupts available for to application, with IRQn in the range 32-63. */ - #define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) --#endif -+ - - __STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) - { - if (IRQn < 32) - { - return ((1UL<= (1 << __NVIC_PRIO_BITS)) - { - return 0; - } --#ifdef NRF51 -- if( priority == 0 -- || priority == 2 -- ) -- { -- return 0; -- } --#endif --#ifdef NRF52 - if( priority == 0 - || priority == 1 - || priority == 4 - ) - { - return 0; - } --#endif - return 1; - } - - __STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) - { - int was_masked = __sd_nvic_irq_disable(); - if (!nrf_nvic_state.__cr_flag) - { - nrf_nvic_state.__cr_flag = 1; - nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); - NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; -- #ifdef NRF52 - nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); - NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; -- #endif - *p_is_nested_critical_region = 0; - } - else - { - *p_is_nested_critical_region = 1; - } - if (!was_masked) - { - __sd_nvic_irq_enable(); - } - return NRF_SUCCESS; - } - - __STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) - { - if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) - { - int was_masked = __sd_nvic_irq_disable(); - NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; -- #ifdef NRF52 - NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; -- #endif - nrf_nvic_state.__cr_flag = 0; - if (!was_masked) - { - __sd_nvic_irq_enable(); - } - } - - return NRF_SUCCESS; - } - --#ifdef NRF51 --#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ --#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ --#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ --#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */ --#endif --#ifdef NRF52 - #define SD_EVT_IRQn (SWI2_EGU2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ - #define SD_EVT_IRQHandler (SWI2_EGU2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. - The default interrupt priority for this handler is set to 4 */ - #define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */ - #define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler. - The default interrupt priority for this handler is set to 4 */ --#endif -- - -/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). - * - * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. - * @param[in] gpregret_msk Bits to be set in the GPREGRET register. - * -- * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. - * @retval ::NRF_SUCCESS - */ - SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); - - /**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). - * - * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. - * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. - * -- * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. - * @retval ::NRF_SUCCESS - */ - SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); - - /**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). - * - * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. - * @param[out] p_gpregret Contents of the GPREGRET register. - * -- * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. - * @retval ::NRF_SUCCESS - */ - SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); - - /**@brief Flash Write - * - * Commands to write a buffer to flash - * - * If the SoftDevice is enabled: - * This call initiates the flash access command, and its completion will be communicated to the - * application with exactly one of the following events: - * - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. - * - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. - * - * If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the - * write has been completed - * - * @note - * - This call takes control over the radio and the CPU during flash erase and write to make sure that - * they will not interfere with the flash access. This means that all interrupts will be blocked --* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual -+* for a predictable time (depending on the NVMC specification in the device's Product Specification - * and the command parameters). - * - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS - * or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. - * - * - * @param[in] p_dst Pointer to start of flash location to be written. - * @param[in] p_src Pointer to buffer with data to be written. --* @param[in] size Number of 32-bit words to write. Maximum size is 256 32-bit words for nRF51 and 1024 for nRF52. -+* @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one -+* flash page. See the device's Product Specification for details. - * - * @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. - * @retval ::NRF_ERROR_BUSY The previous command has not yet completed. - * @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. - * @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. - * @retval ::NRF_SUCCESS The command was accepted. - */ - SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size)); - - - /**@brief Flash Erase page - * - * Commands to erase a flash page - * If the SoftDevice is enabled: - * This call initiates the flash access command, and its completion will be communicated to the - * application with exactly one of the following events: - * - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. - * - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. - * - * If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the - * erase has been completed - * - * @note - * - This call takes control over the radio and the CPU during flash erase and write to make sure that - * they will not interfere with the flash access. This means that all interrupts will be blocked --* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual -+* for a predictable time (depending on the NVMC specification in the device's Product Specification - * and the command parameters). - * - * - * @param[in] page_number Page number of the page to erase - * - * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. - * @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. - * @retval ::NRF_ERROR_BUSY The previous command has not yet completed. - * @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page. - * @retval ::NRF_SUCCESS The command was accepted. - */ - SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); - - - /**@brief Flash Protection set - * - * Commands to set the flash protection configuration registers. -- On nRF51 this sets the PROTENSETx registers of the MPU peripheral. -- On nRF52 this sets the CONFIGx registers of the BPROT peripheral. -+ This sets the CONFIGx registers of the BPROT peripheral. - * - * @note To read the values read them directly. They are only write-protected. - * - * @param[in] block_cfg0 Value to be written to the configuration register. - * @param[in] block_cfg1 Value to be written to the configuration register. -- * @param[in] block_cfg2 Value to be written to the configuration register (ignored on nRF51). -- * @param[in] block_cfg3 Value to be written to the configuration register (ignored on nRF51). -+ * @param[in] block_cfg2 Value to be written to the configuration register. -+ * @param[in] block_cfg3 Value to be written to the configuration register. - * - * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. - * @retval ::NRF_SUCCESS Values successfully written to configuration registers. - */ - - -//| -//| Version information update -//| - /** @brief The major version for the SoftDevice binary distributed with this header file. */ --#define SD_MAJOR_VERSION (4) -+#define SD_MAJOR_VERSION (5) - - - /** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ --#define SD_BUGFIX_VERSION (3) -+#define SD_BUGFIX_VERSION (0) - - -//| -//| SoftDevice unique string related updates -//| -+/** @brief SoftDevice unique string size in bytes. */ -+#define SD_UNIQUE_STR_SIZE 20 -+ - - -+/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address. -+ * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE. -+ */ -+#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18) -+ - --/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use @ref -- * MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual -- * case). */ -+/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address. -+ * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR -+ * (the usual case). */ - #define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ - ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID) - -+/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address. -+ * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR -+ * (the usual case). */ -+#define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ -+ ? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID) -+ - -//| -//| New defines for timing constraints the application must take into account when using NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND with the Radio Timeslot API. -//| -+/**@brief The maximum processing time to handle a timeslot extension. */ -+#define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (17) -+ -+/**@brief The latest time before the end of a timeslot the timeslot can be extended. */ -+#define NRF_RADIO_MIN_EXTENSION_MARGIN_US (79) -+ - - enum NRF_RADIO_SIGNAL_CALLBACK_ACTION - { - NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ -- NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */ -+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current -+ timeslot. Maximum execution time for this action: -+ @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US. -+ This action must be started at least @ref -+ NRF_RADIO_MIN_EXTENSION_MARGIN_US before -+ the end of the timeslot. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ - }; - \ No newline at end of file diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/doc/ble_api.dox b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/doc/ble_api.dox deleted file mode 100644 index e2913931ea796..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/doc/ble_api.dox +++ /dev/null @@ -1,3685 +0,0 @@ -/** - * @addtogroup BLE_COMMON - * @{ - * @defgroup BLE_COMMON_MSC Message Sequence Charts - * @{ - * - * @defgroup BLE_COMMON_ENABLE BLE Stack Enable - * @{ - * @msc - * hscale = "1.5"; - * APP,SD; - * |||; - * APP=>SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; - * APP<SD [label = "sd_ble_cfg_set(cfg_id, cfg, app_ram_base);"]; - * APP<SD [label = "sd_ble_cfg_set(cfg_id, cfg, app_ram_base);"]; - * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; - * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; - * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; - * APP<SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; - * APP<SD [label = "sd_ble_cfg_set(cfg_id, cfg, app_ram_base);"]; - * APP<SD [label = "sd_ble_cfg_set(cfg_id, cfg, app_ram_base);"]; - * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; - * APP<SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; - * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GAP, cfg = {conn_cfg_tag = 1, gap_conn_cfg.conn_count = 1, app_ram_base);"]; - * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATT, cfg = {conn_cfg_tag = 1, gatt_conn_cfg, app_ram_base);"]; - * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATTC, cfg = {conn_cfg_tag = 1, gattc_conn_cfg, app_ram_base);"]; - * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATTS, cfg = {conn_cfg_tag = 1, gatts_conn_cfg, app_ram_base);"]; - * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; - * APP<SD [label = "sd_ble_gap_connect(params, conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT);"]; - * APP<SD [label = "sd_ble_gap_adv_start(params, conn_cfg_tag = 1);"]; - * APP<SD [label = "sd_ble_gap_connect(params, conn_cfg_tag = 1);"]; - * APP<SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; - * APP<SD [label = "sd_nvic_EnableIRQ(SD_EVT_IRQn)"]; - * APP<APP [label = "SD_EVT_IRQHandler()"]; - * APP=>SD [label = "sd_ble_evt_get(buffer);"]; - * APP<SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; - * APP<SD [label = "sd_app_evt_wait(void);"]; - * APP rbox APP [label="App Thread Mode blocked, CPU in low power mode"]; - * |||; - * ...; - * |||; - * SD rbox SD [label="Event Available for the App"]; - * APP<SD [label = "sd_ble_evt_get(buffer);"]; - * APP<SD [label = "sd_app_evt_wait(void);"]; - * APP rbox APP [label="App Thread Mode blocked, CPU in low power mode"]; - * |||; - * ...; - * |||; - * SD rbox SD [label="Event Available for the App"]; - * APP<SD [label = "sd_ble_evt_get(buffer);"]; - * APP<SD [label = "sd_app_evt_wait(void);"]; - * APP rbox APP [label="App Thread Mode blocked, CPU in low power mode"]; - * |||; - * ...; - * |||; - * @endmsc - * - * @} - * @} - */ - -/** - * @addtogroup BLE_GAP - * @{ - * @defgroup BLE_GAP_MSC Message Sequence Charts - * @{ - * @defgroup BLE_GAP_ADV_MSC Advertising - * @msc - * hscale = "1.5"; - * APP,SD,SCANNERS; - * |||; - * APP=>SD [label = "sd_ble_gap_addr_set(peer_addr)"]; - * APP<SD [label = "sd_ble_gap_adv_data_set(adv, sr)"]; - * APP<SD [label = "sd_ble_gap_adv_start(params)"]; - * APP<SCANNERS [label = "ADV packet", textcolor="#000080", linecolor="#000080"]; - * SD->SCANNERS [label = "ADV packet", textcolor="#000080", linecolor="#000080"]; - * SD->SCANNERS [label = "ADV packet", textcolor="#000080", linecolor="#000080"]; - * ...; - * SD->SCANNERS [label = "ADV packet", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #1 App Stops Advertisement "]; - * APP=>SD [label = "sd_ble_gap_adv_stop()"]; - * APP<CENTRAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED"]; - * |||; - * --- [label = " Variant #1 Local Disconnection "]; - * APP=>SD [label = "sd_ble_gap_disconnect(reason)"]; - * APP<CENTRAL [label = "Connection Termination", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {reason}"]; - * |||; - * --- [label = " Variant #2 Remote Disconnection "]; - * SD<:CENTRAL [label = "Connection Termination", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {reason}"]; - * @endmsc - * - * @defgroup BLE_GAP_CPU_MSC Peripheral Connection Parameter Update - * @msc - * hscale = "1.5"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established with conn. params. CP#1"]; - * |||; - * APP=>SD [label = "sd_ble_gap_conn_param_update(CP#2)"]; - * APP<CENTRAL [label = "L2CAP CPU Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #1 Central Accepts "]; - * |||; - * SD<:CENTRAL [label = "L2CAP CPU Response: Accepted", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:CENTRAL [label = "Connection Update Start", textcolor="#000080", linecolor="#000080"]; - * SD:>CENTRAL [label = "Connection Update Complete", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#2}"]; - * |||; - * --- [label = " Variant #2 Central Rejects "]; - * |||; - * SD<:CENTRAL [label = "L2CAP CPU Response: Rejected", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#1}"]; - * --- [label = " Variant #3 Central Ignores "]; - * |||; - * ...; - * |||; - * SD box SD [label="Timeout"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#1}"]; - * @endmsc - * - * @defgroup BLE_GAP_RSSI_FILT_MSC RSSI for connections with event filter - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * --- [label = " Variant #1: Trigger event when a new RSSI is available"]; - * |||; - * APP=>SD [label = "sd_ble_gap_rssi_start(conn_handle, 0, 0)"]; - * APP<SD [label = "sd_ble_gap_rssi_stop()"]; - * APP<SD [label = "sd_ble_gap_rssi_start(conn_handle, 0x05, 0x00)"]; - * APP<SD [label = "sd_ble_gap_rssi_stop()"]; - * APP<SD [label = "sd_ble_gap_rssi_start(conn_handle, 0x05, 0x03)"]; - * APP<SD [label = "sd_ble_gap_rssi_stop()"]; - * APP<SD [label = "sd_ble_gap_rssi_get(conn_handle, p_rssi)"]; - * APP<SD [label = "sd_ble_gap_rssi_start(conn_handle, BLE_GAP_RSSI_THRESHOLD_INVALID, 0x00)"]; - * APP<SD [label = "sd_ble_gap_rssi_get(conn_handle, p_rssi)"]; - * APP<SD [label = "sd_ble_gap_rssi_get(conn_handle, p_rssi)"]; - * APP<SD [label = "sd_ble_gap_rssi_stop()"]; - * APP<SD [label = "sd_ble_gap_authenticate(params)"]; - * APP<CENTRAL [label = "SMP Security Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #1 Central initiates Security Establishment "]; - * |||; - * APP rbox CENTRAL [label="Encryption or Pairing/Bonding initiated by Central"]; - * |||; - * --- [label = " Variant #2 Central ignores "]; - * |||; - * ...; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Timeout, error_src: local}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_LEGACY_MSC Peripheral Legacy Pairing - * @{ - * - * @defgroup BLE_GAP_PERIPH_PAIRING_JW_MSC Pairing: Just Works - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: no_bond, no_mitm, no_io_caps}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: no_bond, no_mitm, no_io_caps, p_keyset: NULL)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD abox CENTRAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with STK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_BONDING_JW_MSC Bonding: Just Works - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, no_mitm, no_io_caps}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: bond, no_mitm, no_io_caps, p_keyset)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD abox CENTRAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with STK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; - * |||; - * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC Bonding: Passkey Entry, Peripheral displays - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, keyboard}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: bond, mitm, display, p_keyset)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=0}"]; - * APP rbox APP [label="Passkey displayed to the user"]; - * |||; - * SD abox CENTRAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with STK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_MITM}"]; - * |||; - * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC Bonding: Passkey Entry, User Inputs on Peripheral or OOB - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, display}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: bond, mitm, keyboard, p_keyset)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_KEY_REQUEST {type}"]; - * APP rbox APP [label="User enters Passkey or data received Out Of Band"]; - * APP=>SD [label = "sd_ble_gap_auth_key_reply(passkey or OOB)"]; - * APP<SD [label = "sd_ble_opt_set(opt_id = BLE_GAP_OPT_PASSKEY, p_opt->p_passkey=passkey)"]; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, keyboard}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: bond, mitm, display, p_keyset)"]; - * - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=0}"]; - * APP rbox APP [label="Passkey displayed to the user"]; - * |||; - * SD abox CENTRAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with STK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_MITM}"]; - * |||; - * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC Pairing failure: Confirm failed - * This occurs if the random value doesn't match, usually because the user entered a wrong pin - * or out of band data was missing. - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: mitm, display}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: mitm, keyboard, p_keyset: NULL)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * SD<:CENTRAL [label = "SMP Pairing Confirm", textcolor="#000080", linecolor="#000080"]; - * SD:>CENTRAL [label = "SMP Pairing Confirm", textcolor="#000080", linecolor="#000080"]; - * SD<:CENTRAL [label = "SMP Pairing Random", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Confirm value, error_src: local}"]; - * SD:>CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @} - * - * @defgroup BLE_GAP_PERIPH_LESC_MSC Peripheral LESC Pairing - * @{ - * - * @defgroup BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC Pairing: Just Works - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, no_bond, no_mitm, no_io_caps}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, no_bond, no_mitm, no_io_caps, p_pk_own)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; - * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * SD abox CENTRAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP abox APP [label="App completes DHKey calculation"]; - * APP=>SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_LESC_BONDING_NC_MSC Bonding: Numeric Comparison - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, display(kbd/yesno)}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, bond, mitm, display(kbd/yesno), keyset with p_pk_own)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; - * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * SD abox CENTRAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=1}"]; - * APP rbox APP [label="Passkey displayed to the user, user compares values"]; - * |||; - * --- [label = " Variant #1 User confirms on both sides "]; - * APP=>SD [label = "sd_ble_gap_auth_key_reply(BLE_GAP_AUTH_KEY_TYPE_PASSKEY, NULL)"]; - * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; - * |||; - * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * --- [label = " Variant #2 User does not confirm locally "]; - * APP=>SD [label = "sd_ble_gap_auth_key_reply(BLE_GAP_AUTH_KEY_TYPE_NONE, NULL)"]; - * APP<CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; - * --- [label = " Variant #3 User does not confirm remotely "]; - * SD<:CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: num comp failure, error_src: remote}"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC Bonding: Passkey Entry, Peripheral Displays - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, keyboard}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, bond, mitm, display, keyset with p_pk_own)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=0}"]; - * APP rbox APP [label="Passkey displayed to the user"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; - * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * --- [label = " Optional keypresses from peer "]; - * SD<:CENTRAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_KEY_PRESSED {type}"]; - * APP abox APP [label="App displays keypress"]; - * SD<:CENTRAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_KEY_PRESSED {type}"]; - * APP abox APP [label="App displays keypress"]; - * |||; - * --- [label = ""]; - * SD abox CENTRAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP abox APP [label="App completes DHKey calculation"]; - * APP=>SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; - * |||; - * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC Bonding: Passkey Entry, User Inputs on Peripheral - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, display}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, bond, mitm, keyboard, keyset with p_pk_own)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_KEY_REQUEST {passkey}"]; - * APP rbox APP [label="User enters Passkey"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; - * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * --- [label = " Optional keypresses sent to peer "]; - * APP=>SD [label = "sd_ble_gap_keypress_notify(type)"]; - * APP<CENTRAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; - * APP=>SD [label = "sd_ble_gap_keypress_notify(type)"]; - * APP<CENTRAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = ""]; - * APP=>SD [label = "sd_ble_gap_auth_key_reply(passkey)"]; - * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; - * |||; - * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC Bonding: Out of Band - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP=>SD [label = "sd_ble_gap_addr_set(addr)"]; - * APP<SD [label = "sd_ble_gap_lesc_oob_data_get(p_pk_own, p_oobd_own)"]; - * APP<SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, bond, oob, keyset with p_pk_own)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk, oobd_req=1}"]; - * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * APP=>SD [label = "sd_ble_gap_lesc_oob_data_set(p_oobd_own, p_oobd_peer)"]; - * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox CENTRAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; - * |||; - * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @} - * - * @defgroup BLE_GAP_PERIPH_PAIRING_KS_OUT_OF_RANGE_MSC Pairing failure: Keysize out of supported range - * This occurs if the min key size offered by the peer is above 16, or max key size below 7. - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Invalid params, error_src: local}"]; - * SD:>CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC GAP Failed Pairing: Keysize too small - * This occurs if the max key size offered by the peer is below the min key size specified by - * the app. - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * SD<:CENTRAL [label = "SMP Pairing Confirm", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Enc key size, error_src: local}"]; - * SD:>CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC Pairing failure: Pairing aborted by the application - * When the application detects that the pairing should not be performed, for example an - * insufficient IO combination, it can use sd_ble_gap_sec_params_reply() to send - * SMP Pairing failed to the peer. - * - * When the stack handles the response from the application it will also validate - * the passkey (SMP_STC_PASSKEY_ENTRY_FAILED). If any error is detected it will be - * reported when sd_ble_gap_sec_params_reply() is called. - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST"]; - * SD abox APP [label="Stack looks for errors", textbgcolor="#7f7fff"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply()"]; - * APP<CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: , error_src: local}"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC Pairing failure: Pairing failed from central - * SMP Pairing Failed may be sent from the central at various times. The application should - * prepare for this and gracefully handle the event. - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * SD<:CENTRAL [label = "SMP Pairing Failed", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: , error_src: remote}"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC Pairing failure: Timeout - * This occurs if the central device doesn't continue the pairing sequence within 30 seconds. - * @msc - * hscale = "2"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS)"]; - * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * --- [ label = "Wait 30 sec" ]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Timeout, error_src: local}"]; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_ENC_MSC Peripheral Encryption Establishment using stored keys - * @msc - * hscale = "1.5"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established"]; - * |||; - * SD<:CENTRAL [label = "LL Encryption Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_INFO_REQUEST {addr, ediv, rand}"]; - * |||; - * --- [label = " Variant #1 App Replies with Keys "]; - * |||; - * APP rbox APP [label = "Load Peripheral Keys"]; - * APP=>SD [label = "sd_ble_gap_sec_info_reply(ediv, rand, LTK)"]; - * APP<CENTRAL [label = "LL Encryption Response", textcolor="#000080", linecolor="#000080"]; - * APP rbox CENTRAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE"]; - * |||; - * --- [label = " Variant #2 App Replies without Keys "]; - * |||; - * APP=>SD [label = "sd_ble_gap_sec_info_reply(NULL)"]; - * APP<CENTRAL [label = "LL Reject Ind: Pin or Key Missing", textcolor="#000080", linecolor="#000080"]; - * APP rbox CENTRAL [label = "Link is NOT encrypted"]; - * |||; - * --- [label = " Variant #3 App Replies with Incorrect Keys "]; - * |||; - * APP rbox APP [label = "Load Incorrect Peripheral Keys"]; - * APP=>SD [label = "sd_ble_gap_sec_info_reply(ediv, rand, LTK)"]; - * APP<CENTRAL [label = "LL Encryption Response", textcolor="#000080", linecolor="#000080"]; - * SD<:CENTRAL [label = "Connection Termination", textcolor="#000080", linecolor="#000080"]; - * APP rbox CENTRAL [label = "Link Terminated"]; - * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {MIC Failure}"]; - * @endmsc - * @} - * - * - * - * @defgroup BLE_GAP_SCAN_MSC Scanning - * @msc - * hscale = "1.5"; - * APP,SD,ADVERTISERS; - * |||; - * APP=>SD [label = "sd_ble_gap_scan_start(params)"]; - * APP<SD [label = "sd_ble_gap_scan_stop()"]; - * APP<SD [label = "sd_ble_gap_connect(params)"]; - * APP<PERIPHERAL [label = "Scanning", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #1 Connection Established "]; - * SD<:>PERIPHERAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED"]; - * |||; - * --- [label = " Variant #2 Connection Establishment Cancelled "]; - * APP=>SD [label = "sd_ble_gap_connect_cancel()"]; - * APP<SD [label = "sd_ble_gap_conn_param_update(CP#2)"]; - * APP<PERIPHERAL [label = "Connection Update Start", textcolor="#000080", linecolor="#000080"]; - * SD<:PERIPHERAL [label = "Connection Update Complete", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#2}"]; - * |||; - * --- [label = " Peripheral Solicited procedure"]; - * |||; - * SD<:PERIPHERAL [label = "L2CAP CPU Request {CP#3}", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST {CP#3}"]; - * |||; - * --- [label = " Variant #1 App Accepts "]; - * APP=>SD [label = "sd_ble_gap_conn_param_update(CP#3)"]; - * APP<PERIPHERAL [label = "L2CAP CPU Response: Accepted", textcolor="#000080", linecolor="#000080"]; - * SD:>PERIPHERAL [label = "Connection Update Start", textcolor="#000080", linecolor="#000080"]; - * SD<:PERIPHERAL [label = "Connection Update Complete", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#3}"]; - * |||; - * --- [label = " Variant #2 App Rejects "]; - * |||; - * APP=>SD [label = "sd_ble_gap_conn_param_update(NULL)"]; - * APP<PERIPHERAL [label = "L2CAP CPU Response: Rejected", textcolor="#000080", linecolor="#000080"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_SEC_MSC Central Security Procedures - * @{ - * - * @defgroup BLE_GAP_CENTRAL_SEC_REQ_MSC Security Request Reception - * @msc - * hscale = "1.5"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Security Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_REQUEST {bond, mitm}"]; - * |||; - * --- [label = " Variant #1 Central initiates Security Establishment "]; - * |||; - * APP=>SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; - * APP<SD [label = "sd_ble_gap_authenticate(params)"]; - * APP<SD [label = "sd_ble_gap_authenticate(NULL)"]; - * APP<PERIPHERAL [label = "SMP Pairing Failed: Pairing Not Supported", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Pairing Not Supp, error_src: local}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_LEGACY_MSC Central Legacy Pairing - * @{ - * - * @defgroup BLE_GAP_CENTRAL_PAIRING_JW_MSC Pairing: Just Works - * @msc - * hscale = "2"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate(no_bond, no_mitm, no_io_caps)"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: no_bond, no_mitm, no_io_caps}"]; - * |||; - * --- [label = " Variant #1 Central Accepts Peripheral parameters "]; - * |||; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_keyset: NULL)"]; - * |||; - * SD abox PERIPHERAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; - * |||; - * APP rbox PERIPHERAL [label = "Encrypted with STK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * |||; - * --- [label = " Variant #2 Central Rejects Peripheral parameters "]; - * |||; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(BLE_GAP_SEC_STATUS_INVALID_PARAMS, own_params: NULL, p_keyset: NULL)"]; - * |||; - * SD:>PERIPHERAL [label = "SMP Pairing Failed", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {FAILURE}"]; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_BONDING_JW_MSC Bonding: Just Works - * @msc - * hscale = "2"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate(bond, no_mitm, no_io_caps)"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, no_mitm, no_io_caps}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_keyset)"]; - * |||; - * SD abox PERIPHERAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; - * |||; - * APP rbox PERIPHERAL [label = "Encrypted with STK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; - * |||; - * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC Bonding: Passkey Entry, Central displays - * @msc - * hscale = "2"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate(bond, mitm, display)"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, keyboard}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_keyset)"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=0}"]; - * APP rbox APP [label="Passkey displayed to the user"]; - * |||; - * SD abox PERIPHERAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; - * |||; - * APP rbox PERIPHERAL [label = "Encrypted with STK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_MITM}"]; - * |||; - * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC Bonding: Passkey Entry, User Inputs on Central or OOB - * @msc - * hscale = "2"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate(bond, mitm, keyboard)"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, display}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_keyset)"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_KEY_REQUEST {type}"]; - * APP rbox APP [label="User enters Passkey or data received Out Of Band"]; - * APP=>SD [label = "sd_ble_gap_auth_key_reply(passkey or OOB)"]; - * APP<SD [label = "sd_ble_gap_authenticate(lesc, no_bond, no_mitm, no_io_caps)"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, no_bond, no_mitm, no_io_caps}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_pk_own)"]; - * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * SD abox PERIPHERAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; - * |||; - * APP abox APP [label="App completes DHKey calculation"]; - * APP=>SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC Bonding: Numeric Comparison - * @msc - * hscale = "2"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate(lesc, bond, mitm, display(kbd/yesno))"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, display(kbd/yesno)}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, keyset with p_pk_own)"]; - * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * SD abox PERIPHERAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=1}"]; - * APP rbox APP [label="Passkey displayed to the user, user compares values"]; - * |||; - * --- [label = " Variant #1 User confirms on both sides "]; - * APP=>SD [label = "sd_ble_gap_auth_key_reply(BLE_GAP_AUTH_KEY_TYPE_PASSKEY, NULL)"]; - * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; - * |||; - * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * --- [label = " Variant #2 User does not confirm locally "]; - * APP=>SD [label = "sd_ble_gap_auth_key_reply(BLE_GAP_AUTH_KEY_TYPE_NONE, NULL)"]; - * APP<PERIPHERAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; - * --- [label = " Variant #3 User does not confirm remotely "]; - * SD<:PERIPHERAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: num comp failure, error_src: remote}"]; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC Bonding: Passkey Entry: Central Displays - * @msc - * hscale = "2"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate(lesc, bond, mitm, display)"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, keyboard}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, keyset with p_pk_own)"]; - * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * --- [label = " Optional keypresses from peer "]; - * SD<:PERIPHERAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_KEY_PRESSED {type}"]; - * APP abox APP [label="App displays keypress"]; - * SD<:PERIPHERAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_KEY_PRESSED {type}"]; - * APP abox APP [label="App displays keypress"]; - * |||; - * --- [label = ""]; - * SD abox PERIPHERAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; - * |||; - * APP abox APP [label="App completes DHKey calculation"]; - * APP=>SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; - * |||; - * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC Bonding: Passkey Entry: User Inputs on Central - * @msc - * hscale = "2"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate(lesc, bond, mitm, keyboard)"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, display}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, keyset with p_pk_own)"]; - * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * --- [label = " Optional keypresses sent to peer "]; - * APP=>SD [label = "sd_ble_gap_keypress_notify(type)"]; - * APP<PERIPHERAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; - * APP=>SD [label = "sd_ble_gap_keypress_notify(type)"]; - * APP<PERIPHERAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = ""]; - * APP=>SD [label = "sd_ble_gap_auth_key_reply(passkey)"]; - * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; - * |||; - * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC Bonding: Out of Band - * @msc - * hscale = "2"; - * APP,SD,PERIPHERAL; - * |||; - * APP=>SD [label = "sd_ble_gap_addr_set(addr)"]; - * APP<SD [label = "sd_ble_gap_lesc_oob_data_get(p_pk_own, p_oobd_own)"]; - * APP<SD [label = "sd_ble_gap_authenticate(lesc, bond, oob)"]; - * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, oob}"]; - * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, keyset with p_pk_own)"]; - * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk, oobd_req=1}"]; - * |||; - * APP abox APP [label="App starts DHKey calculation"]; - * |||; - * APP=>SD [label = "sd_ble_gap_lesc_oob_data_set(p_oobd_own, p_oobd_peer)"]; - * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; - * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; - * |||; - * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; - * |||; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; - * APP rbox APP [label = "Keys stored in keyset"]; - * @endmsc - * @} - * - * - * @defgroup BLE_GAP_INVALID_SMP_PDU_MSC Unexpected Security Packet Reception - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP rbox PEER [label="No pairing in progress"]; - * |||; - * PEER rbox PEER [label="Peer misbehaving"]; - * |||; - * SD<:PEER [label = "SMP Pairing Failed (or other unexpected SMP PDU)", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {PDU_INVALID}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_ENC_MSC Encryption Establishment using stored keys - * @msc - * hscale = "1.5"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; - * APP<PERIPHERAL [label = "LL Encryption Request", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #1 Peripheral replies with keys "]; - * |||; - * PERIPHERAL rbox PERIPHERAL [label = "Peripheral Loads Keys"]; - * SD<:PERIPHERAL [label = "LL Encryption Response", textcolor="#000080", linecolor="#000080"]; - * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE"]; - * |||; - * --- [label = " Variant #2 Peripheral keys missing "]; - * |||; - * PERIPHERAL rbox PERIPHERAL [label = "Peripheral Keys Missing"]; - * SD<:PERIPHERAL [label = "LL Reject Ind: Pin or Key Missing", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE"]; - * APP rbox PERIPHERAL [label = "Link is NOT encrypted"]; - * |||; - * --- [label = " Variant #3 Incorrect peripheral keys "]; - * |||; - * PERIPHERAL rbox PERIPHERAL [label = "Peripheral Loads Incorrect Keys"]; - * SD<:PERIPHERAL [label = "LL Encryption Response", textcolor="#000080", linecolor="#000080"]; - * SD:>PERIPHERAL [label = "Connection Termination", textcolor="#000080", linecolor="#000080"]; - * APP rbox PERIPHERAL [label = "Link Terminated"]; - * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {MIC Failure}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC Central Encryption and Authentication mutual exclusion - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP=>SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; - * APP<PEER [label = "Encryption Start", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP note SD [label = " Encryption in progress, authentication disallowed"]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate()"]; - * APP<SD [label = "sd_ble_gap_conn_param_update()"]; - * APP<PEER [label = "Connection Update Start", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP=>SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; - * APP<SD [label = "sd_ble_gap_authenticate()"]; - * APP<PEER [label = "Encryption Start", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "Encryption Complete", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE "]; - * |||; - * APP=>SD [label = "sd_ble_gap_authenticate()"]; - * APP<SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; - * APP<SD [label = "sd_ble_gap_conn_param_update(conn_handle_3, CP#3)"]; - * APP<PERIPHERALS [label = "Connection Update Start on link #3", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP=>SD [label = "sd_ble_gap_conn_param_update(conn_handle_1, CP#1)"]; - * APP<SD [label = "sd_ble_gap_conn_param_update(conn_handle_2, CP#2)"]; - * APP<PERIPHERALS [label = "L2CAP CPU Response: Accepted", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP note PERIPHERALS [label = " Additional procedure on link #2 fails, since another one is pending"]; - * |||; - * APP=>SD [label = "sd_ble_gap_conn_param_update(conn_handle_2, CP#5)"]; - * APP<PERIPHERALS [label = "Connection Update Start on link #1", textcolor="#000080", linecolor="#000080"]; - * SD<:PERIPHERALS [label = "Connection Update Complete on link #1", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_1, CP#1}"]; - * |||; - * SD:>PERIPHERALS [label = "Connection Update Start on link #2", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP note PERIPHERALS [label = " Peripheral solicited procedure on link #4"]; - * |||; - * SD<:PERIPHERALS [label = "L2CAP CPU Request {CP#4}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST {conn_handle_4, CP#4}"]; - * |||; - * APP=>SD [label = "sd_ble_gap_conn_param_update(conn_handle_4, CP#4)"]; - * APP<PERIPHERALS [label = "L2CAP CPU Response: Accepted", textcolor="#000080", linecolor="#000080"]; - * |||; - * SD<:PERIPHERALS [label = "Connection Update Complete on link #2", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_2, CP#2}"]; - * |||; - * SD:>PERIPHERALS [label = "Connection Update Start on link #4", textcolor="#000080", linecolor="#000080"]; - * SD<:PERIPHERALS [label = "Connection Update Complete on link #4", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_4, CP#4}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_MULTILINK_CTRL_PROC_MSC Central Control Procedure Serialization on multiple links - * @msc - * hscale = "1.5"; - * APP,SD,PERIPHERALS; - * |||; - * APP rbox PERIPHERALS [label="Connection Established with 4 peers, all with conn. params. CP#0"]; - * |||; - * APP note PERIPHERALS [label = " Peripheral solicited procedure on link #2"]; - * |||; - * SD<:PERIPHERALS [label = "L2CAP CPU Request {CP#2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST {conn_handle_2, CP#3}"]; - * |||; - * APP note PERIPHERALS [label = " Encryption procedure on link #3"]; - * |||; - * APP=>SD [label = "sd_ble_gap_encrypt(conn_handle_3, LTK#3)"]; - * APP<PERIPHERALS [label = "Encryption Start on link #3", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP note PERIPHERALS [label = " Connection Update procedure on link #1"]; - * |||; - * APP=>SD [label = "sd_ble_gap_conn_param_update(conn_handle_1, CP#1)"]; - * APP<SD [label = "sd_ble_gap_conn_param_update(conn_handle_2, CP#2)"]; - * APP<PERIPHERALS [label = "L2CAP CPU Response: Accepted", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP note PERIPHERALS [label = " Encryption procedure on link #4"]; - * |||; - * APP=>SD [label = "sd_ble_gap_encrypt(conn_handle_4, LTK#4)"]; - * APP<PERIPHERALS [label = "Encryption Start on link #4", textcolor="#000080", linecolor="#000080"]; - * SD<:PERIPHERALS [label = "Encryption Complete on link #4", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {conn_handle_4}"]; - * |||; - * SD:>PERIPHERALS [label = "Connection Update Start on link #1", textcolor="#000080", linecolor="#000080"]; - * SD<:PERIPHERALS [label = "Connection Update Complete on link #1", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_1, CP#1}"]; - * |||; - * SD:>PERIPHERALS [label = "Connection Update Start on link #2", textcolor="#000080", linecolor="#000080"]; - * SD<:PERIPHERALS [label = "Connection Update Complete on link #2", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_2, CP#2}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_WL_SHARE_MSC Whitelist Sharing - * @msc - * hscale = "1.5"; - * APP,SD; - * |||; - * APP=>SD [label = "sd_ble_gap_adv_data_set(adv, sr)"]; - * APP<SD [label = "sd_ble_gap_whitelist_set(WL#1)"]; - * APP<SD [label = "sd_ble_gap_adv_start(fp = CONNREQ)"]; - * APP<SD [label = "sd_ble_gap_whitelist_set(WL#2)"]; - * APP<SD [label = "sd_ble_gap_scan_start(use_whitelist = 1)"]; - * APP<SD [label = "sd_ble_gap_adv_stop()"]; - * APP<SD [label = "sd_ble_gap_scan_stop()"]; - * APP<SD [label = "sd_ble_gap_whitelist_set(WL#2)"]; - * APP<SD [label = "sd_ble_gap_scan_start(use_whitelist = 1)"]; - * APP<SD [label = "sd_ble_gap_connect(use_whitelist = 1)"]; - * APP<SD [label = "sd_ble_gap_addr_set(addr)"]; - * APP<SD [label = "sd_ble_gap_adv_data_set(adv, sr)"]; - * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_adv_start(params: {p_peer_addr = NULL})"]; - * APP<SCANNERS [label = "ADV packet, Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; - * SD->SCANNERS [label = "ADV packet, Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; - * SD->SCANNERS [label = "ADV packet, Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; - * ...; - * SD box SD [label="Private address timeout"]; - * SD->SCANNERS [label = "ADV packet, Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #2 Advertise with address resolvable by local IRK in device identity list "]; - * |||; - * APP=>SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: {local_irk1}) "]; - * APP<SD [label = "sd_ble_gap_adv_start(params: {p_peer_addr = peer_addr1})"]; - * APP<SCANNERS [label = "ADV packet, Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; - * SD->SCANNERS [label = "ADV packet, Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; - * SD->SCANNERS [label = "ADV packet, Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; - * ...; - * SD box SD [label="Private address timeout"]; - * SD->SCANNERS [label = "ADV packet, Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #3 Advertise with non-resolvable address "]; - * |||; - * APP=>SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: NON_RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_adv_start(params: {p_peer_addr = NULL})"]; - * APP<SCANNERS [label = "ADV packet, Addr = Non-Resolvable1", textcolor="#000080", linecolor="#000080"]; - * SD->SCANNERS [label = "ADV packet, Addr = Non-Resolvable1", textcolor="#000080", linecolor="#000080"]; - * SD->SCANNERS [label = "ADV packet, Addr = Non-Resolvable1", textcolor="#000080", linecolor="#000080"]; - * ...; - * SD box SD [label="Private address timeout"]; - * SD->SCANNERS [label = "ADV packet, Addr = Non-Resolvable2", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GAP_PRIVACY_SCAN_MSC Private Scanning - * @msc - * hscale = "1.5"; - * APP,SD,ADVERTISERS; - * |||; - * APP=>SD [label = "sd_ble_gap_addr_set(addr)"]; - * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_scan_start(params)"]; - * APP<SD [label = "ADV packet", textcolor="#000080", linecolor="#000080"]; - * SD->ADVERTISERS [label = "SCAN REQ packet, Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * ADVERTISERS->SD [label = "SCAN RSP packet", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #2 Active Scan with address resolvable by local IRKs "]; - * |||; - * APP=>SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}, {peer_addr2, peer_irk2}}, pp_local_irks: {local_irk1, local_irk2}) "]; - * APP<SD [label = "sd_ble_gap_scan_start(params)"]; - * APP<SD [label = "ADV packet, Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; - * SD box ADVERTISERS [label = "peer_addr1 is in the device identity list, respond with an address generated from local_irk1"]; - * SD->ADVERTISERS [label = "SCAN REQ packet, Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * ADVERTISERS->SD [label = "SCAN RSP packet, Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; - * |||; - * ...; - * ADVERTISERS->SD [label = "ADV packet, Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; - * SD box ADVERTISERS [label = "Resolvable2 resolved to device identity peer_addr2 in the device identity list, respond with an address generated from local_irk2"]; - * SD->ADVERTISERS [label = "SCAN REQ packet, Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * ADVERTISERS->SD [label = "SCAN RSP packet, Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; - * |||; - * ...; - * ADVERTISERS->SD [label = "ADV packet, Addr = peer_addr3", textcolor="#000080", linecolor="#000080"]; - * SD box ADVERTISERS [label = "peer_addr3 is not in the device identity list, respond with an address generated from device_irk"]; - * SD->ADVERTISERS [label = "SCAN REQ packet, Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * ADVERTISERS->SD [label = "SCAN RSP packet, Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #3 Active Scan with non-resolvable address "]; - * |||; - * APP=>SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: NON_RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_scan_start(params)"]; - * APP<SD [label = "ADV packet", textcolor="#000080", linecolor="#000080"]; - * SD->ADVERTISERS [label = "SCAN REQ packet, Addr = Non-Resolvable", textcolor="#000080", linecolor="#000080"]; - * ADVERTISERS->SD [label = "SCAN RSP packet", textcolor="#000080", linecolor="#000080"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC Scan Private Devices - * @msc - * hscale = "1.5"; - * APP,SD,ADVERTISERS; - * |||; - * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: NULL) "]; - * APP<SD [label = "sd_ble_gap_scan_start(params)"]; - * APP<SD [label = "ADV packet, Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; - * SD note ADVERTISERS [label="Resolvable1 resolved to device identity peer_addr1"]; - * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr1, rssi, data}"]; - * |||; - * ADVERTISERS->SD [label = "ADV packet, Addr = peer_addr2", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr2, rssi, data}"]; - * |||; - * --- [label = " Variant #2 Scan and resolve private devices with whitelist "]; - * |||; - * APP=>SD [label = "sd_ble_gap_whitelist_set({peer_addr1, Resolvable2}) "]; - * APP<SD [label = "sd_ble_gap_scan_start(params)"]; - * APP<SD [label = "ADV packet, Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; - * SD note ADVERTISERS [label="Resolvable1 resolved to device identity peer_addr1 which is in the whitelist"]; - * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr1, rssi, data}"]; - * |||; - * ADVERTISERS->SD [label = "ADV packet, Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; - * SD note ADVERTISERS [label="Resolvable2 did not resolve to a device identity but is in the whitelist"]; - * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {Resolvable2, rssi, data}"]; - * |||; - * ADVERTISERS->SD [label = "ADV packet, Addr = Resolvable3", textcolor="#000080", linecolor="#000080"]; - * SD note ADVERTISERS [label="Resolvable3 is not in the whitelist, no report generated"]; - * |||; - * --- [label = " Variant #3 Scan directed advertisers and resolve initiator address using device IRK"]; - * |||; - * APP=>SD [label = "sd_ble_gap_scan_start()"]; - * APP<SD [label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * ADVERTISERS box SD [label = "Advertiser Address resolved using peer_irk1, Initiator address resolved using device_irk"]; - * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr: peer_addr1"]; - * |||; - * --- [label = " Variant #4 Scan directed advertisers and resolve initiator address using local IRK in device identity list"]; - * |||; - * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: local_irk1) "]; - * APP<SD [label = "sd_ble_gap_scan_start()"]; - * APP<SD [label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * ADVERTISERS box SD [label = "Advertiser Address resolved using peer_irk1, Initiator address resolved using local_irk1"]; - * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr: peer_addr1"]; - * |||; - * --- [label = " Variant #5 Scan directed advertisers with unresolved direct address "]; - * |||; - * APP=>SD [label = "sd_ble_gap_scan_start(params: {adv_dir_report = 1})"]; - * APP<SD [label = "ADV packet, Advertiser Addr = peer_addr2, Initiator Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; - * ADVERTISERS box SD [label = "Resolvable2 could not be resolved, report the unresolved direct address"]; - * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr: peer_addr2, direct_addr: Resolvable2}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC Directed Advertising - * @msc - * hscale = "1.5"; - * APP,SD,INITIATOR; - * |||; - * APP=>SD [label = "sd_ble_gap_addr_set(addr)"]; - * APP<SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: NULL) "]; - * APP<SD [label = "sd_ble_gap_adv_start(params: {p_peer_addr = peer_addr1})"]; - * APP<INITIATOR[label = "ADV packet, Advertiser Addr = addr, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * SD->INITIATOR[label = "ADV packet, Advertiser Addr = addr, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * SD->INITIATOR[label = "ADV packet, Advertiser Addr = addr, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #2 Private directed advertising to private peer using device IRK"]; - * |||; - * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: NULL) "]; - * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_adv_start(params: {p_peer_addr = peer_addr1})"]; - * APP<INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * SD->INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * SD->INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #3 Private directed advertising to private peer using local IRK in device identity list"]; - * |||; - * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: {{local_irk1}}) "]; - * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_adv_start(params: {p_peer_addr = peer_addr1})"]; - * APP<INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * SD->INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * SD->INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #4 Private directed advertising to non-private peer using local IRK in device identity list"]; - * |||; - * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk=0..0}}, pp_local_irks: {{local_irk1}}) "]; - * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; - * APP<SD [label = "sd_ble_gap_adv_start(params: {p_peer_addr = peer_addr1})"]; - * APP<INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; - * SD->INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; - * SD->INITIATOR[label = "ADV packet, Advertiser Addr = Resolvable, Initiator Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_PERIPH_CONN_PRIV_MSC Peripheral Connection Establishment with Private Peer - * @msc - * hscale = "1.5"; - * APP,SD,CENTRAL; - * |||; - * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: NULL) "]; - * APP<CENTRAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED, peer_addr = {peer_addr1, addr_id_peer = 1}"]; - * |||; - * --- [label = " Variant #2 Peer used identity address during connection setup "]; - * |||; - * APP rbox CENTRAL [label="Start Connectable Advertising"]; - * |||; - * SD<:>CENTRAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED, peer_addr = {peer_addr1, addr_id_peer = 0}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_CENTRAL_CONN_PRIV_MSC Central Connection Establishment with Private Peer - * @msc - * hscale = "1.5"; - * APP,SD,PERIPHERAL; - * |||; - * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: NULL) "]; - * APP<SD [label = "sd_ble_gap_connect(peer_addr = {peer_addr1, addr_id_peer = 1})"]; - * APP<PERIPHERAL [label = "Scanning", textcolor="#000080", linecolor="#000080"]; - * --- [label = " Variant #1 Peer used resolvable addresses during connection setup "]; - * |||; - * SD<:>PERIPHERAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED, peer_addr = {peer_addr1, addr_id_peer = 1}"]; - * |||; - * --- [label = " Variant #2 Peer used identity address during connection setup "]; - * |||; - * SD<:>PERIPHERAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED, peer_addr = {peer_addr1, addr_id_peer = 0}"]; - * |||; - * @endmsc - * - * @} - * - * @defgroup BLE_GAP_EVT_PHY_MSC PHY Update Procedure - * @{ - * - * @defgroup BLE_GAP_CENTRAL_PHY_UPDATE Central PHY Update - * @msc - * hscale = "1.5"; - * APP,SD,PERIPHERAL; - * |||; - * APP rbox PERIPHERAL [label="Connection Established. Current TX PHY and RX PHY are both 1Mbit"]; - * |||; - * --- [label = " Variant #1 Initiated by Peripheral - no change in PHY "]; - * SD<=PERIPHERAL [label = "LL_PHY_REQ {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=2Mbit}}"]; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=1Mbit, rx_phys=1Mbit})"]; - * APP<PERIPHERAL [label = "LL_PHY_UPDATE_IND - No change", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=1Mbit, rx_phy=1Mbit}}"]; - * |||; - * --- [label = " Variant #2 Initiated by Peripheral - change of PHY required"]; - * SD<=PERIPHERAL [label = "LL_PHY_REQ {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=2Mbit}}"]; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=2Mbit, rx_phys=2Mbit})"]; - * APP<PERIPHERAL [label = "LL_PHY_UPDATE_IND {M_TO_S_PHY=2Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=2Mbit, rx_phy=2Mbit}}"]; - * |||; - * --- [label = " Variant #3 Initiated by APP, not supported by peer"]; - * |||; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; - * APP<PERIPHERAL [label="LL_PHY_REQ", textcolor="#000080", linecolor="#000080"]; - * SD<=PERIPHERAL [label="LL_UNKNOWN_RSP", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {Status=Not Supported}"]; - * |||; - * --- [label = " Variant #4 Initiated by APP, change required"]; - * |||; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; - * APP<PERIPHERAL [label = "LL_PHY_REQ {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; - * SD<=PERIPHERAL [label = "LL_PHY_RSP {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; - * SD=>PERIPHERAL [label = "LL_PHY_UPDATE_IND {M_TO_S_PHY=2Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=2Mbit, rx_phy=2Mbit}}"]; - * |||; - * --- [label = " Variant #5 Initiated by Peripheral - APP has no preferences for TX direction"]; - * SD<=PERIPHERAL [label = "LL_PHY_REQ {tx_phys=2Mbit, rx_phys=1Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=1Mbit}}"]; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=BLE_GAP_PHY_AUTO, rx_phys=2Mbit})"]; - * APP<PERIPHERAL [label = "LL_PHY_UPDATE_IND {M_TO_S_PHY=1Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=1Mbit, rx_phy=2Mbit}}"]; - * |||; - * --- [label = " Variant #6 Initiated by APP, peer responding with invalid parameters"]; - * |||; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; - * APP<PERIPHERAL [label="LL_PHY_REQ {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; - * SD<=PERIPHERAL [label="LL_PHY_RSP {tx_phys=0x00, rx_phys=0x00}", textcolor="#000080", linecolor="#000080"]; - * SD=>PERIPHERAL [label="LL_UNKNOWN_RSP", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {Status=Invalid LMP Parameters}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GAP_PERIPHERAL_PHY_UPDATE Peripheral PHY Update - * @msc - * hscale = "1.5"; - * APP,SD,CENTRAL; - * |||; - * APP rbox CENTRAL [label="Connection Established. Current TX PHY and RX PHY are both 1Mbit"]; - * |||; - * --- [label = " Variant #1 Initiated by Central - no change in PHY "]; - * SD<=CENTRAL [label = "LL_PHY_REQ {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=2Mbit}}"]; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=1Mbit, rx_phys=1Mbit})"]; - * APP<CENTRAL [label = "LL_PHY_RSP {tx_phys=1Mbit, rx_phys=1Mbit}", textcolor="#000080", linecolor="#000080"]; - * SD<=CENTRAL [label = "LL_PHY_UPDATE_IND - No change", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=1Mbit, rx_phy=1Mbit}}"]; - * |||; - * --- [label = " Variant #2 Initiated by Central - change of PHY required"]; - * SD<=CENTRAL [label = "LL_PHY_REQ {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=2Mbit}}"]; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=2Mbit, rx_phys=2Mbit})"]; - * APP<CENTRAL [label = "LL_PHY_RSP {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * SD<=CENTRAL [label = "LL_PHY_UPDATE_IND {M_TO_S_PHY=2Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=2Mbit, rx_phy=2Mbit}}"]; - * |||; - * --- [label = " Variant #3 Initiated by APP, not supported by peer"]; - * |||; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; - * APP<CENTRAL [label="LL_PHY_REQ", textcolor="#000080", linecolor="#000080"]; - * SD<=CENTRAL [label="LL_UNKNOWN_RSP", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {Status=Not Supported}"]; - * |||; - * --- [label = " Variant #4 Initiated by APP, change required"]; - * |||; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; - * APP<CENTRAL [label="LL_PHY_REQ {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; - * SD<=CENTRAL [label="LL_PHY_UPDATE_IND {M_TO_S_PHY=2Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=2Mbit, rx_phy=2Mbit}}"]; - * |||; - * --- [label = " Variant #5 Initiated by Central - APP has no preferences for TX direction"]; - * SD<=CENTRAL [label = "LL_PHY_REQ {tx_phys=2Mbit, rx_phys=1Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=1Mbit}}"]; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=BLE_GAP_PHY_AUTO, rx_phys=2Mbit})"]; - * APP<CENTRAL [label = "LL_PHY_RSP {tx_phys=ALL_PHY, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * SD<=CENTRAL [label = "LL_PHY_UPDATE_IND {M_TO_S_PHY=2Mbit, S_TO_M_PHY=1Mbit}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=1Mbit, rx_phy=2Mbit}}"]; - * |||; - * --- [label = " Variant #6 Collision between self-initiated PHY Update and peer initiated Channel Map Update procedures"]; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=2Mbit, rx_phys=2Mbit})"]; - * APP<CENTRAL [label = "LL_PHY_REQ {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; - * SD<=CENTRAL [label = "LL_REJECT_EXT_IND {ErrorCode=Different Transaction Collision}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Different Transaction Collision, {tx_phy=1Mbit, rx_phy=1Mbit}}"]; - * |||; - * --- [label = " Variant #7 Initiated by APP, peer responding with invalid parameters"]; - * |||; - * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; - * APP<CENTRAL [label="LL_PHY_REQ {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; - * SD<=CENTRAL [label="LL_PHY_UPDATE_IND {M_TO_S_PHY=(1Mbit|2Mbit), S_TO_M_PHY=(1Mbit|2Mbit)", textcolor="#000080", linecolor="#000080"]; - * SD=>CENTRAL [label="LL_UNKNOWN_RSP", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {Status=Invalid LMP Parameters}"]; - * |||; - * @endmsc - * - * @} - - * @defgroup BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC Data Length Update Procedure - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Self initiated, automatic parameters "]; - * |||; - * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; - * |||; - * ...; - * |||; - * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, NULL, NULL)"]; - * APP<PEER [label = "LL Length Request {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "LL Length Response {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; - * |||; - * ...; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Self initiated, application set parameters "]; - * |||; - * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; - * |||; - * ...; - * |||; - * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, NULL)"]; - * APP<PEER [label = "LL Length Request {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "LL Length Response {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; - * |||; - * ...; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Peer initiated, automatic parameters "]; - * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; - * |||; - * ...; - * |||; - * SD<:PEER [label = "LL Length Request {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST {.peer_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; - * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, NULL, NULL)"]; - * APP<PEER [label = "LL Length Response {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; - * |||; - * ...; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Peer initiated, application set parameters"]; - * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; - * |||; - * ...; - * |||; - * SD<:PEER [label = "LL Length Request {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST {.peer_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; - * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, NULL)"]; - * APP<PEER [label = "LL Length Response {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; - * |||; - * ...; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Using the limitation out parameter to adjust Link Layer Data Channel PDU size, memory limited "]; - * |||; - * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; - * |||; - * ...; - * |||; - * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, &limitation)"]; - * APP<SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=200, .max_rx_octets=200, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, &limitation)"]; - * APP<PEER [label = "LL Length Request {tx=200, rx=200}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "LL Length Response {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=200, .max_rx_octets=200, .max_tx_time_us=1712, .max_rx_time_us=1712}}"]; - * |||; - * ...; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Using the limitation out parameter to adjust Link Layer Data Channel PDU size, time limited "]; - * |||; - * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; - * |||; - * ...; - * |||; - * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, &limitation)"]; - * APP<SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251-178=73, .max_rx_octets=251-178=73, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, &limitation)"]; - * APP<PEER [label = "LL Length Request {tx=73, rx=73}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "LL Length Response {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=73, .max_rx_octets=73, .max_tx_time_us=696, .max_rx_time_us=696}}"]; - * @endmsc - * @} - * - * @} - * @} - */ - -/** - * @addtogroup BLE_GATTC - * @{ - * @defgroup BLE_GATTC_MSC Message Sequence Charts - * @{ - * @defgroup BLE_GATTC_PRIM_SRVC_DISC_MSC GATTC Primary Service Discovery - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Variant #1 Discover All Services "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle, NULL)"]; - * APP<PEER [label = "ATT Read By Group Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read By Group Type Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {SUCCESS, services}"]; - * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle + N, NULL)"]; - * APP<PEER [label = "ATT Read By Group Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read By Group Type Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {SUCCESS, services}"]; - * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle + N + M, NULL)"]; - * APP<PEER [label = "ATT Read By Group Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; - * |||; - * --- [label = " Variant #2 Discover a Specific Service "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle, uuid)"]; - * APP<PEER [label = "ATT Find By Type Value Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Find By Type Value Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {SUCCESS, services}"]; - * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle + N, uuid)"]; - * APP<PEER [label = "ATT Find By Type Value Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Find By Type Value Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {SUCCESS, services}"]; - * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle + N + M, uuid)"]; - * APP<PEER [label = "ATT Find By Type Value Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; - * @endmsc - * - * @defgroup BLE_GATTC_REL_DISC_MSC GATTC Relationship Discovery - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_relationships_discover(handle_range)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_REL_DISC_RSP {SUCCESS, includes}"]; - * APP=>SD [label = "sd_ble_gattc_relationships_discover(handle_range + N)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_REL_DISC_RSP {SUCCESS, includes}"]; - * APP=>SD [label = "sd_ble_gattc_relationships_discover(handle_range + N + M)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_REL_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; - * @endmsc - * - * @defgroup BLE_GATTC_CHAR_DISC_MSC GATTC Characteristic Discovery - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_characteristics_discover(handle_range)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_DISC_RSP {SUCCESS, chars}"]; - * APP=>SD [label = "sd_ble_gattc_characteristics_discover(handle_range + N)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_DISC_RSP {SUCCESS, chars}"]; - * APP=>SD [label = "sd_ble_gattc_characteristics_discover(handle_range + N + M)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; - * @endmsc - * - * @defgroup BLE_GATTC_DESC_DISC_MSC GATTC Descriptor Discovery - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_descriptors_discover(handle_range)"]; - * APP<PEER [label = "ATT Find Information Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Find Information Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_DESC_DISC_RSP {SUCCESS, descs}"]; - * APP=>SD [label = "sd_ble_gattc_descriptors_discover(handle_range + N)"]; - * APP<PEER [label = "ATT Find Information Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Find Information Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_DESC_DISC_RSP {SUCCESS, descs}"]; - * APP=>SD [label = "sd_ble_gattc_descriptors_discover(handle_range + N + M)"]; - * APP<PEER [label = "ATT Find Information Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_DESC_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; - * @endmsc - * - * @defgroup BLE_GATTC_READ_UUID_MSC GATTC Read Characteristic Value by UUID - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_char_value_by_uuid_read(uuid, handle_range)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP {SUCCESS, char_values}"]; - * APP=>SD [label = "sd_ble_gattc_char_value_by_uuid_read(uuid, handle_range + N)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP {SUCCESS, char_values}"]; - * APP=>SD [label = "sd_ble_gattc_char_value_by_uuid_read(uuid, handle_range + N + M)"]; - * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP {ATTRIBUTE_NOT_FOUND}"]; - * @endmsc - * - * @defgroup BLE_GATTC_VALUE_READ_MSC GATTC Characteristic or Descriptor Value Read - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Variant #1 offset == 0 "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_read(handle, 0)"]; - * APP<PEER [label = "ATT Read Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_READ_RSP {SUCCESS, value}"]; - * |||; - * --- [label = " Variant #2 offset != 0 "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_read(handle, offset)"]; - * APP<PEER [label = "ATT Read Blob Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read Blob Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_READ_RSP {SUCCESS, value}"]; - * APP=>SD [label = "sd_ble_gattc_read(handle, offset + N)"]; - * APP<PEER [label = "ATT Read Blob Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read Blob Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_READ_RSP {SUCCESS, value}"]; - * APP=>SD [label = "sd_ble_gattc_read(handle, offset + N + M + 1)"]; - * APP<PEER [label = "ATT Read Blob Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Error Response: Invalid Offset", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_READ_RSP {INVALID_OFFSET}"]; - * @endmsc - * - * @defgroup BLE_GATTC_READ_MULT_MSC GATTC Read Multiple Characteristic Values - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Variant #1 Successful request "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_char_values_read(handles)"]; - * APP<PEER [label = "ATT Read Multiple Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Read Multiple Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VALS_READ_RSP {SUCCESS, char_values}"]; - * |||; - * --- [label = " Variant #2 Failing request (invalid handle) "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_char_values_read(handles)"]; - * APP<PEER [label = "ATT Read Multiple Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Error Response: Invalid Handle", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VALS_READ_RSP {INVALID_HANDLE, error_handle=}"]; - * @endmsc - * - * @defgroup BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC GATTC Characteristic Value Write Without Response - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * --- [label = " Variant #1 App does not keep track of the available queue element count for writes without responses "]; - * APP note PEER [label = " This variant makes it possible for APP to transmit writes without responses without keeping track of the available queue element count. However, successful queuing of writes without responses cannot be guaranteed. "]; - * |||; - * APP=>SD [label = "sd_ble_enable()"]; - * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_1)"]; - * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_2)"]; - * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_3)"]; - * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_4)"]; - * APP<PEER [label = "ATT Write Command {value_1}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Write Command {value_2}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Write Command {value_4}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE {SUCCESS, 3}"]; - * |||; - * --- [label = " Variant #2 App keeps track of the available queue element count for writes without responses "]; - * APP note PEER [label = " This variant makes it possible for APP to know when successful queuing of writes without responses is guaranteed. "]; - * |||; - * APP=>SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATTC, gattc_conn_cfg.write_cmd_tx_queue_size = 2)"]; - * APP<SD [label = "sd_ble_enable()"]; - * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_1)"]; - * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_2)"]; - * APP<PEER [label = "ATT Write Command {value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE {SUCCESS, 1}"]; - * APP abox APP [label="available_queue_element_count += 1"]; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_3)"]; - * APP<PEER [label = "ATT Write Command {value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE {SUCCESS, 1}"]; - * APP abox APP [label="available_queue_element_count += 1"]; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_4)"]; - * APP<PEER [label = "ATT Write Command {value_3}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Write Command {value_4}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE {SUCCESS, 2}"]; - * APP abox APP [label="available_queue_element_count += 2"]; - * @endmsc - * - * @defgroup BLE_GATTC_VALUE_WRITE_MSC GATTC Characteristic or Descriptor Value Write - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_REQ, handle, value)"]; - * APP<PEER [label = "ATT Write Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_WRITE_REQ, SUCCESS}"]; - * @endmsc - * - * @defgroup BLE_GATTC_VALUE_LONG_WRITE_MSC GATTC Characteristic or Descriptor Value Long Write - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_PREP_WRITE_REQ, handle, offset_1, value_1)"]; - * APP<PEER [label = "ATT Prepare Write Request {handle, offset_1, value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Response {handle, offset_1, value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_PREP_WRITE_REQ, SUCCESS, value_1}"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_PREP_WRITE_REQ, handle, offset_2, value_2)"]; - * APP<PEER [label = "ATT Prepare Write Request {handle, offset_2, value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Response {handle, offset_2, value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_PREP_WRITE_REQ, SUCCESS, value_2}"]; - * |||; - * ...; - * |||; - * --- [label = " Variant #1 App executes the Long Write procedure "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_EXEC_WRITE_REQ, PREPARED_WRITE)"]; - * APP<PEER [label = "ATT Execute Write Request: flags = 0x01", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_EXEC_WRITE_REQ, SUCCESS}"]; - * |||; - * --- [label = " Variant #2 App cancels the Long Write procedure "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_EXEC_WRITE_REQ, PREPARED_CANCEL)"]; - * APP<PEER [label = "ATT Execute Write Request: flags = 0x00", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_EXEC_WRITE_REQ, SUCCESS}"]; - * @endmsc - * - * @defgroup BLE_GATTC_VALUE_RELIABLE_WRITE_MSC GATTC Characteristic or Descriptor Value Reliable Write - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_PREP_WRITE_REQ, handle_1, offset, value_1)"]; - * APP<PEER [label = "ATT Prepare Write Request {handle_1, offset, value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Response {handle_1, offset, value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_PREP_WRITE_REQ, SUCCESS, value_1}"]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_PREP_WRITE_REQ, handle_2, offset, value_2)"]; - * APP<PEER [label = "ATT Prepare Write Request {handle_2, offset, value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Response {handle_2, offset, value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_PREP_WRITE_REQ, SUCCESS, value_2}"]; - * |||; - * ...; - * |||; - * --- [label = " Variant #1 App executes the Reliable Write procedure "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_EXEC_WRITE_REQ, PREPARED_WRITE)"]; - * APP<PEER [label = "ATT Execute Write Request: flags = 0x01", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_EXEC_WRITE_REQ, SUCCESS}"]; - * |||; - * --- [label = " Variant #2 App cancels the Reliable Write procedure "]; - * |||; - * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_EXEC_WRITE_REQ, PREPARED_CANCEL)"]; - * APP<PEER [label = "ATT Execute Write Request: flags = 0x00", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_EXEC_WRITE_REQ, SUCCESS}"]; - * @endmsc - * - * @defgroup BLE_GATTC_HVI_MSC GATTC Handle Value Indication - * GATTC Handle Value Indication MSC - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD<:PEER [label = "ATT Handle Value Indication", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_HVX {INDICATION, data}"]; - * APP=>SD [label = "sd_ble_gattc_hv_confirm(handle)"]; - * APP<PEER [label = "ATT Handle Value Confirmation", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTC_HVN_MSC GATTC Handle Value Notification - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD<:PEER [label = "ATT Handle Value Notification", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTC_EVT_HVX {NOTIFICATION, data}"]; - * @endmsc - * - * @defgroup BLE_GATTC_TIMEOUT_MSC GATTC Timeout - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP rbox PEER [label="Any GATTC API used"]; - * SD:>PEER [label = "ATT Packet", textcolor="#000080", linecolor="#000080"]; - * APP note PEER [label = "No Response from Peer"]; - * |||; - * ...; - * |||; - * SD box SD [label="Timeout"]; - * APP<<=SD [label = "BLE_GATTC_EVT_TIMEOUT {source}"]; - * APP rbox PEER [label="No additional ATT Traffic Allowed", textbgcolour="#ff7f7f"]; - * APP=>SD [label = "Any API call"]; - * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATT, gatt_conn_cfg.att_mtu=100)"]; - * APP<SD [label = "sd_ble_enable()"]; - * APP<SD [label = "sd_ble_gattc_exchange_mtu_request(conn_handle, client_rx_mtu=80)"]; - * APP<PEER [label = "ATT Exchange MTU Request {client_rx_mtu=80}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Exchange MTU Response {server_rx_mtu=75}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="att_mtu=75"]; - * APP<<=SD [label = "BLE_GATTC_EVT_EXCHANGE_MTU_RSP {SUCCESS, server_rx_mtu=75}"]; - * @endmsc - * - * @} - * @} - */ - -/** - * @addtogroup BLE_GATTS - * @{ - * @defgroup BLE_GATTS_MSC Message Sequence Charts - * @{ - * @defgroup BLE_GATTS_ATT_TABLE_POP_MSC GATTS ATT Table Population - * @msc - * hscale = "1.5"; - * APP,SD; - * |||; - * APP=>SD [label = "sd_ble_gatts_service_add(uuid#1)"]; - * APP<SD [label = "sd_ble_gatts_characteristic_add(handle_srvc#1, char_md, value)"]; - * APP<SD [label = "sd_ble_gatts_descriptor_add(handle_char#1, value)"]; - * APP<SD [label = "sd_ble_gatts_descriptor_add(handle_char#1, value)"]; - * APP<SD [label = "sd_ble_gatts_characteristic_add(handle_srvc#1, char_md, value)"]; - * APP<SD [label = "sd_ble_gatts_descriptor_add(handle_char#2, value)"]; - * APP<SD [label = "sd_ble_gatts_service_add(uuid#2)"]; - * APP<SD [label = "sd_ble_gatts_include_add(handle_srvc#2, handle_srvc#1)"]; - * APP<PEER [label = "ATT Read Response", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTS_WRITE_REQ_NO_AUTH_MSC GATTS Write Request without Authorization - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Value in ATT Table: current_value"]; - * SD<:PEER [label = "ATT Write Request {peer_value}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Write Response", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Value in ATT Table: peer_value"]; - * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {WRITE_REQ, auth_required=0, peer_value}"]; - * @endmsc - * - * @defgroup BLE_GATTS_WRITE_CMD_NO_AUTH_MSC GATTS Write Command Without Authorization - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Value in ATT Table: current_value"]; - * SD<:PEER [label = "ATT Write Command {peer_value}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Value in ATT Table: peer_value"]; - * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {WRITE_CMD, auth_required=0, peer_value}"]; - * @endmsc - * - * @defgroup BLE_GATTS_WRITE_CMD_AUTH_MSC GATTS Write Command With Authorization - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Value in ATT Table: current_value"]; - * SD<:PEER [label = "ATT Write Command {peer_value}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Value in ATT Table: current_value"]; - * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {WRITE_CMD, auth_required=1, peer_value}"]; - * --- [label = " Variant #1 App Authorizes "]; - * APP=>SD [label = "sd_ble_gatts_value_set(peer_value)"]; - * APP<SD [label = "sd_ble_gatts_value_set(app_value)"]; - * APP<SD [label = "sd_ble_gatts_rw_authorize_reply(SUCCESS, app_value)"]; - * APP<PEER [label = "ATT Read Response {app_value}", textcolor="#000080", linecolor="#000080"]; - * --- [label = " Variant #2 App Disallows "]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(READ_NOT_PERMITTED)"]; - * APP<PEER [label = "ATT Error Response", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTS_WRITE_REQ_AUTH_MSC GATTS Write Request with Authorization - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Value in ATT Table: current_value"]; - * SD<:PEER [label = "ATT Write Request {peer_value}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, peer_value}"]; - * --- [label = " Variant #1 App Authorizes "]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(SUCCESS, peer_value)"]; - * APP<PEER [label = "ATT Write Response", textcolor="#000080", linecolor="#000080"]; - * --- [label = " Variant #2 App Authorizes but changes value "]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(SUCCESS, app_value)"]; - * APP<PEER [label = "ATT Write Response", textcolor="#000080", linecolor="#000080"]; - * --- [label = " Variant #3 App Disallows "]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE_NOT_PERMITTED)"]; - * APP<PEER [label = "ATT Error Response", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC GATTS Queued Writes: Stack handled, no attributes require authorization - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; - * APP=>SD [label = "sd_ble_user_mem_reply {user_mem_block}"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #1 Attribute Values validation passed "]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: peer_value_2"]; - * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {EXEC_WRITE_REQ_NOW}"]; - * APP rbox APP [label="App parses the memory it provided"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; - * |||; - * --- [label = " Variant #2 Attribute Values validation failed "]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD:>PEER [label = "ATT Error Response {Invalid Value Length / Offset}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; - * |||; - * @endmsc - * - * @defgroup BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC GATTS Queued Writes: Stack handled, one or more attributes require authorization - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; - * APP=>SD [label = "sd_ble_user_mem_reply {user_mem_block}"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; - * |||; - * --- [label = " Variant #1 App Authorizes both Prepare Write and Execute Write"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; - * APP rbox APP [label="App parses the memory it provided"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: peer_value_2"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; - * |||; - * --- [label = " Variant #2 App Disallows Prepare Write and Authorizes Execute Write "]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, INSUF_AUTHORIZATION)"]; - * SD:>PEER [label = "ATT Error Response {Insufficient Authorization}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; - * APP rbox APP [label="App parses the memory it provided"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: current_value_2"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; - * |||; - * --- [label = " Variant #3 App Authorizes Prepare Write and Disallows Execute Write "]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; - * APP rbox APP [label="App parses the memory it provided"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, APP_ERROR_CODE)"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD:>PEER [label = "ATT Error Response {APP_ERROR_CODE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; - * @endmsc - * - * @defgroup BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC GATTS Queued Writes: App handled, no attributes require authorization - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; - * APP=>SD [label = "sd_ble_user_mem_reply {NULL}"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_1, offset_1, peer_value_1}"]; - * APP rbox APP [label="App queues {handle_1, offset_1, peer_value_1}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_1, offset_1, peer_value_1)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; - * APP rbox APP [label="App queues {handle_2, offset_2, peer_value_2}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_2, offset_2, peer_value_2)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; - * |||; - * --- [label = " Variant #1 Attribute values in stack memory (VLOC_STACK), attribute values validation passed "]; - * APP=>SD [label = "sd_ble_gatts_value_set {handle_1, offset_1, peer_value_1}"]; - * APP<SD [label = "sd_ble_gatts_value_set {handle_2, offset_2, peer_value_2}"]; - * APP<SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #2 Attribute values in user memory (VLOC_USER), attribute values validation passed "]; - * APP rbox APP [label="Application traverses its queue and executes the write operations (memcpy)"]; - * APP rbox APP [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: peer_value_2"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #3 Attribute values validation failed "]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, INVALID_OFFSET)"]; - * APP rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD:>PEER [label = "ATT Error Response {Invalid Offset}", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC GATTS Queued Writes: App handled, one or more attributes require authorization - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP rbox APP [label="Values in ATT Table in user memory (VLOC_USER):\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; - * APP=>SD [label = "sd_ble_user_mem_reply {NULL}"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_1, offset_1, peer_value_1}"]; - * APP rbox APP [label="App queues {handle_1, offset_1, peer_value_1}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_1, offset_1, peer_value_1)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; - * |||; - * --- [label = " Variant #1 App Authorizes both Prepare Write and Execute Write"]; - * APP rbox APP [label="App queues {handle_2, offset_2, peer_value_2}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_2, offset_2, peer_value_2)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; - * APP rbox APP [label="Application traverses its queue and executes the write operations (memcpy)"]; - * APP rbox APP [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: peer_value_2"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #2 App Disallows Prepare Write and Authorizes Execute Write "]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, INSUF_AUTHORIZATION)"]; - * SD:>PEER [label = "ATT Error Response {Insufficient Authorization}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; - * APP rbox APP [label="Application traverses its queue and executes the write operations (memcpy)"]; - * APP rbox APP [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: current_value_2"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #3 App Authorizes Prepare Write and Disallows Execute Write "]; - * APP rbox APP [label="App queues {handle_2, offset_2, peer_value_2}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_2, offset_2, peer_value_2)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, APP_ERROR_CODE)"]; - * APP rbox APP [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD:>PEER [label = "ATT Error Response {APP_ERROR_CODE}", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC GATTS Queued Writes: Peer cancels operation - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; - * |||; - * --- [label = " Variant #1 Stack handled "]; - * APP=>SD [label = "sd_ble_user_mem_reply {user_mem_block}"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {CANCEL}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; - * |||; - * --- [label = " Variant #2 App handled "]; - * APP=>SD [label = "sd_ble_user_mem_reply {NULL}"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_1, offset_1, peer_value_1}"]; - * APP rbox APP [label="App queues {handle_1, offset_1, peer_value_1}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_1, offset_1, peer_value_1)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; - * APP rbox APP [label="App queues {handle_2, offset_2, peer_value_2}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_2, offset_2, peer_value_2)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {CANCEL}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_CANCEL}"]; - * APP rbox APP [label="App erases queue"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * @endmsc - * - * @defgroup BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC GATTS Queued Writes: Prepare Queue Full - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; - * |||; - * --- [label = " Variant #1 Stack handled "]; - * APP=>SD [label = "sd_ble_user_mem_reply {user_mem_block}"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Error Response {Prepare Queue Full}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: current_value_2"]; - * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {EXEC_WRITE_REQ_NOW}"]; - * APP rbox APP [label="App parses the memory it provided"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; - * |||; - * --- [label = " Variant #2 App handled "]; - * APP=>SD [label = "sd_ble_user_mem_reply {NULL}"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_1, offset_1, peer_value_1}"]; - * APP rbox APP [label="App queues {handle_1, offset_1, peer_value_1}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_1, offset_1, peer_value_1)"]; - * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; - * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, PREPARE_QUEUE_FULL)"]; - * SD:>PEER [label = "ATT Error Response {Prepare Queue Full}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; - * APP=>SD [label = "sd_ble_gatts_value_set {handle_1, offset_1, peer_value_1}"]; - * APP<SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: current_value_2"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTS_QUEUED_WRITE_EXECUTE_WITHOUT_PREPARE_MSC GATTS Queued Writes: Execute Write without Prepare Write - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * |||; - * SD rbox SD [label="No ATT Prepare Write Request has been received by SD"]; - * |||; - * --- [label = " Variant #1 Write cancelled "]; - * SD<:PEER [label = "ATT Execute Write Request {CANCEL}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {EXEC_WRITE_REQ_CANCEL}"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * --- [label = " Variant #2 Write now "]; - * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; - * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {EXEC_WRITE_REQ_NOW}"]; - * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTS_MTU_EXCHANGE GATTS ATT_MTU Exchange - * @msc - * hscale = "2"; - * APP,SD,PEER; - * |||; - * APP=>SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATT, gatt_conn_cfg.att_mtu=100)"]; - * APP<SD [label = "sd_ble_enable()"]; - * APP<SD [label = "sd_ble_gatts_exchange_mtu_reply(conn_handle, server_rx_mtu=75)"]; - * APP<PEER [label = "ATT Exchange MTU Response {server_rx_mtu=75}", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="att_mtu=75"]; - * @endmsc - * - * @defgroup BLE_GATTS_HVI_MSC GATTS Handle Value Indication - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP rbox PEER [label="Indications Enabled in CCCD"]; - * |||; - * SD rbox SD [label="Value in ATT Table: current_value"]; - * APP=>SD [label = "sd_ble_gatts_hvx(INDICATION, app_value)"]; - * APP<PEER [label = "ATT Handle Value Indication {app_value}", textcolor="#000080", linecolor="#000080"]; - * --- [label = " Variant #1 Peer Confirms "]; - * SD<:PEER [label = "ATT Handle Value Confirmation", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_HVC"]; - * --- [label = " Variant #2 Peer Ignores "]; - * |||; - * ...; - * |||; - * SD box SD [label="Timeout"]; - * APP<<=SD [label = "BLE_GATTS_EVT_TIMEOUT"]; - * @endmsc - * - * @defgroup BLE_GATTS_HVN_MSC GATTS Handle Value Notification - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * --- [label = " Variant #1 App does not keep track of the available queue element count for notifications "]; - * APP note PEER [label = " This variant makes it possible for APP to transmit notifications without keeping track of the available queue element count. However, successful queuing of notifications cannot be guaranteed. "]; - * |||; - * APP=>SD [label = "sd_ble_enable()"]; - * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_1)"]; - * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_2)"]; - * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_3)"]; - * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_4)"]; - * APP<PEER [label = "ATT Handle Value Notification {app_value_1}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Handle Value Notification {app_value_2}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Handle Value Notification {app_value_4}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_HVN_TX_COMPLETE {3}"]; - * |||; - * --- [label = " Variant #2 App keeps track of the available queue element count for notifications "]; - * APP note PEER [label = " This variant makes it possible for APP to know when successful queuing of notifications is guaranteed. "]; - * |||; - * APP=>SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATTS, gatts_conn_cfg.hvn_tx_queue_size=2)"]; - * APP<SD [label = "sd_ble_enable()"]; - * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_1)"]; - * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_2)"]; - * APP<PEER [label = "ATT Handle Value Notification {app_value_1}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_HVN_TX_COMPLETE {1}"]; - * APP abox APP [label="available_queue_element_count += 1"]; - * APP=>SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_3)"]; - * APP<PEER [label = "ATT Handle Value Notification {app_value_2}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_HVN_TX_COMPLETE {1}"]; - * APP abox APP [label="available_queue_element_count += 1"]; - * APP=>SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_4)"]; - * APP<PEER [label = "ATT Handle Value Notification {app_value_3}", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "ATT Handle Value Notification {app_value_4}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_HVN_TX_COMPLETE {2}"]; - * APP abox APP [label="available_queue_element_count += 2"]; - * @endmsc - * - * @defgroup BLE_GATTS_HVX_DISABLED_MSC GATTS Handle Value Indication or Notification disabled - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP rbox PEER [label="Indications and Notifications Disabled in CCCD"]; - * |||; - * SD rbox SD [label="Value in ATT Table: current_value"]; - * APP=>SD [label = "sd_ble_gatts_hvx(INDICATION or NOTIFICATION, app_value)"]; - * APP<SD [label = "sd_ble_gatts_hvx(INDICATION or NOTIFICATION, app_value)"]; - * APP<SD [label = "sd_ble_gatts_sys_attr_set()"]; - * APP<SD [label = "sd_ble_gatts_service_changed(N, M)"]; - * APP<PEER [label = "ATT Handle Value Indication {N, M}", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "ATT Handle Value Confirmation", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_SC_CONFIRM"]; - * |||; - * SD rbox PEER [label="Service Discovery"]; - * @endmsc - * - * @defgroup BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC GATTS System Attributes Handling: Unknown Peer - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established with an Unknown Peer"]; - * |||; - * SD<:PEER [label = "ATT Read Request {sys_attr_handle}", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_GATTS_EVT_SYS_ATTR_MISSING"]; - * APP=>SD [label = "sd_ble_gatts_sys_attr_set(NULL)"]; - * APP<PEER [label = "ATT Read Response {sys_attr_value}", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * - * @defgroup BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC GATTS System Attributes Handling: Bonded Peer - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established with a Bonded Peer"]; - * |||; - * APP rbox PEER [label="ATT Traffic"]; - * |||; - * APP rbox PEER [label="Connection Terminated"]; - * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {reason}"]; - * |||; - * APP=>SD [label = "sd_ble_gatts_sys_attr_get()"]; - * APP<SD [label = "sd_ble_gatts_sys_attr_set(sys_attr_data)"]; - * APP<PEER [label = "ATT Read Response {sys_attr_value}", textcolor="#000080", linecolor="#000080"]; - * @endmsc - * @} - * - * @addtogroup BLE_GATTS_QUEUED_WRITES_USER_MEM User memory layout for Queued Writes - * @{ - * The following table shows the memory layout used by the SoftDevice to queue a Queued Write operation (Prepare Write ATT packet) in user memory: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Queued Write
ParameterSize (octets)Description
Handle2Attribute Handle
Offset2Value Offset
Length2Value Length
ValueLengthAttribute Value
- * - * The application can parse the array of Queued Write instances at any time, but it is recommended to do so whenever an Execute Write ATT packet - * has been received over the air. See the GATT Server Queued Writes MSCs for more details. - * The array will be terminated by an Queued Write instance with its handle set to @ref BLE_GATT_HANDLE_INVALID. - * @} - */ - - /** - * @addtogroup BLE_GATTS_SYS_ATTRS_FORMAT User memory layout for System Attributes - * @{ - * The following table shows the memory layout used by the SoftDevice to store a - * system attribute. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
System Attribute
ParameterSize (octets)Description
Handle2Attribute handle
Length2Attribute length
DataLengthAttribute data
- * - * The application can obtain an array of system attributes by using @c sd_ble_gatts_sys_attr_get(). - * The array is terminated by a CRC-16-CCITT checksum of the data in the array. - * @} - * @} - */ - -/** - * @addtogroup BLE_L2CAP - * @{ - * @defgroup BLE_L2CAP_MSC Message Sequence Charts - * @{ - * @defgroup BLE_L2CAP_CH_SETUP_MSC L2CAP Channel Setup - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * --- [label = " Variant #1 Locally initiated, Establishment success "]; - * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid=INVALID, le_psm, rx_mtu, rx_mps, sdu_buf: [len, p_data1])"]; - * APP<PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "L2CAP LE Credit Based Connection Response: Connection successful", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP {conn_handle, local_cid, tx_mtu, tx_mps, credits}"]; - * |||; - * APP rbox PEER [label="L2CAP Channel Established"]; - * |||; - * --- [label = " Variant #2 Locally initiated, Establishment failure - PEER refusal "]; - * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid=INVALID, le_psm, rx_mtu, rx_mps, sdu_buf: [len, p_data1])"]; - * APP<PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "L2CAP LE Credit Based Connection Response: Connection refused - no resources available", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED {conn_handle, local_cid, sdu_buf: [len, p_data1]}"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REFUSED {conn_handle, local_cid, source: REMOTE, status: NO_RESOURCES}"]; - * |||; - * APP rbox PEER [label="L2CAP Channel NOT Established"]; - * |||; - * --- [label = " Variant #3 Locally initiated, Establishment failure - PEER does not respond "]; - * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid=INVALID, le_psm, rx_mtu, rx_mps, sdu_buf: p_data=NULL)"]; - * APP<PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; - * SD abox SD [label="Timeout"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REFUSED {conn_handle, local_cid, source: LOCAL, status: TIMEOUT}"]; - * |||; - * APP rbox PEER [label="L2CAP Channel NOT Established"]; - * |||; - * --- [label = " Variant #4 Remotely initiated, Establishment success "]; - * SD<:PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REQUEST {conn_handle, local_cid, le_psm, tx_mtu, tx_mps, credits}"]; - * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid, rx_mtu, rx_mps, sdu_buf: [len, p_data1], status: SUCCESS)"]; - * APP<PEER [label = "L2CAP LE Credit Based Connection Response: Connection successful", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox PEER [label="L2CAP Channel Established"]; - * |||; - * --- [label = " Variant #5 Remotely initiated, Establishment failure - APP refusal "]; - * SD<:PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REQUEST {conn_handle, local_cid, le_psm, tx_mtu, tx_mps, credits}"]; - * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid, status: LE_PSM_NOT_SUPPORTED)"]; - * APP<PEER [label = "L2CAP LE Credit Based Connection Response: Connection refused - LE_PSM not supported", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox PEER [label="L2CAP Channel NOT Established"]; - * |||; - * --- [label = " Variant #6 Remotely initiated, Establishment failure - SD refusal "]; - * SD<:PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="The limit of available L2CAP channels has been reached"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REFUSED {conn_handle, local_cid=INVALID, source: LOCAL, status: NO_RESOURCES}"]; - * SD:>PEER [label = "L2CAP LE Credit Based Connection Response: Connection refused - no resources available", textcolor="#000080", linecolor="#000080"]; - * |||; - * APP rbox PEER [label="L2CAP Channel NOT Established"]; - * |||; - * @endmsc - * - * @defgroup BLE_L2CAP_CH_RELEASE_MSC L2CAP Channel Release - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP rbox PEER [label="Connection Established"]; - * |||; - * APP rbox PEER [label="L2CAP Channel Established"]; - * |||; - * --- [label = " Variant #1 Locally initiated, PEER responds "]; - * APP=>SD [label = "sd_ble_l2cap_ch_release(conn_handle, local_cid)"]; - * APP<PEER [label = "L2CAP Disconnection Request", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "L2CAP Disconnection Response", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="SD currently has three SDU data buffers supplied by APP"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED {conn_handle, local_cid, sdu_buf1}"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED {conn_handle, local_cid, sdu_buf2}"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED {conn_handle, local_cid, sdu_buf3}"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RELEASED {conn_handle, local_cid}"]; - * |||; - * --- [label = " Variant #2 Locally initiated, PEER does not respond "]; - * APP=>SD [label = "sd_ble_l2cap_ch_release(conn_handle, local_cid)"]; - * APP<PEER [label = "L2CAP Disconnection Request", textcolor="#000080", linecolor="#000080"]; - * SD abox SD [label="Timeout"]; - * SD rbox SD [label="SD does not currently have SDU data buffers supplied by APP"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RELEASED {conn_handle, local_cid}"]; - * |||; - * --- [label = " Variant #3 Remotely initiated "]; - * SD<:PEER [label = "L2CAP Disconnection Request", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="SD does not currently have SDU data buffers supplied by APP"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RELEASED {conn_handle, local_cid}"]; - * SD:>PEER [label = "L2CAP Disconnection Response", textcolor="#000080", linecolor="#000080"]; - * |||; - * @endmsc - * - * @defgroup BLE_L2CAP_CH_TX_MSC L2CAP Channel SDU Transmit - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * --- [label = " Variant #1 App ignores transmit credits, SD will transmit data as soon as possible "]; - * APP rbox PEER [label="L2CAP Channel Established, tx_queue_size=2, tx_mps=100, credits=2"]; - * |||; - * APP=>SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=140, p_data1])"]; - * APP<SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=80, p_data2])"]; - * APP<SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=280, p_data3])"]; - * APP<PEER [label = "SDU 1, Segment 1", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=140, p_data1]}"]; - * APP abox APP [label="App releases memory pointed by p_data1"]; - * SD rbox SD [label="All credits consumed"]; - * APP=>SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=280, p_data3])"]; - * APP<PEER [label = "SDU 2, Segment 1", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=80, p_data2]}"]; - * APP abox APP [label="App releases memory pointed by p_data2"]; - * SD:>PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; - * SD rbox SD [label="All credits consumed"]; - * ...; - * SD<:PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_CREDIT {conn_handle, local_cid, credits=2}"]; - * SD:>PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=280, p_data3]}"]; - * APP abox APP [label="App releases memory pointed by p_data3"]; - * |||; - * --- [label = " Variant #2 App keeps track of transmission credits and transmits only if credits are available "]; - * APP rbox PEER [label="L2CAP Channel Established, tx_queue_size=2, tx_mps=100, credits=2"]; - * APP abox APP [label="available_credits = 2"]; - * |||; - * APP=>SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=140, p_data1])"]; - * APP<PEER [label = "SDU 1, Segment 1", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=140, p_data1]}"]; - * APP abox APP [label="App releases memory pointed by p_data1"]; - * ...; - * SD<:PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_CREDIT {conn_handle, local_cid, credits=2}"]; - * APP abox APP [label="available_credits += 2\n// available_credits == 2"]; - * APP=>SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=80, p_data2])"]; - * APP<SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=280, p_data3])"]; - * APP<PEER [label = "SDU 2, Segment 1", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=80, p_data2]}"]; - * APP abox APP [label="App releases memory pointed by p_data2"]; - * SD:>PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; - * ...; - * SD<:PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_CREDIT {conn_handle, local_cid, credits=2}"]; - * APP abox APP [label="available_credits += 2\n// available_credits == 0"]; - * SD:>PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=280, p_data3]}"]; - * APP abox APP [label="App releases memory pointed by p_data3"]; - * |||; - * @endmsc - * - * @defgroup BLE_L2CAP_CH_RX_MSC L2CAP Channel SDU Receive - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP=>SD [label = "sd_ble_l2cap_ch_setup(rx_mtu=1000, rx_mps=100, sdu_buf: [len=1000, p_data1])"]; - * APP<PEER [label = "L2CAP LE Credit Based Connection Request (Initial Credits=1)", textcolor="#000080", linecolor="#000080"]; - * APP rbox PEER [label="L2CAP Channel Established, rx_queue_size=2, rx_mtu=1000, rx_mps=100"]; - * |||; - * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data2])"]; - * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 1, Segment 1", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; - * PEER rbox PEER [label="1 credit left"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=140, sdu_buf: [len=1000, p_data1]}"]; - * APP abox APP [label="App can process data and release memory pointed by p_data1"]; - * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data3])"]; - * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 2, Segment 1", textcolor="#000080", linecolor="#000080"]; - * PEER rbox PEER [label="1 credit left"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=80, sdu_buf: [len=1000, p_data2]}"]; - * APP abox APP [label="App can process data and release memory pointed by p_data2"]; - * SD<:PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; - * PEER rbox PEER [label="All credits consumed"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=280, sdu_buf: [len=1000, p_data3]}"]; - * APP abox APP [label="App can process data and release memory pointed by p_data3"]; - * |||; - * @endmsc - * - * @defgroup BLE_L2CAP_CH_FLOW_CONTROL_MSC L2CAP Channel advanced SDU reception flow control - * @msc - * hscale = "1.5"; - * APP,SD,PEER; - * |||; - * APP=>SD [label = "sd_ble_l2cap_ch_setup(rx_mtu=1000, rx_mps=100, sdu_buf: p_data=NULL)"]; - * APP<PEER [label = "L2CAP LE Credit Based Connection Request (Initial Credits=0)", textcolor="#000080", linecolor="#000080"]; - * APP rbox PEER [label="L2CAP Channel Established, rx_queue_size=2, rx_mtu=1000, rx_mps=100"]; - * |||; - * --- [label = " Variant #1 App overwrites number of credits peer should have at the start of a SDU "]; - * APP=>SD [label = "sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits=8)"]; - * APP<SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data1])"]; - * APP<PEER [label = "LE Flow Control Credit (credits=8)", textcolor="#000080", linecolor="#000080"]; - * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data2])"]; - * APP<PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; - * PEER rbox PEER [label="8 credits left"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=140, sdu_buf: [len=1000, p_data1]}"]; - * APP abox APP [label="App can process data and release memory pointed by p_data1"]; - * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data3])"]; - * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; - * PEER rbox PEER [label="8 credits left"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=80, sdu_buf: [len=1000, p_data2]}"]; - * APP abox APP [label="App can process data and release memory pointed by p_data2"]; - * SD<:PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; - * PEER rbox PEER [label="5 credits left"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=280, sdu_buf: [len=1000, p_data3]}"]; - * APP abox APP [label="App can process data and release memory pointed by p_data3"]; - * APP rbox APP [label="Peer has credits remaining so application must provide new reception buffer as soon as possible."]; - * |||; - * --- [label = " Variant #2 App pauses traffic on a L2CAP Channel "]; - * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data1])"]; - * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; - * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data2])"]; - * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 1, Segment 1", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; - * PEER rbox PEER [label="1 credit left"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=140, sdu_buf: [len=1000, p_data1]}"]; - * APP abox APP [label="App can process data and release memory pointed by p_data1"]; - * APP=>SD [label = "sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits=0)"]; - * APP<SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data3])"]; - * APP<SD [label = "sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits=0)"]; - * APP<SD [label = "sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits=BLE_L2CAP_CREDITS_DEFAULT)"]; - * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; - * SD:>PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; - * SD<:PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; - * PEER rbox PEER [label="All credits consumed"]; - * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=280, sdu_buf: [len=1000, p_data3]}"]; - * APP abox APP [label="App can process data and release memory pointed by p_data3"]; - * |||; - * @endmsc - * @} - * @} - */ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble.h deleted file mode 100644 index 470577b8aa2f9..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble.h +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_COMMON BLE SoftDevice Common - @{ - @defgroup ble_api Events, type definitions and API calls - @{ - - @brief Module independent events, type definitions and API calls for the BLE SoftDevice. - - */ - -#ifndef BLE_H__ -#define BLE_H__ - -#include "ble_ranges.h" -#include "ble_types.h" -#include "ble_gap.h" -#include "ble_l2cap.h" -#include "ble_gatt.h" -#include "ble_gattc.h" -#include "ble_gatts.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations - * @{ */ - -/** - * @brief Common API SVC numbers. - */ -enum BLE_COMMON_SVCS -{ - SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ - SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ - SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */ - SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ - SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ - SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */ - SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */ - SD_BLE_OPT_SET, /**< Set a BLE option. */ - SD_BLE_OPT_GET, /**< Get a BLE option. */ - SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */ -}; - -/** - * @brief BLE Module Independent Event IDs. - */ -enum BLE_COMMON_EVTS -{ - BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE, /**< User Memory request. @ref ble_evt_user_mem_request_t */ - BLE_EVT_USER_MEM_RELEASE, /**< User Memory release. @ref ble_evt_user_mem_release_t */ -}; - -/**@brief BLE Connection Configuration IDs. - * - * IDs that uniquely identify a connection configuration. - */ -enum BLE_CONN_CFGS -{ - BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE, /**< BLE GAP specific connection configuration. */ - BLE_CONN_CFG_GATTC, /**< BLE GATTC specific connection configuration. */ - BLE_CONN_CFG_GATTS, /**< BLE GATTS specific connection configuration. */ - BLE_CONN_CFG_GATT, /**< BLE GATT specific connection configuration. */ - BLE_CONN_CFG_L2CAP, /**< BLE L2CAP specific connection configuration. */ -}; - -/**@brief BLE Common Configuration IDs. - * - * IDs that uniquely identify a common configuration. - */ -enum BLE_COMMON_CFGS -{ - BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific UUID configuration */ -}; - -/**@brief Common Option IDs. - * IDs that uniquely identify a common option. - */ -enum BLE_COMMON_OPTS -{ - BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE, /**< PA and LNA options */ - BLE_COMMON_OPT_CONN_EVT_EXT, /**< Extended connection events option */ -}; - -/** @} */ - -/** @addtogroup BLE_COMMON_DEFINES Defines - * @{ */ - -/** @brief Required pointer alignment for BLE Events. -*/ -#define BLE_EVT_PTR_ALIGNMENT 4 - -/** @brief Leaves the maximum of the two arguments. -*/ -#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a)) - -/** @brief Maximum possible length for BLE Events. - * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter. - * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead. -*/ -#define BLE_EVT_LEN_MAX(ATT_MTU) (BLE_MAX( \ - sizeof(ble_evt_t), \ - BLE_MAX( \ - offsetof(ble_evt_t, evt.gattc_evt.params.rel_disc_rsp.includes) + ((ATT_MTU) - 2) / 6 * sizeof(ble_gattc_include_t), \ - offsetof(ble_evt_t, evt.gattc_evt.params.attr_info_disc_rsp.info.attr_info16) + ((ATT_MTU) - 2) / 4 * sizeof(ble_gattc_attr_info16_t) \ - ) \ -)) - -/** @defgroup BLE_USER_MEM_TYPES User Memory Types - * @{ */ -#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */ -#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ -/** @} */ - -/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts - * @{ - */ -#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */ -#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */ -/** @} */ - -/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults. - * @{ - */ -#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */ - -/** @} */ - -/** @} */ - -/** @addtogroup BLE_COMMON_STRUCTURES Structures - * @{ */ - -/**@brief User Memory Block. */ -typedef struct -{ - uint8_t *p_mem; /**< Pointer to the start of the user memory block. */ - uint16_t len; /**< Length in bytes of the user memory block. */ -} ble_user_mem_block_t; - -/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */ -typedef struct -{ - uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ -} ble_evt_user_mem_request_t; - -/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */ -typedef struct -{ - uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ - ble_user_mem_block_t mem_block; /**< User memory block */ -} ble_evt_user_mem_release_t; - -/**@brief Event structure for events not associated with a specific function module. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ - union - { - ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ - ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ - } params; /**< Event parameter union. */ -} ble_common_evt_t; - -/**@brief BLE Event header. */ -typedef struct -{ - uint16_t evt_id; /**< Value from a BLE__EVT series. */ - uint16_t evt_len; /**< Length in octets including this header. */ -} ble_evt_hdr_t; - -/**@brief Common BLE Event type, wrapping the module specific event reports. */ -typedef struct -{ - ble_evt_hdr_t header; /**< Event header. */ - union - { - ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ - ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ - ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ - ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ - ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ - } evt; /**< Event union. */ -} ble_evt_t; - - -/** - * @brief Version Information. - */ -typedef struct -{ - uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */ - uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ - uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ -} ble_version_t; - -/** - * @brief Configuration parameters for the PA and LNA. - */ -typedef struct -{ - uint8_t enable :1; /**< Enable toggling for this amplifier */ - uint8_t active_high :1; /**< Set the pin to be active high */ - uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ -} ble_pa_lna_cfg_t; - -/** - * @brief PA & LNA GPIO toggle configuration - * - * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or - * a low noise amplifier. - * - * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided - * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. - * - * @note @ref sd_ble_opt_get is not supported for this option. - * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences - * and must be avoided by the application. - */ -typedef struct -{ - ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ - ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ - - uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ - uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ - uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ -} ble_common_opt_pa_lna_t; - -/** - * @brief Configuration of extended BLE connection events. - * - * When enabled the SoftDevice will dynamically extend the connection event when possible. - * - * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length. - * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval, - * and if there are no conflicts with other BLE roles requesting radio time. - * - * @note @ref sd_ble_opt_get is not supported for this option. - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */ -} ble_common_opt_conn_evt_ext_t; - -/**@brief Option structure for common options. */ -typedef union -{ - ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ - ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */ -} ble_common_opt_t; - -/**@brief Common BLE Option type, wrapping the module specific options. */ -typedef union -{ - ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ - ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ -} ble_opt_t; - -/**@brief BLE connection configuration type, wrapping the module specific configurations, set with - * @ref sd_ble_cfg_set. - * - * @note Connection configurations don't have to be set. - * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections, - * the default connection configuration will be automatically added for the remaining connections. - * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in - * place of @ref ble_conn_cfg_t::conn_cfg_tag. See @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect()" - * - * @mscs - * @mmsc{@ref BLE_CONN_CFG} - * @endmscs - - */ -typedef struct -{ - uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() - calls to select this configuration when creating a connection. - Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */ - union { - ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */ - ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */ - ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */ - ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */ - ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */ - } params; /**< Connection configuration union. */ -} ble_conn_cfg_t; - -/** - * @brief Configuration of Vendor Specific UUIDs, set with @ref sd_ble_cfg_set. - * - * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured. - */ -typedef struct -{ - uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific UUID bases to allocate memory for. - Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is - @ref BLE_UUID_VS_COUNT_MAX. */ -} ble_common_cfg_vs_uuid_t; - -/**@brief Common BLE Configuration type, wrapping the common configurations. */ -typedef union -{ - ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor specific UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */ -} ble_common_cfg_t; - -/**@brief BLE Configuration type, wrapping the module specific configurations. */ -typedef union -{ - ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */ - ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */ - ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */ - ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */ -} ble_cfg_t; - -/** @} */ - -/** @addtogroup BLE_COMMON_FUNCTIONS Functions - * @{ */ - -/**@brief Enable the BLE stack - * - * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the - * application RAM region (APP_RAM_BASE). On return, this will - * contain the minimum start address of the application RAM region - * required by the SoftDevice for this configuration. - * - * @note The memory requirement for a specific configuration will not increase between SoftDevices - * with the same major version number. - * - * @note The value of *p_app_ram_base when the app has done no custom configuration of the - * SoftDevice, i.e. the app has not called @ref sd_ble_cfg_set before @ref sd_ble_enable, can - * be found in the release notes. - * - * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located - * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between - * APP_RAM_BASE and the start of the call stack. - * - * @details This call initializes the BLE stack, no BLE related function other than @ref - * sd_ble_cfg_set can be called before this one. - * - * @mscs - * @mmsc{@ref BLE_COMMON_ENABLE} - * @endmscs - * - * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. - * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not - * large enough to fit this configuration's memory requirement. Check *p_app_ram_base - * and set the start address of the application RAM region accordingly. - */ -SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base)); - -/**@brief Add configurations for the BLE stack - * - * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref - * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS. - * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value. - * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE). - * See @ref sd_ble_enable for details about APP_RAM_BASE. - * - * @note The memory requirement for a specific configuration will not increase between SoftDevices - * with the same major version number. - * - * @note If a configuration is set more than once, the last one set is the one that takes effect on - * @ref sd_ble_enable. - * - * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default - * configuration. - * - * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref - * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref - * sd_ble_enable). - * - * @note Error codes for the configurations are described in the configuration structs. - * - * @mscs - * @mmsc{@ref BLE_COMMON_ENABLE} - * @endmscs - * - * @retval ::NRF_SUCCESS The configuration has been added successfully. - * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied. - * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not - * large enough to fit this configuration's memory requirement. - */ -SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base)); - -/**@brief Get an event from the pending events queue. - * - * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. - * This buffer must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT. - * The buffer should be interpreted as a @ref ble_evt_t struct. - * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. - * - * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that - * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. - * The application is free to choose whether to call this function from thread mode (main context) or directly from the - * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher - * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) - * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so - * could potentially leave events in the internal queue without the application being aware of this fact. - * - * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to - * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, - * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. - * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length - * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return: - * - * \code - * uint16_t len; - * errcode = sd_ble_evt_get(NULL, &len); - * \endcode - * - * @mscs - * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} - * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. - * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. - */ -SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); - - -/**@brief Add a Vendor Specific base UUID. - * - * @details This call enables the application to add a vendor specific base UUID to the BLE stack's table, for later - * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t - * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code - * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses - * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to - * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field - * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to - * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, - * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. - * - * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by - * the 16-bit uuid field in @ref ble_uuid_t. - * - * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in - * p_uuid_type along with an NRF_SUCCESS error code. - * - * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding - * bytes 12 and 13. - * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. - * - * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID. - * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. - * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. - */ -SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); - - -/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. - * - * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared - * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add - * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index - * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. - * - * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. - * - * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). - * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. - * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. - * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. - */ -SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); - - -/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). - * - * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. - * - * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. - * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). - * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. - * - * @retval ::NRF_SUCCESS Successfully encoded into the buffer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. - */ -SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); - - -/**@brief Get Version Information. - * - * @details This call allows the application to get the BLE stack version information. - * - * @param[out] p_version Pointer to a ble_version_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Version information stored successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). - */ -SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); - - -/**@brief Provide a user memory block. - * - * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application. - * - * @mscs - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending. - */ -SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); - -/**@brief Set a BLE option. - * - * @details This call allows the application to set the value of an option. - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} - * @endmscs - * - * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. - * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. - * - * @retval ::NRF_SUCCESS Option set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. - */ -SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); - - -/**@brief Get a BLE option. - * - * @details This call allows the application to retrieve the value of an option. - * - * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. - * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Option retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. - * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. - * - */ -SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); - -/** @} */ -#ifdef __cplusplus -} -#endif -#endif /* BLE_H__ */ - -/** - @} - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_err.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_err.h deleted file mode 100644 index 1b0b9d4435471..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_err.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_COMMON - @{ - @addtogroup nrf_error - @{ - @ingroup BLE_COMMON - @} - - @defgroup ble_err General error codes - @{ - - @brief General error code definitions for the BLE API. - - @ingroup BLE_COMMON -*/ -#ifndef NRF_BLE_ERR_H__ -#define NRF_BLE_ERR_H__ - -#include "nrf_error.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* @defgroup BLE_ERRORS Error Codes - * @{ */ -#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ -#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ -#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ -#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid role. */ -/** @} */ - - -/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges - * @brief Assignment of subranges for module specific error codes. - * @note For specific error codes, see ble_.h or ble_error_.h. - * @{ */ -#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ -#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ -#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ -#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ -/** @} */ - -#ifdef __cplusplus -} -#endif -#endif - - -/** - @} - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gap.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gap.h deleted file mode 100644 index 13f7721c58384..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gap.h +++ /dev/null @@ -1,2170 +0,0 @@ -/* - * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_GAP Generic Access Profile (GAP) - @{ - @brief Definitions and prototypes for the GAP interface. - */ - -#ifndef BLE_GAP_H__ -#define BLE_GAP_H__ - - -#include "ble_types.h" -#include "ble_ranges.h" -#include "nrf_svc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations - * @{ */ - -/**@brief GAP API SVC numbers. - */ -enum BLE_GAP_SVCS -{ - SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ - SD_BLE_GAP_ADDR_GET, /**< Get own Bluetooth Address. */ - SD_BLE_GAP_WHITELIST_SET, /**< Set active whitelist. */ - SD_BLE_GAP_DEVICE_IDENTITIES_SET, /**< Set device identity list. */ - SD_BLE_GAP_PRIVACY_SET, /**< Set Privacy settings*/ - SD_BLE_GAP_PRIVACY_GET, /**< Get Privacy settings*/ - SD_BLE_GAP_ADV_DATA_SET, /**< Set Advertising Data. */ - SD_BLE_GAP_ADV_START, /**< Start Advertising. */ - SD_BLE_GAP_ADV_STOP, /**< Stop Advertising. */ - SD_BLE_GAP_CONN_PARAM_UPDATE, /**< Connection Parameter Update. */ - SD_BLE_GAP_DISCONNECT, /**< Disconnect. */ - SD_BLE_GAP_TX_POWER_SET, /**< Set TX Power. */ - SD_BLE_GAP_APPEARANCE_SET, /**< Set Appearance. */ - SD_BLE_GAP_APPEARANCE_GET, /**< Get Appearance. */ - SD_BLE_GAP_PPCP_SET, /**< Set PPCP. */ - SD_BLE_GAP_PPCP_GET, /**< Get PPCP. */ - SD_BLE_GAP_DEVICE_NAME_SET, /**< Set Device Name. */ - SD_BLE_GAP_DEVICE_NAME_GET, /**< Get Device Name. */ - SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */ - SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */ - SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */ - SD_BLE_GAP_LESC_DHKEY_REPLY, /**< Reply with an LE Secure Connections DHKey. */ - SD_BLE_GAP_KEYPRESS_NOTIFY, /**< Notify of a keypress during an authentication procedure. */ - SD_BLE_GAP_LESC_OOB_DATA_GET, /**< Get the local LE Secure Connections OOB data. */ - SD_BLE_GAP_LESC_OOB_DATA_SET, /**< Set the remote LE Secure Connections OOB data. */ - SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */ - SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */ - SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */ - SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ - SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ - SD_BLE_GAP_SCAN_START, /**< Start Scanning. */ - SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */ - SD_BLE_GAP_CONNECT, /**< Connect. */ - SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */ - SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */ - SD_BLE_GAP_PHY_UPDATE, /**< Initiate or respond to a PHY Update Procedure. */ - SD_BLE_GAP_DATA_LENGTH_UPDATE, /**< Initiate or respond to a Data Length Update Procedure. */ -}; - -/**@brief GAP Event IDs. - * IDs that uniquely identify an event coming from the stack to the application. - */ -enum BLE_GAP_EVTS -{ - BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. \n See @ref ble_gap_evt_connected_t. */ - BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ - BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ - BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */ - BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */ - BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ - BLE_GAP_EVT_KEY_PRESSED, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ - BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */ - BLE_GAP_EVT_LESC_DHKEY_REQUEST, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ - BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ - BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ - BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ - BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ - BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ - BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ - BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ - BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ - BLE_GAP_EVT_PHY_UPDATE_REQUEST, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n See @ref ble_gap_evt_phy_update_request_t. */ - BLE_GAP_EVT_PHY_UPDATE, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */ - BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, /**< Data Length Update Request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */ - BLE_GAP_EVT_DATA_LENGTH_UPDATE, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */ -}; - -/**@brief GAP Option IDs. - * IDs that uniquely identify a GAP option. - */ -enum BLE_GAP_OPTS -{ - BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ - BLE_GAP_OPT_LOCAL_CONN_LATENCY, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ - BLE_GAP_OPT_PASSKEY, /**< Set passkey. @ref ble_gap_opt_passkey_t */ - BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */ - BLE_GAP_OPT_COMPAT_MODE_1, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */ - BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ - BLE_GAP_OPT_SLAVE_LATENCY_DISABLE, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */ -}; - -/**@brief GAP Configuration IDs. - * - * IDs that uniquely identify a GAP configuration. - */ -enum BLE_GAP_CFGS -{ - BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */ - BLE_GAP_CFG_DEVICE_NAME, /**< Device name configuration. */ -}; - -/** @} */ - -/**@addtogroup BLE_GAP_DEFINES Defines - * @{ */ - -/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP - * @{ */ -#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ -#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ -#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ -#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */ -#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */ -#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */ -/**@} */ - - -/**@defgroup BLE_GAP_ROLES GAP Roles - * @note Not explicitly used in peripheral API, but will be relevant for central API. - * @{ */ -#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ -#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ -#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ -/**@} */ - - -/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources - * @{ */ -#define BLE_GAP_TIMEOUT_SRC_ADVERTISING 0x00 /**< Advertising timeout. */ -#define BLE_GAP_TIMEOUT_SRC_SCAN 0x01 /**< Scanning timeout. */ -#define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */ -#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types - * @{ */ -#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */ -/**@} */ - - -/**@brief The default interval in seconds at which a private address is refreshed. */ -#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */ -/**@brief The maximum interval in seconds at which a private address can be refreshed. */ -#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */ - - -/** @brief BLE address length. */ -#define BLE_GAP_ADDR_LEN (6) - - -/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes - * @{ */ -#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ -#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ -#define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY 0x02 /**< Device will send and accept only private addresses for its own address, - and will not accept a peer using identity address as sender address when - the peer IRK is exchanged, non-zero and added to the identity list. */ -/**@} */ - - -/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format - * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm - * @{ */ -#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ -#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ -#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ -#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ -#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ -#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ -#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ -#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ -#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ -#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ -#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ -#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ -#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ -#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ -#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ -#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ -#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */ -#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */ -#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ -#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ -#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags - * @{ */ -#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ -#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ -#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ -#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ -#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ -#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ -#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min - * @{ */ -#define BLE_GAP_ADV_INTERVAL_MIN 0x0020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ -#define BLE_GAP_ADV_INTERVAL_MAX 0x4000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ - /**@} */ - - -/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min - * @{ */ -#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ -#define BLE_GAP_SCAN_INTERVAL_MAX 0x4000 /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */ - /** @} */ - - -/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min - * @{ */ -#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ -#define BLE_GAP_SCAN_WINDOW_MAX 0x4000 /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */ - /** @} */ - - -/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min - * @{ */ -#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in seconds. */ -#define BLE_GAP_SCAN_TIMEOUT_MAX 0xFFFF /**< Maximum Scan timeout in seconds. */ - /** @} */ - - -/**@brief Maximum size of advertising data in octets. */ -#define BLE_GAP_ADV_MAX_SIZE (31) - - -/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types - * @{ */ -#define BLE_GAP_ADV_TYPE_ADV_IND 0x00 /**< Connectable undirected. */ -#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01 /**< Connectable directed. */ -#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02 /**< Scannable undirected. */ -#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03 /**< Non connectable undirected. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies - * @{ */ -#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ -#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ -#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ -#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values - * @{ */ -#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (180) /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180 s). */ -#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode. */ -/**@} */ - - -/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes - * @{ */ -#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ -#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ -#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ -/**@} */ - - -/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities - * @{ */ -#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ -#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ -#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ -#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ -#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ -/**@} */ - - -/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types - * @{ */ -#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ -#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ -#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ -/**@} */ - - -/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types - * @{ */ -#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ -#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ -#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ -#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ -#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ -/**@} */ - - -/**@defgroup BLE_GAP_SEC_STATUS GAP Security status - * @{ */ -#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ -#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ -#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ -#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */ -#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */ -#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */ -#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ -#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ -#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ -#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ -#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ -#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ -#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ -#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ -#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ -#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ -#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ -#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ -#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ -#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ -#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ -/**@} */ - - -/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources - * @{ */ -#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ -#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ -/**@} */ - - -/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits - * @{ */ -#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ -#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ -#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ -#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ -/**@} */ - - -/**@defgroup BLE_GAP_DEVNAME GAP device name defines. - * @{ */ -#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */ -#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */ -#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */ -/**@} */ - - -/**@brief Disable RSSI events for connections */ -#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF - -/**@defgroup BLE_GAP_PHYS GAP PHYs - * @{ */ -#define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/ -#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */ -#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */ -#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */ - -/**@} */ - -/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters - * - * See @ref ble_gap_conn_sec_mode_t. - * @{ */ -/**@brief Set sec_mode pointed to by ptr to have no access rights.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) -/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) -/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) -/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) -/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0) -/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) -/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) -/**@} */ - - -/**@brief GAP Security Random Number Length. */ -#define BLE_GAP_SEC_RAND_LEN 8 - - -/**@brief GAP Security Key Length. */ -#define BLE_GAP_SEC_KEY_LEN 16 - - -/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ -#define BLE_GAP_LESC_P256_PK_LEN 64 - - -/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ -#define BLE_GAP_LESC_DHKEY_LEN 32 - - -/**@brief GAP Passkey Length. */ -#define BLE_GAP_PASSKEY_LEN 6 - - -/**@brief Maximum amount of addresses in the whitelist. */ -#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) - - -/**@brief Maximum amount of identities in the device identities list. */ -#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8) - - -/**@brief Default connection count for a configuration. */ -#define BLE_GAP_CONN_COUNT_DEFAULT (1) - - -/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines. - * @{ */ -#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */ -#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */ -/**@} */ - - -/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines. - * @{ */ -#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */ -#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */ -#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */ -#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */ -/**@} */ - - -/**@brief Automatic data length parameter. */ -#define BLE_GAP_DATA_LENGTH_AUTO 0 - -/**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines. - * @{ */ -#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */ -#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */ -/**@} */ - -/**@defgroup GAP_SEC_MODES GAP Security Modes - * @{ */ -#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ -/**@} */ -/** @} */ - - -/**@addtogroup BLE_GAP_STRUCTURES Structures - * @{ */ - -/**@brief Bluetooth Low Energy address. */ -typedef struct -{ - uint8_t addr_id_peer : 1; /**< Only valid for peer addresses. - Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */ - uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */ - uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */ -} ble_gap_addr_t; - - -/**@brief GAP connection parameters. - * - * @note When ble_conn_params_t is received in an event, both min_conn_interval and - * max_conn_interval will be equal to the connection interval set by the central. - * - * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: - * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval - * that corresponds to the following Bluetooth Spec requirement: - * The Supervision_Timeout in milliseconds shall be larger than - * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. - */ -typedef struct -{ - uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ -} ble_gap_conn_params_t; - - -/**@brief GAP connection security modes. - * - * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n - * Security Mode 1 Level 1: No security is needed (aka open link).\n - * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n - * Security Mode 1 Level 3: MITM protected encrypted link required.\n - * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n - * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n - * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n - */ -typedef struct -{ - uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ - uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ - -} ble_gap_conn_sec_mode_t; - - -/**@brief GAP connection security status.*/ -typedef struct -{ - ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ - uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ -} ble_gap_conn_sec_t; - -/**@brief Identity Resolving Key. */ -typedef struct -{ - uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ -} ble_gap_irk_t; - - -/**@brief Channel mask for RF channels used in advertising. */ -typedef struct -{ - uint8_t ch_37_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 37 */ - uint8_t ch_38_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 38 */ - uint8_t ch_39_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 39 */ -} ble_gap_adv_ch_mask_t; - - -/**@brief GAP advertising parameters. */ -typedef struct -{ - uint8_t type; /**< See @ref BLE_GAP_ADV_TYPES. */ - ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer. - - When privacy is enabled and the local device use @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, the device identity list is searched for a matching - entry. If the local IRK for that device identity is set, the local IRK for that device will be used to generate the advertiser address field in the advertise packet. - - If type is @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this must be set to the targeted initiator. If the initiator is in the device identity list, - the peer IRK for that device will be used to generate the initiator address field in the ADV_DIRECT_IND packet. */ - uint8_t fp; /**< Filter Policy, see @ref BLE_GAP_ADV_FILTER_POLICIES. */ - uint16_t interval; /**< Advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20 ms to 10.24 s), see @ref BLE_GAP_ADV_INTERVALS. - - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising. - - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/ - uint16_t timeout; /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */ - ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. See @ref ble_gap_adv_ch_mask_t. */ -} ble_gap_adv_params_t; - - -/**@brief GAP scanning parameters. */ -typedef struct -{ - uint8_t active : 1; /**< If 1, perform active scanning (scan requests). */ - uint8_t use_whitelist : 1; /**< If 1, filter advertisers using current active whitelist. */ - uint8_t adv_dir_report : 1; /**< If 1, also report directed advertisements where the initiator field is set to a private resolvable address, - even if the address did not resolve to an entry in the device identity list. A report will be generated - even if the peer is not in the whitelist. */ - uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625 ms units (2.5 ms to 10.24 s). */ - uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625 ms units (2.5 ms to 10.24 s). */ - uint16_t timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ -} ble_gap_scan_params_t; - - -/**@brief Privacy. - * - * The privacy feature provides a way for the device to avoid being tracked over a period of time. - * The privacy feature, when enabled, hides the local device identity and replaces it with a private address - * that is automatically refreshed at a specified interval. - * - * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). - * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key, - * and devices can establish connections without revealing their real identities. - * - * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY) - * are supported. - * - * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all - * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. - * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called. - */ -typedef struct -{ - uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ - uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ - uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ - ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. - When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. - By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ -} ble_gap_privacy_params_t; - - -/**@brief PHY preferences for TX and RX - * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each direction. - * @code - * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; - * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; - * @endcode - * - */ -typedef struct -{ - uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */ - uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */ -} ble_gap_phys_t; - -/** @brief Keys that can be exchanged during a bonding procedure. */ -typedef struct -{ - uint8_t enc : 1; /**< Long Term Key and Master Identification. */ - uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ - uint8_t sign : 1; /**< Connection Signature Resolving Key. */ - uint8_t link : 1; /**< Derive the Link Key from the LTK. */ -} ble_gap_sec_kdist_t; - - -/**@brief GAP security parameters. */ -typedef struct -{ - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ - uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ - uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ - uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ - uint8_t oob : 1; /**< The OOB data flag. - - In LE legacy pairing, this flag is set if a device has out of band authentication data. - The OOB method is used if both of the devices have out of band authentication data. - - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data. - The OOB method is used if at least one device has the peer device's OOB data available. */ - uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ - uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ - ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ - ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ -} ble_gap_sec_params_t; - - -/**@brief GAP Encryption Information. */ -typedef struct -{ - uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ - uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ - uint8_t auth : 1; /**< Authenticated Key. */ - uint8_t ltk_len : 6; /**< LTK length in octets. */ -} ble_gap_enc_info_t; - - -/**@brief GAP Master Identification. */ -typedef struct -{ - uint16_t ediv; /**< Encrypted Diversifier. */ - uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ -} ble_gap_master_id_t; - - -/**@brief GAP Signing Information. */ -typedef struct -{ - uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ -} ble_gap_sign_info_t; - - -/**@brief GAP LE Secure Connections P-256 Public Key. */ -typedef struct -{ - uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */ -} ble_gap_lesc_p256_pk_t; - - -/**@brief GAP LE Secure Connections DHKey. */ -typedef struct -{ - uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ -} ble_gap_lesc_dhkey_t; - - -/**@brief GAP LE Secure Connections OOB data. */ -typedef struct -{ - ble_gap_addr_t addr; /**< Bluetooth address of the device. */ - uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ - uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ -} ble_gap_lesc_oob_data_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 - and the address is the device's identity address. */ - uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_connected_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */ -typedef struct -{ - uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ -} ble_gap_evt_disconnected_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */ -typedef struct -{ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_conn_param_update_t; - -/**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */ -typedef struct -{ - ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */ -} ble_gap_evt_phy_update_request_t; - -/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */ -typedef struct -{ - uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/ - uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */ - uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */ -} ble_gap_evt_phy_update_t; - -/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */ -typedef struct -{ - ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ -} ble_gap_evt_sec_params_request_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ - ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ - uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ - uint8_t id_info : 1; /**< If 1, Identity Information required. */ - uint8_t sign_info : 1; /**< If 1, Signing Information required. */ -} ble_gap_evt_sec_info_request_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */ -typedef struct -{ - uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ - uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply - with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or - @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ -} ble_gap_evt_passkey_display_t; - -/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ -typedef struct -{ - uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ -} ble_gap_evt_key_pressed_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ -typedef struct -{ - uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ -} ble_gap_evt_auth_key_request_t; - -/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ -typedef struct -{ - ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory - inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ - uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */ -} ble_gap_evt_lesc_dhkey_request_t; - - -/**@brief Security levels supported. - * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. -*/ -typedef struct -{ - uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ - uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ - uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ - uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ -} ble_gap_sec_levels_t; - - -/**@brief Encryption Key. */ -typedef struct -{ - ble_gap_enc_info_t enc_info; /**< Encryption Information. */ - ble_gap_master_id_t master_id; /**< Master Identification. */ -} ble_gap_enc_key_t; - - -/**@brief Identity Key. */ -typedef struct -{ - ble_gap_irk_t id_info; /**< Identity Resolving Key. */ - ble_gap_addr_t id_addr_info; /**< Identity Address. */ -} ble_gap_id_key_t; - - -/**@brief Security Keys. */ -typedef struct -{ - ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ - ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ - ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ - ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined - in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ -} ble_gap_sec_keys_t; - - -/**@brief Security key set for both local and peer keys. */ -typedef struct -{ - ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */ - ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ -} ble_gap_sec_keyset_t; - - -/**@brief Data Length Update Procedure parameters. */ -typedef struct -{ - uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ - uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */ - uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ - uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */ -} ble_gap_data_length_params_t; - - -/**@brief Data Length Update Procedure local limitation. */ -typedef struct -{ - uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */ - uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */ - uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */ -} ble_gap_data_length_limitation_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */ -typedef struct -{ - uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ - uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ - uint8_t bonded : 1; /**< Procedure resulted in a bond. */ - uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */ - ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ - ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ - ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ - ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ -} ble_gap_evt_auth_status_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */ -typedef struct -{ - ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ -} ble_gap_evt_conn_sec_update_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */ -typedef struct -{ - uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ -} ble_gap_evt_timeout_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */ -typedef struct -{ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ -} ble_gap_evt_rssi_changed_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 - and the address is the device's identity address. */ - ble_gap_addr_t direct_addr; /**< Set when the scanner is unable to resolve the private resolvable address of the initiator - field of a directed advertisement packet and the scanner has been enabled to report this in @ref ble_gap_scan_params_t::adv_dir_report. */ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ - uint8_t scan_rsp : 1; /**< If 1, the report corresponds to a scan response and the type field may be ignored. */ - uint8_t type : 2; /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */ - uint8_t dlen : 5; /**< Advertising or scan response data length. */ - uint8_t data[BLE_GAP_ADV_MAX_SIZE]; /**< Advertising or scan response data. */ -} ble_gap_evt_adv_report_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ -typedef struct -{ - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection requested. */ - uint8_t lesc : 1; /**< LE Secure Connections requested. */ - uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ -} ble_gap_evt_sec_request_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */ -typedef struct -{ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_conn_param_update_request_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */ -typedef struct -{ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 - and the address is the device's identity address. */ -} ble_gap_evt_scan_req_report_t; - -/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */ -typedef struct -{ - ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */ -} ble_gap_evt_data_length_update_request_t; - -/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */ -typedef struct -{ - ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */ -} ble_gap_evt_data_length_update_t; - - -/**@brief GAP event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occurred. */ - union /**< union alternative identified by evt_id in enclosing struct. */ - { - ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ - ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ - ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ - ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ - ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ - ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ - ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ - ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ - ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ - ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ - ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ - ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ - ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */ - ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ - ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ - ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ - ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */ - ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */ - ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */ - ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */ - ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */ - } params; /**< Event Parameters. */ -} ble_gap_evt_t; - - -/** - * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set. - * - * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero. - * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: - * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX. - * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN. - */ -typedef struct -{ - uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration. - The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */ - uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units. - The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN. - The event length and the connection interval are the primary parameters - for setting the throughput of a connection. - See the SoftDevice Specification for details on throughput. */ -} ble_gap_conn_cfg_t; - - -/** - * @brief Configuration of maximum concurrent connections in the different connected roles, set with - * @ref sd_ble_cfg_set. - * - * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too - * large. The maximum supported sum of concurrent connections is - * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX. - * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count. - */ -typedef struct -{ - uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */ - uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */ - uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */ -} ble_gap_cfg_role_count_t; - - -/** - * @brief Device name and its properties, set with @ref sd_ble_cfg_set. - * - * @note If the device name is not configured, the default device name will be @ref - * BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be @ref - * BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name - * will have no write access. - * - * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK, - * the attribute table size must be increased to have room for the longer device name (see - * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t). - * - * @note If vloc is @ref BLE_GATTS_VLOC_STACK : - * - p_value must point to non-volatile memory (flash) or be NULL. - * - If p_value is NULL, the device name will initially be empty. - * - * @note If vloc is @ref BLE_GATTS_VLOC_USER : - * - p_value cannot be NULL. - * - If the device name is writable, p_value must point to volatile memory (RAM). - * - * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: - * - Invalid device name location (vloc). - * - Invalid device name security mode. - * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: - * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN). - * - The device name length is too long for the given Attribute Table. - * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported. - */ -typedef struct -{ - ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ - uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ - uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */ - uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/ - uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/ -} ble_gap_cfg_device_name_t; - - -/**@brief Configuration structure for GAP configurations. */ -typedef union -{ - ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */ - ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */ -} ble_gap_cfg_t; - - -/**@brief Channel Map option. - * Used with @ref sd_ble_opt_get to get the current channel map - * or @ref sd_ble_opt_set to set a new channel map. When setting the - * channel map, it applies to all current and future connections. When getting the - * current channel map, it applies to a single connection and the connection handle - * must be supplied. - * - * @note Setting the channel map may take some time, depending on connection parameters. - * The time taken may be different for each connection and the get operation will - * return the previous channel map until the new one has taken effect. - * - * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. - * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. - * - * @retval ::NRF_SUCCESS Get or set successful. - * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. - * @retval ::NRF_ERROR_NOT_SUPPORTED Returned by sd_ble_opt_set in peripheral-only SoftDevices. - * - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ - uint8_t ch_map[5]; /**< Channel Map (37-bit). */ -} ble_gap_opt_ch_map_t; - - -/**@brief Local connection latency option. - * - * Local connection latency is a feature which enables the slave to improve - * current consumption by ignoring the slave latency set by the peer. The - * local connection latency can only be set to a multiple of the slave latency, - * and cannot be longer than half of the supervision timeout. - * - * Used with @ref sd_ble_opt_set to set the local connection latency. The - * @ref sd_ble_opt_get is not supported for this option, but the actual - * local connection latency (unless set to NULL) is set as a return parameter - * when setting the option. - * - * @note The latency set will be truncated down to the closest slave latency event - * multiple, or the nearest multiple before half of the supervision timeout. - * - * @note The local connection latency is disabled by default, and needs to be enabled for new - * connections and whenever the connection is updated. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle */ - uint16_t requested_latency; /**< Requested local connection latency. */ - uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */ -} ble_gap_opt_local_conn_latency_t; - -/**@brief Disable slave latency - * - * Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. - * When disabled, the peripheral will ignore the slave_latency set by the central. - * - * @note Shall only be called on peripheral links. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle */ - uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/ -} ble_gap_opt_slave_latency_disable_t; - -/**@brief Passkey Option. - * - * Structure containing the passkey to be used during pairing. This can be used with @ref - * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication - * instead of generating a random one. - * - * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks. - * - * @note @ref sd_ble_opt_get is not supported for this option. - * - */ -typedef struct -{ - uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ -} ble_gap_opt_passkey_t; - - -/**@brief Scan request report option. - * - * This can be used with @ref sd_ble_opt_set to make the SoftDevice send - * @ref BLE_GAP_EVT_SCAN_REQ_REPORT events. - * - * @note Due to the limited space reserved for scan request report events, - * not all received scan requests will be reported. - * - * @note If whitelisting is used, only whitelisted requests are reported. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_INVALID_STATE When advertising is ongoing while the option is set. - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable scan request reports. */ -} ble_gap_opt_scan_req_report_t; - -/**@brief Compatibility mode 1 option. - * - * This can be used with @ref sd_ble_opt_set to enable and disable - * compatibility mode 1. Compatibility mode 1 is disabled by default. - * - * @note Compatibility mode 1 enables interoperability with devices that do not support a value of - * 0 for the WinOffset parameter in the Link Layer CONNECT_IND packet. This applies to a - * limited set of legacy peripheral devices from another vendor. Enabling this compatibility - * mode will only have an effect if the local device will act as a central device and - * initiate a connection to a peripheral device. In that case it may lead to the connection - * creation taking up to one connection interval longer to complete for all connections. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable compatibility mode 1.*/ -} ble_gap_opt_compat_mode_1_t; - -/**@brief Authenticated payload timeout option. - * - * This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other - * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX. - * - * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated - * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted - * link. - * - * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance - * to reset the timer. In addition the stack will try to prioritize running of LE ping over other - * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects - * on other activities, it is recommended to use high timeout values. - * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle */ - uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */ -} ble_gap_opt_auth_payload_timeout_t; - - -/**@brief Option structure for GAP options. */ -typedef union -{ - ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ - ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ - ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ - ble_gap_opt_scan_req_report_t scan_req_report; /**< Parameters for the scan request report option.*/ - ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/ - ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ - ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */ -} ble_gap_opt_t; -/**@} */ - - -/**@addtogroup BLE_GAP_FUNCTIONS Functions - * @{ */ - -/**@brief Set the local Bluetooth identity address. - * - * The local Bluetooth identity address is the address that identifies this device to other peers. - * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. - * - * @note The identity address cannot be changed while advertising, scanning or creating a connection. - * - * @note This address will be distributed to the peer during bonding. - * If the address changes, the address stored in the peer device will not be valid and the ability to - * reconnect using the old address will be lost. - * - * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being - * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged - * for the lifetime of each IC. - * - * @mscs - * @mmsc{@ref BLE_GAP_ADV_MSC} - * @endmscs - * - * @param[in] p_addr Pointer to address structure. - * - * @retval ::NRF_SUCCESS Address successfully set. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising, - * scanning or creating a connection. - */ -SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr)); - - -/**@brief Get local Bluetooth identity address. - * - * @note This will always return the identity address irrespective of the privacy settings, - * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. - * - * @param[out] p_addr Pointer to address structure to be filled in. - * - * @retval ::NRF_SUCCESS Address successfully retrieved. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. - */ -SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)); - - -/**@brief Set the active whitelist in the SoftDevice. - * - * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles. - * The whitelist cannot be set if a BLE role is using the whitelist. - * - * @note If an address is resolved using the information in the device identity list, then the whitelist - * filter policy applies to the peer identity address and not the resolvable address sent on air. - * - * @mscs - * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} - * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} - * @endmscs - * - * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared. - * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. - * - * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared. - * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid. - * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. - * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when - * pp_wl_addrs is not NULL. - */ -SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len)); - - -/**@brief Set device identity list. - * - * @note Only one device identity list can be used at a time and the list is shared between the BLE roles. - * The device identity list cannot be set if a BLE role is using the list. - * - * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared. - * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index. - * To fill in the list with the currently set device IRK for all peers, set to NULL. - * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT. - * - * @mscs - * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} - * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} - * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} - * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS The device identity list successfully set/cleared. - * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid. - * This code may be returned if the local IRK list also has an invalid entry. - * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared. - * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. - * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can - * only return when pp_id_keys is not NULL. - */ -SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len)); - - -/**@brief Set privacy settings. - * - * @note Privacy settings cannot be changed while advertising, scanning or creating a connection. - * - * @param[in] p_privacy_params Privacy settings. - * - * @mscs - * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} - * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} - * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. - * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid. - * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. - * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided. - * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising, scanning - * or creating a connection. - */ -SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)); - - -/**@brief Get privacy settings. - * - * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called. - * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return. - * - * @param[in,out] p_privacy_params Privacy settings. - * - * @retval ::NRF_SUCCESS Privacy settings read. - * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. - * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. - */ -SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); - - -/**@brief Set, clear or update advertising and scan response data. - * - * @note The format of the advertising data will be checked by this call to ensure interoperability. - * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and - * duplicating the local name in the advertising data and scan response data. - * - * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding - * length (dlen/srdlen) set to 0. - * - * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect. - * - * @mscs - * @mmsc{@ref BLE_GAP_ADV_MSC} - * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} - * @endmscs - * - * @param[in] p_data Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data. - * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. - * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data. - * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. - * - * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, both p_data and p_sr_data cannot be NULL. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. - * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. - * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data type. - * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. - */ -SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen)); - - -/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). - * - * @note Only one advertiser may be active at any time. - * - * @events - * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} - * @event{@ref BLE_GAP_EVT_TIMEOUT, Advertisement has timed out.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_ADV_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} - * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} - * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} - * @endmscs - * - * @param[in] p_adv_params Pointer to advertising parameters structure. - * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref - * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. If - * @ref ble_gap_adv_params_t::type is @ref BLE_GAP_ADV_TYPE_ADV_NONCONN_IND, - * this is ignored. - * - * @retval ::NRF_SUCCESS The BLE stack has started advertising. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied. - * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. - * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. - * Stop one or more currently active roles (Central, Peripheral or Observer) and try again - */ -SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params, uint8_t conn_cfg_tag)); - - -/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). - * - * @mscs - * @mmsc{@ref BLE_GAP_ADV_MSC} - * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state). - */ -SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void)); - - - -/**@brief Update connection parameters. - * - * @details In the central role this will initiate a Link Layer connection parameter update procedure, - * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for - * the central to perform the procedure. In both cases, and regardless of success or failure, the application - * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. - * - * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. - * - * @events - * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_CPU_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} - * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} - * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, - * the parameters in the PPCP characteristic of the GAP service will be used instead. - * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected - * - * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); - - -/**@brief Disconnect (GAP Link Termination). - * - * @details This call initiates the disconnection procedure, and its completion will be communicated to the application - * with a @ref BLE_GAP_EVT_DISCONNECTED event. - * - * @events - * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_CONN_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). - * - * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress). - */ -SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); - - -/**@brief Set the radio's transmit power. - * - * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -20, -16, -12, -8, -4, 0, 3, and 4 dBm). - * - * @retval ::NRF_SUCCESS Successfully changed the transmit power. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - */ -SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(int8_t tx_power)); - - -/**@brief Set GAP Appearance value. - * - * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. - * - * @retval ::NRF_SUCCESS Appearance value set successfully. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - */ -SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); - - -/**@brief Get GAP Appearance value. - * - * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. - * - * @retval ::NRF_SUCCESS Appearance value retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); - - -/**@brief Set GAP Peripheral Preferred Connection Parameters. - * - * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. - * - * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - */ -SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); - - -/**@brief Get GAP Peripheral Preferred Connection Parameters. - * - * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. - * - * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); - - -/**@brief Set GAP device name. - * - * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t), - * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned. - * - * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t. - * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. - * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). - * - * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable. - */ -SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); - - -/**@brief Get GAP device name. - * - * @note If the device name is longer than the size of the supplied buffer, - * p_len will return the complete device name length, - * and not the number of bytes actually returned in p_dev_name. - * The application may use this information to allocate a suitable buffer size. - * - * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. - * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. - * - * @retval ::NRF_SUCCESS GAP device name retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - */ -SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); - - -/**@brief Initiate the GAP Authentication procedure. - * - * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), - * otherwise in the peripheral role, an SMP Security Request will be sent. - * - * @events - * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:} - * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} - * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} - * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} - * @event{@ref BLE_GAP_EVT_KEY_PRESSED} - * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} - * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} - * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} - * @event{@ref BLE_GAP_EVT_AUTH_STATUS} - * @event{@ref BLE_GAP_EVT_TIMEOUT} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. - * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. - * In the central role, this pointer may be NULL to reject a Security Request. - * - * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. - * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. - */ -SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); - - -/**@brief Reply with GAP security parameters. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * - * @events - * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. - * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have - * already been provided during a previous call to @ref sd_ble_gap_authenticate. - * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure - * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application - * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. - * Note that the SoftDevice expects the application to provide memory for storing the - * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key - * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the - * @ref BLE_GAP_EVT_AUTH_STATUS event. - * - * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. - */ -SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); - - -/**@brief Reply with an authentication key. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * - * @events - * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. - * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination) - * or NULL when confirming LE Secure Connections Numeric Comparison. - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format. - * - * @retval ::NRF_SUCCESS Authentication key successfully set. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); - -/**@brief Reply with an LE Secure connections DHKey. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * - * @events - * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_dhkey LE Secure Connections DHKey. - * - * @retval ::NRF_SUCCESS DHKey successfully set. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); - -/**@brief Notify the peer of a local keypress. - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. - * - * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); - -/**@brief Generate a set of OOB data to send to a peer out of band. - * - * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established, - * the one used during connection setup). The application may manually overwrite it with an updated value. - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. Can be BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. - * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. - * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. - * - * @retval ::NRF_SUCCESS OOB data successfully generated. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own)); - -/**@brief Provide the OOB data sent/received out of band. - * - * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. - * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function. - * - * @events - * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data. - * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. - * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. - * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref sd_ble_gap_authenticate in the central role - * or @ref sd_ble_gap_sec_params_reply in the peripheral role. - * - * @retval ::NRF_SUCCESS OOB data accepted. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer)); - -/**@brief Initiate GAP Encryption procedure. - * - * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. - * - * @events - * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} - * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. - * - * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. - * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry. - */ -SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); - - -/**@brief Reply with GAP security information. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. - * - * @mscs - * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. - * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. - * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. - * - * @retval ::NRF_SUCCESS Successfully accepted security information. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info)); - - -/**@brief Get the current connection security. - * - * @param[in] conn_handle Connection handle. - * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Current connection security successfully retrieved. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); - - -/**@brief Start reporting the received signal strength to the application. - * - * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. - * - * @events - * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is - * dependent on the settings of the threshold_dbm - * and skip_count input parameters.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} - * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. - * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. - * - * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. - * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress. Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); - - -/**@brief Stop reporting the received signal strength. - * - * @note An RSSI change detected before the call but not yet received by the application - * may be reported after @ref sd_ble_gap_rssi_stop has been called. - * - * @mscs - * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} - * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * - * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); - - -/**@brief Get the received signal strength for the last connection event. - * - * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND - * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. - * - * @mscs - * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. - * - * @retval ::NRF_SUCCESS Successfully read the RSSI. - * @retval ::NRF_ERROR_NOT_FOUND No sample is available. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing, or disconnection in progress. - */ -SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi)); - - -/**@brief Start scanning (GAP Discovery procedure, Observer Procedure). - * - * @events - * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} - * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_SCAN_MSC} - * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} - * @endmscs - * - * @param[in] p_scan_params Pointer to scan parameters structure. - * - * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. - * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again - */ -SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params)); - - -/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). - * - * @mscs - * @mmsc{@ref BLE_GAP_SCAN_MSC} - * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state). - */ -SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); - - -/**@brief Create a connection (GAP Link Establishment). - * - * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. - * The scanning procedure will be stopped even if the function returns an error. - * - * @mscs - * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} - * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} - * @endmscs - * - * @param[in] p_peer_addr Pointer to peer address. If the use_whitelist bit is set in @ref ble_gap_scan_params_t, then this is ignored. - * @param[in] p_scan_params Pointer to scan parameters structure. - * @param[in] p_conn_params Pointer to desired connection parameters. - * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref - * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. - * - * @retval ::NRF_SUCCESS Successfully initiated connection procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * - Invalid parameter(s) in p_scan_params or p_conn_params. - * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. - * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set. - * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an - * existing locally initiated connect procedure, which must complete before initiating again. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. - * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. - * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. - * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again - */ -SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)); - - -/**@brief Cancel a connection establishment. - * - * @mscs - * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - */ -SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); - - -/**@brief Initiate or respond to a PHY Update Procedure - * - * @details This function is used to initiate or respond to a PHY Update Procedure. It will always generate a - * @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed. If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys - * is @ref BLE_GAP_PHY_AUTO, then the stack will select a PHY for the respective direction based on the peer's PHY preferences - * and the local stack configuration. If the peer does not support the PHY Update Procedure, then the - * resulting @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to - * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE. - * If the PHY procedure was rejected by the peer due to a procedure collision, the status will be - * @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION. - * If the peer responds to the PHY Update procedure with invalid parameters, the status will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS. - * If the PHY procedure was rejected by the peer for a different reason, the status will contain the reason as specified by the peer. - * - * @events - * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE} - * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE} - * @endmscs - * - * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested. - * @param[in] p_gap_phys Pointer to PHY structure. - * - * @retval ::NRF_SUCCESS Successfully requested a PHY Update. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Unsupported PHYs supplied to the call. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry. - * - */ -SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)); - -/**@brief Initiate or respond to a Data Length Update Procedure. - * - * @note Only symmetric input parameters for the Data Length Update is supported. Only @ref - * BLE_GAP_DATA_LENGTH_AUTO for max_tx_time_us and max_rx_time_us is supported. - * - * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of - * p_dl_params, the SoftDevice will choose the highest value supported in current - * configuration and connection parameters. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update - * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let - * the SoftDevice automatically decide the value for that member. - * Set to NULL to use automatic values for all members. - * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not - * have enough resources to accommodate the requested Data Length - * Update parameters. Ignored if NULL. - * - * @mscs - * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC} - * @endmscs - * - * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. - * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. - * @retval ::NRF_ERROR_RESOURCES The requested parameters can not be accommodated. Inspect - * p_dl_limitation so see where the limitation is. - * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the - * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond. - */ -SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation)); - - - -/** @} */ - -#ifdef __cplusplus -} -#endif -#endif // BLE_GAP_H__ - -/** - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gatt.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gatt.h deleted file mode 100644 index 4e054cf5c3229..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gatt.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common - @{ - @brief Common definitions and prototypes for the GATT interfaces. - */ - -#ifndef BLE_GATT_H__ -#define BLE_GATT_H__ - -#include "ble_types.h" -#include "ble_ranges.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup BLE_GATT_DEFINES Defines - * @{ */ - -/** @brief Default ATT MTU, in bytes. */ -#define BLE_GATT_ATT_MTU_DEFAULT 23 - -/**@brief Invalid Attribute Handle. */ -#define BLE_GATT_HANDLE_INVALID 0x0000 - -/**@brief First Attribute Handle. */ -#define BLE_GATT_HANDLE_START 0x0001 - -/**@brief Last Attribute Handle. */ -#define BLE_GATT_HANDLE_END 0xFFFF - -/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources - * @{ */ -#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ -/** @} */ - -/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations - * @{ */ -#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ -#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ -#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ -#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ -#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ -/** @} */ - -/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags - * @{ */ -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ -/** @} */ - -/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations - * @{ */ -#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ -#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ -/** @} */ - -/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes - * @{ */ -#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ -#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ -#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ -#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ -#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ -#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */ -#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ -#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ -#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ -#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ -#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ -#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ -#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ -#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ -#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ -#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ -/** @} */ - - -/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats - * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml - * @{ */ -#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ -#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ -#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ -#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ -#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ -#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ -#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ -#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ -#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ -#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ -#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ -#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ -/** @} */ - -/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces - * @{ - */ -#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ -#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ -/** @} */ - -/** @} */ - -/** @addtogroup BLE_GATT_STRUCTURES Structures - * @{ */ - -/** - * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set. - * - * @retval NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT. - */ -typedef struct -{ - uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive. - The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. - @mscs - @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} - @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} - @endmscs - */ -} ble_gatt_conn_cfg_t; - -/**@brief GATT Characteristic Properties. */ -typedef struct -{ - /* Standard properties */ - uint8_t broadcast :1; /**< Broadcasting of the value permitted. */ - uint8_t read :1; /**< Reading the value permitted. */ - uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */ - uint8_t write :1; /**< Writing the value with Write Request permitted. */ - uint8_t notify :1; /**< Notification of the value permitted. */ - uint8_t indicate :1; /**< Indications of the value permitted. */ - uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */ -} ble_gatt_char_props_t; - -/**@brief GATT Characteristic Extended Properties. */ -typedef struct -{ - /* Extended properties */ - uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */ - uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ -} ble_gatt_char_ext_props_t; - -/** @} */ - -#ifdef __cplusplus -} -#endif -#endif // BLE_GATT_H__ - -/** @} */ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gattc.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gattc.h deleted file mode 100644 index 191f3a85ea6dd..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gattc.h +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client - @{ - @brief Definitions and prototypes for the GATT Client interface. - */ - -#ifndef BLE_GATTC_H__ -#define BLE_GATTC_H__ - -#include "ble_gatt.h" -#include "ble_types.h" -#include "ble_ranges.h" -#include "nrf_svc.h" -#include "nrf_error.h" -#include "nrf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations - * @{ */ - -/**@brief GATTC API SVC numbers. */ -enum BLE_GATTC_SVCS -{ - SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ - SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ - SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ - SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ - SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ - SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ - SD_BLE_GATTC_READ, /**< Generic read. */ - SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ - SD_BLE_GATTC_WRITE, /**< Generic write. */ - SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ - SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */ -}; - -/** - * @brief GATT Client Event IDs. - */ -enum BLE_GATTC_EVTS -{ - BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */ - BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */ - BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */ - BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */ - BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */ - BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ - BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ - BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */ - BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ - BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ - BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */ - BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ - BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */ -}; - -/** @} */ - -/** @addtogroup BLE_GATTC_DEFINES Defines - * @{ */ - -/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC - * @{ */ -#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ -/** @} */ - -/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats - * @{ */ -#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ -#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ -/** @} */ - -/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults - * @{ */ -#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */ -/** @} */ - -/** @} */ - -/** @addtogroup BLE_GATTC_STRUCTURES Structures - * @{ */ - -/** - * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set. - */ -typedef struct -{ - uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission. - The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */ -} ble_gattc_conn_cfg_t; - -/**@brief Operation Handle Range. */ -typedef struct -{ - uint16_t start_handle; /**< Start Handle. */ - uint16_t end_handle; /**< End Handle. */ -} ble_gattc_handle_range_t; - - -/**@brief GATT service. */ -typedef struct -{ - ble_uuid_t uuid; /**< Service UUID. */ - ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ -} ble_gattc_service_t; - - -/**@brief GATT include. */ -typedef struct -{ - uint16_t handle; /**< Include Handle. */ - ble_gattc_service_t included_srvc; /**< Handle of the included service. */ -} ble_gattc_include_t; - - -/**@brief GATT characteristic. */ -typedef struct -{ - ble_uuid_t uuid; /**< Characteristic UUID. */ - ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ - uint8_t char_ext_props : 1; /**< Extended properties present. */ - uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ - uint16_t handle_value; /**< Handle of the Characteristic Value. */ -} ble_gattc_char_t; - - -/**@brief GATT descriptor. */ -typedef struct -{ - uint16_t handle; /**< Descriptor Handle. */ - ble_uuid_t uuid; /**< Descriptor UUID. */ -} ble_gattc_desc_t; - - -/**@brief Write Parameters. */ -typedef struct -{ - uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ - uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ - uint16_t handle; /**< Handle to the attribute to be written. */ - uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ - uint16_t len; /**< Length of data in bytes. */ - uint8_t const *p_value; /**< Pointer to the value data. */ -} ble_gattc_write_params_t; - -/**@brief Attribute Information for 16-bit Attribute UUID. */ -typedef struct -{ - uint16_t handle; /**< Attribute handle. */ - ble_uuid_t uuid; /**< 16-bit Attribute UUID. */ -} ble_gattc_attr_info16_t; - -/**@brief Attribute Information for 128-bit Attribute UUID. */ -typedef struct -{ - uint16_t handle; /**< Attribute handle. */ - ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */ -} ble_gattc_attr_info128_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Service count. */ - ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_prim_srvc_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Include count. */ - ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_rel_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Characteristic count. */ - ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_char_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Descriptor count. */ - ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_desc_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Attribute count. */ - uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ - union { - ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID. - @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ - ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID. - @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ - } info; /**< Attribute information union. */ -} ble_gattc_evt_attr_info_disc_rsp_t; - -/**@brief GATT read by UUID handle value pair. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */ -} ble_gattc_handle_value_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ -typedef struct -{ - uint16_t count; /**< Handle-Value Pair Count. */ - uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ - uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter. - @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_char_val_by_uuid_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint16_t offset; /**< Offset of the attribute data. */ - uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ -typedef struct -{ - uint16_t len; /**< Concatenated Attribute values length. */ - uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_char_vals_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ - uint16_t offset; /**< Data offset. */ - uint16_t len; /**< Data length. */ - uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_write_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ -typedef struct -{ - uint16_t handle; /**< Handle to which the HVx operation applies. */ - uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ - uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gattc_evt_hvx_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */ -typedef struct -{ - uint16_t server_rx_mtu; /**< Server RX MTU size. */ -} ble_gattc_evt_exchange_mtu_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ -typedef struct -{ - uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ -} ble_gattc_evt_timeout_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */ -typedef struct -{ - uint8_t count; /**< Number of write without response transmissions completed. */ -} ble_gattc_evt_write_cmd_tx_complete_t; - -/**@brief GATTC event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occurred. */ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ - uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ - union - { - ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ - ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ - ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ - ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ - ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ - ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ - ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ - ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ - ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ - ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */ - ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ - ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ - ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */ - } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ -} ble_gattc_evt_t; -/** @} */ - -/** @addtogroup BLE_GATTC_FUNCTIONS Functions - * @{ */ - -/**@brief Initiate or continue a GATT Primary Service Discovery procedure. - * - * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. - * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search. - * - * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with - * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. - * - * @events - * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] start_handle Handle to start searching from. - * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); - - -/**@brief Initiate or continue a GATT Relationship Discovery procedure. - * - * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, - * this must be called again with an updated handle range to continue the search. - * - * @events - * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Characteristic Discovery procedure. - * - * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with - * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. - * - * @events - * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. - * - * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @events - * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. - * - * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @events - * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_uuid Pointer to a Characteristic value UUID to read. - * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. - * - * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor - * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the - * complete value. - * - * @events - * @event{@ref BLE_GATTC_EVT_READ_RSP} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] handle The handle of the attribute to be read. - * @param[in] offset Offset into the attribute value to be read. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); - - -/**@brief Initiate a GATT Read Multiple Characteristic Values procedure. - * - * @details This function initiates a GATT Read Multiple Characteristic Values procedure. - * - * @events - * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. - * @param[in] handle_count The number of handles in p_handles. - * - * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); - - -/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure. - * - * @details This function can perform all write procedures described in GATT. - * - * @note Only one write with response procedure can be ongoing per connection at a time. - * If the application tries to write with response while another write with response procedure is ongoing, - * the function call will return @ref NRF_ERROR_BUSY. - * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer. - * - * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size - * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. - * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete. - * - * @note The application can keep track of the available queue element count for writes without responses by following the procedure below: - * - Store initial queue element count in a variable. - * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. - * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event. - * - * @events - * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.} - * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC} - * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} - * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} - * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_write_params A pointer to a write parameters structure. - * - * @retval ::NRF_SUCCESS Successfully started the Write procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry. - * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued. - * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry. - */ -SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); - - -/**@brief Send a Handle Value Confirmation to the GATT Server. - * - * @mscs - * @mmsc{@ref BLE_GATTC_HVI_MSC} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] handle The handle of the attribute in the indication. - * - * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. - */ -SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); - -/**@brief Discovers information about a range of attributes on a GATT server. - * - * @events - * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} - * @endevents - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range The range of handles to request information about. - * - * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range)); - -/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server. - * - * @details The SoftDevice sets ATT_MTU to the minimum of: - * - The Client RX MTU value, and - * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. - * - * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. - * - * @events - * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] client_rx_mtu Client RX MTU size. - * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. - * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration - used for this connection. - * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply - * if an ATT_MTU exchange has already been performed in the other direction. - * - * @retval ::NRF_SUCCESS Successfully sent request to the server. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu)); - -/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. - * - * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. - * @note If the buffer contains different event, behavior is undefined. - * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with - * the next Handle-Value pair in each iteration. If the function returns other than - * @ref NRF_SUCCESS, it will not be changed. - * - To start iteration, initialize the structure to zero. - * - To continue, pass the value from previous iteration. - * - * \code - * ble_gattc_handle_value_t iter; - * memset(&iter, 0, sizeof(ble_gattc_handle_value_t)); - * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS) - * { - * app_handle = iter.handle; - * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len); - * } - * \endcode - * - * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair. - * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list. - */ -__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter); - -/** @} */ - -#ifndef SUPPRESS_INLINE_IMPLEMENTATION - -__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter) -{ - uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len; - uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value; - uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first; - - if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count) - { - p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0]; - p_iter->p_value = p_next + sizeof(uint16_t); - return NRF_SUCCESS; - } - else - { - return NRF_ERROR_NOT_FOUND; - } -} - -#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ - -#ifdef __cplusplus -} -#endif -#endif /* BLE_GATTC_H__ */ - -/** - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gatts.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gatts.h deleted file mode 100644 index 5e8615c05d0c9..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_gatts.h +++ /dev/null @@ -1,835 +0,0 @@ -/* - * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server - @{ - @brief Definitions and prototypes for the GATTS interface. - */ - -#ifndef BLE_GATTS_H__ -#define BLE_GATTS_H__ - -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_l2cap.h" -#include "ble_gap.h" -#include "ble_gatt.h" -#include "nrf_svc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations - * @{ */ - -/** - * @brief GATTS API SVC numbers. - */ -enum BLE_GATTS_SVCS -{ - SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ - SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ - SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ - SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ - SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ - SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ - SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ - SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ - SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ - SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ - SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ - SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ - SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */ - SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */ -}; - -/** - * @brief GATT Server Event IDs. - */ -enum BLE_GATTS_EVTS -{ - BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */ - BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */ - BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ - BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */ - BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */ - BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */ - BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */ - BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */ -}; - -/**@brief GATTS Configuration IDs. - * - * IDs that uniquely identify a GATTS configuration. - */ -enum BLE_GATTS_CFGS -{ - BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */ - BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */ -}; - -/** @} */ - -/** @addtogroup BLE_GATTS_DEFINES Defines - * @{ */ - -/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS - * @{ */ -#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ -#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ -/** @} */ - -/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths - * @{ */ -#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. */ -/** @} */ - -/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types - * @{ */ -#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ -#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ -#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ -/** @} */ - - -/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types - * @{ */ -#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ -#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ -#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ -#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ -#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ -#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ -#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ -#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ -/** @} */ - - -/** @defgroup BLE_GATTS_OPS GATT Server Operations - * @{ */ -#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ -#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ -#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ -#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ -#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ -#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ -/** @} */ - -/** @defgroup BLE_GATTS_VLOCS GATT Value Locations - * @{ */ -#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ -#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ -#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack - will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */ -/** @} */ - -/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types - * @{ */ -#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ -#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ -#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ -/** @} */ - -/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags - * @{ */ -#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ -#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ -/** @} */ - -/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values - * @{ - */ -#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */ -/** @} */ - -/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size - * @{ - */ -#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */ -#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */ -/** @} */ - -/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults - * @{ - */ -#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */ -/** @} */ - -/** @} */ - -/** @addtogroup BLE_GATTS_STRUCTURES Structures - * @{ */ - -/** - * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set. - */ -typedef struct -{ - uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission. - The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */ -} ble_gatts_conn_cfg_t; - -/**@brief Attribute metadata. */ -typedef struct -{ - ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ - ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ - uint8_t vlen :1; /**< Variable length attribute. */ - uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ - uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ - uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */ -} ble_gatts_attr_md_t; - - -/**@brief GATT Attribute. */ -typedef struct -{ - ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */ - ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */ - uint16_t init_len; /**< Initial attribute value length in bytes. */ - uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ - uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ - uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer - that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. - The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/ -} ble_gatts_attr_t; - -/**@brief GATT Attribute Value. */ -typedef struct -{ - uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ - uint16_t offset; /**< Attribute value offset. */ - uint8_t *p_value; /**< Pointer to where value is stored or will be stored. - If value is stored in user memory, only the attribute length is updated when p_value == NULL. - Set to NULL when reading to obtain the complete length of the attribute value */ -} ble_gatts_value_t; - - -/**@brief GATT Characteristic Presentation Format. */ -typedef struct -{ - uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ - int8_t exponent; /**< Exponent for integer data types. */ - uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */ - uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ - uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ -} ble_gatts_char_pf_t; - - -/**@brief GATT Characteristic metadata. */ -typedef struct -{ - ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ - ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ - uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ - uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ - uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ - ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ - ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ - ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ - ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ -} ble_gatts_char_md_t; - - -/**@brief GATT Characteristic Definition Handles. */ -typedef struct -{ - uint16_t value_handle; /**< Handle to the characteristic value. */ - uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ - uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ - uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ -} ble_gatts_char_handles_t; - - -/**@brief GATT HVx parameters. */ -typedef struct -{ - uint16_t handle; /**< Characteristic Value Handle. */ - uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ - uint16_t offset; /**< Offset within the attribute value. */ - uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after successful return. */ - uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */ -} ble_gatts_hvx_params_t; - -/**@brief GATT Authorization parameters. */ -typedef struct -{ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ - uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. - Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set, - as the data to be written needs to be stored and later provided by the application. */ - uint16_t offset; /**< Offset of the attribute value being updated. */ - uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ - uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */ -} ble_gatts_authorize_params_t; - -/**@brief GATT Read or Write Authorize Reply parameters. */ -typedef struct -{ - uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ - union { - ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ - ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ - } params; /**< Reply Parameters. */ -} ble_gatts_rw_authorize_reply_params_t; - -/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */ -typedef struct -{ - uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */ -} ble_gatts_cfg_service_changed_t; - -/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set. - * - * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: - * - The specified Attribute Table size is too small. - * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. - * - The specified Attribute Table size is not a multiple of 4. - */ -typedef struct -{ - uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */ -} ble_gatts_cfg_attr_tab_size_t; - -/**@brief Config structure for GATTS configurations. */ -typedef union -{ - ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */ - ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */ -} ble_gatts_cfg_t; - - -/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - ble_uuid_t uuid; /**< Attribute UUID. */ - uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ - uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */ - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; /**< Length of the received data. */ - uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. - See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ -} ble_gatts_evt_write_t; - -/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - ble_uuid_t uuid; /**< Attribute UUID. */ - uint16_t offset; /**< Offset for the read operation. */ -} ble_gatts_evt_read_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ -typedef struct -{ - uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ - union { - ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ - ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ - } request; /**< Request Parameters. */ -} ble_gatts_evt_rw_authorize_request_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ -typedef struct -{ - uint8_t hint; /**< Hint (currently unused). */ -} ble_gatts_evt_sys_attr_missing_t; - - -/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ -} ble_gatts_evt_hvc_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */ -typedef struct -{ - uint16_t client_rx_mtu; /**< Client RX MTU size. */ -} ble_gatts_evt_exchange_mtu_request_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ -typedef struct -{ - uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ -} ble_gatts_evt_timeout_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */ -typedef struct -{ - uint8_t count; /**< Number of notification transmissions completed. */ -} ble_gatts_evt_hvn_tx_complete_t; - -/**@brief GATTS event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ - union - { - ble_gatts_evt_write_t write; /**< Write Event Parameters. */ - ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ - ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ - ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ - ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */ - ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ - ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */ - } params; /**< Event Parameters. */ -} ble_gatts_evt_t; - -/** @} */ - -/** @addtogroup BLE_GATTS_FUNCTIONS Functions - * @{ */ - -/**@brief Add a service declaration to the Attribute Table. - * - * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to - * add a secondary service declaration that is not referenced by another service later in the Attribute Table. - * - * @mscs - * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} - * @endmscs - * - * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. - * @param[in] p_uuid Pointer to service UUID. - * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval ::NRF_SUCCESS Successfully added a service declaration. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); - - -/**@brief Add an include declaration to the Attribute Table. - * - * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). - * - * @note The included service must already be present in the Attribute Table prior to this call. - * - * @mscs - * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} - * @endmscs - * - * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] inc_srvc_handle Handle of the included service. - * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval ::NRF_SUCCESS Successfully added an include declaration. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - */ -SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); - - -/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table. - * - * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). - * - * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits, - * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values. - * - * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. - * - * @mscs - * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} - * @endmscs - * - * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] p_char_md Characteristic metadata. - * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. - * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. - * - * @retval ::NRF_SUCCESS Successfully added a characteristic. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - */ -SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); - - -/**@brief Add a descriptor to the Attribute Table. - * - * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). - * - * @mscs - * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} - * @endmscs - * - * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] p_attr Pointer to the attribute structure. - * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval ::NRF_SUCCESS Successfully added a descriptor. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - */ -SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); - -/**@brief Set the value of a given attribute. - * - * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist. - * - * @mscs - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. - * @param[in] handle Attribute handle. - * @param[in,out] p_value Attribute value information. - * - * @retval ::NRF_SUCCESS Successfully set the value of the attribute. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. - */ -SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); - -/**@brief Get the value of a given attribute. - * - * @note If the attribute value is longer than the size of the supplied buffer, - * p_len will return the total attribute value length (excluding offset), - * and not the number of bytes actually returned in p_data. - * The application may use this information to allocate a suitable buffer size. - * - * @note When retrieving system attribute values with this function, the connection handle - * may refer to an already disconnected connection. Refer to the documentation of - * @ref sd_ble_gatts_sys_attr_get for further information. - * - * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. - * @param[in] handle Attribute handle. - * @param[in,out] p_value Attribute value information. - * - * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. - * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - */ -SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); - -/**@brief Notify or Indicate an attribute value. - * - * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation - * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that - * the application can atomically perform a value update and a server initiated transaction with a single API call. - * - * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. - * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, - * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES. - * The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len). - * - * @note Only one indication procedure can be ongoing per connection at a time. - * If the application tries to indicate an attribute value while another indication procedure is ongoing, - * the function call will return @ref NRF_ERROR_BUSY. - * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer. - * - * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size - * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. - * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete. - * - * @note The application can keep track of the available queue element count for notifications by following the procedure below: - * - Store initial queue element count in a variable. - * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. - * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event. - * - * @events - * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.} - * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} - * @mmsc{@ref BLE_GATTS_HVN_MSC} - * @mmsc{@ref BLE_GATTS_HVI_MSC} - * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with - * the contents pointed by it before sending the notification or indication. - * - * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: - * - Invalid Connection State - * - Notifications and/or indications not enabled in the CCCD - * - An ATT_MTU exchange is ongoing - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. - * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry. - * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - * @retval ::NRF_ERROR_RESOURCES Too many notifications queued. - * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry. - */ -SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); - -/**@brief Indicate the Service Changed attribute value. - * - * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute - * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will - * be issued. - * - * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. - * - * @events - * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_GATTS_SC_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] start_handle Start of affected attribute handle range. - * @param[in] end_handle End of affected attribute handle range. - * - * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref - * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t. - * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: - * - Invalid Connection State - * - Notifications and/or indications not enabled in the CCCD - * - An ATT_MTU exchange is ongoing - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. - * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - */ -SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); - -/**@brief Respond to a Read/Write authorization request. - * - * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. - * - * @mscs - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} - * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} - * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. - * - * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond - * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update - * is set to 0. - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. - * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, - * handle supplied does not match requested handle, - * or invalid data to be written provided by the application. - */ -SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); - - -/**@brief Update persistent system attribute information. - * - * @details Supply information about persistent system attributes to the stack, - * previously obtained using @ref sd_ble_gatts_sys_attr_get. - * This call is only allowed for active connections, and is usually - * made immediately after a connection is established with an known bonded device, - * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. - * - * p_sysattrs may point directly to the application's stored copy of the system attributes - * obtained using @ref sd_ble_gatts_sys_attr_get. - * If the pointer is NULL, the system attribute info is initialized, assuming that - * the application does not have any previously saved system attribute data for this device. - * - * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. - * - * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. - * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or - * reset the SoftDevice to return to a known state. - * - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. - * - * @mscs - * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} - * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} - * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. - * @param[in] len Size of data pointed by p_sys_attr_data, in octets. - * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS - * - * @retval ::NRF_SUCCESS Successfully set the system attribute information. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. - * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); - - -/**@brief Retrieve persistent system attribute information from the stack. - * - * @details This call is used to retrieve information about values to be stored persistently by the application - * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, - * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set. - * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for - * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it. - * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes - * may be written to at any time by the peer during a connection's lifetime. - * - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. - * - * @mscs - * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} - * @endmscs - * - * @param[in] conn_handle Connection handle of the recently terminated connection. - * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described - * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. - * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data. - * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS - * - * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. - * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. - * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. - */ -SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); - - -/**@brief Retrieve the first valid user attribute handle. - * - * @param[out] p_handle Pointer to an integer where the handle will be stored. - * - * @retval ::NRF_SUCCESS Successfully retrieved the handle. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); - -/**@brief Retrieve the attribute UUID and/or metadata. - * - * @param[in] handle Attribute handle - * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. - * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. - * - * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. - * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. - */ -SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md)); - -/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client. - * - * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. - * - * @details The SoftDevice sets ATT_MTU to the minimum of: - * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and - * - The Server RX MTU value. - * - * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. - * - * @mscs - * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} - * @endmscs - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] server_rx_mtu Server RX MTU size. - * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. - * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration - used for this connection. - * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request - * if an ATT_MTU exchange has already been performed in the other direction. - * - * @retval ::NRF_SUCCESS Successfully sent response to the client. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied. - */ -SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)); -/** @} */ - -#ifdef __cplusplus -} -#endif -#endif // BLE_GATTS_H__ - -/** - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_hci.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_hci.h deleted file mode 100644 index f0dde9a03adb9..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_hci.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_COMMON - @{ -*/ - - -#ifndef BLE_HCI_H__ -#define BLE_HCI_H__ -#ifdef __cplusplus -extern "C" { -#endif - -/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes - * @{ */ - -#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ -#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ -#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ -/*0x03 Hardware Failure -0x04 Page Timeout -*/ -#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ -#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ -#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ -#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ -/*0x09 Connection Limit Exceeded -0x0A Synchronous Connection Limit To A Device Exceeded -0x0B ACL Connection Already Exists*/ -#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ -/*0x0D Connection Rejected due to Limited Resources -0x0E Connection Rejected Due To Security Reasons -0x0F Connection Rejected due to Unacceptable BD_ADDR -0x10 Connection Accept Timeout Exceeded -0x11 Unsupported Feature or Parameter Value*/ -#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ -#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ -#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/ -#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ -#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ -/* -0x17 Repeated Attempts -0x18 Pairing Not Allowed -0x19 Unknown LMP PDU -*/ -#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ -/* -0x1B SCO Offset Rejected -0x1C SCO Interval Rejected -0x1D SCO Air Mode Rejected*/ -#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ -#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ -/*0x20 Unsupported LMP Parameter Value -0x21 Role Change Not Allowed -*/ -#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ -#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */ -#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ -/*0x25 Encryption Mode Not Acceptable -0x26 Link Key Can Not be Changed -0x27 Requested QoS Not Supported -*/ -#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ -#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ -#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ -/* -0x2B Reserved -0x2C QoS Unacceptable Parameter -0x2D QoS Rejected -0x2E Channel Classification Not Supported -0x2F Insufficient Security -*/ -#define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */ -/* -0x31 Reserved -0x32 Role Switch Pending -0x33 Reserved -0x34 Reserved Slot Violation -0x35 Role Switch Failed -0x36 Extended Inquiry Response Too Large -0x37 Secure Simple Pairing Not Supported By Host. -0x38 Host Busy - Pairing -0x39 Connection Rejected due to No Suitable Channel Found*/ -#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ -#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ -#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */ -#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ -#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ - -/** @} */ - - -#ifdef __cplusplus -} -#endif -#endif // BLE_HCI_H__ - -/** @} */ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_l2cap.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_l2cap.h deleted file mode 100644 index 3b53ded092607..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_l2cap.h +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) - @{ - @brief Definitions and prototypes for the L2CAP interface. - */ - -#ifndef BLE_L2CAP_H__ -#define BLE_L2CAP_H__ - -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_err.h" -#include "nrf_svc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology - * @{ - * @details - * - * L2CAP SDU - * - A data unit that the application can send/receive to/from a peer. - * - * L2CAP PDU - * - A data unit that is exchanged between local and remote L2CAP entities. - * It consists of L2CAP protocol control information and payload fields. - * The payload field can contain an L2CAP SDU or a part of an L2CAP SDU. - * - * L2CAP MTU - * - The maximum length of an L2CAP SDU. - * - * L2CAP MPS - * - The maximum length of an L2CAP PDU payload field. - * - * Credits - * - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer. - * @} */ - -/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations - * @{ */ - -/**@brief L2CAP API SVC numbers. */ -enum BLE_L2CAP_SVCS -{ - SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE, /**< Set up an L2CAP channel. */ - SD_BLE_L2CAP_CH_RELEASE, /**< Release an L2CAP channel. */ - SD_BLE_L2CAP_CH_RX, /**< Receive an SDU on an L2CAP channel. */ - SD_BLE_L2CAP_CH_TX, /**< Transmit an SDU on an L2CAP channel. */ - SD_BLE_L2CAP_CH_FLOW_CONTROL, /**< Advanced SDU reception flow control. */ -}; - -/**@brief L2CAP Event IDs. */ -enum BLE_L2CAP_EVTS -{ - BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE, /**< L2CAP Channel Setup Request event. - \n See @ref ble_l2cap_evt_ch_setup_request_t. */ - BLE_L2CAP_EVT_CH_SETUP_REFUSED, /**< L2CAP Channel Setup Refused event. - \n See @ref ble_l2cap_evt_ch_setup_refused_t. */ - BLE_L2CAP_EVT_CH_SETUP, /**< L2CAP Channel Setup Completed event. - \n See @ref ble_l2cap_evt_ch_setup_t. */ - BLE_L2CAP_EVT_CH_RELEASED, /**< L2CAP Channel Released event. - \n No additional event structure applies. */ - BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED, /**< L2CAP Channel SDU data buffer released event. - \n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */ - BLE_L2CAP_EVT_CH_CREDIT, /**< L2CAP Channel Credit received. - \n See @ref ble_l2cap_evt_ch_credit_t. */ - BLE_L2CAP_EVT_CH_RX, /**< L2CAP Channel SDU received. - \n See @ref ble_l2cap_evt_ch_rx_t. */ - BLE_L2CAP_EVT_CH_TX, /**< L2CAP Channel SDU transmitted. - \n See @ref ble_l2cap_evt_ch_tx_t. */ -}; - -/** @} */ - -/**@addtogroup BLE_L2CAP_DEFINES Defines - * @{ */ - -/**@brief Maximum number of L2CAP channels per connection. */ -#define BLE_L2CAP_CH_COUNT_MAX (64) - -/**@brief Minimum L2CAP MTU, in bytes. */ -#define BLE_L2CAP_MTU_MIN (23) - -/**@brief Minimum L2CAP MPS, in bytes. */ -#define BLE_L2CAP_MPS_MIN (23) - -/**@brief Invalid CID. */ -#define BLE_L2CAP_CID_INVALID (0x0000) - -/**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */ -#define BLE_L2CAP_CREDITS_DEFAULT (1) - -/**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources - * @{ */ -#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */ -#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */ - /** @} */ - - /** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes - * @{ */ -#define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */ -#define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */ -#define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */ -#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */ -#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */ -#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */ -#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */ -#define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */ -#define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */ -#define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */ -#define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */ -#define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */ -/** @} */ - -/** @} */ - -/**@addtogroup BLE_L2CAP_STRUCTURES Structures - * @{ */ - -/** - * @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set. - * - * @note These parameters are set per connection, so all L2CAP channels created on this connection - * will have the same parameters. - * - * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: - * - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. - * - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. - * - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX. - * @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high. - */ -typedef struct -{ - uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall - be able to receive on L2CAP channels on connections with this - configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ - uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall - be able to transmit on L2CAP channels on connections with this - configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ - uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per - L2CAP channel. The minimum value is one. */ - uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission - per L2CAP channel. The minimum value is one. */ - uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection - with this configuration. The default value is zero, the maximum - value is @ref BLE_L2CAP_CH_COUNT_MAX. - @note if this parameter is set to zero, all other parameters in - @ref ble_l2cap_conn_cfg_t are ignored. */ -} ble_l2cap_conn_cfg_t; - -/**@brief L2CAP channel RX parameters. */ -typedef struct -{ - uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to - receive on this L2CAP channel. - - Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */ - uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be - able to receive on this L2CAP channel. - - Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN. - - Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */ - ble_data_t sdu_buf; /**< SDU data buffer for reception. - - If @ref ble_data_t::p_data is non-NULL, initial credits are - issued to the peer. - - If @ref ble_data_t::p_data is NULL, no initial credits are - issued to the peer. */ -} ble_l2cap_ch_rx_params_t; - -/**@brief L2CAP channel setup parameters. */ -typedef struct -{ - ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */ - uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting - setup of an L2CAP channel, ignored otherwise. */ - uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES. - Used when replying to a setup request of an L2CAP - channel, ignored otherwise. */ -} ble_l2cap_ch_setup_params_t; - -/**@brief L2CAP channel TX parameters. */ -typedef struct -{ - uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to - transmit on this L2CAP channel. */ - uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is - able to receive on this L2CAP channel. */ - uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able - to transmit on this L2CAP channel. This is effective tx_mps, - selected by the SoftDevice as - MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */ - uint16_t credits; /**< Initial credits given by the peer. */ -} ble_l2cap_ch_tx_params_t; - -/**@brief L2CAP Channel Setup Request event. */ -typedef struct -{ - ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ - uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */ -} ble_l2cap_evt_ch_setup_request_t; - -/**@brief L2CAP Channel Setup Refused event. */ -typedef struct -{ - uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */ - uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */ -} ble_l2cap_evt_ch_setup_refused_t; - -/**@brief L2CAP Channel Setup Completed event. */ -typedef struct -{ - ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ -} ble_l2cap_evt_ch_setup_t; - -/**@brief L2CAP Channel SDU Data Duffer Released event. */ -typedef struct -{ - ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice - returns SDU data buffers supplied by the application, which have - not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or - @ref BLE_L2CAP_EVT_CH_TX event. */ -} ble_l2cap_evt_ch_sdu_buf_released_t; - -/**@brief L2CAP Channel Credit received event. */ -typedef struct -{ - uint16_t credits; /**< Additional credits given by the peer. */ -} ble_l2cap_evt_ch_credit_t; - -/**@brief L2CAP Channel received SDU event. */ -typedef struct -{ - uint16_t sdu_len; /**< Total SDU length, in bytes. */ - ble_data_t sdu_buf; /**< SDU data buffer. - @note If there is not enough space in the buffer - (sdu_buf.len < sdu_len) then the rest of the SDU will be - silently discarded by the SoftDevice. */ -} ble_l2cap_evt_ch_rx_t; - -/**@brief L2CAP Channel transmitted SDU event. */ -typedef struct -{ - ble_data_t sdu_buf; /**< SDU data buffer. */ -} ble_l2cap_evt_ch_tx_t; - -/**@brief L2CAP event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which the event occured. */ - uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or - @ref BLE_L2CAP_CID_INVALID if not present. */ - union - { - ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */ - ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */ - ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */ - ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released;/**< L2CAP Channel SDU Data Buffer Released Event Parameters. */ - ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */ - ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */ - ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */ - } params; /**< Event Parameters. */ -} ble_l2cap_evt_t; - -/** @} */ - -/**@addtogroup BLE_L2CAP_FUNCTIONS Functions - * @{ */ - -/**@brief Set up an L2CAP channel. - * - * @details This function is used to: - * - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer. - * - Reply to a setup request of an L2CAP channel (if called in response to a - * @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection - * Response packet to a peer. - * - * @note A call to this function will require the application to keep the SDU data buffer alive - * until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or - * @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. - * - * @events - * @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.} - * @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC} - * @endmscs - * - * @param[in] conn_handle Connection Handle. - * @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel: - * - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP - * channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST - * event when replying to a setup request of an L2CAP channel. - * - As output: local_cid for this channel. - * @param[in] p_params L2CAP channel parameters. - * - * @retval ::NRF_SUCCESS Successfully queued request or response for transmission. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link. - * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up). - * @retval ::NRF_ERROR_NOT_FOUND CID not found. - * @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels, - * see @ref ble_l2cap_conn_cfg_t::ch_count. - */ -SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params)); - -/**@brief Release an L2CAP channel. - * - * @details This sends a Disconnection Request packet to a peer. - * - * @events - * @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC} - * @endmscs - * - * @param[in] conn_handle Connection Handle. - * @param[in] local_cid Local Channel ID of the L2CAP channel. - * - * @retval ::NRF_SUCCESS Successfully queued request for transmission. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is - * in progress for the L2CAP channel). - * @retval ::NRF_ERROR_NOT_FOUND CID not found. - */ -SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid)); - -/**@brief Receive an SDU on an L2CAP channel. - * - * @details This may issue additional credits to the peer using an LE Flow Control Credit packet. - * - * @note A call to this function will require the application to keep the memory pointed by - * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX - * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. - * - * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers - * for reception per L2CAP channel. - * - * @events - * @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_L2CAP_CH_RX_MSC} - * @endmscs - * - * @param[in] conn_handle Connection Handle. - * @param[in] local_cid Local Channel ID of the L2CAP channel. - * @param[in] p_sdu_buf Pointer to the SDU data buffer. - * - * @retval ::NRF_SUCCESS Buffer accepted. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is - * in progress for an L2CAP channel). - * @retval ::NRF_ERROR_NOT_FOUND CID not found. - * @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a - * @ref BLE_L2CAP_EVT_CH_RX event and retry. - */ -SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); - -/**@brief Transmit an SDU on an L2CAP channel. - * - * @note A call to this function will require the application to keep the memory pointed by - * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX - * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. - * - * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for - * transmission per L2CAP channel. - * - * @note The application can keep track of the available credits for transmission by following - * the procedure below: - * - Store initial credits given by the peer in a variable. - * (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) - * - Decrement the variable, which stores the currently available credits, by - * ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns - * @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) - * - Increment the variable, which stores the currently available credits, by additional - * credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event. - * - * @events - * @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.} - * @endevents - * - * @mscs - * @mmsc{@ref BLE_L2CAP_CH_TX_MSC} - * @endmscs - * - * @param[in] conn_handle Connection Handle. - * @param[in] local_cid Local Channel ID of the L2CAP channel. - * @param[in] p_sdu_buf Pointer to the SDU data buffer. - * - * @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is - * in progress for the L2CAP channel). - * @retval ::NRF_ERROR_NOT_FOUND CID not found. - * @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than - * @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in - * @ref BLE_L2CAP_EVT_CH_SETUP event. - * @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a - * @ref BLE_L2CAP_EVT_CH_TX event and retry. - */ -SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); - -/**@brief Advanced SDU reception flow control. - * - * @details Adjust the way the SoftDevice issues credits to the peer. - * This may issue additional credits to the peer using an LE Flow Control Credit packet. - * - * @mscs - * @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC} - * @endmscs - * - * @param[in] conn_handle Connection Handle. - * @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set - * the value that will be used for newly created channels. - * @param[in] credits Number of credits that the SoftDevice will make sure the peer has every - * time it starts using a new reception buffer. - * - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will - * use if this function is not called. - * - If set to zero, the SoftDevice will stop issuing credits for new reception - * buffers the application provides or has provided. SDU reception that is - * currently ongoing will be allowed to complete. - * @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be - * written by the SoftDevice with the number of credits that is or will be - * available to the peer. If the value written by the SoftDevice is 0 when - * credits parameter was set to 0, the peer will not be able to send more - * data until more credits are provided by calling this function again with - * credits > 0. This parameter is ignored when local_cid is set to @ref - * BLE_L2CAP_CID_INVALID. - * - * @note Application should take care when setting number of credits higher than default value. In - * this case the application must make sure that the SoftDevice always has reception buffers - * available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have - * such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic - * on the connection handle may be stalled until the SoftDevice again has an available - * reception buffer. This applies even if the application has used this call to set the - * credits back to default, or zero. - * - * @retval ::NRF_SUCCESS Flow control parameters accepted. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is - * in progress for an L2CAP channel). - * @retval ::NRF_ERROR_NOT_FOUND CID not found. - */ -SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits)); - -/** @} */ - -#ifdef __cplusplus -} -#endif -#endif // BLE_L2CAP_H__ - -/** - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_ranges.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_ranges.h deleted file mode 100644 index 5b9d89140214a..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_ranges.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_COMMON - @{ - @defgroup ble_ranges Module specific SVC, event and option number subranges - @{ - - @brief Definition of SVC, event and option number subranges for each API module. - - @note - SVCs, event and option numbers are split into subranges for each API module. - Each module receives its entire allocated range of SVC calls, whether implemented or not, - but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. - - Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, - rather than the last SVC function call actually defined and implemented. - - Specific SVC, event and option values are defined in each module's ble_.h file, - which defines names of each individual SVC code based on the range start value. -*/ - -#ifndef BLE_RANGES_H__ -#define BLE_RANGES_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ -#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */ - -#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */ -#define BLE_GAP_SVC_LAST 0x93 /**< GAP BLE SVC last. */ - -#define BLE_GATTC_SVC_BASE 0x94 /**< GATTC BLE SVC base. */ -#define BLE_GATTC_SVC_LAST 0x9F /**< GATTC BLE SVC last. */ - -#define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */ -#define BLE_GATTS_SVC_LAST 0xAF /**< GATTS BLE SVC last. */ - -#define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */ -#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */ - - -#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ - -#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ -#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */ - -#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ -#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */ - -#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ -#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */ - -#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ -#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */ - -#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ -#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */ - - -#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ - -#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ -#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */ - -#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ -#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */ - -#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */ -#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */ - -#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */ -#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */ - -#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */ -#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */ - -#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */ -#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */ - - -#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */ - -#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */ -#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */ - -#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */ -#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */ - -#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */ -#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */ - -#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */ -#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */ - -#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */ -#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */ - -#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */ -#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */ - -#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */ -#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */ - - - - - -#ifdef __cplusplus -} -#endif -#endif /* BLE_RANGES_H__ */ - -/** - @} - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_types.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_types.h deleted file mode 100644 index 88c93180c83da..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/ble_types.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup BLE_COMMON - @{ - @defgroup ble_types Common types and macro definitions - @{ - - @brief Common types and macro definitions for the BLE SoftDevice. - */ - -#ifndef BLE_TYPES_H__ -#define BLE_TYPES_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup BLE_TYPES_DEFINES Defines - * @{ */ - -/** @defgroup BLE_CONN_HANDLES BLE Connection Handles - * @{ */ -#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ -#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ -/** @} */ - - -/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs - * @{ */ -/* Generic UUIDs, applicable to all services */ -#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ -#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ -#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ -#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ -#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ -#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ -#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ -/* GATT specific UUIDs */ -#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ -#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ -/* GAP specific UUIDs */ -#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ -#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */ -/** @} */ - - -/** @defgroup BLE_UUID_TYPES Types of UUID - * @{ */ -#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ -#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ -#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ -/** @} */ - - -/** @defgroup BLE_APPEARANCES Bluetooth Appearance values - * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml - * @{ */ -#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ -#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ -#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ -#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ -#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ -#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ -#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ -#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ -#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ -#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ -#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ -#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ -#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ -#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ -#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ -#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ -#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ -#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ -#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ -#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ -#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ -#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ -#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ -#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */ -#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ -#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ -#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ -#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ -#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ -#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ -#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ -#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ -#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ -#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ -#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ -#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ -#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ -#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ -#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ -#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ -#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ -#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ -/** @} */ - -/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */ -#define BLE_UUID_BLE_ASSIGN(instance, value) do {\ - instance.type = BLE_UUID_TYPE_BLE; \ - instance.uuid = value;} while(0) - -/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ -#define BLE_UUID_COPY_PTR(dst, src) do {\ - (dst)->type = (src)->type; \ - (dst)->uuid = (src)->uuid;} while(0) - -/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ -#define BLE_UUID_COPY_INST(dst, src) do {\ - (dst).type = (src).type; \ - (dst).uuid = (src).uuid;} while(0) - -/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ -#define BLE_UUID_EQ(p_uuid1, p_uuid2) \ - (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) - -/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ -#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \ - (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) - -/** @} */ - -/** @addtogroup BLE_TYPES_STRUCTURES Structures - * @{ */ - -/** @brief 128 bit UUID values. */ -typedef struct -{ - uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ -} ble_uuid128_t; - -/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ -typedef struct -{ - uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ - uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ -} ble_uuid_t; - -/**@brief Data structure. */ -typedef struct -{ - uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */ - uint16_t len; /**< Length of the data buffer, in bytes. */ -} ble_data_t; - -/** @} */ -#ifdef __cplusplus -} -#endif - -#endif /* BLE_TYPES_H__ */ - -/** - @} - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf52/nrf_mbr.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf52/nrf_mbr.h deleted file mode 100644 index c95bb8d4fd7fc..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf52/nrf_mbr.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @defgroup nrf_mbr_api Master Boot Record API - @{ - - @brief APIs for updating SoftDevice and BootLoader - -*/ - -#ifndef NRF_MBR_H__ -#define NRF_MBR_H__ - -#include "nrf_svc.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup NRF_MBR_DEFINES Defines - * @{ */ - -/**@brief MBR SVC Base number. */ -#define MBR_SVC_BASE (0x18) - -/**@brief Page size in words. */ -#define MBR_PAGE_SIZE_IN_WORDS (1024) - -/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash. -This is the offset where the first byte of the SoftDevice hex file is written.*/ -#define MBR_SIZE (0x1000) - -/** @} */ - -/** @addtogroup NRF_MBR_ENUMS Enumerations - * @{ */ - -/**@brief nRF Master Boot Record API SVC numbers. */ -enum NRF_MBR_SVCS -{ - SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ -}; - -/**@brief Possible values for ::sd_mbr_command_t.command */ -enum NRF_MBR_COMMANDS -{ - SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t*/ - SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ - SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD*/ - SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ - SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset @see ::sd_mbr_command_vector_table_base_set_t*/ - SD_MBR_COMMAND_RESERVED, - SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address @see ::sd_mbr_command_irq_forward_address_set_t*/ -}; - -/** @} */ - -/** @addtogroup NRF_MBR_TYPES Types - * @{ */ - -/**@brief This command copies part of a new SoftDevice - * The destination area is erased before copying. - * If dst is in the middle of a flash page, that whole flash page will be erased. - * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. - * - * The user of this function is responsible for setting the BPROT registers. - * - * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. - * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. - */ -typedef struct -{ - uint32_t *src; /**< Pointer to the source of data to be copied.*/ - uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ - uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/ -} sd_mbr_command_copy_sd_t; - - -/**@brief This command works like memcmp, but takes the length in words. - * - * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. - * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. - */ -typedef struct -{ - uint32_t *ptr1; /**< Pointer to block of memory. */ - uint32_t *ptr2; /**< Pointer to block of memory. */ - uint32_t len; /**< Number of 32 bit words to compare.*/ -} sd_mbr_command_compare_t; - - -/**@brief This command copies a new BootLoader. - * With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR. - * - * Destination is erased by this function. - * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. - * - * This function will use PROTENSET to protect the flash that is not intended to be written. - * - * On success, this function will not return. It will start the new BootLoader from reset-vector as normal. - * - * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. - * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. - * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. - * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info) - */ -typedef struct -{ - uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/ - uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ -} sd_mbr_command_copy_bl_t; - -/**@brief Change the address the MBR starts after a reset - * - * Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset. - * - * To restore default forwarding this function should be called with @param address set to 0. - * The MBR will then start forwarding to interrupts to the address in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set. - * - * On success, this function will not return. It will reset the device. - * - * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. - * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. - * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info) - */ -typedef struct -{ - uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ -} sd_mbr_command_vector_table_base_set_t; - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR - * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not - * change where the MBR starts after reset. - * - * @retval ::NRF_SUCCESS - */ -typedef struct -{ - uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ -} sd_mbr_command_irq_forward_address_set_t; - -typedef struct -{ - uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */ - union - { - sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ - sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ - sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ - sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ - sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/ - } params; -} sd_mbr_command_t; - -/** @} */ - -/** @addtogroup NRF_MBR_FUNCTIONS Functions - * @{ */ - -/**@brief Issue Master Boot Record commands - * - * Commands used when updating a SoftDevice and bootloader. - * - * The SD_MBR_COMMAND_COPY_BL and SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires parameters to be - * retained by the MBR when resetting the IC. This is done in a separate flash page - * provided by the application. The UICR register UICR.NRFFW[1] must be set - * to an address corresponding to a page in the application flash space. This page will be cleared - * by the MBR and used to store the command before reset. When the UICR.NRFFW[1] field is set - * the page it refers to must not be used by the application. If the UICR.NRFFW[1] is set to - * 0xFFFFFFFF (the default) MBR commands which use flash will be unavailable and return - * NRF_ERROR_NO_MEM. - * - * @param[in] param Pointer to a struct describing the command. - * - * @note For return values, see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t ::sd_mbr_command_vector_table_base_set_t ::sd_mbr_command_irq_forward_address_set_t - * - * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). - * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. -*/ -SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); - -/** @} */ - -#ifdef __cplusplus -} -#endif -#endif // NRF_MBR_H__ - -/** - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error.h deleted file mode 100644 index 6badee98e56df..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - /** - @defgroup nrf_error SoftDevice Global Error Codes - @{ - - @brief Global Error definitions -*/ - -/* Header guard */ -#ifndef NRF_ERROR_H__ -#define NRF_ERROR_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions - * @{ */ -#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base -#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base -#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base -#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base -/** @} */ - -#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command -#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing -#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled -#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error -#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation -#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found -#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported -#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter -#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state -#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length -#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags -#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data -#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size -#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out -#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer -#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation -#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address -#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy -#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. -#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation - -#ifdef __cplusplus -} -#endif -#endif // NRF_ERROR_H__ - -/** - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error_sdm.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error_sdm.h deleted file mode 100644 index 530959b9d67ad..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error_sdm.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - /** - @addtogroup nrf_sdm_api - @{ - @defgroup nrf_sdm_error SoftDevice Manager Error Codes - @{ - - @brief Error definitions for the SDM API -*/ - -/* Header guard */ -#ifndef NRF_ERROR_SDM_H__ -#define NRF_ERROR_SDM_H__ - -#include "nrf_error.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source. -#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). -#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). - -#ifdef __cplusplus -} -#endif -#endif // NRF_ERROR_SDM_H__ - -/** - @} - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error_soc.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error_soc.h deleted file mode 100644 index 1e784b8db3832..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_error_soc.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @addtogroup nrf_soc_api - @{ - @defgroup nrf_soc_error SoC Library Error Codes - @{ - - @brief Error definitions for the SoC library - -*/ - -/* Header guard */ -#ifndef NRF_ERROR_SOC_H__ -#define NRF_ERROR_SOC_H__ - -#include "nrf_error.h" -#ifdef __cplusplus -extern "C" { -#endif - -/* Mutex Errors */ -#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken - -/* NVIC errors */ -#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available -#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed -#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return - -/* Power errors */ -#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown -#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown -#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return - -/* Rand errors */ -#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values - -/* PPI errors */ -#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel -#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group - -#ifdef __cplusplus -} -#endif -#endif // NRF_ERROR_SOC_H__ -/** - @} - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_nvic.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_nvic.h deleted file mode 100644 index 40537b45a2177..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_nvic.h +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @defgroup nrf_nvic_api SoftDevice NVIC API - * @{ - * - * @note In order to use this module, the following code has to be added to a .c file: - * \code - * nrf_nvic_state_t nrf_nvic_state = {0}; - * \endcode - * - * @note Definitions and declarations starting with __ (double underscore) in this header file are - * not intended for direct use by the application. - * - * @brief APIs for the accessing NVIC when using a SoftDevice. - * - */ - -#ifndef NRF_NVIC_H__ -#define NRF_NVIC_H__ - -#include -#include "nrf.h" - -#include "nrf_error_soc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/**@addtogroup NRF_NVIC_DEFINES Defines - * @{ */ - -/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions - * @{ */ - -#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */ - -#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ - -/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */ -#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ - (1U << POWER_CLOCK_IRQn) \ - | (1U << RADIO_IRQn) \ - | (1U << RTC0_IRQn) \ - | (1U << TIMER0_IRQn) \ - | (1U << RNG_IRQn) \ - | (1U << ECB_IRQn) \ - | (1U << CCM_AAR_IRQn) \ - | (1U << TEMP_IRQn) \ - | (1U << __NRF_NVIC_NVMC_IRQn) \ - | (1U << (uint32_t)SWI5_EGU5_IRQn) \ - )) - -/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */ -#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) - -/**@brief Interrupts available for to application, with IRQn in the range 0-31. */ -#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) - -/**@brief Interrupts available for to application, with IRQn in the range 32-63. */ -#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) - -/**@} */ - -/**@} */ - -/**@addtogroup NRF_NVIC_VARIABLES Variables - * @{ */ - -/**@brief Type representing the state struct for the SoftDevice NVIC module. */ -typedef struct -{ - uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ - uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ -} nrf_nvic_state_t; - -/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an - * application source file. */ -extern nrf_nvic_state_t nrf_nvic_state; - -/**@} */ - -/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions - * @{ */ - -/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. - * - * @retval The value of PRIMASK prior to disabling the interrupts. - */ -__STATIC_INLINE int __sd_nvic_irq_disable(void); - -/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. - */ -__STATIC_INLINE void __sd_nvic_irq_enable(void); - -/**@brief Checks if IRQn is available to application - * @param[in] IRQn IRQ to check - * - * @retval 1 (true) if the IRQ to check is available to the application - */ -__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn); - -/**@brief Checks if priority is available to application - * @param[in] priority priority to check - * - * @retval 1 (true) if the priority to check is available to the application - */ -__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority); - -/**@} */ - -/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions - * @{ */ - -/**@brief Enable External Interrupt. - * @note Corresponds to NVIC_EnableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was enabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. - */ -__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); - -/**@brief Disable External Interrupt. - * @note Corresponds to NVIC_DisableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was disabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - */ -__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); - -/**@brief Get Pending Interrupt. - * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. - * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. - * - * @retval ::NRF_SUCCESS The interrupt is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); - -/**@brief Set Pending Interrupt. - * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt is set pending. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); - -/**@brief Clear Pending Interrupt. - * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); - -/**@brief Set Interrupt Priority. - * @note Corresponds to NVIC_SetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * @pre Priority is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. - * @param[in] priority A valid IRQ priority for use by the application. - * - * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. - */ -__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); - -/**@brief Get Interrupt Priority. - * @note Corresponds to NVIC_GetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. - * @param[out] p_priority Return value from NVIC_GetPriority. - * - * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. - */ -__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority); - -/**@brief System Reset. - * @note Corresponds to NVIC_SystemReset in CMSIS. - * - * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN - */ -__STATIC_INLINE uint32_t sd_nvic_SystemReset(void); - -/**@brief Enter critical region. - * - * @post Application interrupts will be disabled. - * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each - * execution context - * @sa sd_nvic_critical_region_exit - * - * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. - * - * @retval ::NRF_SUCCESS - */ -__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); - -/**@brief Exit critical region. - * - * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. - * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. - * - * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. - * - * @retval ::NRF_SUCCESS - */ -__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); - -/**@} */ - -#ifndef SUPPRESS_INLINE_IMPLEMENTATION - -__STATIC_INLINE int __sd_nvic_irq_disable(void) -{ - int pm = __get_PRIMASK(); - __disable_irq(); - return pm; -} - -__STATIC_INLINE void __sd_nvic_irq_enable(void) -{ - __enable_irq(); -} - -__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) -{ - if (IRQn < 32) - { - return ((1UL<= (1 << __NVIC_PRIO_BITS)) - { - return 0; - } - if( priority == 0 - || priority == 1 - || priority == 4 - ) - { - return 0; - } - return 1; -} - - -__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) -{ - if (!__sd_nvic_app_accessible_irq(IRQn)) - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; - } - if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; - } - - if (nrf_nvic_state.__cr_flag) - { - nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); - } - else - { - NVIC_EnableIRQ(IRQn); - } - return NRF_SUCCESS; -} - -__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) -{ - if (!__sd_nvic_app_accessible_irq(IRQn)) - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; - } - - if (nrf_nvic_state.__cr_flag) - { - nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F)); - } - else - { - NVIC_DisableIRQ(IRQn); - } - - return NRF_SUCCESS; -} - -__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) -{ - if (__sd_nvic_app_accessible_irq(IRQn)) - { - *p_pending_irq = NVIC_GetPendingIRQ(IRQn); - return NRF_SUCCESS; - } - else - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; - } -} - -__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) -{ - if (__sd_nvic_app_accessible_irq(IRQn)) - { - NVIC_SetPendingIRQ(IRQn); - return NRF_SUCCESS; - } - else - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; - } -} - -__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) -{ - if (__sd_nvic_app_accessible_irq(IRQn)) - { - NVIC_ClearPendingIRQ(IRQn); - return NRF_SUCCESS; - } - else - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; - } -} - -__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if (!__sd_nvic_app_accessible_irq(IRQn)) - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; - } - - if (!__sd_nvic_is_app_accessible_priority(priority)) - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; - } - - NVIC_SetPriority(IRQn, (uint32_t)priority); - return NRF_SUCCESS; -} - -__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) -{ - if (__sd_nvic_app_accessible_irq(IRQn)) - { - *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); - return NRF_SUCCESS; - } - else - { - return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; - } -} - -__STATIC_INLINE uint32_t sd_nvic_SystemReset(void) -{ - NVIC_SystemReset(); - return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; -} - -__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) -{ - int was_masked = __sd_nvic_irq_disable(); - if (!nrf_nvic_state.__cr_flag) - { - nrf_nvic_state.__cr_flag = 1; - nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); - NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; - nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); - NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; - *p_is_nested_critical_region = 0; - } - else - { - *p_is_nested_critical_region = 1; - } - if (!was_masked) - { - __sd_nvic_irq_enable(); - } - return NRF_SUCCESS; -} - -__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) -{ - if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) - { - int was_masked = __sd_nvic_irq_disable(); - NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; - NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; - nrf_nvic_state.__cr_flag = 0; - if (!was_masked) - { - __sd_nvic_irq_enable(); - } - } - - return NRF_SUCCESS; -} - -#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ - -#ifdef __cplusplus -} -#endif - -#endif // NRF_NVIC_H__ - -/**@} */ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_sdm.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_sdm.h deleted file mode 100644 index c41d86d46bc10..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_sdm.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - @defgroup nrf_sdm_api SoftDevice Manager API - @{ - - @brief APIs for SoftDevice management. - -*/ - -#ifndef NRF_SDM_H__ -#define NRF_SDM_H__ - -#include "nrf_svc.h" -#include "nrf.h" -#include "nrf_soc.h" -#include "nrf_error_sdm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup NRF_SDM_DEFINES Defines - * @{ */ -#ifdef NRFSOC_DOXYGEN -/// Declared in nrf_mbr.h -#define MBR_SIZE 0 -#warning test -#endif - -/** @brief The major version for the SoftDevice binary distributed with this header file. */ -#define SD_MAJOR_VERSION (5) - -/** @brief The minor version for the SoftDevice binary distributed with this header file. */ -#define SD_MINOR_VERSION (0) - -/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ -#define SD_BUGFIX_VERSION (0) - -/** @brief The full version number for the SoftDevice binary this header file was distributed - * with, as a decimal number in the form Mmmmbbb, where: - * - M is major version (one or more digits) - * - mmm is minor version (three digits) - * - bbb is bugfix version (three digits). */ -#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION) - -/** @brief SoftDevice Manager SVC Base number. */ -#define SDM_SVC_BASE 0x10 - -/** @brief SoftDevice unique string size in bytes. */ -#define SD_UNIQUE_STR_SIZE 20 - -/** @brief Invalid info field. Returned when an info field does not exist. */ -#define SDM_INFO_FIELD_INVALID (0) - -/** @brief Defines the SoftDevice Information Structure location (address) as an offset from -the start of the SoftDevice (without MBR)*/ -#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) - -/** @brief Defines the absolute SoftDevice Information Structure location (address) when the - * SoftDevice is installed just above the MBR (the usual case). */ -#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) - -/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the - * SoftDevice base address. The size value is of type uint8_t. */ -#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET) - -/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address. - * The size value is of type uint32_t. */ -#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) - -/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value - * is of type uint16_t. */ -#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) - -/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID - * is of type uint32_t. */ -#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) - -/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in - * the same format as @ref SD_VERSION, stored as an uint32_t. */ -#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) - -/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address. - * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE. - */ -#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18) - -/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value - * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is - * installed just above the MBR (the usual case). */ -#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET))) - -/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base - * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above - * the MBR (the usual case). */ -#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) - -/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use @ref - * MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual - * case). */ -#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET))) - -/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use - * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the - * usual case). */ -#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ - ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID) - -/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address. - * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR - * (the usual case). */ -#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ - ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID) - -/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address. - * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR - * (the usual case). */ -#define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ - ? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID) - -/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges - * @{ */ -#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ -#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ -/**@} */ - -/**@defgroup NRF_FAULT_IDS Fault ID types - * @{ */ -#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */ -#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000, - in case of SoftDevice RAM access violation. In case of SoftDevice peripheral - register violation the info parameter will contain the sub-region number of - PREGION[0], on whose address range the disallowed write access caused the - memory access fault. */ -/**@} */ - -/** @} */ - -/** @addtogroup NRF_SDM_ENUMS Enumerations - * @{ */ - -/**@brief nRF SoftDevice Manager API SVC numbers. */ -enum NRF_SD_SVCS -{ - SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ - SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ - SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ - SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ - SVC_SDM_LAST /**< Placeholder for last SDM SVC */ -}; - -/** @} */ - -/** @addtogroup NRF_SDM_DEFINES Defines - * @{ */ - -/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy - * @{ */ - -#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ -#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */ -#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */ -#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */ -#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */ -#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */ -#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */ -#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */ -#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */ -#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */ -#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */ -#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */ - -/** @} */ - -/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources - * @{ */ - -#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ -#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ -#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ - -/** @} */ - -/** @} */ - -/** @addtogroup NRF_SDM_TYPES Types - * @{ */ - -/**@brief Type representing LFCLK oscillator source. */ -typedef struct -{ - uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ - uint8_t rc_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second - units (nRF51: 1-64, nRF52: 1-32). - @note To avoid excessive clock drift, 0.5 degrees Celsius is the - maximum temperature change allowed in one calibration timer - interval. The interval should be selected to ensure this. - - @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. */ - uint8_t rc_temp_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: How often (in number of calibration - intervals) the RC oscillator shall be calibrated if the temperature - hasn't changed. - 0: Always calibrate even if the temperature hasn't changed. - 1: Only calibrate if the temperature has changed (nRF51 only). - 2-33: Check the temperature and only calibrate if it has changed, - however calibration will take place every rc_temp_ctiv - intervals in any case. - - @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. - - @note For nRF52, the application must ensure calibration at least once - every 8 seconds to ensure +/-500 ppm clock stability. The - recommended configuration for NRF_CLOCK_LF_SRC_RC on nRF52 is - rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at - least once every 8 seconds and for temperature changes of 0.5 - degrees Celsius every 4 seconds. See the Product Specification - for the nRF52 device being used for more information.*/ - uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing - windows, see @ref NRF_CLOCK_LF_ACCURACY.*/ -} nrf_clock_lf_cfg_t; - -/**@brief Fault Handler type. - * - * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. - * The protocol stack will be in an undefined state when this happens and the only way to recover will be to - * perform a reset, using e.g. CMSIS NVIC_SystemReset(). - * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset(). - * - * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. - * - * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. - * @param[in] pc The program counter of the instruction that triggered the fault. - * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. - * - * @note When id is set to NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when - * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault. - */ -typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); - -/** @} */ - -/** @addtogroup NRF_SDM_FUNCTIONS Functions - * @{ */ - -/**@brief Enables the SoftDevice and by extension the protocol stack. - * - * @note Some care must be taken if a low frequency clock source is already running when calling this function: - * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new - * clock source will be started. - * - * @note This function has no effect when returning with an error. - * - * @post If return code is ::NRF_SUCCESS - * - SoC library and protocol stack APIs are made available. - * - A portion of RAM will be unavailable (see relevant SDS documentation). - * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). - * - Interrupts will not arrive from protected peripherals or interrupts. - * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. - * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). - * - Chosen low frequency clock source will be running. - * - * @param p_clock_lf_cfg Low frequency clock source and accuracy. - If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2 - In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock. - * @param fault_handler Callback to be invoked in case of fault, cannot be NULL. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. - * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level. - * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. - */ -SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); - - -/**@brief Disables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to disable the SoftDevice. - * - * @post SoC library and protocol stack APIs are made unavailable. - * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). - * @post All peripherals used by the SoftDevice will be reset to default values. - * @post All of RAM become available. - * @post All interrupts are forwarded to the application. - * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); - -/**@brief Check if the SoftDevice is enabled. - * - * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice - * - * This function is only intended to be called when a bootloader is enabled. - * - * @param[in] address The base address of the interrupt vector table for forwarded interrupts. - - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); - -/** @} */ - -#ifdef __cplusplus -} -#endif -#endif // NRF_SDM_H__ - -/** - @} -*/ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_soc.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_soc.h deleted file mode 100644 index d7d3c801b8197..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_soc.h +++ /dev/null @@ -1,931 +0,0 @@ -/* - * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @defgroup nrf_soc_api SoC Library API - * @{ - * - * @brief APIs for the SoC library. - * - */ - -#ifndef NRF_SOC_H__ -#define NRF_SOC_H__ - -#include -#include -#include "nrf_svc.h" -#include "nrf.h" - -#include "nrf_error_soc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/**@addtogroup NRF_SOC_DEFINES Defines - * @{ */ - -/**@brief The number of the lowest SVC number reserved for the SoC library. */ -#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ -#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ - -/**@brief Guaranteed time for application to process radio inactive notification. */ -#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) - -/**@brief The minimum allowed timeslot extension time. */ -#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) - -/**@brief The maximum processing time to handle a timeslot extension. */ -#define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (17) - -/**@brief The latest time before the end of a timeslot the timeslot can be extended. */ -#define NRF_RADIO_MIN_EXTENSION_MARGIN_US (79) - -#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ -#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ -#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ - -#define SD_EVT_IRQn (SWI2_EGU2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ -#define SD_EVT_IRQHandler (SWI2_EGU2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. - The default interrupt priority for this handler is set to 4 */ -#define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */ -#define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler. - The default interrupt priority for this handler is set to 4 */ -#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ -#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ - -#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ - -#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ - -#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ - -/**@} */ - -/**@addtogroup NRF_SOC_ENUMS Enumerations - * @{ */ - -/**@brief The SVC numbers used by the SVC functions in the SoC library. */ -enum NRF_SOC_SVCS -{ - SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, - SD_PPI_CHANNEL_ENABLE_SET, - SD_PPI_CHANNEL_ENABLE_CLR, - SD_PPI_CHANNEL_ASSIGN, - SD_PPI_GROUP_TASK_ENABLE, - SD_PPI_GROUP_TASK_DISABLE, - SD_PPI_GROUP_ASSIGN, - SD_PPI_GROUP_GET, - SD_FLASH_PAGE_ERASE, - SD_FLASH_WRITE, - SD_FLASH_PROTECT, - SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, - SD_MUTEX_ACQUIRE, - SD_MUTEX_RELEASE, - SD_RAND_APPLICATION_POOL_CAPACITY_GET, - SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, - SD_RAND_APPLICATION_VECTOR_GET, - SD_POWER_MODE_SET, - SD_POWER_SYSTEM_OFF, - SD_POWER_RESET_REASON_GET, - SD_POWER_RESET_REASON_CLR, - SD_POWER_POF_ENABLE, - SD_POWER_POF_THRESHOLD_SET, - SD_POWER_RAM_POWER_SET, - SD_POWER_RAM_POWER_CLR, - SD_POWER_RAM_POWER_GET, - SD_POWER_GPREGRET_SET, - SD_POWER_GPREGRET_CLR, - SD_POWER_GPREGRET_GET, - SD_POWER_DCDC_MODE_SET, - SD_APP_EVT_WAIT, - SD_CLOCK_HFCLK_REQUEST, - SD_CLOCK_HFCLK_RELEASE, - SD_CLOCK_HFCLK_IS_RUNNING, - SD_RADIO_NOTIFICATION_CFG_SET, - SD_ECB_BLOCK_ENCRYPT, - SD_ECB_BLOCKS_ENCRYPT, - SD_RADIO_SESSION_OPEN, - SD_RADIO_SESSION_CLOSE, - SD_RADIO_REQUEST, - SD_EVT_GET, - SD_TEMP_GET, - SVC_SOC_LAST -}; - -/**@brief Possible values of a ::nrf_mutex_t. */ -enum NRF_MUTEX_VALUES -{ - NRF_MUTEX_FREE, - NRF_MUTEX_TAKEN -}; - -/**@brief Power modes. */ -enum NRF_POWER_MODES -{ - NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ - NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ -}; - - -/**@brief Power failure thresholds */ -enum NRF_POWER_THRESHOLDS -{ - NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */ -}; - - -/**@brief DC/DC converter modes. */ -enum NRF_POWER_DCDC_MODES -{ - NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ - NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ -}; - -/**@brief Radio notification distances. */ -enum NRF_RADIO_NOTIFICATION_DISTANCES -{ - NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ - NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ -}; - - -/**@brief Radio notification types. */ -enum NRF_RADIO_NOTIFICATION_TYPES -{ - NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ -}; - -/**@brief The Radio signal callback types. */ -enum NRF_RADIO_CALLBACK_SIGNAL_TYPE -{ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ -}; - -/**@brief The actions requested by the signal callback. - * - * This code gives the SOC instructions about what action to take when the signal callback has - * returned. - */ -enum NRF_RADIO_SIGNAL_CALLBACK_ACTION -{ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current - timeslot. Maximum execution time for this action: - @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US. - This action must be started at least @ref - NRF_RADIO_MIN_EXTENSION_MARGIN_US before - the end of the timeslot. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ -}; - -/**@brief Radio timeslot high frequency clock source configuration. */ -enum NRF_RADIO_HFCLK_CFG -{ - NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the - external crystal for the whole duration of the timeslot. This should be the - preferred option for events that use the radio or require high timing accuracy. - @note The SoftDevice will automatically turn on and off the external crystal, - at the beginning and end of the timeslot, respectively. The crystal may also - intentionally be left running after the timeslot, in cases where it is needed - by the SoftDevice shortly after the end of the timeslot. */ - NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. - The RC oscillator may be the clock source in part or for the whole duration of the timeslot. - The RC oscillator's accuracy must therefore be taken into consideration. - @note If the application will use the radio peripheral in timeslots with this configuration, - it must make sure that the crystal is running and stable before starting the radio. */ -}; - -/**@brief Radio timeslot priorities. */ -enum NRF_RADIO_PRIORITY -{ - NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ - NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */ -}; - -/**@brief Radio timeslot request type. */ -enum NRF_RADIO_REQUEST_TYPE -{ - NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */ - NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ -}; - -/**@brief SoC Events. */ -enum NRF_SOC_EVTS -{ - NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ - NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ - NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ - NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ - NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ - NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ - NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */ - NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ - NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ - NRF_EVT_NUMBER_OF_EVTS -}; - -/**@} */ - - -/**@addtogroup NRF_SOC_STRUCTURES Structures - * @{ */ - -/**@brief Represents a mutex for use with the nrf_mutex functions. - * @note Accessing the value directly is not safe, use the mutex functions! - */ -typedef volatile uint8_t nrf_mutex_t; - -/**@brief Parameters for a request for a timeslot as early as possible. */ -typedef struct -{ - uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ - uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ - uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ - uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ -} nrf_radio_request_earliest_t; - -/**@brief Parameters for a normal radio timeslot request. */ -typedef struct -{ - uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ - uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ - uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ - uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ -} nrf_radio_request_normal_t; - -/**@brief Radio timeslot request parameters. */ -typedef struct -{ - uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ - union - { - nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ - nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ - } params; /**< Parameter union. */ -} nrf_radio_request_t; - -/**@brief Return parameters of the radio timeslot signal callback. */ -typedef struct -{ - uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ - union - { - struct - { - nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ - } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ - struct - { - uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ - } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ - } params; /**< Parameter union. */ -} nrf_radio_signal_callback_return_param_t; - -/**@brief The radio timeslot signal callback type. - * - * @note In case of invalid return parameters, the radio timeslot will automatically end - * immediately after returning from the signal callback and the - * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. - * @note The returned struct pointer must remain valid after the signal callback - * function returns. For instance, this means that it must not point to a stack variable. - * - * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. - * - * @return Pointer to structure containing action requested by the application. - */ -typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); - -/**@brief AES ECB parameter typedefs */ -typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ -typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ -typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ - -/**@brief AES ECB data structure */ -typedef struct -{ - soc_ecb_key_t key; /**< Encryption key. */ - soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ - soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ -} nrf_ecb_hal_data_t; - -/**@brief AES ECB block. Used to provide multiple blocks in a single call - to @ref sd_ecb_blocks_encrypt.*/ -typedef struct -{ - soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */ - soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */ - soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */ -} nrf_ecb_hal_data_block_t; - -/**@} */ - -/**@addtogroup NRF_SOC_FUNCTIONS Functions - * @{ */ - -/**@brief Initialize a mutex. - * - * @param[in] p_mutex Pointer to the mutex to initialize. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); - -/**@brief Attempt to acquire a mutex. - * - * @param[in] p_mutex Pointer to the mutex to acquire. - * - * @retval ::NRF_SUCCESS The mutex was successfully acquired. - * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. - */ -SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); - -/**@brief Release a mutex. - * - * @param[in] p_mutex Pointer to the mutex to release. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); - -/**@brief Query the capacity of the application random pool. - * - * @param[out] p_pool_capacity The capacity of the pool. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); - -/**@brief Get number of random bytes available to the application. - * - * @param[out] p_bytes_available The number of bytes currently available in the pool. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); - -/**@brief Get random bytes from the application pool. - * - * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. - * @param[in] length Number of bytes to take from pool and place in p_buff. - * - * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. - * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. -*/ -SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); - -/**@brief Gets the reset reason register. - * - * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); - -/**@brief Clears the bits of the reset reason register. - * - * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); - -/**@brief Sets the power mode when in CPU sleep. - * - * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait - * - * @retval ::NRF_SUCCESS The power mode was set. - * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. - */ -SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); - -/**@brief Puts the chip in System OFF mode. - * - * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN - */ -SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); - -/**@brief Enables or disables the power-fail comparator. - * - * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. - * The event can be retrieved with sd_evt_get(); - * - * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); - -/**@brief Sets the power-fail threshold value. - * - * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. - * - * @retval ::NRF_SUCCESS The power failure threshold was set. - * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. - */ -SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); - -/**@brief Writes the NRF_POWER->RAM[index].POWERSET register. - * - * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to. - * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset)); - -/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register. - * - * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to. - * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr)); - -/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks. - * - * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from. - * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power)); - -/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). - * - * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. - * @param[in] gpregret_msk Bits to be set in the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); - -/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). - * - * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. - * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); - -/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). - * - * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. - * @param[out] p_gpregret Contents of the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); - -/**@brief Sets the DCDC mode. - * - * Enable or disable the DCDC peripheral. - * - * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. - */ -SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); - -/**@brief Request the high frequency crystal oscillator. - * - * Will start the high frequency crystal oscillator, the startup time of the crystal varies - * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. - * - * @see sd_clock_hfclk_is_running - * @see sd_clock_hfclk_release - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); - -/**@brief Releases the high frequency crystal oscillator. - * - * Will stop the high frequency crystal oscillator, this happens immediately. - * - * @see sd_clock_hfclk_is_running - * @see sd_clock_hfclk_request - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); - -/**@brief Checks if the high frequency crystal oscillator is running. - * - * @see sd_clock_hfclk_request - * @see sd_clock_hfclk_release - * - * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); - -/**@brief Waits for an application event. - * - * An application event is either an application interrupt or a pended interrupt when the interrupt - * is disabled. - * - * When the application waits for an application event by calling this function, an interrupt that - * is enabled will be taken immediately on pending since this function will wait in thread mode, - * then the execution will return in the application's main thread. - * - * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M - * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets - * pended, this function will return to the application's main thread. - * - * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ - * in order to sleep using this function. This is only necessary for disabled interrupts, as - * the interrupt handler will clear the pending flag automatically for enabled interrupts. - * - * @note If an application interrupt has happened since the last time sd_app_evt_wait was - * called this function will return immediately and not go to sleep. This is to avoid race - * conditions that can occur when a flag is updated in the interrupt handler and processed - * in the main loop. - * - * @post An application interrupt has happened or a interrupt pending flag is set. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); - -/**@brief Get PPI channel enable register contents. - * - * @param[out] p_channel_enable The contents of the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); - -/**@brief Set PPI channel enable register. - * - * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); - -/**@brief Clear PPI channel enable register. - * - * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); - -/**@brief Assign endpoints to a PPI channel. - * - * @param[in] channel_num Number of the PPI channel to assign. - * @param[in] evt_endpoint Event endpoint of the PPI channel. - * @param[in] task_endpoint Task endpoint of the PPI channel. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); - -/**@brief Task to enable a channel group. - * - * @param[in] group_num Number of the channel group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); - -/**@brief Task to disable a channel group. - * - * @param[in] group_num Number of the PPI group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); - -/**@brief Assign PPI channels to a channel group. - * - * @param[in] group_num Number of the channel group. - * @param[in] channel_msk Mask of the channels to assign to the group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); - -/**@brief Gets the PPI channels of a channel group. - * - * @param[in] group_num Number of the channel group. - * @param[out] p_channel_msk Mask of the channels assigned to the group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); - -/**@brief Configures the Radio Notification signal. - * - * @note - * - The notification signal latency depends on the interrupt priority settings of SWI used - * for notification signal. - * - To ensure that the radio notification signal behaves in a consistent way, the radio - * notifications must be configured when there is no protocol stack or other SoftDevice - * activity in progress. It is recommended that the radio notification signal is - * configured directly after the SoftDevice has been enabled. - * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice - * will interrupt the application to do Radio Event preparation. - * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have - * to shorten the connection events to have time for the Radio Notification signals. - * - * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. - * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio - * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is - * recommended (but not required) to be used with - * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. - * - * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES. - * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or - * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. - * - * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. - * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all - * running activities and retry. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); - -/**@brief Encrypts a block according to the specified parameters. - * - * 128-bit AES encryption. - * - * @note: - * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while - * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application - * main or low interrupt level. - * - * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input - * parameters and one output parameter). - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); - -/**@brief Encrypts multiple data blocks provided as an array of data block structures. - * - * @details: Performs 128-bit AES encryption on multiple data blocks - * - * @note: - * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while - * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application - * main or low interrupt level. - * - * @param[in] block_count Count of blocks in the p_data_blocks array. - * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of - * @ref nrf_ecb_hal_data_block_t structures. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks)); - -/**@brief Gets any pending events generated by the SoC API. - * - * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. - * - * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. - * - * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. - * @retval ::NRF_ERROR_NOT_FOUND No pending events. - */ -SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); - -/**@brief Get the temperature measured on the chip - * - * This function will block until the temperature measurement is done. - * It takes around 50 us from call to return. - * - * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius. - * - * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp - */ -SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); - -/**@brief Flash Write -* -* Commands to write a buffer to flash -* -* If the SoftDevice is enabled: -* This call initiates the flash access command, and its completion will be communicated to the -* application with exactly one of the following events: -* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. -* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. -* -* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the - * write has been completed -* -* @note -* - This call takes control over the radio and the CPU during flash erase and write to make sure that -* they will not interfere with the flash access. This means that all interrupts will be blocked -* for a predictable time (depending on the NVMC specification in the device's Product Specification -* and the command parameters). -* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS -* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. -* -* -* @param[in] p_dst Pointer to start of flash location to be written. -* @param[in] p_src Pointer to buffer with data to be written. -* @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one -* flash page. See the device's Product Specification for details. -* -* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. -* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. -* @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. -* @retval ::NRF_SUCCESS The command was accepted. -*/ -SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size)); - - -/**@brief Flash Erase page -* -* Commands to erase a flash page -* If the SoftDevice is enabled: -* This call initiates the flash access command, and its completion will be communicated to the -* application with exactly one of the following events: -* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. -* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. -* -* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the -* erase has been completed -* -* @note -* - This call takes control over the radio and the CPU during flash erase and write to make sure that -* they will not interfere with the flash access. This means that all interrupts will be blocked -* for a predictable time (depending on the NVMC specification in the device's Product Specification -* and the command parameters). -* -* -* @param[in] page_number Page number of the page to erase -* -* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. -* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. -* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page. -* @retval ::NRF_SUCCESS The command was accepted. -*/ -SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); - - -/**@brief Flash Protection set - * - * Commands to set the flash protection configuration registers. - This sets the CONFIGx registers of the BPROT peripheral. - * - * @note To read the values read them directly. They are only write-protected. - * - * @param[in] block_cfg0 Value to be written to the configuration register. - * @param[in] block_cfg1 Value to be written to the configuration register. - * @param[in] block_cfg2 Value to be written to the configuration register. - * @param[in] block_cfg3 Value to be written to the configuration register. - * - * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. - * @retval ::NRF_SUCCESS Values successfully written to configuration registers. - */ -SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3)); - -/**@brief Opens a session for radio timeslot requests. - * - * @note Only one session can be open at a time. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot - * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed - * by the application. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 - * interrupt occurs. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO - * interrupt occurs. - * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This - * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). - * - * @param[in] p_radio_signal_callback The signal callback. - * - * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. - * @retval ::NRF_ERROR_BUSY If session cannot be opened. - * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); - -/**@brief Closes a session for radio timeslot requests. - * - * @note Any current radio timeslot will be finished before the session is closed. - * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. - * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED - * event is received. - * - * @retval ::NRF_ERROR_FORBIDDEN If session not opened. - * @retval ::NRF_ERROR_BUSY If session is currently being closed. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); - -/**@brief Requests a radio timeslot. - * - * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST - * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST. - * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by - * p_request->distance_us and is given relative to the start of the previous timeslot. - * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. - * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. - * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. - * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this - * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. - * The application may then try to schedule the first radio timeslot again. - * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). - * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. - * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. - * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the - * specified radio timeslot start, but this does not affect the actual start time of the timeslot. - * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency - * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is - * guaranteed to be clocked from the external crystal. - * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral - * during the radio timeslot. - * - * @param[in] p_request Pointer to the request parameters. - * - * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. - * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. - * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request)); - -/**@} */ - -#ifdef __cplusplus -} -#endif -#endif // NRF_SOC_H__ - -/**@} */ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_svc.h b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_svc.h deleted file mode 100644 index 292c692982837..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_API/include/nrf_svc.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NRF_SVC__ -#define NRF_SVC__ - -#include "stdint.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef SVCALL_AS_NORMAL_FUNCTION -#define SVCALL(number, return_type, signature) return_type signature -#else - -#ifndef SVCALL -#if defined (__CC_ARM) -#define SVCALL(number, return_type, signature) return_type __svc(number) signature -#elif defined (__GNUC__) -#ifdef __cplusplus -#define GCC_CAST_CPP (uint16_t) -#else -#define GCC_CAST_CPP -#endif -#define SVCALL(number, return_type, signature) \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ - __attribute__((naked)) \ - __attribute__((unused)) \ - static return_type signature \ - { \ - __asm( \ - "svc %0\n" \ - "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ - ); \ - } \ - _Pragma("GCC diagnostic pop") - -#elif defined (__ICCARM__) -#define PRAGMA(x) _Pragma(#x) -#define SVCALL(number, return_type, signature) \ -PRAGMA(swi_number = (number)) \ - __swi return_type signature; -#else -#define SVCALL(number, return_type, signature) return_type signature -#endif -#endif // SVCALL - -#endif // SVCALL_AS_NORMAL_FUNCTION - -#ifdef __cplusplus -} -#endif -#endif // NRF_SVC__ diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_license-agreement.txt b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_license-agreement.txt deleted file mode 100644 index 00c2e54c47742..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_license-agreement.txt +++ /dev/null @@ -1,35 +0,0 @@ -Copyright (c) 2007 - 2017, Nordic Semiconductor ASA -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form, except as embedded into a Nordic - Semiconductor ASA integrated circuit in a product or a software update for - such product, must reproduce the above copyright notice, this list of - conditions and the following disclaimer in the documentation and/or other - materials provided with the distribution. - -3. Neither the name of Nordic Semiconductor ASA nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -4. This software, with or without modification, must only be used with a - Nordic Semiconductor ASA integrated circuit. - -5. Any software provided in binary form under this license must not be reverse - engineered, decompiled, modified and/or disassembled. - -THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_migration-document.pdf b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_migration-document.pdf deleted file mode 100644 index afd9ec7f417a65d00913eebe6eaebdfd90a17931..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99118 zcmd43W0YmlmNgi*ZQHnE+qQYbwj;wfGi;j~wrywF%8bacI$zbRuIm2YsOn!m>i#+V z>~r_pYwY`D&NbJ(hf-Nwl981O07rRnIJX4HLBc}fXlet;&(ACmbg*=@B4OiT;b4}u zwsQlzFiYB*xB7sC8I$=O%}?qwHY zH=m3dy~_n5$(KmfcX}=IdDtG2Y2@v8gBV$cN+-ACkUogTXXrD*%o8*&1S=dcA9}Wk zZ~gozeiuK6+bd>b6Jxs*d1u&}3j&N=bU{(}B^bj2-z-(9ni(!O@l@a^q-!nmtcg^s z$5@lz9~gy7@^%*=!SU9^+v@Fy zAGkfNx3G%aw&vRw%xAKSM=TH-aaMKJr&E(V(!Ii4?451658Y90_!)6#Prg$H$qED* zO!AvAyW&mqw^R^w<}hxmj$Wp-%0{PYvId8;$9j)fqN5d?tDSIpsj{Tbuq%k#JivJH zu&<*haOB`#Mc-P_(r5=6io=JuVqtRB0wJQTteU?~Ij!mn&)B1s8e3&sW<@MtIA1M1 z;y_u7Z8g(y)mbn>r09qla+Q>pc++B%vk<<<;oxbpCz#pU@KXYE9-70|aFU4zh%Cp7 z^4471G%)B%P%@9@2)o{vx8Zr`+F3?q1h_r0D@3#sae0kn@tzt9hA=U48Hw@@ zg%3rNzibLV*s<-#{?wcfh`n<;7fe>@q&wtgbZMeV-jO_d=z2l6>wvnz8Hd-u2tzw# ztDiD$l%o(fNc3SG{{nN!-#hQvi=_AB_=P-ttac-t5_|W#2}uQ zdfrnp-nmY$F`}>sWO_UjNyS8|m2L!RYA?b`9{2^3Wsp%fo9YCjAzPEt$)42r@J^=> z^}Z$B)3Tvz1s_Qu5>&f4PGKDxCaMm@C!bKz-Vt}{^Z4Yi+LCOrCLl47kZh-!31U;C zIyZ50_EGzato{y33}=pEpntUPB}+@3(&+0(VuD7*9wUVaWXBZpw5G+P&>4G?Rd;-? z6B_1;YTsf|P&d9REp&M>fYg;X(F^vCF#y7330Mm-6UO0xUo~&8wsG1bdWiULdPSEY z2c3nPzK5=FnkE>juSV=tMWC-wa96Ukh9WN4Bj%jGs^l1N<`97&dmHuRXPOi7%o%M^ zrCiX@u0S$@U@4{obK^M^*+02V5-tYI6tiq4^K(Pw2D{}RT9|+lT$4R-ZB>;*$7QO3 zL2boo=$7mH#pHngTeUq%R>LurOV($IVTQ0c$S$L&b*Hl~Wz8Q&90Lt&&L1{1k?s_L z-zr$yDUCA78FF{(SJL`$YPTewZjACCz^Ii|o@o}#3bVX}cfXM*UWsEcYr~b&sy@v0 zC?CSLQQ->3T7{>gpE0WivOTmi*pwE6N5G_*aO>{4sm`ut+*FfbwbZRnqZL!ViL1eW zxqIDI{6^^{l_3Z#>|@c?KP)I|4N&T=XWlOK#D_DS_|dYNpoI*c%bkKrT_y+~wDV*B zwvJ9VLC}k6gTE*chS}&&EUw(HA1G%Mg`iD$#*LV^7 z5DueD4SQ+Ylz^SOYe#QeM{j&ItjA;u|L^(2WHl z#o6(+4-mFiTg{EKcxsflZSZg0PT=hh{+>pSeL$K z>F!;RZ43e5_(*x03OS<~GDB*|r-}Na0BSS#_WAamt`0am;M?(^ljtNJ#1WMDU%Vjjgx)j`BC)o6JnoE8 zGwK1K-i5vUsL0V8QeVabE?Z4CSY_Z&iz@_3$ojNKkN#lI&~8eq14yE%>3q;Y>@2%a zM-*1dw$>U}7N<$xhY~9Kv#qXcusbu61B!t^vsxRt1{qyW?knM2Pp%~dQS z+?kV0K%uR0{#3YHXkHf7k7_0=rcuVw^NSL-Zzy{Enrv)kXTSJ#(LZ*L7|24=g z(7-U}Ob|V3-0b=3S$iemKiBvrttW#c#Z$&15E$6UmfON`j1b5d^l5B%ZbDY*kz zxSS?x<@iAn{Z;E}6T&^s9dW=i$i%Q~qVl}($6P8}B9k8wx0x1WK9%m>&C|cFkY5io zWd2+}b7mPCDmdJnEZF&=&QM`{E=|4MF1X!2IIv~s%Ws+4jk!Co+72K-9&PdC?aq8* zaVRtEAfc^_z0V`**r=IM0yIxxL#Z}?XU9Vv{RK~c8{n)Vsfr;z_ z5w<@B-M!{oewRBgJj^_d%(%OG3*^i9#r276Wvp3Z@y-fdJUS(`;e}FglEN;f_p7$c zT%MF*GZQsbq=)Cp(@EvTd*EaE0rxrRfP_=7I+kr7uPRV;OS(iFuMEjR zIgS7*U8;NZG0)RZWIV%?!6H`ylS~{HhDCGbfUYwK5f((e)T}smIl5OquRK}u@RF%Bg`FynIZhrr;x)0Zi}k^BEc!HOhU8>VZ<0@?J#rr$4 zhzNP{Iwk53>>fTO3W@QsgAhRma)zRI>4CwloJ}SF7nyCTZ zNc5QhGE5R?b)c6U3A2p-->-@O^D6ewtBe7&D&|Nj4Jpe;=@u0RAx$ z{QF^60GeByh&p=dvHYFl;Nf6m<0jz-urhIT8wd*iBmI9Q&Gq-$|BJ!0vHuSYwnzKl z8SI$Ww3xH$sh8D#K_ z_5h3#R7CL56v4N?SVelvb8%3UJSnyCil79NO{O?PaU#TpaNq0OA^*t3#n4P-6hWj* zQsR~#by3pX0f-hM#dps-diF>Vzz!*;0Y`VQiT~B-4x~+B_Ki=%4aOI0BJAlBjxT{H z85?c*da5ixz?ks$%#EyZmAS#L{wd_o_^ziB8~_qgI)Cvka*w%U+8( z+?Tdlp?|Vaa-5LB@ZwVo(TeAl!_nj-e$bea)XLAud*gzGLN9_Ai&#lRlVSydrj82h z8Z7}zGG?3xH;^lc<4XMV+2#@-MY6($>HlMi7#UJcAt?V`1C&{0%e$bHrWOG9oQ>4V z)xtzpYLY>|K?oB8uP&;Y69H&Xr@J|Y17n5LJYG6I{5>eqi)wb0C1-|1Ld<&u!L|0> z$iT0+NgSdu=8^>zQ9F80(-uKnRDplR6I~HlnP`n|Ps5F_2vA$H6**g=;q;nh*$1pa zDO$@?L0sd(fPKTEeXB$gJb0d{5ZT0$rdMNEGu%x425vnbZD|7%H@y6f6Ke4_i;A+x zE%z-#>CU79?Bx%cED7luuQ+bPY-BsEY zkLB&tA!#R_tm{x=HHzQXYiiA4HM(p&;Q3^TJ?`ZDofm{A9F3wr+WpuQbMuszBhy!2 zkI(lH*MQ%2T|c_Jy#t+Jn!{bGouJeIar)%@{v=#j%RPVu$&>~3n?#$HTnS42XBtyyT( zyGUD<0p`MMx%^CRVmJQGnpYtKX7;?(?DW&EX4Rk>OvUs-kkJTaK2)O?AR{8kub53<1EKL;xsk83gQ8!JlpSJ%4%vkpH4JX!lDe;W04 zb#&$lwH}C=Z#y;BVBU_`qG0aFglQ|Y8Nm)_mod2f#CDfh&90+tL-AvY;QmQd{R?U!b%x%t5sd zSLxU{D>U!*G?-twrQ%-Xg-K7yMecMuK+@8|9O{mGNM@=2QWVC>C>p^z!1KF%Z99iK z%5=*vtK7=_W6*;Gu^kwB<%IVQ0;AQn@F1{ztsKN=#{hZr*1AgQW10xTTo0Y}8p zUZy8CNIw#&66BDJQp=q_wDHV;_dNrDVd52vU|I)SNrbgeaxnow_F8j=r&X* zMBiS_`~tDJrIHVv1n4FRlKVuQZ5o?wtDrM@%02>zZ#{7}(R?FCwOpRn7E5Y(U_S9~ zBVcZYXf8Np?{%2LAbcfI%0CjAR1P{IX0^II(UTqGfE1UP05j%M!?YPwNMR2vd&l=;CT0}s2t1A$3R6-@% zp)()k`Y_x+mRy~Bq}A0J5ipm($4_@bQW)Ba`s&`=Db-8q z-57WBC)iprmoZ_e#P;v0&9B|0m`ZPXGiP!U>Ilg2ztf0|bOr}YCH?s5#tK#Orw*P< zREocPyo;ym2#`p3KL-_bBQ@`j%`6A$KH{Vm9} ztvSf8@Gwe^+c%DoKhzMj`8wm$sDU@ruCAeus|<8T$J-1>(-Ib;yY}I@Ot%3VN7X$m z6HCq3Ogz3=Jz0Es-e>5Tb}7^r5-)=+gPwS&Cy=|hTfL`cVM8r?OpLT3`Bi#`B*^|5J5jpy8D=v(|@jlMeW%*aPoNEK~y+JxJ>9I%F_ z0R1w-#F2BT+wV3R1+){n#7Dd!ZKeSZAE4FcxPHufEUM~Rd6~G%#xAOdXq2V9=uc5` z!8WUmHeO#^y8x*<*AFhH2b3+7(%`X5TCLKvW5^|sOHEHpduyb@Is}` zpKuz3N+KWZniuT!@tsUJOOr2T$w)M)2cbJqy{!;xs2_Wbi4+(@ycJ+UHGqCS>!%?S z>|bZc%Yi;_CrW|$@6DEh&!?6N3Eh=nKCc&ky!Qb=?*+$uz2FIkeAEX035nzg57Ny* ziLOH0F}~5cjt`f|jl;7>JQ)@AciED%!Gu8kg!jXlHc2Y2zKi;SCIfm&0ox`+^%8x=Or#`@$et{DEn zljC$uaWy2P3)8|+gEtm1Ip7O!5}kPo_aFgw)OJ)?w*tCveu%B0fka|C znYGl_LL_60G!BRh60Dl=L_aPTTc(_TPV?Q(T7Dk=`MsQbHUQdDcJ>8^O`G?hmy6_qwQ1QeSBl2S7ac#OYQFb6rRGm;7zb2-bv9WmxF80;&8 zym7dglxT*yeePWNlAlj)83@1JYYu66jZJUa=}f13*Q(}W2amHKcxR#s!ef&v@d1(F zGA37XN&3ve*N>VYC3qMhm`)MoNCy#g?Tinuqbmn|2+fQVEe6dHEN>PWHbt?M|&H%>8pCQ2vinIDZ zWim;rLT0dCe-+MmarQ+_i*Vx|X{(}_SL+_wZYj2{o?bOnC>#G4A+d8`FuR>w?lt3< zeMYc<`BJ(bad}RcFg%*I27VQ-2kvN-`U9~f^uivAPrl8ec-u-E&a9Z>DB$?f!dokQ zxiFN_1Nk1QiIv`@e_*473%H(1X$L8 zh!6i182&ZF{sYbaw;?R+f6;RO17bP2{|AVj(Xn^j;zaqZGjh%kFOk-X^4XmSwN5sr zT_m%=a_DD+iB=f9FrP>|0t_{LHRX4b(@vDUlexPGjXKq^-{$fCButQc9q{5{lZPRQ zfdGvy8yy+gGaq`N^(g%v31B}Vg%(^+CXalP0CkO)F2qGj*4u(_I9cyW4FB&o(* ztHrAiC!e^3~(Q)rG+ zk?Isr{T?B@xw*2jURfOpuf=;sLYVn!7+DuYXk^8+rx$uqfr(~vco3E>Vm^+nWA^Z9s2Ds$LcS2RZc#YXQ?y7{Dkk(Um><|UT1L&T6Fo^G zpxc;TQ(6uu$IxgHkY9rpiKQizC-RO%ZS9v)DfpxQ4kV&3cy|%{5&Z<$ z;wIa3H$0=5zw<@IY_>39o3=3z_!ZrNtPoLIG+@?xspes=zyZd32;+*|Gj5@*oM;;( zthCb!5!blDIk>4Dc^_?Q%B#;DI1cH4#?{wB6&xU;-{@4gOQrBnkuhK|rRMe{+Xw8s zj>T>rO71+h)gl{e#$WE)U^9&xC`K)gjH$Ri%DK6+;u%R1GyP0pc90Z$w-;cTpFA45LkYB!XcX86dK3^=l&m8OeIcs+ z?z4@ye{=7>Ra?MFE94j%g({UfCX@hLDqdG{e#k1w9@X`AFrs(CMZ`nj-y@_Bq+VzL`MX%kKZoX^MxO%HkaWJ!dj! z-v#?5mxR{VBI1qS>UxDz-8Oramg^BXHfpgwqP@nMdspuYyFk|#C>?sjv)4e?Ct8EL zHUR+@6lJAU`ob?!)0`bf-h;U&BX!AFL`pvI7>w1k-)ndys%HF6T%Jv}Zq6XSJLqq? z-yErL_^Y_EJm~kusVX@1ySLIhUo_W)SESVX8{tumwMS7`pF(>N^$$@n;kMA&_qaSi z%1s?!dgpcq+xeS9vvFigs+Hoc?w~e{y~KzweN67Ey4A#!p)v}dKaB?F@UT(*3z+z018Gi3XIQenCIOohj`4<6>xXWjE$ofy=44}%K)gK?*{wmF zF8-wweIv|b-%BYZXKx4&HbOH}MaM#sV9_=z!5dyJ8}80}wp~r@F^l%10}E~~VJrT) zF4piEQe?qqhg~ZmI!?g+vwvet1QzR84metM0SiPUCg`=vT)?kxEXc6(qFXiKMgiAc zdwT^k=bE;s|4zK$busbi*$W>ctBVs#91*O3FfBi2%g>yGete6g_3>by^(B{DK@>gv zTrPz}CJjD)f(AF~gCNU2MoWYx|3TZvI8?9sxWPxxkNuNQhRwI1o^8m1;F5F4*0D)3AzlQ=sP~XmH+d3q+f9+e zCt+)g79?$(PXk4_PUbgbrM_`rfh@9|D9i7ltOYZn%t{EZ za9-_GLC|NGW_apzi|UP6j9J>*3UP7K^#1F+^qX@4znSwmEa4$gLmEUWa9Vg@^wj1A zt03O1Mu%;FKjB=~V!#GH)o3n3(>fUf|9fa7uZVMJvU5Z9Ao?G%u|6HXVvLjxK~(&E zUIb#+QS20`!KVg2{2KGZ`K1iz;EX>TDQg2UPceHN^#cb(2}>k-w%U>N=VC4EG=Cmn z_%JXlrh%$<#ZBs@lE_Nsh59Dzk@IX?clU0g5IKb#!|1^{2kzv59Amy2Fq+QNNw6$D zU_tYPTBg03aUs*W!q8TyRa^B+2^V+`#&0^6+jgp-RVkCwsihvDGr?ifap-n3r6 zHSD1Wdg0%QRgF$7J6#Zn%DV0mB&>xf$opK!F7d=UCiCujF{|2qvFCr@2?OQ>%j!=7tFSaq@>I>lG2F}~C#W>hVFA%%=y)y;NaWQ*t(msR71Kz48g zpoOo>=xIWV&Z0xuK~Nt@5I~TOI&DD!wekW2Z<&UOM4$J)bCDsrf~$nSf+0;;bMCpX z@___QCg=jhetbfC&D0mqJ%5z&Vde;Wh7{iIB+<*aSuv`zo>PYZIH@rprREy?expOT z@$X1cVIbwEkuA#rZYwiagH?GP7w7L2*O6D(vwfek54x}a5p|d&6Rf(b>LO_h%bJrT z;EA%!wViGFO_=!Cm`u-ZhnQ!)N)R~;%vi1Fr&!vW^(Su6Y;mr>zgYdEvO+u=1QJZ~ zn~Hh<2StzMh(>y;w~jgkcWAG3e|5e3N89Hkv=$2I_6^0j63-{ zL3-_igRGN{k}*LpcKbM^Wd#&POWI|d!m~3!v){QftdQdhXF1nMvx(hUvWL@l2$__RclC$bI?K$^%s^t)|4e_X4#lNwlF>%V-slwR*@2ZFy}_ zGL5+u8oSV#VnbMiBx`PL1}>DB`C2#~L#h^akI?B@8NUW}mP0?6_2k>|{$`LANRU6> zG_LZW@3rP#QCOow&Jy`VnhRXWRAg$IGjd~FV@UYX7IUeUW#6$(bN-`1Am#!qQS-1# zzjayACTbMsv!osG*E3RMCTO<@Wy=p0*^d~LS0eB!<($2ZUNu(6*07Vz;YI?RSDF=o za%9nAaGOEMru5L}t9u91@!2x@2s4hKHbXI|V0)z*tO^F0PBO{$kAYnuCYddcO6%5G zv>MrN-3H#4-s^&c`s}VvwszXUgv9Wf9kw<*JBbods0@==f+dwEMEIrZvmXWabLB*f zF5WQ=T4pyWv+m=oEE}S>_|uG2ByCvt71mlhT5h;hC!5KbtE=@>?p*_J!Znd4Bl;Jq zN%R$9vXq|pjU}1zg)DklD@i3-HAuCNzFJbMGmqi53cr2LmlD#Ly$Y|Wtxe|PMIigpVYT4bA}s;g8ZzN{zvF7eG6$r&+U*9p0$IXKfA>76m3 zhseDrxSC9uj6t1ZC|X$`#W%7fnI`IcSxcqmB+|f2gEQ5;RyzV=h+)=@-vzejQ0o93 zVKPl^dP$Q!OQkJsJz&!~ae7d#KgLK>1f_K5;(HV9cf7|L_4~jFrib04z1H8KlNILE z!%Tg2G9jIibV>8@>U2fp^<+RaOf30n{<^}GgJLb)JM;c(<_~tx{A3HPN5~KDat_#{ zRPkO&A(>}zo!Zm)BN^EBAwNUE)wagT`JfWH;qX`YXorq>B z7tmyDAa1KWRERb(zoRq)7su`UrXGv*bq(bPg^tO~x{97nGn*)(7 z6#AXZ&j_SU)#)yHTqI0nLOm&)aR`ue%pcdppXEM^;@7NWFu63d@LVMoKw_3xd+3WQ zhT4^r^3yNxj-kujRg`4WwKozC_cHU8!ssp|Y=yIO*9qj%$6w$oW-sq^8UIPKJmj|% z8(|)lu^LM!|JR@3@iU~feFUy-?yNBH7DW^yV_NOqSae=cq(qjvrL#-IXE+$7zHpte zw66jNf-_6`^bvQgpLdpc$o>n?b~YWsu4HC%oN)cPbN4hIGxJB{L0w*tD93Wi;S+v6 z$xr=BEt6(6_fKm>nZgfknZ6K2%LiWrpA>RppPJm(Cn}2L;Sse6GoW0-TTbXS2_cB) z&S{W5);~esKkL4J*WH{sOdvec({|8)!=msYBm4Xi&Qp7yo3GSc-mPap1wEl1C+6xd zYhJre2stmW7Gb$Dc$C6c-NhImFn9ZOMP7BUZYx~CS9Rw^-fV<0-)WKW^j3rMZ=LZK zy0F_*E^usNv>VWC1%gxgZE)44oNWe!~jueypyG3q|lNle3G7C`~io#1?}#{ zPd2ICVLsK|6D&G4OKEl_Df~Uz$DXv*6R$y`&TUl9?#U4`W`=J#3(PIfk4z?~g z7vXvRODxpQETl&JDpY)x`d~F_$hqNq4MER~zkKs7td4yaR{hDhNajjr_E7Zg(nZyMI@jVhQQLE6IXUMG887()aM$fcF%yN}}9EkkMldA9i*Qr86c6PZl6N zVgD6tvg!@%c8x@Z4kZ9$6?ZOUgHB|=(C4)uM+b=_Q^e1gnbU?=CU)tly*fQ>{yZnr zJZJY}fy>CAjV5VnnSyPBJ!CheZ4cvoIRd7O35G3;w$$NJj>2`rHuP&Ze9j5@F1;03 zS_`8W139MY>AMwheK`NgY2UfH&^}f&XXy+xLsbKXg;r+$Ow$F8!1e;}6AK#Y?E?Sy zB`EHBgH#4i4b{OTeU;*XH3gmk5s)x}aat8Y6Mu=wIJH&@aGVH)KlQ_^9mH{I3ThFK zNKtT~I&v7HLOQPap;LGCY|m8>T23+$!zwX5w}k^87|VP+&Mx{*s+-Kfl0To(XxS(a z$O7Qvi5t*NIX+^NbwResGb1}!AOS*=pi74DT>m*aJLqw%-CTaE2KePRUDtX&>8=%P zq6V=dpF#^z8Fw?RV-+dQkkc~7`$?Ub4#0tjTz$Rmk9nP9|-Nv2-O)@4SXjEnQ74PlkiRZaiA zRLtjtmW49dO%zP%4@%w3MyNP|2}+IX!SIuHn0mr{OUOf@l9^+a3P$Mnf~HpFmg%-r zHZ7CWF~B2&3g9IKL-Jj^lyQnaO}LM#HfAA8*mDD+4uQ@29#Jgkwe0rfI{Ag$4X}sgi|p^9jHo&E5a@d%02lE&8wmM|o~;f>wU^oR>=L z!}ctd1R&cLuAExVW#lbv6tY*RxrM%*p7MM=Uk|&^N-2u(1+&B>KgQZdl2_)Lt)J5- zW9+&}D#|2>)e z-{@#${VzTJe`@#aY%Hw*J(kkzD_~T+syjN2W`DKtr^t!FHzx1BTVpZFBR=v=}TUx6Hf^yIzfj&}=}y z_d5ImO3$?4AEoEdHQe9xD_4DA_wyE#=ok^KU4dNi*0KKfT9b-2k2IOfFBP{wIUl~7 zb1ora45GdNAarp%fKw=vZ;+7!-m? zvGm>OXXL#?qbqJ=rhHxeHE+fb?HX9-j6hd{IR-k~{ga9^#_?6SpUYkPCEK|Tu)hgiS})bPdDe~~wll%5OsCy+qEbi}eeR5^mU4Mw69 zP=p5oN<(6(*4k;|7tBmS7_!ARrQ?z6(7|Q2A$3Rw)8VVP?1^5pmPO>K!_K66AQljT z48^+g&R?SSfV-h*5Ji*18fh$PQqc3L zYNS72&MA$hryXS7F|A-ss@+#UkdXaVYziS$P2C^~ABG+Xu%n)KO zs5}^OgoaH_P3X2jf0GkHl<|gEuKA-Ep-0m}YZwix6A=naDTnP@ROW|?h;&u1JQRq8 z)@o`#@yY*@s0>e6o?J+CLn*hu8ii z+jKqhDtMcizo%>c_jIQ&%Kn~i9PQ%1Xq71;Hf*3%F;6yd{-Cb%{NzlpKc#H8D@!)2wldi>XL;oT$B^^W}c z!c!mr>meZK?r^`c0{NI%2m}95>X**-JtA*vmuVn>!Pt9;uu*i8WPi!JaSKDVmJHPD zXrYwx(7t_+E4)Gw$t8)0XgsgYC^nT@dN4=Ox#iIeAz zy`}CeV_y3xw}75%UmcFV$Z41(zo=>Q6SGNj*&@H}uUkaG(t3p`I^(&dD#6o?aKv2s z8Lf?Eh4~JuffYi489!(j90&M5Yx8GZg7u_ogk1U|T`+uqsP23kH%<(H2O54k)m z)uaz!g(V-)JFunAaU7BQPGf9mEsK1dG`qBtlkzu$Yz|$ zuU4I=)u3!vmc!vO5Ssx;=>cQy{-T++gxI~?Z$uPXO)vd}#uJ^{f!*B`btgi=n0(Ec z%j4r2cMo4r*IsQV=6YtYgvpx>bWjPFH%LWcwFPm8Ff%0o8&JDo3f%nwZ+qvytX+eC zNQIZsHoO7B3u=N^V?AVB8)e1$i@PSlNK5iSpDJ~|Ey68u-lM(&*T3%fnYGK0M!^O_ z?P4?dpK1%}ljZcySC?|$Ugnqb6(H;|*|u@TDkk3E&H`VlxpPAPyxI9*^x66KnFRWo z2}=(Iznf7*x~I5~iE53Z9jZS-XB?Sx$3QP=+=vb^z{%IGL~d@a{V#mp?=j5;Vbe8 zoRH>Jg5i4oervQdPS6!PnGf5FZ{K|i6T^t=s9%}9J<(Ezd=XYLQeHdHWg|CJ!x-OzSG*+@axD-&wRepvYAHCJF|arvb+0f zD3GZ?`I$$tj9z;jI&O1LyW}&L^vx zzDx?Ij}Z`M#`%!VF^UFxZ<{z6RQsmZsvW%8o0)1XYyQfVv|g~a#0LobGp3HzYu9WL zAbCk3Sq8gf%>P?$3xDI@QIFt4q>k50A>PBj}X$7rJ~f`^oDz zE8~k}WQn(4#tkKB^ZS&d`gUa8hGq>R5em&q0*Oat?sJk%hqXQv0Ca5*iwM+SZ=h-Z zJzVhuUabkTv8aF0UK)#^?lC?IgBqvZp9z!hjIqx1^C%xd#Tgt1*GlYM?&VO{Y8u2s zn{V=jkb|lAd7}&J?V0%d2;T$?%4#P`j%?t5f4f7psj}?<9jyCVgAp^J zO3Zzl9NJ2M$p8ABr=Dp7LMDZ@U1@2K*CZ4Zl3swcZEC2Rtpw|eNx<-n9(k4yVAxWC zgPe|eD)xf#fjH`-Ikn}lac#72?qLk-|Mb(fedM%+I`)sS>L5~}$h1;1!YNdnx))wA zK9ex-uZ9Ra_Er=qx?kdKfVILEDGa%@1N=6(VpNKFEfX{myD9E`ef`{(RE_|vmv z=lVTVGT+!2Tm|W%_VMG{&%1ZL?o=!0$r(}X5y{X=fMC?)YUv!ed)BOh_W{u!q}kzu zVov&#elsPpnU*3wTUMewIw2)+@P1d|B&Gdlecy}uaTu*k5yaSSH;p_Emq+b2pd0}nL}_^bDj9|`QeRZfqRx>7KB2Yc~+_d0oQlxxzZ?cRY6ip{eSqA`M3gjMUEYp zb_f^Te-nc`bI+L(IRCX`EDI0PjFtBeo}h5g{|!8E2@q!C@iWa@$mFXr?NY5(&A~Wt z38!Sww;(mk^nF6_C<`6X_l9a<2+Q28X`SF!fT&;oFhCXyj;H=5=Z6=5h+=R11batO zSGCF=kIwcXJ_-vLQhcbLG^=XAR*XoDP+7G`Ulme{Bh5}+k`E>G(#St zBYr~jy#@Asp}kWpLD53oljB9*6ig>lk%ESd4E_oN$+6GmOgGF~nCFjCgL|vLTMQQt z4VsK~?pra01qO*=j4m!M9Q}Q_g%=M&hACIN(Qk&L4QYIZGHX}u{lchC$ys-J zadss$&6#CcoO5V+&LK2^r-jt`Lo zE)G^9Nw}MfEG;Ylz60T=NJ$$CFx-Y4Y`~tBt)dm-Vl_AfjY zobWau3o9V0GdFLGj<{M3XJ&8VjOezFI*K*U=A!y?$(mIOmOWNXro8MrLt_U`5s{dXE6uzCCwQ)#lNl4UUlh zQ1=|{>mCsyrhJ9Q!`v>(?+cDgW7uww{zMIb!FsAp63y7Br#Ae+4rrAD2#T-r=ahvVe@$*QmQDoVB8mAK+ zJ992Ssh40pW`r!T>p84uE1pEZgMcnlvI-NWZdId$?8%5Y>iO!$kN*mh?5DqhtQ6Rn zkuU&uk1amF%LQ8eHt!wry)H6P;`PD^*wu@VdYkuCpa+EY#7Q2_rH)HoDO3@_&$9&I zzduMw6mlC=xBlQ}2CfP)$K?h(izI@i$G|Msy9oFe&P;J}y*%AIINskH^~@THDb`1( z#;E!vaW-6l8(?uMfbN;Er$abRL=~RQSJ`d&eNz`eog> zZQIuD*|u%>Y}>YN+qUhVZQHgv+qQ4Nd+&AQJ$J8t);%ZUoY>zgDyqgmMpZ;+j?7;^ zPu+CHVhWCcQ^3s8DbuTPJ^dH95Ojm0QTjwoP!?Sis%n}c2 zInSYQYkM6sxX;^aQAPLO!_Vv9Hh}X&%$Y;$HB>SLRdf$mv3hQRr+>2`;N0b@F#PBf zV6GRmUJB7bXU*4 z@N@2J-01hGL^%C1mjOkhSWy*DaJk>(M{QNI#w`I|d;Rc(0-#=fSr-7|$W9*0dR`_l z$W@#DcJm}u$6{`^suDG3IWA238Jg)HiuF1;zgOTfXmDyY9*b;R5mQ2972W!thTgI#ZMF-(C*&HJ=G4@Ikj8>aLa zZ;GP{>Q47ZNgc?Wd?o5_U1{%2)8Kr3`bLo}0bxjhrQs<`OX-FnN1HvB;zsO~k?3jp zOTbh>@DEs0itE0r4vfIHRPBQ2u}Pjli#5N>ayTrb57dP+dM86u@pVrX#ZA@myVgD1 z3Amv{*2#`tfElse)t&c)wgA^BO46T|&Ij*#TJXF*`5FQiZ6Om6z}7zp?KP6*EY5&2 z`kO4^GcNG5mCyE#)Fv8X4kj?ANlbo3k}M=R0hV0V^Sjn_IJPuZa@P*1pPR%J(U@qu zkWg(WQ2nNgh5Ln$+xYgUwmqbyAFp(EY(;GNXa3=zH5;^?{F0%=NhJJ{O(Vn!u!1s z*@Idgey>NYnN>9znXo~97e(f>_tbrKoEIZGL9;I(dlk`9KQx za$6Af4PeR~0f$|;6}~&rR}^MZ+;si3<&Qc5nMS`Tp3b4xH9TTlHtZl40C(kzI~hPr zurg$4dkxPoSV@X|r-%W|CR-}Eb4AiAqL%Jzq4B<5=@)`m?k)>H4|`HuXH;ht?XCzD zs($pkksVy25D{Bx8JfduRUgk2)Kv(P(3BjWOqAVJ&;X)+xG0U(B25p^)>P&q6sOTGira{(3w5@^%wq?>?ITV2St9|?`^07ZQ zTVAhCPCzc9=Mb=`Ox-W84(%h`8yj8P@2TA%C(6B__@7F^A3l$tut&POFaNnzW%wH` z|IbU+f2#%m8<(nogD?M4sxq>&{Lf3(-)dS8>rLOKYE9347Ri1D!aKmI;p@&ocvkd9 z3-kU)T3dgfu)6-wxNtGG$&UvuPozSU1oMPZwx#%$fPlf?OMy@G&IoGkAiQ3^(7lQD zfhF1{mGPk_>}OL8_G1&*uMpvH5wVZQ_9%vNX!#v*%lEn4P5{m|Z3@o&+6%uEC!SMz zhqDMJb&xurvoug1MBzkNJ#a;Z60=twf@T&0*_dwym#5sTmpZ-LC-!kYx zf%9iNVn{2TpfT-6XWz6k5oqXKod+%u|9xk~)QjMi2pAzF7rqS$PCVZcx4^OzFSPvT zSb~A-Iyf`R7`)s+I~Wk!0D45!flY&Z54OZ;TIhg!^E4n0iyh{kAtBxr26?~~0kiPO z+OePda2FMrze@1qrf8@*K-oUMLMZFK`2bWQ3=`nkbsl; zt4+_{Bg2O(;F99(qG!YRrcv>r>r1CGSvlmAS{g!$Wln|~?Jf4?f1l!DYBQP3!AURg z2AzMX;2#irNVTl@Lt+iu2zgIGXO(X0y>fVzD`;VwfU394b-IDliN4Ux%HF%!=cTWFXW4S5?SJJi2D%8Lon0X zA)2_H5;Rb~a#p4R{!-1v-d){HCSs}GEZbX4?|0B_y5i(aiSO2Hi%Q5&BCR%8zWj(c zwT1#xv3yVMAk3UxV$ly*di0MlJ&Hc2a9e^GFqR!5Bx$Vh8h3I?x)Qi%IIXxxCM_|K zt_lqB#3~sEv|wW@DRC*+AH*oV3dRG!;%~!k3k?Wh2Gu(gxV{fD2w^!UGgk{RdJF$8 zTPL}Q^B-;Mnx#M? zB~ApUFtFtt!+|ZA%U>5yM_k*MHLYY+L<7UO{#Y?C1b9Q8ohhB?nn$=bw^ZXR&R z(2y@5-3Z&Wyx6|JFeJ|qV{+Jf9>euV#2lf2h3Z3#YWVceuin6@*5BFg*wwgZ7lbrU zGzl+F%r;WuN30rWu?Q>W=ZnN-I5AEyQ;eUTw7HHjDkef?=dL$sP?2+S!AE&Yt+{36 z%Mzs_{)R7C4j<;wQI>TJo*k~YzGdR%Up3ZBWE^UlDDhlz%yQTw&(v*Grw%Vu72~d9 ziGW$ec72TM#%(o0G>uP99LUzv@@kXe*&Hx`i(X^Tky9>Gmud<$jo#@Becxql`*SC4NPNI5qOH`Kum&j$~HKp2~Oa+4VS#tg;~UobP66PbN@CL zJSZqN*MlV=dsqu$IN-Axn5fw>xjLT7L*kT7D+AlX)TC@$xE@{9IGktfQ>zHCBG{ar zq1O^xEba%V?TPWMW5VI+Omr*FqbIVeQBep^)zYFuT-gB>!weC}r6N1XWyT+zwt z+w6goqt19{k?pP!aVD0akk|z&^hDl6qy9iGK^AKSkh)dnJ+lvEv6`;w%YL#Sy)Qv&$ci!Y)8yfPPgO;6OKwciLfxCG&?`ga4_gDI0Q=P1fv|WHgbhgUg6=1h< zLfRoTP*X(+xjRjq7o4MK%Z=A9t*e;XTt&V;z}a7MtwyB;y<~#Rrq7qOPap9-(vphG z8eR~)2u1U}4$hRUxzvsRARQEAys{!=L2Q8`wTFZXqIW7pvB=Sx6VcTO(c@jrda)Vl zzo{mlclauLs#U1J(I($Tyh~G7fa_> z%MbXaKLJG~16?*mbjw886gYG?3#;Wae-1)CcPKn!ZL&pMl=6DAv3qfwzchkC?Nz|p z`)cu8R>x6pT4hXL#9sL6?*&^bA%$f>B~mItGZQ(s4dt#Xs7yFY@3g6by^79f-LsY} z$|uZO!p*AHVIX^gBEhtx=udjr2L(Z6TzkJu?^Vy=W~n_Qcq&W70&NU`*gZ3_A`#wr zB+t_(2z6Lr$c~yL9FurZlcH^#?ndf&eQU<``N9?pCls8wl;MZk|QwBy}C{eL32@BV5^+mzVwjfWw z6N^<`h1GPH4|q9lDT@3UO%}dOa{MfWn^kW$?5KYjw z__|(7?YA|L|0DBh7z&&QK?vI9S24geBO5`%I#^qlJd9Nh`9&u2W;cd-0AB{#!y9(X zJJ0zJxP(IGFk$2N{zRUV<^i#BaE4t5Ke-cdM}&Ly>-OpU{8C^`cKpa^O{H!txyS5! zi&t}Z*4R3*opUw3UJn4qctfN3Y|$|SPYuIk(Dr0o`X9_jYu@U?k7h~3&+c!8xN2^7 z>Yr4Te_JW}FRICZ7rpxLg%C6RjePz`4av&zFQ}7A_3w>QHl)u>o!%I$StH?a_i;e* zmZ;`s!T92^_0IMS0XZwOn{2Dr`glvbman-ScSg?yQ_kc}M?b+>RReoG9-OIIM#U~T z?HF)CanJ%YiJ|#kQ?6&aXATHc1Tw@{eA`~ynHNsVWn}0pWmDG6o8noO*vY;1CXW?=d=i0@Z+(vNDx>dP*5jqh%?%* zuhN~l zfy&t$m?2__QZCyFS~i-Tjz>-7O`i7s8mw7rjBm(fZ;BFtz4%s@Oho=BOi_R(h`=Iz zy7Uk~ki>zo7=B8D*@*;ML@1;eDpw!^Aaa<~!XOvhs(Qrv)w5^IF*->OSd02B;^lZ-~Cv0faqtd7SVLoJg_2)%?9 zM+)sMbuNI_E5DSlSNyxu*EgC8BSJWt38KsvOwOO!Y7IuVXwi7(&jcex4jGtR@-J(H zSQE&o^Y6ZMJWIZ@absmJ0<{GSBX)ou!psoV^EulY+VBs90pepj8HIF~;6Fbyb6LRT zcUZupcGxUtujka2Hb4mK8OlY( zv7*K@S09Ihnw^!&?T+Hl?rRH~LXfa+l+M`AYvhW?vjTuG2zG{nwox0VmrlbKgpU4= z2FqAvn1h;447=HS2!mgy!9~qBRXiEXM;enOs+I~|juse+o+7w(>tNZnZ|`&*;y&1_LK+{E;q9kGjMpQrj3+T82selR`)mdvM{E zIYJjW0yiIt%4+?OX%Xbj_bv1%)(_RFrBVP}Fpc-bSiuJBSW#xhR7h%zYO%Jigqf{(-J!(H-|& z5vY~&XFbJF5_$B7mvm=%a3#L-koH&|8xvG13ws5sn#0!-iZ94jhC-HsPl2h5Mk)D{C>qE zRMuzqfOwog{@mFlcDOE9{RCo@VOoD+`eI0VajF~hlZu;0{r#>i|MqTKq<*ONF|V@= zKWP2T{v%}^hf9|ug?4mxI05F%!E5x!bq5&p9%ez4o4lx~Ae?y!5)E3XgLD=Tju zG9N~>p#)jzhmEH06^HEDpgG(bmlve`k9I%1BZV1ws*u|Z=1pxr%9?7r^DD#Zx6)&s zv9n)SGMj?^ZbbpPHxJ?uC7?>$d^DixLZ?TAxxGwr+h>5Aqioc z`_5mT(oPD0QPx5l@G>E1tL}{EgT>mpP}#{_gV*=Vyxs*zS3a0pj+eba(Za<6xxZ^* zrnjra0r84bG;qJkrj88hU5bWz`J>)Xz*-zY&L%K3GEj0TPc#J&IqAdlcw}aEbc^UB zQRu{1p4vg6U(unzQSlgNo2qvN(w67Fd>$n}ysRAaM&KEvMZ>>VUB#L%2n6JiS9Glm zOxx$W0<1E8N%Ok2L+e5nojc!!Y)i-*m{VPuX>}zDo)}k1VMy)>n#s#A*>G?yw<~V7 zmDxc|S|^t4Ki|*q?t*cnfWXrFc=+(Z$4=Y%C+E?wx6DFp9YyT0>xoBeo&5s|40xwx zU^jxZ$nH*Oo!4N^vzvT9R?Ga(YZV|4El%y8x29`tDThX57%hRD^;XWv*>52?j5>aZgw^5i|wazGW zGi4#2)e{CU+Q@V^SY&c)b%OFtrT2R-C}D3NsX(6UTO)6gn31`}U)#l?fgR{Zx@qq2 zZiIQb+@2oK9UWON+vDX9jqz}}CtCS z#YHx`gspOcrIAT6NY;hm4tnEJXo=WJMD*^N3L5FQ;D-0#9pCA@J)dgiy}4f9o^J}9 z=lO0i-AqF`q9|1~UfZGpM3NWv0vC!*4H=O;OnvhM6HkG3OPrilG50to*XXw2ULnur zriwxFQs1pB6}2qF42@b1)F?3QTD1`j}@l1O;aB+93Jm!FPL&4cd28lPosSg#i)B>Up zzZuK zS<{c~_E0aebB4r;tME|82}i*;+k>more(sAS+;?FUQ|EjO>GPB*}gtUN!iM%?<^ll zhirE8I31vWs&Ii@q-pe%TFJqR=Li`hb<{F_{j6R&?p3#SoFeAQf0O2|Ur!k&9DMhb z7mgxh){1~2V8Ade8~KVhjE)=iPcZ-1s8J^|j5`S=&;mp*d>`zZ(J9LCpXF6c}BPx;XvLT5@x%t&ycpDoGe z222Wtj?emF9!`zeJCp7E@0+XS6mc;g>3IF=7uoL1QUWWU2_bGcUw2eK+#NULg6F`%KHO|<+GM3XF6{TSRXesN{b3c z#16nnj}f89Y!Ah(4U+S7B3?A@2Q-2_#^Af4Lyt7iW)OwTPeDvMC@Rk8htd?RQw-5h zvb9AZ-T#dA2@{L-j`)1#6j2(mPrQ+u><(iax81uKT4nF22TqXgdR1FLjwy|T_~r8^ z4Z=etjEVe1#*Dxm-*pi`o{bcwM03!4ee?XS zm*|2+Sc*v*wWnsnvpI?>{ih;8_2`02nhcTy!0cSYiCIEUBNbvM-6E0o>)4S~71~3Y zahjN6(;w`El^s{cPzLlJD11b%x;RZa_tHT4k$WH;D5reW2H74a6m{cTNF#UCqRd(& zQy3fbO@iYKv(usobBSpS;AW(Q+zU2@JXUpce<#(!dj@B1#pP23Yj%XQi7DQ;$AS% zw%=}TEw%jFNbSMoXiEF01^#DKxv62IEL7=CZbGJ2VEIWzYmB=Iir!d}1k(K-@?rx_ znJdf!YL%REQ@_1a zmXM1kW@+TciOn*J33|DA7}t>z9pm;i{Q3Ev#Lrqx5T7J(3>-DIbAy>wF25bC#{??w zFttH$*e_ljDce}3$4pvanDr>)a8IF*i~EO6@=?T-$zc28^p(t34z-MqA`42JcQTJM z4`-`uzPA(L(q5Wyf6JDQ-+8}O)xZzq>tOL}a55#Z!&zs+PUZFAIJt_(`I*MA^-K~M zhZp>h0hc(-_SIUYrx;$7-l>N^$ln(_=RW-xY1i&Bmc7Ea!WB?h$UTpu}{sHYtMUa*28lrqf5d zhIL3s)D}PwYsBLUI^>ymlSWp0PenVHS|$qX4K>~x#%$UnA?L7$g_=gpgWWr`QL z?rPi(DM;yMcN{Yg*mwQHb(-&LrCu-j@%mv9hyLj=(Sq^N4VebUlGj`+qIs=H z_W@KDU-k{VX64=_l)o#wHaY@t>I<)a97mX;xmNvC{HIh0NS;czThDu4uo`!N;KbRCc zuAzks2~*b(Pkr!GW_crDJ~;nLYWUmQ&3~i@hJP2&{D1Y&8U9@l{l8h`=5L_gKQaO{ z^S_e%QeC%R7eV;u)Fu@4O2&epBqPw|ELWu~R^Wt6DDr)CN0SBu(StNcog>~oOh!qi zCCW!gC=ejpsMtN6o&QX%=JANrYKenssDxStU`rsYxD$KD8xmP013tw=b?<+`#}oBi zoNRhv3WzuNGEiCPhy`0C{>B`BSXm0I+?Tt0x2#m2%lSq5qetiES08&cWRw2rfNLMh zKG-)3z?Lpd1t&MT(mgk!CJsHiU@M$vT9lKn{-PGW?_QaX7WaZ-wcd@*8BL6geah{108UX`f&+1_}LEz8}_R>6))hM+ZyY5@0DBu z^9EFE_U3WowPk1bFV-)1o?$|r-J{ZS=P|(3mhIH7yHD*FQY^xscce2W{S#qA=d5-0 z+XH$OZ1#$RV1r2A+8(QqXzXUK0sX_b$uGPQ@Je6(1?ZW*2U$|EcLy0c9VKy6*1N}z zI960n$YX{M#ylYOS+FkHwpZ`W zS*faBR|%7@d@|f>XP%iqp#GDj&&A8`l3+(>5;%#DC_0CX^M>lH9o=04@3~}u||5sC{Dn<`?Kt3 zbU1Mmc69d69+Y^qZK5=um(&)Y!0y-L#V8S-D%3~+C?LcOOMDcpDBsy?`*lR^@%hsm zA)EY@8m{6a5wT6xmT=>jd~)rGz1RtZ0pb?iTZ%FY|Fk{NYbLs3s7PrvF$9Edio%xx zFSX)264N`CW%qBR#BZg|hJI}gtD5jm0-A8G2KmG1@U4`z8#PDtK}3&05@^mlC@5c!xXz z13p4`rBaxd^uX`B79iLa2xto?nW_(i-X-)k!AeiLRMYyZ%lA~ab-z0HQ-?q{hK!o} zyskeYbrlq?hHiqGJSCE{9`)%wB8KH~RN5~@XKqG^Pl%X=2G;bra<%j?h)T(>uG9ep z_UoA|IBH)`>;NYD5ogvQJk1rC;jj<|m9Ggkt+@ryLpF$tXTi#TpS%t|Wap|Ay!FbV zr14&tF@)qRMm%|`mxU^<$nd@HL@6<6=MMden)Of%R-1Dp=>%L^VA`4A;kZZf zp<3T0!Z$d6awmup;?{xBCYb!vO--GHjfA^Rfu|D;8D8y8{e_Bb)EHr#_yul0!#~#u zIC9f@yTOGCUx^5+v|v8{7LFu;gQ;=ix<(VX>iF)wCw;Th#ql=I>BEe@ze%fG_3P=m zVbVQIuVMnePpMIpFaU^z8p+(V}WMCzd8ZG1!Ux4)@cd|EN3e6SNcISJi(`g^Yhg zpZ}{=_}@|WlJRdK&p%Qj0~6E#oP*g^wfYv8{!7hkMZB9N``*(9$0pm`4%K9DAq-bd zdd-XjCb*wSm;ku`)Mr0ujT-@@HfUxcYjgoGO3m6P$HXPaBhIEV#{>&hgHC^)4!SWR z?NPjamLjjss7HPO8gIDUEV2*$B8K+|NP6veEfzdM|fN;fJkLvpx+oU^}gk5l%6c?*eP0`*#_Bd zrwa4(guF3fGq1&!zaG_1Di(5gi4nv0NI4hhKM0{x;E0@2;C{arZL#j?sQTlY+%~sc?s2BeJJtD9gGQ;Olvtk*feN*pbqT1WnRvsirz%`maMnk^j2H|U;B%1kJ*8qbq&#Lpc z-IfiZuzKh7x8Es(j#-5xkkyxCsl(_cwb|n!#R+%gkQ6bRLvyq>~gmPiO6@3NiXp|FmAbu9ZH%^K@U(=aFzCk<)#h= znhHraC8Bb~DxKnVIWj(q)b?s9^7dZ5nQ3%5PG@F_QuQ;`l6ynX2-@v~w(gPa14CIWpxGA#E5!XADsPxbvo1^}-LumBCv+57uQd`fY`qJ`q=d~{y zBeO@1IoOM)M^J|r!qB#H_q8J>f0h*?0J5)2gcbcrN2d7leDnU`cJpNw`-!n3_w|SD zgk+KCM0^>hVT+PyTS|ocHZ1{Uf?nP(bMchnZ-k}d>lK`iOAg4hdbx5sW zCHp3FIx+{^T4N~2Ncvr8-ixYfKf#jRlD>^8J(~JXkrl++2KE{bbXE0}An3NrZb!-W z)ph&y*V%Yp`j_|{_|G4E3I8Op{|yxUF9Q3&#nAsdsN?_tT^z>0&D8%9*jd^B#V*dp zUoKB9e?8;u&`%XY0B$9m1nB?7ZSERWo*!Mng{2liQjky-8>?PF={`_shXz6rAB|t5 zV01e+#Bu1|3<%f^06msn%J4Hvm@#6486~KD1wPAq7_Be60Ks#sWqU!~@@Y(!o~qLE zX%N?MC4}q%_%KO60!zf^oOeF{wGKLO#f?={_7K6`jM3{eIN+Z;LLN6PFxH7$ibq$v zT{jaEi`h4t`Vglyvw)=$C#V^s5JODK1rS=#XvK+OQUKdEX|f-}#sVAm3D~!;hxu^L zUBFL}M?o@|>igJ%y6vWuAtsde^B03+@6V7`maj`7CC`LQ%P4E?FUVN5qfHD898OHL zFuzrpvm^WJp4Ny5CFf$RVV57G8ZRzZ`!R=t!mLW`u|}e`THG!pdhS`JO0Gs3Qg*|| zT?#4rFP85tXJ*irSyJSdqzW18vSeL%T`cUrYxSWW?Px&HEICoz#@tqZ zRS9Mu58m>l3&l$bVOJeB(nD!1DuwCpzu+3IzU``59u{)9i`R#IfC>lQSckBNWkgs` z!i2kkY90zK3&{VJT9(y;4Lu7zfz98<}$$WepF6F+;=|9jwTURan-rgTs7a zKAb5=oM&7J&eO~YPllPBMw+IB!#y?ayT%a)lf??IcP|msm5b0xs6TUGFbS?dYh#+p zoUL_IPRwKf*+5pD-$;naY_|L`t0M}U=msW_mHyki#C4<;Z8)wC7We&IgYeKhXv$}2 zazIUJwR{YxCZ%mG6LbMuNjfpFqH>}wo>BrENnQnWQcNXH5dY38De3#|ZA|qzS#_KY zB_7i|PF0CrgZ)Dd(?UGV$h@LGicrjIxLO2NUd)L~6Hp=Tmh8eB8b56I(;eIXuF!(6qy*6?UG97A!@_I*agIaC6D2Lw=* zpo|nP<{Ih5_fbCkd-*k`goMkVt)GMd&)d~4h9A~sYiOr2Tg&$H`?xGcbqQE&g7O`J zugXmNN4JpP)H|+phiwLYtYwa^A+B$ZEkRa%YMYy^YKpC-TIyJ`r)_=o&&@c)#*vV) z6Obgd!vvDk`5x*WKRHud{LoNQ3Mz#%JA6kvPz;->e%h0d*vIuaONen{9SQ@PkKwtD z4>;@wIz_2Qjn%b9dHI@0H83p47jc&N?ec)Gn&l?gr_(kFAyNC0qAZmbxi~QgriIwJ zvwATEKMWZH4$6v-Q_-X&v!5aNe!yJ;SA>ljx~7EXr4C=8J+5BNUgEI1()X>%^Wc{x z7!k5+Hg8t4!oWYKnzNXg9F&V)?a%H{oovh$5Na@wh@@ZDLMF=T{-QyTz`2iERn=3N z8?QH3pja-ic|6hNIwlaiD%;3{pKnA`gZlg?Vtc9sy!2Qv0IElrtw8W2TGY|}<1OgH z%*xHq$hu=cpin?2(8ED0A#rKw9NAMu1u}~k3)t~(iyAukA}M7W?3>%7WPq!mHEgT~XO*=Kp%xY-IfH5POvQ!6~K#*YrbqWSIN$#bbRIyrN? zEo~yCDd0RAR+yozL&ZBVhQxotRJfNV#ge^bzZ-phxWl&qOg&&#W6D}g3c`c=1 zJonS59;J|f=v^K49!4w?*~HvCZtuXl`Dn4(QlFppy)3uw$geC0&3z)YS#$mTEilou zg|(ZvJr~NKyOwz=S+=P!z`OUH)(s8pd;B{Cm3DPHZd-y{9G0qL z3v;5aI`l+@*(9QaoccoT8GBA2Gkn8RUuGa(JJu}f$lGPhR`)gYLPJCQO1oyk;du7; zb%pvS_gdWbME{xf0AH}`4*X9t|KISg|0?tU-&3~y-!n>Wg#v`qwW@|zg31B$uI{I@3W%3IZ03!o9L=}+we;j0v8+S&4_TPJ zhc(an+cvTkk`#;-d9#M3{IR9I)?xJuO4>#%-eu?DkXe{_c!w>SaWnrr$`W;T%JAQn zg!Kg0GV;%X|QS1@Sn=lh@>U(Rh2QI3M2HL)PII#95^EAJ}1CoUy=j0 z>>eLh*lK!@yuap+@2;==N!N-Zy9L6)Rey`)hBbmpu!99y0(BU9F~*I7oTZ>NeKL`_ z<;DzvIXlBI&Y0<-J?30t(5Nfr*=Rm>sMqO_GkmGK>G5^dTBuISH18x1Yq*i5_*1xu z))%;|5Kh_1K^vA&MCVr(lQg?4ZKA%kX|@;tW~5|a8wh06S*yy&*S5QN0JX8A@7J!# zZnNl@lmJ}6rdotYi8I@F+Oh14XNT0=lAo* z=R;FD7@DasF89|q*U!C!MprxMB~qc}nSo#ma^XxLcCGFxfo`uo@uwv*7S6;9vo~db z<+nahhqQBTt?8xtmrBRqnzDLKX_duB?9^I3+kESrL4~dPW)vhhri7%f6HDee8(lfm zLv(3dlSA|I&ctGM@Ia*LM3^6H_4!2mB0jhyj;DsOd_S{k$D7uoWn^f=ch7pw=%4qW zS6}7@kNMI~OH4)0J$7w|-~mPTM9oBvh6kcwyCj=QTnouKRcJY?@seV>%^z^tK=Bqc zB911geyzx_$*p@ts-CDr$40Wp(i2ttw z>i;=)x&LLGT*kjfS^poQdwSM?p%6T&qV;VEgW|PZ(;};8;R@4Ds<#qQPomM*=)maG zANw6Ve}<{A+fkEh$$baU_eV-(I?^pYft0M|j!_IsO55e1!3lLWq$jy|Zkt zxSmiHc|?lW>^s*$Z@eIped9atxIt46^^plR@|$?qbVI3q+hR$M$v9nG_w41}e1NvS zWc)?+wm)wJoY;Ef7(^Jz#zn(o7zJinpZ2h;i!R)BM6)LZrmaL>4Ntlz@a!K-cUxoB zn=E!E{Io}z03Qu%;kPCAA0$bHSQtPI)9(pAq1;2r@2P|<_KOa)e03D+D@|JxLPH5@ zOI66PU6wwWKyoNmVuC#tZPOMlNna)9bi&p@N?ZTkLil*9tO4_*q6n55F&`}t3d^iw zCQN1099YOQ5cVcyu`T#{9w7ZpWWIbju2z8q($q z8Q)91rSgI6$}7ri%B#u>v_-DRHOLB6$pEGkvmD)7iI|GFC?MK0V<$?=zIv&spxTF$ zBPOf$6XTqzN5bMAnH6OOuN5z)+0RU8<*BV+we5kWq0Y^MNwEX!taVG$l}^YOo8K>I zpYTRh#}i#d66dCl;3*Hyv`CZI!8sKrLNA?d|N5BKPs^WH6_ypq_-B;wHutPGeZ-e4 zfml696&(|i?9+#wyjg}g%x}6i8qy)1*c%4840BVLVAU2kdSB7#x)fRaUV(AyY_!XB z2MzZI&LMjX9?K3T;)84c(FDqSo^Ey*>{(0p7W(_U|2Tyfn9 zoED4l);&IxXhW>hzab}&zXVTvv|eR~ME*H;={)SsuTV;CeEq>&}+>V{89t zLBH}eg0MXIlF{vT*{@(%KiK%E!=a?)$Fuj8q!b_~;5=Xn>HpIJFMw_fradV7^KpETG;pXAcE zp~fk`HeA(f&k)HLk1;GC^eXalXVEj);_H1RDUuhfy0Z%j+xpi6fjU2HZaKvQSx#KPHeaf4 zeuA9XWM*+wKfJ<|=P?y_%@DkAo8?N~9Cxet#pf{MZS%l#X9ivgMKQ()p&@*U@t;#%_98TZrXm6j}hb`nljRSvFF*{L}QKYvU9@T{e<#Q`pHcaYH1$ z=ccq;{L!PLIZc*RSBZ|lDZosqzhtSaxmpOR|HX9rM~1ArUYBII4_}6C@|%`R`?Cfg z2hY`T%aH*sQO5Itrfh)4Cq?TaGAYetmHR@9#)shbsPGFE2>s&(l$42{p;RQnE}v`!%3E!5RO-FxzPR3AYSluzvw*r2PUdmi z)lUCt^UxjVeKT;$N`w}oeu6%2xG<37MyFUZO%gJ7Dv5=>(Ju`%e!_Gr5Bgr3Sv52P zQ-H(v(K_u}9`S_e0OxRc^=*2r?uKu3825^`LYdXj8U(VhUM0HN;1{Y1e36x z+3d5x;ERKo8O5gag(H`2ey+Pe<7CSC@Q_#vAp#j+2dR=R^*ejn&dw-LN?BC2)rWJw z7o}wl8Z0Q@5wWDC$Ty>$xBQlme3rZrOHNLJOtls*#<0|M zPXY9)Y{b&8mK<9O_qpFXAz+$ZXwRLuq!IZzlICp5q_A8V zo}KbaP|KcV)nnlSMWyb;BT#BbwEJs-;;;!KCS6)iO+UE7s2bWx%)Moh=5No@x-^lI*TFLTF9WAQ=ICKQKps5#>nnaKGFiGGf3I;ujUec;n_u zNoB1MEP`8Qeqj$izTxCGjb9H!JY$0F`QQc)AC(*fwWWE9xz{lJLxVi(>v4AZtqL&p z{*cWeose^j3crP091p^%)a`qD7H*1SJ#1v3r8WqJ@(xM&oEj%ZNw-&%ZY$_3j`{%y znMwtMdfVDGFG&MGA4~K>X zS0Kp~v|hB#s4ZLWNl1=(Jj!9?j+mu!0QK~dG~rW#dp8|q%NrWdQ*|NNdx(|JjKh>!tDQ_(?8R{ z<`o$KJMs!l|Cv`{U}pIjx*ZpP*|xC#rSzS9n^?#N)5~d6-ZZvP5msXV`($Fmx=ED@ zay3&fzc1qAeEC438JpEVo{AECdR=*}PMwbxu1%H|>pEq%W^{rqPPB@GNSr={yaB#} zmT|p)bB4T`G2|U=-)FK^dTZkI!6pNRk(MYAfA9Tp;z?k9*1qUqq`?wi$mU*tx-I*I zM`Mzr*JpAO#&OSAZaA+RG{U^%72E2G{8Y5g6UTo7K67Z3{1W3rn(@zeqv&tzy*8Th2$pO+}Mf(iBbLoRTLw7FTsTd zdgl?-gx_G)tPt&^N3e#vv+%g%Pa&m}YVD(UWvKrTbMF|PX|wHn$LZKs$F|vV(y`s~ z9ou%twr$(C?R0G0I$3M)eabkBPv#RF&&)<9{f&gz8I_kGK(IE-v7kn9EPr5Z_HpH4op6IG>PMHSvs1|EWSZMIMzM zF&$XB&jG42tiu73kM@MtKiZDSqCqGjEGP-}Cs!0luv_RiIv5@crOCLR)XtU$aX9gE zbi6H3H$;pZv=cw4bU%^cboFnF9H3E9GTY|B(}V$FHgL1n&OmA6H3d`g zzU9zjEg@*=22^mSoP0iecW4&yT5e=!uSnFx{A`9YMktU3(I?U9ZB-L~2>+Tu3(ZNO z6c|uLIteYUpPmN~EQY%6cFZDfX2XKh(fi3@z7oV9#KY50klR35Zi&On$pYD>96tpN z&~w4a>c3u-*>tAAlCnnSHaMZl{MSR6N992{8^jM>-7+yuDC?VUI~cXeJskiuA>&sMzfG_0t?MGw&FQJ@%gvK#YI%9^!;7;=_Qx+Nmz_1W0bj=T&~lAuU`YF!Q#U zedwU9`7#mL1@;xdz_4v>zI7}N3bzgTX{IT#1O~WHkk$`i40^T2`>hK%fg8L7@s(I* zPsvrUj!K;H-hEa4)LXY1USoE^B#oVv%9%=_!RJdSC}1Ukzp~Eh>_Qri9nqELDENtV z#FgtaIsf*Dj5c1EC#P8b@yc7@z#C7B69^*RU2}uvpb7~!v`V*VX{h0;eaYZa<698r5#X zJ&(sAdb9l5E7i*E_Vm&g{lg+J`*N^8bQc6%obtodYn*;nLEC9MEp6qBEUISMT_90n z7*2e5+AlqmC>Et1QCYn|lX3Z7p2lSio*&2B!4Xjt(>;LTYZjz-&MvXsiJDBOuYIOj z!_U7;1Ws3=s=m}vvMSSh_EN8RdU9GcWX?Bf)tdDI{Hbn7+%-S;A|}DV&(ITwDNrd4Ep!#0H|J`lDo|h zDB+R~i7~kQbFRz4cJAcj+i4pP)IY#jDB$oP5Bh5@k6XH?b3$;OgSh4QGcYTGPY2C=nKDD-*bPumCSFRJ-_HHHUK#E<>Fxd@P32EbwF z*#X!tC0empd2$IO-rn+AJcXC5YNcxdFQjBQZ@#V=EqNu{1Gl`_BO*@ei-esl`u4p zkW66oyf&iGxiKib!1I*qOl3De-VjMFm+m<2_DphBZ3v5UV!H$inw_v-_^s0^>RNg5E=h3C$~|d*YpzdKspQ zTH%vp-d29hV8zW93d#eQB(A8QQJQ`qV+gVs(- z;fJF(Wvq1GVkDXl?W{9Pd<|zG@3Rcul~ZbGS4yk9;LQ(Wvrzg|Vwi}(H&pI%)w;b6+sZ2+VtB#tI%FjwN|=ivhsOYx`PgAP*8ef_^U0{^|T>z}91 z|2rNqrtkk2I~M(4c7?J03uPDE-?_pj)c#VazFu5C#!aUN*y@ChGIhQpp+ZyfTdDAx zndL}=A^A%67j&eRSY#wNRup~}*gpD8f;Gk4?tUS@ANDZ6iP<$vGe=lnlhkmYD$G8^!mX1g4|DEJyFd|~ z8O(i~MhkSt>%2{fwCepzosTb~lBgDXiMXlPy?T2Y_WFd^l? z48O|J_}+md6TRDQfLCq9Dv`{Oa8z!v&-qdxJS`hR9iP z#&V(2a0SIeX9}(EQ@3VQ@+aiABKTN?&yJn^Ygyt?%4~s}@369nwhZg_Y(x`-=C|Wc zA-jupP7p*p`~V^bzA~efa5dKKH+<7k)qCNX=&xu4aSDRt*mOvrQ+f(Hda=!Pw)S~0 z6ZT|6iHmYwygVUWx`=jqYMoroy08E?ocX=fOl%z&F7bkdS2L_bZ}!K4p+2+M+aDl= zH>^be;p*_LX=VkMZXHudf+U_TQwq9M1_V_RIl-Yooh|G4EOLZ5+1#{E;F7lfxacT? z-uR?y=&INSBXHtP1etex3Jl!Bm2!{4rl0+U(25i;*g}aylf;=8oID;pM}rS?U9-|b zq$xpwm0#bGoK^NAF!*U7pp_%g2`{q;)IDW=4K_!jo=%pA^ibJ;Vxz=C+ zEFz2|xD!zU3}9FFuz6GNzL*q(PzwD$bfy@PKOE6LzXc#RyD+5Fr)fxlT-uHX^;{>4 zDSNU1)KI{2LLuu(441Hc|bT)t9srs(M z2Y1y~ZnmN5Nbgav+B#ac05zv;DN=h>KLOlRMtwc(HgWalXD_$nZk(~;z}B0--5Y^p za6#&s6{!KT)<2(~CZ1hR2tY>7mf15c+Sfc~0odG~BMh0QWwV$Y0A&=m z_JZEw7|@*CaoCcDqk}%Ai7y&##z{!a zj?o;#S?8<(f?o+OLOZaj`kbkh33aUNsmrJ5;_AXcIq*8#nmt{E)>AuO7|v!|2!}t4 zmMVe>E$vkWHlNNkJ`lKbB?Wgd*Ng%V`ALNF1gR@_X7pq8?e}pIcEWckQJr;{jCRc2 zxL(PUjdOQ2b#=^>;lVv1ziX4zG?Ro5F&B-N7juY!8u8H7w2cUDiqR<{_YIk=Bh{jb zF0?>v!Z~%QGhrAAsgWHUuXx><+o}h+2*XOM-Bfq?sfP|iAk8XBiFLE$7hKIRTAU?8 zJ=2Ht&5D&t|`LZTA@l-iI|NZWk^4k_qua;PfCSxZoZ^MoEgu779D{{$6%ThXS>%JdB^zg%$ z0qgzxYrQHf4TkhU#Oy38UH5bWkPK&@*m3RrLXMI7%x3lR1dl*y!l}j7J(58p-)5 zsz5APT)*p~hZ9AP_EBF#-xgY>w}TdRRmLL$MLvAg_dB5m@AD@flJdAO+E%(;BoP6R zQ=7_Umdti@Hs4x-KbI{~hNARu?4<=LpH-VR-6D@Rd+2X4WD zR*Cjd<-k`~pLBQQ!@fy&C5Hs$RiyhdP2{n8(!g&mp3=|vOt}8RB)h9=Bb29G$kjc& zzLe3Lt^9KBD=?C`8PwJZ{KXQ3Ck7o4vi#HCj1dEjC78s}AQ531_;y{Mu9+f+uP0&E zbQ!X4mB1}>$Omvw|6_2W}uk^~?taT5ljCqmLnH14_#PL0Guf z(EA5UzqhU7y8^i37qyCZN0b&ymz2Vzv2UCc ziYP3_og}g%Oy!87DYs|AOkF_pjKM(XN-zwoPuzbp7oBU~Xku$x12i0Td7jvdem*{? z8ip0R9>$T{p;~i>-@M^#B&TXh@^%>3`;av(r7654rvaa7Do`KKaheAuW35NwC4D1C z;y?OqeghW$=t(oHP}lIxVVof}M(769T>d93`fSt?0V-HPxVnRW@XmL-NQ!UlPI5N1 zyy4S&RwDjo3$=cY%X)**x3s)!dno7*=nd03Y~~O_i`cs9X+LlK+Q3L*&oIpKAn$iK zd4dVmb(@sn_=jX0xX)(rNz4y>cEuPd`vG)0+CN>mGP>1i53;sqc7sO5Sl2EY1&NW( zi7%lD3E(dfh!Uhv>q}?MRVs9~(SN5esjK7evV3FswYf9jx2Il|2Z5kIzoIqI^gE(? zQZhy`qhkNdt1jQ8tWxzo0cK{8)dR_u7z)>^M+4Hhc2NM;*^M#{8+~8pav~GOI4uw__eXKn_{CW%FnE>J!S(A#(7cu93+;%*P%*x> zm+R3%56oJq$A{JpZ|0Wglo+~AGe;5kEsdRaLfT2;x}ahf_U@~M%F0^&`lwEed5BPz zSagnjNAq;A!8RY|d>E=J22abJ`p)epflxM@ffDe!Z=*5%32;$c~)uuTbDCkVkR zp%Z|LqHLSPg7HKK^K|~a+w~Jt{bl%abd@@B6{O0s%)>KtuHljutXTne>vg0ALwRBp z_BI`tJFCS>jd8E$HFBW9N=E{;2dL>6ZJiONq6n*;5}>QJB^C492iu5OeQz@Q?1^*Z zxb0|sa7eRa8)dxx)!bf*6mMA%;;S-Yq-a(19!rOUsa#05dv!^Nb{$dg&avLdhLAUx zbVNT8sEvnZ=m|N9qs4tCDmP5s-3xxkj5&kS{Mig!q;mE^o8B#qk2?ywN8x7)EmqWu2&(ZA_CJTS%-@k%DOMLnjOhT=$#>}i?3LaNT40BeWZTO z^Fn@wN-Pyt&c1q_q;_l+keAP2QQT3Gj&QNS~WRI&9?Z?b633=;@Quf0ZS34)LY zWzKk$k3w?PxS^TUT(kyVUrVGfeW#kvawbvWqZJ%9p)^V%Tqwxl%X@<^Y^ex*uS`dwmZ1@3u(!WlnXAY8Iqbh%j73qUk@&f zz+MlI8KW*tskZ7SbsMdL7m2q@lN(v1PQe`4s|O4xl{@VRs1TlzGQ|Q0rZtU5j-vnr zMbTiU=!so4NK`^bOv)KcAxBiQWVj*8?}QS~1Y=>cDh3zQ2n$VF{2GI$+!Z+wJVFJQ zbOC6`xKBOG1liWy0p`#ql1K}3j1$@v5oc1Kf45&M2W(6|BsJ-u^GeTCYwcPL1x%ZK z&1><$&kOORe1Z^H!JmOMAP5*v`pBebRwcKvus-}d60POaehRLiV4KTdpPcY5Z?U2U zL6n6P4BW^r7@fwF)XYp`>>KjTY#f7k0|zaNo zCt?$rRuKmiNIo)6Np3_-0kIx*2U@jNiTU~Xf2_U&JTOZE<7taEzsj!_6J?4opgB#O zE2Q}(BVa6851!E@I`WV9ixTtWU+q1LvhxgKxcno^X^%9j^Y4>M0Wht=7Mw$wLYxvB zgK`-(diN_=%CS57Ec3=tfMGw~mcjCZQa+qQw|<5i9@hC!6aO7~nQ;UQ=FY4L?Jgt| z!a8sZ7TZf;^o3VpHEaQ+vKiH?F2Xpf*Jc`Vd&THWS@ONwk%O#Z_NuPTcV9?i`WzRz z2h!21_}R@@G{NA#ZYg(l7Q+PI=(*Y#VVSxieaVe1tr&p(FLrjZe647UI`zcca>^yN zmZ{Q0GJsGj>$6()f?HU4omqE&j87so`Toq%P+>7-hbE?-8r6L3B-^pu-1JV)PhZ@1 zJ{AN@L|OJ{%hnP6q*EH%)0<83XGo~G%i+_dxFCxLb@a_xjjmib@@zicjqbe8boMLK zHDIdgC^5PP)PwhPYPGSupzGJWw|AP1Hy%k@@~>Ef^-IiV=Z6&#gTvlV^gSGMAs)zj zsa1E?=u6=ElCtvnJ`+5nCr}JJE(>j=n$c>LdV;w%-9>0A78|J{IpE$^WsE_boWSUK z#Dz_??VZ6r4ZjO7>z#q~*$D{K*p2raW5DQ1YB>gcS?xu$v$jPjRS>X5AzX?v8kei< zFWfup})R*^yUE*Q5!8 z`@86F4u3pik`j)+C!APpZ}cce1f2@Bs{jU@unc^|!mhnbITg{)c6Nvy&^z!{!%X$@c)0$@Lr6$%E>PFVeOzoAi`&>@n z99Mx)qPfto2piEN(m}Ti(yi&uG-lW`7eG33pZp46YVk-qa8AF2 z)V1aJlb^_xUG{uDD<6qcpk}=1i1!xfN?3|HFSmGUOjA7oLGt@_6O%EM zLqb{EamXFUktp5ZP~FJDogEvmOw^P;>B z(f$ev-WFw1nM2$<+GxLKu_tv(Cd3d9f?<1uO{Ai+nI{7m#A@U#ekL@RjZlaUF!ja^ zZtO$Otsd{*W3H}`!LtC-`jh(Byc4-6`cK^mLK?6OK}b5rpg=lwJW`i9xC?}f(EZ(Q z${cX)=>6&pL%f1@=N~*(48Hp<(llJzkuM-5-*N`*79M9qE+ndPTDmCHK%5l6prO?T z8u3d_&D_<*YIA1dCd-hOi_5@tNkIVIo@y2DaNONxQ>W1pL>PgzVUW1~VW$on3*zf` z^dNlFZ+v}~A+mY>%HAWDq*krf3*NJh8S>Sahskq4$(FqU6pAKV$1ccS(WM!J>A=@%kn3(`E<1&GtxV7{5(h&)$mu(!)+~w5 zj4Y|yTXyT0S=zhPa*RX68$CCkmCFS;3~JQ*rHa${RkrT~PB6569&nn|8yCdE3wVj( zc6H~|nMD0}hq}XgkzrxCFwdng=Y`~Pbt?{R8Cr#Nb$2IrH?_xL*={3*#pJ4&kdLv1 z+6^{GGA*B^Z{SP0;M^JbQO0qgi8HFoeJswmL!1|b?#|^%Lv9B3knumWUR^c~St8Tn zVAL&^sE>J@kMY~@gRiYtx3D(xv(mNlhq`e6Db`=l-pY+@T>T*9JvnyER-WTj)*)f5 z>tJbf$76UqD9%6xuh@HLSmi=itzJ6=&XQ;^>%6@Xq@(tjzcghytScj=#gM4fCEC=+63h%Sd1Vt2Q;EcTXG#0rt@QTt-IrCZ0}| zE**?fmdp!{t5cpC_@wDy?IPNNT|wT~pAL>R`yUI{EzQ;bY`)K4poioa@=v~x*&J9O2Z8rwK`^q zx)`>L35;OzNuPK-$+gY9TyS5^Zf??36e$)Y=|=Ta9s!mR`N?H%OX4S>+nvdNH^Xfl z)6!Gc{JcZA&$)r$iL1@3EW27pu`zY%#YNdfYIv(jcVL%hQ{)bEm}HU6bu|uhWKlN3 zk1gU-hotqQE+9B)!csWZRyXBg*L|3eX0m5&s{hnJ)g&7?Ir;{jUoDxf7uOY*yY;UL zo}FLM0@SNUN{6XDCTS*ZFY0iveB8zt7!UejLe`nL z4?W_>h_-xSmy0{EKnU|JFq4X6g~Jyr2lyq+(xTI2RXyF6D?5et<8?~L@A?CkS?Tg! zOs;YnR3F&~8tv;8(IFSVzgZ<6a^L159PYENqr0fHGAIwzXSy6Pj4W3-n=5$UYVLKY zgzr1A;wJl#V~S13agA0*z9@ltDe@g34U3=2_uYEaAC-=vmF)v!I}}`48JO)%UVGv1 z?>zx8VV$Bpz39X8v`twG>Ktww6vJmX)cmiZluG$KdM3M*9$3HIIC!5CqF}K!vdmvc z3_WEl$GESYkH%inaS9`ZF+lu)@*qa9eS9R<#9aCP%(E_7>0k`KtXVTDI;LnT&Ny{ZaxpZaEX-!e=V#ua4LTOc*~+J{@gwKVOde>{V#6F zf6?audtMjIKe7uH=>IzgkmcX7fd92HfUJMfK>kO1EE7A^-=)WXVE{S)%@G_80Z;rz z3w_yIz93r9w^d{pi9z)vnrXz=v?JxjKz)A1Q;4@%NsBjC)YVH~luKt0+DjpP|HX}K z%H@JinhBYwh7(?ou<9&L-g>-hQ-*Z~zv(?!3{So~po*tIans%Ki_fcaB~dbbFms{N z7-?N_&Wx8WuW;4)D~ft0%QrJUONw*HK|I z{aKv)fI3(?gp?oWwXCusH8O6UB5uTk1`M2h%+-In@uvrdtqPe)WV{?CoWB}+GZ&+& zrEuylN}21SOM1zj23Bw|Xn`rxl+WrI8Ji{IZzNO4`jd=3!gdW@;uKVG-6?Gg`5F?u zc9D(#M?Dr%+AFVg)W_+N?QWCGbNGwiXZ=B4`D#GAK>Pq~qDZVvb~=;z3N6je9$ENB z4mZ!s>B12Xy`{I|hB(xT^~6R1`n`sKpnz7-hb{tysmt#-&b7W>U=NzUBkTuwk~wlY z+;Zna{+90n9?CX0mOIt~6&PZa*#_J5%|F~A;%tz_FLjX)w%fl+m^gRiJmvgoSK%K7 zs|L5j@tHqJw?4(`BM9hnj$byB|;MGBgfZ@g+;l_ zASZXe^MI$in3|w+7(R219oi%mFeW93W=f5@Zx8}@L@GJ+`N;QCBPTzAoiL>P9C~*m zIVj?i3jhimeKeHSi@zzWteP=*4Qt2M$L#}@57Xki1hvdY;rgyuEY!)=CE|^Oe>hPa z%bhNr;nx-Bl*F?H9*!A6Ed*mKZ{+Vv&8*+=ZGgP7mIE;NR*-6F*2_HR+-8GBsVX{KPEI9P0@&)o8cx!meR~{7DUSk8qM*#Q-8ObCl+z0ivI0cDZ!?Vk=Fe}GGszENoR zoFC?sIu};tWgthVrLzX^f0h4`D~3LAswXkWYYb_o7gSd%L7l zesn)X9Dr$i9p)5PP8_k(=E}%?eaK!yU6PN-2Wke@hR|% zah4y>^FJGX*1rg`{}ZGCPy70RH2U}d-y6#M7qQR3+j>rxzo8*bDE|)`z_ zOYDlsA7AU*uU*|FWux~>_lF7QqyL^=3fg5*yAwH@i5zJ2e#E;^Yv@qL_;3&&mkyUD zqo?||RqwOf?`O8P;{*fQ9e=BpuDvONTw4nKV@|!+*#0bOH`&QtiuOF5X5BQzv3QU> z9q^h8XnWT1M8NrtkCej&9D)@Xi3`v{Q2u3K!XHZ>3w$;c+@?Baq)Ufjo4x7O#-R?v zGBO*4jdCl#Q#YkmKD%!FTc|0%yH6q5;0;Kd{&N!q2%=~~yRgLHb0C@&xNFNTHNPxq zHQXN_#0NYJ9`apCW)0w)`oX3#LY`wwlOp%$?C0u$gJ$z`hAg2vv%L)}k}>QK zt53lHAgosRMMqE1EI$R%QSCXobX%08oia6+1wwSje~%7srMd) zb2c=_;E#eobF@JH*nUqJqi| zT}kKC>D@-P0Ec_TekuV*9xtw_&t&cX+cApFNxI$rw;d0xce@|aI4`1BK8A(AsZ ziCphIpPd*A^QmH*_5~qbICb}RaC>CxuAL;ah0p0&U`7r5VE8QnvZr!JS88ePIX(Hf zz0q}OFp}oJO+0TN%F-7dv6t!}+cimE>A{lfrNu2Frb>Os{x1j9Ehu?u5fq(x#IBs`3!n4>#7-+*^->|1}nfC<2>ClTBFVwr|16163*Xv){slTY@ z{xduEf4sQZ|FWi!^)FhAe>YD|3~YaApVYos1B3r4N2_+1BM$34LE7?WVoUHxsl}w~ zJU=*9^E>=E35^vCN(nSd?h}zuNiQ?whcHQr#{K>l3fMmGy~&iiI%DIYkG@y0vuBbB zOld`?OxL`c$GXR$L&YCb94+@CHz@6&69#;oj~gA2BjaHTu~%S+^gQ^aEY(hcGnQO0 zFr#^#RrRF}?~YXiFz-cG{3k<3J=^X$c!d=7Yn(xaNgJi(=Qi2!u?F_X+GsGZR0aI+ zhL~GCx7kbx$UpL+RvFgtoKcWQizpepx*rG)MO)Hirb%LKP?1+wd|c*-Fel}ldOfg7 zL9J%hgQii?A14SZ6<;4Y=$$wpiT?o46?p=U!cXbxyXETgozZs6Dntcy{-VVGw>uK=k1!Re(CQ z7L@p!iX06b#S|AXoF(@s<=r028?YUek}e|kptvAVZDZ72kA6+f!*ksb~n>AnJ+|ylp>Bms=?$5o3kP} z+v@pcSqfQ4{Cd6FGU>XMVPtT9%k6Wh3bVV5c`)wXc&$8z zAvrJxo3qM+1!YnbKegGFfQ!-euzWi|~IW*@0DY{}N^(+)A|r zlWOK9SY?QBC~+~RH~5~N6Rt8CVmoSrtIltVIeCylnqa%bbY^SB2#^;`wZ%3JWC<(Y zrx{ADt!JU#*N25Nru0t%1TsmQq^t3ms*S#6?8gK0#ilC|{*fu&%#q(o>`QWr3d9?L z=7XJPNF_-sVaf0=2h9;Qij`X2u6xVKpCsSb$2)Hv;Q|)LCNiiv>~?1B zZW)}UXKw4pUjl}e7`9;Psnudw3-#QHcDTNHL^xWS*eL&3>`EgY`hI^3I&E5Ex)R7c&K=N@qkzi5o%0OaR+}1{Ie1mg!9H4lW{YM^mIJE6 zYg9hD2yYv$F=Ac$&uwI?QrUT(k+_ zl>`iiATIj#pR`sZcE9H%FLiVg`vADyokM%ACc5n3iv}#nm>;fvadWH>_@kfgq=kP; zmDYB0r6fdP$L!WQy6JR)s+3~Jk%Wah*POzWiXNZ@vc@xYs+o@XM7XYyg3NNqt4 z203Ry+bE|5(WYCBNR5X{FU-C+DKugdN=thP;LFJZ844|lm07vu7hnf0`W=n=3_ETl zDvK=U0>`?vJ`6)<;FG4%^cId1KB^6z$;t)f3UJi1QaDqn7`Ccc=|N_jp;Z&I`vIMA z;(&;NYO_mnTX)7--B?-+JtR87XM|RPbpG*a+Sp8KrY!RFA?hzevrDvl>$Kk@kRQnl zp9@e=pb16T*RMM&ttO+CZMSK0S|}(lGMD$^iv$FYqLXUUTSFGK{}w!bu~vEF0fLXC zjUSq#Y?en(E$~+8iEt6_8!u_L82}P#hKeNMVvmV01g$PQCh4VIZU>%1Y`B51VO1k^K&Qbxh9svPG-jMM^~0Dw2lOpJ6sN{V z^u&+AlLDPuZle?_Z3WrvRLY~wx04^m+vOEY&>(rx2~?@mjG)pE&6Y1`3luYc!On!$xwwH0P%!Qw-FtbBO$BO97swi(6XrkYK+% zB=j{SK0RN!KK1S%cJ4gDymc}^?ARu!L^1Y`_JE2RScjaes6q_zGEq&K1;JZ=3+c}L z_TnZyKCHyw-tJUM-tqlB96L$b^*a)N`i8k_?C9})r}0WHt+wiAJWvg)9`xp;at@;H zC`nZOUhot-WPQ_QT&2BdJy=Blaf`>v*{asKqj}@6sI^bpo-V^)Mr)ewjE)cl&lLEH z+&gV!nbmmSnr@*XFi7#!ZI}<@>Ur3Cq{{B7h`rgq502wIp+I^v=&pV*Z-S6C*m&Wa zBF$maRN!*b6oNp|C1zt-<)t@D&aXb8(ABzQ#~L!RuXjv~u7&mz{}9P3((#yecZUGm z=`=1x1U{Zl{tF>d4snr!;Kl$>kgoJbwm{N-h7~enzI$ps2V3c_%AJ~nEMCD*PNUj= zCe#~J=JL}!YZ-P_CbzQccE^8Qrs_KIa`Ct@*46Gp<4ZXEE|2%@5{!E!cBdZ>SjP}r z3d`xO0j9KZ|028j59b^+eyORP{(OL)IdGB7W;#<^t!qm zd8Vr-gC?4N+zY46JDEZfB8A>&ZClQjaA$jk_1-qr+St9veXwWgM31d zTzNU==V8>wSak5yMzGSRlv$76(#ti(tI^2}!7Sd+4-lrUb^?R2-C|;d^3D7>#}zz)(~2p->Wld2KG(a=PSCha%5vIj~qsty=(DA5yky zTf1XCSa0`yJs{h3Oin&d{ns>++3FFE*qrE;t+XaYYNOk~jTy`4mBi`g-w4qAHisnx ztN_d_{gUjEUnIG!3-Y_!ACRuJkAy4pV@5So44HNg;5#SF=O?1o7l8=gZ%U0C+s;5(Pbt6=B&#YYg?Eya6BTb`%2m&mBT`ySc2XdvH8qA6z*t@-IE|r&|_>?X)&sSgyPpYwEr~BTh+WY-6<(>kb;4 zCy;@Q2FlA5ZQ~Nawb&N8OcxWDrSwNQe`6jpOgwP>6#g}aq_bPAIg_>wOE)UIRUT=o zYs@PBRh#&s!@$`DO*J+=2J}X-ooWJ^e>b=^*j|koSH1*eANx>Eo=q(?v(V<&*!^dJ znQ|uSx!3YXs0{ySiTprV#f1EO3x)7+N7Yj^W&Lvr7MD%ADk{b)GsA}U059eGkch!$ zCg{iHcH*mi!PE((wvt@cbGc3GI5vMP{#6D-lCb7vnAq|bVxp#Dn4gPs_G_V`W(OKE z6H-Q_2aX6`!svW^J`xqBH*9&5k96kf3hfemM3vxeK|1}g6X8pY3u%CsW&5T!GCtdv zc*l|T5Zoa{6aR?AVfa;Hr>-vMv<0&yq=&r%2fS0($Ir_p*&N~L%ZM&uFadh5f3ZRQ zMJM>5Z4mzzi#W0V1z`0bS7w&Kg`27$Tdj#Be@qpbz@jH}*l<~FjN|(Z+4`NyFkxxd zy&5ziY8XoD_X=%q8)T71aVdMsMW35!$px&3Kkc} zU%q}>nRgP(`lAm2%+2#@$e7mN^zlxRmY;|bGmUWl-h0y#&BdF6!*x@94tyLz_u9m^ z*i}BO5B7P|0M28}uZFpd|69bpM0k6 za7+tfim@UDNjpa~3w_SFG|_$!pbN$j*cc8geoviI0bE|F+DwF&M|^5zM&S?4D8u>Q z``ex2Q+J%XKcM*oz_T@1Ln7f@GGQFuO+{fbFahCQSMyK}7Le_OtPWNt5b%3M722D` zuT3*XNBu%#crH7cQ5S91f<`EBio-x%1Zzi{13re~Ks_KkVvP5=$gA^!K=E>*&R1gr z;l5#;^Ka4L=*^J9`j`jMxaZkH_8s+)8|G2q1Z%^A$n0)kR7e(P4I(X0u!i-dgp5?= zgb~zZuoDfLmK3z3IP6RiFf03-Reed^hF?-3e5HszgoZ13r@vniw!wQ~jf*qnp-E$o zrz&-`BoXEdgRVM$S9R&PahaJCbSVOJ_RxNi!@=faiFjIl?fcra-SICZy$ zyVTsdF8@eDTdWIgc?_%7etv`r5){su;L}@)EzdT^9wI*Y#)6^99@}0gy%;S@VyTiq zf+nqCEIAV`?I^Yyin`KzP|-d1E;3wN3Egf!)@ISORVf{04r(Fy41D$d+YCqZOT*JF zph5g+?e@L~ODc}wctp?2Ll@*rH314N*>(I@n%P1pdXqYlc-*@xW(#ozUnO=h+SF31 z{CK`b40@$AQ-GzNDGb(=Q<^bUQtA5Q0{JwPI-n(c4gzGz5iOKm zS^9&p7MH}Y0J>-FV8PZaB~);nWcag@NWBCYIJlyC4HmZi(NOoA3Ebog!FtlA1D)3N z+0HG8p)@Z!Z7aoN@i9}X{N3d2+cZV`{Y~r z#hJ8cngG_a`Z_n5FA^>+_{!rM`C4Pp7(p#(Wf-O5xKoP(ch8E)kHP-%_RGPCBkXD< zayS=RYO`b3Y{XdOedF(p5>2$r4W{6-Q@(X(V3e(eq>=)yme7o8$eAR{8GZ%_2zP5B zW6qxQ(Xi#-+Of6Ni9Y)DMzYIvFbvA6%c~(~y41~pT94&0mfGzm8_nR_sHOvkW(mSs zh&*^Fov?hW#%y}I?$o@{z0-nbVjQ_d6{Fh-?Cb3FZ-Qvq?PHqV>V>))_s6SOf=LiP zGB|y_m$fkZUAqV*bCN!q4x|^?D)Syt+Jq;qrD^sGf`cEhpAsN{ev~6B-GbtU?o0dk z=p?|kps<>mX)YX5P;pC!H4#6_RVL8&XsG0mZCDLeLPzH!0TT&DO{uc|{KQmUGA{Rvd) zRw}KjamF0>uc)*Oo)N8oe3ZkW^1U~*`DYmA3E=7>(aLUsrS zg$@K9hzx_)e@IfouzIBq7L`e`1hrF>0~bP?c@C0iCx0V2KK0?@hS)NF14&iD?cQ{V0xD(AK~3srB=xlkWX}P(nTo$acew; zHy1>?8U{J+F3VQ|_R3HqD)d3)>DSrb-Hfz^H%>dn&3I&+9Y)LV{wpMHyOgM2ov|X! zb7M|9~D9>$K*_0FT&?%vVt+R@zH($bol5gaQ**SH00TQy9KR$Ebb zuQC5slEw^&bO~fFQ;0p8NwvP|Xmb8Y8T^wb`y0W`hyfF5vN0slh_HkM2zL1QbTc(h zRI%mAQHth$b-Far^+)e+K8Be4%HBpTAF*9=@-zp!)9PZ$%)WsNlT{1axrq&$$Kh1? z@t8&`(b9V|<&+;%%8U>IlW`tp&wKgxNCD1%23C9*VaQkDB#2x@5#=Ac+%&18fL?Nr zz{_U$Fv%g8)qrh|n>#CV1Jv&r1V89DbUM14+tdAeANoCbFXZ_A^_=>zP^0XKQsQIa z`nEXOiu)J{VbwY}0Ird=0%Otw5_8xzy7Q40uInZKK~A7Q)&GR$n>$XyWDeh2Ot~Bi zvw95)-=|pgLgA%BR1Yz9_x|?jVWwgQRm~_xT#nThBSHak;xf8v8OuJV9s!-7i$OU7 zp&qOMZ_K?@kZx_erJ1&E+qP|ErES}`ZD+2uZQHhOugsOs%KEFTVn^@4`|H@zQBkM! zjW_0VHpg?1G45*%$(X3Gy;^F~Sl*<7VnBEjkm^?uiMFhG60IG_M*Nh&MvAnxytKBW zKY1>&hH?gUs6Lyadtwo2PggluRL90j2A6ZigN~qB4t30-PdW_K*poX4(Tzuah;~}_ zk`XU)5MnEC)2ZVI^YO>UDZ6RtnsSvhr8pMmvHa!w?d0t?nKWC2N1tWOQ+p&L8UiG%!j2d;MR&5#z8Wb(t`+=r- z$&_9gc9>|sa6VL00C+Oga0_@)7e?VK^3=&uUx6i=DX`X+)UqS0u7tOr!pxTfva>lP zbyKWZG1K>M<5Gc+>&3Z%SL2T5o4Dt}lQ_1scea^NGK|V?T0z)J(eZbE4i(iwggdyJ zUWz62OCHf40NRGBwA`NRT0ZcHeo(`gNjpP~+e?`dtHGM1Z4Fo!$oBDi>SsjauDT5UNuP9_K` z2?}LWGH&bQ_d(tUD2dc>W9WwMsio0$g8E%L*Ir%b$FXU-N*8jn-Qb}Q>o%VRXb zi%uL30_3*vm!-%0Nwu;`Zt1OCpggcO7nEGIjkftjOs#TI^xSF2#j{XrxgCKDRmw4!SF>ie$BDvnIa1>^~#eeqtz$Qx1I_(!Ymg zLh3?C=18PKvXM&pEXaCCs$>jY6^goBg_dkNXeK)6qc*VC!oVhgH+V%-0~HdNB3om> zf{Ee)ULT&0cU+}W!4%erv5LILG?UpC)t(fR$u|h+Q>Ki4!Y+Vt*xD1@1)9@kKqaR3 zcs#SR`=*s*#R^d*H?725S4vv6YuTYT&jx?}=D_)ISx&d>_GZ zy(7pLt#fh@JjnL&Ryw~74(HeeDlWM)@3%jgsC{B1g88Lw(lNqL2vKu>(@{ow=o)fVV5vY8;Ea)iYe=ovV&cv zqJ0eAg0khz!-=lBu_oIIA_xns(X;Z;79L}EL9K#7B9LtR-9dz3%3k@(D36w)+RMjQ(?n2(A|{ZvC)=zD7eUQwjLZMU}$WC68XipY00 z>NeO*UA{2(Lr;~xgDt!92Rsydsc%?Z<$&l`Zo9qe-WLxeI-Oh>oa`zT`f^BRZ-`f?GAf$?lRYEK6aXKP#yl_#5-=$kj0E-Ea}*2~EBw z!r7NiC{X%CfN+i^g+FVM2F2dS%jY?Yth7dQLu#QWtZGR_8Wf|w{ zA=W=)kcU~}sn>DNvCW*MNcO3hEwaiPEq=aux$v>|bPR`#?ZEmIm=_uW{9u=MD`Mzyqym_N7}B)#6ZR**4QKrr3n zF513mdc-BtHMh;4qD>z&dzdL?UF<(!kUQFvPcpX_Y>KS=lt>foxRY~mh(YW$Kb2@~ zr5U4iuYV3G-!=KHk?``&$s7P)c7fQzpM zyjn;r{VWFJ%Y{q$?JTH;>2T*@*-^u&aLru`U=U~Wr* zxD2SA$}<|cm%}ghNAN-B6(d9;lWbyZ3Z+KMLTOQDdJnz_Ept*ovT1@sfuNn8ZhJSbafoYtDJ;h$@Z~~W5xN&C6M`Yz!<>*vsr4Cmkmnm2o6u?QjWWje@|Qc%Z(+retV_MQH$4?MJueP0%q>d-@wWgzl`x0Crsjh&QbnM1_m-?YDP> z0ZPH7LK!=*hHjW_z%Fk!PRY)mrhR8<00&&OtCj1NMc$C)N7GeFY$enUu;~Z{^;- zL&I@&6)(a!&=yP4a3-9w*lhO;>?w*wqk{p6Qs;c3e=gnZK-t4-fVY zpG{-V3tPHA9vDL`g#%BB^L>`DHucL=Wfr@$bK(Zh;UJ)i^htXQQgkY4eRG-e&I>gc zEaz!wD62A+?u+p=@JBE`Mb3LocB-=zk^4;d?*l^Mf$GJ*VEp9H0%bftkwe&L&>V(X zz~Lz!_V2Klrv_z#^YT&}Gc~1fkq?U3B=*k$sio)Sb2$KP94w!NH61PLu>(^Siqnk1 z`tOa_rnNyZ#uKm>f5I}Lpd=Fo3-qA4#V}RXwQ-5Y|f=Nu}`-Al;8Fi zKfO*TFy^p$j*(@G;2>T~jH#1cFv4ar0Glb@DRYLljVN3!O!cC^=*nh&1uI3tMNP4I zG+1l;&?T0dXT!J-TRTN4u$J~x2Z?IL5k%`3_>-RlMAe(=2l<~D{+tV5>tE*rQkG*W zlm=eygX3*7q50RjEO3;pf*nA(_04O;a5-4?!CLSa+y2HNd9Fz<&HeN#e-Goi?iF^d zTr_SpDs5aoYVh*}vI$)>M?1u=fNO!##F09h=s@!RBDEAy8viim3Taw*!OykDs7mN}8af0k&1rfCj5YL#3!@h4^_&$DnGgv#>RPg3 zwCdIZLCFe4!N8Rwtob}~^jo+)AoFb+6NMdIYTg?%1nv@{P8r4#A_a!VCX|Lh-^<;_)cxi#3wM$ukO*RzOta@Ow#mbUMC4bTImVl?j97$ypDZ7x$@2cCO zKxbt#?HeUqt^DW5outzu2yFv?cx2g{*>8sqy_n&8<4VC=%T!5^#krLGIrI*kffJC0 zgDh3e?MSrKtpMOnQKju;jR#cD*ZYq<1`tFQo?dw2&U6SslH@^aTAWxKcGZ<*mt`S= z8<265CQuDF7s&nbN-f7v=JAC>b4gu`zSXA&FKU2>KFYGv4Z7=xDWzSc$m`0JHJ8e9n=9WRqir1i zmDVN1b+6FoCR?qfkuX85vz~6NEn29n9%UTP?dHSIC4RTpcC^_cFaOi&%rP4fr zF|Q2OY}Gwlh?o*qFNtOsu=NQbf+`TFoSs9BMuEVB1&Xl&`hU~BvP5zP$M#NXuq`qF4NSeTy$R_JZ5mSZl2q^=4M9zwY$s$y4 z6%WdZ2zGRFN!Q5jOj&3{BE#xpj77kBK8wH|5}b&zV8nD=ad9LZb;6UY zlczl{F1EhEF2}V0ne$Cby9EylJ0*+bxd8XEr5j?}M!^lBI|6VMr8{XhIS^zVy9Nsf z+n`&_)bF^FanVtGRO3rz{o6MMS`&S!J#*9_6>?~whJQe`HA~$Y?$}uofQoMFQ^Du& z?1_7UR-?0=Wf%~Hy`#-;NSO(?V%wc6)%HA$>s+!Sn5D+MHpU9eJ}>W4)D6~B-z(b) z12%ngj$gz9_uXN6XyP(IT{1u!J$?#-?*ZpB$QM%~>j8{Q^KxRQNUP7cYL##-eKy1I z&EW^V3?5qUoG@XDp;^<2{bH6y&!rkz@;LjbkB_@)^!KdZKHxe+j9^TW3?-$B-HP%oL4!0(}e+sn>C9vExgIug3wf0 z>lB2F6Qun)J%7{mWTf)~Zu*Ho+Lq&w|$2N`lJC5KVRt1AQQe zre%5vnWpIJivqDisPRq7+Cca8q8jXfeX2?iQA6FC-osJEEdsJ(GwvmwX-QXw5T6?b zo|P%zGzxT#SD zFlcYSkJkzTLC=-XG0SYvai^pjs`=9AvB6b%eQSKfv+O00{DHvU1IK|%gZbR+S(L}p=_4=nEgTCkS?ub1`oUB{OgJ54ffyAv6o+ca;lp*V*W&B$ z@bm*M-hXh^#_y>bbtcXOi(CJ5aRh`__2)U<$(J4CPLvso>--H5b=&vrM83Kye45SJ zqI4z{Fr#f4M`itO?5uz?C0thJ)#7NHN(Wdl*v8E;ka<39 zXS!L;rWm}rwGJM}TZ*bD>@^0HLN)qUnHmu8_A&Gm(8;|auW5iM;-F0f>+{e%rZx~> zD{8FWz7G3{8yzYm^NtYh#M>pkkgJ{bnCxT}U0+o#^wovGb)2!mThHxjkop&n_6-Fc(eYF7BT!4aR0f69ue+ zgdGIQOA3H@Kb?3yRW&b<`OztpG*pfE2Pmsu#n@0!U~UuWJ$0kMIQ!XiDd-7_HYM}q zXq{3uoPv0?Uay9bwXs!ywCe`t$NrF3q0g7KY9{&c7Q*s;c$&ZNB8&lBs7J=vW8}NaV+`T|_MVi`v|fCV z2!cA9ly9M_2FF!s)_v*`Y=L?JaXdr2E2eOTsKb>g;FoX#gOP3aHIiA1x$BEnr0Fh$FyG8Cl4D3Ute2Mz_nG!t-<$**5f@nz(U(?8RvGI;hbRh zFlWLHPtV#nxicX24l2dD7$Ti!nu_o2qH{ix7o~!_@3La>RBX)=g$p&z7iN-l(%V@Y zzSDIScO7`@I)8jbJ)hm}m$l%Y*Ls~(1?>r;kerex{~&oOUH1d5hLp|zH#f9@&h!84 zGW5UahW1~Y_x|UsKO-j#!~c8jv{_@@akB-f=Tv!*h*_4KPRjqg+X?41TK-6HwORd3J3&JA(FzZ+Ro-aH4{U+UAh zo!7zFgSMroLVq5v><{d(uXO{uc9*aBG-W2BNZKV9R$?=!Vem07p)7Oju zHY}`ewehT!kV{k?Ca64w+l*PzKP zw2Y||3uiybl}DT~>w(93A+DK*CT2gxXcl%y?ZEJCQ+Mr*ZEvl_7a}2EbnZ$cgmYbsHd_ zp|;|O-(QCSZuBSR7si3&*^mXUZ4Q^z6<`Zh6hlmFk^R_%;z3CP_JIwBU^{zNYnCsD zRlOoVI2suYo-!lvguw?G9IXynOp%A}#z`sV(W9>yUkn(36T?6^z&Va#?NI+lYd>=9 zsQswe@oIPkTNF!mf9xRO{AgKL=uEh)wVJPu`fck62AUTU*bWf)tsGSb-U&k_aZ(Ex zq#NW{9|8dJCjD)`O@4?MhTsv`6b9iGBuO|hR=?+YmuYf5{w@EZj2jjZzCBd%ofDy8 z_;11?ZuEmN$6mi1UwE0aAdpj`UjjyCg!}CX=tN~WQDg|W0D*&fd3*U0?{+)iuH6#! z{Jt{iX|3m3lbx4~V3;DvaK`2Y9->+`|TU&@6`mC9TXR% zT^sRqUKAh}txrbML*EUK>fxzNR!T?9yM=_;%C8FOv};pb4O3JNNS9qmv&>*czhb3| z6a&>7O2YioR8Wsio>`xx1O(=jKo zo3tR->e7D6*!8h_JzdDIL^f7|JK`mA(V?Ga;1XJRIz8RIT~GULgu`khdfc^4X41*d zHrz1l?0>nqxa2+|CYDrIP0loi%|_BBM5Px#X6eWs8n;cv{8}MZ2~7EwU=1FTPTLy4 z{@eGAK>aS#EWVV~d)1L#QSaFU7=f7_LKpsn`i%0Sn1+_b?s!3g(U8 z5IBp3%!|xid=kZP85=r6sN28d2Mg|pPePCE^uxo1^8Mr76_=i~IJ*+?SccuDN8DkAbKJ1B&fLxv^JCBrlf5K=XWRP~-Z9-f*3nH4>7-HZ z3(yiru0=H7^eq@C^#kc8V6$1`I8_k$PQ6ugZ|8@USd&uI!46M?Sa=o~c*S&PLAv$2q;J2R zTwHwI*quNJAWkzO|9IBF)Jg36N!ZoeohrL#zw)c_l0J&YlOnoQgNI^bd4R|pulQmD zjVW3WG3iyKF*F%(hp@k@E3R|$I^knRPwP+Bc`zbF%vc;`_}if-KhhyeBVA~~WjjU0 zid%S3z12_}_68x!d<+JG;IT94gzUUDG$0GW-ytiD&aRzP;zK;#-;3!4pf^nZlIWgO zVNll=g15^8jQ<28m%k#UzrupSD;6@f)M9smR7B!N(w&0u^F`U8v;*|UU4VrC6h#}U2wKQnW@vuLga~IledI|)WUoE9!sh{O=uz7@CGWw(J@f*B<|A3#T z+&N_4Zav^5u`;ep-$JGJ#wO-`XQkt!^}TR#9Erv(W-R*TgTVf@XQNfWt}KASS;RR` zNF~V@Rvl!Jj}TeSB@cXhupVZhT2s zYeDPX&l~X*x`LHUkzU5jxo{_aqk}B;=$+|<{{(;L8!$Mhzxm%tlYfrdv;FUj+W(iN z$-fERv$6eyH2GPLY`gWZ)yOh>3mo<)N^S*rgIqf(wujnXj!;c>Ak{_90l#NQ;8@>UI^3H~_rUX9p+8U8PVSL;A z`u8D$Vwi_E;X8ixCmbQ6PX6m4g}xw%XF(A34wSI)U7FCf77_5CO-kux@GA}M&?wzl zkj=hRS}UN^exkpW|B6k)|svcrT6?CMFhp8T(K1i-FVrnPJDrAzvtK-qYG&WcJ& zNWBsAqRVE>hg2Krk=k6o@@O8AhlqG#ii2K_mJUx%-fpfou5^HY2GQ`~r6Mzbr2spO z-^Z@wj$>+fvBiq1gNCC6?x#kYFpXTMOA$q9} zM`0QnjvQc4K(?~V7ExJt2SP7=5rh7t8j*+}zeYHz?S0dWDWQ)S0m%DfkMC^<9|$sx z0ZA(gTxfrRcLIJ$71EDOAZqlR_4oaOmWN}nv7$*Gr<*V3ZT~WY#uxK+o?%BRZV#*W*fpcgR%6^;&~^( z^Za^KdSuM*%6{*i;<4L5?1kRV%6W-u&K)uMeaW0tkV4?g9;V_=>rFi7mQEV z&r}tvUr0=pP4w`$yJgWY*V#bcf*b4x&@ym%t)A+B^zPyyq_@rc%e&{7Hf}WZ{GU*< zyis!H4Fuph^4s{DO07STso7pRFq{5i*fhO~52XlTlE26VRfEYn z1IFYSG~KdG?)%%8J8W1{01aAJXJ7E6czF?oCt+!zv)p53l{hF;=n$GaY626=kPj

BDFr^J>ikY=5W1=}yphQv4L67Y3uGpN0%$RN4XT8? z#?(HN$CYq@C%CiJAj{`^N)NTrv7`VmqhGWkOxu_PzvI&nN=?;^jPZFubdn(S=|>3h zUomY70KI7m@g}OK-%7!KcC~Y*@3C33PhFUwX7Nz3VlScBo3xLdM15L@K#-*iSB08T zm2*KPo}MDN{m!r*jCG*0a0hDm z3u?@jlz4T*NHp$^v09@Ai~S~or56FN+MR}wn_qPH5y-aI++ei@8wJ<@fOAiyfsqXA ziA;zjadj0!T-7$Q_RXPF^rZ9E=IW|j{ zMw7Oi>xE|q-V%%II_cah?#2CMUPm^2^gVBSJsT)Deu@r-XO$2BOT1*cQH3^-zB6maOgLGNq1-QF*-t*tSt@IDHSpc_ZCQG>K$b(pcbX`4 zJi5uiLp0aDMa@|^cgPUb0iu>R_-ntL+dCMgqUzhb3J1qiIXiocRV|;}Z7XU4b;=35 zm8f}K3t^K7ASbH6o}nFc_}hX@W=Tb%PLBXt^t6Moj1DIH6GL(Ofn9DA?;<3km0r~^ zP}R6QnSb*M{^v3S+y9AW2DX1wW?=tE|5n2$X|o0K2X7r9Uwxfx5O~`m$92@y^kVtdxIPQMcN!lI--Z@K$b~#&wo|GWI5I@gC zn&j=wiuuX$#`92yPJ*Zr=lwwM{=FIQaWs9FrpKEYH;_!C7`Urm^s~}*HLET1_x;x;BJzCqur*>7RfC$kP9SHxVN@|xG)8LjA*0!{+u zh2?&p>H~-^T3eIz4{&B7%x*{T-`xV-xRRkS(4o<3CairgvC#-7(f*`vh?QKJKW;l# zjDLi&NV)Tqf9M2!WwAcJoq|QT1J%!aaMyl=V*rm9*j^ZJJWTq+17+}bKD%pRwDfh3 z7RLw}mjzY)yNK_#KWIy{v_?2ex3i8()0ipZ7ja_gepe)OV=crpFrX;GI}41&p(4OW zA-2d-maE-iN?E1KX4F0+Z}TAp9h+t%toofoq=p0?*z)BI4*ZOg0PvHkjkRiFvpKavFfDE+d zemhSfcNexp4E6aHqt9z8a?M&~0?J~Ji`93kXpDp9Pr1u939(Y}oD=Y~?IoBFHqcyV z9nC4(umgj+ZoO=@Dg>_)4VIz$=Ra#kU=~|OvAkG+)0^jv*ls-)4#V3Zbf#c9kYc>% zV2rS_<|y0~GzKBinh;r;e%@j-UufDVAtPIaS{clSmZGn?=>`_IfTfSq2PceW_u4O1 zmfxa~-&bW7JvX>g7*O&9O`v(M6CU%^qWFcOocDy5GB?O}3jEOnrC7?JhiO z#FQZ{D%QeW$OMLgmL$pQxrF+S9K6a&NkYlRL_g6`W~VTbX{iB4IWY|yY2_|_VJd4$ z=tzX^t~VQ%r3!uV`{+8xoPN*elLg(Whl;dZWVs1@K&wAOlN8+}!J)jl|DaSnj=a|( ztk56qT_7OMo`pl-tT=tgp0cyNj1x+Fb>K@)17!|j4aM-gh{oGfCNgs@ga9+_6Cj>0 zuaMN{4%u6vH`hO<1I%Nx(w2&z9#D-t#hY!o8w(l_HmLqKX**BBG1)=jY~EZSrvcXx z(_jg8M;sTLXJP3WEWfwwOLF*vcQz_ig}VKK6j86iaT!%sHnVsLpO)iG?g%Z2)^WE) zm?yS;XWE#s2hXkimXrmPo61#{Kz=*Ep*#S>cw9>|v)%Dem?@oJL?;pQ(d(1d0&6gR z8YvUt5|`4w7Rgoxa@icRY|@mzK@jg%7)au>5nKuScY9`!_urH0&elb@)ui+H(^}o$ ztiZ<-JKs!gpRO>Yg>=tM&y8{r$t2cxfG#ds3cx(vKZ3MO^Da0_0DK|Slb~Ha$klMm zxpsS`Vj9J`ZD3;%x$)2sZ=@i9Y7{gB=DG2RKyrtEi6FRtesP;qam}L@b`o5QCeY%< zSHE;oY0h6KS&$uRLgf6wd$5_{NsSG9EFHe5m71tx{}@Ea{kR`Svi)&=xmRiefcvby zh$&^qyhLaqEE2S7397W5#tAg;;99|-sqZ;6#?2*k?A>n>4v$2k1sMgp4alv`WjLy>-{3n4QjAu{J;epTf}| z4;g*liy>Yvw3)weN4d7pb1#r>y%sx@Y^IPkNBC>3(-LESWJ=j`6dcn8Z0Nn{{^Fi+6?ni-UOca!IV=S->!UIdL9#>w;2pU} z1i{qs+ZK}%CbmZjc=S+0IdyP7O8n&SY;CDJzx>{r_xtn3@zKTdaUC+3@yKKSvU-Gd zP%+Q*-=vEDU!P~HZbkB6f~g&>ok{ZFkl%CIJt6^I_&N15g>(v*8Ac#DcQ^E*HfHIo z=zJz$>&U}FgIDK8^0_?RHms2jP$gA2`PaS<@n2AKT&vsmtPnBdn17C1)sFjH&vxC8 z!te&6vw0t~SlvsJm4wi8@(u+nMs!b`YiLxN>BUbk!}6YZ0cHhrO$;fyeeT#z)~gr` zZr$4hpTjRt?+|862sb7VS3$S4xT3I-h%y+P%q=$vf!`0FVLvQG5h}vW!EQj)jx6?$ z=_?jJ6^-Ai=N<*=d8)&{V3jVcx>p~&ZvDddt^s}(~ zIPouuk3DkH&p;?1>WUv+Rd;2j7db-Z~uHa1O{QC|Blk{Exk`d3CoBD8u`>0_^S>L6bI*AiJFY4Tk{IW z%}YZ%W`9dk{YlagMuwBI_I`5V+z+C%I*eoMAg{{T?f!jrvHafK-w)?@qjY~)@bQ;e zOrv4cZ{9@sD~ijC{Y0wDaV1#0rBbFw(; zLzz~{m%c%$6r_1d)G532MGraXmQe&erzg*XCdOh6jE|)pOfkoh<6VXui7jtl1zk#F zPE~6R7H#+jXq5j`b}7SmPgau@aOI+>IW)Ihoqjln;y&J1)7hxqgCGqP1z^#SLtBmI zh9>TPIE~}vC+6jHs+=a+U)Md}p?Ji)vJAXUSQ#@O8=xH1h35vbbJonp%I@pV_a-qN6(zGDB0yEc(DgtH5XKx zI)%jx6JX^;=9rWI&MUP8fiq!XH&5GwJZ#r0Me|@ETtio*paMUr4E)%U6nI+kC-orI zEDKKuycw|1N+`?H|2Su7^ROW78#-2>z$dl(Y=)G;h;arD2bkNp^?8nSxC?*ui*NM% zy^e9}Vm-ow^ae?8l%$1jc6lTI+B4Q^x)bibyi&783tpIsE)!?co?I#%3NF$VHrp@0 zox2}k2t3H$lW*{6d>?ZOy1{mC^$l!Hmff(MM?GhTs<7)qA00ERzd@^|>sGN=CMjI> zx{o5nOyH~UAgu}>+Q;8^oQA?deF+?VrqXraUCi8cfA{i!x@y_=awGWd#wjBULCTYRpQ%N%@;k_k@0k^hyz2o$%ZlLp&ri z{b513+5o4m^Og5wgothyC<*t@&Ww1UEN?bP3Zu|Ij{Js4;4fd7V=iNHMSh=~go}uA z5@%r?zKjnZ5*oy(VzC@99N}G$Ytfl;zIdp_X?uAWix59ddIt8rR7p}cv|ecUy*=TY zFuQIBsKF zvK%_cn?|etkWAQKc8IYUTmE71p-u?tLDW)U%lP9z+;g7=-8638e>-r!;Ws1!?$jGY z8;y;(E=V@()?_1!N6T((ST7xv%8PBt{I+Inh$HZRU1QbmkaYPX6FCN) zd{WkHhfHExEzYFOe=wFDAifmyiSmMBTDE|>HG`AUgJPw(1)yli3V!lH5a$#CG}EmF zg$Bk=P5Cqf0<=OH!6H`u4PAY|RD`$|8qe*pQkO3DWscvTs7DnebRq`CdqcA&?_ZBrmqRIte181KPY6fcxFL9P- z|LC8S0Le~^F{P=})|3iXPQ#WS5Ihx(4ORd1l%?#69ah@Xg<*q*!&2i@4GV`|5Z4TFvw}bheX-R@g~>l_4t z=N=^9R$8lH5gtU<{Q3b|SJ-e6=0IpV(;{!D{Gs$_nqkxoCH?e0!B&jrTx`lqQ{eXAmM+cQu;-u0DAWeY=sr!{zwLLxz(HSPU8BG$_TICe^ zSI+&Lp1oF~q3Wj%V@5>;e!7s<`;8?E5i z^7cFaXV5;vYw3>F3EM!bEraIMw2-1qKWx`hzk#RslO9kG={kqTMlVXa}xE5(rtGb1q8W z(B0KgdzhQ4`5&_>0b>aYBh!rHY_x*c1sbclS7Qr0QJ6ZQ9~Wb}6owbW*0-isE^v(NRJ_!HPcA&@`&Q=EnKUVy#HwEjE(K}! zROkRM44*KY38y5q^L0JOIKxQ0YZ=&|Gp#mMC8#*H0%rA^2&AsP5bbpvwR% zqoNecDTE1VD!A4N2N{rb6tB9gBLZ2n{{E z2d!3r(_NpSPzDUcWB^AqMQAohYiaX6dzKUbL>=7Q89%JC5QMwVx$Bwe07PYFbuI{{ zRrr7Z4kV24WSmm+DtKv?RH;l1+Q?ht%G#@4x}BV%;%LjvLuneraf~S*@O)?2I2L z`28q+Ej`&Se^>9>>2K)l=w*=2eyMAFtM-mjtaz1MQkpm-wU73yhE5WnzL#pgTN!8$ zWH~1N$aux?drIT&U?MJ!ejc;54O(?{yB}fSo2Lz5htI)s;f~Wi@wS`adN4{-=g!=J*E;L$k(a?9v!!&tK&wRS2 z`0zCDWHevC^OQ7m@oB-8p5KgRjpA`Tj%PH^_-I&|GQU-_L;<6%_cUzK@ZyESK!bk^ z+am3Q|HWw>t76#yszV>)iG)qjkcj0dO9T8{S6VJ)3l1#aK1M?vMe$xvr&r| z5+UDm9acQ*BVUP2Mi=KzD?%T=;aRS-sA5XUiPbzvvKKoEquOU=wnu?3X46>u6t9Ae z%Z%I6+aC8hlDpS;-UX;Q3eFZFwsaq$S$4e&9aN@EwZxL5fglWAb_ks5k6GxCv&E1M z4P3VVgF~vQ56zG>=t*m%%lZ!HEc=;(0kyEfuUQ5ukTBz(0P~;$Mo<`3c0V1}rd6VP z(PwJS*SQf*>v>y8$}u=lPt^Fll3sU|wB6j3R8Gi!EYyo#Rca;pd33yGOiTdeC5K6$ zN-`yY_vu)0Nov`I5PI)*A#*cP!Le-n(5|uBtT!VRBhIqPHk)m$)zt&0eR~gL8rR*_ z7}~7<(O6|K9B%(%8)sa<;rzCU*xjU~W$v$lrRJ(mXw;8HCf$M?{aMsPyMrhQF`AX` z*o}ONEwE7ox!N4+yzK*;DmMkJ#{^77xf%7z3PWGXZIsspiykpOnjofH%z@#+)3=~n zHMS2pe4-o3)7C#ZO6ywaPu`zSp0V{;ln>(-pm-`lC8CrgV$;?~9IyRGw};0=o;*3+ zr~)0_73-8)(Y1WlUhK%|w9?H2485c0`=N~!4@%g%MKpgu;5vVqli~zlulG>O9=s&@ zQnE;H0GkW}DR-_Upw%0-i>ecM&4;u{PQ-w*@Egs48$^Dl@=O$2HM@9WA>T%4G6X)+sRVaa%Lri}aF=>Yos<9`C{zG3bYuO@NGpYs*IOnG!v~YBAaB+%gAnbI9(fh zi_WG`=K{8tLPYGKz7mAaY#alPV*r~}ArB?Q@X~P~V*bn%`se+@EcFVpzVypNmCPa- zoY=C-_>U6jwuOt9d?cmh#OkWVNvQXRPSTLD%%KgN<-t8G2Fl7WQ)+|M3Ot^peHNN- zVe0uvIn*}7$P2M8G}Yakn;5_Ft+oMnSD1n%g_{gFm^7c(>db@QBWoEKIDWNv-h8WG zBJ21$Bvo3zfl^S$Tw+2gq6l;b;$y{+XKk`>-TIE?=r$`Ttbx;8n=~?O%Soe2 zG5AAEjY_3JVm%}AlFx>`nDZbm7qz72`v)8-KH~x>A1WQHkURg8UTP1sij`TIjoo6&KNhb zP9iExCGjS_DGrC6Wz{F<;@|-~w%&LW#BTib!n(+d)`voUxd?j&g`Mayjys=4e{6Yru1vk`w zin(~{0q5~)bk7^ z?;G>`zJT$l$jDC{4FnwaB+z(34=p%2`$mhdJ1UQsA>Nk(^_LA>a_dY=acmypWLz6_ zBC7CGqbIG;x3-4!3yh?0-)FmOUlETM+)OSZ7_iOnVU(;&^3(cU<6H~poYX+dsTHNK zR_~2edbcBs=Y#dG9kU7&W~%e!vTo(Kxpv9o-j@c7IpJ%_n7(~@B#DGl@LVgx4tB(J>;DXE~d`G?|!TX?h&Z<^nq)gj)$xH0|9W zGl_Nu_n@@=JDt2Q7GJ|hn@8qR9rr7l8uxj>H@upj$(I4j`!4frefp&BeRRMDDapnQtpr_sL4}Z?cY8l`gw18QU;=Z7JN$V44RjUL1#{rRz9S z;q^ufwd(WZ2<54*r##%BqoODxNRi2X3HU;=j>{~a$(v8R)RXeQVW-}1#C(b_hUr7k zi$$Kn_*{a49}){dlbp=UW(~b=*$ETlztzjwEA1eB#X?eE00g%+ z@$gy!0m8tOU>P@$psULcijgzAR3wh)ipJXkoR{!(WgApeS!jK`Q=Z=p*&r{&x_D%L zak^4GnwC_2sg=(+XP4(!k7pqtM`>z#>E=)~&vlG8^Ls`{LI1#Wt zy8Wd_M`{D%k4E;D>1M-sIi-Wa=~Q}{cY5V@(UEcxf)eEKq3jA`NPug_8Nn4H&be?U z9{Sd2I8l^cdE+#b2;P}Wtd6kVTY>7#q&jTVV&Q3QCHewxmT&vzcwB5p^)tYoaKFDM z%A@5<1Z5K?DQ`Y4%%u*wyLl^B=76>REO9QE+UqcBCDwuAcV+_| zLe>*uqe~TyTuuvc!|LlP(>e-~YkFI1=vbDfyzB`4b$sTf7Un7vm}F+)37J@va~eJ4 z+XkQa!UVDY`mhNJpQCM>(0%;Q7|bSYaVo4Lll-nkjn+ z1HEnuKXYA6lNuRLIV$HmicUpn#wp(L+=#DO^HP+$bfMXJab=8xndZWq8k)TlySE13 zkItNtWMjc|-ywn*?LOHqqDW7fr)ox_M!jhCRZu~7iw3=dH+Ca4u3A6nGRf@h`mTs6 z&>}U&&}m|?*ON|9s(FF#ziP({a-_!)z3ijf-n{IK2hp40o|fus2E7PN*7#%1!nkCY zyt2ofV3dytwe z7^xJ}k_XAT3d&)Sq2na!Q`aNa)(zX(NKN|@bB#5`pMBeGpvKz`O44$&Gn+Jc7JsJU z#GWX^lh&Ab?utBeb)VzPkuGA%J&wGA*Xwj1PrBzqEePCO{n6rDw#059k*( z2kF>%+FS^=ZCoT1y9`@qNX}^cl^~lCdEn7Ux?HU@m^d1y#ggAES2d|IeuT9G!Ph|m z-;>4R;)phayX>S~(1!#T!ah z3}`uDyTWRNx(U!_Byx0fp-$-u%728;t{+(c$ znzd~v8^Y&Q^-VEFsR9~Zja_keQjzC!X4NILWcrpfcDC;v40h)n zkJrMiLcJDKEvdnWM13VB3+sLZc01}4HM&M;Y=&~UOQCVP|A4A{WiQS&KZ!jSJf~4) zTiWUlPc7A+!7!?u!~B+zschchPp{M!4w3{)ddw<^%qGKmf|ax$^d%Qw+a*XW?Dmom zz@g{Ub@aAIXU931boS?53gmb_Jon|UhGoTsM_Xp+ab=bBe!m3w)0o;%6kA&4cH3O-UNg~Uu z$vb($o!@Cz-2M$Z@9JY`|07f9m3CVz^NSmnrpT7InDMKaUu>N*$pRtrSX3C`4)z4r z_YV5KZyEnM8GVm{s$V%+lYTy@K-WUUe!>E(EQ$;)ebn@YX zIc%x?6H;iiE>q3|l1A|@9@3#Dj}tQ~vR

#P*WNgkM;8`$M3XR;bZ=KmC9kpLZi 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 diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_release-notes.pdf b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_release-notes.pdf deleted file mode 100644 index 0cff6f8c314cead8d5a26b10d50b81c07cfc5d70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35595 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 diff --git a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_softdevice.hex b/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_softdevice.hex deleted file mode 100644 index 65bb381042a31..0000000000000 --- a/ports/nrf/bluetooth/s132_nrf52_5.0.0/s132_nrf52_5.0.0_softdevice.hex +++ /dev/null @@ -1,8678 +0,0 @@ -:020000040000FA -:1000000000040020E90800007D050000C908000088 -:1000100087050000910500009B050000000000001E -:100020000000000000000000000000000D090000BA -:10003000A505000000000000AF050000B9050000A4 -:10004000C3050000CD050000D7050000E105000054 -:10005000EB050000F5050000FF05000009060000A3 -:10006000130600001D0600002706000031060000F0 -:100070003B060000450600004F0600005906000040 -:10008000630600006D060000770600008106000090 -:100090008B060000950600009F060000A9060000E0 -:1000A000B3060000BD060000C7060000D106000030 -:1000B000DB060000E5060000EF060000F906000080 -:1000C000030700000D0700001707000021070000CC -:1000D0002B070000350700003F070000490700001C -:1000E000530700005D07000067070000710700006C -:1000F0007B070000850700008F07000099070000BC -:10010000A30700001FB500F003F88DE80F001FBD26 -:1001100000F0E0BB1FB56FF00100009040100390AD -:10012000029001904FF010208069000B420900F00E -:100130001F045DF822300120A04083434DF8223097 -:10014000684600F045F91FBDF0B54FF6FF734FF458 -:10015000B4751A466E1E11E0A94201D3344600E080 -:100160000C46091B30F8027B641E3B441A44F9D14B -:100170009CB204EB134394B204EB12420029EBD17E -:1001800098B200EB134002EB124140EA0140F0BD8F -:10019000DE4992B00446D1E90001CDE91001FF2209 -:1001A0004021684600F03CFB94E80F008DE80F000A -:1001B000684610A902E004C841F8042D8842FAD12B -:1001C00010216846FFF7C0FF1090AA208DF8440068 -:1001D000FFF7A0FF00F0F3F84FF01024A069102201 -:1001E0006946803000F002F9A069082210A900F0E9 -:1001F000FDF800F0D8F84FF080510A6949690068AD -:100200004A43824201D8102070470020704710B541 -:10021000D0E900214FF0805002EB8103026944696C -:100220006243934209D84FF01022536903EB8103D4 -:100230000169406941438B4201D9092010BD5069D1 -:10024000401C01D0002010BD0F2010BD70B501680A -:100250000446AF4D4FF01020072952D2DFE801F0DD -:10026000330419293C1E2500D4E902656468294637 -:10027000304600F0CDF82A462146304600F0B6F868 -:10028000AA002146304600F09FFA002800D0032043 -:1002900070BD00F051FB4FF4805007E0201DFFF7C8 -:1002A000AAFF0028F4D100F047FB60682860002016 -:1002B00070BD241D94E80700920000F085FA002824 -:1002C000F6D00E2070BD8069401C12D0201DFFF7B3 -:1002D0009EFF0028F6D109E08069401C09D0201D4E -:1002E000FFF789FF0028EDD1606820B12046FFF7B5 -:1002F0004FFF042070BDFFF70DFF00F060F800F025 -:1003000052F8072070BD10B50C46182802D0012005 -:10031000086010BD2068FFF799FF206010BD4FF006 -:100320001024A069401C05D0A569A66980353079E4 -:10033000AA2808D06069401C2DD060690068401C64 -:1003400029D060692CE010212846FFF7FDFE3168B6 -:1003500081421CD1A16901F18002C03105E030B1B8 -:1003600008CA51F8040D984201D1012000E0002094 -:100370008A42F4D158B1286810B1042803D0FEE7AE -:10038000284600F057F862496868086008E000F005 -:1003900016F800F008F84FF480500168491C01D0AD -:1003A00000F0A4FAFEE7BFF34F8F5A4801685A4A9B -:1003B00001F4E06111430160BFF34F8FFEE74FF09E -:1003C00010208169491C02D0806900F0AEB87047E6 -:1003D000524A01681160121D416811604F4A8168DC -:1003E00010321160111DC068086070472DE9F0419E -:1003F00017460D460646002406E03046296800F000 -:10040000A7F8641C2D1D361DBC42F6D3BDE8F08153 -:1004100070B50C4605464FF4806608E0284600F0AB -:1004200084F8B44205D3A4F5806405F58055002C0A -:10043000F4D170BD4168044609B1012500E00025F2 -:100440004FF010267069A268920000F0BDF9C8B1A3 -:10045000204600F01AF89DB17669A56864684FF4EB -:10046000002084420AD2854208D229463046FFF74E -:10047000CFFF2A4621463046FFF7B8FFFFF79FFF20 -:10048000FFF791FFFFF746FEF8E72DE9FF414FF038 -:100490001024616980680D0B01EB800000F6FF708D -:1004A000010B0020009001900290024603906846E4 -:1004B00001230BE0560902F01F0C50F8267003FAD6 -:1004C0000CFC47EA0C0740F82670521CAA42F1D3F4 -:1004D0000AE04A0901F01F0650F8225003FA06F616 -:1004E000354340F82250491C8029F2D3A169090BF9 -:1004F0004A0901F01F0150F822408B409C4340F80C -:100500002240FFF765FFBDE8FF8100005C090000A5 -:10051000000000200CED00E00400FA050006004099 -:10052000144801680029FCD07047134A0221116069 -:1005300010490B68002BFCD00F4B1B1D186008687E -:100540000028FCD00020106008680028FCD070470C -:10055000094B10B501221A60064A1468002CFCD021 -:10056000016010680028FCD0002018601068002886 -:10057000FCD010BD00E4014004E5014008208F4993 -:1005800009680958084710208C4909680958084724 -:1005900014208A49096809580847182087490968BA -:1005A0000958084730208549096809580847382004 -:1005B00082490968095808473C2080490968095858 -:1005C000084740207D4909680958084744207B496D -:1005D00009680958084748207849096809580847B0 -:1005E0004C20764909680958084750207349096822 -:1005F0000958084754207149096809580847582084 -:100600006E490968095808475C206C49096809580F -:100610000847602069490968095808476420674904 -:100620000968095808476820644909680958084753 -:100630006C20624909680958084770205F490968B9 -:100640000958084774205D49096809580847782007 -:100650005A490968095808477C20584909680958C7 -:10066000084780205549096809580847842053499C -:1006700009680958084788205049096809580847F7 -:100680008C204E4909680958084790204B49096851 -:10069000095808479420494909680958084798208B -:1006A00046490968095808479C204449096809587F -:1006B0000847A0204149096809580847A4203F4934 -:1006C000096809580847A8203C490968095808479B -:1006D000AC203A49096809580847B02037490968E9 -:1006E00009580847B4203549096809580847B8200F -:1006F0003249096809580847BC2030490968095837 -:100700000847C0202D49096809580847C4202B49CB -:10071000096809580847C82028490968095808473E -:10072000CC202649096809580847D0202349096880 -:1007300009580847D4202149096809580847D82092 -:100740001E49096809580847DC201C4909680958EE -:100750000847E0201949096809580847E420174963 -:10076000096809580847E8201449096809580847E2 -:10077000EC201249096809580847F0200F49096818 -:1007800009580847F4200D49096809580847F82016 -:100790000A49096809580847FC20084909680958A6 -:1007A00008475FF480700549096809580847000048 -:1007B00003480449024A034B704700000000002030 -:1007C000680900006809000040EA010310B59B07B2 -:1007D0000FD1042A0DD310C808C9121F9C42F8D0AB -:1007E00020BA19BA884201D9012010BD4FF0FF305C -:1007F00010BD1AB1D30703D0521C07E0002010BD72 -:1008000010F8013B11F8014B1B1B07D110F8013BFD -:1008100011F8014B1B1B01D1921EF1D1184610BDDE -:1008200002F0FF0343EA032242EA024200F005B865 -:100830007047704770474FF000020429C0F01280E3 -:1008400010F0030C00F01B80CCF1040CBCF1020F83 -:1008500018BF00F8012BA8BF20F8022BA1EB0C0158 -:1008600000F00DB85FEAC17C24BF00F8012B00F84E -:10087000012B48BF00F8012B70474FF0000200B574 -:10088000134694469646203922BFA0E80C50A0E8B3 -:100890000C50B1F12001BFF4F7AF090728BFA0E861 -:1008A0000C5048BF0CC05DF804EB890028BF40F82D -:1008B000042B08BF704748BF20F8022B11F0804F6F -:1008C00018BF00F8012B7047014B1B68DB68184705 -:1008D0000000002009480A497047FFF7FBFFFFF7B7 -:1008E00011FC00BD20BFFDE7064B1847064A10600B -:1008F000016881F30888406800470000680900002B -:10090000680900001F030000000000201EF0040F13 -:100910000CBFEFF30881EFF3098188690238007892 -:10092000182803D100E00000074A1047074A126860 -:100930002C3212681047000000B5054B1B68054AB1 -:100940009B58984700BD00000703000000000020EE -:100950005809000004000000001000000000000022 -:0809600000FFFFFF0090D0032F -:10100000E8120020111D0200152F0000831C0200B1 -:10101000152F0000152F0000152F00000000000004 -:10102000000000000000000000000000691D020038 -:10103000152F000000000000152F0000152F0000E4 -:10104000D11D0200D71D0200152F0000152F000032 -:10105000152F0000152F0000152F0000152F000080 -:10106000DD1D0200152F0000152F0000E31D0200FA -:10107000152F0000E91D0200EF1D0200F51D020002 -:10108000152F0000152F0000152F0000152F000050 -:10109000152F0000152F0000152F0000152F000040 -:1010A000152F0000FB1D0200152F0000152F00005A -:1010B000152F0000152F0000152F0000152F000020 -:1010C000011E0200152F0000152F0000152F000033 -:1010D000152F0000152F0000152F0000152F000000 -:1010E000152F0000152F0000152F0000152F0000F0 -:1010F000152F0000152F0000152F0000152F0000E0 -:10110000152F0000152F000000F002F820F0EDFD73 -:101110000AA090E8000C82448344AAF10107DA4552 -:1011200001D120F0E2FDAFF2090EBAE80F0013F092 -:10113000010F18BFFB1A43F0010318471C130200EC -:101140003C1302000A444FF0000C10F8013B13F06E -:10115000070408BF10F8014B1D1108BF10F8015B10 -:10116000641E05D010F8016B641E01F8016BF9D103 -:1011700013F0080F1EBF10F8014BAD1C0C1B09D15A -:101180006D1E58BF01F801CBFAD505E014F8016BCC -:1011900001F8016B6D1EF9D59142D6D3704700005E -:1011A0000023002400250026103A28BF78C1FBD870 -:1011B000520728BF30C148BF0B6070471FB500F011 -:1011C0003DF88DE80F001FBD1EF0040F0CBFEFF3BC -:1011D0000880EFF30980014A104700006F2E0000DD -:1011E0008269034981614FF001001044704700009B -:1011F000F511000001B41EB400B512F0AFFD01B44A -:101200000198864601BC01B01EBD0000F0B4404606 -:10121000494652465B460FB402A0013001B506486C -:10122000004700BF01BC86460FBC804689469246F7 -:101230009B46F0BC704700000911000020F052BD31 -:1012400070B51A4C054609202070A01C00F05FF80C -:101250005920A08029462046BDE8704007F0F1BF24 -:1012600007F0FABF70B50C461149097829B1A0F111 -:101270006001552908D3012013E0602804D06928B3 -:1012800002D043F201000CE020CC0A4E94E80E009C -:1012900006EB8000A0F58050241FD0F8806E284611 -:1012A000B047206070BD012070470000080000209A -:1012B0001C0000204C1E020010B504460021012035 -:1012C00000F03BF800210B2000F037F80421192032 -:1012D00000F033F804210D2000F02FF804210E2037 -:1012E00000F02BF804210F2000F027F80421C84358 -:1012F00000F023F80621162000F01FF80621152023 -:1013000000F01BF82046FFF79BFF002010BD9D2139 -:1013100001807047FFF7A4BF10487047104A10B50E -:1013200014680F4B0F4A08331A60FFF79BFF0C48F5 -:10133000001D046010BD704770474907090E002862 -:1013400006DA00F00F0000F1E02080F8141D70476D -:1013500000F1E02080F800147047000003F900421B -:101360001005024001000001FE48002101604160BB -:10137000018170472DE9F743044692B091464068D9 -:1013800012F0B2FF40B1606812F0B7FF20B9607888 -:1013900000F00300022801D0012000E00020F14EFF -:1013A0004D463072484612F05BFF18B1102015B060 -:1013B000BDE8F0832946012001F029FF0028F6D17D -:1013C00001258DF842504FF4C050ADF84000002286 -:1013D00010A9284606F0FAFB0028E8D18DF8425003 -:1013E0004FF428504FF00008ADF8400047461C214C -:1013F0006846CDF81C8020F018FC9DF81C0008AA57 -:1014000020F00F00401C20F0F00010308DF81C0080 -:1014100020788DF81D0061789DF81E0061F3420070 -:1014200040F001008DF81E009DF800000AA940F070 -:1014300002008DF800002089ADF83000ADF8327060 -:10144000608907AFADF834000B97606810AC0E9060 -:101450000A94684606F0AFF90028A8D1BDF820002C -:1014600030808DF8425042F60120ADF840009DF8E2 -:101470001E0008AA20F00600801C20F001008DF854 -:101480001E000220ADF83000ADF8340013A80E9015 -:101490000AA9684606F08FF9002888D1BDF8200017 -:1014A0007080311D484600F033F9002887D18DF84F -:1014B000425042F6A620ADF840001C216846CDF807 -:1014C0001C8020F0B2FB9DF81C00ADF8345020F0D9 -:1014D0000F00401C20F0F00010308DF81C009DF82B -:1014E0001D0008AA20F0FF008DF81D009DF81E00C9 -:1014F0000AA920F0060040F00100801C8DF81E00B3 -:101500009DF800008DF8445040F002008DF8000076 -:10151000CDE90A4711A80E90ADF83050684606F0A4 -:101520004AF9002899D1BDF82000F08000203EE75C -:101530003EB504460820ADF80000204612F090FEAB -:1015400008B110203EBD2146012001F060FE0028B8 -:10155000F8D12088ADF804006088ADF80600A088B6 -:10156000ADF80800E088ADF80A007E4801AB6A4695 -:101570008088002106F024FDBDF800100829E1D084 -:1015800003203EBD1FB50446002002900820ADF8A0 -:101590000800CDF80CD0204612F062FE10B11020E9 -:1015A00004B010BD6F4802AA81884FF6FF7006F0A4 -:1015B0004EFF0028F4D1BDF80810082901D00320FF -:1015C000EEE7BDF800102180BDF802106180BDF883 -:1015D0000410A180BDF80610E180E1E701B582B0FA -:1015E0000220ADF800005F4802AB6A464088002147 -:1015F00006F0E6FCBDF80010022900D003200EBD65 -:101600001CB5002100910221ADF80010019012F0EC -:101610004DFE08B110201CBD52486A4641884FF665 -:10162000FF7006F014FFBDF800100229F3D003206C -:101630001CBDFEB54B4C06461546207A0F46C0072A -:1016400005D0084612F00CFE18B11020FEBD0F2088 -:10165000FEBDF82D01D90C20FEBD304612F000FE73 -:1016600018BB208801A905F0ECFD0028F4D13078E2 -:101670008DF80500208801A906F081FC0028EBD137 -:1016800000909DF800009DF8051040F002008DF8D4 -:101690000000090703D040F008008DF80000208802 -:1016A000694606F009FC0028D6D1ADF8085020881C -:1016B0003B4602AA002106F083FCBDF80810A942AF -:1016C000CAD00320FEBD7CB50546002000900190E5 -:1016D0000888ADF800000C462846019512F004FE7B -:1016E00018B9204612F0E2FD08B110207CBD15B1FA -:1016F000BDF8000050B11B486A4601884FF6FF70E4 -:1017000006F0A5FEBDF8001021807CBD0C207CBD3C -:1017100030B593B0044600200D460090142101A876 -:1017200020F083FA1C2108A820F07FFA9DF8000021 -:10173000CDF808D020F00F00401C20F0F000103051 -:101740008DF800009DF8010020F0FF008DF80100E9 -:101750009DF8200040F002008DF8200001208DF857 -:10176000460001E0E201002042F60420ADF844000A -:1017700011A801902088ADF83C006088ADF83E00CB -:10178000A088ADF84000E088ADF842009DF8020066 -:1017900006AA20F00600801C20F001008DF802004F -:1017A0000820ADF80C00ADF810000FA8059001A9B5 -:1017B00008A806F000F8002803D1BDF8180028801A -:1017C000002013B030BD0000F0B5007B059F1E4621 -:1017D00014460D46012800D0FFDF0C2030803A204F -:1017E0003880002C08D0287A052806D0287B0128CC -:1017F00000D0FFDF17206081F0BDA889FBE72DE94D -:10180000F04786B0144691F80C900E9A0D46B9F147 -:10181000010F0BD01021007B2E8A8846052807D0A7 -:10182000062833D0FFDF06B0BDE8F0870221F2E7DB -:10183000E8890C2100EB400001EB400018803320C8 -:101840001080002CEFD0E889608100271AE0009614 -:10185000688808F1020301AA696900F07AFF06EBC3 -:101860000800801C07EB470186B204EB4102BDF87B -:10187000040090810DF1060140460E3210F04CFD3F -:101880007F1CBFB26089B842E1D8CCE73420108019 -:10189000E889B9F1010F11D0122148430E301880A8 -:1018A000002CC0D0E88960814846B9F1010F00D012 -:1018B0000220207300270DF1040A1FE00621ECE747 -:1018C0000096688808F1020301AA696900F041FFE7 -:1018D00006EB0800801C86B2B9F1010F12D007EBAD -:1018E000C70004EB4000BDF80410C18110220AF1CA -:1018F0000201103020F000F97F1CBFB26089B842AD -:10190000DED890E707EB470104EB4102BDF8040085 -:10191000D0810AF102014046103210F0FDFCEBE7E5 -:101920002DE9F0470E4688B090F80CC096F80C8070 -:10193000378AF5890C20109902F10C044FF0000A47 -:10194000BCF1030F08D0BCF1040F3ED0BCF1070F6F -:101950007DD0FFDF08B067E705EB850C00EB4C009E -:10196000188031200880002AF4D0A8F1060000F089 -:10197000FF09558125E0182101A820F056F90097AC -:101980007088434601AA716900F0E3FEBDF80400C7 -:101990002080BDF80600E080BDF808002081A21C70 -:1019A0000DF10A01484610F0B7FCB9F1000F00D064 -:1019B00018B184F804A0A4F802A007EB080087B2CD -:1019C0000A346D1EADB2D6D2C4E705EB850C00EB30 -:1019D0004C00188032200880002ABBD0A8F10500F6 -:1019E00000F0FF09558137E000977088434601AA4F -:1019F000716900F0AEFE9DF80600BDF80410E180AC -:101A00002179420860F3000162F34101820862F328 -:101A10008201C20862F3C301020962F304114209A0 -:101A200062F34511820962F386112171C009607168 -:101A3000BDF80700208122460DF10901484610F04B -:101A40006BFC18B184F802A0A4F800A000E007E045 -:101A500007EB080087B20A346D1EADB2C4D279E735 -:101A6000A8F1020084B205FB08F000F10E0CA3F807 -:101A700000C035230B80002AA6D0558194810097A1 -:101A800083B270880E32716900F063FE62E72DE95F -:101A9000F84F1E460A9D0C4681462AB1607A00F531 -:101AA0008070D080E089108199F80C000C274FF0ED -:101AB00000084FF00E0A0D2873D2DFE800F09E07F1 -:101AC0000E1C28303846556A737373002146484609 -:101AD0000095FFF779FEBDE8F88F207B9146082836 -:101AE00002D0032800D0FFDF378030200AE000BF9B -:101AF000A9F80A80EFE7207B9146042800D0FFDF99 -:101B0000378031202880B9F1000FF1D1E3E7207B45 -:101B10009146042800D0FFDF37803220F2E7207B97 -:101B20009146022800D0FFDF37803320EAE7207B90 -:101B30001746022800D0FFDF3420A6F800A0288036 -:101B4000002FC8D0A7F80A80C5E7207B17460428D5 -:101B500000D0FFDF3520A6F800A02880002FBAD0E3 -:101B60004046A7F80A8012E0207B1746052802D0DD -:101B7000062800D0FFDF1020308036202880002F7C -:101B8000A9D0E0897881A7F80E80B9F80E00B88155 -:101B9000A1E7207B9146072800D0FFDF3780372060 -:101BA000B0E72AE04FF0120018804FF0380017001D -:101BB000288090D0E0897881A7F80E80A7F810805F -:101BC00099F80C000A2805D00B2809D00C280DD054 -:101BD000FFDF80E7207B0C2800D0FFDF01200AE038 -:101BE000207B0D2800D0FFDF042004E0207B0E289E -:101BF00000D0FFDF052038736DE7FFDF6BE770B5BE -:101C00000C46054601F076FA20B10078222804D26D -:101C1000082070BD43F2020070BD052128460EF079 -:101C20001DFF206008B1002070BD032070BD2DE9AC -:101C3000FF4784B00027824602970798904689465E -:101C400012300AF0E2F8401D20F00306079828B988 -:101C500007A95046FFF7D3FF002853D1B9F1000F71 -:101C600005D00798017B19BB052504681BE098F88F -:101C70000000092803D00F2812D0FFDF45E00799A4 -:101C800003254868B0B3497B42887143914238D9F3 -:101C90008AB2B3B2011D0EF03AFD0446078002E09D -:101CA000079C042508340CB1208810B1032D28D0DE -:101CB0002BE00798012112300AF0DFF8ADF80C0094 -:101CC000024602AB2946504608F0B1F9070001D19F -:101CD000A01C029007983A461230C8F80400A8F8F1 -:101CE00002A003A94046029B0AF0D4F8C0B107281D -:101CF00014D200E005E0DFE800F0060811110F0A39 -:101D00000C00132026E6002024E6112022E60820FD -:101D100020E643F203001DE607201BE6032019E638 -:101D2000BDF80C002346CDE900702A4650460799BD -:101D300000F035FD57B9032D08D10798B3B2417BA8 -:101D4000406871438AB2011D0EF0F5FCB9F1000F35 -:101D5000D9D0079981F80C90D5E72DE9FE4F91462F -:101D60001A881C468A468046FAB102AB494608F0FA -:101D70005EF9050019D04046A61C27880EF08AFFA0 -:101D80003246072629463B4600960EF049FB20883E -:101D90002346CDE900504A465146404600F0FFFC3C -:101DA000002020800120BDE8FE8F0020FBE710B559 -:101DB00086B01C46AAB104238DF800301388ADF814 -:101DC00008305288ADF80A208A788DF80E200988EC -:101DD000ADF80C1000236A462146FFF728FF06B035 -:101DE00010BD1020FBE770B50D4605210EF036FE44 -:101DF000040000D1FFDF294604F11200BDE8704065 -:101E00000AF024B82DE9F8430D468046002607F075 -:101E1000CCFA0446287812287BD2DFE800F07A5406 -:101E2000543C355632321332323209323232323287 -:101E30002879001FC0B2022801D0102810D114BB8D -:101E4000FFDF35E004B9FFDF052140460EF006FE56 -:101E5000007B032806D004280BD0072828D0FFDFFA -:101E6000072657E02879801FC0B2022820D050B141 -:101E7000F6E72879401FC0B2022819D0102817D0E1 -:101E8000EEE704B9FFDF13E004B9FFDF287901288A -:101E90000ED1172139E0052140460EF0DFFD070085 -:101EA00000D1FFDF07F11201404609F0A6FF2CB177 -:101EB0002A462146404600F05CFC2BE013214046B8 -:101EC00002F0AAFC26E0FFDF24E004B9FFDF0521D1 -:101ED00040460EF0C3FD060000D1FFDF694606F163 -:101EE000120009F094FF060000D0FFDFA98817292F -:101EF00001D2172200E00A46BDF80000824202D952 -:101F0000014602E005E01729C3D3404600F057FC24 -:101F1000CEE7FFDF3046BDE8F883401D20F0030226 -:101F200019B102FB01F0001D00E0002010447047D1 -:101F300013B5009850B100244FEA0D000EF091FB4C -:101F4000002C02D1F84A009911601CBD0124002028 -:101F5000F4E72DE9F0470C461546242120461FF0F2 -:101F600064FE05B9FFDFA87860732888DFF8B8A39E -:101F7000401D20F00301AF788946DAF800000EF02A -:101F80008EFB060000D1FFDF4FF000082660A6F8A8 -:101F9000008077B109FB07F1091D0AD0DAF80000CB -:101FA0000EF07DFB060000D1FFDF6660C6F8008002 -:101FB00001E0C4F80480298804F11200BDE8F0476C -:101FC00009F00DBF2DE9F047804601F112000D46E2 -:101FD000814609F01AFF401DD34F20F003026E7BAB -:101FE0001446296838680EF085FB3EB104FB06F202 -:101FF000121D03D0696838680EF07CFB05200EF0D6 -:10200000D7FC044605200EF0DBFC201A012802D183 -:1020100038680EF039FB49464046BDE8F04709F004 -:10202000F3BE70B5054605210EF018FD040000D181 -:10203000FFDF04F112012846BDE8704009F0DDBE63 -:102040002DE9F04F91B04FF0000BADF834B0ADF882 -:1020500004B047880C4605469246052138460EF0E6 -:10206000FDFC060000D1FFDF24B1A780A4F806B074 -:10207000A4F808B0297809220B20B2EB111F297AA5 -:102080007DD104F110023827C91E4FF00C094FF022 -:10209000010803920F2973D2DFE801F0F4F3F28113 -:1020A00008D48A8FA13DDDF5F0B8B800307B022856 -:1020B00000D0FFDFA88909EBC001ADF80410302182 -:1020C000ADF83410002C25D06081B5F80E900027B3 -:1020D0001DE004EBC708317C88F80E10F189A8F8E0 -:1020E0000C10CDF800906888042304AA296900F038 -:1020F00030FBBDF81010A8F8101009F10400BDF86D -:1021000012107F1C1FFA80F9A8F81210BFB2608964 -:10211000B842DED80FE1307B022800D0FFDFE9892A -:1021200009EBC100ADF804003020ADF83400287B85 -:102130000A90001FC0B20F90002CEBD06181B5F85F -:102140001090002727E000BFCDF8009068886969EB -:1021500003AA0A9B00F0FDFA0A9904EBC70809EBF1 -:1021600001001FFA80F908F10C0204A90F9810F081 -:10217000D3F818B188F80EB0A8F80CB001E0D7E099 -:10218000D4E0BDF80C10A8F81010BDF80E107F1C9C -:10219000A8F81210BFB26089B842D5D8CBE00DA81C -:1021A000009001AB224629463046FFF728FBC2E0EB -:1021B000307B082805D0FFDF03E0307B082800D003 -:1021C000FFDFE8891030ADF804003620ADF83400A8 -:1021D000002C3FD0A9896181F189A18127E0307B62 -:1021E000092800D0FFDFA88900F10C01ADF8041028 -:1021F0003721ADF83410002C2CD06081E889009094 -:10220000AB89688804F10C02296956E0E889392114 -:10221000103080B2ADF80400ADF83410002C74D04A -:10222000A9896181287A10280AD002212173E989BD -:10223000E181288A0090EB8968886969039A3CE00B -:102240000121F3E70DA8009001AB22462946304654 -:10225000FFF766FB6FE0307B0A2800D0FFDF12201B -:10226000ADF80400ADF834704CB3A9896181A4F8CD -:1022700010B0A4F80EB084F80C805CE020E002E01E -:1022800031E039E042E0307B0B2800D0FFDF288AC4 -:10229000ADF834701230ADF8040084B1042121731C -:1022A000A9896181E989E181298A2182688A00906E -:1022B0002B8A688804F11202696900F04AFA3AE050 -:1022C000307B0C2800D0FFDF1220ADF80400ADF801 -:1022D00034703CB305212173A4F80AB0A4F80EB001 -:1022E000A4F810B027E00DA8009001AB22462946C3 -:1022F0003046FFF769FA1EE00DA8009001AB2246B8 -:1023000029463046FFF7C3FB15E036E03B21ADF828 -:102310000400ADF8341084B3A4F80680A4F808B023 -:1023200084F80AB007E0000010000020FFDF02E0A0 -:10233000012919D0FFDFBDF80400AAF800007CB124 -:10234000BDF834002080BDF804006080BDF8340082 -:10235000392805D03B2803D03C2801D086F80CB0A2 -:1023600011B00020BDE8F08F3C21ADF80400ADF8BD -:10237000341014B1697AA172DDE7FFE7AAF8000012 -:10238000EEE72DE9F84356880F46804615460521AD -:1023900030460EF063FB040000D1FFDF12340094DE -:1023A0003B46414630466A6809F02EFFB3E570B5FA -:1023B0000D4605210EF052FB040000D1FFDF294637 -:1023C00004F11200BDE8704009F02CBD70B50D4657 -:1023D00005210EF043FB040000D1FFDF294604F184 -:1023E0001200BDE8704009F050BD70B505460521EA -:1023F0000EF034FB040000D1FFDF04F10803214696 -:102400002846BDE870400422A7E470B505460521C2 -:102410000EF024FB040000D1FFDF2146284623688C -:10242000BDE87040052298E470B5064605210EF01F -:1024300015FB040000D1FFDF04F1120009F0E5FCF8 -:10244000401D20F0030511E0011D00880322431800 -:1024500021463046FFF781FC00280BD0607BABB2F1 -:10246000684382B26068011D0EF09BF96068418884 -:102470000029E9D170BD70B50E46054606F095FFFE -:10248000040000D1FFDF0120207266726580207891 -:1024900020F00F00C01C20F0F00030302070BDE8AC -:1024A000704006F085BF2DE9F0438BB00D46144611 -:1024B000814606A9FFF7A3FB002814D14FF6FF764B -:1024C00001274FF420588CB103208DF80000102014 -:1024D000ADF8100007A8059007AA204604A90FF040 -:1024E0003AFF78B107200BB0BDE8F0830820ADF8C3 -:1024F00008508DF80E708DF80000ADF80A60ADF848 -:102500000C800CE00698A17801742188C1818DF8B7 -:102510000E70ADF80850ADF80C80ADF80A606A4650 -:1025200002214846069BFFF782FBDCE708B5012243 -:102530008DF8022042F60202ADF800200A4603237D -:102540006946FFF734FC08BD08B501228DF802206A -:1025500042F60302ADF800200A4604236946FFF75D -:1025600026FC08BD00B587B079B102228DF80020A5 -:102570000A88ADF808204988ADF80A1000236A4699 -:102580000521FFF754FB07B000BD1020FBE709B1A0 -:1025900007230CE40720704770B588B00D46144639 -:1025A000064606A9FFF72BFB00280ED17CB10620BA -:1025B000ADF808508DF80000ADF80A40069B6A4659 -:1025C0000821DC813046FFF732FB08B070BD0520E2 -:1025D0008DF80000ADF80850F0E700B587B059B1AC -:1025E00007238DF80030ADF80820039100236A46D8 -:1025F0000921FFF71CFBC6E71020C4E770B588B0BF -:102600000C460646002506A9FFF7F9FA0028DCD19A -:1026100006980121123009F030FC9CB1217806297E -:1026200021D2DFE801F0200505160318801E80B2D4 -:10263000C01EE28880B20AB1A3681BB1824203D9EE -:102640000C20C2E71020C0E7042904D0A08850B9AC -:1026500001E00620B9E7012913D0022905D0042999 -:102660001CD005292AD00720AFE709208DF80000EB -:102670006088ADF80800E088ADF80A00A068039013 -:1026800023E00C208DF800006088ADF80800E08899 -:10269000ADF80A00A0680A25039016E00D208DF819 -:1026A00000006088ADF80800A088ADF80A00E08856 -:1026B000ADF80C00A0680B25049006E00E208DF804 -:1026C000000060788DF808000C256A4629463046DF -:1026D000069BFFF7ACFA78E700B587B00F228DF8BC -:1026E0000020ADF8081000236A461946FFF79FFA4C -:1026F00049E700B587B071B102228DF800200A8841 -:10270000ADF808204988ADF80A1000236A46062172 -:10271000FFF78DFA37E7102035E770B586B006462B -:1027200001200D46ADF808108DF800000146002389 -:102730006A463046FFF77BFA040008D12946304646 -:1027400005F058FC0021304605F072FC204606B02A -:1027500070BDF8B51C4615460E46069F0EF088FA69 -:102760002346FF1DBCB231462A4600940DF01FFEE1 -:10277000F8BD10B548800878144620F00F00C01C42 -:1027800020F0F00090300B4608701822214603F12B -:1027900008001FF0F6F9BDE8104006F009BE30B49D -:1027A0001146DDE902423CB1032903D0002330BCCD -:1027B00008F0D3BA0123FAE71A8030BC704770B52D -:1027C0000C460546FFF70FFB2146284605F021FC85 -:1027D0002846BDE87040012105F02ABC4FF0E022F8 -:1027E0004FF400410020C2F88011204908702049B0 -:1027F00090020860704730B51C4D04462878A0420E -:1028000018BF002C02D0002818BFFFDF2878A04294 -:1028100008BF30BD2C701749154A0020ECB1164D89 -:10282000DFF858C0131F012C0DD0022C1CBFFFDF96 -:1028300030BD086003200860CCF800504FF4000061 -:102840001060186030BD086002200860CCF80050AD -:102850004FF040701060186030BD086008604FF0A5 -:102860006070106030BD00B5FFDF00BD18000020B3 -:1028700008F5014000F500402403002014F5004055 -:1028800070B50B2000F0B5F9082000F0B2F9002176 -:102890000B2000F0C4F90021082000F0C0F9EC4C36 -:1028A00001256560A5600020C4F84001C4F844011A -:1028B000C4F848010B2000F0A7F9082000F0A4F9A3 -:1028C0000B2000F08BF9256070BD10B50B2000F0D7 -:1028D00090F9082000F08DF9DD4801214160816008 -:1028E000DC490A68002AFCD10021C0F84011C0F878 -:1028F0004411C0F848110B2000F086F9BDE81040E3 -:10290000082000F081B910B50B2000F07DF9BDE87A -:102910001040082000F078B900B530B1012806D089 -:10292000022806D0FFDF002000BDCB4800BDCB4809 -:1029300000BDCA48001D00BD70B5C9494FF0004038 -:102940000860C84DC00BC5F80803C74800240460E0 -:10295000C5F840410820C43500F04BF9C5F83C41AA -:10296000C248047070BD08B5B94A002128B10128D9 -:1029700011D002281CD0FFDF08BD4FF48030C2F810 -:102980000803C2F84803B3483C300160C2F8401164 -:10299000BDE80840D0E74FF40030C2F80803C2F8A1 -:1029A0004803AC4840300160C2F84411AB480CE029 -:1029B0004FF48020C2F80803C2F84803A548443009 -:1029C0000160C2F84811A548001D0068009008BDCC -:1029D00070B516460D460446022800D9FFDF0022D6 -:1029E0009B48012304F110018B4000EB8401C1F8E6 -:1029F000405526B1C1F84021C0F8043303E0C0F8C7 -:102A00000833C1F84021C0F8443370BD2DE9F041CE -:102A10001C46154630B1012834D0022839D0FFDFDA -:102A2000BDE8F081891E002221F07F411046FFF7AA -:102A3000CFFF012C24D000208C4E8A4F01247070CF -:102A40003C61894900203C3908600220091D08606A -:102A5000854904203039086083483D350560C7F852 -:102A60000042082000F0D0F82004C7F80403082032 -:102A700000F0B4F87A49E007091F08603470CFE726 -:102A80000120D9E7012B02D00022012005E001221C -:102A9000FBE7012B04D000220220BDE8F04197E7BC -:102AA0000122F9E76B480068704770B500F0C7F87D -:102AB000674C0546D4F840010026012809D1D4F816 -:102AC0000803C00305D54FF48030C4F80803C4F8E8 -:102AD0004061D4F8440101280CD1D4F808038003E4 -:102AE00008D54FF40030C4F80803C4F8446101204D -:102AF00010F0F6FBD4F8480101280CD1D4F80803F3 -:102B0000400308D54FF48020C4F80803C4F8486196 -:102B1000022010F0E5FB5648056070BD70B500F06E -:102B20008EF8524D0446287858B1FFF705FF6878B3 -:102B300020B1002085F8010010F0D2FB4C48046061 -:102B400070BD0320F8E74FF0E0214FF40010C1F80A -:102B500000027047152000F057B842490120086173 -:102B6000082000F051B83F494FF47C10C1F8080329 -:102B70000020024601EB8003C3F84025C3F8402142 -:102B8000401CC0B20628F5D37047410A43F60952EB -:102B90005143C0F3080010FB02F000F5807001EB18 -:102BA0005020704710B5430B48F2376463431B0C49 -:102BB0005C020C602F4C03FB04002F4B4CF2F724FB -:102BC00043435B0D13FB04F404EB402000F58070DD -:102BD0004012107008681844086010BD00F01F0211 -:102BE000012191404009800000F1E020C0F800116F -:102BF000704700F01F02012191404009800000F160 -:102C0000E020C0F88011704700F01F0201219140C0 -:102C10004009800000F1E020C0F8801270474907A9 -:102C2000090E002806DA00F00F0000F1E02080F81D -:102C3000141D704700F1E02080F8001470470C4824 -:102C4000001F00680A4A0D49121D116070470000FC -:102C500000B0004004B500404081004044B1004055 -:102C600008F501400080004040850040340000200D -:102C700014050240F7C2FFFF6F0C010001000001C4 -:102C80000A4810B50468094909480831086010F07D -:102C9000BBFB0648001D046010BD0649002008600B -:102CA0004FF0E0210220C1F8800270471005024079 -:102CB00001000001FC1F004010B50D2000F06FF86E -:102CC000C4B26FF0040000F06AF8C0B2844200D0D1 -:102CD000FFDF3A490120086010BD70B50D2000F0FB -:102CE00048F8374C0020C4F800010125C4F804530B -:102CF0000D2000F049F825604FF0E0216014C1F884 -:102D0000000170BD10B50D2000F033F82C480121F2 -:102D100041600021C0F80011BDE810400D2000F016 -:102D200033B8284810B50468264927480831086098 -:102D30002349D1F80001012804D0FFDF2148001DFC -:102D4000046010BD1D48001D00680022C0B2C1F81B -:102D5000002110F074FFF1E710B51948D0F8001108 -:102D60000029FBD0FFF7DDFFBDE810400D2000F08B -:102D70000BB800F01F02012191404009800000F1D2 -:102D8000E020C0F88011704700F01F02012191403F -:102D90004009800000F1E020C0F880127047002850 -:102DA00006DA00F00F0000F1E02090F8140D03E0C7 -:102DB00000F1E02090F800044009704704D500407D -:102DC00000D00040100502400100000110B5202095 -:102DD00000F075F8202000F07DF84449202081F8AB -:102DE0000004434900060860091D42480860FEF7D8 -:102DF00093FA3F49C83108603F48D0F8041341F0C6 -:102E00000101C0F80413D0F8041341F08071C0F838 -:102E10000413364901201C39C1F8000110BD10B55A -:102E2000202000F04CF8324800210160001D0160B4 -:102E30002F4A481EE83A10602F4AC2F808032C4B6C -:102E4000C8331960C2F80001C2F860012B4908605C -:102E5000BDE81040202000F03DB825492848EC3955 -:102E60000860704722492648E8390860704770B505 -:102E70001F4A8069E83A224911601F49D1F8006170 -:102E80000023204D1D4A5C1E1EB1A84206D300211E -:102E90000FE0D1F8606186B1A84209D2C1F80031D3 -:102EA000C1F860311460BDE87040202000F012B815 -:102EB0001168BDE870401EF0E3BEFFDF70BD00F09A -:102EC0001F02012191404009800000F1E020C0F87C -:102ED0008011704700F01F020121914040098000DD -:102EE00000F1E020C0F880127047000020E000E010 -:102EF000000602406413002000000240000402406B -:102F000001000001003002000F4A12680D498A4298 -:102F10000CD118470C4A12680A4B9A4206D101B5E7 -:102F200010F00EFFFFF799FFBDE80140074909685F -:102F30000958084706480749054A064B70470000EC -:102F400000000000BEBAFECAB0000020040000204D -:102F5000E8120020E812002070B50C46054609F082 -:102F6000F0FA21462846BDE870400AF0E2BB10B5F1 -:102F700011F054FBFFF732FC11F0F0F9BDE81040FE -:102F800011F0A2BA01208107086070470120810773 -:102F90004860704712480068C00700D001207047A1 -:102FA0000F48001F0068C00700D0012070470C4880 -:102FB00008300068C00700D0012070470848103072 -:102FC0000068704706490C310A68D20306D50968C3 -:102FD00001F00301814201D10120704700207047B8 -:102FE0000C0400407047704770477047704702F00C -:102FF000FF0343EA032242EA02421EF0F6BD704795 -:103000002CFFFFFFDBE5B151003002009D00FFFF08 -:1030100084000000404B4C0066D342DA82CFB49D5E -:10302000E40AD77E68976592800939FF30B5FF4D75 -:10303000044610280AD0112C06D02846122CC1783C -:1030400006D0132C08D0FFDFEC7030BDFFDFFBE7AC -:103050001129F9D0FFDFF7E71129F5D0FFDFF3E7FA -:1030600070B50FF0E3FA044610F0A0FC201AC4B2C9 -:1030700006200DF09DFC054606200DF0A1FC2E1A41 -:1030800007200DF095FC054607200DF099FCE74957 -:10309000281A3218C87812280DD000231A44132891 -:1030A0000BD0002002440878022808D000201044E9 -:1030B000201AC0B270BD0123F0E70120F2E7012021 -:1030C000F5E7DA4800B58079D849420897B051F859 -:1030D000070F89880CD017228DF80020CDF8020048 -:1030E000ADF806100BA968460AF0B4FF17B000BD92 -:1030F0004422F1E702210DF0B1BC2DE9F04196B078 -:103100001D4690460E460746FFF7F4FF04000BD01D -:103110002078222804D3A07FC0F34010A84206D113 -:10312000082016B0BDE8F08143F20200F9E749201B -:103130008DF80000ADF802703DB101208DF804005B -:103140008DF805608DF8068002E000208DF80400FF -:103150000BA968460AF07EFFA07F65F34510A077B3 -:103160000020DEE730B50446A1F120000D460A2814 -:103170004AD2DFE800F005070C1C2328353A3F440B -:10318000FFDF42E0207820283FD1FFDF3DE0A74865 -:103190000178032939D0C078132836D02078242824 -:1031A00033D0252831D023282FD0FFDF2DE0207801 -:1031B00022282AD0232828D8FFDF26E020782228BA -:1031C00023D0FFDF21E0207822281ED024281CD025 -:1031D00026281AD0272818D0292816D0FFDF14E077 -:1031E0002078252811D0FFDF0FE0207825280CD08B -:1031F000FFDF0AE02078252807D0FFDF05E02078F0 -:10320000282802D0FFDF00E0FFDF257030BD30B599 -:103210000B8840F67B444FF6FF72022801D09342A0 -:1032200004D09D1FA54224D2022802D04D88954289 -:1032300003D04D88AD1FA5421BD24C88A34218D89D -:103240008B88B3F5FA7F14D2022802D0C888904246 -:1032500005D0C88840F677450A38A84209D2C88800 -:10326000904208D0944206D05B1C6343B3EB800FBE -:1032700001DB072030BD002030BD70B514460D467F -:10328000064610F0EDFF60B90DB1A54201D90C2042 -:1032900070BD002409E000BF56F8240010F0E0FFE4 -:1032A00008B1102070BD641CE4B2AC42F4D300201D -:1032B00070BDF0B50024059D10B1A94203D850E0BF -:1032C00009B90020F0BD0920F0BD055DD5B1071991 -:1032D00097F801C0BCF1150F2DD03BDCBCF1150FE8 -:1032E00038D2DFE80CF037122020262628282F2F8E -:1032F000373737373737373737372000025D22BB4C -:10330000641CE4B28C42F9D3DBE7022DDBD1BD783B -:103310001D70072D01D26D0701D40A20F0BD15786C -:1033200045F0010515E0EF43FF0707E0012D07D049 -:1033300010E00620F0BD2F07A7F18057002FF5D031 -:103340003046F0BD1578AF0701D50B20F0BD45F034 -:1033500002051570055D641C2C44E4B28C4202D950 -:10336000B1E74FF448568C42AFD3AAE710B50278C4 -:10337000540809D0012243F20223012C07D0022C69 -:103380000DD0032C13D10FE00020087005E08079E8 -:103390000324B4EB901F0AD10A70002010BD80797D -:1033A000B2EB901F03D1F7E780798009F4D018467B -:1033B00010BD1E4A117C39B1517C022908D0032965 -:1033C00008D043F2022070470146901D01F0FCBC7A -:1033D000032100E0012101700020704738B50C4640 -:1033E0000546694601F0F0FC00280DD19DF800105B -:1033F000207861F34700207055F8010FC4F80100F0 -:10340000A888A4F80500002038BD38B51378E8B1C5 -:1034100002281BD006A46D46246800944C7905EB65 -:103420009414247864F34703137003E0CC01002064 -:103430000302FF0103280ED003F0FE00107008689D -:10344000C2F801008888A2F8050038BD23F0FE0309 -:1034500013700228E9D1D8B240F00100EEE730B590 -:103460000C46097897B0222902D2082017B030BD47 -:1034700028218DF80010ADF80200132A03D03B2A52 -:1034800001D00720F2E78DF804200BA968460AF066 -:10349000E1FD050003D121212046FFF763FE284608 -:1034A000E4E700B597B023218DF80010ADF80200D5 -:1034B0001088ADF804005088ADF80600D088ADF84B -:1034C0000A009088ADF808000020ADF80C00ADF8B7 -:1034D0000E000BA968460AF0BDFD07E600B597B0DF -:1034E0002C22FA4968461EF04CFB0020CDF8030060 -:1034F000ADF80700F648007C022801D0012000E06A -:1035000000208DF809000BA968460AF0A3FD0028E9 -:1035100000D0FFDFEAE52DE9FF470220EC4E8DF8F1 -:1035200004000027B08AADF80600B84643F202094D -:103530004DE001A80DF0FBF9050006D0B08AA8B354 -:10354000A6F81480ADF806803FE0039CA07F010739 -:103550002DD504F124000090A28EBDF8080021466C -:1035600004F1360301F00DFE050005D04D452BD0CA -:10357000112D3DD0FFDF3BE0A07F20F00800A077B9 -:10358000E07F810861F30000C10861F34100E0774A -:1035900094F8210000F01F0084F8200020782828EB -:1035A00027D129212046FFF7DDFD22E015E0400765 -:1035B0000BD5BDF80800214604F10E02FFF771FF9C -:1035C00005000DD04D4510D100257F1CFFB2022013 -:1035D0000DF0EEF9401CB842ABD8052D12D008E032 -:1035E000A07F20F00400A07703E0112D00D0FFDFC2 -:1035F0000025BDF80600B082052D05D0284604B090 -:10360000BDE8F087A6F814800020F8E770B50646FC -:10361000FFF770FD054605F0C8FE040000D1FFDF8E -:103620006680207820F00F00801C20F0F000203011 -:1036300020700620207295F83E006072BDE8704050 -:1036400005F0B6BE2DE9F04786B0040000D1FFDFDB -:1036500020789F4E20F00F00801C20F0F00070308A -:10366000207060680178091F182931D2DFE801F065 -:10367000FD30303053FC300CFCFC40FD3030FD762A -:10368000FDFD3030FDFDFBFA86883046FFF732FD48 -:103690000546304607F05FFAE0B16068807985F84A -:1036A0003E0021212846FFF75DFD3046FEF7B9FCBC -:1036B000304603F0C3FF3146022010F085FDA87F9D -:1036C00020F01000A877FFF726FF002800D0FFDFCA -:1036D00006B095E7207820F0F0002030207006201A -:1036E0002072668060688079607205F061FED8E7BC -:1036F00085882846FFF7FEFC00B9FFDF6068807808 -:10370000012800D0FFDF6068817906B02846BDE857 -:10371000F04707F0FDBD86883046FFF7EBFC05005B -:1037200000D1FFDF05F044FE60683146C088288183 -:1037300060680089688160684089A881022010F073 -:1037400043FD0020A875A87F00F003000228BFD128 -:10375000FFF7E1FE0028BBD0FFDFB9E780783C2807 -:1037600003D0002502280AD000E00125002720B15F -:103770003C2802D0022800D0FFDF17B1B8E00127B3 -:10378000F5E705F015FE1DB1B07801F0DCFAA1E017 -:103790006568B5F804A0A879AD1C012806D0307979 -:1037A000814605F097FB070003D101E0B078F7E709 -:1037B000FFDF0022022150460DF047F9040000D13E -:1037C000FFDF22212046FFF7CDFC2879012800D019 -:1037D0000220A17F804668F30101A177288B208118 -:1037E000688B6081A88BA08184F822908DF8088076 -:1037F000B8680090F86801906A46032150460DF0C1 -:1038000024F900B9FFDFB888ADF81000B8788DF85A -:10381000120004AA052150460DF017F900B9FFDF88 -:10382000B888ADF80C00F8788DF80E0003AA0421D2 -:1038300050460DF00AF900B9FFDF062105F112002C -:1038400001F0EDFA28B36879800700D5FFDF6979C8 -:10385000E07D61F34700E075D5F80600A061688956 -:10386000A08303E05EE057E050E062E0062105F14E -:103870000C0001F0D4FAB0B1B0794108607861F37E -:1038800047006070D6F80700C4F80200B6F80B00D5 -:1038900012E0E07D20F0FE00801CE075D5F81200FB -:1038A000A061E88ADCE7607820F0FE00801C607090 -:1038B000E868C4F80200288AE080B8F1010F09D056 -:1038C000B8F1020F14D0FFDF02E70000CC1F0200A6 -:1038D000CC0100203078032800D0FFDF002108460B -:1038E00010F072FC06B00120BDE8F04701F0FAB913 -:1038F000F078132800D0FFDF0021062010F064FCD0 -:1039000006B01120BDE8F047FFF790BB06B0204697 -:10391000BDE8F04701F0E6BE05F04AFDB07C40F09E -:10392000020004E005F044FDB07C40F00400B074F7 -:10393000CEE606B0BDE8F04705F03ABD2DE9F04708 -:1039400005460078914600270209FF480C463E468E -:10395000012A6DD000234FF6FF71022A69D0072A91 -:1039600009D00A2A71D0FFDFA9F800600CB12780C6 -:103970006680002044E6D5F804C09CF80060142E50 -:103980007DD010DC04F1080204F118080F2E21D0BC -:1039900004DC042E5AD0082E57D10DE0122E6FD021 -:1039A000132EF9D11FE0153E072E4ED2DFE806F0A8 -:1039B000C14D4D099FEAB00012271026BCF8040043 -:1039C00014E11C27092694B3BCF80200A0806868A3 -:1039D00000795AE11B2709264CB30320207268683E -:1039E0004088A080C0E79CF802003C2827D0102720 -:1039F00018260CF1020CD4B1BCF80200A080BCF86F -:103A000018006082BCF818002082BCF81A00A0825E -:103A1000BCF81C00E0829CF805000CF10601FFF7E1 -:103A2000F4FC9CF8040028B10120E0739CE703E05B -:103A3000BFE0DFE00220F8E7A9F8006099E71B2764 -:103A40000926002CF8D023728EE720E11D273726A7 -:103A5000002CF1D0A18069680879491DFFF7D5FCD9 -:103A6000686890F82B00A0756868C0780428E07D2D -:103A700016D020F00100E0756968C97801E06DE0BA -:103A800011E061F34200E07569681F22C97A61F3B1 -:103A9000C700E075696840460C311EF02DF863E7F9 -:103AA00040F00100E7E71D273726002CC4D0A18095 -:103AB0006868411D0079FFF7A8FC696804F10F02EE -:103AC00001F10C00CB7A01461846FFF79EFC6868AE -:103AD000807CA0756868C178E07D61F3420020F0C9 -:103AE000F900E0751F2140461EF09FF83CE72027B3 -:103AF0001026002CA0D0A180686804F10902407A49 -:103B000020726968CB1C88781946FFF77EFC2BE78A -:103B100021270A26002C8FD0BCF80210A1806968EA -:103B200009792172696849796172817C21F0040107 -:103B300057E022270B26002C84D0BCF80400A0807C -:103B40006868807820726868807901F077F960721F -:103B50006868C07901F072F9A07205E72427102681 -:103B6000002CA3D0BCF80200A080686800792081F6 -:103B70006868007A60816868C088A0816868408948 -:103B8000E081F1E623271026002C8FD0BCF802102C -:103B9000A1806968898821816968C98861816968AB -:103BA0000989A18169684989E181817C21F002014B -:103BB00017E0297A012903D0022914D0FFDFD3E6C8 -:103BC0001F271026002C95D06988A180A989218102 -:103BD000E9896181298AA181698AE181817C21F059 -:103BE00001018174C0E6122768881026214601F081 -:103BF00003F9B9E6287A072850D2DFE800F0373D0C -:103C00003D484848040011270926002C94D0B5F8F7 -:103C100002804046FFF76EFA90F822A0A4F80480D4 -:103C2000687A2072042140460CF02AFF05214046A4 -:103C30000CF026FF002140460CF022FF01214046F7 -:103C40000CF01EFF032140460CF01AFF02214046F3 -:103C50000CF016FF062140460CF012FF07214046EB -:103C60000CF00EFF504601F06EF87DE61B2709268A -:103C7000002C8AD0A180E6E61B270926002C84D0E0 -:103C8000A180287A012800D0022020726CE64A46E2 -:103C900021462846BDE8F04701F0AFBEFFDF63E6EE -:103CA00030B5294D97B0E878132802D0082017B016 -:103CB00030BD22208DF800000BA968460AF0CAF931 -:103CC000040002D1287901F03EF80021062010F00E -:103CD0007BFA2046EBE700B51B4897B0C078122866 -:103CE00001D0082016E41E208DF8000000208DF879 -:103CF00002008DF803000BA968460AF0ABF9002812 -:103D0000F0D10021062010F05FFA1120FFF78EF9A4 -:103D10000020E7E710B50C4C96B02078012815D0AC -:103D20001B208DF8000000208DF802000BA96846CA -:103D30000AF090F900280AD10021084610F044FA50 -:103D40002078032805D007E0CC010020082016B019 -:103D500010BDA07800F0F7FF012000F0C3FF0020A5 -:103D6000F5E770B5002538B1022817D0062836D0FF -:103D7000072800D0FFDF70BDFFF7CCFF0028FAD185 -:103D800005F013FB0028F6D0017821F00F01891C03 -:103D900021F0F0012031017005723FE08EB2304613 -:103DA000FFF7A8F9040000D1FFDF20782128E2D036 -:103DB00005F0FBFA60B1017821F00F01891C21F0B8 -:103DC000F00110310170022101724680A57525E0D5 -:103DD00021463046BDE870401322FFF740BBFE4845 -:103DE000C478122C03D0132C04D0FFDF70BDFFF772 -:103DF00072FF01E0FFF754FF0028F7D105F0D5FA74 -:103E00000028F3D0017821F00F01891C21F0F00186 -:103E100020310170122C05D002210172BDE87040E2 -:103E200005F0C6BA0121F8E72DE9F04116460C006D -:103E3000804600D1FFDF307820F00F00801C20F09A -:103E4000F000103030702078012804D0022817D0FC -:103E5000FFDFBDE8F0814046FFF74CF9050000D1D7 -:103E6000FFDF0320A87505F0A3FA94E80F000836D9 -:103E700086E80F00D848817C41F001018174E8E7B1 -:103E80004046FFF737F9050000D1FFDFA1884FF664 -:103E9000FF700027814202D1E288824203D0814232 -:103EA00001D1E08840B105F083FA94E80F000836AC -:103EB00086E80F00AF75CCE7A87D0128C9D178232B -:103EC00000224146022010F0D5F80220A875C0E774 -:103ED00030B5054697B00C46084610F0C1F978BBDE -:103EE00000210120203D072D73D2DFE805F00425D5 -:103EF0004C515A6640000021072010F03BF908B1F0 -:103F00001120D4E624208DF80000D4F80200CDF86A -:103F10000200A0798DF806000BA968460AF09AF80D -:103F2000050057D1002208231146072010F0A2F8FF -:103F300007284FD0FFDF4DE0606810F0D5F908B1D9 -:103F40001020B4E64A208DF800002088ADF8020069 -:103F50006088ADF804000BA968460AF07BF80500FC -:103F600038D1606898B3BDF83010018032E04C2041 -:103F70008DF800002088ADF80200A07800F0010064 -:103F80008DF8040014E0206801F0D5FF054621E01B -:103F90004B2207E08DF802000AE000BF8DF8021006 -:103FA00006E046228DF800202278D207F6D0F1E70D -:103FB0000BA968460AF04EF8E8E738208DF80000B3 -:103FC0002088ADF802006088ADF80400F0E701E059 -:103FD000FFE7072528466AE630B5054697B00C4648 -:103FE000084610F063F908B1102060E6203D072D67 -:103FF00027D2DFE805F00424242426262400208884 -:10400000FFF778F820B10078222804D208204EE685 -:1040100043F202004BE625208DF800002088ADF821 -:1040200002000BA968460AF015F80028DDD1DDF87A -:104030003210C4F802109DF83610A17137E6062040 -:1040400035E6072033E66448801D704738B51621F1 -:1040500061481DF0C8FD012000F044FE1120FEF76C -:10406000E5FF5D4C6846E11D05F0FFF89DF8001086 -:10407000A07961F3470020F00100A07100202074B6 -:104080004FF46170E08102206074FFF71AF800B10C -:10409000FFDFFDF769F901F0E2FA38BD10B50C4613 -:1040A000402120461DF09FFDA07F20F00300A07757 -:1040B000202020700020A07584F8230010BD7047D8 -:1040C0007CB5054610F0CCF808B110207CBD424C00 -:1040D000A11DD4F806000090D4F80A0001902846EB -:1040E000FFF77CF90028F1D1FEF7EBFF0028EDD0B7 -:1040F0000099C4F80610BDF8041061819DF80610FF -:1041000021737CBD10B5044610F0D0F808B1102022 -:1041100010BD314922468879C91D4008FFF775F95D -:10412000002010BD2DE9F0479CB00D4604004FF073 -:10413000000812D00822FFF7A0F800281CD10026A2 -:1041400009E000BF54F8260004A9FFF70FF9002882 -:1041500012D1761CF6B2AE42F4D32F460A2006AD39 -:104160000DF1440A8DF8180026465146284609F0FC -:1041700071FF20B143F203201CB0BDE8F087404638 -:10418000DFF8548088F805002EB300244FF00B09A7 -:104190001DE000BF56F8240005A9FFF7E7F800B1BD -:1041A000FFDF9DF81400A87056F8240050F8011F96 -:1041B000C5F803108088A5F8070085F800905146DF -:1041C000284609F047FF00B1FFDF641CE4B2BC429F -:1041D000E0D388F8057001E0CC0100200020CBE797 -:1041E0002DE9F0479EB01546894604001DD00F46C4 -:1041F00008222946FFF741F8002810D1002612E0D6 -:1042000054F8260005A9103000F0DEFD002806D184 -:104210003FB157F8260010F023F810B110201EB05F -:10422000ABE7761CF6B2AE42EAD30026A5F1010850 -:104230001CE000BF06F1010A0AF0FF0712E000BF10 -:1042400054F82600017C4A0854F827100B7CB2EB86 -:10425000530F05D10622113011311DF021FC78B128 -:104260007F1CFFB2AF42EBD30AF0FF064645E1DB0D -:10427000C8462E4607AD0DF1480924B1012003E0E0 -:1042800043F20520CBE700208DF81E0031208DF889 -:104290001C004946284609F0DDFE38B934208DF867 -:1042A0001C004946284609F0D5FE10B143F204200F -:1042B000B5E77CB300272BE054F82700A91C103089 -:1042C00000F082FD00B1FFDF54F82700102250F803 -:1042D000111FC5F803108088A5F8070054F82710AF -:1042E00005F109001DF008FCB8F1000F16D058F8D0 -:1042F0002710102205F119001DF0FEFB3220287056 -:104300004946284609F0A6FE00B1FFDF7F1CFFB238 -:10431000B742D1D3FFF7E2F8002080E705F119009A -:1043200001F0FDFDEAE770B596B004460FF098FF86 -:1043300018B960680FF0E1FF10B1102016B070BD21 -:1043400060884AF2B811884207D82078FE4D6E4640 -:1043500028B1012806D0022804D00720EEE7FEF796 -:10436000B0FE1AE06078022804D0032802D043F29D -:104370000220E3E7687417208DF80000697C0020B4 -:10438000CDF80200ADF80600022934D003292FD061 -:10439000FFDF0BA9684609F05DFE0028CED16068FA -:1043A00001F0B0FD207870B101208DF80200F01C02 -:1043B00001F0B5FD4E208DF800000BA9684609F00C -:1043C00049FE00B1FFDF20782874FFF787F8608886 -:1043D00098B1E88180B2ADF8020030208DF800007D -:1043E0000BA9684609F036FE00B1FFDF0020A5E703 -:1043F0008DF80700CDE74020FAE74FF46170E8E759 -:1044000010B504460FF052FF20B9606838B10FF0C4 -:104410006BFF08B1102010BD606801F080FDCA4834 -:10442000C1896180417C6170007C2070002010BDDA -:104430002DE9F0419CB0054600208DF864008DF810 -:1044400060008DF830008DF868001E4614468846DE -:1044500028460FF052FF18B920460FF04EFF10B15A -:1044600010201CB0F5E455EA040018D01F270CAB4F -:1044700019AA414628460097FEF71BFF0028F0D1F5 -:104480001AAB18AA314620460097FEF712FF002803 -:10449000E7D19DF86000C00703D00A20E1E70720BC -:1044A000DFE701AF7DB11A208DF804008DF806809A -:1044B00042462946F81C1DF01FFB0DA901A809F072 -:1044C000C9FD0028CDD17CB120208DF804008DF8E5 -:1044D000066032462146F81C1DF00EFB0DA901A80E -:1044E00009F0B8FD0028BCD197499DF8300048700C -:1044F0000020B6E72DE9F0479CB08A464FF000084F -:1045000092A104468DF83480D1E90001CDE919016A -:1045100020460FF0A5FE90B92078012803D16068ED -:104520000FF09EFE58B9884D4FF00109287C40B12C -:10453000687C022805D160680FF0DFFE08B110200A -:104540001AE62878012801D0082015E607200CF08B -:1045500037FA18B9207878B101280DD0FEF780FD20 -:1045600060B1608943F6E172A0F1200191422178A7 -:104570000CD3012904D0B6E01220FDE51320FBE5A1 -:1045800000287DD1A18900297AD109E0012907D02D -:104590006978C90704D0A189002971D0B4296FD8DE -:1045A000217831B1012908D0022904D0032967D12B -:1045B0000AE0002609E0022607E008B9A08908B150 -:1045C000042609E0012607E00326287C50B1687C18 -:1045D000022807D1606828B10DA96068FEF7C6FE01 -:1045E0000028ADD1207A30B1012806D0022806D0AB -:1045F000032878D105E0002704E0012702E0022724 -:1046000000E003270EB1022E0ED16FB16879B8B366 -:104610006878800702D043F20120ADE5022E03D175 -:10462000022F60D0032F5ED0207808B1012806D178 -:10463000504600F06BFB002887D185F802A01820B7 -:104640008DF838006089ADF83A006089ADF83C001B -:104650008DF83E600DF13F00FEF7ABFE00B1FFDFCD -:104660009DF834008DF840002078012806D0287C81 -:1046700068B1687C02280AD1606840B1606800E0D7 -:1046800031E050F8011FCDF84110808802E040462B -:10469000CDF84180ADF845008DF84870A07BC0F39F -:1046A0004002014662F35F01C0F3800041EA8000EE -:1046B00019A9085C8DF84700A8B169460EA809F051 -:1046C000C9FC0028A9D11B208DF838008DF83A903C -:1046D00069460EA809F0BEFC00289ED19DF8010095 -:1046E0001B281CD101E0072046E5052E0CD2DFE88F -:1046F00006F0030308080300A87800F017FB032066 -:1047000000E0022000F0EEFA012E0AD0A08940B1AC -:1047100000228300114610460FF0ACFC08B10320C4 -:104720002AE5002028E52DE9FC4107460D46032631 -:1047300008460FF0E2FD00286CD13846FEF7DAFC9F -:1047400004000CD0207805E0CC0100200706050409 -:1047500003020100222805D20820BDE8FC8143F2B3 -:104760000200FAE7A07F00F0030C2DB12946604655 -:10477000FEF74DFD0600F0D1BCF1010F05D0BCF1F4 -:10478000020F18D0FFDF3046E7E7A07D2946022858 -:1047900001D011B107E01120DFE76846FCF7F2FE17 -:1047A0000028DAD16946384606F075FD0600EAD1E0 -:1047B0000120A075E7E7A07D032803D1FE48807C97 -:1047C000C00701D035B30EE025B1A07F40071FD44C -:1047D000002100E00121384606F07DFD0600D2D11F -:1047E000A075002DCFD02A4621463846FEF759FE47 -:1047F00006461128C7D1A07F4107C4D4296844F8D0 -:104800000E1F6968616040F0040020740026BAE75A -:104810001126B8E71020A0E770B50C460546FEF754 -:1048200069FC010005D022462846BDE87040FEF72D -:1048300016BE43F2020070BD00B597B043218DF85B -:1048400000108DF802000BA9684609F003FC17B0B0 -:1048500000BD0123FEF751BC00231A461946FEF79E -:104860004CBC30B597B004460FF0FAFC10B11020E4 -:1048700017B030BD204600F095FA0028F8D1CE4D93 -:10488000E878112801D00820F2E7FEF7E9FBE0B351 -:104890002078800701D56879C0B31D208DF800000D -:1048A0002078022200F001008DF802006088ADF847 -:1048B0000400A088ADF806002078C0F3400102EAA9 -:1048C000500001438DF8091002A8FEF772FD00B1F7 -:1048D000FFDF0BA9684609F0BDFB0028C8D11E20E8 -:1048E0008DF8000001208DF8020000208DF80300F3 -:1048F0000BA9684609F0AEFB0028B9D1E08800F0AA -:104900006DFA0400B4D1122001E004E005E0FEF7E6 -:104910008DFB2046ACE71320AAE70720A8E72DE986 -:10492000F043A54E074697B0F078994615460C46D9 -:10493000122803D1FFF7CFF9002816D120460FF037 -:104940008FFCE8BB28460FF08BFCC8BB204600F06C -:1049500029FA002809D129460220FEF758FC002830 -:1049600003D1F078112803D0082017B0BDE8F083F8 -:1049700006200CF025F850B12078800701D5707919 -:1049800038B1FEF76DFB022805D21320EDE71220A7 -:10499000EBE70720E9E721208DF800006088ADF8FB -:1049A0000200A088ADF8040020784FF00008C0F3A2 -:1049B00040008DF80600207880071FD4384600E0BC -:1049C00002E00FF04DFC08B11020CEE73878400827 -:1049D00008D0012809D0022807D0032805D043F2C7 -:1049E0000220C2E78DF8078002E001208DF8070061 -:1049F00057F8010F0290B888ADF80C000DF10E00C9 -:104A0000FEF7D7FC08B10320AFE72888ADF8100007 -:104A10006888ADF81200A888ADF81400E888ADF8F1 -:104A20001600ADF81880ADF81A80484600F06EF90F -:104A300000289AD186F804900BA9684609F00AFB71 -:104A4000002892D1307900F071F9E08800F0C6F9C1 -:104A500004008AD11320FEF7E9FA204685E730B535 -:104A6000054697B00C4608460FF020FC08B1102010 -:104A7000FEE62846FEF73EFB38B10178222902D334 -:104A8000807F800604D40820F2E643F20200EFE6BD -:104A900013208DF80000ADF802500BA9684609F00C -:104AA000D9FA0028E4D19DF932107F2901D0217074 -:104AB000DEE60520DCE630B5054697B00C46084634 -:104AC0000FF0CEFB08B11020D2E62846FEF712FB0D -:104AD00020B10078222804D20820C9E643F202005F -:104AE000C6E63548807C400701D51120C0E6207815 -:104AF000800802D16078800801D00720B8E65620EF -:104B00008DF80000ADF8025020788DF80400607830 -:104B10008DF805000BA9684609F09CFAA8E62DE976 -:104B2000F041B0B014460D460646FEF7E3FA070022 -:104B300006D03878222806D2082030B0BDE8F081AF -:104B400043F20200F9E728460FF0D7FB30B94FF0E7 -:104B500000084CB120460FF0C7FB08B11020ECE76D -:104B6000C4F80080A4F804801348807C800701D535 -:104B70001120E2E797F8220004F0ACF98088011DCB -:104B8000FB2901D2001D00E0FB20C0B26A46294685 -:104B900000F0E3F82C22094904A81CF0F2FFBDF84C -:104BA0000200ADF81400BDF80600ADF81600ADF82F -:104BB0001260BDF8000003E0CC010020A01F02003D -:104BC000ADF81800BDF80400ADF81A001AA904A841 -:104BD00009F040FA00B1FFDFBDF86C00ADF8080045 -:104BE000BDF86E00ADF80A00BDF87000BDF8721097 -:104BF000BDF800200844ADF80C0007201B2A9CD308 -:104C0000BDF802101B2998D3FB2A96D8FB2994D80B -:104C100006278A4210D10121104600F05AF8BDF84B -:104C20000410884208D1BDF80200012100F051F8BB -:104C3000BDF80610884201D038467EE7BDF808006E -:104C400028B9BDF80A1011B9BDF80C1029B35DB12F -:104C5000298849B1698839B124B102982060BDF82A -:104C60000C00A080132068E7BDF80010BDF80A20F2 -:104C7000081A80B2ADF80000BDF80210891AADF82C -:104C80000210012100F025F8ADF80400BDF8020083 -:104C9000012100F01EF8ADF806002C226B490FA888 -:104CA0001CF06FFFADF83E60BDF80200ADF84000AB -:104CB000BDF80600ADF84200BDF80000ADF84400B4 -:104CC000BDF80400ADF8460025A90FA809F0C2F907 -:104CD00033E7022903D0C000703080B270478000F3 -:104CE0003C30FAE730B55A4D040008D0012C04D00E -:104CF000022C06D0032C04D0FFDF2C7030BDFFDF68 -:104D0000FBE728780128F8D0FFDFF6E710B5044666 -:104D100004F0E0F830B1407830B1204604F0EEFB0A -:104D2000002010BD072010BD122010BD10B504F0EA -:104D3000D1F8040000D1FFDF607800B9FFDF6078B0 -:104D4000401E607010BD10B504F0C4F8040000D11E -:104D5000FFDF6078401C607010BD10B5144631B1A3 -:104D60000A68226049686160218839B107E02080C3 -:104D700060800121FFF7ADFFA0800DE020806188F9 -:104D800001B96080A08820B920880121FFF7A1FF28 -:104D9000A080E088002804D160880121FFF799FFF6 -:104DA000E08010BD418843F6FD730A1F9A4209D284 -:104DB0008088042806D3B0F5804F03D8884201D8F4 -:104DC00000207047072070470278520804D0012A5B -:104DD00002D043F202207047FEF7C8BA10B548B1BE -:104DE00083000022114606200FF044F9062801D066 -:104DF000032010BD002010BD70B50C0006460DD07C -:104E0000FEF778F9050000D1FFDFA6802889208110 -:104E1000288960816889A081A889E08170BD10B56A -:104E200000231A4603E0845C2343521CD2B28A4218 -:104E3000F9D30BB1002010BD012010BD00B5012831 -:104E400003D0022801D0FFDF002000BDF81F0200C0 -:104E5000CC01002010B504460FF002FA08B1102072 -:104E600010BD2078C0F30210042807D86078072806 -:104E700004D3A178102901D8814201D2072010BDA6 -:104E8000E078410706D421794A0703D4000701D40A -:104E9000080701D5062010BD002010BD10B51378FD -:104EA0005C08C37F64F30003C3771478A40864F339 -:104EB0004103C3771078C309487863F34100487011 -:104EC00013781C090B7864F347130B701378DB0815 -:104ED00063F3000048705078487110BD10B5C47875 -:104EE0000B7864F300030B70C478640864F3410327 -:104EF0000B70C478A40864F382030B70C478E408D0 -:104F000064F3C3030B700379117863F3000111702C -:104F100003795B0863F34101117003799B0863F324 -:104F2000820111700079C00860F3C301117010BDD7 -:104F300070B514460D46064604F037FA80B1017884 -:104F4000182221F00F01891C21F0F001A03100F896 -:104F5000081B21461CF015FEBDE8704004F028BA7D -:104F600029463046BDE870401322FEF778BA10B5E6 -:104F7000FE4C94F8300000280CD104F120014FF6CB -:104F8000FF72A1F110000DF04DF900B1FFDF01201B -:104F900084F8300010BD2DE9F047064608A8894680 -:104FA00090E830041F469046142128461CF03DFE30 -:104FB0000021CAF80010B8F1000F03D0B9F1000FBA -:104FC00003D114E03878C00711D020680FF06EF9D3 -:104FD000F0BBB8F1000F07D12068123028602068BC -:104FE000143068602068A8602168CAF8001038781A -:104FF000800728D560680FF077F948BBB9F1000F3A -:105000002DD0FFF720F80168C6F8C8118188A6F8EE -:10501000CC11807986F8CE01FFF7A9FFDFF84C8329 -:1050200008F12008C5F80C80626862B196F8C801E2 -:1050300006F2C91140081032FEF7E7F91022414686 -:1050400060681CF059FD3878400712D5A06800E070 -:1050500002E00FF02BF950B11020BDE8F087606836 -:105060000028F9D0E8606068C6F8C401EBE7A068E2 -:1050700028610020F1E730B5054608780C4620F09D -:105080000F00401C20F0F0011031217000206070F2 -:1050900095F8230030B104280FD0052811D0062838 -:1050A00014D0FFDF20780121B1EB101F04D295F856 -:1050B000200000F01F00607030BD21F0F0002030B3 -:1050C00002E021F0F00030302070EBE721F0F0003A -:1050D0004030F9E710B510B190F8BD4044B1A34895 -:1050E00090F83540002064B108601060186010BD71 -:1050F00000F1BC040C6000F1E40100F58670116061 -:10510000F4E79A4C34340C60EFE700B58BB007231A -:10511000CDE902128DF801300191944900236431E8 -:105120000591099301468DF8103068460DF052F84C -:10513000002800D0FFDF0BB000BD70B590B0154661 -:105140000C4602220646ADF80820092103AB04F004 -:105150006EFF0490002812D00C208DF8010004206E -:105160008DF8040004F59A74099605948DF818508A -:105170000AA968460DF02EF800B1FFDF012010B03B -:1051800070BD30B597B00C462C251A998DF800509B -:10519000ADF80200B3B11868019058680290ADF8FC -:1051A0000C2010220DF10E001CF0A6FC0BA9684685 -:1051B00008F050FF002803D1A17F41F01001A17732 -:1051C00017B030BD00200190E8E72DE9F047064612 -:1051D000808A8CB080B20D468246FDF78BFF044674 -:1051E000624F3078283FDFF884914FF00008112893 -:1051F00073D2DFE800F072F1350936777E98A7F2B6 -:10520000EFEEEDEC5BECEC00A07F00F0030001287A -:1052100006D0002150460BF021FC050003D101E02F -:105220000121F7E7FFDF99F85C10C90702D0D9F830 -:1052300060000BE0032105F121000EF0E2FCD5F83F -:1052400021004B49B0FBF1F201FB1200C5F821002F -:105250007068A867B068E8672078252800D0FFDF6D -:10526000ECE0A07F00F00300012806D000215046AA -:105270000BF0F4FB060003D101E00121F7E7FFDFAB -:105280003078810702D52178252904D040F001002B -:1052900030700CB0E1E60220287096F820002871EA -:1052A00006F121003136C5E90206F2E7A07F00F0E1 -:1052B0000300012806D0002150460BF0CFFB04006C -:1052C00003D101E00121F7E7FFDF2078C10605D512 -:1052D0001320287041346C60DBE7BEE140F0080029 -:1052E0002070D6E72148082128380EF08AFC0320D8 -:1052F00016E02A208DF8000010220DF102007168DE -:105300001CF0FAFB10220DF11200B1681CF0F4FB46 -:10531000164968462C3908F09DFE00B1FFDF0420D5 -:1053200028706F60B5E7E07FC00600D5FFDF307CF6 -:10533000B28800F001030CB05046BDE8F0470921E7 -:1053400005F00BBD04B9FFDF716821B1102204F133 -:1053500024001CF0D1FB28212046FDF703FFA07F8D -:1053600000F00300022814D104E00000180200201D -:1053700040420F0004F12400002300901A46214609 -:105380005046FFF7FEFE112807D029212046FDF7E1 -:10539000E9FE307A84F820007BE7A07F000700D583 -:1053A000FFDF14F81E0F40F008002070A4F81680EC -:1053B000C4F81880C4F81C806178084661F3820044 -:1053C000410861F3C3006070307AE07061E727E064 -:1053D0003FE17AE051E000E037E0A07F00F0030019 -:1053E000012806D0002150460BF038FB040003D101 -:1053F00001E00121F7E7FFDF022104F189000EF04F -:1054000000FC1020287004F5E4706860B4F889107E -:10541000298204F18000FD496861C5E9029138E7FD -:10542000A07F00F00300012805D0002150460BF0BA -:1054300015FB18B901E00121F8E7FFDF0CB0324697 -:1054400021465046BDE8F04772E504B9FFDF2078F9 -:105450002128A1D93079012803D1E07F40F0100044 -:10546000E077324621465046FFF762FD0CB02046F9 -:10547000BDE8F0472321FDF775BE3279AA8005F11A -:1054800008030921504604F0D2FDE86010B1112054 -:105490002870FEE6A07F00F00300012806D000215E -:1054A00050460BF0DBFA040003D101E00121F7E7DD -:1054B000FFDF04F1660102231022081F0BF03BF905 -:1054C00080F8008031794170E3E6A07F00F00300AE -:1054D000012806D0002150460BF0C0FA050003D188 -:1054E00001E00121F7E7FFDF95F8880000F00300F5 -:1054F000012879D1A07F00F00307E07FC0F34006C8 -:1055000016B1012F04D02BE095F8A400C0072AD0D3 -:10551000D5F8C00118B395F88720017C62F38701A4 -:105520000174E27FD5F8C00162F341010174D5F83E -:10553000C00166F300010174AEB1D5F8C0011022BC -:1055400004F124018C351CF0D7FA287E40F00100CC -:105550002876287820F0010005F88C0900E016B1C3 -:10556000022F04D02CE095F88C00C00726D0D5F887 -:10557000BC1119B395F88720087C62F38700087482 -:10558000E27FD5F8BC1162F341000874D5F8BC1174 -:1055900066F3000008748EB1D5F8BC01102204F146 -:1055A00024018C351CF0A8FA287840F0010005F899 -:1055B000180B287820F0010005F8A409022F44D028 -:1055C0005FF0000000EB400005EBC00090F88C009D -:1055D000800709D595F88000D5F8C421400805F169 -:1055E00081011032FDF711FF05208DF8000095F8BC -:1055F00088006A4600F003008DF8010095F88C10D1 -:105600008DF8021095F8A4008DF80300214650464D -:1056100001F046FA2078252805D0212807D0FFDFA1 -:105620002078222803D922212046FDF79BFDA07F68 -:1056300000F0030001280AD0002150460BF020FAA8 -:1056400000283FF432AEFFDF23E60120BAE7012154 -:10565000F3E7716881F801801BE6FFDF19E670B59A -:105660006A4C0025103C04F85C5F65600CF07FFD1F -:105670006649A1F1100003F02AFE04F82C5C062014 -:10568000607262487C3020615030A0611030E0616F -:1056900070BD70B50D46FDF72DFD040000D1FFDF94 -:1056A0004FF4E87128461CF0C0FA5848543068613D -:1056B00004F124002861A07F00F00300012809D034 -:1056C0005FF0020105F59A700CF052FD002800D041 -:1056D000FFDF70BD0121F5E70A46014602F59A7029 -:1056E0000CF066BD70B5054640689CB0017809298C -:1056F00006D00C2937D00D2933D0FFDF1CB070BD88 -:1057000046883046FDF7F6FC040000D1FFDF207824 -:105710002128F3D0282821D1686802210C3001F01B -:10572000B4F9D8B168680821001D01F0AEF9A8B13C -:105730002D208DF80000ADF80260102204F1240144 -:1057400001A81CF0D9F90BA9684608F083FC00B148 -:10575000FFDF29212046FDF705FDCFE703F028FEF6 -:10576000CCE701218171686886883046FDF7C2FC6C -:10577000040000D1FFDFA07F00F00301022902D165 -:1057800020F01000A077207821280AD0686881795D -:1057900009B1807880B1A07F00F0030002285ED0BC -:1057A000FFDFA07F00F003000228A7D1FDF7B3FEC2 -:1057B0000028A3D0FFDFA1E703F0FAFDE07FC107D7 -:1057C00028D0800705D594F8200000F01F0010288D -:1057D0001ED0052084F82300207829281CD02428F6 -:1057E000DFD1314605200EF0EFFC22212046FDF7E7 -:1057F000B9FCA07F00F0030001282ED00021304624 -:105800000BF03EF90028CCD0FFDFCAE728020020C9 -:105810000620DFE70420DDE7A07F00F00300012879 -:1058200006D0002130460BF019F9050003D101E044 -:105830000121F7E7FFDF25212046FDF793FC0F202C -:105840008DF8580016A905F59A700CF0A8FC0228EE -:10585000A7D00028A5D0FFDFA3E70121CFE703F001 -:10586000A7FD9EE72DE9F0438BB099461546884683 -:105870000646FDF73FFC04004FD0207822284CD389 -:1058800023284AD0E07FC00647D4A07F00F0030061 -:10589000012806D0002130460BF0E0F8070002D0C6 -:1058A0000CE00121F7E7A07F00F00300012805D1FB -:1058B0000121002230460BF0C8F8074601AB02AACE -:1058C00003A93846FFF706FC039800B9FFDF4FB184 -:1058D000039807F59A7787612078222806D0242834 -:1058E00004D007E003990020886103E025212046C9 -:1058F000FDF738FC03980B21417046628580C0E9B2 -:105900000289029901610199416104A90CF062FCCC -:10591000022802D0002800D0FFDF0BB0BDE8F083E2 -:1059200070B586B00546FDF7E5FB017822291CD944 -:10593000807F00F00300012806D0002128460BF0EC -:105940008DF8040030D101E00121F7E7FFDF2BE003 -:10595000B4F8620004F1660630440178427831B14F -:1059600021462846FFF7E9FBB8B906B070BDADF88F -:1059700004200921284602AB04F059FB03900028BB -:10598000F3D011208DF80000694604F59A700CF0F0 -:1059900006FC022801D000B1FFDF022310223146AD -:1059A00004F162000AF0FDFEB4F864000028CFD1D3 -:1059B000DBE710B586B00446FDF79CFB0178222991 -:1059C00019D9807F00F00300012806D0002120466D -:1059D0000BF044F8040003D101E00121F7E7FFDFF9 -:1059E00012208DF80000694604F59A700CF0D7FB80 -:1059F000002800D0FFDF06B010BD2DE9F05F05469E -:105A00000C4600270078904601093E46BA4604F14C -:105A1000080B02297ED0072902D00A2909D142E0C9 -:105A200068680178092905D00C292CD00D292AD0C5 -:105A3000FFDFB2E114271C26002C6CD04088A08028 -:105A4000FDF758FB5FEA000900D1FFDF99F8170066 -:105A50005A46400809F11801FDF7D7FC68688089AB -:105A6000208269684868C4F812008868C4F8160083 -:105A7000A07E20F0060040F00100A07699F81E00FC -:105A800040F040014DE01A270A26002CD5D080882E -:105A9000A080FDF72FFB050000D1FFDF5946284607 -:105AA000FFF7E9FA79E10CB1A88BA080287A0D28DC -:105AB0007ED006DC01287CD0022808D0032804D13F -:105AC00035E00F2876D0102875D0FFDF65E11E275E -:105AD0000926002CB1D0A088FDF70CFB5FEA000975 -:105AE00000D1FFDF287B00F003000128207A1BD0C3 -:105AF00020F001002072297B890861F341002072A7 -:105B0000297BC90861F382002072297B090961F3AE -:105B1000C30001E036E1E9E0207299F81E0040F090 -:105B2000800189F81E1038E140F00100E2E71327F8 -:105B30000D26002CAAD0A088FDF7DCFA8146807FD4 -:105B400000F00300012806D00021A0880AF086FF9B -:105B5000050003D101E00121F7E7FFDF99F81E00FE -:105B600000F00302012A59D0E86F817801F00301A7 -:105B70000129217A54D021F00101217283789B08F8 -:105B800063F3410121728378DB0863F382012172A0 -:105B900083781B0963F3C3012172037863F3061151 -:105BA0002172437863F3C711217284F809A003E0DE -:105BB0005EE0A4E08BE09CE0C178A172012A32D0C3 -:105BC0004279E17A62F30001E1724279520862F3AC -:105BD0004101E1724279920862F38201E1724279F5 -:105BE000D20862F3C301E1720279217B62F3000102 -:105BF00021730279520862F34101217302799208FC -:105C000062F3820121730079C00860F3C30121733C -:105C100099F80000232859D9262168E0A86FA4E745 -:105C200041F00101A9E70279E17A62F30001E17232 -:105C30000279520862F34101E1720279920862F33B -:105C40008201E1720279D20862F3C301E172427902 -:105C5000217B62F3000121734279520862F3410112 -:105C600021734279920862F3820121734079CBE774 -:105C700018271026D4B3A088FDF73CFA8346807F0E -:105C800000F00300012807D00021A0880AF0E6FEFA -:105C90005FEA000903D101E00121F6E7FFDFE868D0 -:105CA000A06099F8000040F0040189F8001099F80C -:105CB0000100800708D5012020739BF800002328ED -:105CC0006BD9272158464FE084F80CA065E01527D2 -:105CD0000F265CB1A088FDF70DFA814606225946D1 -:105CE000E86808F01FFA0120A0739BE03FE04846F7 -:105CF0003AE016270926D4B3287B20724DE0287B92 -:105D000019270E269CB3C4F808A0A4F80CA00128FB -:105D100007D0022805D0032805D0042803D0FFDFD0 -:105D20000DE0207207E0697B042801F00F0141F0CB -:105D3000800121721CD0607A20F003006072A0887C -:105D4000FDF7D8F905460078212826D0232800D071 -:105D5000FFDFA87F00F00300012811D00021A088F8 -:105D60000AF08EFE22212846FDF7FCF915E004E03A -:105D7000607A20F00300401CE0E7A8F8006011E022 -:105D80000121ECE70CB16888A080287A03282BD089 -:105D900004280AD005284BD0FFDFA8F800600CB11A -:105DA000278066800020BDE8F09F15270F26002C75 -:105DB000E3D0A088FDF79EF9807F00F00300012862 -:105DC00006D00021A0880AF049FE050003D101E0B9 -:105DD0000121F7E7FFDFD5F821000622594608F038 -:105DE000A1F984F80EA0D8E717270926002CC4D003 -:105DF000A088FDF77FF98146807F00F0030001282D -:105E000006D00021A0880AF029FE050003D101E098 -:105E10000121F7E7FFDF6878800701D5022000E065 -:105E20000120207299F800002328B6D927215EE7C7 -:105E300019270E26002CA0D0A088FDF75BF95FEA99 -:105E4000000900D1FFDFC4F808A0A4F80CA084F872 -:105E500008A0A07A40F00300A07299F81F1061F327 -:105E60008200A07299F81F10C1F34002114205D0C0 -:105E700099F8201001F01F0110292CD020F0080003 -:105E8000A07299F81F004108607A61F3C300607244 -:105E9000697A01F003010129A5D140F00400607284 -:105EA00099F81E00E97A00F00300012816D0607B03 -:105EB00061F300006073AA7A217B62F30001217311 -:105EC000EA7A520862F341006073A87A400860F3EE -:105ED0004101217361E740F00800D1E7207B61F3C5 -:105EE00000002073AA7A617B62F300016173EA7A91 -:105EF000520862F341002073A87A400860F3410120 -:105F000061734AE710B5FE4C30B10146102204F12E -:105F100020001BF0F1FD012084F8300010BD10B509 -:105F20000446FFF724F8F64920461022BDE8104049 -:105F300020311BF0E1BD70B5F14D06004FF00004BB -:105F400012D00EF08DF908B110240BE00621304676 -:105F500008F0CFF8411C04D02866012085F85C00C9 -:105F600000E00724204670BD0020F7E7007810F01D -:105F70000F0204D0012A05D0022A0CD110E000093A -:105F800009D10AE00009012807D0022805D003281A -:105F900003D0042801D00720704708700020704704 -:105FA0000620704705282AD2DFE800F003070F1704 -:105FB0001F00087820F0FF001EE0087820F00F0096 -:105FC000401C20F0F000103016E0087820F00F00A0 -:105FD000401C20F0F00020300EE0087820F00F0088 -:105FE000401C20F0F000303006E0087820F00F0070 -:105FF000401C20F0F000403008700020704707205F -:1060000070472DE9F041804688B00D4600270846CC -:106010000EF073F9A8B94046FDF76CF8040003D000 -:106020002078222815D104E043F2020008B0BDE830 -:10603000F08145B9A07F010603D500F003000228D6 -:1060400001D01020F2E7A07FC10601D4010702D5DC -:106050000DB10820EAE7E17FC90601D50D20E5E78B -:1060600000F00300022805D125B12846FEF7F2FE14 -:106070000700DBD1A07F00F00300012806D000213B -:1060800040460AF0EBFC060002D00DE00121F7E7E4 -:10609000A07F00F0030001280CD000210022404620 -:1060A0000AF0D3FC060007D0A07F00F0030002280E -:1060B00004D009E00121F1E70420B7E725B12A4621 -:1060C00031462046FEF7EAFE07AB1A4669463046DF -:1060D000FFF700F8009800B9FFDF00990C20487026 -:1060E00006F59A70C1F82480486100200881A07FDD -:1060F00000F00300012828D0EDB302200871301D04 -:1061000088613078400908777078C0F3400048779C -:10611000287800F00102887F62F301008877E27F2F -:1061200062F382008877E27F520862F3C3008877C7 -:10613000727862F304108877A878C87701F1210299 -:1061400028462031FEF7CAFE22E001200871287897 -:1061500000F00102087E62F3010008762A785208F6 -:1061600062F3820008762A78920862F3C300087608 -:106170002A78D20800E007E062F3041008762421B0 -:106180002046FCF7EFFF0BE003200871052008769E -:1061900025212046FCF7E6FFA07F20F08000A077B5 -:1061A00001A900980CF016F8022801D000B1FFDF19 -:1061B00038463BE72DE9FF4F524A0D4699B09A46C3 -:1061C00007CA14AB002783E807001998FCF792FF71 -:1061D000060006D03078262806D008201DB0BDE87D -:1061E000F08F43F20200F9E7B07F00F00309B9F144 -:1061F000010F03D0B9F1020F07D008E03DB91B9899 -:10620000FEF728FE0028E9D101E01B9880BBB07F93 -:1062100000F00300012806D0002119980AF01EFCA6 -:10622000040003D101E00121F7E7FFDF852D28D02D -:1062300007DCF5B1812D1ED0822D1ED0832D08D113 -:106240001DE0862D1FD0882D1FD0892D1FD08A2DAF -:106250001FD00F2020710F281DD003F0A6F8E0B149 -:1062600001208DF83400201D0E902079B8B160E136 -:1062700011E00020EEE70120ECE70220EAE703202E -:10628000E8E70520E6E70620E4E70820E2E7092042 -:10629000E0E70A20DEE70720A0E711209EE7B9F13A -:1062A000010F17D0D4E91E50804602200190012032 -:1062B0000090A87898F80210C0F3C000C1F3C001A4 -:1062C00008405FEA000B63D050460DF0C9FF00287C -:1062D00072D133E0D4E91E850120019002200090A4 -:1062E000214630461B9AFEF7D9FD1B98007800F036 -:1062F0000101A87861F30100A870F17F04E00000BB -:10630000180200202420020061F38200A870F17FAF -:10631000490861F3C300A870617861F30410A870A4 -:106320002078400928706078C0F3400068701B989E -:106330008078E870002068712871BAE7DAF80C00FC -:106340000DF08EFFC0BBDAF81C000DF089FF98BB82 -:10635000DAF80C00A060DAF81C00E06098F80100A0 -:10636000617800F0010041EA4000607098F8021086 -:10637000C0B2C1F30011891E08406070002084F88B -:106380002000009906F1170002290BD001210AE034 -:1063900098F80110607801F00101FD2242EA410104 -:1063A0000840E2E7002104EB810188610199701C3B -:1063B000022902D0012101E028E0002104EB810143 -:1063C0008861A87800F00300012849D198F80200FC -:1063D00000F00300012843D1B9F1010F04D12A1DB7 -:1063E000691D1B98FEF77AFD287998F8041008407B -:1063F0008DF82C00697998F8052011408DF830103F -:1064000008432DD050460DF02BFF08B11020E5E6D3 -:106410000AF1100004F5DE7104F190020490B9F164 -:10642000020F3CD00090CDE9012100210BAB5A4670 -:106430002046FEF7B0FD0028E9D104F5E07104F133 -:10644000A802B9F1010F30D004980090CDE90121E4 -:1064500000210CAB5A462046FEF79DFD0028D6D100 -:106460006078800740D4A87898F80210C0F38000C4 -:10647000C1F38001084337D0297898F8000014AAA6 -:10648000B9F1010F17D032F810204B00DA4012F0AA -:10649000030718D0012F1ED0022F12D11DE0CDF816 -:1064A00000A0CDE901210121C0E7CDF800A0CDE990 -:1064B00001210121CDE732F811204300DA4002F03A -:1064C0000307032F07D0BBF1000F0DD0012906D021 -:1064D000042904D008E00227F5E70127F3E70128A3 -:1064E00001D0042800D10427F07F40F001006BF3B5 -:1064F0004100F077607881074FF003000CD5A07160 -:10650000BBF1000F15D100BF8DF85C0017AA314612 -:10651000199800F0C5FA0CE00221022F18D0012FC3 -:1065200018D0042F22D00020A071F07F20F00100AD -:10653000F07725213046FCF715FE0DA904F59A7079 -:106540000BF02DFE10B1022800D0FFDF002045E641 -:10655000A171D9E7A1710D2104F124001BF065FBA5 -:10656000207840F0020020700420CDE70120A071C7 -:10657000DFE72DE9F04387B09046894604460025C1 -:10658000FCF7B8FD060006D03078272806D0082092 -:1065900007B0BDE8F08343F20200F9E7B07F00F0F6 -:1065A0000300012806D0002120460AF057FA040013 -:1065B00003D101E00121F7E7FFDFA7795FEA0900D6 -:1065C00005D0012821D0B9F1020F26D110E0B8F191 -:1065D000000F22D1012F05D0022F05D0032F05D0A7 -:1065E000FFDF2DE00C252BE0012529E0022527E027 -:1065F00040460DF035FEB0B9032F0ED110224146B2 -:1066000004F121001BF078FA1AE0012F02D0022FCA -:1066100003D104E0B8F1000F12D00720B8E74046DC -:106620000DF01EFE08B11020B2E7102104F1210088 -:106630001BF0D9FA0621404607F05BFDC4F82100A3 -:106640002078252140F0020020703046FCF78AFDBA -:106650002078C10714D020F00100207002208DF8AE -:10666000000004F1210002908DF80450694604F501 -:106670009A700BF094FD022804D018B1FFDF01E0FE -:1066800084F82050002083E730B587B00D460446DB -:10669000FCF730FD88B1807F00F0030001280FD0A7 -:1066A000002120460AF0DAF904000ED028460DF049 -:1066B000D7FD38B1102007B030BD43F20200FAE731 -:1066C0000121EEE72078400701D40820F3E72946AE -:1066D00004F14100202205461BF00EFA207840F01C -:1066E0001000207001070FD520F008002070132043 -:1066F0008DF80000694604F59A7001950BF04FFD86 -:10670000022801D000B1FFDF0020D4E770B50D46AC -:106710000646FCF7EFFC18B1017827291FD102E0EB -:1067200043F2020070BD807F00F00300012806D014 -:10673000002130460AF092F9040003D101E0012162 -:10674000F7E7FFDFA079022809D16078C00706D0FB -:106750002A4621463046FEF7F0FC10B10FE0082033 -:1067600070BDB4F864000E280BD204F16601022358 -:106770001022081F09F0DFFF012101704570002081 -:1067800070BD112070BD70B5064686B014460D462A -:1067900008460DF065FD18B920460DF087FD10B1D3 -:1067A000102006B070BDA6F57F40FF380ED03046F1 -:1067B000FCF7A0FC38B1417822464B08811C1846F2 -:1067C000FCF723FE07E043F20200EAE72046FDF76C -:1067D00099FC0028E5D11021E01D0DF012FAE21D10 -:1067E00029466846FEF791FC102204F11700019932 -:1067F0001BF082F90020D4E72DE9F041044686B071 -:1068000015468846002708460DF077FD18B928463A -:106810000DF073FD10B1102006B008E42046FCF71F -:1068200069FC060003D03078272818D102E043F233 -:106830000200F1E7B07F00F00300012806D000213C -:1068400020460AF00BF9040003D101E00121F7E72B -:10685000FFDF2078400702D56078800701D4082048 -:10686000DAE7B07F00F00300012818D0D4E91E0158 -:10687000407800B1B5B1487810B1B8F1000F11D02F -:10688000C5B1EA1D6846E168FEF73FFC102205F13C -:10689000170001991BF004F930B104270AE0D4E98C -:1068A0001E10E5E70720B7E71022E91D04F13100CB -:1068B0001BF022F9B8F1000F06D0102208F10701F1 -:1068C00004F121001BF018F92078252140F0020086 -:1068D00020703046FCF746FC2078C10716D020F027 -:1068E0000100207002208DF8000004F121000290C8 -:1068F000103003908DF80470694604F59A700BF01F -:106900004EFC022804D018B1FFDF01E084F82070AB -:10691000002081E7F8B515460E460746FCF7EAFB6E -:10692000040004D02078222804D00820F8BD43F2C7 -:106930000200F8BDA07F00F00300022802D043F25D -:106940000400F8BD30460DF08BFC18B928460DF058 -:1069500087FC08B11020F8BD00953288B31C214691 -:106960003846FEF70EFC112814D00028F3D1297CFC -:106970004A08E17F62F30001E1772A7C62F341017A -:10698000E177297C890884F82010A17F21F080011B -:10699000A177F8BDA17F0907FBD4D6F80200C4F89F -:1069A0003600D6F80600C4F83A003088A0861022D7 -:1069B000294604F124001BF09FF8287C4108E07F61 -:1069C00061F38200E077297C61F3C300E077287CE3 -:1069D000800884F82100A07F40F00800A077002004 -:1069E000D3E770B596B00D46064613B1072016B032 -:1069F00070BDFCF77FFB040007D02078222802D36B -:106A0000A07F400604D40820F1E743F20200EEE73D -:106A1000C5B12D208DF80000ADF802601022294686 -:106A200001A81BF069F8287C4108E07F61F30000B1 -:106A3000E077297C61F34100E077287C800884F8C6 -:106A4000200004E02E208DF80000ADF802600BA9B4 -:106A5000684607F0FFFAA17F21F04001A177C6E761 -:106A600070B50D46FCF746FB040005D028460DF036 -:106A70001DFC20B1102070BD43F2020070BD2946FC -:106A80002046FEF7F8FA002070BD04E010F8012B54 -:106A90000AB100207047491E89B2F7D20120704721 -:106AA00070B51546064602F080FC040000D1FFDFF9 -:106AB000207820F00F00801C20F0F00020302070A3 -:106AC00066802868A060BDE8704002F071BC0000DC -:106AD00018B18178012938D101E010207047018870 -:106AE00042F60112881A914231D018DC42F60102B6 -:106AF000A1EB020091422AD00CDC41B3B1F5C05F9A -:106B000025D06FF4C050081821D0A0F57060FF3870 -:106B10001BD11CE001281AD002280AD117E0B0F5D9 -:106B2000807F14D008DC012811D002280FD0032860 -:106B30000DD0FF2809D10AE0B0F5817F07D0A0F57C -:106B40008070033803D0012801D0002070470F2047 -:106B500070470B2826D008DC1BD2DFE800F01C2091 -:106B600025251A25292325271E0011281CD008DCDD -:106B70000C2817D00D281DD00F2815D0102808D1AB -:106B800010E0822809D0842810D0852810D08728CA -:106B900012D003207047002070470520704743F251 -:106BA00003007047072070470F207047042070478C -:106BB000062070470C20704743F20200704738B53A -:106BC0000C46050041D06946FFF7D0F9002819D1DD -:106BD0009DF80010607861F3020060706946681CDF -:106BE000FFF7C4F900280DD19DF80010607861F31B -:106BF000C5006070A978C1F34101012903D00229C1 -:106C000005D0072038BD217821F0200102E021784D -:106C100041F020012170410704D0A978C90861F32F -:106C200086106070607810F0380F07D0A9780909D5 -:106C300061F3C710607010F0380F02D16078400621 -:106C400003D5207840F040002070002038BD70B59A -:106C500004460020088015466068FFF7B0FF002852 -:106C600016D12089A189884211D860688078C00730 -:106C70000AD0B1F5007F0AD840F20120B1FBF0F252 -:106C800000FB1210288007E0B1F5FF7F01D90C202E -:106C900070BD01F201212980002070BD10B504787B -:106CA000137864F3000313700478640864F34103F9 -:106CB00013700478A40864F3820313700478E40862 -:106CC00064F3C30313700478240964F3041313708A -:106CD0000478640964F3451313700078800960F345 -:106CE0008613137031B10878C10701D1800701D52F -:106CF000012000E0002060F3C713137010BD42783C -:106D0000530702D002F0070306E012F0380F02D05A -:106D1000C2F3C20300E001234A7863F302024A701F -:106D2000407810F0380F02D0C0F3C20005E04307EE -:106D300002D000F0070000E0012060F3C5024A70B5 -:106D400070472DE9F04F95B00D00804615D0B8F191 -:106D5000000F16D0122128461AF045FF4FF6FF7B90 -:106D600005AA0121584606F0C0FF002426463746F2 -:106D70004FF420596FF4205A75E0102015B0BDE88B -:106D8000F08F0720FAE700BF9DF81E0001280AD106 -:106D9000BDF81C0048450BD010EB0A000AD00128B2 -:106DA0000CD002280CD0042C0ED0052C0FD10DE0F5 -:106DB000012400E00224BDF81A6008E0032406E084 -:106DC0000424BDF81A7002E0052400E00624BDF892 -:106DD0001A10414547D12C74BEB34FF0000810AAD9 -:106DE0004FF0070ACDE90282CDE900A80DF13C0978 -:106DF0001023CDF8109042463146584607F028F847 -:106E000008BBBDF83C002A46C0B210A90BF084FABA -:106E1000C8B9AE81CFB1CDE900A80DF1080C0AAE1A -:106E200040468CE84102132300223946584607F0B9 -:106E30000FF840B9BDF83C00F11CC01EC0B22A1DBD -:106E40000BF06AFA10B1032098E70AE0BDF82900B8 -:106E5000E881062C05D19DF81E00A872BDF81C0023 -:106E6000288100208AE705A806F04BFF00288BD078 -:106E7000FFF76FFE82E72DE9F0471C46DDE9097850 -:106E8000DDF8209015460E00824600D1FFDF0CB1E0 -:106E9000208818B1D5B11120BDE8F087022D01D0AE -:106EA000012100E0002106F1140005F003FEA8F81E -:106EB000000002463B462946504603F0B8F8C9F8A0 -:106EC000000008B9A41C3C600020E5E71320E3E7BC -:106ED000F0B41446DDE904528DB1002314B1022C44 -:106EE00009D101E0012306E00D7CEE0703D025F077 -:106EF000010501230D742146F0BC03F02EBF1A805A -:106F0000F0BC70472DE9FE4F91461A881C468A4610 -:106F10008046FAB102AB494603F089F8050019D062 -:106F20004046A61C278809F0B5FE324607262946AA -:106F30003B46009609F074FA20882346CDE90050BC -:106F40004A4651464046FFF7C3FF002020800120FB -:106F5000BDE8FE8F0020FBE72DE9F04786B09146A3 -:106F6000DDE90E460F46824603AA05A904A8109D36 -:106F70008DE807009846324621465046FFF77BFFD2 -:106F8000049909B1012200E000222A70002817D1DB -:106F9000F84A03AB1060059A009104F11400CDE9A2 -:106FA00001204A463946504606F048F990B1082873 -:106FB0000ED2DFE800F00407040D0D090B0B0020D2 -:106FC00006B069E71120FBE70720F9E70820F7E79B -:106FD0000320F5E7BDF80C100498CDE90001434605 -:106FE000324621465046FFF773FFE8E72DE9F043AC -:106FF00089B00D46DDE9108781461C4616461421EE -:1070000003A81AF012FE012002218DF810108DF84D -:107010000C008DF81170ADF8146064B1A278D2073D -:1070200009D08DF81600E088ADF81A00A088ADF8F8 -:107030001800A068079008A80095CDE90110424605 -:1070400003A948466B68FFF787FF09B0BDE8F083E6 -:10705000F0B58BB0002406460694079407270894E1 -:1070600005A80994019400970294CDE903400D46C8 -:1070700010232246304606F0EBFE78B90AA806A98E -:10708000019400970294CDE90310BDF8143000225A -:107090002946304606F0B2FC002801D0FFF759FD22 -:1070A0000BB0F0BD06F052BB2DE9FC410C4680460A -:1070B000002602F07AF9054620780D287ED2DFE816 -:1070C00000F0BC0713B325BD49496383AF959B000E -:1070D000A848006820B1417841F010014170ADE04E -:1070E000404602F092F9A9E00421404609F0B6FCBE -:1070F000070000D1FFDF07F11401404605F06EFCE8 -:10710000A5BB13214046FDF787FB97E004214046CD -:1071100009F0A4FC070000D1FFDFE088ADF8000013 -:107120000020B8819DF80000010704D5C00602D5F3 -:10713000A088B88105E09DF8010040067ED5A088B2 -:10714000F88105B9FFDF22462946404601F068FC78 -:10715000022673E0E188ADF800109DF801100906E1 -:107160000FD5072803D006280AD00AE024E004211E -:10717000404609F073FC060000D1FFDFA088F081D3 -:107180000226CDB9FFDF17E00421404609F066FC76 -:10719000070000D1FFDF07F1140006F00EFB90F0AE -:1071A000010F02D1E079000648D5387C022640F074 -:1071B0000200387405B9FFDF224600E03DE02946B1 -:1071C000404601F02DFC39E00421404609F046FC20 -:1071D000017C002D01F00206C1F340016171017CC8 -:1071E00021F002010174E7D1FFDFE5E7022601216A -:1071F000404602F045F921E00421404609F02EFC0A -:107200000546606800902089ADF8040001226946B7 -:10721000404602F056F9287C20F0020028740DE068 -:10722000002DC9D1FFDFC7E7022600214046FBF74A -:10723000CDF8002DC0D1FFDFBEE7FFDF3046BDE84F -:10724000FC813EB50C0009D001466B4601AA002026 -:1072500006F080FE20B1FFF77CFC3EBD10203EBD55 -:1072600000202080A0709DF8050002A900F0070012 -:10727000FEF798FE50B99DF8080020709DF80500B3 -:1072800002A9C0F3C200FEF78DFE08B103203EBD87 -:107290009DF8080060709DF80500C109A07861F3B1 -:1072A0000410A0709DF80510890961F3C300A07057 -:1072B0009DF80410890601D5022100E0012161F347 -:1072C00042009DF8001061F30000A07000203EBD58 -:1072D00070B5144606460D4651EA040005D075B156 -:1072E00008460DF001F878B901E0072070BD294685 -:1072F000304606F090FE10B1BDE8704029E454B16C -:1073000020460CF0F1FF08B1102070BD2146304638 -:10731000BDE8704095E7002070BD2DE9FC5F0C468C -:1073200090460546002701780822007A3E46B2EBD7 -:10733000111F7DD104F10A0100910A31821E4FF024 -:10734000020A04F1080B0191092A72D2DFE802F067 -:10735000EDE005F528287BAACE006888042109F015 -:107360007DFB060000D1FFDFB08928B15227072638 -:10737000C3E000001403002051271026002C7DD00C -:107380006888A0800120A071A88900220099FFF7D9 -:107390009FFF002873D1A8892081288AE081D1E04D -:1073A000B5F81290072824D1E87B000621D5512793 -:1073B00009F1140086B2002CE1D0A88900220099BE -:1073C000FFF786FF00285AD16888A08084F806A0BD -:1073D000A88920810120A073288A2082A4F8129015 -:1073E000A88A009068884B46A969019A01F0F5FACD -:1073F000A8E0502709F1120086B2002C3ED0A889DF -:1074000000225946FFF764FF002838D16888A08021 -:10741000A889E080287A072813D002202073288AC0 -:10742000E081E87BC0096073A4F81090A88A01E0AD -:1074300085E082E0009068884B4604F11202A96959 -:10744000D4E70120EAE7B5F81290512709F11400BA -:1074500086B2002C66D06888042109F0FFFA8346C2 -:107460006888A080A88900220099FFF731FF0028D2 -:107470006ED184F806A0A889208101E052E067E07F -:107480000420A073288A2082A4F81290A88A009071 -:1074900068884B46A969019A01F09FFAA989ABF85F -:1074A0000E104FE06888FBF725FE07466888042128 -:1074B00009F0D4FA064607B9FFDF06B9FFDF687B9B -:1074C000C00702D05127142601E0502712264CB3E2 -:1074D0006888A080502F06D084F806A0287B5946E3 -:1074E00001F08BFA2EE0287BA11DF9E7FE49A8895F -:1074F0004989814205D1542706269CB16888A0801D -:1075000020E053270BE06888A080A889E08019E07C -:107510006888042109F0A2FA00B9FFDF5527082680 -:10752000002CF0D1A8F8006011E056270726002CA7 -:10753000F8D06888A080002013E0FFDF02E0012877 -:1075400008D0FFDFA8F800600CB12780668000201B -:10755000BDE8FC9F57270726002CE3D06888A08051 -:10756000687AA071EEE7401D20F0030009B14143A5 -:10757000091D01EB4000704713B5DB4A0020107174 -:10758000009848B10024684609F06BF8002C02D13D -:10759000D64A009911601CBD01240020F4E770B5A3 -:1075A0000D46064686B014465C2128461AF03DFB7F -:1075B00004B9FFDFA0786874A2782188284601F01A -:1075C00046FA0020A881E881228805F1140130469E -:1075D00005F0E9F96A460121304606F086FB19E01C -:1075E0009DF80300000715D5BDF806103046FFF7DB -:1075F0002FFD9DF80300BDF8061040F010008DF837 -:107600000300BDF80300ADF81400FF233046059ACF -:1076100006F0CCFC684606F074FB0028E0D006B00B -:1076200070BD10B50C4601F1140005F0F3F90146E8 -:10763000627C2046BDE8104001F03EBA70B50546B8 -:10764000042109F00BFA040000D1FFDF04F114015A -:107650000C46284605F0C2F921462846BDE8704090 -:1076600005F0C3B970B58AB00C460646FBF742FD7B -:10767000050014D02878222827D30CB1A08890B117 -:1076800001208DF80C0003208DF8100000208DF8EB -:10769000110054B1A088ADF81800206807E043F24B -:1076A00002000AB070BD0920FBE7ADF81800059094 -:1076B0000421304609F0D2F9040000D1FFDF04F1C3 -:1076C000140005F0BEF9C00601D40820E9E701F076 -:1076D0006CFE60B108A802210094CDE9011095F874 -:1076E000232003A930466368FFF736FCD9E7112051 -:1076F000D7E72DE9F04FB2F802A0834689B01546CE -:1077000089465046FBF7F6FC07460421504609F02F -:10771000A5F90026044605964FF002080696ADF836 -:107720001C6007B9FFDF04B9FFDF4146504603F094 -:107730007CFE60B907AA06A905A88DE807004246A5 -:10774000214650466368FFF796FB00B1FFDF6648AD -:1077500007AB0660DDE9051204F11400CDF80090D6 -:10776000CDE90320CDE9013197F823205946504651 -:107770006B6805F0AFF906000AD0022E04D0032E84 -:1077800014D0042E00D0FFDF09B03046BDE8F08FE2 -:10779000BDF81C000028F7D00599CDE9001042463D -:1077A000214650466368FFF793FBEDE7687840F0A9 -:1077B00008006870E8E72DE9F04F9BB004464FF0F1 -:1077C00000084948ADF85480ADF83080ADF85080DD -:1077D000A0F80880ADF81480ADF81880ADF82080CE -:1077E000ADF81C80007916460D464746012808D0A2 -:1077F000022806D0032804D0042802D008201BB099 -:10780000C4E720460CF02CFDD0BB28460CF028FD28 -:10781000B0BB60680CF071FD90BB606848B16089D6 -:107820002189884202D8B1F5007F01D90C20E6E712 -:1078300080460BAA06A92846FFF709FA0028DED1E0 -:1078400068688078C0F34100022808D19DF81900CB -:1078500010F0380F03D028690CF046FD80B905A957 -:107860002069FFF7ACF90028C9D1206950B16078D0 -:1078700080079DF8150000F0380002D5C0B301E084 -:1078800011E0A8BB9DF8140080060ED59DF81500E8 -:1078900010F0380F03D060680CF026FD18B960684E -:1078A0000CF02BFD08B11020A9E707A96069FFF7CC -:1078B00086F90028A3D1606940B19DF81D0000F051 -:1078C000070101293FD110F0380F3CD008A9A06969 -:1078D000FFF775F9002892D19DF81C00800632D47C -:1078E0009DF82000800604E014030020140000200E -:1078F00029E028D4A06940B19DF8210000F00701DB -:10790000012920D110F0380F1DD0E06818B100789F -:10791000C8B11C2817D20EAA611C2046FFF7BEF979 -:107920000120B94660F30F27BA4607468DF84E008E -:1079300042F60300ADF84C000DF13B0217A9286890 -:107940000AF009FD08B1072059E79DF85C0016A967 -:10795000CDF80090C01CCDE9019100F0FF0B002391 -:107960000BF20122514613A806F002F9F0BBBDF854 -:1079700058000990FE482A8929690092CDE9011032 -:107980006B89BDF82C202868069906F0F1F80100F3 -:107990007ED120784FF0020AC10601D480062BD593 -:1079A000ADF80C90606950B907A906A8FFF7A7F9D0 -:1079B0009DF81D0020F00700401C8DF81D009DF86B -:1079C0001C008DF84E7040F0C8008DF81C0042F687 -:1079D0000210ADF84C000CA903AACDF800A0CDE927 -:1079E0000121002340F2032213A800E01EE00799C2 -:1079F00006F0BEF801004BD1DD484D4608385B4625 -:107A00000089ADF839000EA8CDE90290CDF80490B8 -:107A1000CDF810904FF007090022CDF80090BDF886 -:107A200058104FF6FF7005F0E9FF10B1FFF791F81D -:107A3000E5E69DF83800000625D52946012060F3CB -:107A40000F218DF84E704FF42450ADF84C00ADF876 -:107A5000105062789DF81000002362F300008DF84A -:107A600010006278CDF800A0520862F341008DF852 -:107A7000100004AACDE9012540F2032213A806F064 -:107A800077F8010004D1606888B32069A8B900E0E4 -:107A900086E005A906A8FFF732F96078800706D4CA -:107AA0009DF8150020F038008DF8150005E09DF8D0 -:107AB000140040F040008DF814008DF84E7042F62E -:107AC0000110ADF84C00208940F20121B0FBF1F229 -:107AD00001FB1202606814ABCDF80080CDE9010310 -:107AE000002313A8059906F043F8010058D1207827 -:107AF000C00729D0ADF80C50A06950B908A906A854 -:107B0000FFF7FDF89DF8210020F00700401C8DF8DC -:107B100021009DF820008DF84E7040F040008DF857 -:107B2000200042F60310ADF84C0015A903AACDF8C9 -:107B300000A0CDE90121002340F2032213A80899F7 -:107B400006F016F801002BD1E06868B32946012041 -:107B500060F30F218DF84E7042F60410ADF84C0022 -:107B6000E068002302788DF8602040788DF861008D -:107B7000E06818AA4088ADF86200E06800798DF8E6 -:107B80006400E068C088ADF86500CDF80090CDE9EC -:107B900001254FF4027213A805F0EAFF010003D09B -:107BA000099800F0B5FF2AE67148032108380171F1 -:107BB00056B100893080BDF850007080BDF83000AB -:107BC000B080BDF85400F080002018E670B50125A3 -:107BD0008AB016460B46012802D0022816D104E0CE -:107BE0008DF80E504FF4205003E08DF80E5042F601 -:107BF0000100ADF80C005BB10024601C60F30F24A1 -:107C000004AA08A918460AF0A6FB18B1072048E5FF -:107C1000102046E504A99DF820205548CDE9002113 -:107C2000801E02900023214603A802F2012205F0E3 -:107C30009FFF10B1FEF78DFF33E54D4808380EB1B8 -:107C4000C1883180057100202BE5F0B593B007465F -:107C500001268DF83E6041F60100ADF83C0012AA05 -:107C60000FA93046FFF7B2FF002848D1404C00254D -:107C7000083CE7B31C2102A819F0D7FF9DF80800C3 -:107C80008DF83E6040F020008DF8080042F6052097 -:107C9000ADF83C000E959DF83A00119520F00600D5 -:107CA000801C8DF83A009DF838006A4620F0FF00ED -:107CB0008DF838009DF8390009A920F0FF008DF8F3 -:107CC00039000420ADF82C00ADF830000EA80A9061 -:107CD00011A80D900FA80990ADF82E5002A8FFF73B -:107CE0006AFD00280BD1BDF80000608100E008E0CB -:107CF000BDF80400A081401CE0812571002013B074 -:107D0000F0BD6581A581BDF84800F4E72DE9F74F86 -:107D10001749A0B00024083917940A79A146012A0E -:107D200004D0022A02D0082023B02FE5CA8882425C -:107D300001D00620F8E721988A46824201D1072027 -:107D4000F2E701202146ADF848004FF6FF7860F3D6 -:107D50000F21ADF84A808DF86E0042F6020B0691B5 -:107D60008DF87240ADF86CB0ADF870401CA901E020 -:107D70001C0300201391ADF8508012A805F0E5FF18 -:107D800000252E462F460DAB072212A9404605F0CE -:107D9000DFFF78B182285DD195B38EB3ADF8645022 -:107DA000ADF866609DF85E008DF8144019AC0128AE -:107DB00064D06BE09DF83A001FB3012859D1BDF89B -:107DC000381059451FD118A809A901940294CDE98A -:107DD000031007200090BDF8361010230022404603 -:107DE00006F036F8B0BBBDF86000042801D00628C4 -:107DF0004AD1BDF82410219881423AD10F2093E74F -:107E00003AE0012835D1BDF83800B0F5205F03D045 -:107E100042F6010188422CD1BAF80600BDF83610AE -:107E2000884201D1012700E0002705B19EB12198C9 -:107E300081421ED118A809AA01940294CDE9032019 -:107E4000072000900D4610230022404606F000F85F -:107E500000B902E02DE04E460BE0BDF860000228BC -:107E600001D0102810D1C0B217AA09A90AF054FAFB -:107E700050B9BDF8369086E7052055E705A917A843 -:107E8000221D0AF068FA08B103204DE79DF814009E -:107E90000023001DC2B28DF8142022980092CDE973 -:107EA00001401BA8069905F063FE10B902228AF86A -:107EB0000420FEF74EFE37E710B50B46401E88B093 -:107EC00084B205AA00211846FEF7E8FE00200DF155 -:107ED000080C06AA05A901908CE80700072000906D -:107EE0000123002221464FF6FF7005F087FD04466E -:107EF000BDF81800012800D0FFDF2046FEF729FE5C -:107F000008B010BDF0B5F94F044687B038790E4679 -:107F1000032804D0042802D0082007B0F0BD04AA2A -:107F200003A92046FEF793FE0500F6D1606880782D -:107F3000C0F3410002280AD19DF80D0010F0380F5F -:107F400005D020690CF0D0F908B11020E5E72089B0 -:107F500005AA21698DE807006389BDF81020206813 -:107F6000039905F005FE10B1FEF7F3FDD5E716B154 -:107F7000BDF814003080042038712846CDE7F8B5EC -:107F80000C0006460BD001464FF6FF7500236A46EB -:107F9000284605F0DFFF20B1FEF7DBFDF8BD10201D -:107FA000F8BD69462046FEF70AFE0028F8D1A07801 -:107FB000314600F001032846009A05F0F7FFEBE791 -:107FC00030B587B0144600220DF1080C05AD0192C2 -:107FD0008CE82C00072200920A46014623884FF6BF -:107FE000FF7005F00BFDBDF814102180FEF7B1FD08 -:107FF00007B030BD70B50D46042108F02FFD040018 -:1080000000D1FFDF294604F11400BDE8704004F000 -:1080100011BD70B50D46042108F020FD040000D10B -:10802000FFDF294604F11400BDE8704004F025BDCF -:1080300070B50D46042108F011FD040000D1FFDFEA -:10804000294604F11400BDE8704004F03DBD70B550 -:108050000546042108F002FD040000D1FFDF21469F -:1080600028462368BDE870400122FEF74BBF70B57B -:108070000646042108F0F2FC040000D1FFDF04F101 -:10808000140004F0C7FC401D20F0030511E0011DA1 -:1080900000880022431821463046FEF733FF0028AF -:1080A0000BD0607CABB2684382B2A068011D08F0BF -:1080B00078FBA06841880029E9D170BD70B50546FC -:1080C000042108F0CBFC040000D1FFDF2146284644 -:1080D0006368BDE870400222FEF714BF70B50E461B -:1080E000054601F062F9040000D1FFDF0120207293 -:1080F00066726580207820F00F00001D20F0F000EF -:1081000040302070BDE8704001F052B910B504460F -:10811000012900D0FFDF2046BDE810400121FAF719 -:1081200055B92DE9F04F97B04FF0000A0C00834687 -:10813000ADF818A0D04619D0E06830B1A068A8B159 -:108140000188ADF81810A0F800A05846FAF7D2FF41 -:10815000070043F2020967D03878222862D304214D -:10816000584608F07BFC050005D103E0102017B04D -:10817000BDE8F08FFFDF05F1140004F04BFC401D5B -:1081800020F00306A078012803D0022801D00720A0 -:10819000EDE7208878B1401C81B209AA584605F065 -:1081A000A4FD09A805F0ADFD9DF82E204FF4505117 -:1081B000012A0DD102E043F20300D8E7BDF82C20DC -:1081C000A2F52453023B03D1822801D0A0B901E0DB -:1081D0000846CCE7E068B0B1CDE902A0072006AAC6 -:1081E000CDF804A000900492A2882188BDF8183030 -:1081F000584605F003FC10B1FEF7ABFCB7E7A168E9 -:10820000BDF8180008809DF82700C00602D543F28B -:108210000140ACE70D9838B1A1780078012905D06C -:1082200080071AD40820A2E74846A0E7C007F9D083 -:1082300002208DF83C00A8684FF00009A0B1697CCD -:108240004288714391420FD98AB2B3B2011D08F03E -:108250005EFA8046A0F800A006E003208DF83C00FE -:10826000D5F800804FF001099DF8280010F0380F74 -:1082700000D1FFDF9DF828001D49C0F3C20008446B -:1082800097F8231010F8010C884201D90F206EE7EF -:108290002088ADF8400014A90095CDE9019143462E -:1082A00007220FA95846FEF757FE002885D19DF8F2 -:1082B000500050B9A078012807D1687CB3B2704350 -:1082C00082B2A868011D08F036FA00204FE770B5A9 -:1082D000064615460C460846FEF7FAFB002809D16B -:1082E0002A4621463046BDE870406FE41403002062 -:1082F0002E20020070BD09E570B51E4614460D0023 -:1083000009D044B1616831B138B1F849C9888142B6 -:1083100003D0072070BD102070BD2068FEF7D8FB89 -:108320000028F9D1324621462846BDE87040FFF7C3 -:1083300042BA70B515460C0006D038B1EB49098930 -:10834000814203D0072070BD102070BD2068FEF769 -:10835000BFFB0028F9D129462046BDE87040D1E591 -:1083600070B5064686B00D46144610460BF09EFFCB -:10837000D0BB60680BF0C1FFB0BBA6F57F40FF38F3 -:1083800003D03046FAF7B6FE80B128466946FEF7BC -:10839000D8FC00280CD19DF810100F2008293CD2E1 -:1083A000DFE801F008060606060A0A0843F20200A2 -:1083B00006B070BD0320FBE79DF80210012908D12B -:1083C000BDF80010B1F5C05FF2D06FF4C052D142D9 -:1083D000EED09DF8061001290DD1BDF80410A1F5CD -:1083E0002851062907D200E028E0DFE801F0030366 -:1083F00004030303DCE79DF80A1001290ED1BDF840 -:108400000810B1F5245FD3D0A1F524510239CFD0A3 -:108410000129CDD0022901D1CAE7FFDF606878B910 -:10842000002305AA2946304605F094FD10B1FEF759 -:1084300090FBBDE79DF81400800601D41020B7E73B -:108440006188224628466368FFF7BAFDB0E72DE948 -:10845000F043814687B08846144610460BF026FF4D -:1084600018B1102007B0BDE8F083002306AA4146EA -:10847000484605F06FFD10B1FEF76BFBF2E79DF883 -:108480001800C00602D543F20140EBE7002507279C -:1084900005A8019500970295CDE9035062884FF633 -:1084A000FF734146484605F0D3FC060013D16068CF -:1084B0000BF0FCFE60B960680195CDE902500097B1 -:1084C0000495238862884146484605F0C1FC06466B -:1084D000BDF8140020803046CEE739B1834B0A88BE -:1084E0009B899A4202D843F20300704719E610B5FF -:1084F00086B07E4C0423ADF81430638943B1A4895F -:108500008C4201D2914205D943F2030006B010BD5E -:108510000620FBE7ADF81010002100910191ADF8A5 -:10852000003002218DF8021005A9029104A90391DF -:10853000ADF812206946FFF7F4FDE7E72DE9FC47A7 -:1085400081460E4608460BF08BFE88BB4846FAF77C -:10855000D1FD5FEA00080AD098F80000222829D34C -:108560000421484608F07AFA070005D103E043F2F7 -:108570000200BDE8FC87FFDF07F1140004F061FA98 -:1085800005463078012803D0022804D00720F0E700 -:10859000A8070FD502E015F0340F0BD0B079341DC9 -:1085A000C00709D0E08838B1A0680BF059FE18B1B7 -:1085B0001020DEE70820DCE732782088002628B388 -:1085C000A0F201130721112B18D20CD2DFE803F01F -:1085D0000B090D0B1D0B121D100B0B1D1D1D1D0B73 -:1085E0001D00022A11D10846C3E7012AFBD00CE086 -:1085F000EA0600E0AA06002AF5DA06E0A0F5C07255 -:108600001F2A02D97D3A022AEDD8C6B200F0CDFE6B -:1086100050B198F82300CDE90006FA89234639467F -:108620004846FEF7E3FCA4E71120A2E72DE9F04F4E -:108630008BB01F4615460C4683460026FAF75AFDB6 -:1086400028B10078222805D208200BB090E543F22B -:108650000200FAE7B80801D00720F6E7032F00D19F -:1086600000274FF6FF79CCB1022D72D320460BF0D4 -:1086700044FE30B904EB0508A8F101000BF03DFE03 -:1086800008B11020E1E7AD1EAAB22146484605F028 -:108690005AFD38F8021C88425BD1ADB21349B807C5 -:1086A00002D58889401C00E001201FFA80F8F807F5 -:1086B00001D08F8900E04F4605AA4146584605F093 -:1086C00014FB4FF0070A4FF00009D4B3204608E02E -:1086D000408810283DD8361D304486B2AE4238D28C -:1086E000A01902884245F3D353E000001403002090 -:1086F0009DF8170002074CD594B304EB0608361D0D -:10870000B8F80230B6B2102B23D89A19AA4220D852 -:10871000B8F8002091421CD1C0061CD5CDE900A9B3 -:108720000DF1080C0AAAA11948468CE80700B8F810 -:1087300000100022584605F061F920B1FEF709FA51 -:1087400083E726E005E0B8F80200BDF8281088426B -:1087500001D00B2079E7B8F80200304486B207E078 -:10876000FFE7C00604D55846FEF772FC002889D101 -:108770009DF81700BDF81A1020F010008DF81700B2 -:10878000BDF81700ADF80000FF235846009A05F029 -:108790000DFC05A805F0B5FA18B9BDF81A10B942D4 -:1087A000A6D90421584608F059F9040000D1FFDF8A -:1087B000A2895AB1CDE900A94D4600232146584669 -:1087C000FEF714FC0028BBD1A5813EE700203CE762 -:1087D0002DE9FF4F8BB01E4617000D464FF00004E9 -:1087E00012D0B00802D007200FB0C1E4032E00D190 -:1087F00000265DB108460BF077FD28B93888691E60 -:1088000008440BF071FD08B11020EDE7C64AB0072F -:1088100001D5D18900E00121F0074FF6FF7802D0A1 -:10882000D089401E00E0404686B206AA0B9805F0AB -:108830005CFA4FF000094FF0070B0DF1140A38E015 -:108840009DF81B00000734D5CDF80490CDF800B09A -:10885000CDF80890CDE9039A434600220B9805F025 -:10886000F7FA60BB05B3BDF814103A882144281903 -:10887000091D8A4230D3BDF81E2020F8022BBDF816 -:10888000142020F8022BCDE900B9CDE90290CDF8F3 -:1088900010A0BDF81E10BDF8143000220B9805F092 -:1088A000D7FA08B103209FE7BDF814002044001D4B -:1088B00084B206A805F025FA20B1822806D0FEF77A -:1088C00048F991E7BDF81E10B142B9D934B17DB174 -:1088D0003888A11C884203D20C2085E7052083E755 -:1088E00022462946404605F02EFC01462819018003 -:1088F000A41C3C80002077E710B504460BF0D6FCA2 -:1089000008B1102010BD8848C0892080002010BD0B -:10891000F0B58BB00D460646142103A819F085F971 -:1089200001208DF80C008DF8100000208DF811004A -:10893000ADF814503046FAF7DDFB48B10078222834 -:1089400012D30421304608F089F8040005D103E071 -:1089500043F202000BB0F0BDFFDF04F11400074644 -:1089600004F06FF8400601D40820F3E7207C0221D0 -:1089700040F00100207409A80094CDE901100722FD -:1089800003A930466368FEF7E7FA20B1217C21F0A5 -:1089900001012174DEE729463046F9F708FD08A9F0 -:1089A000384604F03DF800B1FFDFBDF82040172C39 -:1089B00001D2172000E02046A84201D92C4602E04F -:1089C000172C00D2172421463046FFF722FB214600 -:1089D0003046F9F708FA0020BCE7F8B51C46154602 -:1089E0000E46069F08F044F92346FF1DBCB23146EF -:1089F0002A46009407F0DBFCF8BD70B50C4605462E -:108A00000E21204619F0EFF8002020802DB1012D15 -:108A100001D0FFDF70BD062000E00520A07170BD11 -:108A200010B548800878134620F00F00001D20F094 -:108A3000F00080300C4608701422194604F108003A -:108A400019F09FF800F0B4FC3748046010BD2DE920 -:108A5000F047DFF8D890491D064621F0030117467C -:108A60000C46D9F8000007F01AFE050000D1FFDF20 -:108A70004FF000083560A5F800802146D9F80000C5 -:108A800007F00DFE050000D1FFDF7560A5F800803E -:108A90007FB104FB07F1091D0BD0D9F8000007F0E6 -:108AA000FEFD040000D1FFDFB460C4F80080BDE823 -:108AB000F087C6F80880FAE72DE9F0411746491D0E -:108AC00021F00302194D064601681446286807F094 -:108AD00011FE22467168286807F00CFE3FB104FBC6 -:108AE00007F2121D03D0B168286807F003FE0420C6 -:108AF00007F05EFF0446042007F062FF201A0128F9 -:108B000004D12868BDE8F04107F0BEBDBDE8F081A2 -:108B100010B50C4605F0B5F800B1FFDF2046BDE802 -:108B20001040FEF716B800001403002014000020C7 -:108B300010B50C460246817B808819B1518981426B -:108B400000D908462080D18800F0C5FF032800D353 -:108B50000320C1B22088BDE8104000F0B1BF10B5BD -:108B60000C460246817B808819B11189814200D967 -:108B700008462080D18800F0AEFF022800D30220F2 -:108B8000C1B2208800F09CFF401CC0B210BD2DE98E -:108B9000F04F0C00F84999B08146D1E90201CDE9C6 -:108BA0000C0109F10300F54E20F003010091357E20 -:108BB00005F1010504D1E8B209F054FB00B1FFDF73 -:108BC00000984FF0000B00EB0510C01C20F00301D3 -:108BD00000915CB9707A327A81F800B01044C2B268 -:108BE000B08B80B204F0D5FE00B1FFDF0098F169D0 -:108BF000084400902146684600F02CFF0098C01CF5 -:108C000020F003000090737A327AB17A04B1002028 -:108C100007F016FE0099084400902146684600F0CF -:108C20006EFF00273D46B24696F801800CE02846CC -:108C300000F0F3FE064681788088F9F76EF97178C6 -:108C40006D1C00FB0177EDB24545F0D10098C01CCA -:108C500020F00300009004B100203946F9F768F9CC -:108C600000990027084400903D469AF801800CE0E6 -:108C7000284600F0D2FE0646C1788088FEF773FCD5 -:108C800071786D1C00FB0177EDB24545F0D100987D -:108C9000C01C20F00300009004B100203946FEF70C -:108CA0006BFC00994FF000080844009045469AF884 -:108CB00001700EE0284600F0B0FE0646807B30B121 -:108CC00006F1080001F0F9FE727800FB02886D1CC5 -:108CD000EDB2BD42EED10098C01C20F00300009020 -:108CE00004B10020414601F0ECFE00990844C01D8B -:108CF00020F007000090E4BBA24AA1491160111DB9 -:108D0000401E086001222C219F4807F062FCFAF700 -:108D10002EF99E484178806805F09CFB42208DF832 -:108D200004009A480C30C0788DF8060010B1012874 -:108D300004D005E001208DF8060001E08DF806B0B2 -:108D400001A806F0C5FE10B10EA805F042FC0021F6 -:108D50001E22084603F03CF8FBF778F987480CAA76 -:108D600000210C30F8F706FB00B1FFDF9AF819007C -:108D700000E015E0FEF769FF00B1FFDF7F484FF428 -:108D8000F671443018F051FF7C480421443080F8DB -:108D9000E91180F8EA11062180F8EB110321017135 -:108DA000009919B0A1EB0900BDE8F08F70B5734CC4 -:108DB00006464434207804EB4015E078083590B935 -:108DC000A01990F8E80100280ED0A0780F2800D351 -:108DD000FFDF2021284618F028FF687866F302009C -:108DE00068700120E070284670BD2DE9F04105460D -:108DF0000C4600270078052190463E46B1EB101F37 -:108E000000D0FFDF287A58B101280FD0FFDF00BF64 -:108E1000A8F800600CB1278066800020BDE8F081D2 -:108E20000127092674B16888A08008E0022714266B -:108E300044B16888A0802869E060A88A2082287BE5 -:108E40002072E5E7A8F80060E7E710B54F4C6068CE -:108E5000C11D21F00701814200D0FFDF47480121F9 -:108E60000022017042700172032343728172027307 -:108E7000052282821F22C282417345A202610A2218 -:108E8000027641764FF4B061C1616168416010BD06 -:108E900030B53E4C1568636810339D4202D2042001 -:108EA000136030BD354B5D785A6802EB05121070C7 -:108EB00051700320D080172090800120D0709070D6 -:108EC000002090735878401C5870606810306060C3 -:108ED000002030BD70B5064628480024457807E0DC -:108EE000204600F09AFD0178B14204D0641CE4B23F -:108EF000AC42F5D1002070BDF7B5064608780C46A7 -:108F000008B3FFF7E7FF0546202E08D0232E17D021 -:108F1000212E41D0222E3FD0242E2BD114E000F060 -:108F200087FD0DB1697800E00021401A81B2A07878 -:108F30000144FF291ED830B1A08802282CD219E0A4 -:108F40006088172828D215E0227A2AB36188172969 -:108F500010D3A08817280DD3A3795BB1E3794BB167 -:108F6000402A07D84FF6FB72914201D8904213D99C -:108F70000420FEBD0720FEBD342002003004002086 -:108F80000000002000060240600600201C000020B7 -:108F90006E5246357800000065B9207802AA01219A -:108FA000FFF776FF0028E6D12078FFF793FF050052 -:108FB00000D1FFDF203E052E18D2DFE806F0030BBC -:108FC0000E081100A0786870A088E8800FE0608823 -:108FD000A8800CE0A078A87009E0A078E87006E00E -:108FE00054F8020FA8606068E86000E0FFDF00202E -:108FF000C1E700B597B053218DF8001000780BA998 -:1090000000F001008DF80200684605F023F817B063 -:1090100000BD00B5017897B001F001018DF8021094 -:10902000417801F001018DF803100178C1F340018E -:109030008DF804104178C1F340018DF805100178D6 -:1090400089088DF80610417889088DF80710817815 -:109050008DF80810C1788DF8091000798DF80A0094 -:109060004D208DF800000BA9684604F0F3FFCEE711 -:109070002DE9F04FDFF8F883FE4C97B000271BE096 -:10908000012000F07FFD0120FFF790FE0546FA4821 -:1090900007F0C8FA686000B9FFDF686805F027F8D4 -:1090A000A0B12846FAF7CEFA284600F071FD18B9AB -:1090B000F148696807F0BFFA94F9E9010428DFDA9A -:1090C000022007F075FC06460025AAE0EA48696818 -:1090D00007F0B1FAF4E7B8F802104046491C89B22B -:1090E000A8F80210B14201D3002141800221B8F852 -:1090F000020007F0B3FC00286BD0B8F8020054213E -:109100008DF80010ADF802000BA9684604F0A2FF2C -:1091100000B1FFDF9DF8300010F0010F0FD0B8F85C -:10912000020007F0B7FD5FEA000900D1FFDF484603 -:1091300006F0A3FF18B1B8F8020002F065F9B8F81C -:10914000020007F095FD5FEA000900D1FFDF484605 -:1091500006F08CFFE8BB0321B8F8020007F07EFCA4 -:109160005FEA000B48D1FFDF46E000BFDBF81000EC -:1091700010B10078FF2849D0022000F003FD022042 -:10918000FFF714FE8246484607F0A2F8CAF804002A -:1091900000B9FFDFDAF8040007F07CF90021009045 -:1091A0000170B8F802105046AAF8021001F032FE21 -:1091B000484607F071F900B9FFDF504600F0E8FCBF -:1091C00018B99AF80100000704D50098CBF81000F0 -:1091D00012E024E0DBF8100038B10178491C11F0EE -:1091E000FF01017008D1FFDF06E00022114648466A -:1091F00000F011FC00B9FFDF94F9EA01022805DB59 -:10920000B8F8020001F0CAFD0028AFD194F9E901D5 -:10921000042804DB484607F0B5F900B101276D1CAE -:10922000EDB2B54204D294F9EA010228BFF653AF79 -:10923000002F7FF423AF17B00320BDE8F04F00F0FC -:10924000A1BC10B58A4CA0600868E060AFF2DF10E6 -:1092500002F031FD607010BD864800214438017075 -:109260008348017085494160704730B505464FF02D -:1092700080500C46D0F8A41097B0491C05D1D0F806 -:10928000A810C9430904090C08D050F8A01F01F028 -:10929000010129704168216080680EE02B208DF863 -:1092A00000000BA9684604F0D5FE00B1FFDF0120E5 -:1092B00028700C982060BDF83400A0802878002821 -:1092C00003D0607940F0C000607117B030BDF0B5D8 -:1092D0004FF080540746D4F8800097B00D462B26F7 -:1092E000401C0BD1D4F88400401C07D1D4F888006E -:1092F000401C03D1D4F88C00401C0BD0D4F8800063 -:109300003860D4F884007860D4F88800B860D4F865 -:109310008C0016E08DF82C6069460BA804F09AFECC -:1093200000B1FFDF01983860029878608DF82C60FA -:1093300069460BA804F08EFE00B1FFDF0198B8600B -:109340000298F860D4F89000401C0BD1D4F8940037 -:10935000401C07D1D4F89800401C03D1D4F89C00DD -:10936000401C08D054F8900F286060686860A068BE -:10937000A860E06816E08DF800600BA9684604F06C -:1093800069FE00B1FFDF0C9828600D9868608DF8C9 -:1093900000600BA9684604F05DFE00B1FFDF0C9889 -:1093A000A8600D98E86017B0F0BD32480079FDE480 -:1093B00070B5304CE07830B3207804EB4010407A40 -:1093C00000F00700204490F9E801002800DCFFDFEE -:1093D0002078002504EB4010407A00F007000119C6 -:1093E00091F8E801401E81F8E8012078401CC0B2E5 -:1093F00020700F2800D12570A078401CA0700AF0C2 -:109400001BFBE57070BDFFDF70BD3EB50546032157 -:1094100007F024FB0446284607F02AFC054604B959 -:10942000FFDF206918B10078FF2800D1FFDF01AA13 -:109430006946284600F0EFFA60B9FFDF0AE0002233 -:1094400002A9284600F0E7FA00B9FFDF9DF80800FE -:1094500000B1FFDF9DF80000411E8DF80010EED234 -:1094600020690199884201D1002020613EBD0000A1 -:109470001C000020740400206006002068130020F7 -:1094800070B50546A0F57F400C46FF3800D1FFDFE0 -:10949000012C01D0FFDF70BDFFF787FF040000D172 -:1094A000FFDF207820F00F00401D20F0F00050304A -:1094B000207065800020207201202073BDE870407C -:1094C00076E72DE9F04116460D460746FFF76DFF9A -:1094D000040000D1FFDF207820F00F00401D20F0B5 -:1094E000F0005030207067800120207228682061D1 -:1094F000A888A0822673BDE8F04159E730B599B03D -:10950000FFF7E8FC040000D1FFDF0CA92046FFF7BD -:109510000FFB05460BA92046FFF721FB0146522011 -:109520008DF80000BDF830008DF80250001DADF838 -:109530000400BDF82C008DF80310001DADF80600E6 -:10954000E088ADF808000DA9684604F083FD002806 -:1095500000D0FFDF19B030BD2DE9F047DFF80094EF -:109560000546002799F8000010B10820BDE8F087F3 -:1095700028460AF09BFE08B11020F7E7F94C207846 -:1095800008B9FFF762FC607A217A0844C6B200F09D -:109590004FFAB04207D2301AC1B22A460020FFF774 -:1095A00077FC0700E2D1D9F804004E46C01C20F039 -:1095B0000300C9F8040000F05EFB716800EB0108CD -:1095C00001214046FFF7E3FA0646296840448842F5 -:1095D00002D8B6F5803F15D328600020FFF77AFC4B -:1095E00005000DD005F11300D9F8041020F0030098 -:1095F0004E46884200D0FFDF6078401E6070756084 -:109600000420B3E700214046FFF7C1FA0446A64212 -:1096100000D0FFDF04EB0801C9F8041029604FF601 -:10962000FF71A9F80210012189F8001038469DE762 -:109630002DE9F0410446CA4817460D46007810B19E -:109640000820BDE8F08108460AF00AFE08B11020A3 -:10965000F7E7C44E307808B9FFF7F7FB601E1E2805 -:1096600007D8012C3FD12878FE283CD8307600203E -:10967000E7E7A4F120001F2805D8E0B23A462946C2 -:10968000BDE8F04138E4A4F140004FF000081F2885 -:1096900021D8402C02D0412C25D117E068782978B8 -:1096A0004418A97881421ED8FF2C08D808F0BEFFC4 -:1096B00007460AF07BF9381A801EA04201DA122010 -:1096C000BFE728883081A878B07224E02846BDE83A -:1096D000F04100F085BAA4F1A0001F2803D8A02C07 -:1096E00003D0A12C06D00720ABE7287800F00100BA -:1096F000707610E029680920F829A2D38A07A0D142 -:10970000727B02F00302012A04D1F28AD73293B2AB -:109710008B4296D8F161404693E72DE9F0478146A8 -:109720000E4608460AF0C2FD48B948460AF0DCFD7C -:1097300028B909F1030020F00301494501D01020A8 -:1097400014E788484FF0000A4430817869B14178C5 -:10975000804600EB41140834378832460021204609 -:1097600000F024FA050004D027E0A6F800A00520A8 -:10977000FCE6B9F1000F24D03088B84201D90C259D -:109780001FE0607800F00705284600F0FBF908EBC1 -:109790000507324697F8E8014946401C87F8E8017A -:1097A000204607F5F47700F001FA05463878401EA8 -:1097B0003870032000F0E6F92DB10C2D01D0A6F889 -:1097C00000A02846D2E66078654F00F00701012925 -:1097D00023D002290CD0032932D0FFDF98F80110E2 -:1097E0004046491CC9B288F801100F2933D034E033 -:1097F000616821B1000702D46088FFF706FE98F87F -:10980000EA014646012802D1787802F073FA96F907 -:10981000EA010428E2DBFFDFE0E7616811B15248AA -:1098200006F009FF98F8E9014646032802D1787846 -:1098300002F060FA96F9E9010428CFDBFFDFCDE7FB -:10984000C00602D56088FFF7E0FD98F9EB01062815 -:10985000C4DBFFDFC2E780F801A08178491E817078 -:10986000617801F0070101EB080090F8E811491C4C -:1098700080F8E811A5E770B50D4604460AF0F0FC43 -:1098800018B928460AF012FD08B1102070BD29460B -:109890002046BDE8704008F01CBD70B50446154672 -:1098A0000E4608460AF0DCFC18B928460AF0FEFC11 -:1098B00008B1102070BD022C03D0102C01D009205B -:1098C00070BD2A463146204608F026FD0028F7D014 -:1098D000052070BD70B514460D4606460AF0C0FC62 -:1098E00038B928460AF0E2FC18B920460AF0FCFC18 -:1098F00008B1102070BD22462946304608F02BFDE5 -:109900000028F7D0072070BD10B596B004460AF0C5 -:10991000CDFC10B1102016B010BD0F208DF8000046 -:109920000BA9684604F096FB0028F4D19DF834009A -:109930002070BDF836006080BDF83800A08000209F -:10994000E9E770B505460C4608460AF0CDFC20B99B -:1099500074B120680AF0AAFC40B1102070BD00006C -:109960001C0000203004002060060020A08828B1E0 -:1099700021462846BDE87040FDF774BE0920EDE79A -:1099800070B504460D4608460AF06AFC30B9601E00 -:109990001E2814D828460AF063FC08B11020DDE721 -:1099A000022C01D90720D9E704B9FFDFE64800EB14 -:1099B000840050F8041C2846BDE870400847A4F114 -:1099C00020001F28EED829462046BDE87040FAF74F -:1099D0007FBA70B504460D4608460AF067FC30B9F8 -:1099E000601E1E280DD828460AF03AFC08B1102047 -:1099F000B4E7012C01D0022C01D10620AEE70720EC -:109A0000ACE7A4F120001F28F9D829462046BDE87C -:109A10007040FAF7E1BA06F0E4BA30B5CB4D04462F -:109A20006878A04200D8FFDF686800EB041030BD02 -:109A300070B5C64800252C46467807E02046FFF75B -:109A4000ECFF4078641C2844C5B2E4B2B442F5D1BE -:109A5000284683E72DE9F0410C46064600F043F91D -:109A600007463068C01C20F0030232601CBBB748B8 -:109A70003B46092120300AF0CDFA002408E0092CE9 -:109A800011D2DFE804F005070509090B05050700F9 -:109A9000AF4804E0AF4802E0AF4800E0AF480AF04A -:109AA000D9FA054600E0FFDFA54200D0FFDF641CC5 -:109AB000E4B2092CE3D3306800EB07103060C0E556 -:109AC000021D5143452900D245210844C01CB0FB6A -:109AD000F2F0C0B2704700B597B055228DF8002063 -:109AE000001DADF80200ADF804100BA9684604F0A3 -:109AF000B1FA00B1FFDFBDF8300017B000BD2DE9AD -:109B0000FC5F064691484FF000088B4647464446A6 -:109B100090F8019022E02046FFF77FFF050000D17A -:109B2000FFDF687869463844C7B22846FFF700F877 -:109B3000824601A92846FFF712F80346BDF8040043 -:109B40005246001D81B2BDF80000001D80B206F033 -:109B5000DBFF6A78641C00FB0288E4B24C45DAD172 -:109B60003068C01C20F003003060BBF1000F00D053 -:109B700000204246394606F0D5FF3168084430607F -:109B8000BDE8FC9F7149443108710020C8707047DE -:109B90006E494431CA782AB10A7801EB4211083182 -:109BA000814201D001207047002070472DE9F0412B -:109BB00006460078154600F00F0400201080601E55 -:109BC0000F46052800D3FFDF5F482A46103000EB20 -:109BD0008400394650F8043C3046BDE8F04118474F -:109BE00038B50446407800F00300012803D002286D -:109BF0000BD0072038BD606858B10AF07EFBD0B9A1 -:109C000060680AF071FB20B915E060680AF028FB73 -:109C100088B969462046FCF7A9F90028EAD160789E -:109C200000F00300022808D19DF8000028B1606808 -:109C30000AF05AFB08B1102038BD6189F8290DD807 -:109C4000208988420AD8607800F003023F48012A40 -:109C500006D1D731C26989B28A4201D2092038BD02 -:109C600094E80E0000F10C0585E80E000AB9002109 -:109C70008182002038BD2DE9F05F4FF000093348A4 -:109C8000C8464F464E464D46CB464C4690F801A03E -:109C900011E02046FFF7C1FE4178827809F1010901 -:109CA000884412FB0177C27812FB0166807B10FBAF -:109CB0000155641CE4B25445EBD10BEB890000EB79 -:109CC000C80000EB870000EB860000EBC5011F48D1 -:109CD000027A01EBC201427A807A01EBC20101EB08 -:109CE000C000BDE8F09F2DE9F047DFF86090002547 -:109CF0002C4699F8092099F8081099F801700A443F -:109D0000D6B299F80A20114401F0FF0808E0204675 -:109D1000FFF783FE817B407811FB0055641CE4B2A1 -:109D2000BC42F4D199F80800401C3044304440440F -:109D3000401C0EB1012100E0002108444419FF2C11 -:109D400000D9FFDFE0B211E434200200300400202B -:109D5000633D00008DAB0000592F00003120010051 -:109D60002DE9F041074614468846084601F02EFDCD -:109D7000064608EB88001C22796802EBC0000D182B -:109D8000688C58B14146384601F028FD0146786894 -:109D90000078C200082305F120000CE0E88CA8B18F -:109DA0004146384601F021FD014678680823407895 -:109DB000C20005F1240006F0F4FC38B1062121723E -:109DC0006681D0E90010C4E9031009E02878092869 -:109DD0000BD00520207266816868E0600020287042 -:109DE0002046BDE8F04101F0E7BC07202072668103 -:109DF000F4E72DE9F04116460D460746406801EBB1 -:109E000085011C2202EBC1014418204601F00FFD20 -:109E100040B10021708865F30F2160F31F410820D5 -:109E20000AF0D2F909202070324629463846BDE8AA -:109E3000F04195E72DE9F0410E46074600241C212C -:109E4000F07816E004EB8403726801EBC303D25C84 -:109E50006AB1FFF7AAFA050000D1FFDF6F802A463A -:109E600021463046FFF7C5FF0120BDE8F081641CA4 -:109E7000E4B2A042E6D80020F7E770B50646002419 -:109E80001C21C0780AE000BF04EB8403726801EB78 -:109E9000C303D5182A782AB1641CE4B2A042F3D8CF -:109EA000402070BD2821284617F09DFE70688089EB -:109EB0002881204670BD70B5034600201C25DC7843 -:109EC0000DE000BF00EB80065A6805EBC606324481 -:109ED000167816B1128A8A4204D0401CC0B284425D -:109EE000F0D8402070BDF0B5044600201C26E5786F -:109EF0000EE000BF00EB8007636806EBC7073B443A -:109F00001F788F4202D15B78934204D0401CC0B2CC -:109F10008542EFD84020F0BD0078032801D0002012 -:109F20007047012070470078022801D00020704758 -:109F3000012070470078072801D0002070470120D9 -:109F400070472DE9F041064688461078F1781546AD -:109F5000884200D3FFDF2C781C27641CF078E4B221 -:109F6000A04201D8201AC4B204EB8401706807EB48 -:109F7000C1010844017821B14146884708B12C70DD -:109F800073E72878A042E8D1402028706DE770B5CB -:109F900014460B880122A240134207D113430B80C1 -:109FA00001230A22011D06F0C6FB047070BD2DE9D5 -:109FB000FF4F81B00878DDE90E7B9A4691460E4648 -:109FC00040072CD4019806F065FE040000D1FFDFA5 -:109FD00007F1040820461FFA88F105F0A9FE0500E4 -:109FE00000D1FFDF204629466A4606F092F9009824 -:109FF000A0F80370A0F805A0284606F04BFA0178F7 -:10A0000069F306016BF3C711017020461FFA88F14E -:10A0100005F0DEFE00B9FFDF019804F07CF906EBE5 -:10A020000900017F491C017705B0BDE8F08F2DE9DB -:10A03000F84F0E469A4691460746032106F00EFD5C -:10A040000446008DDFF8B085002518B198F80000AF -:10A05000B0421ED1384606F01DFE070000D1FFDFDA -:10A0600009F10401384689B205F062FE050010D0FE -:10A07000384629466A4606F04CF9009800210A46FF -:10A080000180817004F00AFA0098C01DCAF800002F -:10A0900021E098F80000B04216D104F1260734F808 -:10A0A000341F012000FA06F911EA090F00D0FFDF82 -:10A0B0002088012340EA090020800A22391D384601 -:10A0C00006F054FB067006E0324604F1340104F158 -:10A0D0002600FFF75CFF0A2188F800102846BDE83B -:10A0E000F88FFEB514460D46064602AB0C2206213B -:10A0F000FFF79DFF002826D00299687812220A7087 -:10A10000801C487008224A80A87020888880608857 -:10A11000C880A0880881E088488100240C20CDE90F -:10A1200000040523062229463046FFF740FF21465A -:10A1300066F31F41F0230022012009F09BFF68789D -:10A14000801C68700120FEBDFEB514460D46062237 -:10A15000064602AB1146FFF76AFF002812D0029BA9 -:10A16000132000211870A8785870022058809C8015 -:10A170000620CDE900010246052329463046FFF7B7 -:10A1800016FF0120FEBD2DE9FE430C46804644E04B -:10A1900002AB0E2207214046FFF749FF002841D0BD -:10A1A00060681C2267788678BF1C06EB860102EB8C -:10A1B000C101451802981421017047700A2141809D -:10A1C000698A0181E98A4181A9888180A98981817F -:10A1D000304601F0FBFA029905230722C8806F7010 -:10A1E0000420287000250E20CDE9000521464046B8 -:10A1F000FFF7DDFE294666F30F2168F31F41F023C8 -:10A200000022082009F036FF6078FC49801C60704D -:10A2100062682046921CFFF794FE606880784028B0 -:10A22000B6D10120BDE8FE83FEB50D46064638E0F6 -:10A2300002AB0E2207213046FFF7F9FE002835D089 -:10A2400068681C23C17801EB810203EBC202841809 -:10A25000029815220270627842700A224280A28916 -:10A260004281A2888281084601F0B0FA0146029834 -:10A270008180618AC180E18A0181A088B8B1002013 -:10A28000207000210E20CDE9000105230722294678 -:10A290003046FFF78CFE6A68D9492846D21CFFF782 -:10A2A00050FE6868C0784028C2D10120FEBD06205B -:10A2B000E6E72DE9FE430C46814644E0204601F0E6 -:10A2C000A0FAD0B302AB082207214846FFF7AFFE41 -:10A2D0000028A7D060681C2265780679AD1C06EBC3 -:10A2E000860102EBC10147180298B7F810800621D9 -:10A2F0000170457004214180304601F067FA014643 -:10A30000029805230722C180A0F804807D700820F0 -:10A3100038700025CDE9000521464846FFF747FE85 -:10A32000294666F30F2169F31F41F023002208201C -:10A3300009F0A0FE6078801C60706268B149204618 -:10A34000121DFFF7FEFD606801794029B6D101209A -:10A3500068E72DE9F34F83B00E4680E0304601F008 -:10A3600050FA002875D071681C2091F8068008EB1F -:10A37000880200EBC2000C184146304601F035FA65 -:10A380000146A078C30070684078C20004F1240040 -:10A3900006F023FA07468088E18B401A80B2002538 -:10A3A00081B3AA46218B814200D8084681460246E5 -:10A3B00002AB07210398FFF73AFE010028D0BAF15B -:10A3C000000F03D0029AB888022510808B46E28BDA -:10A3D0003968A9EB05001FFA80FA0A440398009235 -:10A3E00006F058FCED1D009A59465346009506F0BC -:10A3F00017F8E08B504480B2E083B988884209D1D5 -:10A40000012508E0FFE7801C4FF0010A80B2C9E790 -:10A41000002009E60025CDE90095238A0722314670 -:10A420000398FFF7C4FDE089401EE0818DB1A0785C -:10A43000401CA0707068F178427811FB02F1CAB23A -:10A44000816901230E3006F076F980F80080002043 -:10A45000E08372686C493046921DFFF772FD7068A8 -:10A46000817940297FF47AAF0120DDE570B5064699 -:10A4700048680D4614468179402910D104EB8401C7 -:10A480001C2202EBC101084401F0F2F9002806D0B9 -:10A490006868294684713046BDE8704059E770BD50 -:10A4A000FEB50C460746002645E0204601F0A9F916 -:10A4B000D8B360681C22417901EB810102EBC10134 -:10A4C0004518688900B9FFDF02AB0822072138462A -:10A4D000FFF7ADFD002833D00299607816220A708C -:10A4E000801C4870042048806068407901F06EF953 -:10A4F000014602980523072281806989C1800820CE -:10A50000CDE9000621463846FFF751FD6078801CF2 -:10A510006070A88969890844B0F5803F00D3FFDFE7 -:10A52000A88969890844A8816E81626837492046F4 -:10A53000521DFFF706FD606841794029B5D1012021 -:10A54000FEBD30B5438C458BC3F3C704002345B132 -:10A55000838B641EED1AC38A6D1E1D4495FBF3F3B5 -:10A56000E4B22CB1008918B1A04200D820460344BF -:10A570004FF6FF70834200D3034613800C7030BD4A -:10A580002DE9FC41074616460D46486802EB860158 -:10A590001C2202EBC101441801AA69462046FFF7BC -:10A5A000D0FFA1896389BDF80420C81880B2824217 -:10A5B0001FD001280AD99DF800C0BCF1000F03D0BC -:10A5C000B4F808C0844501D8002B12D0501A00D529 -:10A5D000002060816868407940280AD1204601F057 -:10A5E0003DF9002805D06868294646713846FFF7CE -:10A5F00057FFBDE8FC8100002C000020199F0000DF -:10A60000279F0000359F000071B800005DB8000072 -:10A610002DE9FE4F8946804615465088032106F0F5 -:10A620001DFA8346B8F80200402801D2402000E01D -:10A63000403880B282460146584601F0E2F80028D0 -:10A640007ED00AEB8A001C22DBF8041002EBC0006B -:10A650000C18204601F0EBF8002877D1B8F800007C -:10A66000E18A88423CD8A189D1B348456ED1002601 -:10A670005146584601F0B2F8218C0F18608B48B94A -:10A68000B9F1020F62D3B8F804006083618A88428E -:10A6900026D80226A9EB06001FFA80F9B888A28BFB -:10A6A000801A002814DD4946814500DA084683B245 -:10A6B00068886968029139680A44CDE9003206F079 -:10A6C000D7FADDE90121F61D009B009605F06FFE2B -:10A6D000A18B01EB090080B2A083618B884207D96E -:10A6E000688803B052465946BDE8F04F01F0DDB826 -:10A6F0001FD14FF009002872B8F802006881D7E92D -:10A700000001C5E90401608BA881284601F054F8D6 -:10A710005146584601F062F80146DBF80400082370 -:10A720000078C20004F1200006F03BF80020A0836E -:10A730006083A0890AF0FF02401EA081688800E0C3 -:10A7400004E003B05946BDE8F04F19E7BDE8FE8FBD -:10A750002DE9F041064615460F461C46184609F0FD -:10A760007FFD18B9206809F0A1FD08B1102007E4A9 -:10A770007168688C0978B0EBC10F01D3132005E430 -:10A780003946304601F02AF80146706808230078FF -:10A79000C20005F1200005F0CEFFD4E90012C0E9A7 -:10A7A00000120020E3E710B50446032106F056F935 -:10A7B0000146007800F00300012804D08A8A204670 -:10A7C000BDE81040C0E42046BDE8104001F114028D -:10A7D00087E470B50446032106F040F905460146BA -:10A7E0002046FFF766FD002816D029462046FFF7D1 -:10A7F00057FE002810D029462046FFF715FD0028F7 -:10A800000AD029462046FFF7BEFC002804D029467E -:10A810002046BDE870409CE570BD2DE9F0410C4636 -:10A8200080461EE0E178427811FB02F1CAB28169EC -:10A8300001230E3005F0B5FF077860681C22C1794E -:10A84000491EC17107EB8701606802EBC101461820 -:10A850003946204600F0D5FF18B1304600F0E0FF41 -:10A8600020B16068C1790029DCD180E7FEF79DFD49 -:10A87000050000D1FFDF0A202872384600F0A6FF4D -:10A8800068813946204600F0B0FF01466068082321 -:10A890004078C20006F1240005F083FFD0E90010E3 -:10A8A000C5E90310A5F80280284600F085FFB078BE -:10A8B00000B9FFDFB078401EB07058E770B50C46A5 -:10A8C0000546032106F0CAF801464068C2792244D1 -:10A8D000C2712846BDE870409FE72DE9FE4F8246D1 -:10A8E000507814460F464FF0000800284FD001283A -:10A8F00007D0022822D0FFDF2068B8606068F860C7 -:10A9000024E702AB0E2208215046FFF790FB0028F7 -:10A91000F2D00298152105230170217841700A2197 -:10A920004180C0F80480C0F80880A0F80C806288DC -:10A9300082810E20CDE90008082221E0A678304669 -:10A9400000F044FF054606EB86012C22786802EBF6 -:10A95000C1010822465A02AB11465046FFF767FB79 -:10A960000028C9D002980721017021784170042184 -:10A97000418008218580C680CDE9001805230A465C -:10A9800039465046FFF713FB87F80880DEE6A678C5 -:10A99000022516B1022E13D0FFDF2A1D914602AB0D -:10A9A00008215046FFF743FB0028A5D0029801215B -:10A9B000022E0170217841704580868002D005E02A -:10A9C0000625EAE7A188C180E1880181CDE90098E8 -:10A9D0000523082239465046D4E710B50446032122 -:10A9E00006F03CF8014600F108022046BDE81040A0 -:10A9F00073E72DE9F05F0C4601281DD0957992F898 -:10AA00000480567905EB85011F2202EBC10121F07C -:10AA1000030B08EB060111FB05F14FF6FF7202EA8A -:10AA2000C10909F1030115FB0611F94F21F0031AC1 -:10AA300040B101283DD124E06168E57891F80080BB -:10AA40004E78DFE75946786805F029FE606000B966 -:10AA5000FFDF5946606817F0E8F8E57051467868FE -:10AA600005F01DFE6168486100B9FFDF606842695A -:10AA700002EB09018161606880F8008060684670BF -:10AA800017E0606852464169786805F033FE5A461F -:10AA90006168786805F02EFE032005F089FF044602 -:10AAA000032005F08DFF201A012802D1786805F0F7 -:10AAB000EBFD0BEB0A00BDE8F09F024600210220EF -:10AAC00097E713B5009858B10024684605F0C9FD12 -:10AAD000CF490A22002C0A7001D1009A4A601CBD9D -:10AAE00001240020F2E770B50C46154638212046B7 -:10AAF00017F09BF8012666700A2104F11C0017F07C -:10AB000094F805B9FFDF297A207861F301002070FD -:10AB1000A879002817D02A4621460020FFF769FFB0 -:10AB20006168402088706168C870616808716168F8 -:10AB300048716168887161682888088161686888DF -:10AB400048816068868170BDC878002802D00022E4 -:10AB500001204EE7704770B50546002165F31F419F -:10AB6000012009F031FB0321284605F077FF04009E -:10AB700000D1FFDF21462846FFF75CF9002804D00A -:10AB8000207840F010002070012070BD2DE9FF41B9 -:10AB900080460E460F0CFEF708FC050007D06F80BC -:10ABA0000321384605F05AFF040008D106E004B03E -:10ABB0003846BDE8F0411321F9F72EBEFFDFB8F1AA -:10ABC000010F05D0B8F1080F18D0FFDFBDE8FF81F5 -:10ABD00020782A4620F0080020700020ADF80200FE -:10ABE00002208DF800004FF6FF70ADF80400ADF8BC -:10ABF000060069463846F9F717F9E7E7C6F3072173 -:10AC000001EB81021C23606803EBC202805C042814 -:10AC100003D008280AD0FFDFD8E7012000904FF4C6 -:10AC200040432A46204600F009FECFE704B02A46FA -:10AC30002046BDE8F041FFF7DCB82DE9F05F0027C2 -:10AC4000B0F80A9090460C4605463E46B9F1400FD2 -:10AC500001D2402001E0A9F140001FFA80FA287AD1 -:10AC6000C01E08286BD2DFE800F00D04192058360A -:10AC70003C4772271026002C6CD0D5E90301C4E9AB -:10AC800002015CE070271226002C63D00A2205F135 -:10AC90000C0104F1080016F074FF50E071270C2637 -:10ACA000002C57D0E868A06049E0742710269CB3B8 -:10ACB000D5E90301C4E902016888032105F0CEFE4D -:10ACC0008346FEF772FB024668885080514658461C -:10ACD000FFF746F833E075270A26ECB1A8892081F2 -:10ACE0002DE076271426BCB105F10C0004F1080311 -:10ACF00007C883E8070022E07727102664B1D5E96A -:10AD00000301C4E902016888032105F0A7FE01469A -:10AD10006888FFF782FD12E01CE073270826CCB19B -:10AD20006888032105F09AFE01460078C00606D522 -:10AD30006888FFF77FF810B96888F8F767FCA8F80B -:10AD400000602CB12780A4F8069066806888A080F7 -:10AD50000020B0E6A8F80060FAE72DE9FC410C46B7 -:10AD60001E4617468046032105F078FE05460A2C4C -:10AD70000AD2DFE804F005050505050509090907FC -:10AD8000042303E0062301E0FFDF0023CDE9007682 -:10AD9000224629464046FFF70AF92AE438B5054617 -:10ADA000A0F57F40FF3830D0284605F061FF040051 -:10ADB00000D1FFDF204605F08BFA002815D00146B0 -:10ADC0006A46204605F0A5FA00980321B0F8054030 -:10ADD000284605F043FE0546052C03D0402C05D23D -:10ADE000402404E0007A80B1002038BD403CA4B289 -:10ADF000214600F006FD40B1686804EB84013E2264 -:10AE000002EBC101405A0028EFD0012038BD0000FC -:10AE10002C0000202DE9F04F044689B0408805F051 -:10AE200027FF050000D1FFDF06AA2846616800F071 -:10AE3000C1FC069D001F81B235F8032F6B888A4242 -:10AE400005D1042B0AD0052B1DD0062B15D0224688 -:10AE50002846FFF7DDFB09B0BDE8F08F16462D1D33 -:10AE6000224629463046F7F78CFA0828F3D12246C5 -:10AE700029463046FCF73DFCEDE76088291D6368F4 -:10AE8000FAF7F0FCE7E717466088032105F0E6FDD6 -:10AE90004FF000088DF804800646ADF80680042FB8 -:10AEA000D9D36A79002AD6D028794FF6FF794FF0A6 -:10AEB0001C0A13282CD008DC012878D0062847D09B -:10AEC000072875D0122874D106E0142872D01528EE -:10AED00071D016286DD1ACE10C2F6AD1307800F01A -:10AEE0000301012965D040F0080030706879B07026 -:10AEF00001208DF804002889ADF808006889ADF8B4 -:10AF00000A00A889ADF80C00E889ADF80E0019E038 -:10AF1000B07890429FD1307801079CD5062F9AD106 -:10AF200020F0080030706088414660F31F41012026 -:10AF300009F04AF902208DF80400ADF8089028893C -:10AF4000ADF80A006088224601A9F8F76DFF82E794 -:10AF5000082F80D12F89B5F80A90402F01D24020C8 -:10AF600001E0A7F1400080B280460146304600F083 -:10AF700048FC08B3716808EB88002C2202EBC00083 -:10AF8000095A4945E3D1FE4807AAD0E90210CDE9A4 -:10AF9000071068798DF81C0008F0FF058DF81E5029 -:10AFA00060883146FFF799FC2246294639E0B6E031 -:10AFB00014E03CE039E0E6E0F148D0E90010CDE9EA -:10AFC00007106879ADF820708DF81C00ADF822905C -:10AFD000608807AA3146FFF780FC3CE7082FB6D10E -:10AFE0006889B5F80880402801D2402000E0403848 -:10AFF00087B23946304600F004FC0028A7D007EBA2 -:10B00000870271680AEBC2000844028A42459ED159 -:10B01000017808299BD140786979884297D1F9B2A3 -:10B0200022463046FEF7E5FE15E70E2F07D0CDF895 -:10B030001C80CDF8208068798DF81C00C8E76989EC -:10B04000EF898B46B5F80C903046FEF734FFABF134 -:10B050004001402901D309204AE0B9F1170F01D37B -:10B06000172F01D20B2043E040280ED000EB8002C6 -:10B0700071680AEBC20008440178012903D14078C5 -:10B0800069798842A9D00A2032E03046FEF7F5FE01 -:10B09000014640282BD001EB810372680AEBC30004 -:10B0A00002EB0008012288F800206A7988F8012064 -:10B0B00070682A894089B84200D938462D8A03230E -:10B0C0002372A282E7812082A4F80C906582084650 -:10B0D00000F07CFB6081A8F81490A8F81870A8F81C -:10B0E0000E50A8F810B0204600F066FBB3E604202E -:10B0F00005212172A4F80A80E08101212173A04971 -:10B10000D1E90421CDE9072169798DF81C10ADF84A -:10B110001E00608807AA3146FFF7DFFBE3E7062F32 -:10B12000E4D3B078904215D13078010712D520F0E1 -:10B13000080030706088414660F31F41012009F02B -:10B1400043F802208DF804002889ADF80800ADF816 -:10B150000A90F7E604213046FEF7C5FE0546402872 -:10B16000C4D002208303009022462946304600F0D6 -:10B1700065FB4146608865F30F2160F31F4108209D -:10B1800009F022F867E60E2FB0D104213046FEF711 -:10B19000AAFE81464028A9D04146608869F30F2164 -:10B1A00060F31F41082009F00FF8288A0790E8890A -:10B1B00000907068AF894089B84200D9384683460C -:10B1C000B5F80A8028890590484600F0FFFA6081AA -:10B1D000079840B10220079B00902246494630461E -:10B1E00000F02CFB37E6B8F1170F1ED3172F1CD336 -:10B1F0000420207200986082E781A4F810B0A4F8BF -:10B200000C8009EB890271680AEBC2000D180099E5 -:10B210000598A5F81480A5F818B0E9812882204681 -:10B2200000F0CAFA0620287015E601200B230090D2 -:10B23000D3E7082FA6D129893046FEF73CFE074602 -:10B2400040289FD007EB870271680AEBC2000844D0 -:10B25000804600F0ECFA002894D16D89B8F80E0011 -:10B260002844B0F5803F05D360883A46314600F067 -:10B270001CFBF0E5002D85D0A8F80E0060883A464A -:10B280003146FFF7F3F808202072384600F09EFAA6 -:10B290006081A58127E770B50D460646032105F0BC -:10B2A000DDFB040004D02078000704D5112070BD18 -:10B2B00043F2020070BD2A4621463046FEF711FFD8 -:10B2C00018B9286860616868A061207840F00800BB -:10B2D0002070002070BD70B50D460646032105F0B4 -:10B2E000BDFB040004D02078000704D4082070BD02 -:10B2F00043F2020070BD2A4621463046FEF724FF85 -:10B3000000B9A582207820F008002070002070BDD0 -:10B310002DE9F04F0E4691B08046032105F09EFBCB -:10B320000446404605F0B6FC07460020079008900A -:10B330000990ADF830000A9002900390049004B98F -:10B34000FFDF0DF1080917BBFFDF20E038460BA92E -:10B35000002204F046FE9DF82C0000F07F050A2D27 -:10B3600000D3FFDF6019017F491E01779DF82C0093 -:10B3700000060CD52A460CA907A8FEF708FE01E036 -:10B380005C20020019F80510491C09F80510761E0A -:10B39000F6B2DBD204F13400FC4D04F1260BDFF8E9 -:10B3A000F0A304F12A07069010E05846069900F031 -:10B3B0006EFA064628700A2800D3FFDF5AF82610D6 -:10B3C00040468847E08CC05DB04202D0208D002806 -:10B3D000EBD10A202870EE4D4E4628350EE00CA920 -:10B3E00007A800F054FA0446375D55F8240000B968 -:10B3F000FFDF55F82420394640469047BDF81E002F -:10B400000028ECD111B027E510B5032105F026FB8B -:10B41000040000D1FFDF0A2104F11C0016F005FC36 -:10B42000207840F00400207010BD10B50C460321B8 -:10B4300005F014FB01190A7F01211AB9808EA14081 -:10B44000084000D0012010BD2DE9F84F894615466F -:10B450008246032105F002FB070004D0284608F0CD -:10B46000FFFE40B903E043F20200BDE8F88F484612 -:10B4700008F01CFF08B11020F7E7786828B1698848 -:10B480000089814201D90920EFE7B9F800001C24A6 -:10B4900018B1402809D2402008E03846FEF7EDFCFC -:10B4A0008046402819D11320DFE7403880B280461B -:10B4B0000146384600F0A5F948B108EB88007968E4 -:10B4C00004EBC000085C012803D00820CDE705206C -:10B4D000CBE7FDF76AFF06000BD008EB8800796820 -:10B4E00004EBC0000C18B9F8000020B1E88910B1D5 -:10B4F00013E01120B9E72888172802D36888172895 -:10B5000001D20720B1E7686838B12B1D22464146B9 -:10B510003846FFF71DF90028A7D104F10C0269464F -:10B520002046FFF70EF8288860826888E082B9F824 -:10B53000000030B102202070E889A080E889A0B125 -:10B540002BE003202070A889A080786881784029AA -:10B5500005D180F8028039465046FEF714FE404679 -:10B5600000F034F9A9F8000021E07868218B4089C7 -:10B57000884200D908462083A6F802A00420307231 -:10B58000B9F800007081E0897082F181208B3082EF -:10B59000A08AB081304600F00FF97868C178402960 -:10B5A00005D180F8038039465046FEF73DFE002065 -:10B5B0005BE770B50D460646032105F04FFA04001F -:10B5C00003D0402D04D2402503E043F2020070BDB9 -:10B5D000403DADB2294600F014F958B105EB8501A4 -:10B5E0001C22606802EBC101084400F020F918B188 -:10B5F000082070BD052070BD2A462146304600F067 -:10B6000054F9002070BD2DE9F0410D4616468046E4 -:10B61000032105F023FA0446402D01D2402500E025 -:10B62000403DADB28CB1294600F0EBF880B105EB9E -:10B6300085011C22606802EBC1014718384600F002 -:10B64000F6F838B10820BDE8F08143F20200FAE7CD -:10B650000520F8E733463A4629462046FFF778F8B2 -:10B660000028F0D1EAB221464046FEF789FF0020CB -:10B67000E9E72DE9F0410D4616468046032105F025 -:10B68000EDF90446402D01D2402500E0403DAFB227 -:10B6900024B1304608F0E4FD38B902E043F202007C -:10B6A000D1E7306808F0DCFD08B11020CBE739465F -:10B6B000204600F0A6F860B107EB87011C22606805 -:10B6C00002EBC1014518284600F0B1F818B1082076 -:10B6D000B9E70520B7E7B088A98A884201D90C20CC -:10B6E000B1E76168E88C4978B0EBC10F01D3132052 -:10B6F000A9E73946204600F078F80146606808233B -:10B700004078C20005F1240005F015F8D6E90012D2 -:10B71000C0E90012FAB221464046FEF7A7FE00201B -:10B7200091E72DE9F0470D461F46904681460321DB -:10B7300005F094F90446402D01D2402001E0A5F126 -:10B74000400086B23CB14DB1384608F0CDFD50B155 -:10B750001020BDE8F08743F20200FAE76068C8B144 -:10B76000A0F80C8024E03146204600F04AF888B169 -:10B7700006EB86011C22606802EBC10145182846D1 -:10B7800000F055F840B10820E3E700002C0000204D -:10B79000742002000520DCE7A5F80880F2B22146FB -:10B7A0004846FEF7EDFE1FB1A88969890844388034 -:10B7B0000020CEE704F0ADBD017821F00F01491C57 -:10B7C00021F0F00110310170FDF7F2BD10B5044613 -:10B7D000402800D9FFDF4034A0B210BD4068426964 -:10B7E0000078484302EBC0007047C2784068037895 -:10B7F00012FB03F24378406901FB032100EBC10017 -:10B800007047C2788A4209D9406801EB81011C2245 -:10B8100002EBC101405C08B1012070470020704775 -:10B820000078062801D90120704700207047007871 -:10B83000062801D00120704700207047F0B401EBCA -:10B8400081061C27446807EBC6063444049D052680 -:10B850002670E3802571F0BCFEF782BA10B54189ED -:10B8600011B1FFF7DDFF08B1002010BD012010BDB0 -:10B8700010B5C18C8278B1EBC20F04D9C18911B166 -:10B88000FFF7CEFF08B1002010BD012010BD10B59C -:10B890000C4601230A22011D04F083FF0078218851 -:10B8A000012282409143218010BDF0B402EB820559 -:10B8B0001C264C6806EBC505072363554B681C79AD -:10B8C000402C03D11A71F0BCFEF7F3BCF0BC7047FA -:10B8D00010B5EFF3108000F0010472B6E94841782A -:10B8E000491C41704078012801D1F7F74BFB002C2F -:10B8F00000D162B610BD70B5E24CE07848B90125C0 -:10B90000E570FFF7E5FFF7F745FB20B1002008F0F1 -:10B910009AF8002070BD4FF080406571C0F8045364 -:10B92000F7E770B5EFF3108000F0010572B6D54C63 -:10B93000607800B9FFDF6078401E6070607808B9F9 -:10B94000F7F724FB002D00D162B670BDCD4810B5CD -:10B95000C17821B100214171C170FFF7E2FF0020E1 -:10B9600010BD10B50446F7F715FBC649C978084065 -:10B9700000D001202060002010BD2DE9F05FDFF82D -:10B9800004934278817889F80620002689F8071008 -:10B99000074689F808600078354620B101280FD0A5 -:10B9A00002280FD0FFDFF7F702FB98B1F7F706FB8D -:10B9B000B0420FD13046F7F705FB0028FAD047E038 -:10B9C0000126F0E7FFF784FFF7F7E4FA0028FBD041 -:10B9D0000226E8E701208407E060C4F80451AA4980 -:10B9E0000E600107D1F84412A74AC1F34231243254 -:10B9F0001160A549343108604FF0020BC4F804B35C -:10BA0000A060DFF888A2DAF80010C94341F3001102 -:10BA100001F10108DAF8001041F01001CAF8001035 -:10BA200000E020BFD4F804010028FAD03046F7F730 -:10BA3000C9FA0028FAD0B8F1000F05D1DAF80010E1 -:10BA400021F01001CAF80010C4F808B3C4F804517A -:10BA500099F807004C4670B1387860B9F7F79AFA50 -:10BA6000074608F09FF96FF0004117B1C4E90310D1 -:10BA700001E0C4E9030116B12571BDE8F09F01277B -:10BA8000BE0727714FF01908C6F80883B761C6F8DA -:10BA90000051C6F80C51C6F81051F7F77BFA10B1F7 -:10BAA000A770376100E02770FFF712FF7649A07991 -:10BAB00020310860C6F80483DFE770B5050000D1C7 -:10BAC000FFDF4FF080424FF0FF30C2F80803002143 -:10BAD000C2F80011C2F80411C2F80C11C2F810111A -:10BAE000684C6170F7F75CFA10B10120E07060708B -:10BAF0002846BDE8704040E72DE9F05F6448D0F883 -:10BB000000B0634A6349083211608406D4F8080122 -:10BB100010B14FF0010801E04FF00008D4F8000127 -:10BB200000B101208146D4F8040108B1012600E0EB -:10BB30000026D4F80C0100B101208246D4F810018F -:10BB400008B1012700E0002748EA090126EA0100C0 -:10BB500020EA0A00B84300D0FFDF0025B8F1000F4B -:10BB600004D0C4F80851012007F06DFF5FEA090016 -:10BB7000DFF810814FF0010913D0C4F8005198F894 -:10BB8000050020B188F80550002007F05CFF98F808 -:10BB9000000030B1F7F7FEF918B188F80290C4F848 -:10BBA00010900EB1C4F80451BAF1000F0CD0C4F8D3 -:10BBB0000C5198F80200464600B9FFDFB5703570A9 -:10BBC000C4F81490FFF7ADFE37B1C4F8105198F8DF -:10BBD000040008B100F020F82D49091DC1F800B09B -:10BBE0004BE770B5274DE87808B9F7F7CFF9012092 -:10BBF0008407A061A87850B1D4F80C0120B90020C6 -:10BC0000F7F7E0F90028F7D10020C4F80C014FF055 -:10BC1000FF30C4F8080370BD2DE9F041194C4FF016 -:10BC200080470125E079F0B1012803D0217A401E38 -:10BC3000814218DAF7F7AEF9064608F0B3F8E17971 -:10BC4000012902D9217A491C21720EB1216900E033 -:10BC5000E168411A022902DA11F1020F0BDC0EB180 -:10BC6000206100E0E060FFF733FEF7F793F928B1B9 -:10BC70003D61A57003E07D61BDE8F0812570002085 -:10BC80002072F9E7380000201805004010ED00E0B0 -:10BC900010050240010000014FF0E0214FF000705C -:10BCA000C1F88001C1F88002384B802283F800245B -:10BCB000C1F80001704700B502460420344903E092 -:10BCC00001EBC0031B792BB1401EC0B2F8D2FFDFDD -:10BCD000FF2000BD41F8302001EBC00100224A7175 -:10BCE0008A7101220A7100BD294A002102EBC000BD -:10BCF0000171704710B50446042800D3FFDF2448C3 -:10BD000000EBC4042079012800D0FFDF6079A1791D -:10BD1000401CC0B2814200D060714FF0E0214FF072 -:10BD20000070C1F8000210BD2DE9F0411948056806 -:10BD300018491948083108601448042690F800048E -:10BD4000134F4009154C042818D0FFDF16E0217866 -:10BD500007EBC1000279012A08D1427983799A421E -:10BD600004D04279827157F8310080472078401C16 -:10BD7000C0B22070042801D300202070761EF6B2D5 -:10BD8000E5D20448001D0560BDE8F08119E000E03F -:10BD90009006002010050240010000014C00002028 -:10BDA000F8B51D46DDE906470E000AD004F072FF23 -:10BDB0002346FF1DBCB231462A46009404F030FBF6 -:10BDC000F8BDD0192246194615F096FE2046F8BD5A -:10BDD000F84B586019721A80C90015F026BF70B56B -:10BDE0000D460446102115F0FEFE258117206081C6 -:10BDF000A07B40F00A00A07370BD4FF6FF720A806E -:10BE00000146032008F0E0B9704700897047827B43 -:10BE1000D30701D1920703D480890880002070479E -:10BE200005207047827B920700D5818170470146CB -:10BE30000020098847F2FE12114200D00120DD499E -:10BE4000497A002901D040F00800704700B5034648 -:10BE5000807BC00701D0052000BD59811846FFF73F -:10BE6000E6FFC00703D0987B40F004009873987BEE -:10BE700040F001009873002000BD827B520700D57E -:10BE800009B14089704717207047827B61F3C30274 -:10BE9000827370472DE9F04F0E46017804464FF04B -:10BEA000010B0BFA01F047F2FF1100EA010961688A -:10BEB0004FF6FF7887B008881D469646404506D065 -:10BEC000B9F1000F07D047F2FE12104203D0012053 -:10BED00007B0BDE8F08F40EA090008804FF0000A83 -:10BEE00095B185F800A022780027052003210223C0 -:10BEF000102A6FD2DFE802F06E0D2C35546F768079 -:10BF000054CBC79CCFFEFDFC20780B28EBD004203F -:10BF1000DEE762682089937B9B077DD5172851D384 -:10BF200013898342FBD39289172A01D3824249D1D4 -:10BF30002A7822F03F02921C2A70A5F80100318075 -:10BF4000616888816068817B21F00201817342E130 -:10BF5000042129702189A5F801106189A5F8031031 -:10BF60008FE0208A3188C01D1FFA80F84145D6D362 -:10BF7000062028702089A5F801006089A5F8030033 -:10BF8000A089A5F805000721208ACDE90001608875 -:10BF90002A4671466369FFF703FFA6F800801AE19D -:10BFA000082A10D0082129702189A5F8011061897B -:10BFB000A5F8031030806A1D694604F10C0006F0F4 -:10BFC000CAF910B1CCE01021EDE730889DF80010DF -:10BFD000084456E00EE10A2028702089A5F80100E7 -:10BFE0003180B2E00C2129702189A5F80110618906 -:10BFF000A5F803103080A8E0218933880BEB4102BB -:10C000001FFA82FA534576D3BAF1050F73D30E2285 -:10C010002A7008EA410100E07FE0CDE9001B60885A -:10C020002A467146E368FFF7BBFEA6F800A0D2E0FF -:10C030006048417A002970D0491E41724068217AD7 -:10C04000E26800EBC105D046A9882868D2F800C094 -:10C050000844A0F1080140F808CC506848608DF809 -:10C0600000308DF801A028680290A888ADF804007F -:10C0700060886946F5F7C6FEA5F80480002E01D059 -:10C0800040463080A7E0287840F080022A70287867 -:10C0900040F040022A7060893288C01C1FFA80F884 -:10C0A00042455DD3287820F03F0012302870228965 -:10C0B000A5F801206089CDE9000160882A46714613 -:10C0C000E368FFF76DFEA6F80080287841063CD5AE -:10C0D00000065ED58DF800B08DF801A03188CDE95D -:10C0E000025A091DADF804100420DFF8C88003E0EF -:10C0F00059E04FE02DE033E0049098F808008DF807 -:10C10000140060886946F5F77DFE074630880C30DC -:10C110003080022F02D0E7B36FE048E09DF8142092 -:10C12000D8F8041098F80830404601EBC2019A4252 -:10C1300016D28A88A2B9427A521C88F809200D606A -:10C1400030888880A6F800A057E061682089888040 -:10C1500041E0A1893288491D1FFA81F8424501D288 -:10C1600004274AE029782A4621F03F011631297038 -:10C170002189A5F801106189A5F80310A189CDE9ED -:10C180000010608871462369FFF70AFEA6F8008058 -:10C19000DBE720E0287820F03F0018302870207A74 -:10C1A0006870338017E060680188090404D40527AB -:10C1B00023E00000B0060020C0882189884201D019 -:10C1C00006271AE01E202870A6F800B060680188D3 -:10C1D00021F400410180B9F1000F0ED0DF486188E1 -:10C1E000002200888300032007F044FF6168207864 -:10C1F000887007E0A6F800A003276068018821EA9C -:10C2000009010180384663E62DE9F04F87B01746F3 -:10C21000109C0D0083461E461AD03078C10703D00B -:10C2200000F03F00192801D9012100E0002120463B -:10C23000FFF723FEA8420BD32088A0F57F41FF39EA -:10C2400006D03078410601D4000603D508203FE629 -:10C2500007203DE600208DF800008DF801003078C1 -:10C260006B1E00F03F0C0122A81E4FF0050A4FF094 -:10C27000020999B2BCF1200F76D2DFE80CF08C10E5 -:10C28000755F7569758D759E75B875BD75CB75D7FC -:10C2900075E4757575F475F275F175F0758C052D8D -:10C2A00079D104208DF80000A0788DF80400708802 -:10C2B000ADF8060030798DF80100707800F03F008D -:10C2C0000C2829D00ADCA0F10200092863D2DFE89B -:10C2D00000F0126215621A621D622000122824D03A -:10C2E00004DC0E281BD01028DAD11BE016281FD042 -:10C2F0001828D5D11FE02078800701E0207840077A -:10C30000002848DAF1E020780007F9E72078C00635 -:10C31000F6E720788006F3E720784006F0E72078FB -:10C320000006EDE72088C005EAE72088C004E7E7BB -:10C3300020888004E4E720884004E1E72078800733 -:10C3400029D5032D27D18DF800A0B6F8010083E090 -:10C35000217849071FD5062D1DD381B27078012899 -:10C3600003D0022817D102E0CCE0022000E0102028 -:10C3700006228DF8002072788DF80420801CB1FB15 -:10C38000F0F2ADF8062092B242438A4203D10397FD -:10C39000ADF80890A9E07BE02078000778D5072168 -:10C3A00098B28DF800108108ADF80410B0EB810F41 -:10C3B0006ED10297ADF8062097E02178C90667D5BF -:10C3C000022D65D381B208208DF800007078022814 -:10C3D0005ED300BFB1FBF0F28DF80400ADF806208B -:10C3E00092B242438A4253D1ADF808907CE0207863 -:10C3F00080064DD5092003E02078400648D50A2064 -:10C400008DF80000A088ADF80400ADF80610ADF876 -:10C41000082069E02078000672D50B20ADF80410E2 -:10C420008DF80000ADF8062002975EE02188C9056E -:10C4300066D5022D64D381B20C208DF8000070788F -:10C4400004285DD3C6E72088C00459D5012D57D1F3 -:10C450000D208DF80000A088ADF8040045E021E033 -:10C4600026E016E0FFE72088800449D5052D47D354 -:10C470000E208DF80000A088ADF80400B6F8030087 -:10C480006D1FADF80850ADF80600ADF80AA02BE01E -:10C4900036E02088400433D5012D31D10F208DF8AE -:10C4A000000022E0208800042AD4B6F80100E080D1 -:10C4B000A07B000724D5032D22D3307800F03F0065 -:10C4C0001B2819D011208DF80000208840F400406E -:10C4D000A4F80000B6F80100ADF80400ED1E03203A -:10C4E000ADF80650ADF80800039769465846F5F7D1 -:10C4F00089FC050008D016E010208DF80000E9E75F -:10C50000072510E008250EE0307800F03F001B28DA -:10C5100009D01D2807D05946032007F055FE208872 -:10C5200000F400402080A07B400708D52046FFF79C -:10C530007EFCC00703D1A07B20F00400A073284636 -:10C54000C6E400B587B0032805D18DF8000088B295 -:10C550006946F5F757FC07B000BD0000B0060020A3 -:10C56000F8B51D46DDE906470E000AD004F092FB3F -:10C570002346FF1DBCB231462A46009403F050FF0B -:10C58000F8BDD0192246194615F0B6FA2046F8BD76 -:10C590002DE9FF4F8DB09B46DDE91B57DDF87CA0F0 -:10C5A0000C46082B05D0E06901F00CF950B11020C1 -:10C5B000D2E02888092140F0100028808AF8001075 -:10C5C000022617E0E16901208871E2694FF42051E9 -:10C5D0009180E1698872E06942F601010181E069B8 -:10C5E000002181732888112140F0200028808AF8DA -:10C5F0000010042638780A900A2038704FF002099B -:10C6000004F118004D460C9001F09FFBB04681E00C -:10C61000BBF1100F0ED1022D0CD0A9EB0800801C2D -:10C6200080B20221CDE9001005AB52461E990D984B -:10C63000FFF796FFBDF816101A98814203D9F74804 -:10C6400000790F9004E003D10A9808B138702FE008 -:10C650004FF00201CDE900190DF1160352461E9963 -:10C660000D98FFF77DFF1D980088401B801B83B24B -:10C67000C6F1FF00984200D203461E990BA8D9B11B -:10C680005FF00002DDF878C0CDE9032009EB060178 -:10C6900089B2CDE901C10F980090BDF816100022B3 -:10C6A0000D9801F0D5FB387070B1C0B2832807D067 -:10C6B000BDF8160020833AE00AEB09018A19E1E788 -:10C6C000022011B0BDE8F08FBDF82C00811901F0F7 -:10C6D000FF08022D0DD09AF80120424506D1BDF881 -:10C6E0002010814207D0B8F1FF0F04D09AF80180E2 -:10C6F0001FE08AF80180C94800680178052902D145 -:10C70000BDF81610818009EB08001FFA80F905EBCF -:10C71000080085B2DDE90C1005AB0F9A01F018FB9B -:10C7200028B91D980088411B4145BFF671AF022D05 -:10C7300013D0BBF1100F0CD1A9EB0800801C81B203 -:10C740000220CDE9000105AB52461E990D98FFF776 -:10C7500007FF1D980580002038700020B1E72DE903 -:10C76000F8439C46089E13460027B26B9AB3491FB4 -:10C770008CB2F18FA1F57F45FF3D05D05518AD88EE -:10C780002944891D8DB200E000252919B6F83C80A6 -:10C790000831414520D82A44BCF8011022F8021B78 -:10C7A000BCF8031022F8021B984622F8024B91466F -:10C7B00004F05EFA4FF00C0C41464A462346CDF891 -:10C7C00000C003F0F4FDF587B16B00202944A41DDF -:10C7D0002144088003E001E0092700E08327384670 -:10C7E000BDE8F88310B50B88848F9C420CD9846B0C -:10C7F000E018048844B1848824F40044A41D234430 -:10C800000B801060002010BD822010BD2DE9F04784 -:10C810008AB00025904689468246ADF81850072711 -:10C820004BE0059806888088000446D4A8F800608C -:10C8300007A8019500970295CDE903504FF40073C6 -:10C8400000223146504601F003FB04003CD1BDF804 -:10C850001800ADF82000059804888188B44216D1EC -:10C860000A0414D401950295039521F40041009720 -:10C87000049541F4804342882146504601F0BEF8B9 -:10C8800004000BD10598818841F40041818005AAFC -:10C8900008A94846FFF7A6FF0400DCD000970598DA -:10C8A00002950195039504950188BDF81C3000227E -:10C8B000504601F0A3F8822C06D105AA06A94846E5 -:10C8C000FFF790FF0400ACD0ADF8185004E00598D5 -:10C8D000818821F40041818005AA06A94846FFF716 -:10C8E00081FF0028F3D0822C03D020460AB0BDE897 -:10C8F000F0870020FAE710B50C46896B86B051B17D -:10C900000C218DF80010A18FADF80810A16B0191DA -:10C910006946FAF7C9FB00204FF6FF71A063E18773 -:10C92000A08706B010BD2DE9F0410D460746896B82 -:10C930000020069E1446002911D0012B0FD132464B -:10C9400029463846FFF762FF002808D1002C06D0A0 -:10C95000324629463846BDE8F04100F042BFBDE806 -:10C96000F0812DE9FC411446DDE9087C0E46DDE945 -:10C970000A15521DBCF800E092B2964502D207207B -:10C98000BDE8FC81ACF8002017222A70A5F80160F0 -:10C99000A5F803300522CDE900423B462A46FFF7C1 -:10C9A000DFFD0020ECE770B50C4615464821204617 -:10C9B00015F03BF904F1080044F81C0F00204FF675 -:10C9C000FF71E06161842084A5841720E08494F8DD -:10C9D0002A0040F00A0084F82A0070BD4FF6FF726A -:10C9E0000A800146042007F0EFBB30B585B00C4645 -:10C9F0000546FFF780FFA18E284629B101218DF859 -:10CA000000106946FAF750FB0020E0622063606383 -:10CA100005B030BDB0F84000704700005000002065 -:10CA200090F84620920703D4408808800020F3E75E -:10CA30000620F1E790F846209207EDD5A0F84410C3 -:10CA4000EAE70146002009880A0700D5012011F015 -:10CA5000F00F01D040F00200CA0501D540F00400FB -:10CA60008A0501D540F010004A0501D540F02000AC -:10CA70000905D1D540F04000CEE700B5034690F857 -:10CA80004600C00701D0062000BDA3F8421018469A -:10CA9000FFF7D7FF10F0760F05D093F8460040F06F -:10CAA000040083F8460013F8460F40F001001870A8 -:10CAB000002000BD90F84620520700D511B1B0F813 -:10CAC0004200A9E71720A7E710F8462F61F3C30239 -:10CAD0000270A1E72DE9FF4F9BB00E00DDE92B347A -:10CAE000DDE92978289D25D02878C10703D000F0FA -:10CAF0003F00192801D9012100E000212046FFF75D -:10CB0000D9FFB04216D3287841060FD400F03F0178 -:10CB10001E2909D0218811F47F6F0BD13A884AB1C0 -:10CB2000A1F57F42FF3A05D0010606D500F03F008F -:10CB3000122802D004201FB0C4E5FC491D984FF014 -:10CB4000000A08718DF818A08DF830A00CAA0A60B0 -:10CB5000ADF81CA0ADF824A02978994601F03F0259 -:10CB6000701F5B1C04F1180CD3464FF0030ECDF878 -:10CB700028C01F2A7ED2DFE802F07D7D107D227D55 -:10CB8000AE7DF77DF67DF57DF47DF77DF37D7D7DD2 -:10CB9000F27DF17D7D7D7D7DF00094F84610B5F845 -:10CBA0000100890767D5032E65D14FF40061ADF808 -:10CBB000241060808DF830E0ADF83400E9E2052EF5 -:10CBC000F2D1B5F801002083ADF81C00B5F80310D0 -:10CBD0006183002870D088426ED884F80AB0A4F827 -:10CBE00008B04FF6FF7020840A9801F0AEF80520D7 -:10CBF00089F8000002208346029011AB1D9A0A9921 -:10CC00001B9801F0A5F820B15EE000BF8DF8180078 -:10CC1000FEE29DF84A00012804D0022089F80100B4 -:10CC2000102003E0012089F8010002200390002277 -:10CC300004A912A805F08FFBE8BB9DF8101003981B -:10CC400088423ED13A88891CA2EB0B00884238DB2F -:10CC500002990220CDE900010DF146034A46414602 -:10CC60001B98FFF77DFC02980BF1020B801C81B230 -:10CC700017AA01E0ACE2B1E0029104A912A805F004 -:10CC80006AFB02999DF81000CDE9000117AB4A46F6 -:10CC900041461B98FFF764FC9DF8100011AB0BEBAD -:10CCA00000011FFA81FB02991D9A084480B202908C -:10CCB0000A991B9801E004E091E001F049F800288E -:10CCC000B5D0BBF1020F03D10A208DF818005DE248 -:10CCD000A7F800B05AE2CDF80CB0072E7ED3B5F815 -:10CCE00001002083ADF81C00B5F803206283002802 -:10CCF00075D0904273D84FF0010B84F80AB0B5F8A4 -:10CD0000050020810020A073E06900F05BFD80B980 -:10CD1000E16942F6010081F806B0E2694FF4205162 -:10CD20009180E16981F80AB0E1690881E169002038 -:10CD30008873F01F20841E984FF0070B6062A4F8E0 -:10CD400022B00A9801F001F889F800B0012083466A -:10CD500004900020ADF846002AE026E2B0E147E169 -:10CD6000EDE01FE2B0E088E04FE000BFBBF1010F53 -:10CD700015D0E0698079012803D1BDF84400ADF8F1 -:10CD80000E0004990420CDE9000103AB4A46414658 -:10CD90001B98FFF7E5FB0498001D80B20490BDF8D6 -:10CDA0004600ADF80C00ADF80E0005981FFA80FBA8 -:10CDB00011AB1D9A0A991B9800F0CAFF28B939884F -:10CDC0000BF1040005908142D0D2BBF1010F3FF47A -:10CDD0001BAFE0698079012808D001E098E023E0EA -:10CDE000BDF84410A1F57F40FF3803D1BDF84400E1 -:10CDF000ADF80E0004990420CDE9000103AB4A46CA -:10CE000041461B98FFF7ACFB62E7072E01D0152EB9 -:10CE10007ED1B5F801102183ADF81C10B5F80320C0 -:10CE2000628309B1914201D90120EFE60121A1728B -:10CE3000A4F808B084F80EB0052E07D0C0B2691D62 -:10CE4000E26905F069FA00287FF4DEAE4FF6FF7064 -:10CE5000208401A806AA09A9CDF800B080E88603BD -:10CE60002878214600F03F031D9A1B98FFF790FB9E -:10CE70008246208BADF81C0088E10120032EC7D12B -:10CE80004021ADF82410B5F801102183ADF81C1035 -:10CE90000AAAB8F1000F00D00023CDE902030492E2 -:10CEA0001D98CDF80480009038880022401E83B27F -:10CEB0001B9800F0CDFF8DF8180050BB0B2189F8AE -:10CEC0000010BDF8280038E04FF0010C052E9FD16E -:10CED0008020ADF82400B5F801102183B5F80300D7 -:10CEE0002084ADF81C10B0F5007F01D907208DE635 -:10CEF00040F47C42228412A8B8F1000F00D0002335 -:10CF0000CDE90330CDE9018C1D980090388801E00F -:10CF10009CE007E0401E83B21B9800F099FF8DF85B -:10CF2000180028B18328A7D10220C7E050000020B4 -:10CF30000D2189F80010BDF84800401C25E1C80902 -:10CF400000EB40020EEB8200B04203D948067DD5CB -:10CF500058461AE1B5F80110ADF81C102A785206AF -:10CF600008D506228DF830202A78120605D58DF8CE -:10CF700030B02FE107228DF830200323CDE9023BAA -:10CF8000DDF878C0CDF810B01D9AA6EB000800922D -:10CF9000CDF804C01FFA88F300221B9800F02EFD84 -:10CFA0008DF818008DF830B0297849060DD5208805 -:10CFB000C00506D5208BBDF81C10884201D1C4F8ED -:10CFC00024B058468DF818B0DFE0832801D14FF027 -:10CFD000020A4FF48070ADF82400BDF81C002083D5 -:10CFE000A4F820801E986062032060841321C9E0A9 -:10CFF000052E2BD3B5F80110ADF81C10A28F32B35B -:10D00000A2F57F43FE3B29D008228DF8302005236E -:10D01000CDE9023BDDF878C0CDF810B01D9A80B2A2 -:10D02000CDF804C040F400430092B5F803201B98EB -:10D0300000F0E4FC4FF400718DF818008DF830B06A -:10D04000ADF82410832813D010B301E0DBE005E035 -:10D05000A08FA0F57F41FE3907D0D9E00B228DF8D3 -:10D0600030204FF6FE72A287D1E7A4F83CB0CFE0A3 -:10D0700000942B4631461E9A1B98FFF770FB8DF8E3 -:10D08000180008B183284BD1BDF81C0020834BE762 -:10D0900000942B4631461E9A1B98FFF760FB8DF8D3 -:10D0A0001800E8BBE18FA06B0844831D8DE888035E -:10D0B0004388828801881B98FFF753FC824665E00D -:10D0C00095F80180022E6FD15FEA080002D0B8F116 -:10D0D000010F7FD109208DF8300007A800908DF84E -:10D0E00034804346002221461B98FFF71CFC8DF834 -:10D0F00036008DF837B050B9B8F1010F11D0B8F142 -:10D10000000F04D1A08FA0F57F41FF3909D0A08F77 -:10D1100038B14FF480608DF830B0ADF824000EE0E7 -:10D1200034E00CA91B98F9F7BFFF82464FF48060EA -:10D130008DF830B0ADF82400BAF1020F06D0FB48EC -:10D140000068C07928B18DF8180027E0A4F818808D -:10D1500042E0BAF1000F03D081208DF818003BE0C7 -:10D1600007A800904346012221461B98FFF7DBFBEE -:10D170008DF8180021461B98FFF7BDFB9DF818009D -:10D1800020B9192189F80010012038809DF830005D -:10D1900020B10CA91B98F9F787FF8246BAF1000F5E -:10D1A00033D019E0062031E514E02078000711D5CE -:10D1B000012E0FD10A208DF83000E088ADF8340040 -:10D1C00004201B9907F000F80820ADF824007FE543 -:10D1D000480618D54FF0040A2088BDF824100843EB -:10D1E0002080BDF8240080050BD5A18FA1F57F40DC -:10D1F000FE3806D11E98E06228982063A6864FF07C -:10D20000030A504697E4042000E59DF8180078B121 -:10D21000012089F80000297889F80110BDF81C1058 -:10D22000A9F802109DF8180089F80400052038803C -:10D230002088BDF8241088432080E2E72DE9FF4FC5 -:10D240008846087895B0012181404FF20900249C5E -:10D250000140ADF820102088DDF88890A0F57F42CD -:10D260004FF0000AFF3A02D029B1000703D5012090 -:10D2700019B0BDE8F08F239E4FF0000B0EA886F882 -:10D2800000B018995D460988ADF83410A7498DF8AB -:10D290001CB0179A0A718DF838B0086098F8000031 -:10D2A00001283BD0022809D003286FD1307820F024 -:10D2B0003F001D303070B8F80400E08098F800108E -:10D2C0000320022904D1317821F03F011B31317054 -:10D2D00094F84610090759D505ABB9F1000F13D0E2 -:10D2E000002102AA82E80B000720CDE90009BDF861 -:10D2F0003400B8F80410C01E83B20022159800F064 -:10D30000A7FD0028D1D101E0F11CEAE7B8F804003C -:10D31000A6F80100BDF81400C01C04E198F805103F -:10D320008DF81C1098F80400012806D04FF4007AFC -:10D3300002282CD00328B8D16BE12188B8F8080066 -:10D3400011F40061ADF8201020D017281CD3B4F8D8 -:10D350004010814218D3B4F84410172901D38142F8 -:10D3600012D1317821F03F01C91C3170A6F80100BB -:10D370000321ADF83410A4F8440094F8460020F0DE -:10D38000020084F8460064E105257DE176E120880D -:10D3900008F1080700F4FE60ADF8200010F0F00F6F -:10D3A0001BD010F0C00F03D03888228B9042EBD1F5 -:10D3B00099B9B878C00710D0B9680720CDE902B193 -:10D3C000CDF804B00090CDF810B0FB88BA88398849 -:10D3D000159800F013FB0028D6D12398BDF8201033 -:10D3E000401C80294ED006DC10290DD020290BD0FE -:10D3F000402987D124E0B1F5807F70D051456DD0B0 -:10D40000B1F5806F97D1DDE0C80601D5082000E0B6 -:10D41000102082460DA907AA0520CDE902218DF82A -:10D420003800ADF83CB0CDE9049608A93888CDE9BC -:10D4300000015346072221461598FFF7A9F8A7E0F7 -:10D440009DF81C2001214FF00A0A002A9BD105AB50 -:10D45000B9F1000F00D00020CDE902100720CDE97E -:10D460000009BDF834000493401E83B2218B0022D2 -:10D47000159800F0EDFC8DF81C000B203070BDF805 -:10D48000140020E09DF81C2001214FF00C0A002A16 -:10D4900022D113ABB9F1000F00D00020CDE902106A -:10D4A0000720CDE900090493BDF83400228C401E0A -:10D4B00083B2218B159800F0CBFC8DF81C000D2059 -:10D4C0003070BDF84C00401CADF8340005208DF8DC -:10D4D0003800208BADF83C00BBE000E028E0388845 -:10D4E000218B88427FF450AF9DF81C004FF0120A48 -:10D4F00000281AD1606A98B1B878C0073FF444AFE9 -:10D50000BA680720CDE902B2CDF804B00090CDF89A -:10D5100010B0FB88BA88159800F070FA8DF81C00DE -:10D52000132030700120ADF8340092E0500000204C -:10D530003988208B8142D5D19DF81C004FF0160A06 -:10D540000028A06B08D0E0B34FF6FF7000215F46C3 -:10D55000ADF808B0019027E068B1B978C907C1D12A -:10D56000E18F0DAB0844821D03968DE80C024388C1 -:10D570008288018809E0B878C007BFD0BA680DABCF -:10D5800003968DE80C02BB88FA881598FFF7E9F935 -:10D5900005005ED0072D72D076E0019005AA02A9A1 -:10D5A0002046FFF71FF90146E28FBDF808008242CE -:10D5B00001D00029F1D0E08FA16B084407800198C9 -:10D5C000E08746E09DF81C004FF0180A40B1208B20 -:10D5D000C8B13888208321461598FFF78CF938E0C8 -:10D5E00004F118000090237E012221461598FFF7D0 -:10D5F0009AF98DF81C000028EDD119203070012017 -:10D60000ADF83400E7E7052521461598FFF773F9D3 -:10D610003AE0208800F40070ADF8200050452DD18C -:10D62000A08FA0F57F41FE3901D006252CE0D8F867 -:10D6300008004FF0160A48B1A063B8F80C10A18793 -:10D640004FF6FF71E187A0F800B002E04FF6FF70DF -:10D65000A087BDF8200030F47F611AD07823002223 -:10D660000420159906F006FD98F800002071208826 -:10D67000BDF82010084320800EE000E00725208838 -:10D68000BDF8201088432080208810F47F6F1CD0C4 -:10D690003AE02188814321809DF8380020B10EA90D -:10D6A0001598F9F701FD05469DF81C000028EBD000 -:10D6B00086F801A001203070208B70809DF81C003E -:10D6C00030710520ADF83400DEE7A18EE1B1189885 -:10D6D0000DAB0088ADF834002398CDE90304CDE903 -:10D6E0000139206B0090E36A179A1598FFF7F2F959 -:10D6F000054601208DF838000EA91598F9F7D4FCDD -:10D7000000B10546A4F834B094F8460040070AD5A5 -:10D710002046FFF796F910F0760F04D114F8460F63 -:10D7200020F0040020701898BDF8341001802846BD -:10D730009EE500B585B0042806D102208DF80000D2 -:10D7400088B26946F9F7B0FC05B000BD10B5384C99 -:10D750000B782268012B02D0022B2AD111E013781A -:10D760000BB1052B01D10423137023688A889A809A -:10D770002268CB88D38022680B8913814989518123 -:10D780000DE08B8893802268CB88D38022680B8938 -:10D7900013814B8953818B899381096911612168B8 -:10D7A000F9F782FC226800210228117003D00028BA -:10D7B00000D0812010BD832010BD806B002800D0D8 -:10D7C000012070478178012909D10088B0F5205FD8 -:10D7D00003D042F60101884201D1002070470720A2 -:10D7E0007047F0B587B0002415460E460746ADF8E1 -:10D7F000144010E0069801882980811DCDE902417E -:10D800000721019404940091838842880188384656 -:10D8100000F0F4F830B906AA05A93046FEF7E2FF99 -:10D820000028E7D0822800D1002007B0F0BD00001A -:10D830005000002010B58B7883B102789A4205D150 -:10D840000B885BB102E08B79091D4BB18B789A4252 -:10D85000F9D1B0F801300C88A342F4D1002010BDFA -:10D86000812010BD072826D012B1012A27D103E05C -:10D87000497801F0070102E04978C1F3C2010529A6 -:10D880001DD2DFE801F00318080C12000AB10320D2 -:10D8900070470220704704280DD250B10DE00528D2 -:10D8A00009D2801E022808D303E0062803D00328EB -:10D8B00003D005207047002070470F20704781205B -:10D8C0007047C0B282060BD4000607D5FE48807AA6 -:10D8D0004143C01D01EBD00080B27047084670473D -:10D8E0000020704770B513880B800B781C0625D577 -:10D8F000F54CA47A844204D843F01000087000204C -:10D9000070BD956800F0070605EBD0052D78F54051 -:10D9100065F304130B701378D17803F0030341EA25 -:10D92000032140F20123B1FBF3F503FB15119268CB -:10D93000E41D00FB012000EBD40070BD906870BDB9 -:10D9400037B51446BDF8041011809DF804100A067E -:10D950001ED5C1F30013DC49A568897A814208D835 -:10D96000FE2811D1C91DC9085A422846F5F73FFBC8 -:10D970000AE005EBD00100F0070201250878954088 -:10D98000A843934018430870207820F010002070BE -:10D990003EBD2DE9F0410746C81C0E4620F00300AD -:10D9A000B04202D08620BDE8F081C74D0020344649 -:10D9B0002E60AF802881AA72E8801AE0E988491CAD -:10D9C000E980810614D4E17800F0030041EA0020E8 -:10D9D00040F20121B0FBF1F201FB12012068FFF7D8 -:10D9E00070FF2989084480B22881381A3044A06029 -:10D9F0000C3420784107E1D40020D4E72DE9FF4F13 -:10DA000089B01646DDE9168A0F46994623F440454B -:10DA1000084600F00DFB04000FD0099802F0E6FF65 -:10DA20000290207800060AD5A748817A02988142A0 -:10DA300005D887200DB0BDE8F08F0120FAE7224617 -:10DA400001A90298FFF74EFF834600208DF80C00D5 -:10DA50004046B8F1070F1AD001222146FFF702FF16 -:10DA60000028E7D12078400611D502208DF80C005F -:10DA7000ADF81070BDF80400ADF81200ADF81460F8 -:10DA80001898ADF81650CDF81CA0ADF818005FEA54 -:10DA9000094004D500252E46A84601270CE0217830 -:10DAA000E07801F0030140EA012040F20121B0FBDF -:10DAB000F1F2804601FB12875FEA494009D5B8457B -:10DAC00007D1A178207901F0030140EA0120B0429A -:10DAD00001D3BE4201D90720ACE7A8191FFA80F98B -:10DAE000B94501D90D20A5E79DF80C0028B103A97F -:10DAF0000998F9F7D7FA00289CD1B84507D1A07842 -:10DB00004FEA192161F30100A07084F804901A987B -:10DB100000B10580199850EA0A0027D0199830B151 -:10DB20000BEB06002A46199913F0E6FF0EE00BEB0B -:10DB300006085746189E099803F09AF82B46F61DDA -:10DB4000B5B239464246009502F031FC224601A9A1 -:10DB50000298FFF7C7FE9DF80400224620F010004F -:10DB60008DF80400DDE90110FFF7EAFE002061E70F -:10DB70002DE9FF4FDFF8509182461746B9F806109D -:10DB8000D9F8000001EB410100EB810440F20120D3 -:10DB9000B2FBF0F185B000FB11764D46DDF84C800C -:10DBA00031460698FFF78DFE29682A898B46611A4F -:10DBB0000C3101441144AB8889B28B4202D88420D5 -:10DBC00009B038E70699CDB2290603D5A90601D5D3 -:10DBD0008520F5E7B9F806C00CF1010C1FFA8CFCA2 -:10DBE000A9F806C0149909B1A1F800C0A90602D588 -:10DBF000C4F8088007E0104480B2A9F80800191A98 -:10DC000001EB0B00A0602246FE200699FFF798FE6C -:10DC1000E77026712078390A61F30100320AA17891 -:10DC200040F0040062F30101A17020709AF8020034 -:10DC30006071BAF80000E08000262673280602D53D -:10DC400099F80A7000E00127A80601D54FF00008F6 -:10DC50004D4600244FF007090FE0CDE90268019618 -:10DC6000CDF800900496E9882046129B089AFFF7A9 -:10DC7000C5FE0028A4D1641CE4B2BC42EDD3002050 -:10DC80009EE72DE9F047804600F0D2F9070005D065 -:10DC9000002644460C4D40F2012919E00120BDE860 -:10DCA000F087204600F0C4F90278C17802F0030240 -:10DCB00041EA0222B2FBF9F309FB13210068FFF7E6 -:10DCC00000FE304486B201E0BC060020641CA4B211 -:10DCD000E988601E8142E4DCA8F10100E88028891F -:10DCE000801B288100203870D9E710B5144631B167 -:10DCF000491E218002F07AFEA070002010BD012094 -:10DD000010BD10B5D24904460088CA88904201D39C -:10DD1000822010BD096800EB400001EB80025079C1 -:10DD2000A072D08820819178107901F0030140EA37 -:10DD30000120A081A078E11CFFF7D4FD206120889C -:10DD4000401C2080E080002010BD0121018270472E -:10DD50002DE9FF4F85B04FF6FF788246A3F800808B -:10DD600048681F460D4680788DF806004868008890 -:10DD7000ADF8040000208DF80A00088A0C88A04243 -:10DD800000D304462C8241E0288A401C2882701D62 -:10DD90006968FFF74FFDB8BB3988414501D1601E66 -:10DDA00038806888A04236D3B178307901F0030119 -:10DDB00040EA012901A9701DFFF73CFD20BB29891C -:10DDC00041452CD0002231460798FFF74BFDD8B9CA -:10DDD0002989494518D1E9680391B5F80AC0D6F8F0 -:10DDE00008B05046CDF800C002F042FFDDF800C098 -:10DDF0005A460CF1070C1FFA8CFC4B460399CDF8E0 -:10DE000000C002F097FA50B1641CA4B2204600F0A2 -:10DE10000FF90600B8D1641E2C828220D0E67C80E7 -:10DE20007079B871F088B8803178F07801F003012A -:10DE300040EA01207881A7F80C90504602F0D6FD08 -:10DE4000324607F10801FFF74DFD38610020B7E6C3 -:10DE50002DE9FF4F87B081461C469246DDF860B041 -:10DE6000DDF85480089800F0E3F805000CD048462F -:10DE700002F0BCFD2978090608D57549897A8142E6 -:10DE800004D887200BB0D6E50120FBE7CAF30906CA -:10DE90002A4601A9FFF726FD0746149807281CD03B -:10DEA00000222946FFF7DEFC0028EBD12878400647 -:10DEB00013D501208DF808000898ADF80C00BDF8C6 -:10DEC0000400ADF80E00ADF81060ADF8124002A9E4 -:10DED0004846F9F7E7F80028D4D12978E87801F026 -:10DEE000030140EA0121AA78287902F0030240EAFE -:10DEF0000220564507D0B1F5007F04D9611E81424A -:10DF000001DD0B20BEE7864201D90720BAE7801B5E -:10DF100085B2A54200D92546BBF1000F01D0ABF870 -:10DF20000050179818B1B9192A4613F0E5FDB8F159 -:10DF3000000F0DD03E4448464446169F02F0AAFE0C -:10DF40002146FF1DBCB232462B46009402F068FA0F -:10DF5000002097E72DE9F04107461D461646084682 -:10DF600000F066F804000BD0384602F03FFD21783F -:10DF7000090607D53649897A814203D8872012E5F8 -:10DF8000012010E522463146FFF7ACFC65B121784F -:10DF9000E07801F0030140EA0120B0F5007F01D8EC -:10DFA000012000E0002028700020FCE42DE9F04171 -:10DFB00007461D461646084600F03AF804000BD006 -:10DFC000384602F013FD2178090607D52049897AE1 -:10DFD000814203D88720E6E40120E4E4224631466A -:10DFE000FFF7AEFCFF2D14D02178E07801F003029A -:10DFF00040EA022040F20122B0FBF2F302FB1300E0 -:10E0000015B900F2012080B2E070000A60F301014E -:10E0100021700020C7E410B50C4600F009F828B1C3 -:10E02000C18821804079A070002010BD012010BD62 -:10E030000749CA88824209D340B1096800EB400011 -:10E040006FF00B0202EB800008447047002070471D -:10E05000BC06002010B50C4601F03AFD80B3204606 -:10E0600000F0B7FA68B32278102A09D0112A07D035 -:10E07000022A05D0032A03D0162A2ED0FFDF1DE086 -:10E08000A0781E282BD00EDC0C2824D008DC092810 -:10E0900027D2DFE800F013261726261E1E1A1C00C2 -:10E0A00012281ED11BE0302819D01ADDA0F13A0049 -:10E0B000032816D2DFE800F011150B00002010BD78 -:10E0C00013E010E043F20200F9E70420F7E70D2027 -:10E0D000F5E70F20F3E70820F1E71120EFE707202D -:10E0E000EDE70320EBE7FFDFE8E7FFDFE6E700F01F -:10E0F00070BA70B50346002002466FF02F050EE09F -:10E100009C5CA4F130060A2E02D34FF0FF3070BDA4 -:10E1100000EB800005EB4000521C2044D2B28A4242 -:10E12000EED370BD30B50A240AE0B0FBF4F304FB73 -:10E1300013008D18303005F8010C521E1846D2B26B -:10E14000002AF2D130BD30B500234FF6FF7510E044 -:10E15000040A44EA002084B2C85C6040C0F303149F -:10E16000604005EA00344440E0B25B1C84EA4010A1 -:10E170009BB29342ECD330BD10B50AF0FFF90428EE -:10E1800003D00AF0FBF9052802D108F0A0FC28B959 -:10E190000BF056FB20B107F047FB08B1012010BD82 -:10E1A000002010BD0178406819B190F8721059B97B -:10E1B00001E001F017BD90F8041129B190F80401B5 -:10E1C000042801D0012070470020704770B50C462C -:10E1D0000546062102F042FC606008B1002006E01E -:10E1E0000721284602F03AFC606018B10120207037 -:10E1F000002070BD022070BD2DE9FC470C4606468C -:10E200006946FFF7E3FF00287DD19DF8000050B17B -:10E2100007F09CFAB0427CD0214630460EF0A1F9BE -:10E22000002873D12DE008F065F9B04271D0214685 -:10E2300030460CF041FC002868D1019D95F8C800DB -:10E2400022E0012000E00020804695F835004FF0E4 -:10E25000010A4FF00009F0B195F8360080071AD591 -:10E2600084F8019084F800A084F80290A68095F8C4 -:10E270003710A171298F2181698F618185F83590CF -:10E2800044E0019D95F8040158350028DBD1A87EB3 -:10E290000028D8D0D5E7304602F0FCFC070000D1BA -:10E2A000FFDF384601F051FE40B184F801900E21A5 -:10E2B0002170A680E08084F802A027E0304602F0BA -:10E2C000D7FC070000D1FFDFB8F1000F21D038469E -:10E2D00001F0CCFEB8B19DF8000038B90198D0F833 -:10E2E000F0004188B14201D180F80090304607F03B -:10E2F000C3F884F801900B21217084F80290A68065 -:10E30000E97EA17100E004E085F81A900120BDE8E3 -:10E31000FC870020FBE71CB56946FFF757FF00B1FB -:10E32000FFDF684601F06CFCF94900208968A1F81C -:10E33000CA001CBD2DE9FC4104460E46062002F031 -:10E3400037FB0546072002F033FB2844C7B20025FF -:10E35000A8463E4417E02088401C80B22080B0428E -:10E3600002D34046A4F8008080B2B84204D3B04241 -:10E3700002D20020BDE8FC816946FFF727FF002894 -:10E38000F8D06D1CEDB2AE42E5D84FF6FF7020809C -:10E390001220EFE738B54FF6FF70ADF800000DE042 -:10E3A0000621BDF8000002F06BFB04460721BDF812 -:10E3B000000002F065FB0CB100B1FFDF00216846F0 -:10E3C000FFF7B8FF0028EBD038BD2DE9F047D1A109 -:10E3D0000F79D1F8008007F0BDF810F003F8CF4CAA -:10E3E0004FF004091020A4F8389060874FF6FF76AC -:10E3F000A4F85460A4F85660002584F8315004F85D -:10E400002E5BC6492570A5713E39A573C1F87B8086 -:10E4100081F87F707B31481E0CF029FD25751B208B -:10E42000E0824FF4A47121836083A1830321A1774B -:10E4300084F81F9020846084B848A1843E38057019 -:10E440004680B3480C300570B448103805704680DB -:10E45000BDE8F08770B5AE4C0D466060217006F0E7 -:10E46000F3FFFFF797FFFFF7B0FF207809F031FDCA -:10E4700008F02EF9217860680CF00CFC20780FF081 -:10E4800011FA28460AF071FE07F06AF921786068EF -:10E490000EF068F9BDE870400FF0A4BF10B501247C -:10E4A0000AB1002010BD21B1012903D0002420466B -:10E4B00010BD022111F0C6FBF9E72DE9F047040079 -:10E4C00000D1FFDF954D002695F8310058B16670F8 -:10E4D0001620207095F83200A07095F83300E07097 -:10E4E00085F8316068E0287840B12C22A91C2046CC -:10E4F00013F002FB102020702E705DE095F82E00C6 -:10E5000060B10120E07095F82F00A07095F8300000 -:10E5100060701120207085F82E604DE07F48022148 -:10E5200056308246FFF706FF00B1FFDFB5F8569080 -:10E53000062002F03DFA0746072002F039FA384477 -:10E54000C7B2781C00F0FF08B5F85600B84212D1E7 -:10E55000204607F04BFF50BB95F8340070B366704F -:10E56000132020702021A01C13F03DFB0220A0707E -:10E5700085F8346020E040451AD1204607F09CF829 -:10E58000E0B12078132817D1A0783C2814D1A088B6 -:10E59000072102F063FA050000D1FFDF288806F0AA -:10E5A0006BFFA088072102F06BFA00B1FFDF03E0E8 -:10E5B0002146FFF721FE08B1012049E7022150461C -:10E5C000FFF7B8FE18B9B5F856104945BCD1002080 -:10E5D0003EE772E710B5514C207828B10A21BDE81A -:10E5E0001040102001F0A1BAFFF7C6FD08B10C20C1 -:10E5F00002E00FF042FF00202071012060710A212B -:10E60000E170207010BD70B5444D0446287828B1E3 -:10E61000BDE870403221102001F087BA207818B18F -:10E62000012801D0122010E001F090FA20B110F082 -:10E630006EF808B10C2008E0207801F057FA04F1D8 -:10E640001703E21D611C0FF06FFF28710120687134 -:10E650003221E970287070BD70B5304C05462078C5 -:10E6600028B1BDE870400B21102001F05EBA287877 -:10E6700018B1012801D012200EE0FFF77DFD08B18E -:10E680000C2009E0287801F031FA691C0FF0BCFE7B -:10E6900008B1002000E007202071012060710B21EB -:10E6A000E170207070BD10B51C4C217829B130216B -:10E6B000BDE81040102001F038BA008810F02AF8A8 -:10E6C000302110B10020207100E021710120607123 -:10E6D000E170207010BD70B5104C0546207828B14F -:10E6E000BDE870403121102001F01FBA01F02EFA70 -:10E6F00008B10C2005E0287800F0010010F004F8C3 -:10E7000000202071012060713121E170207070BD06 -:10E7100058000020FFFFFFFF1F0000000607002039 -:10E7200010B5FB4C207828B13421BDE810401020F2 -:10E7300001F0FBB901F00AFA20B10FF0E8FF08B1CF -:10E740000C2002E00FF044FF0020207101206071D6 -:10E750003421E170207010BDED48017819B10F210E -:10E76000102001F0E2B900210171102181700F2108 -:10E77000C170FF2181714FF6FF710181E549496840 -:10E780000A7882728A8882814988C1810121417117 -:10E790000170704710B5DE4C207828B12B21BDE800 -:10E7A0001040102001F0C1B90821A01D05F029FA80 -:10E7B00000202071012060712B21E170207010BDBC -:10E7C00070B5D34C217829B1BDE8704043211020A9 -:10E7D00001F0ABB990F90000042816D0032814D03A -:10E7E00098B1011D11D010F1080F0ED010F10C0FCF -:10E7F0000BD010F1100F08D010F1140F05D010F14C -:10E80000280F02D01220207103E0002506F020F826 -:10E8100025714320E07001206071207077E710B50A -:10E82000BB4C217829B12A21BDE81040102001F00D -:10E830007CB9A31D012200F1100110F03AFE002066 -:10E8400020711020A0702A20E070012060712070DB -:10E8500010BD70B5AE4C0546207828B1BDE87040BB -:10E860004621102001F061B909F088FE052804D086 -:10E87000284609F01BFB002000E00C20207101203D -:10E8800060714621E170207041E770B5A04C0546EB -:10E89000207828B1BDE870404421102001F045B92E -:10E8A00001F054F938B10C2020710120607144212D -:10E8B000E17020702BE72946002006F04CFE002076 -:10E8C000F2E770B5924C0546207828B1BDE870405B -:10E8D0004221102001F029B909F091FB50B10AF052 -:10E8E000A2FF38B128780AF064FC287808F026F9ED -:10E8F000002000E00C202071012060714221E170B5 -:10E90000207004E770B5824C0546207828B1BDE838 -:10E9100070401721102001F008B901F017F938B143 -:10E920000C202071012060711721E1702070EEE64B -:10E930002946012006F00FFE0020F2E738B5744D9D -:10E940000446287828B1BDE838404D21102001F058 -:10E95000ECB8A079E179884213D021791F2910D829 -:10E9600061791F290DD80022114612F0C7FA40B96B -:10E970000022E079114612F0C1FA10B9207A072876 -:10E9800001D9122012E04FF6FF70ADF800000AF036 -:10E9900057FF90B909F0F2FD78B900216846FFF7FA -:10E9A000C9FC50B1204605F070FE002028710120FE -:10E9B00068714D21E970287038BD0C20F6E72DE90B -:10E9C000FC47534C054694F82E0020B12821112015 -:10E9D00001F0ABF89BE4282084F83000012184F892 -:10E9E0002E10A8784FF000091A2825D00EDC162822 -:10E9F00031D2DFE800F0303030303021303030308C -:10EA00003030303030303030302121212A2822D0AF -:10EA10000BDCA0F11E000C281DD2DFE800F01C1C4E -:10EA20001C1C1C1C1C1C1C1C1C0D3A38042812D25B -:10EA3000DFE800F0110211022888B0F5706F0AD2E9 -:10EA40001F20884684F82F0028886946FFF7BEFB00 -:10EA500018B1022019E0122017E09DF80000019F74 -:10EA6000002806D007F5B377019E05D106F1ED0623 -:10EA700004E007F1EC07F7E706F267166846FFF7D0 -:10EA800091FB08B1387818B10C2084F82F003EE4CF -:10EA900087F80080A878307084F82F90684601F0DD -:10EAA000AFF834E47CB51A4C0546207820B1252116 -:10EAB000102001F03AF87CBD28886946FFF786FBF4 -:10EAC000020013484FF00001A0F13E000DD00222D9 -:10EAD000227140F8461F0171E1801020A0702520AE -:10EAE000E0700120607120707CBD019A134658329D -:10EAF00082F83E109E68C0F846601E7B80F84A602F -:10EB000092F83E60002EF3D12888E080E5E700000F -:10EB1000060700205800002010B540B10478406876 -:10EB200013B1B0F8480003E0B0F84A0000E0FB2061 -:10EB30001B2908D3814206D8B2F5A47F03D340F63F -:10EB40004800824201D9122010BD002010BD2DE9DD -:10EB5000FC41FA4D0446287828B1BDE8FC4150211B -:10EB6000102000F0E2BF4FF0010885F805801F215A -:10EB700029711021A9705021E9702188E98085F858 -:10EB8000008020886946FFF721FB08B102200DE0D4 -:10EB90002289E18801236846FFF7BEFF30B9A288C9 -:10EBA000618800236846FFF7B7FF10B12871BDE800 -:10EBB000FC819DF800103A20019E002749B186F89B -:10EBC0008981019991F8C81106F5C476B9B1287107 -:10EBD00013E086F8FD80019991F82011FC36002998 -:10EBE000F5D12F71E08870802089B0806088F08036 -:10EBF000A0883081012201990CE07770D7E72F714E -:10EC0000E08870802089B0806088F080A0883081A2 -:10EC100001990022304610F091FD86F80080ECE763 -:10EC200070B5C64D044686B0287830B106B0512183 -:10EC3000BDE87040102000F078BF01206871002608 -:10EC40002E711021A9705121E9702870208803A924 -:10EC5000FFF7BCFA18B10220287106B057E59DF8FD -:10EC60000C0040B100220499E088B1F84830984285 -:10EC700003D9C01A02E00122F5E70020E88063888A -:10EC8000B1F84A00834201D9181A00E00020288117 -:10EC9000009601960296E088ADF802002089ADF852 -:10ECA00004006088ADF80600A088ADF8080068464A -:10ECB00010F044FD2089BDF80410401A6881A08836 -:10ECC000BDF80810401AA881E088BDF80210401A6B -:10ECD000E988884200DC0846E8806088BDF80610B4 -:10ECE000401A2989884200DC08462881B5E770B5BA -:10ECF000924D0446287828B1BDE870403E2110208E -:10ED000000F013BF00F022FF20B10FF000FD08B1AA -:10ED10000C2008E0E2792078611C0FF07BFE08B13E -:10ED2000002000E002202871012068713E21E97076 -:10ED30002870ECE47CB5814C05461F2084F82F0038 -:10ED400028886946FFF742FA18B1022084F82F009C -:10ED50007CBDAA7802B90322EB7803B903239DF89E -:10ED600000603A2501210020002E019E06D086F881 -:10ED70009311019E96F8DC6146BB1FE086F80711EF -:10ED8000019E96F82C613EB9019E96F806611EB967 -:10ED9000019E96F87B6016B184F82F500AE0019D21 -:10EDA00085F80611019981F80821019981F8093146 -:10EDB00084F82F00019981F807017CBD019E96F827 -:10EDC00092611EB9019E96F87B6016B184F82F50AF -:10EDD0000AE0019D85F89211019981F89421019929 -:10EDE00081F8953184F82F00019981F893017CBD59 -:10EDF000524930B491F82E2022B1562130BC112056 -:10EE000000F093BE562281F83020012281F82E2096 -:10EE10008378DA0802D1C278D40801D0122004E045 -:10EE20005B0701D4520704D5112081F82F0030BCB4 -:10EE3000704730BC7EE770B5404C0546207828B15D -:10EE4000BDE870401D21102000F06FBE1F20207112 -:10EE5000012060711D21E170207009F08FFB0428F2 -:10EE60000BD0052809D0A9791220012907D031B18A -:10EE7000022904D0032929D101E00C2026E02978B9 -:10EE800009B1012922D1E97929B1012903D0022947 -:10EE900001D003291AD1698843F6FD720B1F302077 -:10EEA000934213D2AB881B1F93420FD22187A888AD -:10EEB0006087A87907F065FDE87907F0D0FD28782C -:10EEC000012805D00120002107F0F8FD20711EE483 -:10EED0000220F8E770B5194C217829B1BDE87040DF -:10EEE0001E21102000F021BE1F212171012161711E -:10EEF0001E22E270217002781221012A00D01AB974 -:10EF0000407818B1012801D0217187E40025012A39 -:10EF100009D009F033FB0C26052802D008F008FFC1 -:10EF200088B126717AE407F022FD48B107F031FD7F -:10EF3000618F208F09F070F803E0000006070020C1 -:10EF4000122020716AE4257168E42DE9F047F94C3C -:10EF500007469246B4F84400B7F84A200E4690425D -:10EF600000D31046804697F85210104600F0D4FDAA -:10EF7000B4F84610814200D208460546A146B4F8CE -:10EF80004840B7F84800844200D3044697F851102F -:10EF900000F0C2FDB9F84A10814200D208464FF491 -:10EFA000A4721B2C01D0904204D1B8F11B0F0DD0DC -:10EFB00095420BD0A6F8068035817480B080524609 -:10EFC0003946304610F0BAFB01203070BDE8F087BA -:10EFD0002DE9F04786B00546AFF6C800D0E90090AD -:10EFE000D44E804696F82E0028B12121112000F041 -:10EFF0009CFD06B0EAE71F2086F82F00212086F846 -:10F0000030004FF0010A86F82EA0284600F007FED7 -:10F01000002811D109F0B2FA05280CD009F0AEFA97 -:10F02000042808D096F8340028B907F063FAA0F550 -:10F030007F41FF3901D00C20AAE0BE4801AA3E382A -:10F040000190BD480290BB4806211038039004A8E7 -:10F0500001F0D4FC04007DD003210FF0DAFFB6F8F4 -:10F060004E00A4F84800B6F85000A4F84A0096F8FC -:10F070004D00009096F84C30B6F85020B6F84E107F -:10F08000208801F07EFD00B1FFDF208806F0F3F953 -:10F09000218804F10E0000F068FDA8A004F1120719 -:10F0A000006800900321684604F033FD00206946A3 -:10F0B0000A5C3A54401CC0B20328F9D3288A608005 -:10F0C000688AA080A88AE08094F8522094F85110B1 -:10F0D000B6F8520009F01DF80146A062204609F07A -:10F0E00038F8002784F85E7084F85F70687900F063 -:10F0F000FDFC6076D5F80600C4F81A006889E08344 -:10F10000C4F8089084F80C8084F8F8A0012204F177 -:10F11000FC012046FFF719FF8DF8007001216846B9 -:10F1200004F0F7FC9DF8000000F00701C0F3C102F5 -:10F130001144C0F3401008448DF80000401D2076B3 -:10F14000092801D208302076002120460FF061FF07 -:10F15000287B00E010E007F014FC69792879AA1DEB -:10F1600007F0E5FB50B107F014FC69792879AA1D76 -:10F1700007F080FC78B118E0092009E0208806F04B -:10F180007BF92088062101F07BFC00B1FFDF122013 -:10F1900086F82F002DE72146032007F08FFC20B9C9 -:10F1A0006A882988204608F0C0FE86F82F000028CB -:10F1B000F0D0208806F060F92088062101F060FC7C -:10F1C0000028E7D0FFDF14E738B55A4C207820B18B -:10F1D0002221102000F0A9FC38BD1F20207101253C -:10F1E00065712220E070257094F8340018BB09F096 -:10F1F000C5F9052805D007F07DF9A0F57F41FF3955 -:10F2000019D000202071684608F055FF0028E3D18E -:10F210000098008806F030F900980621008801F077 -:10F220002FFC00B1FFDF444884F834500C380078DC -:10F23000FCF760FD38BD0C20207138BD2DE9F04190 -:10F240003C4D044695F82E0028B1BDE8F04123213D -:10F25000112000F06ABC1F2085F82F00232085F8BC -:10F260003000012085F82E00618840F67B438A1F1C -:10F2700030209A4252D2A288961F9E424ED291428C -:10F280004CD8E188B1F5FA7F48D2218940F677461B -:10F29000A1F10A03B34241D2B1EBD20F3ED9618949 -:10F2A000A28991423AD84FF000082088062101F047 -:10F2B000D5FB06004FF0020707D000F093FC20B109 -:10F2C000D6F8F000017841B903E085F82F70BDE869 -:10F2D000F081D6F83C11097809B13A201EE00521E9 -:10F2E0008171D6F8F0004146A0F80880D6F8F020E9 -:10F2F000A0885081D6F8F020E0889081D6F8F020E0 -:10F300002089D081D6F8F000028943899A4204D836 -:10F310008279082A01D89A4203D3122085F82F0057 -:10F32000D5E722884280D6F8F000077085F82F10C4 -:10F33000CDE7000006070020640000201122330002 -:10F34000FEB5F84C0646207820B12421102000F0AC -:10F35000ECFBFEBD012565712420E0702570304670 -:10F3600010F042F808B1002000E0122020710028BF -:10F37000EFD1EC4884F83C503E38316840F87B1FB0 -:10F3800031790171002684F83C606946062001F05D -:10F39000F0FA00B1FFDF684601F0C9FA60B9BDF8C4 -:10F3A0000470029880F8F850684601F0C0FA18B965 -:10F3B000BDF80400B842F4D12671FEBD2DE9F0413C -:10F3C000D84D064695F82E0028B1BDE8F0412C2115 -:10F3D000112000F0AABB1F2085F82F002C2085F8F3 -:10F3E0003000012085F82E003088062101F036FB20 -:10F3F000040007D000F0F6FB20B1D4F8F010087834 -:10F4000030B901E0022026E0D4F83C01007808B1D0 -:10F410003A2020E094200027005D10F0010F19D061 -:10F42000D6F802004860D6F80600886054F8F00F5D -:10F43000718910228181206806F10C010E3012F0D2 -:10F440005BFB21680320087021683088488085F8BC -:10F450002F703CE70C2085F82F0038E72DE9F041AC -:10F46000B04D04460C26287828B1BDE8F04118219B -:10F47000102000F05ABB0AF0E3F9012730BB607995 -:10F48000032824D8A179012921D8A17B03291ED8DA -:10F49000617BE1B107291AD82179052917D2DFE864 -:10F4A00001F0030C030303002288202A0FD3618894 -:10F4B0008A420CD8B1F5804F09D806F0D6F92079E8 -:10F4C00085F83600204606F098FA064600E0122637 -:10F4D0002E716F711820E8702F70F8E610B5914CFE -:10F4E000217829B11A21BDE81040102000F01DBB81 -:10F4F00001781F2902D91220207106E00021217114 -:10F500000278411C104606F0FCFA012060711A21B5 -:10F51000E170207010BD10B5824C217829B12021F6 -:10F52000BDE81040102000F000BB01781F2902D96F -:10F530001220207106E0002121710278411C104642 -:10F5400006F0CEFA012060712021E170207010BD1C -:10F550002DE9FC41734C217829B1BDE8FC411B2108 -:10F56000102000F0E2BA012767710C2121710078A8 -:10F5700000261225012802D0002866D167E006F097 -:10F5800024F900285ED006F056F900285AD00AF077 -:10F5900057F900286CD106F06FF994F8360050B195 -:10F5A000012808D0042806D0002009F005FE00B18B -:10F5B000FFDF26715CE006F0C9F8A0F57F41FF3956 -:10F5C00056D10022072101A801F018FA05004FD0FA -:10F5D00055480321856028460FF0E2FB284606F0D7 -:10F5E000BAFBB4F84E00A5F84800B4F85000A5F8EE -:10F5F0004A00B4F8520001214C3409F016FF0146CC -:10F60000A8620022284608F0CEFF6078009014F827 -:10F61000043B288834F8022934F84E1901F0B1FA75 -:10F6200000B1FFDF288805F026FF284609F0C4FD59 -:10F6300000B1FFDF2671002205F5C4712846FFF7EF -:10F6400084FC15E006F0C1F890B1257110E008F0D7 -:10F65000A7FF054609F0E8FC50B9267145B1288896 -:10F6600005F00AFF2888072101F00AFA00B1FFDF40 -:10F670001B20E0702770BDE8FC812DE9F041294C8A -:10F680000646207828B1BDE8F0412D21102000F079 -:10F690004CBA3088072101F0E1F905004FF001076D -:10F6A00020D095F8690140B995F86400142801D07C -:10F6B000152802D195F8AA0150B10C202071102014 -:10F6C000A0702D20E0703088E08067712770FEE523 -:10F6D0001022B11C05F5B57012F00EFA85F86971AB -:10F6E0000020EBE70220E9E770B50E4C05462078D4 -:10F6F00028B1BDE870402E21102000F016BA2888ED -:10F70000072101F0ABF90221A0B190F869212AB9D3 -:10F7100090F86420142A09D0152A07D00C202071F3 -:10F7200009E00000060700205800002080F8691159 -:10F730000020F4E721711020A0702E20E0702888AE -:10F74000E08001206071207070BD2DE9FC47FD4C08 -:10F750000646207828B13821102000F0E6F9BDE8EF -:10F76000FC8770884BF68032122190420AD848B14B -:10F770004FF0000830886946FEF728FD20B10220CE -:10F78000207110E021710EE0019800F15809851CEC -:10F790002F887288394648460FF0BCFA2888B8424C -:10F7A000F6D184F80480012060713821E170207066 -:10F7B000D5E77CB5E34C0546207820B149211020DF -:10F7C00000F0B3F97CBD28886946FEF7FFFC38B12C -:10F7D00002202071012060714921E17020707CBD00 -:10F7E00001987F22014680F8602080F86120002285 -:10F7F00080F86220A87801F82C0FE8784870287902 -:10F8000088702271E6E71CB5CE4C217821B15421D5 -:10F81000102000F08AF91CBD00886946FEF7D6FC6E -:10F8200048B102202071012060715421E170102143 -:10F83000A17020701CBD019890F8720000B10120E9 -:10F8400000212171A071EEE71CB5BE4C217821B1D9 -:10F850001321102000F069F91CBD00886946FEF7ED -:10F86000B5FC08B1022005E0019890F82C100129A0 -:10F8700002D00C20207106E0602100222271095C78 -:10F8800021720088E080012060711321E170102155 -:10F89000A17020701CBD2DE9F041AA4C05462078CE -:10F8A00028B1BDE8F0414A21102000F03EB9288877 -:10F8B000072101F0D3F8012358B382886D88C688E8 -:10F8C000418803EB4207BD4217D342F210777E43D3 -:10F8D000BF107943B6FBF1F1491E89B24FF4FA76B5 -:10F8E000B14200D931468D4200D22946491C521CF2 -:10F8F000B1FBF2F15143491E8AB290F8961101B959 -:10F900000284E2800020207163714A20E07023703D -:10F91000DDE40220F7E770B58A4C0546207828B16F -:10F92000BDE870404C21102000F0FFB82888072166 -:10F9300001F094F890B1A97811F0010180F8D71086 -:10F9400004D090F8D51009B109F08AFD002020718B -:10F95000012060714C21E170207070BD0220F6E73B -:10F9600078490A781AB15221102000F0DEB80278E6 -:10F970009AB142788AB142881B2A0ED382881B2A08 -:10F980000BD3C288022A08D36E4A0368423242F877 -:10F990000A3F40685060002000E0122008710120FA -:10F9A00048715222CA700870704770B5654C0546A0 -:10F9B000207828B1BDE870405321102000F0B5B880 -:10F9C000287800F0010008F0A1FB287800F0010081 -:10F9D00009F0F7FC00202071012060715321E170D3 -:10F9E000207070BD70B5574D0646287828B1BDE827 -:10F9F00070405521102000F098B8012270881146FF -:10FA000008F087FB04467088012109F00EFD84424E -:10FA100000D204463088012100F06FF8064601212B -:10FA2000002000F06AF8304401219630844206D963 -:10FA300000F19601201AB0FBF1F0401C81B2E98080 -:10FA400000202871012068715521E970287070BD6F -:10FA500070B53C4D0446287828B1BDE870404E2171 -:10FA6000102000F062B800F071F808B10C200DE031 -:10FA7000601C0EF0A5FF207800F0010005F0F8FEF4 -:10FA8000207800F0010006F080FF0020287101209E -:10FA900068714E21E970287070BD70B5294C05461B -:10FAA000207828B1BDE870404B21102000F03DB80F -:10FAB00009F0C6FE08B10C2003E0287806F031F802 -:10FAC00000202071012060714B21E170207070BD19 -:10FAD00010B50178572907D21B4A52F8211019B1E5 -:10FAE000801C8847012010BD002010BD18B10228DD -:10FAF00001D0012070470020704710B5012904D0C3 -:10FB0000022905D0FFDF204610BDC000503001E0C3 -:10FB100080002C3084B2F6E7022903D0C000703098 -:10FB200080B2704780003C30FAE7064A92F83130E4 -:10FB3000002B06D182F8320082F83310012082F8BF -:10FB40003100704706070020C420020010B508F0FD -:10FB500015FD042807D008F011FD052803D009F091 -:10FB60006FFE002800D0012010BD2DE9FE430025C6 -:10FB70000F4680460A260421404604F042F84046DB -:10FB80000FF00EFC062000F013FF044615E0694656 -:10FB9000062000F0EEFE0AE0BDF80400B84206D0F0 -:10FBA0000298042241460E3011F07AFF50B16846A7 -:10FBB00000F0BDFE0500EFD0641E002C06DD002D18 -:10FBC000E5D005E040460FF0F4FBF5E705B9FFDFAF -:10FBD000D8F800000FF0A8F8761E01D00028CAD08F -:10FBE000BDE8FE8390F8721041B990F8C81029B1B1 -:10FBF00090F8C800042801D00120A2E70020A0E767 -:10FC0000017801299DD1416891F8D520002A98D02A -:10FC1000002281F8D520406809F022BC91E710B598 -:10FC2000038843F6FD711A1F8A4223D24288141FAB -:10FC30008C421FD29A421DD8C28940F67B43911F45 -:10FC4000994217D2018A8C1F9C4213D28A4211D842 -:10FC5000428AB2F5FA7F0DD2828A40F67744A2F149 -:10FC60000A03A34206D2B2EBD10F03D9C18A028B99 -:10FC7000914201D9302010BD017911B1012910D173 -:10FC800007E0417929B1012903D0022901D00329D4 -:10FC900007D1007B38B1012805D0022803D0032802 -:10FCA00001D0122010BD002010BD00000844083013 -:10FCB000424301F14A00104480B27047F0B51D463E -:10FCC0000446A818059B083000FB03F205F14A0022 -:10FCD000104486B2B14238BFFFDF0027276067605B -:10FCE000A760E76027616761A761E76127624FF658 -:10FCF000FF706762A082A6F1280080B265776080FD -:10FD0000B0F5004F88BFFFDF608805F13C018842F5 -:10FD100038BFFFDF6088401B3C3880B220801B2842 -:10FD200038BF1B202080A777F0BD816188617047B4 -:10FD30002DE9F04F0D46C188044600F128080089DE -:10FD400021F4004320F4004221F4004620F400474F -:10FD50004FF0010A4FF000099A4208D100F4004028 -:10FD600001F4004188421CBF0020BDE8F08FB7427B -:10FD70000BD9617FB81B401A083885421BDC08EBA1 -:10FD800006000021058041801EE06088617F801BA5 -:10FD9000401AB0F1080B0ED4BBF11B0FB8BFFFDF48 -:10FDA0005D45D4BF29461FFA8BF1681A0204120C74 -:10FDB00018BFBA4204DD84F817900020BDE8F08F28 -:10FDC00008EB06000180428084F817A0BDE8F08FA0 -:10FDD0002DE9F041044600F12802C08820F40043D8 -:10FDE000E07D002808BFBDE8F081D0180288438874 -:10FDF00013448B423CBF0020BDE8F08100279142B4 -:10FE00009CBF0180478013D9891A0D042D0C4580B1 -:10FE10000ED0E088A61D20F40040854288BFFFDF99 -:10FE200030884FF4004121EA0000284330800AE086 -:10FE3000627F008802F108031044083081B26288B2 -:10FE4000A01D00F0A8FBE7750120BDE8F08130B4EB -:10FE5000B0F804C0C488034600F128052CF4004023 -:10FE60002844A44503D10020188230BC7047B3F861 -:10FE70000CC00488A44509D34088ACEB040CA0EB6B -:10FE80000C0084B20CEB0500C01E06E0A4EB0C04D1 -:10FE90005D7FA4B2AC446044401DB1F800C0A445ED -:10FEA00088BF0C80B3F80CC0BCF1000F0CBF4FF042 -:10FEB000010C4FF0000C82F800C00988198230BC98 -:10FEC00070472DE9F041044600F12801808820F4B4 -:10FED00000404518208A002808BFBDE8F081A089AD -:10FEE00010B9A069807F2871A089218A084480B256 -:10FEF000A08129886A881144814238BFFFDF2888A1 -:10FF00006D88A2894119002791421AD175B1A08844 -:10FF1000261D20F40040A84238BFFFDF30884FF490 -:10FF2000004121EA00002843308009E0627F10444C -:10FF3000083081B202F108036288201D00F02BFB1B -:10FF4000A78127820120BDE8F0812DE9F047418992 -:10FF5000B0F804800027044600F1280A414518BF84 -:10FF60004FF400493AD000BF21F400405044468885 -:10FF70006EB1608904F10A0520F40040B04238BF38 -:10FF8000FFDF288829EA00003043288021E0637FD2 -:10FF9000008803F1080C18446389083023F40045F5 -:10FFA0006288284480B204F10A0190420BD2121AEE -:10FFB00092B20CF11B0C62452CBF03F4004229EAFB -:10FFC000030004D204E0801A80B229EA030210433D -:10FFD0000880781C618987B24145C5D13846BDE8A3 -:10FFE000F0872DE9F047B0F808800B46044600F191 -:10FFF0002801B0F80A90808828F4004C01EB0C0529 -:020000040001F9 -:10000000804504BF0020BDE8F087002A1CBF681DA2 -:10001000106023B1627F691D184611F06DFD2F88B5 -:100020006D888DB1E81987B2208904F1080620F4A3 -:100030000040A84238BFFFDF30884FF4004121EA7A -:100040000000284330800AE0607F6288C1190831CF -:1000500000F1080389B204F1080000F09CFAC845D9 -:1000600004BF208960813846BDE8F0878188C08858 -:1000700081420CBF012000207047018980888142A5 -:100080000CBF01200020704730B48488C28800F182 -:10009000280324F4004C22F40041634494421BD012 -:1000A0008289048A15191C885A88A3189D4216D380 -:1000B00012B18A4210D212E0437F0CF1080C1A19D7 -:1000C0006244408892B2801A80B22333984201D2AF -:1000D00011B104E08A4202D130BC0020704730BC2C -:1000E000012070472DE9F007B0F806C0048900F13F -:1000F000280702462CF400457E1924F400492CF40C -:10010000004A002024F400434FF00108D1450AD1F1 -:1001100004F400440CF4004C644504D05082BDE863 -:10012000F00700207047AB4208D992F81DC05B1B56 -:10013000A3EB0C03A3F10804002308E0B2F802C00B -:10014000547FACEB050CACEB040CACF10804002CB8 -:10015000E4DBB2F80EC0BCF1000F0DD0B6F800C061 -:1001600075884DB15B1B10778B42D7DBD089384443 -:10017000A0EB0C00C01E09E0A4EB0C0410778C422D -:1001800008DB507FD38918443044401D5182BDE8BC -:10019000F00770478B42A8BF82F81C80E6DABDE703 -:1001A0002DE9F05F044600F1280AC088934620F448 -:1001B00000400AEB0005608A894608B1484502D232 -:1001C0000020BDE8F09FE08980B1B5F800806E881E -:1001D00008EB0601884218BFFFDF207F4FF00007C1 -:1001E00050EA060108D0002840D04AE04FF000084D -:1001F000A17F46462971F0E7E08948B1617F01445B -:100200004819B4F81F10A0F8051094F82110C17116 -:10021000E18908EB09004944E18128806F80BBF146 -:10022000000F19D0607F298800F1080301440831CC -:1002300089B26288A01D00F0AEF9E781A07F401C62 -:10024000A077A07D00281CBFE088A082A7756782E8 -:10025000E7750120BDE8F09F607FE18908442844EC -:10026000B0F80510A4F81F10C0792EE0E089B4F8AA -:100270001F105044A0EB080020F8031D94F8211033 -:10028000817006EB090086B2E089BBF1000F48449B -:10029000E081A5F800806E800ED0E088A51D20F4D6 -:1002A0000040B04238BFFFDF28884FF4004121EA08 -:1002B000000030432880C0E7E0895044A0EB0800EC -:1002C00030F8031DA4F81F10807884F82100BEE7E1 -:1002D000818800F1280221F4004C6244B0F814C077 -:1002E000C388614518BF99420FD0818969B9806977 -:1002F00068B101898388994209D021F400412830EE -:10030000084411790079884201D1002070471046D5 -:10031000704700F12803407F01F1050C6044106034 -:100320000888002804BFD81E10600888498808443F -:1003300080B270472DE9F04115460A4600F12806C3 -:100340001C46407F531D0344108857880699002897 -:100350001CBFC01C80B226D088429CBF081A80B245 -:1003600013D9401AA042A8BF20461FFA80F8581897 -:100370004246294611F094FB002818BFBDE8F081E1 -:100380004544A4EB080084B2002001198F423CBF11 -:100390004FF0FF30BDE8F081304422462946BDE8E9 -:1003A000F04111F07DBBFA1C97B2F61ED4E72DE99F -:1003B000F04100F128071D46407F4B1D03441646BF -:1003C00008880024B1F80280069A00281CBFC01CCF -:1003D00080B21FD090429CBF101A80B20DD9801AF3 -:1003E000A842A8BF284684B299182246304611F088 -:1003F00083FB281B85B2264400204119414506D8BD -:1004000039182A46304611F077FB601984B220462D -:10041000BDE8F08108F103011FFA81F8FF1ED9E75A -:100420002DE9F04116460A4600F128071D46407F97 -:10043000531D034410880024B2F802800699002856 -:100440001CBFC01C80B21FD088429CBF081A80B25B -:100450000DD9401AA842A8BF284684B2581822468F -:10046000314611F049FB281B85B226440020411972 -:10047000414506D838442A46314611F03DFB601903 -:1004800084B22046BDE8F08108F103021FFA82F829 -:10049000FF1ED9E7401D704770B5044600F12801E2 -:1004A000C288808820F400431944904208D0A28971 -:1004B000002A04BF228A002A02D1A28A904201D1D6 -:1004C000002070BDB1F800C04D8885B1261D20F414 -:1004D0000040A84238BFFFDF30884FF4004121EAD6 -:1004E00000002843308000202082012070BD607F02 -:1004F0000CF1080100F10803084481B26288201D54 -:1005000000F049F8EFE70021C18101774182C17510 -:100510008175704703881380C289002A04BF0020B8 -:100520007047C28800F1280322F400421A440A608E -:10053000C089704710B50446808AA0F57F41FF3915 -:1005400018BFFFDFE088A082E089002818BF0120E3 -:10055000A07510BD4FF6FF71818200218175704733 -:1005600010B50446808AA0F57F41FF3908BFFFDF40 -:10057000A07D28B9A088A18A884204BF002010BDB0 -:10058000012010BD8188828A914205BF807D0028AC -:1005900000200120704710B4B0F800C02CF40044D3 -:1005A000214489B24FF4004491420AD2521A92B2C5 -:1005B0001B339A422CBF0CF4004224EA0C0104D2F3 -:1005C00004E0891A89B224EA0C021143018010BCAC -:1005D000704770B516464FF6FC72C91C01EA020559 -:1005E000D8B10446C01C20F00301A14200D0FFDFB7 -:1005F000201D012108E00246284401D2034600E004 -:100600000023491CC9B21360B142F4D916B104F1F8 -:10061000040001E04FF00000206005FB06F000F14F -:10062000040070BD024600201168002902D008466F -:1006300009681160704702680A60016070474FF6F0 -:10064000FC73C91C1940101A001F90FBF1F0C0B2D6 -:1006500070474FF6FC73C91C1940001D01FB0200D6 -:10066000704770B50C00054609D0082C00D2FFDF9A -:100670001DB1A1B2286800F044F8201D70BD0DB175 -:1006800000202860002070BD0021026803E09388EC -:100690001268194489B2002AF9D100F032B870B555 -:1006A00000260D460446082900D2FFDF206808B95D -:1006B0001EE0044620688188A94202D00168002912 -:1006C000F7D181880646A94201D100680DE005F105 -:1006D000080293B20022994209D32844491B0260C0 -:1006E00081802168096821600160206000E00026A7 -:1006F000304670BD00230B608A8002680A6001608A -:10070000704700234360021D018102607047F0B50D -:100710000F460188408815460C181E46AC4200D38F -:10072000641B3044A84200D9FFDFA019A84200D9B9 -:10073000FFDF3819F0BD2DE9F041884606460188F3 -:10074000408815460C181F46AC4200D3641B384441 -:10075000A84200D9FFDFE019A84200D9FFDF708866 -:100760003844708008EB0400BDE8F0812DE9F041C9 -:10077000054600881E461746841B8846BC4200D3A7 -:100780003C442C8068883044B84200D9FFDFA0196F -:10079000B84200D9FFDF68883044688008EB040065 -:1007A000E2E72DE9F04106881D460446701980B243 -:1007B000174688462080B84201D3C01B208060883D -:1007C000A84200D2FFDF7019B84200D9FFDF60886D -:1007D000401B608008EB0600C6E730B50D46018877 -:1007E000CC18944200D3A41A4088984200D8FFDF66 -:1007F000281930BD2DE9F041C14D04469046A87836 -:100800000E46A04200D8FFDF05EB8607B86A50F815 -:10081000240000B1FFDFB868FFF704FF05000CD02B -:10082000B86A082E40F8245000D3FFDFB54842468E -:10083000294650F82630204698472846BDE8F081E2 -:100840002DE9F0471E460400074602EB06009146DC -:100850008A46C5B227D000218846FF2800D9FFDF8D -:10086000E01C20F00300A04200D0FFDFB24500D919 -:10087000FFDFA34880F800A080F801908570C57064 -:10088000057145718671DFF87CA280F8079000261B -:100890000AF1400A8146FF1C27F003000746B8F121 -:1008A000000F03D005E04FF00101D5E709EB860109 -:1008B00088603AF8161019F8062001D04FF00000B1 -:1008C000FFF787FE761CF6B20744082EE3D3FF1C21 -:1008D00027F003002A460646B8F1000F0DD000208D -:1008E0000221FFF776FE4346002130440F46C846FA -:1008F000C01C20F003021BB110E0C9F84800EFE76C -:1009000008EB81060020B26206E000BFD6F828C0DE -:100910004CF82070401CC0B2A842F7D3491CC9B2A1 -:1009200002EB85000829E3D3001BBDE8F08710B572 -:10093000044603F0BBFC08B1102010BD2078704ABB -:10094000618802EB800092780EE0836A53F82130D0 -:1009500043B14A1C6280A180806A50F82100A060E7 -:10096000002010BD491C89B28A42EED86180052062 -:1009700010BD70B505460C46084603F097FC08B15B -:10098000102070BD082D01D3072070BD25700020F8 -:10099000608070BD0EB56946FFF7EBFF00B1FFDF69 -:1009A0006846FFF7C4FF08B100200EBD01200EBD50 -:1009B00010B50446082800D3FFDF5148005D10BD84 -:1009C0003EB5054600246946FFF7D3FF18B1FFDFA7 -:1009D00001E0641CE4B26846FFF7A9FF0028F8D0E4 -:1009E0002846FFF7E5FF001BC0B23EBD44498978A9 -:1009F000814201D9C0B27047FF2070472DE9F04114 -:100A000090460C460546062901D0072C10D13C4FD4 -:100A1000B86CFFF707FE02004FF6FF7604D0022104 -:100A2000B86CFFF70CFE00E030462880B04201D1E0 -:100A3000002003E742462146FFF7DCFE040002D116 -:100A4000288800F04FF82046F8E6A0F57F43FF3BEA -:100A500001D0082901D300207047CBE6A0F57F42E2 -:100A6000FF3A0BD0082909D2254A9378834205D949 -:100A700002EB8101896A51F820007047002070471D -:100A80002DE9F04105460C46A5F57F4143F20200F1 -:100A9000FF3902D0082C01D30720CFE618494FF0C8 -:100AA00000088A78AA42F8D901EB8406B26A52F8A3 -:100AB0002570002FF1D013483946203050F82420FB -:100AC00028469047B16A062C41F8258001D0072CB2 -:100AD00002D1284600F006F83946B068FFF7ABFDB2 -:100AE0000020ABE610B5064CC2B20221A06CFFF7A5 -:100AF000B0FD0146A06CBDE81040FFF79CBD0000B2 -:100B0000600700202022020070B50E461D461146E7 -:100B100000F0D4F804462946304600F0D8F82044C6 -:100B2000001D70BD2DE9F04190460D4604004FF0C8 -:100B3000000610D00027E01C20F00300A04200D0E7 -:100B4000FFDFDDB141460020FFF78BFD0C3000EBED -:100B5000850617B112E00127EDE7614F04F10C00A3 -:100B6000A9003C602572606000EB85002060606831 -:100B700011F05BF841463868FFF773FD3046BDE879 -:100B8000F0812DE9FF4F564C804681B020689A468F -:100B9000934600B9FFDF2068027A424503D94168D5 -:100BA00051F8280020B143F2020005B0BDE8F08FF3 -:100BB0005146029800F082F886B258460E9900F02D -:100BC00086F885B27019001D87B22068A1463946A3 -:100BD0000068FFF764FD04001FD067802580294668 -:100BE000201D0E9D07465A4601230095FFF766F823 -:100BF0002088314638440123029ACDF800A0FFF73F -:100C00005DF82088C1193846FFF78FF8D9F8000041 -:100C10004168002041F82840C7E70420C5E770B5C7 -:100C20002F4C0546206800B9FFDF2068017AA942F1 -:100C30000ED9426852F8251051B1002342F82530F0 -:100C40004A880068FFF756FD216800200A7A08E00C -:100C500043F2020070BD4B6853F8203033B9401C9A -:100C6000C0B28242F7D80868FFF70EFD002070BDC1 -:100C700070B51B4E05460024306800B9FFDF3068B0 -:100C8000017AA94204D9406850F8250000B1041D3A -:100C9000204670BD70B5124E05460024306800B97C -:100CA000FFDF3068017AA94206D9406850F8251064 -:100CB00011B131F8040B4418204670BD10B50A4636 -:100CC0000121FEF7F3FFC01C20F0030010BD10B59A -:100CD0000A460121FEF7EAFFC01C20F0030010BD08 -:100CE0006C00002070B5044600780E46012813D031 -:100CF000072802D00B2813D10EE0A068616905789F -:100D0000052003F061FA052D0AD078230022052082 -:100D1000616903F0AFF903E00520616903F054FA5B -:100D200031462046BDE8704001F0A8B910B500F189 -:100D30003902C3799478411D64F003042340C371E0 -:100D4000DB070DD04B79547923404B710B79127925 -:100D500013400B718278C9788A4200D9817010BD26 -:100D600000224A710A71F5E74178012900D00C216F -:100D7000017070472DE9F74F88B000208C698DF81D -:100D800004000878012617460D464FF007094FF07A -:100D9000110A4FF00A0B292876D2DFE810F029005B -:100DA000D20215032D036F037E039903C703DC03EF -:100DB0000604330457047004AE04BF04E204EA04DA -:100DC0000A052C0557057A05A605C605D605F605BC -:100DD000F805050637065906AD06EA06EC061B07B8 -:100DE0003B074407550792071B08410808080D08F0 -:100DF00014B120781E2829D0D5F808805FEA0800B1 -:100E000042D001208DF80400686A02228DF8082083 -:100E100006908DF809B0286A0390A8880028EFD0C2 -:100E200098F8001091B10F2910D27DD2DFE801F0BF -:100E30007C134BDCFEFDFCFBFAF9F8089EF7F6008C -:100E4000022821D124B120780C2801D00026F9E312 -:100E50008DF80420B3E10520696A03F0B5F9A8888C -:100E60000728EED1204601F003F9022809D02046D8 -:100E700001F0FEF8032808D9204601F0F9F8072808 -:100E800003D20120207005E003E2002CB8D02078C6 -:100E90000128D6D198F80400C11F0A2903D300BF46 -:100EA00085F81CB04CE2A070D8F80010A163B8F827 -:100EB0000410A18798F8060084F83E0001202870ED -:100EC0000320207046E00728BBD1002C98D0207862 -:100ED0000D28B6D198F8031094F83B20C1F3C00058 -:100EE000C2F3C002104201D0062000E007208907AB -:100EF00007D198F805100142D2D198F806100142A6 -:100F0000CED194F83D2098F8051020EA0202114253 -:100F1000C6D194F83E2098F8061090430142BFD104 -:100F200098F80400C11F00E008E20A29B8D2617FE6 -:100F3000814201D906209AE3D8F800106160B8F820 -:100F40000410218198F80600A072012028700E205C -:100F5000207003208DF80400686A069004F13900BF -:100F60000290601D039017300490DBE0412890D17F -:100F7000204601F07DF8042802D1E078C00704D1B2 -:100F8000204601F075F80F289ED1A88CD5F80C806A -:100F900080B24FF04009666AFFF76AFE32460826C3 -:100FA00041464B460096FFF702FA0D208DF80400EB -:100FB000686A0690606A0290002101A8FFF792FE1D -:100FC0002078042808D0A07F48B1012807D0032842 -:100FD00008D0102020709CE005202070CEE184F81D -:100FE00000A033E71220F5E71128C0D1204601F018 -:100FF0003FF8042802D1E078C00719D0204601F05C -:1010000037F8062805D1E078C00711D1A07F022863 -:101010000ED0204601F02CF8112808E0B3E083E060 -:1010200072E156E136E109E1EAE0D0E017E09ED155 -:10103000102208F1010104F1480010F05DFD607814 -:10104000012809D012202070E078C00765D0A07F69 -:1010500090B301285DD060E084F8009059E0112839 -:1010600085D1204601F004F8082804D0204600F07D -:10107000FFFF132888D12869D0B16869C0B104F195 -:101080007800102208F10101064610F035FD2078A5 -:10109000082812D014202070E078C0070FD0A07F5D -:1010A000022818D06178022912D0032831D034E008 -:1010B00000208DF80400ECE02BE00920EBE70B208A -:1010C0002870296901204870206CC1E9010662E29C -:1010D00008B101287AD10B202870296981F8019084 -:1010E000606A4860206AC1E9020648E2206CE27842 -:1010F0000068C2F34402521ED04000F0010040F0EC -:10110000800000E000200874E06A48614CE2064676 -:10111000FEE3042028700520BAE185F800B08DF8C0 -:1011200004B08EE33946F4E31128C4D1204600F020 -:101130009FFF0A2802D1E078C00704D1204600F0C2 -:1011400097FF1528B7D1102208F1010104F14800DA -:1011500010F0D2FC20780A2810D01620207012201F -:10116000287029690920487004F15800486020302F -:1011700088601038C860206C086184E30B20207000 -:10118000B9E22870FEE3022895D1204600F070FFF6 -:10119000042804D3204600F06BFF082809D320461A -:1011A00000F066FF0E2886D3204600F061FF12286B -:1011B0006FD2A07F0228B8D110208DF80400686A91 -:1011C000069098F801008DF80800F6E33DE2022849 -:1011D000ABD1204600F04CFF00285AD0204600F04A -:1011E00047FF0128F9D0204600F042FF0C28F4D038 -:1011F00004208DF8080098F801008DF809005AE7DE -:101200001128FCD1002CFAD020781728F7D161786A -:10121000E06A022910D0002101EB4101182606EBFB -:10122000C1011022405808F1010110F065FC0520B1 -:10123000696A00F010FF1DE10121EDE70B28DED106 -:10124000002CDCD020781828D9D16178E06A0229F6 -:101250001BD0002101EB4101102202EBC1014158DA -:10126000B8F8010008806078E16A02280FD00020F9 -:1012700000EB4002142000EBC2000958404650F831 -:10128000032F0A604068486039E00121E2E701204D -:10129000EEE7A1E11128B2D1002CB0D020781928B6 -:1012A000ADD16078E16A022811D0002000EB400245 -:1012B0001C2000EBC2001022085808F1010110F0B8 -:1012C0001BFC0520696A00F0C6FE1A20D4E001204C -:1012D000ECE7082893D1002C91D020781A288ED1E1 -:1012E000E06A98F80120017862F347010170E16A31 -:1012F000D8F8022041F8012FB8F8060088800520B0 -:10130000696A00F0A8FE3CE3112898D1002C98D01F -:1013100020781B2893D16178E06A02290CD0002143 -:1013200001EB4101202202EBC1011022405808F1DB -:10133000010110F0E1FBE2E70121F1E785F81C90E3 -:10134000EFE338780128A6D11C2204F11C0079684B -:1013500010F017FCE079C10894F83B0001EAD001D5 -:10136000E07861F30000E070217F09B1297733E173 -:10137000217803290AD0C0073FF42DAE032028703E -:101380008DF804B0686A06904120B1E3607FA178CF -:1013900088423FF6CFAD02262671E179204621F042 -:1013A000E001E171617A21F0F0016172A17A21F02E -:1013B000F001A172FFF7BAFC2E708DF804B0686AD4 -:1013C00006908DF80890ADE638781128CFD18DF8C9 -:1013D0000490696A0691916800208DF814000391C9 -:1013E000ADF8089008466168016021898180A17A82 -:1013F000817104202070E0E238781128B7D18DF88F -:101400000490686A0690381D02AB07C883E807009D -:101410004120ADF8080000208DF8140008460C218A -:101420000170A88CCA4680B2FE684FF04009D4F81B -:101430002080FFF72FFC3146082642464B46009697 -:10144000FEF7EEFF002101A8FFF74CFCE07820F04A -:101450003E00801CE0702078052801D00F200BE0B2 -:10146000A07F20B1012802D0032803D03DE184F8F9 -:1014700000A04EE62670E9E42070E7E438780328FF -:10148000A4D178680168A1664068E06605202870EC -:101490008DF80400686A069044E63878032895D1F0 -:1014A00078680168216740686067206C68B9A07F30 -:1014B00028B1012803D0062028700420E8E785F829 -:1014C0000090FE4820646064F9E385F80090F6E33C -:1014D0003878022892D1387900287CD1A07F022860 -:1014E0000BD00328F1D1607801280BD0A07994F8B3 -:1014F0003A1001280AD0F1480BE0B86800286BD0F8 -:10150000206411E0A17994F83A00F2E7B868002865 -:10151000F5D02064E078C00701D0012901D0E74868 -:1015200002E0F8680028EAD06064CEE78DF804B0E5 -:10153000696A0691E1785846C90709D0617802299D -:1015400003D1A17F29B1012903D0A17F032900D0B4 -:101550000820287064E33878112891D1B86828628F -:1015600009202870E0782969C0070DD081F8019022 -:10157000206A4860606A886004F16800C860A07FE3 -:1015800002287FF4BFADB1E501204870206C4860AF -:1015900004F16800886004F13800C860201D08610B -:1015A000206B4861606B88612AE2E1783878C9076E -:1015B00001D0062100E00A2188428BD1207807283B -:1015C0001DD084F800A000BF8DF80490686A0690D2 -:1015D000286A039001E0CAE08DE20024ADF808A07B -:1015E0008DF81440032100F8011B5168102210F0FF -:1015F00083FA002101A8FFF775FB2C6226E408207E -:101600002070E1E738781128A7D18DF80490686A36 -:1016100006909068039000208DF814000398ADF8B0 -:1016200008A0042100F8011B102204F1680110F049 -:1016300063FA002101A8FFF755FB2078092802D0A2 -:10164000132019E73CE384F800B016E0E17838781D -:10165000C90701D0062100E00A218842ADD110223D -:1016600004F14800796810F01BFA10B104202877C3 -:10167000EAE3207809283FF4EEAC0C2081E5E0781D -:10168000C10738D0A17F012902D002291BD02EE04A -:101690000D202870296981F801B06078012809D0EF -:1016A000206A4860606A886004F16800C860103091 -:1016B000086129E5606A4860206A886004F1780062 -:1016C000C8601038F4E7C0F3440114290FD24FF07A -:1016D000006101EBB0104FEAB060E0706078012863 -:1016E00003D010202070042057E10620C4E6607863 -:1016F00001283FF476AC0E2043E538780928ADD1B7 -:1017000085F800B00F208DF80400686A06905068D4 -:101710000290002101A8FFF7E5FAE8E7E078C007AA -:101720000AD0A07F012803D10F202870042036E1C1 -:10173000102028700E2032E115202870296902201F -:101740004870206C48606078012805D004F178006A -:1017500088601038C86053E104F168008860103078 -:10176000F8E738780228CAD138790028E0D02877FD -:1017700068E338781328FBD185F800A02969082090 -:10178000487078684860607801280DD004F16800DE -:1017900088601030C860206B0861606B486104F19C -:1017A00058008861A06A22E004F17800886010384F -:1017B000F0E738780728DBD16078012801D01320C2 -:1017C00029E2A178A06A0844C1F1100110F00BFAD7 -:1017D0001220287029690920487004F158004860D7 -:1017E000203088601038C860206C086144E0C8610F -:1017F000E06A086204E138780828B9D1102204F1BF -:101800004800796810F04CF908B10B202FE72078D8 -:101810000B2812D02046FFF789FAA178A06A084465 -:10182000C1F1100110F0DFF91620287008208DF8A2 -:101830000400686A0690002072E0132028708DF87A -:1018400004B0686A06908DF808A06BE43878112817 -:101850008ED1B86828621420287029690920487040 -:1018600004F158004860103088601030C860606C27 -:1018700008616078012806D004F139004861206BC6 -:101880008861606BB3E7601D4861606B8861206BA5 -:10189000ADE7387808288ED18DF80490686A0690F4 -:1018A000286A00260D210390ADF808A08DF8146079 -:1018B00000F8011B1022796802E000007423020086 -:1018C00010F01AF9002101A8FFF70CFA2E626078D7 -:1018D000012801D01520CFE51620287008208DF8AA -:1018E0000400686A029606901BE038780B2884D1C1 -:1018F000162028706078022802D12046FFF716FAD9 -:10190000A17878680844C1F1100110F06CF901E089 -:1019100083E215E008208DF80400686A0690786874 -:101920000290A0788DF80C004DE538780F288FD103 -:10193000E079C00773D01720287009202FE01146E6 -:1019400001A8FFF7CFF9FFF7E2BB38781028A2D142 -:101950001422391D04F11C0010F013F9E16A208DE6 -:10196000A1F80900E16AA078C871E179E26A01F0A2 -:1019700003011172E16A627A0A73E16AA07A81F85E -:10198000240000E09BE1242078E6192043E1387828 -:101990001128ACD1B86828621A20287005208DF86B -:1019A0000400686A0690CAE7387803289FD16078F7 -:1019B000E16A022802D0012001E05CE2002000EB95 -:1019C0004002142000EBC2027B688A58196811603B -:1019D000596851601B212970D5E9041205234B7009 -:1019E000636A4B606678E36A022E01D0012600E04C -:1019F000002606EB460600EBC6001858C1E90202B5 -:101A0000686A4862089800F050FB9CE738780E2816 -:101A100071D16078E26A022802D0012001E0ADE1D4 -:101A2000002000EB4001102000EBC1000223105801 -:101A3000093279680EF01EFB1C20287029690420E9 -:101A40004870206A4860E06A09308860FB4881E697 -:101A500038780D284FD16178E06A022901D0012140 -:101A600000E0002101EB4101182606EBC101A2783C -:101A70004058796810F040F86078E16A022801D097 -:101A8000012000E0002000EB400206EBC200B0465F -:101A90000858A1780844C1F1100110F0A4F88DF89D -:101AA0000490686A0690286A00260390ADF808A0A2 -:101AB0008DF81460062101706178E26A022901D074 -:101AC000012100E0002101EB410308EBC301401CB0 -:101AD0005158102210F010F8002101A8FFF702F968 -:101AE0001D202E6228708DF804B0686A06900B20C5 -:101AF0008DF8080067E481E0387811287ED18DF8F0 -:101B00000490686A0690B86803900B20ADF808004E -:101B1000039880F800906278E16A022A02D00122DC -:101B200001E091E1002202EB4202102303EBC2022A -:101B300089580988A0F801106178E26A022901D069 -:101B4000012100E0002101EB4103142101EBC3015D -:101B500051580A6840F8032F4968416056E0272031 -:101B6000287001208DF814002DE424202870002016 -:101B70009FE01F204FE0387811283FD18DF8049066 -:101B8000686A0690B868039000208DF814000398E6 -:101B9000ADF808A0082606706178E26A022901D033 -:101BA000012100E0002101EB41031C2101EBC301F5 -:101BB000401C515810220FF09FFF002101A8FFF791 -:101BC00091F8202028708DF804B0686A06908DF88E -:101BD000086061E43878112810D18DF80490686AA3 -:101BE0000690B86803900820ADF808000398092112 -:101BF0000170E16909784908417000E094E0E16909 -:101C000051F8012FC0F802208988C18020781D2852 -:101C1000ABD1A4E7222028708DF804B0686A069042 -:101C20008DF808A08BE6387811287DD1B868286235 -:101C300023202870296904204870206A4860E06ADF -:101C4000093088607E4885E538780D286CD1617848 -:101C5000E06A022901D0012100E0002101EB4101ED -:101C6000202606EBC1011022405879680FF044FF8E -:101C70008DF80490686A0690286A0390ADF808A071 -:101C800080F800B06278E16A022A01D0012200E007 -:101C9000002202EB420206EBC202401C89581022CD -:101CA0000FF02AFF0020286221781D29B1D02421BD -:101CB00029708DF81400002101A8FFF713F80326FE -:101CC000DFE0E078C00702D04FF0060C01E04FF0F3 -:101CD000070C6078022809D04FF0000000EB0401E7 -:101CE00001F1090105D04FF0010004E04FF00100BF -:101CF000F4E74FF000000B78204413EA0C030B705C -:101D000010F8092F02EA0C02027004D14FF01C0CEB -:101D100084F800C092B394F801C0BCF1010F00D068 -:101D2000E3B990F800C000E053E05FEACC7804D05B -:101D30002CF00106067018260EE05FEA8C7804D5B8 -:101D40002CF0020606701E2606E05FEA4C7805D5E8 -:101D50002CF00406067021262E70032694F801C08C -:101D6000BCF1020F00D0DAB991F800C05FEACC787C -:101D700005D02CF001060E7017210FE01AE05FEA83 -:101D80008C7804D52CF002060E70192106E05FEA6B -:101D90004C7805D52CF004060E701B21217000260E -:101DA0000078D0BBCAB3C3BB1D20207035E03878A3 -:101DB000122847D1282061E42078012842D00C283D -:101DC00040D02046FEF7D0FF0B208DF80400686A53 -:101DD000069037E038784FF02608112805D01220F9 -:101DE0001070032685F800804BE08DF80490686A37 -:101DF0000690B86803900220ADF8080001208DF825 -:101E00001400039805210170297F4170114601A833 -:101E1000FEF768FF064685F80080012E12D030E0FC -:101E200001208DF80400686A069003208DF80800F0 -:101E3000287F8DF809000020287716E06C23020027 -:101E400070220200287F80B11E202070252028707B -:101E50008DF804B0686A069002208DF808003946B3 -:101E600001A8FEF73FFF06460BE00CB1FE202070F4 -:101E70009DF8040028B1002101A8FEF733FFFEF70A -:101E8000E5BF0BB03046BDE8F08FF0B587B00C462B -:101E90004E6900218DF804100120257803460227A1 -:101EA0004FF0070C85B1012D50D0022D36D1FE2008 -:101EB00030708DF80030606A059003208DF80400C2 -:101EC000207E8DF8050060E02179012922D00229C9 -:101ED00029D0032924D0042920D1B17F02291DD182 -:101EE00031780D1F042D04D30A3D032D01D31E2983 -:101EF00014D12189022911D38DF80470237020890F -:101F00009DF80410884217D20A208DF80000606AFC -:101F1000059057E070780128EED0052007B0F0BD9D -:101F20001E203070E8E771780229F6D131780C294B -:101F3000F4D18DF804C0E1E71120083402F8040B55 -:101F400094E80B0082E80B000320E7E71578112DD9 -:101F5000E4D18DF800C0656A0595956802958DF805 -:101F6000101094F804E0BEF1010F13D0BEF1020F7F -:101F70002DD0BEF1030F1CD0BEF1040FCED1ADF8B1 -:101F800004700E202870207E687000216846FEF7DD -:101F9000A9FE0CE0ADF804700B202870207E002113 -:101FA00000F01F0068706846FEF79CFE3770002046 -:101FB000B4E7ADF804708DF8103005202870207E4D -:101FC0006870277011466846FEF78CFEA6E7ADF8EC -:101FD00004C02B70207F6870607F00F00100A87043 -:101FE000A07F00F01F00E870E27F2A71C0071CD0BC -:101FF00094F8200000F00700687194F8210000F0C8 -:102000000700A87100216846FEF76CFE2868B063DF -:10201000A888B087A87986F83E00A06940787077D4 -:102020002879B0700D203070C1E7A9716971E9E7B6 -:1020300000B587B005280CD101208DF800008DF87F -:102040000400002005918DF8050001466846FEF762 -:1020500049FE07B000BD70B50C46054602F0B4F865 -:1020600021462846BDE870407823002202F002B8DD -:1020700008B1007870470C207047000070B50C0064 -:1020800005784FF000010CD021702146F3F79DF840 -:1020900072482178405D884201D1032070BD022042 -:1020A00070BDF3F792F8002070BD027B032A05D0C3 -:1020B00000220A704B780B2B02D003E004207047FB -:1020C0000A770A62027B9300521C0273C1500320FC -:1020D0007047F0B587B00F4605460124287B05EB15 -:1020E000800050F8046C7078411E0C290AD25B49BC -:1020F0003A46123101EB8000314650F8043C284644 -:10210000984704460CB1012C11D1287B401E10F0D9 -:10211000FF00287301D00324E0E70C208DF80000B5 -:10212000706A0590002101966846FFF7A7FF032C0F -:10213000D4D007B02046F0BD70B515460A46044617 -:1021400029461046FFF7C5FF064674B12078FE28E1 -:102150000BD1207E30B100202870294604F10C00FC -:10216000FFF7B7FF2046FEF7FFFD304670BD704712 -:1021700070B50E46044688210FF057FD0225012E4A -:1021800003D0022E04D0052070BD0120607000E055 -:1021900065702046FEF7E8FDA577002070BD28B1E8 -:1021A000027E1AB10A4600F10C01C5E70120704712 -:1021B00010B5044686B0052002F006F82078FE2807 -:1021C00006D000208DF8000069462046FFF7E7FFA3 -:1021D00006B010BD7FB50E4600218DF80C10417879 -:1021E0000B2903D00C2903D0002405E0846900E00A -:1021F00044690CB1217E91B16D4601462846FFF736 -:1022000054FF032809D1324629462046FFF794FFA0 -:102210009DF80C10002900D0042004B070BD04F11A -:102220000C05EAE710B590B00C4607900B48042166 -:10223000801E08900A488DF8191009900F9269467F -:1022400006A8FFF7C7FF002805D1102220460199F4 -:102250000FF052FC002010B010BD000076220200EA -:102260006C23020070B50D46040011D085B1210128 -:1022700028460FF0B8FC10224E4928460FF03CFCCF -:102280004C4801210838018044804560002070BD21 -:10229000012070BD70B5474E00240546083E10E091 -:1022A0007068AA7B00EB0410817B914208D1C17B4E -:1022B000EA7B914204D10C2229460FF0F1FB30B1A8 -:1022C000641C30888442EBDB4FF0FF3070BD204649 -:1022D00070BD70B50D46060006D02DB1FFF7DAFFD0 -:1022E000002803DB401C14E0102070BD314C083C7A -:1022F00020886288411C914201D9042070BD616828 -:10230000102201EB001031460FF0F6FB2088401C34 -:1023100020802870002070BD70B514460D0018D0C4 -:10232000BCB10021A170022802D0102811D105E013 -:10233000288870B10121A170108008E02846FFF7BD -:10234000A9FF002805DB401CA070A8892080002080 -:1023500070BD012070BD70B5054614460E000BD04F -:1023600000203070A878012808D005D91149A1F1C2 -:1023700008010A8890420AD9012070BD24B128784A -:1023800020702888000A5070022008700FE064B1A5 -:102390004968102201EB0011204610390FF0ACFB08 -:1023A000287820732888000A60731020307000207D -:1023B00070BD0000780000202DE9F04190460C46E9 -:1023C00007460025FE48072F00EB881607D2DFE8F6 -:1023D00007F00707070704040400012500E0FFDFFA -:1023E00006F81470002D13D0F548803000EB8801FA -:1023F00091F82700202803D006EB4000447001E04C -:1024000081F8264006EB44022020507081F82740D6 -:10241000BDE8F081F0B51F4614460E460546202A59 -:1024200000D1FFDFE649E648803100EB871C0CEB6A -:10243000440001EB8702202E07D00CEB46014078C8 -:102440004B784870184620210AE092F825304078F1 -:1024500082F82500F6E701460CEB41000570407854 -:10246000A142F8D192F82740202C03D00CEB440471 -:10247000637001E082F826300CEB41042023637086 -:1024800082F82710F0BD30B50D46CE4B441900221E -:10249000181A72EB020100D2FFDFCB48854200DD43 -:1024A000FFDFC9484042854200DAFFDFC548401CD3 -:1024B000844207DA002C01DB204630BDC148401CB5 -:1024C000201830BDBF48C043FAE710B50446016884 -:1024D000407ABE4A52F82020114450B102200844EC -:1024E00020F07F40F0F751FB94F90810BDE8104050 -:1024F000C9E70420F3E72DE9F047B14E803696F89E -:102500002D50DFF8BC9206EB850090F8264034E0B1 -:1025100009EB85174FF0070817F81400012806D0BB -:1025200004282ED005282ED0062800D0FFDF01F089 -:10253000E5F8014607EB4400427806EB850080F899 -:10254000262090F82720A24202D1202280F82720BE -:10255000084601F0DEF82A4621460120FFF72CFF4D -:102560009B48414600EB041002682046904796F8CD -:102570002D5006EB850090F82640202CC8D1BDE8F0 -:10258000F087022000E003208046D0E710B58C4C95 -:102590002021803484F8251084F8261084F8271030 -:1025A000002084F8280084F82D0084F82E10411EA5 -:1025B000A16044F8100B2074607420736073A073E2 -:1025C0008449E07720750870487000217C4A103CEF -:1025D00002F81100491CC9B22029F9D30120F0F7F3 -:1025E000C2F90020F0F7BFF9012084F82200F9F7C2 -:1025F00053FB7948F9F75FFB764CA41E20707748AF -:10260000F9F759FB6070BDE81040F0F739B910B523 -:10261000F0F75BF96F4CA41E2078F9F765FB607842 -:10262000F9F762FBBDE8104001F0A0B82020704728 -:102630002DE9F34F624E0025803606EB810A89B002 -:102640009AF82500202822D0691E02916049009541 -:1026500001EB00108146D0E90112C0680391CDE979 -:102660000420B08BADF81C00B07F8DF81E009DF8E3 -:102670001500C8B10227554951F820400399E219C5 -:10268000114421F07F41019184B102210FE001202A -:10269000F0F769F90020F0F766F9F0F734F901F086 -:1026A00065F886F82F508AE00427E4E700218DF8CA -:1026B0001810022801D001281BD1039839190144B0 -:1026C0000998081A20F07F4033280BD903208DF891 -:1026D00015000398C4F13201401A20F07F403224E3 -:1026E00003900CE096F8240018B9F0F753FC00288A -:1026F0004DD0322C03D214B101F02CF801E001F0DE -:1027000035F8344A107820B393465278039B121B55 -:1027100000219DF81840984601281BD0032819D0A5 -:102720005FF000008DF81E00002A04DD981A039067 -:1027300001208DF818009DF81C0000B102210398BB -:10274000274A20F07F40039003AB099801F01AF864 -:1027500010B110E00120E5E79DF81D0018B99BF8C5 -:102760000000032812D08DF81C50CDF80C808DF895 -:1027700018408DF81E509DF8180058B10398012399 -:10278000C11900221846F0F741F906E000200BB00D -:10279000BDE8F08F0120F0F7E6F899F90C2001234D -:1027A00000200199F0F732F9012086F82F008AF80D -:1027B000285003482022694680300FF0E2F911E0EA -:1027C000AC090020FF7F841E0020A107B822020070 -:1027D000AC0700208A000020233F0100F7240100FD -:1027E000FFFF3F000120D2E72DE9F05FDFF84084D2 -:1027F000064608EB860090F82550202D1FD0A8F142 -:1028000080002C4600EB8617A0F50079DFF824B491 -:1028100005E0A24607EB4A004478202C0AD0F0F7E6 -:1028200041F909EB04135A4601211B1D00F0AAFFD0 -:102830000028EED0AC4202D0334652461EE0FE489D -:1028400008B1AFF30080F0F72DF998F82F206AB1A6 -:10285000D8F80C20411C891A0902CA1701EB126131 -:102860000912002902DD0020BDE8F09F3146FFF784 -:10287000DFFE08B10120F7E733462A462021042075 -:10288000FFF7C8FDEFE72DE9F041E94C2569F0F7C6 -:1028900009F9401B0002C11700EB1160001200D4BF -:1028A000FFDF94F8220000B1FFDF012784F82270D7 -:1028B00094F82E00202800D1FFDF94F82E6020200D -:1028C00084F82E00002584F82F5084F8205084F8D6 -:1028D0002150DA4825600078022833D0032831D00F -:1028E00000202077A068401C05D04FF0FF30A0608A -:1028F0000120F0F738F80020F0F735F8F0F733F959 -:10290000F0F72BF9EFF7FFFF0EF094FBCC480560D2 -:1029100005604FF0E0214FF40040B846C1F8800256 -:10292000F0F7BBF994F82D703846FFF75DFF0028EB -:10293000FAD0BF48803800EB871010F81600022844 -:1029400002D006E00120CCE73A4631460620FFF7E8 -:1029500033FD84F8238004EB870090F826002028BC -:1029600004D0B648801E4078F9F7C4F9207F0028CB -:1029700003D0F0F7E8F82577657749E50146AC48DC -:1029800010B590F82D200024803800EB821000BF95 -:1029900010F814302BB1641CE4B2202CF8D32020A2 -:1029A00010BDA84800EB0410016021460120FFF78C -:1029B00003FD204610BD10B5012801D0032800D129 -:1029C00071B39B4A92F82D30994C0022803C04EB65 -:1029D000831300BF13F812400CB1082010BD521C25 -:1029E000D2B2202AF6D3954A48B1022807D0072947 -:1029F00016D2DFE801F01506080A0C0E10000021BF -:102A00000AE01B2108E03A2106E0582104E0772182 -:102A100002E0962100E0B52151701070002010BD39 -:102A2000072010BD854810B54078F0F7AEF880B2A9 -:102A300010BD10B5202811D27D4991F82D30A1F19B -:102A4000800202EB831414F810303BB191F82D3062 -:102A500002EB831212F81020012A01D0002010BDD1 -:102A600091F82D2001460020FFF7A6FC012010BDA3 -:102A700010B5F0F717F8BDE81040F0F786B82DE96B -:102A8000F0410E466A4F01782025803F0C4607EB47 -:102A9000831303E0254603EB45046478944202D097 -:102AA000202CF7D108E0202C06D0A14206D103EB60 -:102AB00041014978017007E00020A9E403EB4400DC -:102AC00003EB4501407848705F4F7EB127B100218C -:102AD00040F2DA30AFF300803078A04206D127B15F -:102AE000002140F2DD30AFF30080357027B10021C6 -:102AF00040F2E230AFF30080012089E410B5426873 -:102B00000B689A1A1202D41702EB1462121216D42E -:102B1000497A91B1427A82B94C4A006852F8211040 -:102B2000126819441044001D891C081A0002C117BC -:102B300000EB11600012322801DB012010BD0020E3 -:102B400010BD2DE9F047814639483E4E00EB81002B -:102B5000984690F825402020107006F50070154624 -:102B600000EB81170BE000BF06EB04104946001D87 -:102B7000FFF7C4FF28B107EB44002C704478202CE9 -:102B8000F2D1297888F8001013E000BF06EB041595 -:102B9000291D4846FFF7B2FF68B988F80040A97BB5 -:102BA00099F80A00814201D80020E8E407EB4400CC -:102BB0004478202CEAD10120E1E42DE9FC410E46C5 -:102BC000074600241F4D08E09DF8000005EB0010AB -:102BD0008168384600F0EAFD01246B4601AA3146BF -:102BE0003846FFF7AEFF0028EED02046BDE8FC8156 -:102BF00070B504460E4801258038A54300EB8411CA -:102C000000EB851040220EF077FF0F4E26B1002119 -:102C100040F25C40AFF30080054800EB850100EB1B -:102C20008400D0F82500C1F82500AEB100210FE0E6 -:102C30002C0A0020FFFF3F00000000008A00002057 -:102C400000F50040AC07002000000000B8220200A0 -:102C50004FF48C60AFF30080284670BD2DE9FC4135 -:102C60008446FF481546089C00EB85170E4617F86A -:102C70001400012803D0022801D00020B6E70B463B -:102C8000F84A0121604600F07DFDA8B101AB6A461B -:102C900029463046FFF755FF70B1F1489DF80420F2 -:102CA0009DF80010803000EB85068A4208D02B4644 -:102CB0000520FFF7AFFB0BE02A462146042014E075 -:102CC000202903D007EB4100407801E096F8250069 -:102CD00007EB440148709DF80000202809D007EB5D -:102CE000400044702A4621460320FFF765FB01207F -:102CF0007CE706F8254F0120F070F3E7DA4901EB95 -:102D00000010001DFFF7E1BB7CB51D4613460446CD -:102D10000E4600F1080221461846EFF743FF94F9EA -:102D200008000F2804DD1F3820722068401C206036 -:102D300096B10220CD4951F8261046182068694600 -:102D4000801B20F07F40206094F908002844C01CBC -:102D50001F2803DA012009E00420EBE701AAEFF7BE -:102D600021FF9DF8040010B10098401C00900099CC -:102D7000206831440844C01C20F07F4060607CBD66 -:102D80002DE9FE430C460646097860799072207959 -:102D900098461546507241B1B148803090F82E10D7 -:102DA00020290AD00069401D0BE0D4E902232179D3 -:102DB00003B02846BDE8F043A6E7AD484178701D52 -:102DC000084420F07F47217900222846A368FFF7B6 -:102DD0009BFF3946284600F0E9FCD4E9023221790C -:102DE0006846FFF791FF41462846019CFFF7E5FE44 -:102DF0002B4622460021304600F0C4FC002803D1B7 -:102E00003146284600F0D2FCBDE8FE832DE9FE4F96 -:102E1000814600F087FC38B15FF0000799F80000A8 -:102E200020B10020BDE8FE8F0127F7E78C4D914CC3 -:102E30004FF0000A803524B1002140F2D340AFF3B7 -:102E4000008095F82D8085F823A0002624B100216C -:102E50004FF49B60AFF300801FB94046FFF7C8FEF8 -:102E6000804624B100214FF49C60AFF30080EFF75F -:102E700019FE43466A464946FFF782FF24B1002106 -:102E800040F2E640AFF3008095F82E0020280CD0E9 -:102E900029690098401A0002C21700EB1260001264 -:102EA00003D5684600F082FC012624B100214FF4CE -:102EB0009E60AFF3008095F823000028BBD124B1B9 -:102EC000002140F2F640AFF30080EFF7EBFD6B46D8 -:102ED000644A002100F056FC0028A3D027B94146DF -:102EE0006846FFF76AFE064326B16846FFF7EDFA2B -:102EF000C9F8080024B1002140F20950AFF3008066 -:102F000001208FE72DE9FF5F8A46814600F00AFC29 -:102F1000534C803410B39AF80000002710B10128F8 -:102F200000D0FFDF534D25B1002140F27F50AFF3B9 -:102F300000800120A84600905FEA080604D0002126 -:102F400040F28750AFF30080009800F0E2FB94F865 -:102F50002D50002084F8230067B119E094F82E006A -:102F60000127202800D1FFDF9AF800000028D9D0DF -:102F7000FFDFD7E72846FFF73BFE054626B10021D5 -:102F800040F29150AFF3008094F823000028D3D191 -:102F900026B1002140F29B50AFF30080EFF782FD95 -:102FA00083462B4601AA5146FFF7EAFE5FEA060870 -:102FB00004D0002140F2A250AFF300803B462A46E5 -:102FC00001A95846CDF80090FFF748FE064604EBED -:102FD000850090F828B0B8F1000F04D0002140F22D -:102FE000A950AFF3008000F089FB0090B8F1000F0A -:102FF00004D0002140F2AF50AFF3008094F82300DA -:10300000002899D1B8F1000F04D0002140F2B75048 -:10301000AFF3008014490DF1040C01EB09109CE89A -:103020000E0000F1040080E80E002EB35FEA0806EF -:1030300004D0002140F2C450AFF300803BEA070007 -:1030400020D094F82E0020281CD126B1002140F277 -:10305000C950AFF300802846FFF7C6FB90B90CE0DB -:10306000AC090020FFFF3F00AC070020B82202009F -:103070008A0000200000000010E09AF80000D8B399 -:10308000012849D0B8F1000F04D0002140F2E650E9 -:10309000AFF30080284600F02AFB01265FEA08050E -:1030A00004D0002140F2EF50AFF30080009800F010 -:1030B00030FB25B1002140F2F350AFF300808EB118 -:1030C00094F82D0004EB800090F82600202809D009 -:1030D00025B1002140F2FA50AFF30080F948407862 -:1030E000F8F708FE25B1002140F2FF50AFF3008051 -:1030F00004B03046BDE8F09FFFE7B8F1000F04D000 -:10310000002140F2D150AFF3008094F82D204946C1 -:103110000420FFF751F9C0E7002E3FF40DAF002166 -:1031200040F2DC50AFF3008006E72DE9F84FE64DA2 -:10313000814695F82D004FF00008E44C4FF0010B4C -:10314000474624B1002140F20D60AFF3008058469D -:1031500000F0DFFA85F8237024B1002140F21260FC -:10316000AFF3008095F82D00FFF742FD064695F875 -:10317000230028B1002CE4D000214FF4C3604BE0C1 -:1031800024B1002140F21C60AFF30080CE488038AB -:1031900000EB861111F81900032856D1334605EBD0 -:1031A000830A4A469AF82500904201D1012000E0A6 -:1031B000002000900AF125000021FFF760FC014685 -:1031C0000098014203D001228AF82820AF77E1B3AA -:1031D00024B1002140F22160AFF30080324649461D -:1031E0000120FFF7E9F89AF828A024B1002140F265 -:1031F0002C60AFF3008000F081FA834624B10021F7 -:1032000040F23160AFF3008095F8230038B1002C14 -:1032100097D0002140F23560AFF3008091E7BAF11A -:10322000000F07D095F82E00202803D13046FFF775 -:10323000DBFAE0B124B1002140F24960AFF3008035 -:10324000304600F054FA4FF0010824B1002140F25A -:103250005260AFF30080584600F05BFA24B10021C1 -:1032600040F25660AFF300804046BDE8F88F002C76 -:10327000F1D0002140F24460AFF30080E6E7002087 -:10328000EFF74ABB0120EFF747BB8E480078704745 -:103290002DE9F0418C4C94F82E0020281FD194F891 -:1032A0002D6004EB860797F82550202D00D1FFDF15 -:1032B0008549803901EB861000EB4500407807F81E -:1032C000250F0120F87084F82300294684F82E5039 -:1032D000324602202234FFF76FF8002020700CE401 -:1032E0002DE9F0417A4E784C012538B1012821D0E2 -:1032F000022879D003287DD0FFDFF0E700F02AFA1A -:10330000FFF7C6FF207E00B1FFDF84F821500020C8 -:10331000EFF729FBA168481C04D0012300221846BE -:10332000EFF774FB14F82E0F217806EB01110A68F1 -:10333000012154E0FFF7ACFF0120EFF714FB94F8F4 -:10334000210050B1A068401C07D014F82E0F21783E -:1033500006EB01110A68062141E0207EDFF8648156 -:10336000002708F10208012803D002281ED0FFDF41 -:10337000B5E7A777EFF7E7FB98F80000032801D13E -:1033800065772577607D534951F8200094F8201027 -:1033900051B948B161680123091A00221846EFF7B4 -:1033A00035FB022020769AE7277698E784F82050AC -:1033B00000F0D0F9A07F50B198F8010061680123B6 -:1033C000091A00221846EFF721FB257600E0277640 -:1033D00014F82E0F217806EB01110A680021BDE8D0 -:1033E000F041104700E005E036480078BDE8F041C4 -:1033F000F8F780BCFFF74CFF14F82E0F217806EB8E -:1034000001110A680521EAE710B52F4C94F82E0047 -:10341000202800D1FFDF14F82E0F21782C4A02EB70 -:1034200001110A68BDE81040042110477CB5264C04 -:10343000054694F82E00202800D1FFDFA068401C2C -:1034400000D0FFDF94F82E00214901AA01EB001003 -:10345000694690F90C002844EFF7A4FB9DF904009D -:103460000F2801DD012000E0002000990844616878 -:10347000084420F07F41A16094F82100002807D083 -:1034800002B00123BDE8704000221846EFF7BEBA33 -:103490007CBD30B5104A0B1A541CB3EB940F1FD3EC -:1034A000451AB5EB940F1BD3934203D9101A431856 -:1034B0005B1C15E0954211D9511A0844401C434247 -:1034C0000EE00000880000202C0A00200000000010 -:1034D000AC070020B8220200FF7F841EFFDF00231C -:1034E000184630BD0123002201460220EFF78EBAB4 -:1034F0000220EFF738BAEFF7D5BA2DE9FC47B14C07 -:10350000054694F82E00202800D1FFDF642D58D303 -:10351000AD4A0021521B71EB010052D394F82E20CA -:10352000A0462046DFF8A49290F82D7009EB021413 -:10353000D8F8000001AA28446946EFF733FB9DF94B -:103540000400002802DD0098401C0090A06800994B -:1035500062684618B21A22F07F42B2F5800F30D26C -:1035600008EB8702444692F82520202A0AD009EB6E -:1035700002125268101A0002C21700EB1260001209 -:1035800088421EDBA068401C10D0EFF78BFAA168C0 -:10359000081A0002C11700EB11600012022810DDAA -:1035A0000120EFF7E0F94FF0FF30A06020682844D9 -:1035B000206026F07F402061012084F82300BDE8D0 -:1035C000FC870020FBE72DE9F0477E4C074694F886 -:1035D0002D00A4F1800606EB801010F8170000B94A -:1035E000FFDF94F82D50A046794C24B1002140F61D -:1035F0006500AFF3008040F6710940F67A0A06EBE9 -:10360000851600BF16F81700012818D0042810D01E -:1036100005280ED006280CD01CB100214846AFF377 -:10362000008020BF002CEDD000215046AFF3008079 -:10363000E8E72A4639460120FEF7BEFEF2E74FF0E2 -:10364000010A4FF00009454624B1002140F68100EF -:10365000AFF30080504600F05CF885F8239024B169 -:10366000002140F68600AFF3008095F82D00FFF7AB -:10367000BFFA064695F8230028B1002CE4D00021BB -:1036800040F68C001FE024B100214FF40960AFF335 -:10369000008005EB860000F1270133463A462630CC -:1036A000FFF7EDF924B1002140F69400AFF300805C -:1036B00000F024F8824695F8230038B1002CC3D0DE -:1036C000002140F69A00AFF30080BDE785F82D6039 -:1036D000012085F82300504600F01BF8002C04D090 -:1036E000002140F6A700AFF30080BDE8F087354920 -:1036F00081F82D00012081F82300704710B535486E -:1037000008B1AFF30080EFF3108000F0010072B653 -:1037100010BD10B5002804D12F4808B1AFF30080C8 -:1037200062B610BD2D480068C005C00D10D010381D -:1037300040B2002806DA00F00F0000F1E02090F817 -:10374000140D03E000F1E02090F8000440097047F8 -:103750000820704710B51B4C94F82400002804D1B1 -:10376000F8F7B6F8012084F8240010BD10B5154C08 -:1037700094F82400002804D0F8F7D3F8002084F847 -:10378000240010BD10B51C685B68241A181A24F0B8 -:103790007F4420F07F40A14206D8B4F5800F03D2C9 -:1037A000904201D8012010BD002010BDD0E90032A8 -:1037B000D21A21F07F43114421F07F41C0E900314A -:1037C000704700002C0A0020FF1FA107AC07002053 -:1037D00000000000000000000000000004ED00E018 -:1037E000F0B5734AD2F80032724D002401212E78D0 -:1037F00056B9714E3460704F03263F1D3E606E4FC8 -:1038000004260C373E602970C2F80042D160116076 -:10381000694C4834D16425688542FBD35160D1603E -:10382000C2F80032F0BD2DE9F041044680074FF0A8 -:1038300000054FF0010604D560480560066024F0DD -:103840000204E0044FF0FF3705D55D484660C0F83C -:10385000087324F48054600003D55A48056024F0AE -:103860008044E0050FD55248C0F80052C0F80873F4 -:1038700051490D60091D0D604F4A04210C32116041 -:10388000066124F48074A00409D54F484660C0F84E -:103890000052C0F808734D48056024F40054C4F386 -:1038A0008030C4F3C031884200D0FFDF14F4404FB1 -:1038B00014D047484660C0F8087346488660C0F890 -:1038C0000052C0F8087344490D600A1D16608660F6 -:1038D000C0F808730D60166024F4404420050AD532 -:1038E0003E4846608660C0F80873C0F848733C489C -:1038F000056024F400640DF077FB3A48044200D0E0 -:10390000FFDFBDE8F08170B5202500224FEA0203F9 -:1039100020FA02F1C90719D051B201F01F060124A3 -:10392000B4404E09B60006F1E026C6F88041C6F85C -:103930008042002906DA01F00F0101F1E02181F84F -:10394000143D03E001F1E02181F80034521CAA4249 -:10395000DED370BD70B5174C0D466060FFF763FF96 -:103960006068FFF7D0FF2846F8F7A7F80CF05EFF75 -:1039700000F0ABF80DF038FB0DF083FAF8F78CF996 -:10398000BDE870400DF000B810B50A4C6068FFF754 -:103990004AFF6068FFF7B7FF0DF026FBF8F721F943 -:1039A0000020606010BD0348406870470A207047DF -:1039B000008000408C00002004850040FC1F004077 -:1039C00000C0004004E5014000D0004004D50040A4 -:1039D00000E0004000F0004000F5004000B0004072 -:1039E00008B50040FEFF0FFD70B522490A680AB312 -:1039F0000022154601244B685B1C4B60092B00D349 -:103A00004D600E7904FA06F30E681E420FD0EFF3F4 -:103A1000108212F0010272B600D001220C689C43A1 -:103A20000C6002B962B649680160002070BD521C8A -:103A3000092AE0D3052070BD4FF0E0214FF480004B -:103A4000C1F800027047EFF3108111F0010F72B658 -:103A50004FF0010202FA00F20648036842EA03024C -:103A6000026000D162B6E7E70248002101604160D0 -:103A70007047000094000020AD4911F8410F4978CB -:103A8000884201D3401A02E0C1F141010844C0B2AA -:103A90007047A749433111F8410F4978884201D353 -:103AA000401A02E0C1F141010844C0B27047A04988 -:103AB000863111F8410F4978884201D3401A02E05B -:103AC000C1F141010844C0B270479A4910B5802045 -:103AD00081F8000496490020433101F8410F4870F5 -:103AE000934901F8410F48709149863101F8410F1F -:103AF000487091480DF00EF98F48401C0DF00AF9FE -:103B0000EFF7DAF8BDE8104000F006B94020704742 -:103B1000B2E770B50C4605460026FFF7ADFF844AB4 -:103B2000A04214D30021641EE4B20FD392F84200E5 -:103B3000105C05F8010B92F84200401CC0B282F8FC -:103B400042004128EFD182F84210ECE7012600F054 -:103B5000E3F8304670BD402070479AE770B50C46D8 -:103B600005460026FFF795FF714A4332A04214D361 -:103B70000021641EE4B20FD392F84200105C05F8F5 -:103B8000010B92F84200401CC0B282F8420041286A -:103B9000EFD182F84210ECE7012600F0BDF8304684 -:103BA00070BD402101700020704710B50446FFF73A -:103BB0007EFF2070002010BD70B50C460546FFF753 -:103BC00076FF5B4A8632A04215D30021641EE4B220 -:103BD0000FD392F84200105C05F8010B92F84200F6 -:103BE000401CC0B282F842004128EFD182F8421056 -:103BF000ECE7002401E042F2070400F08DF82046D3 -:103C000070BD70B50C460546412900D9FFDF4B4811 -:103C10000068103840B200F066F8C6B20D2000F01F -:103C200062F8C0B2864203D2FFDF01E0EFF794F8FA -:103C300021462846FFF76DFF0028F7D070BD2DE91B -:103C4000F0413D4F0025064617F10407412257F881 -:103C5000254094F8421094F8410000F053F888B3DE -:103C60006D1CEDB2032DF1D331484122433090F861 -:103C7000421090F8410000F045F8002831D02C485F -:103C8000412290F8421090F8410000F03BF80028E3 -:103C900027D027484122863090F8421090F8410002 -:103CA00000F030F800281CD0EFF72CF822480DF077 -:103CB00039F8B0F5005F00D0FFDFBDE8F0411E48E5 -:103CC0000DF046B894F84100265494F84100401C89 -:103CD000C0B284F841004128C6D1002084F84100D8 -:103CE000C2E7BDE8F081002806DA00F00F0000F11D -:103CF000E02090F8140D03E000F1E02090F80004BB -:103D000040097047401C884204D0904200D109B15C -:103D1000002070470120704710B507480DF002F8E9 -:103D2000002803D1BDE81040EEF7D7BF10BD00005A -:103D30005C0A00200DE000E09C00002004ED00E0A3 -:103D4000164908784A78401CC0B2904205D0144BFE -:103D500001221A60BFF34F8F087070472DE9F041C0 -:103D60000E4C4FF0E02600BFEFF77CF820BF40BFBD -:103D700020BF677820786070D6F80052EDF7CCFA53 -:103D8000854305D1D6F8040210B92078B842EBD0AB -:103D9000EFF763F80020BDE8F0810000AC000020E0 -:103DA000180502402DE9F041012528034FF0E021DC -:103DB0000026C1F880011E4CC4F800610C2000F000 -:103DC0002CF81C4801680268C94341F3001142F015 -:103DD00010020260C4F804532560491C00E020BFB3 -:103DE000D4F80021002AFAD019B9016821F0100195 -:103DF0000160114807686560C4F80853C4F80061A1 -:103E00000C2000F00AF83846BDE8F08110B50446F1 -:103E1000FFF7C8FF2060002010BD00F01F02012145 -:103E200091404009800000F1E020C0F88012704706 -:103E300000C0004010ED00E008C500402DE9F0474B -:103E4000FF4C0646FF21A06800EB06121170217896 -:103E5000FF2910D04FF0080909EB011109EB0617F3 -:103E60004158C05900F0F4F9002807DDA168207816 -:103E700001EB061108702670BDE8F08794F8008009 -:103E800045460DE0A06809EB05114158C05900F006 -:103E9000DFF9002806DCA068A84600EB08100578CA -:103EA000FF2DEFD1A06800EB061100EB08100D709C -:103EB0000670E1E7F0B5E24B0446002001259A6860 -:103EC0000C269B780CE000BF05EB0017D75DA742DE -:103ED00004D106EB0017D7598F4204D0401CC0B262 -:103EE0008342F1D8FF20F0BD70B5FFF704FBD44C3E -:103EF00008252278A16805EB0212895800F0A8F97C -:103F0000012808DD2178A06805EB01114058BDE8C3 -:103F10007040FFF7E7BAFFF7B8F9BDE87040F7F770 -:103F2000E9BE2DE9F041C64C2578FFF7E4FAFF2DF4 -:103F30006ED04FF00808A26808EB0516915900F002 -:103F400087F90228A06801DD80595DE000EB0511CA -:103F500009782170022101EB0511425C5AB1521E11 -:103F60004254815901F5800121F07F418151284659 -:103F7000FFF764FF34E00423012203EB051302EB97 -:103F8000051250F803C0875CBCF1000F10D0BCF5DF -:103F9000007F10D9CCF3080250F806C00CEB423C6D -:103FA0002CF07F4C40F806C0C3589A1A520A09E018 -:103FB000FF2181540AE0825902EB4C3222F07F4209 -:103FC0008251002242542846FFF738FF0C21A06896 -:103FD00001EB05114158E06850F82720384690471A -:103FE0002078FF2814D0FFF786FA2278A16808EB22 -:103FF00002124546895800F02BF9012893DD2178FB -:10400000A06805EB01114058BDE8F041FFF76ABA1E -:10401000BDE8F081F0B51D4614460E460746FF2B5D -:1040200000D3FFDFA00700D0FFDF8548FF2100227B -:10403000C0E90247C5700671017042708270104677 -:10404000012204E002EB0013401CE154C0B2A8427C -:10405000F8D3F0BD70B57A4C064665782079854274 -:1040600000D3FFDFE06840F825606078401C607096 -:10407000284670BD2DE9FF5F1D468B460746FF248D -:10408000FFF739FADFF8B891064699F80100B8420F -:1040900000D8FFDF00214FF001084FF00C0A99F81B -:1040A0000220D9F808000EE008EB0113C35CFF2BD7 -:1040B0000ED0BB4205D10AEB011350F803C0DC451A -:1040C0000CD0491CC9B28A42EED8FF2C02D00DE0B8 -:1040D0000C46F6E799F803108A4203D1FF2004B09A -:1040E000BDE8F09F1446521C89F8022008EB041129 -:1040F0000AEB0412475440F802B00421029B00224C -:10410000012B01EB04110CD040F801204FF4007892 -:1041100008234FF0020C454513D9E905C90D02D01B -:1041200002E04550F2E7414606EB413203EB04134F -:1041300022F07F42C250691A0CEB0412490A8154E2 -:104140000BE005B9012506EB453103EB041321F023 -:104150007F41C1500CEB0411425499F800502046A5 -:10416000FFF76CFE99F80000A84201D0FFF7BCFEF3 -:104170003846B4E770B50C460546FFF7BCF906466D -:1041800021462846FFF796FE0446FF281AD02C4DFC -:10419000082101EB0411A8684158304600F058F896 -:1041A00000F58050C11700EBD14040130221AA68EE -:1041B00001EB0411515C09B100EB4120002800DC47 -:1041C000012070BD002070BD2DE9F0478846814672 -:1041D000FFF770FE0746FF281BD0194D2E78A86800 -:1041E0003146344605E0BC4206D0264600EB0612B6 -:1041F0001478FF2CF7D10CE0FF2C0AD0A6420CD18A -:1042000000EB011000782870FF2804D0FFF76CFE47 -:1042100003E0002030E6FFF76BF941464846FFF720 -:10422000A9FF0123A968024603EB0413FF20C85429 -:10423000A878401EB84200D1A87001EB041001E03C -:10424000280B002001EB061100780870104613E6D9 -:10425000081A0002C11700EB11600012704700003D -:1042600070B50446A0F500002D4EB0F1786F02D273 -:104270003444A4F500042B48844201D2012500E017 -:10428000002500F043F848B125B9B44204D32648CC -:10429000006808E0012070BD002070BD002DF9D13C -:1042A000B442F9D321488442F6D2F3E710B504466C -:1042B000A0F50000B0F1786F03D219480444A4F5CA -:1042C000000400F023F84FF0804130B11648006838 -:1042D00004E08C4204D2012003E014488442F8D266 -:1042E000002080F0010010BD10B520B1FFF7DEFF07 -:1042F00008B1012010BD002010BD10B520B1FFF79E -:10430000AFFF08B1012010BD002010BD08480949C9 -:104310000068884201D101207047002070470000EA -:1043200000000020003002002000002008000020D3 -:10433000B0000020BEBAFECA0548064A0168914294 -:1043400001D100210160044901200860704700008C -:10435000B0000020BEBAFECA40E50140534800212B -:104360000170417010218170704770B50546164686 -:104370000C460220EEF73FFA4C49012008704C49E8 -:10438000F01E08604B480560001F046070BD10B54A -:104390000220EEF730FA4549012008704648002116 -:1043A000C0F80011C0F80411C0F8081143494FF4D7 -:1043B0000000086010BD3D480178C9B1404A4FF483 -:1043C000000111603C49D1F800310022002B1CBFD4 -:1043D000D1F80431002B02D0D1F8081111B142708C -:1043E000102103E001214170364909688170027093 -:1043F0000020EEF700BA2D480178002904BF40786C -:1044000070472D48D0F80011002904BF02207047E2 -:10441000D0F8001100291CBFD0F80411002905D0E4 -:10442000D0F80801002804BF012070470020704721 -:104430001E4800B50278204B4078C821491EC9B2F9 -:1044400082B1D3F800C1BCF1000F10D0D3F8000145 -:1044500000281CBFD3F8040100280BD0D3F80801B2 -:1044600050B107E0022802D0012805D002E000295F -:10447000E4D1FFDF002000BD012000BD0B48017822 -:10448000002904BF807870470B48D0F8001100293C -:104490001CBFD0F80411002902D0D0F8080108B1DF -:1044A0001020704707480068C0B27047B400002071 -:1044B00010F5004008F5004000F0004004F5014010 -:1044C00008F5014000F400404C48002101704170A3 -:1044D000704770B5064614460D460120EEF78BF97D -:1044E00047480660001D0460001D056070BD70B582 -:1044F000424A012540EA01411570424A41F080716B -:104500001160414C0026C4F80461404A4FF04071EC -:104510001160002802BFC4F80052256070BD012858 -:1045200018BFFFDFC4F8006225604FF00070384903 -:10453000086070BD3148017879B1344A4FF040715C -:1045400011603149D1F804210021002A08BF4170CF -:1045500002D0304A1268427001700020EEF74BB969 -:1045600026480178002904BF407870472648D0F8D3 -:104570000401002808BF704726480068C0B2704791 -:10458000002808BF704730B51C480078002808BFD5 -:10459000FFDF1D48D0F80411002918BF30BD0224E8 -:1045A000C0F80443DFF870C0DCF80010C1F3001558 -:1045B000DCF8001041F01001CCF80010D0F8041124 -:1045C000002904BF4FF400414FF0E02207D100BFA3 -:1045D000C2F8801220BFD0F80431002BF8D02DB9DA -:1045E000DCF8001021F01001CCF80010C0F80843EE -:1045F00030BD05490120886070470000B7000020E9 -:1046000008F5004004F5004000F0004008F50140C6 -:1046100004F5014000F4004010ED00E070B5FF4CDF -:1046200000250120657025706572A572E07284F81E -:104630002150A56204F1380065630CF06BFB002883 -:1046400018BFFFDFA577F6480DF0F6FBF5494FF0F0 -:10465000FF300860091D0860091D0D60091D086014 -:10466000091D0D60091D0860091D0860091D08600D -:10467000091D0860091D0860091D0860091D086002 -:10468000091D0860091D086070BD30B4E349026867 -:10469000DFF898C34A6142688A61007A08770A7D28 -:1046A000E14BACF1040401204AB10A7E00FA02F2A7 -:1046B0001A608D7D002D0CBF2260CCF800204A7D51 -:1046C000002A04BF30BC70474A7E90401860C97D04 -:1046D00000290CBF2060CCF8000030BC7047D549E1 -:1046E000D3480860091DD4480860704710B50446D7 -:1046F000012908BF002105D002291ABFFFDF0021D0 -:104700004FF0807141F48470CA4940F48010086011 -:10471000E0B240F44030091D40F000700860C74826 -:10472000D0F80001002818BFFFDF10BD01202DE9DF -:10473000F04102254FF0E0270026C7F88051C0491C -:104740000E600860BF490A6822F0770242F08802D2 -:1047500042F000420A60091D0A6822F47F4242F4D6 -:10476000B0520A60AD4CB84965770D60B84AB74998 -:104770001160121FB7491160B74A40F25B611160C6 -:10478000121F40F203111160111F0860B34903208A -:104790000860B3499620086094F91E000CF06AFD89 -:1047A000607F002814BF4FF4C020AE48AE490860B7 -:1047B000AF49AE480860091FAE480860C7F880528C -:1047C0009E491020C1F8040384F82D60BDE8F081F3 -:1047D000A948016821F0010141F080710160704732 -:1047E0008E4A0368C2F802308088D0801172704708 -:1047F0008A4890F821007047884A517010707047BD -:10480000F0B50546800000F1804000F580508B88AF -:10481000C0F820360B78D1F8011043EA0121C0F826 -:10482000001605F10800012707FA00F6934C002A4C -:1048300004BF2068B04304D0012A18BFFFDF2068FE -:1048400030432060206807FA05F108432060F0BD7E -:1048500010B504460CF00EFD7048847710BD6F480B -:1048600090F82E0070476D4890F830007047844AE9 -:10487000C1781160006883490002086070472528EC -:1048800008BF02210ED0262808BF1A210AD02728E7 -:1048900008BF502106D00A2894BF0422062202EB4A -:1048A0004001C9B2784A116078490860704770B415 -:1048B0005A4B93F80AC0BCF1010F21D0BCF1020F92 -:1048C0001CBF70BC70475C7D002C04BF70BC70477F -:1048D0004FF47A74BCF1010F6D4E16D0DD7D93F864 -:1048E00019C0002D18BF0125012908BF292121D099 -:1048F000022A08BF674E06F2E141B1FBF4F119E06C -:104900001C7D002CE4D170BC70479D7D93F818C0CD -:10491000002D18BF0125012947D0022A06BF5E4E8F -:104920004FF47A714FF4C861314401F5FA7100BF58 -:10493000B1FBF4F1491F0844584908605849002068 -:10494000C1F84C014FEA0C2085F0010140EA01500A -:1049500040F00311187F820002F1804202F5C0424C -:10496000C2F810154F4901EB8001987EC20002F198 -:10497000804202F5F832C2F81415DFF82CC1C2F8F3 -:1049800010C5DA7ED30003F1804303F5F833C3F892 -:1049900014153849C3F81015012101FA00F09140AF -:1049A00008434249086070BC7047022A14BF4FF4A4 -:1049B000C8614FF47A7149F6FC621144B8E72DE9F9 -:1049C000F0411E4D0746032014468846C5F80002F4 -:1049D000124E707F002814BF4FF4C0202148334985 -:1049E000086040460CF094FC20460CF071FC01205D -:1049F00017B1012F60D062E02D4B19685A06022CC6 -:104A0000D2F8202314BFC2F30622C2F3066221F4B7 -:104A1000FE4141EA02211960B0724BE0380B0020E0 -:104A20004C0B0020000E0040180500500C050050F3 -:104A3000060102001415004025000302001000408A -:104A4000FC1F00403C1700406015004044800040BF -:104A50009CF5014028110040381500401015004019 -:104A6000441500400000040408F501404080004067 -:104A7000A4F501401011004074170040401600409A -:104A8000241500401C150040081500405415004036 -:104A9000A224020004360200683602004C85004061 -:104AA00000800040006000404C81004004F501405F -:104AB00088150040286002E00221B1726860F9495F -:104AC000C864F948006822464146BDE8F041EEE678 -:104AD0002DE9F0418846F549074603201546C1F8FF -:104AE0000002F34C607F002814BF4FF4C020F1484F -:104AF000F14E306040460CF00BFC28460CF0E8FB11 -:104B000017B1012F19D021E0EC490A684806022D9F -:104B1000D0F8200314BFC0F30620C0F3066022F4CF -:104B2000FE4242EA002008600120A072606B40F45F -:104B3000801060634FF4801007E00220A072606B69 -:104B400040F4001060634FF4001030602A46414684 -:104B5000BDE8F0410020AAE62DE9FF4FD34C824684 -:104B6000002681B003208946C4F80002D04D687F3A -:104B7000002814BF4FF4C020CE48CF4F38600398B0 -:104B80000CF0C6FB04980CF0A3FBCD494FF00108D4 -:104B9000BAF1000F03D0BAF1010F32D03BE0C74B9E -:104BA00004981A684FF0805C0228DCF8200314BFD8 -:104BB000C0F30620C0F3066022F4FE4242EA002061 -:104BC00018600C6095F82D00012806D0022818BF47 -:104BD000FFDF0CD085F80A801DE0DDE9031395F8AE -:104BE0002C2048460CF0E6FBA96A4618F2E7DDE9FE -:104BF000031295F82C3048460CF097FBA96A46182A -:104C0000E8E7B048086095F82D00012818BFFFDFDD -:104C100020D00220A872AC480660AD49AB480860BD -:104C2000686B40F400206863D4F800924FF0100ADB -:104C3000C4F808A30025C4F80052A6484FF4802BFE -:104C4000C0F800B0FF208DF80000C4F81051C4F87F -:104C500010800EE0DDE9031395F82C2096200CF06F -:104C600087FBA96A4618D4E79DF80000401E8DF81E -:104C700000009DF8000018B1D4F810010028F3D00E -:104C80009DF80000002808BFFFDFC4F80051C4F8F9 -:104C90000C51C4F81051C4F80451C4F81451C4F8AC -:104CA0001851C4F828518C4800680090C4F800924C -:104CB000C7F800B0C4F804A34FF400203860794866 -:104CC000C0F84C8078480068B04228BFFFDF30460B -:104CD000DDE9031205B0BDE8F04FE8E52DE9F8473E -:104CE000724CD4F8000220F00309D4F804034FF00A -:104CF000100AC0F30018C4F808A30026C4F8006224 -:104D00006B4D687F002814BF4FF4C020694871497B -:104D10000860A87A0127012802D0022803D014E0F5 -:104D2000287D10B911E0687D78B1A87EEA7E07FA87 -:104D300000F007FA02F210430860287F800000F1BB -:104D4000804000F5C040C0F81065FF208DF80000DD -:104D5000C4F81061276104E09DF80000401E8DF842 -:104D600000009DF8000018B1D4F810010028F3D01D -:104D70009DF80000002808BFFFDFC4F81061C4F8E8 -:104D800028616E72AE72EF72C4F80092B8F1000F33 -:104D900018BFC4F804A3BDE8F88700684F4920F0A5 -:104DA0007F40086070474FF0E0200221C0F880117A -:104DB000C0F8801270474FF0E0210220C1F80001D6 -:104DC000704747490870704710B546480BF0AAFF76 -:104DD000002818BFFFDF10BD42480BF0B9BF4249A1 -:104DE0000860704730B5324C0546A06AA84228BF1B -:104DF000FFDF012020732561607F40B128442061DE -:104E00002A48D0F8001241F04001C0F800122549AC -:104E10000020C1F84401354920690860606B2649CB -:104E200040F4800060634FF48000086030BD70B5CE -:104E30001F4C0546022020730CF057FA024694F8E6 -:104E40002C1028460CF0E0FA2061617F41B1084443 -:104E500020611648D0F8001241F04001C0F800125D -:104E600010490020C1F844012169A06A08441F4983 -:104E7000086070BD17494FF4800008600C48416B12 -:104E800021F480014163002101737047054801212D -:104E90004160C1600021C0F8441114480160044819 -:104EA00081627047008000404C8500400010004047 -:104EB000380B00200000040404F501408815004070 -:104EC000ACF5014004100040488500404881004096 -:104ED000A8F5014008F50140181100403C150040BC -:104EE000B9000020700B00200415004044850040EC -:104EF000FE4940204877FE490860FE48D0F800127D -:104F000041F04001C0F800127047FA48D0F8001292 -:104F100021F04001C0F80012F549022008607047F6 -:104F2000F448D0F8001221F01001C0F8001201215D -:104F300081617047EF480021C0F81C11D0F80012C1 -:104F400041F01001C0F800127047EA4981B0D1F871 -:104F50001C21012A1EBF002001B07047E64A1268DA -:104F600002F07F02524202700020C1F81C01E348A7 -:104F700000680090012001B0704730B50C00054674 -:104F800008BFFFDF14F0010F1CBF012CFFDF002D55 -:104F90000CBF01200220D54901284872CC72D549A6 -:104FA00004BFD1F8000240F0040007D0022807BF78 -:104FB000D1F8000240F00800FFDF30BDC1F8000268 -:104FC00030BD70B5C94C0023E17A11F0020F18BF53 -:104FD00010F0040F16D111F0100F1CBF94F82F2001 -:104FE000002A02D094F8312062B111F0080F1CBFE2 -:104FF00094F82020002A05D111F0040F03D094F872 -:10500000211001B9012394F809C00122B949BCF16A -:10501000000F06D000F00200184312D0BDE8704027 -:105020005CE6607F002814BF4FF4C020B448B54B45 -:105030001860D1F8000220F00300C1F80002E2720B -:1050400070BD00252846BCF1010F0BD0BCF1020F4A -:1050500018BFFFDF16D0A06A01222844BDE87040C7 -:10506000002124E4D1F8003223F00403C1F8003217 -:105070006072E272A27201231A46002196200CF09F -:1050800054F90FE0D1F8003223F00803C1F80032E0 -:105090006072E2720220A07201231A46002196205B -:1050A0000CF066F90546D6E72DE9F84F964FD7F88C -:1050B0004C218E4C93494FF00108A07A0026CAB1CA -:1050C000012802D0022803D014E0227D12B911E099 -:1050D000627D7AB1A27EE37E08FA02F208FA03F357 -:1050E0001A430A60227F920002F1804202F5C04218 -:1050F000C2F81065626B0A606663217B29B1D7F83C -:105100004411012908BF012200D00022794DD5F8B1 -:10511000101101290CBF40210021012805BFD5F83D -:105120000C31012B002320231943012805BFD5F89A -:105130000431012B002310230B437449022804BFC0 -:10514000D1F800C0BCF1010F07D1D5F80CC1BCF1FA -:10515000010F08BF4FF0080C01D04FF0000C4CEAD3 -:105160000303022804BF0968002905D1D5F80C11F2 -:10517000012908BF042100D000211943022803D1CE -:10518000002A18BF022200D100221143022804BFC6 -:10519000D5F80401012805D1D7F84401012818BF2A -:1051A000012000D1002040EA01095948016811F0AE -:1051B000FF0F03D0D5F81411012900D0002184F885 -:1051C0002E10006810F0FF0F03D0D5F81801012849 -:1051D00000D0002084F82F004E48006884F830008A -:1051E00043480068402803D1FFF705F9012800D0A3 -:1051F000002084F83100C5F80061C5F80C61C5F8DD -:105200001061C5F80461C5F81461C5F81861C5F8E6 -:105210002861414800680090C7F844613F48006831 -:105220004D46DFF8FC900090D9F800106162607F75 -:1052300000281CBF081A60623A480068A0620CF09F -:1052400054F884F82C00A07ADFF8DCA084F82D0054 -:1052500002280CD1607850B1DAF8001009780840C3 -:10526000217831EA000008BF84F8208001D084F85A -:105270002060DFF8B88015F0010F15D098F8001005 -:105280002B4A4908606A52F8211088470121294AAF -:1052900098F80030A06A52F82320904798F8000050 -:1052A00010F0010F0BD01FE015F0200F18BF0221E6 -:1052B000EDD115F0020F18BF0021E8D1EEE7DAF8C2 -:1052C0000000062200F10901A01C0CF0E9FB40B926 -:1052D000207ADAF800100978B0EBD11F08BF01205E -:1052E00000D0002084F82100284625E0380B00205B -:1052F0006015004000100040481500401C1100409F -:105300000000040408F50140008000400014004043 -:105310004016004010140040181100404481004025 -:10532000448500404085004004150040B90000203D -:10533000D022020008230200FFF743FE15F0020FFF -:1053400005D03D4898F8001050F82100804715F02E -:105350000C0F07D0394898F8001050F82110C5F309 -:10536000C000884715F0200F05D0354898F8001088 -:1053700050F82100804798F80000022805D105F078 -:105380006E00402806D101F0DDFB98F800000428EB -:1053900028BFFFDFA07A022818BFBDE8F88F207B66 -:1053A000002808BFBDE8F88FC7F84461022815D06F -:1053B000012818BFFFDFA16A2069884298BFFFDF7C -:1053C000D4F81000C9F80000606B1E4940F480005A -:1053D00060634FF480000860BDE8F88F2169A06A1F -:1053E0000844EFE7012804BF28207047022804BFC3 -:1053F0001820704700B5FFDF282000BD012804BF3A -:1054000041F6A4707047022804BF41F2883070470B -:1054100000B5FFDF41F6A47000BD012804BF41F2D2 -:10542000D4707047022804BF41F20400704700B5F1 -:10543000FFDF41F2D47000BDD8220200E822020052 -:10544000F822020004F5014010B53F480AF0F7FBCE -:1054500000213D480AF022FC01213B480AF0F2FB02 -:105460003A49002081F822004FF6FF7088843849BD -:105470000880488010BD704734498A8C824218BF2A -:105480007047002081F822004FF6FF708884704733 -:105490002D49016070472E49088070472B498A8C3E -:1054A000A2F57F43FF3B03D000210160084670470F -:1054B00091F822202549012A1ABF0160012000200D -:1054C0007047224901F1220091F82220012A04BFED -:1054D00000207047012202701D4800888884104611 -:1054E00070471B49488070471849194B8A8C5B8864 -:1054F0009A4206D191F82220002A1EBF01600120A5 -:105500007047002070471148114A818C528891429F -:1055100009D14FF6FF71818410F8221F19B10021C3 -:10552000017001207047002070470848084A818CAC -:105530005288914205D190F8220000281CBF00201B -:1055400070470120704700009A0B0020740B002068 -:10555000BA0000207047574A012340B1012818BF04 -:105560007047137008689060888890817047537006 -:105570000868C2F802008888D08070474D4A10B190 -:10558000012807D00EE0507860B1D2F80200086020 -:10559000D08804E0107828B19068086090898880ED -:1055A0000120704700207047424910B1012803D004 -:1055B00006E0487810B903E0087808B10120704788 -:1055C0000020704730B58DB00C4605460D2104A86B -:1055D0000CF02BFBE0788DF81F0020798DF81E0071 -:1055E00060798DF81D002868009068680190A868AF -:1055F0000290E868039068460BF0B2F920789DF8B5 -:105600002F1088420CD160789DF82E10884207D167 -:10561000A0789DF82D10884202BF01200DB030BD4A -:1056200000200DB030BD30B50C4605468DB04FF0B2 -:10563000030104F1030012B1FEF790FA01E0FEF756 -:10564000E0FA60790D2120F0C00040F04000607168 -:1056500004A80CF0EAFAE0788DF81F0020798DF8A4 -:105660001E0060798DF81D00286800906868019020 -:10567000A8680290E868039068460BF071F99DF8FD -:105680002F0020709DF82E0060709DF82D00A070F6 -:105690000DB030BD10B5002904464FF0060102D010 -:1056A000FEF75CFA01E0FEF7ACFA607920F0C0008A -:1056B000607110BDBE00002070B5FA4E044696F829 -:1056C00092000025012828D096F88C00012833D0BC -:1056D00096F86A0001281CBF002070BD6570132079 -:1056E0002070202206F16C01A01C0CF005FA0120AC -:1056F000A07186F86A50B6F86E10A6F88E10EA49C6 -:1057000049684A7B86F8902086F88C000888FBF769 -:10571000AFFAFAF71FFF012070BD657019202070E5 -:10572000D6F89300C4F80200D6F89700C4F8060033 -:1057300086F89250012070BD657006202070D6F862 -:105740008E00C4F8020086F88C50E4E7D54890F843 -:105750006A10002914BFB0F86E004FF6FF70704752 -:1057600070B5D14800250570017800291CBFFFDF06 -:1057700070BDCC4C84F8625084F8635084F8645057 -:1057800084F8655084F85E5084F8605084F8565070 -:1057900084F8365084F867507F21817094F8660051 -:1057A00028B1FFF7B2FBFEF706FE84F8665084F8D6 -:1057B0006A5084F88C5084F89250BC480AF0D6F8AD -:1057C000BDE87040BA480AF0D1B8B64890F8620017 -:1057D0007047B44900B591F8580091F85710C0F3DC -:1057E0008002C0F340031A4400F001001044052970 -:1057F00010D2DFE801F00B070B030900AD4931F8C7 -:10580000100000BDAC4800BDAC4900E0AC4931F827 -:10581000100000BDFFDF002000BDA24840F2712152 -:10582000B0F85A00484370479E4890F86800002836 -:1058300018BF0120704710B59A4C207A022818BF73 -:10584000032808D1207C04F1110108F071FF082819 -:105850001CBF012010BD207A002816BF022800209E -:105860000120BDE81040FFF79FBE8E4908727047C7 -:105870008C4981F8600070472DE9F041894C82B075 -:10588000207A002816BF022800200120607204F14F -:105890000A01FFF773FE207A022816BF03280121B0 -:1058A000002184F85F10082084F85D00607A0126EA -:1058B000002504F10A02012804BF527912F0C00F3A -:1058C0000AD004F10A02012804D1507900F0C00086 -:1058D000402801D0002000E0012084F85E0029B9B2 -:1058E00094F85700012818BF042806D1207C04F141 -:1058F000110108F01DFF84F85D002560FDF7B8F880 -:1059000060604FF0000894F85D0008F02DFF074636 -:1059100094F85F00002818BF002F04D010213846EB -:1059200009F093FD68B194F8600000281CBF94F85A -:105930005E0000281DD0607A04F10A0101280ED013 -:1059400012E06672424604F10A013846FFF76BFE28 -:1059500094F85D1004F10A0008F0FEFF09E04879B0 -:1059600000F0C000402840D0294604F10A00FFF7AB -:1059700091FE04F10A014D480AF01EF8617A4B4885 -:105980000AF03FF804F10A0149480AF015F8617A73 -:1059900047480AF036F894F8570001281EBF04283B -:1059A00002B0BDE8F081002594F85D0008F0E5FE46 -:1059B000040004BF02B0BDE8F081102109F045FDEC -:1059C00000281CBF02B0BDE8F0812A466946204687 -:1059D000FFF729FE6946354809F0FCFF01213348ED -:1059E0000AF01CF802B0BDE8F08108F0EEFF424674 -:1059F00004F10A01FFF717FEBBE770B5294C417BA4 -:105A000084F85810017984F8571001290CBF00223E -:105A10000288A4F85A20827B84F868208279002AC0 -:105A200016BF022A002201222274D0F80720C4F8EF -:105A30001120B0F80B00A4F8150094F856000125C9 -:105A4000002818BF84F8635094F83600002818BF67 -:105A500084F8645005293AD2DFE801F0030C1E34C3 -:105A60000C000021114809F084FF01210F4809F0C2 -:105A7000BFFF2DE001210D4809F07BFF04F111016A -:105A80000A4809F0A7FF217C084809F0C7FF012157 -:105A9000064809F0ADFF1BE00621044809F069FF44 -:105AA00016E00000BC0B0020CC000020580C0020A9 -:105AB000800C002028230200D0891300302302002C -:105AC000202302000221FE4809F053FF00E0FFDF1F -:105AD0000421FC4809F04DFF84F86250002070BD9D -:105AE00070B5F94C0546002084F864002A4604F19C -:105AF00017000CF001F884F83650012084F8640097 -:105B000070BD10B5F04C002284F8632084F8560074 -:105B1000024604F137000BF0EFFF012084F8630028 -:105B200010BDE94981F8670070472DE9F041E74E63 -:105B300082B0307808BBE44C94F86200E8B1FFF71B -:105B400043F9002584F8615075702846FFF739F94C -:105B5000FEF7ECFDFEF7C3FDDD48FEF788FEDD48ED -:105B6000FFF71BF994F85800002610F0010F08D039 -:105B70002520FEF784FE012612E002B00C20BDE8CD -:105B8000F08110F0020F04D02620FEF778FE0226E6 -:105B900006E010F0040F03D02720FEF770FE042665 -:105BA000FEF79DFD84F85C60FFF705F900210122F6 -:105BB0000846FEF78DFF0F210520FEF71DFE94F825 -:105BC0005E00002804BF94F85F00002805D194F817 -:105BD0005700012818BF042874D1FCF749FF064676 -:105BE00031466068FDF755FCBB4990FBF1F701FBBE -:105BF000170041423046FCF746FC6060206838449C -:105C0000206008F092FD2168884274D8C4E90056EB -:105C10004FF0010894F85D0008F0A6FD064694F8E0 -:105C20005F000127002818BF002E04D01021304645 -:105C300009F00BFC68B194F8600000281CBF94F8D0 -:105C40005E0000281DD0617A04F10A0001290ED0FF -:105C500012E03A46677204F10A013046FFF7E3FCAE -:105C600094F85D1004F10A0008F076FE09E040792E -:105C700000F0C00040281DD0414604F10A00FFF7A3 -:105C800009FD04F10A018E4809F096FE617A8C48FC -:105C900009F0B7FE04F10A018A4809F08DFE617A25 -:105CA000884809F0AEFE94F85700012818BF042870 -:105CB00021D108E008F089FE3A4604F10A01FFF715 -:105CC000B2FCDEE717E0012794F85D0008F055FD0F -:105CD000060010D0102109F0B8FB60B93A466946B9 -:105CE0003046FFF7A0FC6946754809F073FE0121B4 -:105CF000734809F093FE617A04F10A00FEF770FD23 -:105D000094F8570001281EBF042894F86300002867 -:105D100008D094F8562004F13701694809F09CFE38 -:105D200084F8635094F8640040B194F8362004F18C -:105D30001701644809F0BCFE84F8645008F069FD5E -:105D4000664808F0FAFD84F86600FFF745F802B0EF -:105D50000020BDE8F0815D494860704770B55A4C3D -:105D600006002BD094F8581094F85C20002521EA06 -:105D7000020010F0010F04D02520FEF780FD012560 -:105D800015E011F0020F02D012F0020F06D011F050 -:105D9000040F0CD012F0040F05D008E02620FEF707 -:105DA0006EFD022503E02720FEF769FD0425FEF7BE -:105DB00096FC94F85C00284384F85C0094F8610039 -:105DC00040B194F85700012808BFFFDFBDE87040DC -:105DD00000F0BFBA36B1002201234FF4967110468D -:105DE000FEF7BAFE3648FEF7FAFF94F8570005288A -:105DF00009D2DFE800F0030303090300012108468C -:105E0000FFF7BBF800E0FFDF94F8580094F85C104F -:105E100030EA01014FF0010002D02C49087070BD3A -:105E200094F85710012912BF84F86100002184F80A -:105E30005C10F2E710B5FEF7C7FF2448007840B9C0 -:105E4000214890F8620020B10020FFF787FF002072 -:105E500010BDFFF71BF8FFF70DF8FEF73FFFFEF749 -:105E6000A2FFFEF7B9FF0C2010BD184901204870B1 -:105E70007047154981F86500704770B5002503F03B -:105E8000A3FA48B1114E3078012809D0022801D078 -:105E9000032842D0FFDF70BDBDE8704000F059BA62 -:105EA000094C94F85700032837D094F8660018B1CD -:105EB000FEF76DFAFFF71CF80848FEF790FF0FE0B9 -:105EC000580C0020800C0020BC0B0020CC000020CF -:105ED0001B2302001823020040420F00A80C0020E0 -:105EE0009620FEF7A4FF94F85700012818BF042855 -:105EF0000AD094F86800012814BF0328102545F043 -:105F00000E010020FFF739F894F86700012808BF58 -:105F1000FFF710F80220307070BDBDE8704001201E -:105F20001CE770B5FE4DFF4C95F86700012817D0AF -:105F300095F8660018B1FEF7E8FFFEF73CFA03F0AB -:105F400043FAB8B12078022818BFFFDF0120FFF71D -:105F500005FF207800281EBF20780128FFDF70BDD4 -:105F6000F148FEF7F2FF002804BF7F20A070FEF783 -:105F7000D7FFDDE7BDE8704000F0EBB92DE9F05F39 -:105F800007464FF00009FEF76AFCE64E824630787D -:105F9000022818BFFFDFE24D7F2495F86700012833 -:105FA00030D0E24809F004FD83464FF0FF08002F8F -:105FB00000F0E480DD4809F00EFE002800F0DE80ED -:105FC000FEF716FC002800F0D98095F86600D74F40 -:105FD00068B108F003FC8046FF2808D00146F81C91 -:105FE00008F0EBFB404608F004FC40EA0A0A584679 -:105FF0004FF0000B062880F0C180DFE800F0BFBF43 -:10600000BF0CBF69C848FEF7A0FF002808BFB470E6 -:10601000FEF786FFC5E795F85700012818BF04284A -:1060200070D0BAF1000F18D195F86800002818BF99 -:10603000022867D13878F91CC0F3801008F078FB8B -:10604000824608F0DAFC40B1504608F096FB20B1D9 -:10605000102109F0FAF9002854D095F867000128BA -:1060600004BF95F89200002805D0B148FEF7B7FEAE -:106070000320307084E0012085F89200B8F1FF0F12 -:106080000FD005F19402511E404608F07FFB002816 -:1060900008BFFFDF95F8930040F0020085F89300F9 -:1060A0000CE03878C0F3801085F89300D5F8EF0045 -:1060B000C5F89400B5F8F300A5F89800B07805F19C -:1060C0009A077F2808BFFFDFB0783870B470CCE73C -:1060D0003878297CC0F38010884209D1062205F166 -:1060E0001101F81C0BF0DCFC002808BF012000D0D7 -:1060F0000020B8F1FF0F06D0C0B995F85D0040450B -:106100001AD113E03AE0B8B13878F91CC0F3801026 -:1061100008F00EFB044608F070FC38B1204608F089 -:106120002CFB18B1102109F090F928B195F857000F -:10613000012818BF04281DD095F85700F0B9BAF10E -:10614000000F17D195F86800002818BF012815D155 -:106150003878F91CC0F3801008F0EAFA044608F019 -:106160004CFC38B1204608F008FB18B1102109F0AA -:106170006CF918B195F865002C46D8B14FF00109BB -:1061800095F8660018B1FEF7C0FEFEF714F9B9F1F4 -:10619000000F1CBF0120FFF7E1FD307800281ABF77 -:1061A00030780128BDE8F09F3078032818BFFFDF62 -:1061B000BDE8F09F7068D4F8FB10C0F80E10B4F87A -:1061C000FF10418294F801110175B97D4175B7F84E -:1061D0001710C182B7F819104180B7F81B108180E1 -:1061E000B7F81D10C180534908300BF02AFE97F80C -:1061F000240000F01F017068017697F82410490907 -:1062000080F864113A78417BC2F340121140417327 -:1062100094F86A00002818BFFFDF84F86CB0D6F845 -:1062200004A0BAF80000A4F86E00BAF80200A4F8BE -:106230008400BAF80400A4F88600BAF80600A4F8AE -:1062400088009AF8640184F88A0094F85F0048B1E5 -:10625000607A04F10A01012804D1487900F0C000F5 -:10626000402835D094F8600040B1607A04F10A010A -:10627000012804BF487910F0C00F29D0C4F878B0C5 -:10628000A4F87CB03878B8F1FF0FC0F380108AF81A -:106290001900D4F8EF00CAF81A00B4F8F310AAF8FD -:1062A0001E101CD0C4F87E00BAF81E00A4F88200AC -:1062B00004F17202511E404608F068FA002808BF37 -:1062C000FFDF94F8710040F0020084F8710015E0DF -:1062D000D4F80A00A067E089A4F87C00D2E7164849 -:1062E0000BF0A6FD9AF8190084F87100DAF81A008C -:1062F000C4F87200BAF81E00A4F87600012084F8F1 -:106300006A0070680088FAF7B3FCFAF713F986F8A8 -:1063100000B0FEF7BBFDFEF7ADFDFEF7DFFC0DE0C4 -:10632000BC0B0020CC000020CE000020A80C0020D8 -:10633000800C0020C70C00203A0C0020FEF733FD33 -:10634000FEF74AFD012003F09CF919E7012203F052 -:1063500048BA70B5FEF79AFDFEF78CFDFEF7BEFC5D -:10636000FEF721FD1F4C002694F8660028B1FEF7C9 -:10637000CCFDFEF720F884F866601B4D2E70FEF70A -:106380002BFD94F85700012804D0BDE87040002090 -:1063900003F077B9022003F074F994F86A0000283A -:1063A00018BFFFDF6878002808BF70BD207C84F824 -:1063B0007100D4F81100C4F87200B4F81500A4F804 -:1063C00076003C2084F86C0068680188A4F86E10A0 -:1063D000012184F86A100088FAF74AFCFAF7AAF853 -:1063E0006E7070BDBC0B0020CC0000202DE9F04188 -:1063F000FF4F044600207978FE4D4FF00108064615 -:1064000011B1012923D007E095F85310002918BFD6 -:1064100087F8018000D0012079782B2211FB02F14E -:10642000294491F82820104318D02A22A01C293191 -:106430000BF062FB66700420207084F8028078788C -:106440002B2110FB01F0284480F8286023E095F808 -:106450002810002918BF7E70DDD1DDE795F87E0099 -:10646000E0B1D5F87F00C4F80200D5F88300C4F885 -:106470000600D5F88700C4F80A00D5F88B00C4F8E8 -:106480000E0095F88F00A07466701220207084F8BA -:10649000028085F87E600120BDE8F08195F8220039 -:1064A00001281ED0287801281CBF0020BDE8F081FB -:1064B0006670132020702022A91CA01C0BF01CFB6E -:1064C000A6712E70A888A884D5F89C00417B85F819 -:1064D000261085F822800088FAF7CAFBFAF73AF806 -:1064E000D9E7667006202070686AC4F8020085F853 -:1064F0002260D0E7BF480178002914BF80884FF69A -:10650000FF7070472DE9F041BA4C064694F8280018 -:10651000002818BFBDE8F081304609F049FA01466D -:1065200001250020072937D2DFE801F00A040736E9 -:106530003636090084F82A5009E0032000E00220E2 -:1065400084F82A0004F13301304609F09BFA84F8FC -:10655000320094F8AF0018B1FDF74DFF01281FD0AD -:10656000304609F057FA84F82B0004F12C0130462C -:1065700009F029FA9E4E04F1520730787F2808BFAF -:10658000FFDF307838707F20307084F82850BDE805 -:10659000F041032001F005BF84F83200BDE8F0812E -:1065A000FDF76CFF04F12C02511E08F0EFF80028F3 -:1065B00008BFFFDF94F82B1041F0020184F82B1084 -:1065C000D8E710B5002001F0F6FD8A4CA8B1FEF71F -:1065D000F2FB012200211046FEF7F1F904F1BC00A4 -:1065E000FEF7FDFBD4F8B400FEF7FCFB94F8A00026 -:1065F000032818BF02281FD022E0FEF747FCFEF751 -:1066000039FCFEF76BFBFEF7CEFB94F8AF0030B120 -:10661000FEF77BFCFDF7CFFE002084F8AF000120E1 -:1066200084F8B800022084F8B200FEF7D5FBBDE87C -:106630001040002001F0B5BE01210020FEF79DFCB6 -:10664000FEF778FC94F8AF0018B1FDF7A0FEFEF756 -:106650004FFC032084F8B20010BD66490028B1F851 -:10666000BA202CD0FF2A0BD24FF6FF7000EA42006E -:10667000A1F8BA00FF2888BFFF2001D9A1F8BA000D -:106680005B484268012A12BF002A0D224260D243B1 -:10669000C2EBC20303EB021291F8B930DB4303EB08 -:1066A000830CCCEB83131A444260900CB1F8BA20EF -:1066B000B0FBF2F302FB130081F8B9007047012A26 -:1066C000DED95008A1F8BA0008BF0120D8D1D5E71B -:1066D00070B5484C002584F8B250012684F8B260A9 -:1066E00094F8B20002281BBF94F8B20001280020E1 -:1066F000FFDF18BF70BD2B2101FB004181F828503E -:10670000401CC0B20228F6D3257084F8225094F8B9 -:10671000AF0028B1FEF7F9FBFDF74DFE84F8AF504E -:1067200084F8AE5084F89B60324884F8A05084F816 -:10673000B15040F2011120F8981F817070BD2DE911 -:10674000F0412C4C05460C2794F8B20001281FBFDD -:1067500094F8B20002280C20BDE8F081FEF734FB6B -:10676000FDF7E4FFFDF7BBFF94F898000126002831 -:1067700001BF94F89900002894F89A00002874D07A -:1067800094F8A000032802D0022805D008E00521D3 -:10679000194800F0DEFE03E00321174800F0D9FE9F -:1067A00094F8AC00002804BF94F8AD00002847D04E -:1067B000FCF75EF907463946D4F8A800FCF769FEF5 -:1067C0000E4990FBF1F801FB180041423846FBF7F7 -:1067D0005AFEC4F8A800D4F8A4004044C4F8A400A9 -:1067E00007F0A3FFD4F8A410884229D8002007E0BE -:1067F000D4000020D00C0020B40D002040420F0037 -:10680000C4E9290794F8AD0000281CBF012008F056 -:10681000AFF8012194F8AE0000281CBF94F8AC003A -:1068200000280DD094F8910004F19202012804D1BF -:10683000507900F0C00040280ED01046FEF72AFF25 -:1068400094F8911004F19200FDF7CAFF94F8B20099 -:106850000027012818D112E008F0B7F8324604F1F9 -:106860009201FEF7E0FEEBE7FFE794F8B2000228A2 -:1068700004BF84F8B2600C2006D1BDE8F08184F832 -:10688000B860022084F8B20094F89B0080B108F050 -:1068900018F8FE4808F051F884F8AF00FC48C4F836 -:1068A000B450FEF77AFAFEF797FA3846BDE8F08161 -:1068B00007F0AFFFEDE770B5FEF786FAF54C94F8F8 -:1068C000B200022803D0FEF787FA0C2070BD012029 -:1068D00084F8B900A4F8BA000220FEF772FAEE4874 -:1068E000FDF7C5FFED4B002004F1980294F8B110BC -:1068F000491CA3FB015C4FEA5C0CACEB8C0C6144C3 -:10690000C9B284F8B110895C012907D0401CC0B21B -:106910000328EBD3FFF755FE002070BD94F8B100BB -:10692000DF49085CFDF7ABFFFDF7D9FEF2E710B5D4 -:10693000D84C94F89030022B14BF032B00280BD1B5 -:1069400000291ABF022901200020114607F0F0FE9D -:1069500008281CBF012010BD94F89000002816BF25 -:10696000022800200120BDE81040FEF71DBEC948E6 -:1069700090F89000002816BF022800200120FEF7A2 -:1069800013BEC44981F890007047C24981F8AE0037 -:10699000704770B5BF4C94F89000002816BF0228CD -:1069A0000020012084F8910004F19201FEF7E6FD39 -:1069B00094F89000022816BF03280121002184F8D2 -:1069C000AD1094F89100002504F19202012804BF53 -:1069D000527912F0C00F0AD004F19202012804D1BA -:1069E000507900F0C000402801D0002000E00120D4 -:1069F00084F8AC00002804BF002970BDC4F8A4507E -:106A0000FCF736F8C4F8A80094F8AD0000281CBFC5 -:106A1000002007F0ADFF002694F8AE0000281ABF52 -:106A200094F8AC00002870BD94F8910004F1920134 -:106A3000012804D1487900F0C000402806D029463A -:106A400004F19200BDE87040FEF724BE07F0BDFFE0 -:106A5000324604F19201BDE87040FEF7E4BD002823 -:106A600016BF0228012200228A4981F89B2081F862 -:106A7000A100704770B5874D0C4600280CBF01215E -:106A8000002185F89B1085F8A2004FF0080085F8DA -:106A9000A3000BD1002C1ABF022C012000201146AC -:106AA00007F046FE85F8A300082801D0002070BD3D -:106AB000022C14BF032C1220F8D170BD754A032894 -:106AC00008BFC2F89C1082F8A000002070477149EE -:106AD00091F8A000032804D0012818BF022807D08D -:106AE00004E091F8A200012808BF70470020704719 -:106AF00091F8A100012814BF03280120F6D17047A6 -:106B000010B5FEF7C3F9FEF7B5F9FEF7E7F8FEF7A3 -:106B10004AF9604C94F8AF0030B1FEF7F6F9FDF792 -:106B20004AFC002084F8AF00012084F8B80002205D -:106B300084F8B200FEF750F9002010BD554981F8E5 -:106B4000B300704710B5FEF7A1F9FEF793F9FEF711 -:106B5000C5F8FEF728F94F4C94F8AF0030B1FEF7B6 -:106B6000D4F9FDF728FC002084F8AF00012084F858 -:106B7000B800022084F8B200FEF72EF9BDE81040FC -:106B8000002001F00EBC2DE9F84F424CFF217F2779 -:106B9000444E84F8B0104FF00008002800F0DC826A -:106BA00004F1BC0008F0E7FF30B904F1BC0009F0C3 -:106BB00002F8002800F0D08294F8B200334D052886 -:106BC00080F0C782DFE800F0F1F1F103F0002F4818 -:106BD00008F0EEFEB07094F89B0030B9FDF73FFE70 -:106BE000002808BF4FF0000801D04FF0010894F8CA -:106BF000AF0078B107F0F2FD84F8B0000146FF283D -:106C00000CD0E81C07F0D9FD94F8B00007F0F1FDB6 -:106C100040EA080894F8B000FF2812D107F081FE7E -:106C200084F8B00094F89B1059B1082809D128784D -:106C3000E91CC0F3801007F07BFD082818BF4FF057 -:106C40000008B078072880F0C781DFE800F04BB873 -:106C500004FCFCFC300094F8AF0018B1FEF755F9C5 -:106C6000FDF7A9FB0F48FEF770F9002808BF377041 -:106C7000FEF756F9B8F1000F00F0598194F8A00022 -:106C8000012818BF022840F052810DE08C0D002031 -:106C900038230200D00C00203E230200ABAAAAAA8F -:106CA0003B230200D4000020FEF718F868E094F8B7 -:106CB000AF0018B1FEF729F9FDF77DFBFE48FEF79E -:106CC00044F9002808BF3770FEF72AF9B8F1000F21 -:106CD00000F02D8194F8A00002284AD001284FD05E -:106CE00000F025B994F8AF0018B1FEF70EF9FDF7E2 -:106CF00062FBF148FEF729F9002808BF3770FEF75C -:106D00000FF9B8F1000F00F0128194F8A0000228EA -:106D10002FD0012834D003281CBFFFDFBDE8F88F37 -:106D2000E978D4F89C00827E91421BD12979C27EF9 -:106D3000914217D16979027F914213D1A979427F9B -:106D400091420FD1E979827F91420BD1297AC27F9A -:106D5000914207D12978427EC1F38011914208BF48 -:106D6000012100D0002194F8A220012A0ED0E9B11F -:106D7000D9E0D248FFF7C6FBBDE8F84F00F002BBF0 -:106D8000CE48FFF7BFFBBDE8F84F1AE4002974D1E5 -:106D900000F11A01C94808F016FEC84808F03AFE8A -:106DA000D4F89C104876BEE024E1D2E194F8A30028 -:106DB00008287DD094F8B01081425ED0B7E094F8F6 -:106DC000AF0018B1FEF7A1F8FDF7F5FABA48FEF7E3 -:106DD000BCF8002808BF3770FEF7A2F894F8AD00A1 -:106DE00000280CBF4FF0010B4FF0000B4FF00009D3 -:106DF0002878C10905F1090007D0407900F0C000EA -:106E0000402808BF4FF0010A01D04FF0000A94F863 -:106E1000A000032806D194F89B00002818BF94F81E -:106E2000A30001D194F8B00007F09EFC009088B157 -:106E3000102108F00AFB002818BF4FF0010BBAF12F -:106E4000000F07D000E0C7E005F109010098FEF748 -:106E5000B9FB814694F8A00003280FD0FDF73EFF50 -:106E6000B8F1000F69D0FDF7C3FC50EA090064D007 -:106E70009248FFF747FB00F041B954E0D4F89C007A -:106E8000E978827E91421DD12979C27E914219D141 -:106E90006979027F914215D1A979427F914211D13E -:106EA000E979827F91420DD1297AC27F914200E037 -:106EB0003DE007D12978407EC1F38011814208BFAF -:106EC000012500D0002594F8B000082805D094F8DA -:106ED000A310884208BF012600D00026B9F1000F98 -:106EE00005D1BBF1000F04D0FDF782FC08B10121F0 -:106EF00000E00021B8F1000F09D094F8A2000128A9 -:106F000003D020B955EA060001D0012000E000209E -:106F100001420CD094F8A200012804BF002DD4F83F -:106F20009C003FF435AFBDE8F84F00F08ABAFDF79A -:106F3000D5FEBDE8F84FFFF744BB94F8A100032845 -:106F400018BF02287ED1BAF1000F7BD0B9F1000F33 -:106F500078D1DFF8688194F87E00002872D101258D -:106F600084F8805094F8AF0018B1FDF744FA012876 -:106F700021D0404608F04EFD84F8810004F18201E2 -:106F8000404608F020FD404608F051FD84F8880096 -:106F900004F18901404608F024FD307804F18F089F -:106FA0007F2808BFFFDF307888F80000377084F84A -:106FB0007E500320A0E0FDF761FA04F18202511E29 -:106FC00007F0E4FB002808BFFFDF94F8810040F0E1 -:106FD000020084F88100D6E794F8AF0018B1FDF7FD -:106FE00094FFFDF7E8F93448FDF7AFFF00286CD1B6 -:106FF0003770CAE0314808F0DBFCB0703048E978FF -:10700000427A91421CD12979827A914218D16979C8 -:10701000C27A914214D1A979027B914210D1E979C7 -:10702000427B91420CD1297A827B914208D1297806 -:107030000078C1F38011B1EBD01F08BF012500D04B -:10704000002500E042E0FDF749FEB07804286BD14E -:10705000D5B31948FDF779FF002808BF3770FDF751 -:107060005FFF94F8B80000281CBF0020FFF7F5FA76 -:107070004FF0010884F8B880104D94F8530028BBF5 -:10708000042084F8550094F8AF00A5F1910918B1D7 -:10709000FDF7B1F9012835D0284608F0BBFC0949B5 -:1070A00081F8560009F12C01284608F08CFC00BF3D -:1070B00004F15E0128460AE0D40000208C0D002077 -:1070C000B40D0020D00C00202EE05EE016E008F0A9 -:1070D00005FD84F85D001F2884BF1F2084F85D0033 -:1070E00004F17D0530787F2808BFFFDF30782870F5 -:1070F000377084F85380042001F053F9BDE8F84F4D -:10710000FFF75FBAFDF7BAF909F12C02511E07F03B -:107110003DFB002808BFFFDFFE4890F8560040F016 -:10712000020089F82B00C3E7FB48FDF70EFF00289B -:1071300008BF3770FDF7F4FE94F8B800002804BFCC -:107140000120FFF78AFA84F8B880BDE8F84FFFF70E -:1071500038BAFFDFBDE8F88F94F8B200052828BFE1 -:10716000BDE8F88FDFE800F0030303041900F1E73E -:1071700094F8AF0018B1FDF7C8FEFDF71CF9E6481A -:10718000FDF7E3FE00283FF433AFFDF7C9FEFDF73E -:10719000A5FDBDE8F84FFFF714BADF48FDF7D5FEAF -:1071A000002808BF3770FDF7BBFE94F8B800002830 -:1071B00004BF0120FFF751FA84F8B880FDF78EFD77 -:1071C000BDE8F84FFFF7FDB970B5D24C94F8B200A6 -:1071D000072878D2DFE800F08D8D8D8D8D041000AA -:1071E000CE48FDF7FCFDFDF7A5FE9620FDF71FFE3E -:1071F000042084F8B20070BDFDF748FEFDF73AFEAA -:10720000FDF76CFDFDF7CFFD012584F8B850022095 -:1072100084F8B200FDF7E0FD2078002818BFFFDFFA -:107220000026A670D4F89C000188A1804188618363 -:107230008188A183C088E08384F8206094F8AD1031 -:10724000B74849B10178C21CC1F3801121B151790D -:1072500001F0C00140292ED094F8AE1041B110F8D1 -:10726000031BC1F3801119B1407910F0C00F22D077 -:10727000AC480AF0DDFD00BF94F8AF0018B1FDF78F -:10728000BAF8012820D0D4F89C00417EE171D0F8F2 -:107290001A10A160C08BA081666126832570D4F886 -:1072A0009C000088F9F7E4FCF9F744F9BDE8704068 -:1072B000022001F076B8D4F8E700C4F80E00B4F864 -:1072C000EB006082D8E714E0FDF7D8F804F108027B -:1072D000E11D07F05BFA002808BFFFDFE07940F00E -:1072E0000200E071D4F8BF006061B4F8C3002083ED -:1072F000D4E7FFDF70BD70B5864C94F8B20000256E -:10730000052828BF70BDDFE800F03939391B0300BC -:107310008148FDF71AFE10B97F497F200870FDF7FC -:10732000FFFD94F8B800002804BF0120FFF795F98D -:1073300084F8B850FDF7D2FCBDE87040FFF741B9C2 -:10734000FDF7A4FDFDF796FDFDF7C8FCFDF72BFD4D -:1073500094F8AF0028B1FDF7D8FDFDF72CF884F8BC -:10736000AF50012084F8B800022084F8B200FDF785 -:1073700033FDBDE87040002001F013B870BD01225C -:1073800001F0E1B870B5012000F015FF614CC8B103 -:1073900004F1E401A1F1280008F04CFB04F1E4063B -:1073A00094F89110304608F02CFB04F1920130461D -:1073B00008F002FB94F8AD00C0B394F8A0000328D5 -:1073C0001FD025E0FDF762FDFDF754FDFDF786FCBB -:1073D000FDF7E9FC94F8AF0030B1FDF796FDFCF73E -:1073E000EAFF002084F8AF00012084F8B8000220F2 -:1073F00084F8B200FDF7F0FCBDE87040002000F01A -:10740000D0BF94F89B00002818BF94F8A30001D1C6 -:1074100094F8B00007F0DBFA050007D001213046F0 -:1074200008F0EFFA2946304608F0C6FA3C48FDF766 -:10743000D6FC01210846FDF7A0FD052084F8B20026 -:1074400070BD70B5022000F0B6FE324C68B301206A -:1074500000F0A7FF04F1E401A1F1280008F0EAFA26 -:10746000D4F89C00417B04F1E40008F0C1FAD4F8A0 -:107470009C0004F1BC0204F1E4061278417BC2F3E3 -:1074800040121140417394F89110304608F0B9FA57 -:1074900004F19201304608F08FFA94F8AD00B8B3C9 -:1074A00094F8A00003281FD025E0FDF7EFFCFDF7BE -:1074B000E1FCFDF713FCFDF776FC94F8AF0030B16A -:1074C000FDF723FDFCF777FF002084F8AF000120D3 -:1074D00084F8B800022084F8B200FDF77DFCBDE816 -:1074E0007040002000F05DBF94F89B00002818BF9A -:1074F00094F8A30001D194F8B00007F068FA0500F1 -:1075000014D00121304608F07CFA294630460BE0C1 -:107510000CE00000D00C0020D40000208C0D0020D6 -:10752000B40D0020DE0C002008F046FAD4F89C00D0 -:10753000C18A324808F0FEFAD4F89C00417D2F48F9 -:1075400008F0FCFA2D48FDF74AFC062084F8B2004A -:1075500070BD70B50C46054608F008FA032C47D0FC -:10756000052C18BF70BD0521284608F002FA244CEE -:10757000D4F89C0000F10E01284608F0C5FAD4F8B2 -:107580009C0000F11201284608F0C2FAD4F89C00D1 -:10759000417D284608F0D2FAD4F89C00C18A2846DA -:1075A00008F0C8FAD4F89C004188284608F0B6FADA -:1075B000D4F89C008188284608F0B4FAD4F89C00DE -:1075C000C188284608F0B2FAD4F89C0000F10801FE -:1075D000284608F0CDFAD4F89C00017E284608F031 -:1075E000AFFA94F8B3102846BDE8704008F0B2BA7C -:1075F0002846BDE87040032108F0BBB9B40D002057 -:10760000D00C00202DE9FF4F06460C46488881B07B -:1076100040F2E24148430090E08A002500FB01FB74 -:1076200094F8630091460D2818BF0C281ED0252819 -:107630001EBF94F8640025284FF0000A16D0049865 -:1076400018B10121204603F029FB94F8510094F869 -:10765000528094F8C810074659B1012958D0022920 -:107660003DD0032918BFFFDF52D0A6E04FF0010A3A -:10767000E5E7B9F1000F08BFFFDFFE4D686800289D -:1076800008BFFFDF94F85100FDF7C7FE00F2E731B5 -:107690004FF47A70B1FBF0F0696800EB010994F8DF -:1076A0005100FDF7BAFE94F85110022907BFF249C4 -:1076B0004FF47A72F1494FF4C8621144084400F261 -:1076C000E7314FF47A70B1FBF0F040F2E241081A72 -:1076D0002969584449440844051D012015E0E5483E -:1076E000A9F101014068084308BFFFDFE448B9F190 -:1076F000000F006800EB0B0506D0DE48406800F282 -:107700002230A84288BFFFDF032084F8C80053E07E -:1077100094F86310009D25291CBF94F86410252956 -:1077200036D1B4F85810B4F8EA20891A491C09B2C5 -:1077300000292DDB94F8E81009B30F4694F8E910FE -:10774000002918BF8846022807BFCB484FF47A713A -:10775000CA484FF4C8610144022F07BFC6484FF41E -:107760007A72C6484FF4C8621044814208D9081A98 -:1077700000F5FA714FF47A70B1FBF0F0054407E0C0 -:10778000401A00F5FA714FF47A70B1FBF0F02D1A3F -:10779000B9F1000F10D0DFF8DC92D9F8040020B95D -:1077A000B9F80200002818BFFFDFD9F8040000F282 -:1077B0002230A84288BFFFDF05B9FFDF2946D4F891 -:1077C000CC00FAF760FEC4F8CC00B0600020307046 -:1077D0004FF0010986F80490204603F04CFBAAF113 -:1077E0000101084208BF86F8059006D094F8C80049 -:1077F00001280CBF0220032070714046D4F824B049 -:10780000FDF7FCFD0146022F07BF9B484FF47A723B -:107810009A484FF4C8621044084400F23F614FF4A4 -:107820007A70B1FBF0F0584400F5C970F06004982C -:1078300030EA0A0004BF05B0BDE8F08F29463046A3 -:1078400007F010FF87B2204603F015FBB8420FD8AF -:10785000074686F8059005FB07F1D4F8CC00FAF747 -:1078600012FEB0602946304607F0FCFE384487B26D -:107870003946204603F012FAB068C4F8CC0005B0CF -:10788000BDE8F08F2DE9F04304467E4885B00D46F3 -:1078900090F80004DFF8F091400999F800144909C4 -:1078A000884218BFFFDFDFF8CC81002708F13C06D3 -:1078B000082D80F0FA80DFE805F0045B656560F86C -:1078C000F894202C28BFFFDF36F814000621F9F7C2 -:1078D000C5F8050008BFFFDF202C28BFFFDF36F802 -:1078E00014002988884218BFFFDF95F8C8000028D7 -:1078F00008BFFFDF284602F0BCFEC8F80470A8F8F5 -:10790000027029460020C8F8107007F0EFFE00F161 -:107910009804686AA04218D995F85200FDF76EFDE8 -:1079200095F85110022907BF53494FF47A72534911 -:107930004FF4C862114408444FF47A7100F23F607A -:10794000B0FBF1F1686A0844071B29460020C8F81B -:10795000087007F0CBFE698840F2E242514398304C -:10796000081AA0F22230C8F80C0005B0BDE8F08378 -:1079700005B0BDE8F04303F05DB805B0BDE8F043E5 -:10798000FDF792BB99F8140D4049400991F8001495 -:107990004909884218BFFFDF202C28BFFFDF36F8D7 -:1079A00014000621F9F75AF8050008BFFFDF202C64 -:1079B00028BFFFDF36F814002988884218BFFFDF90 -:1079C0000022012329466846FFF71CFE95F8D200E5 -:1079D0006946FBF797FA002808BFFFDF05B0BDE84E -:1079E000F083202C28BFFFDF36F814000621F9F7BA -:1079F00035F8050008BFFFDF202C28BFFFDF36F871 -:107A000014002988884218BFFFDF95F8C8000428B1 -:107A100018BFFFDF85F8C87095F8D2404FF6FF79A0 -:107A2000202C28BFFFDF26F8149095F8D200FBF732 -:107A300000F8002808BFFFDF202085F8D200D5F825 -:107A4000D800002804BFD5F8D400C8F8140008D026 -:107A5000D5E937121144826911448161D5E93501B4 -:107A6000C860D5F8D40000281CBFD5F8D810016133 -:107A700014D10EE0DC0D002068360200A2240200C2 -:107A8000E000002001E000E00BE000E019E000E091 -:107A90000BE0D5F8D800002818BF8761FC480078B3 -:107AA00005B0BDE8F043F4F725B9FFDF05B0BDE848 -:107AB000F0832DE9F047F74D0746E88B6C68401CD2 -:107AC000E88328784FF00008002808BFFFDF07D0C0 -:107AD000DFF8C4A3042814D0052818BFFFDF40D066 -:107AE00021462869FAF7CFFCB86087F800800120AA -:107AF0003871A86800F5B370F860287804287CD144 -:107B000085E00029ECD02E69DAF8141039B38946E3 -:107B1000C9680029FBD1B9F1000F20D099F8000005 -:107B2000002808BFFFDFD9F81410D9F80400014479 -:107B30003046FBF7AEFC002807DA211A4A1E92FBFA -:107B4000F4F202FB0406214604E090FBF4F202FB8F -:107B5000140621468E4288BFFFDF3446C0E7444604 -:107B6000BEE70029BCD0D5F81890B9F1000F08BFC6 -:107B7000FFDF0026D9F8DC10DAF814403046721E18 -:107B80005CB1A069884228BF824284BF0246264673 -:107B90002046E468002CF4D106B9064609F1C80471 -:107BA000C9F8D860002E04BFC4F80C80CAF814408D -:107BB00005D0F068F460E060002818BF0461D4F8D4 -:107BC0001090C4F81880B9F1000F0ED0D9F8180041 -:107BD00048B1D4F814A0504538BFFFDFD9F81800D9 -:107BE000A0EB0A00A061C9F81880002E08BFC5F8F4 -:107BF000208009D03078002800E00DE008BFFFDFCA -:107C0000716970680844286240F6B83468E7E88B08 -:107C10000A2838BF032000D302207871E88B01289E -:107C200006D93846696807F01DFDE98B0844E883EA -:107C3000B8682861BDE8F0872DE9F0418046974893 -:107C400084B00E4690F80004954F410997F800045F -:107C50004009814218BFFFDF01210025082E8D4C0D -:107C600062D2DFE806F0041A35353061614D617388 -:107C70002173607800281CBF04B0BDE8F0818648FD -:107C8000456005612573A068C138FEF758FD0028DE -:107C900018BFFFDF04B0BDE8F081607850B1207BF1 -:107CA000002808BFFEF72CFF657304B0BDE8F04163 -:107CB000FAF7E9BDA173FEF7FEFD002818BFFFDF4C -:107CC00004B0BDE8F08104B0BDE8F041FDF7ECB9C7 -:107CD00097F8140D7349400991F800144909884236 -:107CE00018BFFFDF00216846FFF7E3FE6946404604 -:107CF000FBF708F9002808BFFFDF04B0BDE8F081FA -:107D00002078052818BFFFDF207F002808BFFFDF8D -:107D100025772570207DFAF78CFE002808BFFFDF4D -:107D2000257504B0BDE8F081FFDF04B0BDE8F08147 -:107D30002DE9F041574C0026207804281FBF2078F9 -:107D400005280C20BDE8F08101206070607B0025D3 -:107D5000A8B1EFF3108010F0010F72B60CBF00272E -:107D60000127607B00281CBFA07B002805D0FEF700 -:107D7000C7FE6573A573FAF786FD2FB903E0207D72 -:107D8000FBF7D3F900E062B6207DFBF71CFC207FF7 -:107D900028B125772078052818BFFFDF0C266570ED -:107DA0002570207DFAF745FE002808BFFFDF257506 -:107DB0003046BDE8F0812DE9F04F364883B00078B9 -:107DC000002818BFFFF7B4FF0120DFF8CC8088F847 -:107DD000000069460620F8F7CCFD002818BFFFDF39 -:107DE00000274FF6FF7934E0029800281CBF90F876 -:107DF000C81000292DD0008848451CBFDFF8A8A076 -:107E00004FF0200B3BD00621F8F728FE040008BFF6 -:107E1000FFDF94F8D200FBF7D6FB84F8C87094F823 -:107E2000D2504FF6FF76202D28BFFFDF2AF81560CD -:107E300094F8D200FAF7FDFD002808BFFFDF84F8B0 -:107E4000D2B069460620F8F794FD002818BFFFDF7E -:107E500010E06846F8F76BFD0028C5D00FE00298E7 -:107E600000281CBF90F8C810002903D0008848459E -:107E7000C9D104E06846F8F75AFD0028EFD088F829 -:107E80000070C8F8147003B00020BDE8F08F000047 -:107E9000DC000020F40D0020DC0D002001E000E0FB -:107EA0000BE000E019E000E0180E002010B50078AB -:107EB000F84C60B101280CBF40F6C410FFDF06D0BB -:107EC000A06841F66A01884228BFFFDF10BDA060AC -:107ED000F6E710B5EF4C00232070EF4803704370B5 -:107EE000037703734373837320218361017518380B -:107EF00043703A3010214FF6FF72428020F8042F71 -:107F0000491EFAD1180008BFA36005D0002B0EBF90 -:107F1000FFDF40F6C410A060A06841F66A01884205 -:107F200028BFFFDFBDE8104045E72DE9F043DA4CFC -:107F3000054685B0207816460F4600281EBF0C2047 -:107F400005B0BDE8F08395F8519095F85200D5F84A -:107F50002480FDF753FAB9F1020F07BFCF494FF460 -:107F60007A72CF494FF4C862114408444FF47A79C9 -:107F700000F23F60B0FBF9F0404400F22230C5F857 -:107F8000DC00A56195F8C800002818BFFFDF40F2AB -:107F90007120784360600120FDF730FA00F2E7308D -:107FA000B0FBF9F040F2712106FB0100A0606168AE -:107FB000A1F2F621884298BF01460020A160B9498C -:107FC00008610521217060702077E083B648FAF7D8 -:107FD000D5FC2075202808BFFFDFFAF749FD206196 -:107FE00001216846FFF765FD207D6946FAF78AFFA3 -:107FF000002808BFFFDF002005B0BDE8F083A648D9 -:10800000007800281CBF0020704710B50620F8F744 -:10801000C1FC80F0010010BD30B59F4C85B02278C6 -:10802000002A1EBF0C2005B030BD0D4640F2712164 -:10803000484360600120FDF7E1F94FF47A7100F2E6 -:10804000E730B0FBF1F040F2712105FB0100A060C8 -:108050006168A1F2F621884298BF01460020A16024 -:10806000607004212170E0838F48FAF787FC207547 -:10807000202808BFFFDF8B48406938B10146C0683F -:108080000028FBD111B1FAF7F3FC05E0FAF7F0FC98 -:1080900040F6B831FAF7F7F9206101216846FFF799 -:1080A00008FD207D6946FAF72DFF002808BFFFDF95 -:1080B000002005B030BD70B5774CA1690160FFF7B5 -:1080C00037FE002300BBA169D1F8D8205AB1D1E90D -:1080D00037C5AC449569AC44C2F818C0D1E9352C19 -:1080E000CCF80C2005E0DFF8BCC1D1F8D420CCF8E6 -:1080F0001420D1F8D420D1F8D810002A18BF11616B -:1081000002D1002918BF8B61A36170BD6549487019 -:10811000704770B540F2E24300FB03F510460C4691 -:10812000FDF76CF9022C07BF5C494FF47A725C4989 -:108130004FF4C862114408444FF47A7100F23F6072 -:10814000B0FBF1F000F2223085428CBF281A0020EB -:1081500070BD70B50D4606460146002007F0C6FA10 -:10816000044696F85200FDF749F996F85110022995 -:1081700007BF4A494FF47A7249494FF4C862114423 -:1081800008444FF47A7100F23F60B0FBF1F071885F -:1081900040F271225143C0EB4100A0F22230A542CF -:1081A00034BF21462946814203D2A5422CBF28462E -:1081B0002046706270BD3B4910B54968002801F146 -:1081C000980408BF04F5BC7409D0012808BF04F561 -:1081D000317404D0022814BFFFDF04F5B0742E48B8 -:1081E0008068A0428CBF0120002010BD10B52D4C2E -:1081F000607828B1D4E90201626807F05BFAA060F8 -:10820000D4E9010188429CBF2078002814BF0020D7 -:10821000012010BD04222DE9F043204FDFF88080BB -:1082200085B04FF47A79052980F0B980DFE801F054 -:108230000A2B033E890080F8C82005B0BDE8F04352 -:10824000FAF721BB044617480078002818BF84F8C5 -:10825000C82004D005B0BDE8F043FAF714BB0122F2 -:10826000002321466846FFF7CDF994F8D20069460D -:10827000FAF748FE002808BFFFDFB4F85800401C9A -:10828000A4F85800E6E7032180F8C81005B0BDE85F -:10829000F0830000DC000020F40D002068360200AE -:1082A000A2240200DC0D0020397C01000446408835 -:1082B00040F2E2414843B3490860D4F8F000214657 -:1082C0000089E082D4F8F00080796075D4F8F0007D -:1082D00040896080D4F8F0008089A080D4F8F00054 -:1082E000C089E0800020A66A07F000FA054694F8ED -:1082F0005200FDF783F894F8511002290EBF4FF495 -:108300007A7147464FF4C8613944084400F23F602F -:10831000B0FBF9F1608840F271225043C1EB40009C -:10832000A0F22230AE4234BF29463146814203D208 -:10833000AE422CBF304628466062022084F8C80056 -:10834000A4E706460146856A002007F0CFF90446F7 -:1083500096F85200FDF752F896F8511002290EBF18 -:108360004FF47A7147464FF4C8613944084400F22B -:108370003F60B0FBF9F0718840F271225143C0EBCD -:108380004100A0F22230A54234BF21462946814255 -:1083900003D2A5422CBF28462046706276E7FFDF55 -:1083A00074E72DE9F041DFF8E0810025774C98F87B -:1083B000001084B0052880F0C180DFE800F00316CB -:1083C0006DB9B900E5830846F3F794FC607800289E -:1083D00073D100216846FFF76CFB207D6946FAF7F0 -:1083E00091FD002808BFFFDF67E00120FDF706F8D8 -:1083F0006749684E08444FF47A71B0FBF1F0216987 -:10840000726840F2E2431144081AA16900F2DE608A -:108410004A88C83102FB03F772698A4208BF002507 -:1084200014D0216AFBF735F8002807DA391A4A1EFA -:1084300092FBF7F202FB0705394604E090FBF7F2E6 -:1084400002FB170539468D4288BFFFDFD8F80800C8 -:10845000854208D2A06940F271224188C1824A4314 -:1084600005EB420505E040F2E240B5FBF0F0A16902 -:10847000C882A06905214175C08A6FF41C71484308 -:1084800005EB400040F635413061B0EB410F28BFAD -:10849000FFDF04B0BDE8F081E5830846F3F72AFC6E -:1084A00001202077A0692169C0F8CC1080F8C8505D -:1084B0002178052918BFFFDF06D0FAF7E4F96573C4 -:1084C000A57304B0BDE8F081002808BFFFDFA069F4 -:1084D00090F8C800002818BFFFDFA06990F8D2000C -:1084E000202818BFFFDF2C48FAF748FAA169064692 -:1084F000202881F8D2000F8828BFFFDF274820F806 -:108500001670A06990F8D200202808BFFFDF002372 -:1085100001226846A169FFF775F8A069694690F8DD -:10852000D200FAF7EFFC002808BFFFDFA561C4E71F -:1085300004B00846BDE8F041F3F7DCBBFFDF04B050 -:10854000BDE8F081704770B5124D0446002912BF96 -:108550000129686070BD02291CBFFFDF70BD6888FB -:10856000401C68801046FCF758FF4FF47A7100F207 -:10857000E730B0FBF1F0201A686070BD0348007866 -:1085800070470000E0000020DC000020F40D002017 -:10859000C92E0200DC0D002085780100180E002095 -:1085A000FE48406870472DE9F0410D4606460146F9 -:1085B0001746012007F09AF8044696F85200FCF797 -:1085C0001DFF96F8521002290CBFF549F5490844E1 -:1085D0004FF47A7100F2E140B0FBF1F0718840F2A3 -:1085E00071225143C0EB4100C01BA0F55970A54258 -:1085F00034BF21462946814203D2A5422CBF2846DA -:1086000020467062BDE8F0812DE9FF4F8FB004462F -:1086100090F85200DDF8709098460B9049EA0800F7 -:108620000C9094F86400002617460D280CBF01201A -:1086300000200890B8F1000F04BF94F8040103284B -:1086400071D1089800286ED0B4F87C01B8426AD184 -:10865000D4F80C01C4F8F800608840F2E2414843C5 -:10866000C4F8FC00B4F85201B4F8DE100844C4F8B1 -:108670000001204604F00DFDB4F88001E08294F87A -:108680007E016075B4F882016080B4F88401A08036 -:10869000B4F88601C549E080C348097894F864318C -:1086A000628830F8111030F81300D4F828A008447C -:1086B0000004000C4FF0000105D000FB02F1BC48A3 -:1086C000B1FBF0F0411C1FFA81FB2146012007F0AD -:1086D0000DF8054694F85200FCF790FE94F85210FD -:1086E00002290CBFAE49AF49084400F2E1414FF402 -:1086F0007A70B1FBF0F1608840F271225043C1EB17 -:108700004000A0EB0B00A0F55970AA4534BF2946E4 -:108710005146814203D2AA452CBF5046284660628A -:10872000022084F80401D4E956ABB4F8DE000390CB -:10873000B4F85001D4F84C110691B8F1000F03D0F1 -:1087400094F8181149B17FE004F1D8010091743117 -:10875000099104F59C75091D07E004F596710091D7 -:10876000091D099104F58E75091D0A91B4F8581078 -:10877000381A791A09B200B20491002805DAD4F83F -:108780004801069001200C90084694F80411002935 -:108790005ED0012900F0668102297DD0032918BF2F -:1087A000FFDF00F0A98131460698F9F76CFE0999C0 -:1087B00008600A9801210780002028702971099813 -:1087C0000068A8607948D0E90520824287BF009AF6 -:1087D0001060009802600098626A0068104400F21D -:1087E0008310E8606971B4F8C800C01B00B20028AB -:1087F000C4BF032068710898002800F0F181B9F126 -:10880000000F18D0B4F8F020002A0CBF0020B4F8F4 -:10881000F200A4F8F20094F8F430401C584390425F -:1088200009D26879401E002805DD6971B4F8F200AC -:10883000401CA4F8F200B8F1000F00F0F58194F8A4 -:108840001801002800F0EC8113B00220BDE8F08F81 -:10885000BAF1000F08BFFFDFE08A40F27121484300 -:10886000490001EB400210980021002806D000FBCF -:1088700002F14F48B1FBF0F000F10101C4F808111A -:10888000608840F2E24100FB01F210994FF00000D5 -:1088900008D001FB02F100E042E04548B1FBF0F0F6 -:1088A00000F10100C4F80C010AF101064FF00100CB -:1088B000FCF7A4FD3F494FF47A7B0844B0FBFBF082 -:1088C000E18A40F271225143C0EB4101D4F8080122 -:1088D0000190091A314401F2C246607D510010FB3B -:1088E00001F00C900120FCF789FD33490844B0FBEE -:1088F000FBF1019801EB40010C9801EB000B01200A -:10890000FCF770FD584400F1620128484161816123 -:10891000A6EB0A00401EB0F53D7F38BFFFDF42E7FF -:10892000E28A40F271215143D4F8FC00109A00EB26 -:1089300041010020002A06D01D4802FB01F2B2FBD3 -:10894000F0F000F10100C4F80801628840F2E2434F -:1089500002FB03FC109B4FF0000206D0144A03FBFD -:108960000CF3B3FBF2F202F10102C4F80C21039AFA -:108970009AB9B9F1000F38D094F85200FCF73EFDD7 -:10898000014694F8520002280CBF054A054A1144DA -:1089900001F2E1424FF47A7110E026E0580E002017 -:1089A00004360200A224020042230200E800002054 -:1089B00040420F007D2A020083290200B2FBF1F140 -:1089C000D4F80821E38A114440F2712CD4F8FC2039 -:1089D00003FB0CF302EB4302561AFCF703FDABEB6F -:1089E00000003044A0F1200600E00E1AD4F8002167 -:1089F000D4F8F810D4F8080101FB020B607D40F2B6 -:108A0000E24110FB01F00C9094F852A05046FCF7A4 -:108A1000F5FC0146BAF1020F0CBFF948F9480844C9 -:108A200000F2E1414FF47A70B1FBF0F000EB4B0142 -:108A30000C9801EB000B5046FCF7D4FC584400F1B5 -:108A40006001F14840F2712341616288D4F80C1151 -:108A50005A43C1EB4201A1F213318161012084F834 -:108A60000401A0E6628840F27123D4F80C115A4345 -:108A7000C1EB420202FB00F6DDE903020244D4F836 -:108A80000001D4F8F8C0121AD4F80831521E0CFBB9 -:108A9000003002FB010B607D40F2E24110FB01F06F -:108AA0000C9094F852000190FCF7A8FC0146019844 -:108AB000022814BFD348D248084400F2E1414FF4E1 -:108AC0007A70B1FBF0F000EB4B010C9801EB000B5E -:108AD0000198FCF787FC584400F16001CA48B9F1DD -:108AE000000F4161A6F2133181613FF45CAEBAF12F -:108AF000000F08BFFFDF56E6628840F27123D4F80A -:108B00000C115A43C1EB420101FB00F694F86300DB -:108B100025281CBF94F8640025280AD1B4F87C01EC -:108B2000381A00B2002804DB94F87F01002818BF2F -:108B30000B900C9828B1039880B3BBF1000F18BFBD -:108B4000FFDFDDE903010144D4F80C0101FB00FA69 -:108B50000B98FCF753FC01460B9802280CBFA84861 -:108B6000A848084400F2E1414FF47A70B1FBF0F0FC -:108B700000EB4A0A0B98FCF735FC504400F1600109 -:108B8000A14840F2712341616288D4F80C115A4324 -:108B9000C1EB4201A1F21331816104E6FFE7BBF1B1 -:108BA000000F14BFBAF1000FFFDF0B98FCF726FC93 -:108BB0000B9902290CBF92499249084400F2E14105 -:108BC0004FF47A70B1FBF0F0361A94F85200FCF7CB -:108BD00009FCABEB00003044A0F12006B1E700BF78 -:108BE000B9F1000F7FF40EAE94F8040100283FF4B1 -:108BF00022AE618840F27122D4F80C015143C0EBDF -:108C00004101284606F02EFD0004000C3FF413AE8F -:108C10001D99002918BF0880012013B0BDE8F08F0E -:108C200094F85401FAF781FA94F854012946FAF7B6 -:108C300069F900281CBF88F0010084F819010020A0 -:108C400013B0BDE8F08F2DE9F04F704C804683B033 -:108C500020788A4600256C4E4FF00209032804BF95 -:108C6000207B40457CD1606830612078032818BFA4 -:108C7000FFDF0327BAF1080F70D2DFE80AF0040E15 -:108C80001B1B166F6F6A6562FCF74FFF002818BF49 -:108C9000FFDFB77003B0BDE8F08FFDF7CBF8002819 -:108CA00018BFFFDF03B0BDE8F08F03B0BDE8F04FA1 -:108CB000FCF7FAB927752574E07A012658B14FF40C -:108CC0007A71A069F9F7DFFBA061002104F11000BF -:108CD00006F0C8FC1AE001216846FAF71AFF9DF871 -:108CE000000042F210710002B0FBF1F201FB12052C -:108CF000FCF793FD05442946A069F9F7C4FBA06180 -:108D0000294604F1100006F0ADFC461C208C411CE5 -:108D10000A293CBF30442084606830B1208C401C5C -:108D20000A2828BF84F8159000D26775607A002859 -:108D30001CBF03B0BDE8F08F207B04F11001FAF7EF -:108D4000E1F8002808BFFFDF03B0BDE8F08F07E0BF -:108D500004E0207BF9F76DFE2570F5E7FFDFF3E710 -:108D6000B8F1200F28BFFFDF294F072137F818007F -:108D7000F7F774FE040008BFFFDFB8F1200F28BF2B -:108D8000FFDF37F818002188884218BFFFDF4FF057 -:108D900001083461BAF1080F80F04481DFE80AF07D -:108DA000049AA2A29DEEEEEDC4F85851F580C4F8E5 -:108DB0005C5194F8190138B9F9F75AFED4F8241126 -:108DC000FAF767FB002825DCB4F81611B4F8580050 -:108DD000814206D1B4F8CC10081AA4F8CE0020467F -:108DE00005E0081AA4F8CE00B4F816112046A4F83D -:108DF0005810D4F84011C4F82411C0F8481127E0E5 -:108E000004360200A2240200E8000020580E0020D0 -:108E1000800E0020B4F81411B4F85800081AA4F811 -:108E2000CE00B4F814112046A4F85810D4F8241138 -:108E3000C4F84011C4F84811D4F82C11C4F8D81063 -:108E4000D4F83011C4F84C11B4F83411A4F850110E -:108E500003F0D7FFF9F7E6FD94F852A00746504615 -:108E6000FCF7CCFABAF1020F0CBFFE49FE490844E8 -:108E70004FF47A7100F2E140B0FBF1F1D4F80C014B -:108E800040F27122014460885043C1EB4000A0F1E0 -:108E9000300AB72F98BFB7272146012006F026FCDD -:108EA0003844AAEB0000A0F21937A246214601205F -:108EB00006F01CFCDAF824109C30814288BF0D1AA1 -:108EC000F760BD4228BF3D46B56084F8188186F83A -:108ED000029039E704F0DBF801E0FCF7E5F884F8EC -:108EE000188131E7F9F7C4FDD4F84821014610464E -:108EF000FAF7CFFA48B1628840F27123D4F80C1126 -:108F00005A43C1EB4201B0FBF1F094F864100D2913 -:108F10000FD0B4F85810B4F816210B189A42AEBF0F -:108F2000501C401C0844A4F8160194F81A0178B9A2 -:108F300005E0B4F81601401CA4F8160108E0B4F8E6 -:108F40001601B4F8CC10884204BF401CA4F81601E6 -:108F5000B4F85201DFF81493401CA4F85201B4F89D -:108F60007E00B4F87C100DF1080B401AB4F85810CC -:108F7000401E08441FFA80FA17E045E052E03078BE -:108F8000002339F81000CDE9005B94F8641139F83A -:108F90001110084481B22046FFF736FB00283FF449 -:108FA000D3AE012818BFFFDF26D0B4F81621AAEBF4 -:108FB000020000B20028E2DA082084F8730084F886 -:108FC0007280204603F0D2FB84F8045194F8545187 -:108FD0004FF6FF78202D00D3FFDF27F8158094F897 -:108FE0005401F9F726FD202084F85401307903B0AC -:108FF000BDE8F04FF2F77EBEB4F81601BDF80810D8 -:109000000844A4F81601D0E794F80401042818BF16 -:10901000FFDF84F8045194F854514FF6FF78202D67 -:10902000DBD3D9E7FFDF8FE610B5914C207850B144 -:1090300001206072FCF71DFF2078032805D0207AFC -:10904000002808BF10BD0C2010BD207BFAF76DF87A -:10905000207BFAF7B8FA207BF9F7EBFC002808BF71 -:10906000FFDF0020207010BD2DE9F04F804F83B04E -:10907000387801244FF0000840B17C720120FCF7E1 -:10908000F8FE3878032818BF387A0DD0DFF8E4915D -:1090900089F8034069460720F7F76BFC002818BFE2 -:1090A000FFDF4FF6FF7440E0387BFAF73EF8387B7D -:1090B000FAF789FA387BF9F7BCFC002808BFFFDF14 -:1090C00087F80080E2E7029800281CBF90F804119E -:1090D00000292AD00088A0421CBFDFF89CA14FF0D5 -:1090E000200B3AD00721F7F7B9FC040008BFFFDFD7 -:1090F00094F85401FAF767FA84F8048194F854510B -:109100004FF6FF76202D28BFFFDF2AF8156094F870 -:109110005401F9F78EFC84F854B169460720F7F73B -:1091200028FC002818BFFFDF12E06846F7F7FFFBB6 -:109130000028C8D011E0029800281CBF90F8041144 -:10914000002905D00088A0F57F41FF39CAD104E08D -:109150006846F7F7ECFB0028EDD089F8038087F824 -:109160000B8003B00020BDE8F08F70B50446434883 -:1091700090F80004424D400995F8001449098842CE -:1091800018BFFFDF95F8140D40093E4991F800140F -:109190004909884218BFFFDF3649002001220C71BF -:1091A00088700A704870C87031490870BDE8704016 -:1091B0005AE73049087070472DE9F8432C4C0646B1 -:1091C0002078002875D13048F9F7D8FB2073202883 -:1091D0006FD0032766602770002565722572AEB1D7 -:1091E000012106F1F400FAF70CFD0620F7F7E0FB89 -:1091F00080460720F7F7DCFB96F8F4104044B1FBFB -:10920000F0F200FB1210401C86F8F400F9F70AFC9B -:109210001E49091838BF40F2F65000F59D7086B21D -:10922000FCF7D7FAE061FCF7F8FA4FF0010878B3E1 -:1092300084F80A8001216846FAF76BFC9DF800006B -:1092400042F210710002B0FBF1F201FB1200064481 -:10925000F9F70EFC3146F9F716F9A0612775677525 -:10926000257416E004360200A22402004223020004 -:10927000580E0020E8000020800E002001E000E0F1 -:109280000BE000E019E000E0478C01000AFAFFFF64 -:1092900012E0207B04F11001F9F734FE002808BF2A -:1092A000FFDF25840020FCF7E4FD0020BDE8F88303 -:1092B000FFE70C20BDE8F883F9F7DAFB3146F9F750 -:1092C000E2F8A061A57284F80B80C7E72DE9F047AA -:1092D00082B00026044680F80461A0F85061DFF8EF -:1092E00000944288FD4FD0F8288099F8000094F847 -:1092F000641137F8100037F8111008440104090C04 -:10930000304605D001FB02F0F649B0FBF1F0401CFD -:109310001FFA80FA2146012006F0E8F9054694F884 -:109320005200FCF76BF894F8521002290CBFEE497A -:10933000EE4908444FF47A7100F2E140B0FBF1F1DC -:10934000608840F271225043C1EB4000A0EB0A005C -:10935000A0F55970A84534BF29464146814203D241 -:10936000A8452CBF4046284660620096019699F8B1 -:10937000000094F86411002337F8100037F811103A -:109380001A46084481B22046FFF73EF9002818BF6C -:10939000FFDFC4F800610120C4F8F86084F804011C -:1093A000A4F81661A4F8146184F81A61B4F858009E -:1093B000401EA4F85800A4F8526102B00020BDE895 -:1093C000F087C74948707047C94810B5417A0124F1 -:1093D000002918BF002408D1C17A31B1406AC549BB -:1093E000884284BF0024FCF740FD204610BD70B5C4 -:1093F000BB4C0546E088401CE080D4E9020162785D -:10940000D5F85861002A1CBF324606F053F9A06017 -:10941000864208D895F80401012804D0E078002895 -:1094200004BF012070BD002070BD70B50D4640F234 -:10943000E24100FB01F42846FBF7E0FF022D0CBFE0 -:10944000A949AA4908444FF47A7100F2E140B0FBFF -:10945000F1F000F54D7084428CBF201A002070BDE1 -:109460002DE9F04383B00026044680F8186190F897 -:10947000D600002807BF94F80401032803B0BDE814 -:10948000F083F9F7F5FAD4F8482101461046FAF7C7 -:1094900000F80028DCBF03B0BDE8F083628840F22A -:1094A0007123D4F80C115A43C1EB4201B0FBF1F027 -:1094B000411CB4F858000144A4F81411B4F8CC10BD -:1094C000B4F81421891A09B20029DCBF03B0BDE841 -:1094D000F083012184F81A11B4F87E10B4F87C20CE -:1094E0007E4F891A491E084485B2DFF8F4810DF1D8 -:1094F00008091EE098F8000037F81000CDE900696F -:10950000B4F8142194F86411012337F811100844B9 -:1095100081B22046FFF778F8002804BF03B0BDE809 -:10952000F08301280FD0022812BFFFDF03B0BDE88F -:10953000F083B4F81401281A00B20028BCBF03B0AD -:10954000BDE8F083D6E7B4F81401BDF8081008446C -:10955000A4F81401EDE7F0B5DFF884C104265F4BF1 -:109560009CF80020002583B006297DD2DFE801F0B9 -:10957000073C03191941044680F8046107E00446DA -:109580009CF80300002818BF84F804610BD0F9F799 -:109590007AF9A4F85251B4F85800A4F8160184F8E6 -:1095A0001A5103B0F0BD33F8120094F804210121E0 -:1095B000032A13BF94F80421C4F80051C4F8F850EA -:1095C000012AE4D1CDE9001594F86411B4F8CC2057 -:1095D00033F811100023084481B22046FFF714F835 -:1095E000002818BFFFDFD2E7032180F8041103B081 -:1095F000F0BD0446B0F802C0866A90F8640133F802 -:10960000121033F8100008440104090C4FF0000058 -:1096100005D001FB0CF03349B0FBF1F0401C87B2E0 -:109620002146012006F062F8054694F85200FBF747 -:10963000E5FE94F8521002290CBF2B492B4908442F -:109640004FF47A7100F2E140B0FBF1F0618840F232 -:1096500071225143C0EB4100C01BA0F55970AE42CE -:1096600034BF2946314600E008E0814203D2AE42D1 -:109670002CBF30462846606203B0F0BDFFDF03B068 -:10968000F0BD2DE9F8431A4C0327154EE27AA17A72 -:1096900042F21079002550B1012843D002281CBFA6 -:1096A000FFDFBDE8F8834FF000081AB95EE04FF025 -:1096B00000080AB1E5722EE051B101216846FAF7BF -:1096C0004DFA9DF800000002B0FBF9F109FB11080A -:1096D000FCF7A3F800EB0801A0690DE042230200AB -:1096E000E800002040420F0004360200A2240200DD -:1096F000580E0020DB821300F8F7C5FEA061257428 -:109700006775607A30B9207B04F11001F9F7FAFB34 -:1097100000284BD02584F9F7B6F83079BDE8F84336 -:10972000F2F7E8BAE572A7692570012020720021DE -:10973000606805F035FB6068C0F84871217B80F8EF -:109740005411616AC0F84C71C0F8581190F8545126 -:109750000788202D28BFFFDF3C4820F8157060687F -:10976000FFF7B4FD002818BFFFDFD4E751B1012196 -:109770006846FAF7F3F99DF800000002B0FBF9F132 -:1097800009FB1108FCF749F800EB0801A069F8F79C -:109790007AFEA06125746775607A0028BAD1207BB3 -:1097A00004F11001F9F7AEFB0028B3D1FFDFB1E7F8 -:1097B00070B5274CA178022906BFE188002970BD49 -:1097C0002569C5F85C0195F85200FBF70BFED5F84A -:1097D0005C11081AA1680144A160E1680844E060D6 -:1097E00070BD70B505461A488378022B06BF006924 -:1097F00000F5AC74174C002904BF256070BD012929 -:1098000008BF681E0DD002291CBFFFDF70BD1046C7 -:10981000FBF703FE4FF47A7100F2E140B0FBF1F088 -:10982000281A206070BD0C48007800281CBF00205A -:10983000704710B50720F7F7ADF880F0010010BDB4 -:1098400005480078002818BF01207047800E0020CE -:10985000E80000207C0E0020580E0020F8490C285B -:10986000896881F8C3001ABF13281828704700229E -:1098700011280FD0072808BF704715280AD00128E3 -:109880001ABF002802287047A1F88220012081F821 -:1098900086007047A1F88820704770B5E84CA16831 -:1098A0000A88A1F8362181F8340191F85100012885 -:1098B00008BF012508D0022808BF022504D00428CB -:1098C00016BF08280325FFDFA06880F8385190F8FC -:1098D0005200012808BF012508D0022808BF022530 -:1098E00004D0042816BF08280325FFDFA068012143 -:1098F00080F8395180F83211002180F80611E078A3 -:10990000BDE87040F2F7F6B9F0B4CD48806890F841 -:109910004E30478EC68E458FB0F84010C28FB0F8DB -:1099200042C0022B1FD08D4238BF294601866245B6 -:1099300028BF62468286018FB0F84430994238BF12 -:109940000B464386818FB0F84640A14238BF0C4693 -:10995000C486BB4228BF1F464786B44228BF26465E -:10996000C686F0BC7047038E9D4228BF1D46838E7D -:109970009A4228BF1A46A94298BF0D4605869445CB -:1099800098BF62468286002180F84E10D3E7AC4A29 -:10999000012992681BD0002302290FD0032921D06E -:1099A00028B301282ED0032818BF704792F863000F -:1099B00013281CBF1628182805D1704792F8C30039 -:1099C000002808BF7047D2F8F0000370704792F883 -:1099D000C300012808BF7047D2F8F4000178491E7F -:1099E0000170704792F8C3000328ECD17047D2F899 -:1099F000F000B2F858108288891A09B20029A8BF6D -:109A000003707047B2F85800B2F8FA10401A00B26A -:109A10000028E1DA70472DE9F04100260327884C41 -:109A20000125A0B1206906F0CCF9A16881F8C20037 -:109A300005FA00F010F4000F08BFFFDFA06880F8FF -:109A40006370A0F8826080F88650BDE8F081A0685D -:109A50000023194690F86420583005F0A2FD002834 -:109A600004BF6570BDE8F0816078002818BFBDE8CC -:109A7000F081206906F0A5F9A16881F8C10081F89C -:109A80006470A1F8886081F88A50BDE8F08170B5F3 -:109A90006B4C84B0207910F0010F04BF04B070BD8E -:109AA000206900230521C578A06890F8632058300C -:109AB00005F077FD002818BF022D0FD00B2D18BF21 -:109AC000042D0BD0052D18BF062D07D00D2D18BF66 -:109AD000112D03D0607840F0080060706078002895 -:109AE0001CBF04B070BD2069C078801E162880F0AD -:109AF0005283DFE800F00BFBA7C5FA26FBF9FB9ABF -:109B0000F8FCFBFBFBE3F6F5F4F3F2F1A0680023AD -:109B1000012190F86620583005F043FD002840F000 -:109B2000B583206906F0A8F9A16881F8EE00072046 -:109B300081F86600002081F88A0081F8860000F034 -:109B4000A5BBA0680921002390F86320583005F0D8 -:109B500028FD20B1206906F0DFF9122814D0A06892 -:109B60000A21002390F86320583005F01AFD20B137 -:109B7000206906F0D1F9142821D0206906F0CCF92B -:109B8000162840F0838342E0A0680125002390F866 -:109B900063200921583005F004FD002808BF6570D6 -:109BA00000F074836078002840F07083A16881F829 -:109BB0007A0081F8860081F8630000F067BBA06836 -:109BC0000021012580F86310A0F8821080F886102B -:109BD0000421FEF71FFBA06890F84E10012900F049 -:109BE0007C820288A0F81621028EA0F81821828EAD -:109BF000A0F81A21428E00F58671A0F81C21C08EB3 -:109C000048820D72E078F2F775F800F03FBBA0686B -:109C100090F86310202940F03983002180F8631008 -:109C200080F886101A2000F02FBBA06890F863100F -:109C30000F292AD1002180F8681012213AE0000093 -:109C400004010020A06890F8631013291DD1D0F8FA -:109C5000F01000884988814218BFFFDFA068D0F863 -:109C6000F00000F12601206906F033F9A06800F148 -:109C7000BC01206906F035F91620A16800F064B92E -:109C8000A26892F86300162802D0022000F064BA9D -:109C9000D2F8F00002F1A80300F11E0100220E30FC -:109CA00005F007FCA0680021C0E92611012180F819 -:109CB0006810182180F8631000F0E8BA206906F0F7 -:109CC000B0F9032840F0E282206906F0AEF900BF47 -:109CD00001F022FC00F0DABA8DE202E2AEE152E1DC -:109CE0001EE135E103E050E0C4E004E0D5E1206985 -:109CF00006F00EF9ECE7A06890F863101B29C4D1B8 -:109D0000002580F88B5080F88650D0F8F01000883D -:109D10004988814218BFFFDFA068D0F8F0100D70AD -:109D2000D0F83C110A78002A18BFFFDF40F0F3801A -:109D300090F88C207AB180F88C500288CA80D0F8D4 -:109D40003C110D71D0F83C210D211170D0F83C214F -:109D50000188518010E00288CA80D0F83C110D7152 -:109D6000D0F83C2101211172D0F83C210C21117056 -:109D7000D0F83C21018851800088F6F779FFF6F78A -:109D8000D9FBE078F1F7B6FFC5E0A06800231946DB -:109D900090F86420583005F004FC50B9A068002306 -:109DA000082190F86320583005F0FBFB002800F0F4 -:109DB00027826078002840F06982A06890F88E00C1 -:109DC00010F0020F17D1206906F098F8A16881F809 -:109DD0008F00206906F094F8A168A1F8900020692E -:109DE00006F091F8A168A1F8920091F88E0040F079 -:109DF000020081F88E00A06890F88E1011F0010F1B -:109E000012D190F8642000231946583005F0C9FBA0 -:109E1000002808BFFFDF0121A06880F8641080F8E7 -:109E20008A100021A0F88810A06890F8631001291A -:109E300007D1002180F8631080F88610E078F1F7F0 -:109E400059FFA168D1F8F000098842888A4204BF0E -:109E50000178042940F01A8200250570E078F1F7B6 -:109E600049FFA06890F86310002908BF80F8865069 -:109E700000F00CBAA0680023072190F86320583046 -:109E800005F08FFB002800F0BB816078002840F0CF -:109E9000FD8102A9206906F079F8A0689DF80820E4 -:109EA000002590F89410114001F02F0180F89410D3 -:109EB00090F895109DF80920114001F0410180F8BB -:109EC000951080F88650D0F8F010008849888142BB -:109ED00018BFFFDFA068D0F8F0100D70D0F83C116B -:109EE0000A78002A18BFFFDF15D10288CA80D0F88F -:109EF0003C110D71D0F83C11029A8A60039ACA6035 -:109F0000D0F83C21072111700188D0F83C01418034 -:109F1000E078F1F7EFFEA06880F8635000F0B6B982 -:109F2000A0680023092190F86320583005F039FB20 -:109F3000002800F065816078002840F0A781A168C2 -:109F400081F87A0081F8860081F8630000F09EB9FC -:109F5000A0680023194690F86420583005F021FBD2 -:109F6000002800F04D816078002840F08F81A068C3 -:109F70000021A0F88810012180F88A10022180F8C1 -:109F8000641000F083B9A0680023194690F864209B -:109F9000583005F006FB00287ED0206905F0E0FF70 -:109FA00000287AD0206905F0D7FFA16808872069CA -:109FB00005F0CEFFA1684887206905F0CFFFA168B2 -:109FC0008887206905F0C6FFA168C88791F86300FB -:109FD0001D2813BF91F84E00012081F84E00012882 -:109FE00007D091F8FD00002804BF91F8FC0000287C -:109FF00003D01F2081F8640017E01E2081F8640060 -:10A000000A88A1F822210A8FA1F824214A8FA1F8F9 -:10A0100026218A8F01F58670A1F82821C98FC18376 -:10A0200001210175E078F1F765FEA0680021A0F834 -:10A030008810012180F88A1000F028B9A068002358 -:10A040000A2190F86320583005F0ABFA20B320695C -:10A0500005F086FFA8B1206905F07EFFA16808879A -:10A06000206905F075FFA1684887206905F076FF33 -:10A07000A1688887206905F06DFFA168C887FFF790 -:10A0800043FCA068002180F8861080F8631004214A -:10A09000FEF7C0F8A06801E01AE07CE090F84E10EE -:10A0A00001291AD00288A0F81621028EA0F81821E2 -:10A0B000828EA0F81A21428E00F58671A0F81C212C -:10A0C000C08E488201200872E078F1F713FEDDE0CF -:10A0D000607840F001006070D8E0022180F84E10F6 -:10A0E000D4E0A0680023194690F86420583005F0A9 -:10A0F00058FA80B3A06890F86300242812BF25287E -:10A10000607840F0200027D06846FBF7EDF9002882 -:10A1100008BF002105D0009805F053FE8DF8080017 -:10A1200002A9A06801AB162290F8630005F001FCBB -:10A13000A0B1A0689DF80420162180F8E42080F8E2 -:10A14000E5101A2180F86410012180F88A1000219E -:10A15000A0F888109AE053E0607097E0206905F05D -:10A1600022FFC0B1206905F018FFA16800F00700C8 -:10A1700081F84F00206905F014FF00F00701A06886 -:10A1800080F8501090F80721002A04BF90F80621AB -:10A19000002A04D024E00020FFF73DFC76E090F890 -:10A1A0004F3090F852C000F151029C4501BF127827 -:10A1B0008A42012180F87B1012D00288A0F82E215B -:10A1C00090F84F2000F5867180F8302190F850000B -:10A1D00081F82500012081F82000E078F1F78AFD60 -:10A1E000A068222180F86410012180F88A100021E3 -:10A1F000A0F888104AE0A06890F86300202801D0F9 -:10A200000120A9E7206905F0D8FEC0B3206905F058 -:10A21000C4FE00F0070060F30705206905F0C1FEE9 -:10A2200000F0070060F30F25A2680120002682F8E5 -:10A230008600A2F88260242082F86300D2F8080128 -:10A24000B2F851202946ADF8002005F020FB9DF81A -:10A250000020C1B28A4207BFA16881F8E860A26805 -:10A2600082F8E8109DF80110C0F30720814219BF61 -:10A27000A16881F8E900A06880F8E96006E0FFE7DE -:10A280000120FFF7C8FB1E20FFF707FBA068D0E9FD -:10A2900028134A1C43F10001C0E9282104B070BD15 -:10A2A0002DE9F047FE4D04464FF00007687808435B -:10A2B0006870287910F0200F2846806818BFA0F831 -:10A2C0007C7004D1B0F87C10491CA0F87C1090F888 -:10A2D0006910012639B990F863200023062158300F -:10A2E00005F05FF958B3A88810F4006F07D0A8688C -:10A2F00090F86910002918BFA0F874701FD1A868E1 -:10A30000B0F87410491C89B2A0F87410B0F8762027 -:10A310008A422CBF511A00218288521D8A4228BFCE -:10A3200080F87A60B0F87410B0F87620914206D3C5 -:10A33000A0F8747080F81261E878F1F7DBFC2879F6 -:10A3400010F0600F08D0A86890F8671021B980F865 -:10A3500067600121FDF75EFF4FF00808002C56D121 -:10A360006878002851D1287910F0040F0DD0A86822 -:10A3700090F86300032808BFFFDFA86890F8661014 -:10A38000072904BF2E7080F8667001F015F928794E -:10A3900010F0080F19D06878B8B9A868002190F8B3 -:10A3A000C300FFF7F4FAA86890F8C300FF2808BFBD -:10A3B000FFDFFF21A86880F8C31090F86610082915 -:10A3C00003D10221297080F86670FFF760FBA8783E -:10A3D00010F0080F16D0A8680023052190F863201C -:10A3E000583005F0DEF850B185F80180A868D0F843 -:10A3F0003C1108780C2808BF0020087002E00020FB -:10A4000003F04DFDA86801F010F800F06CFDA8689D -:10A41000A14600F1580490F8EC0030B9A27B00236B -:10A420000121204605F0BDF810B1208D401C20858B -:10A430003D21B9F1000F18D12878022808BF162055 -:10A440000ED0012804BFA86890F8EE0008D0687804 -:10A45000E8B110F0140F1CBF1E20E07602D005E01A -:10A46000E07603E010F0080F02D0E176A67641E036 -:10A4700010F0030F03D02A20E076A6763AE010F021 -:10A48000200F08BFFFDF2320E076A67632E094F8A5 -:10A490002E0028B1608D411C6185A18D884213D2A8 -:10A4A00094F8320028B1208E411C2186A18D88426B -:10A4B0000AD2218DE08C814203D3AA6892F8EC2065 -:10A4C00012B9A28D914203D32220E076A67611E044 -:10A4D000E17B31B1A18C814228BF84F81B80C5D2B9 -:10A4E00006E0A08C062803D33E20E076A67601E0A5 -:10A4F000A07EA0B1E7722773E7730221A868FDF779 -:10A5000089FEA86890F8C310012904D1D0F8F4009E -:10A510000178491E0170E878F1F7ECFB03E00021B7 -:10A52000A868FDF777FEBDE8F047FAF7ECBF5C4995 -:10A530004A788B781A430ED101280AD0087910F096 -:10A54000040F04D0886890F86600072803D0012023 -:10A550007047FDF74BBE0020704770B5504C064663 -:10A560000D46A0883043A08016F0020F04D016F0EC -:10A57000010F18BFFFDFE56016F0010F18BF25615E -:10A5800016F0020F12D0284605F01BFC062802D058 -:10A590000B282ED00AE0A06890F86310182905D186 -:10A5A0000021C0E92811012180F8691016F0800F00 -:10A5B0001CBF0820A07016F4806F08BF70BDA06893 -:10A5C000B0F8581080880844801D86B2284605F0EF -:10A5D000F8FB012804BFA068A0F8FA6015D028464F -:10A5E00005F0EFFB68B1284605F0EBFB182823D0F7 -:10A5F0000BE0A06890F86310122908BF0021D5D1A4 -:10A60000D2E7A068D0F8F0008680284605F0D9FB94 -:10A6100001281DD0284605F0D4FB08B3284605F0D4 -:10A62000D0FB182818BF70BDA068B0F8EA10284603 -:10A63000BDE8704005F0D3BCA06890F8E810002990 -:10A6400002BF90F8E91000290026A0F8EA60DCE7D4 -:10A65000A068B0F8FA102846BDE8704005F003BCC9 -:10A66000A068D0F8F00081882846BDE8704005F069 -:10A67000CABBF0B50A4C85B00026A060A680667003 -:10A68000A670054626700088FAF705FFA0680088C6 -:10A69000FAF727FFB5F8D000A168401C82B201E0AC -:10A6A0000401002001F1580004F085FD002818BFC6 -:10A6B000FFDF95F8640025280AD1B5F85810B5F8E1 -:10A6C000EA00081A00B20028A4BF6078002804D06D -:10A6D00095F8630025283BD119E0A06890F8E810B0 -:10A6E000002908BF90F8511080F8511090F8E91037 -:10A6F000002908BF90F8521080F852100020FFF790 -:10A70000CCF885F86460A16881F87B6020E0B5F83A -:10A710005810B5F8EA00081A00B20028A4BF607803 -:10A72000002815D1A06890F8E810002908BF90F81B -:10A73000511080F8511090F8E910002908BF90F8E6 -:10A74000521080F852100020FFF7A7F885F86360D8 -:10A75000A5F8D060A06890F8861039B1B0F88210E2 -:10A76000B0F88420914224BF05B0F0BD90F88A1063 -:10A7700039B1B0F88810B0F88420914224BF05B0F8 -:10A78000F0BDB0F88020B0F87E108A4224BF05B03A -:10A79000F0BD90F867208AB3B0F87C208A4224BFCD -:10A7A00005B0F0BD90F8C370FF2F00F02A81684615 -:10A7B000FAF774FE002808BFFFDF009805F03FFAA3 -:10A7C0000321009805F052FA0098017821F0100159 -:10A7D0000170394605F0C7FA192F80F0E780DFE8ED -:10A7E00007F02A22144EE5E5E61B7CE5E6E66CE57B -:10A7F000E5E5E5D8E6E6869FB8E5C500B0F87C104B -:10A80000062924BF05B0F0BDCCE7A06890F8ED1094 -:10A81000009805F02FFBCAE0A06890F8C4100098DB -:10A8200005F078FBC3E0A068D0F8F400411C009864 -:10A8300005F011FBBBE0A068D0F8F000817900982A -:10A8400005F0DDFAA068D0F8F0000189009805F065 -:10A85000CFFAA068D0F8F0004189009805F0B3FA6B -:10A86000A068D0F8F0008189009805F0B3FAA068DC -:10A87000D0F8F000C189009805F0B3FA97E0A0681D -:10A88000D0F8F000011D009805F0F8FAA068D0F8A3 -:10A89000F00000F10C01009805F0FAFAA068D0F879 -:10A8A000F00000F11E01009805F0F8FAA06800F130 -:10A8B000B801009805F000FB79E060690178009824 -:10A8C00005F012FB60698188009805F00FFB606954 -:10A8D0004188009805F00EFB69E0FE49D1E90001CE -:10A8E000CDE9020102A9009805F018FB5FE0A0681D -:10A8F000B0F84410009805F01BFBA068B0F84610B3 -:10A90000009805F019FBA068B0F84010009805F019 -:10A9100017FBA068B0F84210009805F015FB46E060 -:10A92000A068B0F84010009805F00AFBA068B0F8E5 -:10A930004210009805F008FBA068B0F84410009899 -:10A9400005F0F6FAA068B0F84610009805F0F4FAA1 -:10A950002DE0A06890F80811009805F01CFBA06895 -:10A9600090F80911009805F01AFB20E0A06890F813 -:10A97000E80004F087FF0146009805F028FBA06876 -:10A9800090F8E90004F07EFF0146009805F023FBF3 -:10A990000DE0A06890F8E510009805F040FBA06875 -:10A9A00090F8E410009805F03EFB00E0FFDFFAF7B6 -:10A9B00088FD002808BFFFDF009F384605F001FA38 -:10A9C000012809D0384605F0FCF960B1384605F099 -:10A9D000F8F918280FD014E0A068B0F8FA1038463B -:10A9E00005F041FA0DE0A068D0F8F0008188384603 -:10A9F00005F009FA05E0A068B0F8EA10384605F05D -:10AA0000EEFAB5480090B54BB54A2946304603F0FA -:10AA100081F9A0680023052190F86320583004F0E4 -:10AA2000C0FD002804BF05B0F0BD05B0BDE8F04092 -:10AA300002F041BFAB48806890F8861029B1B0F8A9 -:10AA40008210B0F8842091421AD290F88A1029B16D -:10AA5000B0F88810B0F88420914211D2B0F880206C -:10AA6000B0F87E108A420BD290F86720B0F87C00D4 -:10AA700022B1884204D200BF03F0ECB90628FBD310 -:10AA8000002001460CE470B50C46064615464FF40E -:10AA9000A071204607F0C9F82680002D08BFFFDF0F -:10AAA0002868C4F8F0006868C4F8F400A868C4F81E -:10AAB0003C0170BDF6F7B3B82DE9F0410D460746ED -:10AAC0000621F5F7CBFF040008BFBDE8F081D4F8FC -:10AAD0003C110026087858B14A8821888A4207D15B -:10AAE000082810D00D281FD00C2835D0072850D0AA -:10AAF00094F8120100285ED06E700F20287084F840 -:10AB000012616F8042E06E7008202870D4F83C011A -:10AB10004168C5F802108168C5F80610808968810F -:10AB2000D4F83C01067031E00846F6F7A1F8074674 -:10AB3000F5F716FDB8B96E700D202870D4F83C01F9 -:10AB40004068C5F80200D4F83C0106703846F5F7B5 -:10AB500001FD0120BDE8F0810846F6F789F80746B7 -:10AB6000F5F7FEFC10B10020BDE8F0816E700C20FE -:10AB70002870D4F83C014168C5F802100089E880CB -:10AB8000D4F83C0106703846F5F7E4FC0120BDE836 -:10AB9000F0816E7007202870D4F83C01416882680B -:10ABA000C068C5F80210C5F80620C5F80A00D4F838 -:10ABB0003C010670EAE794F81401C8B16E701420E5 -:10ABC000287094F814010028E0D000BF84F81461C4 -:10ABD000D4F81601C5F80200D4F81A01C5F8060029 -:10ABE000B4F81E01688194F814010028EED1CDE775 -:10ABF00094F8200180B16E701A20287084F82061CA -:10AC0000D4F82201C5F80200D4F82601C5F80600E0 -:10AC1000B4F82A016881B9E794F82C0148B16E7044 -:10AC20001B20287084F82C61D4F82E01C5F802008E -:10AC3000ACE794F80C0190B16E701820287094F86D -:10AC40000C010028A2D000BF84F80C61D4F80E01DA -:10AC5000C5F8020094F80C010028F5D196E794F8A5 -:10AC60003201002808BFBDE8F0816E701520287001 -:10AC700094F83201002889D084F83261D4F8340184 -:10AC8000C5F80200B4F83801E88094F832010028D1 -:10AC9000F2D17BE7134A5061D17070472DE9F0473C -:10ACA0000446481E85B238BFBDE8F08704F10808A5 -:10ACB0000126DFF830904FF0080A0027B4F8D000E2 -:10ACC000401CA4F8D000B4F87C00401CA4F87C0020 -:10ACD0000AE000005C230200A1A201002FA50100F0 -:10ACE0005BA501000401002094F8690040B994F8C4 -:10ACF00063200023062104F1580004F052FCD8B16F -:10AD0000B4F87400401C80B2A4F87400B4F8761053 -:10AD100081422CBF0A1A0022A3885B1D934228BFE0 -:10AD200084F87A60884207D3A4F8747084F81261BA -:10AD300099F80300F0F7DEFF94F8860020B1B4F82C -:10AD40008200401CA4F8820094F88A0020B1B4F874 -:10AD50008800401CA4F8880094F8EC0040B994F8EE -:10AD600066200023012104F1580004F01AFC20B1F0 -:10AD7000B4F88000401CA4F8800094F863000C280C -:10AD800002D00D2820D067E0B4F85800411CB4F878 -:10AD9000FA00814260D1D4F8F400411C404607F02B -:10ADA00050F80221204604F034F9D4F8F400007879 -:10ADB000002808BFFFDF0121FF20FEF7E8FD84F82F -:10ADC000637084F8966047E0B4F85800411CD4F8EA -:10ADD000F000808881423FD1D4F83C0101780029FD -:10ADE00018BFFFDF22D12188C180D4F8F00041894B -:10ADF000D4F83C010181D4F8F0008189D4F83C01F9 -:10AE00004181D4F8F000C189D4F83C018181D4F8A3 -:10AE10003C010771D4F83C0180F800A0D4F83C0153 -:10AE20002188418099F80300F0F764FF0121204652 -:10AE300004F0EFF803212046FDF7ECF9D9F80800FB -:10AE4000D0F8F0000078022818BFFFDF0221FF20B1 -:10AE5000FEF79DFD84F86370B4F85800401C691E2D -:10AE6000A4F858008DB2BFF429AFBDE8F087FE4AC0 -:10AE7000C2E90601704770B50446B0F87C0094F84A -:10AE80006710002908BFC0F1020503D0B4F87E1096 -:10AE9000081A051F94F87A0040B194F86320002343 -:10AEA000092104F1580004F07CFBA0B1B4F87460EF -:10AEB00094F8690058B994F863200023062104F13E -:10AEC000580004F06EFB002808BF284603D0B4F8F1 -:10AED0007600801B001F8542C8BF0546002DD4BFE9 -:10AEE0000020A8B270BDF0B5DF4C83B0A06890F828 -:10AEF000C310FF2907BF6178002903B0F0BD90F8A7 -:10AF0000662000230121583004F04BFB00281CBFB1 -:10AF100003B0F0BDA06890F8EC1029B103B0022096 -:10AF2000BDE8F040FEF79ABC90F863200023194674 -:10AF3000583004F036FB48B1A06890F87A0028B188 -:10AF400003B01220BDE8F040FEF788BCA0680025E1 -:10AF500090F86320122A23D004DC032A47D0112A58 -:10AF600024D003E0182A3CD0242A4CD0002304210A -:10AF7000583004F016FB00281CBF03B0F0BDD4F815 -:10AF800008C0022701269CF864001A2800F01E81E0 -:10AF900041DC012873D002287FD0032863D03EE033 -:10AFA00003B00B20BDE8F040FEF758BCF8F7D5FD24 -:10AFB0000C283CBF03B0F0BDA0680821D0F8F00019 -:10AFC0001E30F8F7CBFD28B1A0680421B830F8F79F -:10AFD000C5FD00B9FFDF03B00320BDE8F040FEF778 -:10AFE0003DBC03B00620BDE8F040FEF737BC90F84A -:10AFF000C21080F8C4100720FEF730FCA06880F86B -:10B00000635003B0F0BD1820FEF728FCA068A0F83C -:10B01000825003B0F0BD1F2847D022287ED0DCF834 -:10B02000F0000178002900F010814088BCF8001081 -:10B03000884274D100239CF8632019460CF1580013 -:10B0400004F0AFFA00286AD0A068D0F8F0100978B0 -:10B05000022972D0032971D0042970D0052908BFB4 -:10B0600008206DD0F1E09CF8C1008CF8C4000720E6 -:10B07000FEF7F4FBA06800F0B0B900E00DE00C2092 -:10B08000FEF7ECFBA068A0F8885090F88E1041F015 -:10B09000010180F88E1000F0A0B91320FEF7DEFB4E -:10B0A000A068A0F8885000F098B99CF8FD0000282E -:10B0B0001CBF03B0F0BD9CF8FC0088B1BCF8FE00DA -:10B0C000ACF84000BCF80001ACF84200BCF802014A -:10B0D000ACF84400BCF80401ACF846008CF8FC5015 -:10B0E000FEF712FC0421A068FDF794F8A06890F820 -:10B0F0004E10012908BF80F84E7016D00288A0F8C3 -:10B100001621028EA0F81821828EA0F81A21428EF4 -:10B1100000F58671A0F81C21C08E01E011E094E0DA -:10B1200048820E72E078F0F7E5FD1520FEF796FBF9 -:10B13000A068A0F8885000F050B94CE051E071E0F0 -:10B1400058E09CF87B0058B18CF8E8508CF8E95036 -:10B150001820FEF783FBA068A0F8885003B0F0BD6C -:10B160009CF8070100281CBF03B0F0BD9CF8060145 -:10B17000002804BF03B0F0BDBCF84F10DCF8080194 -:10B18000ADF80410BCF85110ADF80010019904F0AE -:10B190007EFB9DF80020C1B28A4207BFA16881F8FA -:10B1A000E850A26882F8E8109DF80110C0F307206B -:10B1B000814219BFA16881F8E900A06880F8E950D0 -:10B1C000182003B0BDE8F040FEF748BB1120FEF7A1 -:10B1D00045FBA06801E190F8640004F0D5F9A0BB3C -:10B1E00008E090F8681041B190F86900002808BFA5 -:10B1F000FFDF0A20FEF732FB27E0F8F7AEFC0C2851 -:10B2000023D3A0680821D0F8F0001E30F8F7A6FC80 -:10B2100028B1A0680421B830F8F7A0FC00B9FFDF1E -:10B220000320E7E790F88E0010F0030F0DD10C20FB -:10B23000FEF714FBA068A0F8825080F8866090F8B2 -:10B240008E1041F0010180F88E10A06890F8C310B4 -:10B25000FF291CBF03B0F0BD90F8632000231946FE -:10B26000583004F09EF901E004010020002804BFDA -:10B2700003B0F0BDA06890F8F810E9B3A1690978AF -:10B28000D1BB90F8640004F07FF9A8BBA068B0F8C7 -:10B2900058100A2935D900F108010522E06906F0A5 -:10B2A000FFFB0028A06802BF80F8F85003B0F0BD93 -:10B2B000D0F8F400017869B1411C0522E06906F07C -:10B2C000EFFB00281CBF03B0F0BDA068D0F8F4006D -:10B2D000007830B9A068E169D0F8F400401C06F0AD -:10B2E000B0FDA068D0F8F4000178491C017001207D -:10B2F000FEF7B4FAA06800E003E080F8F85003B06D -:10B30000F0BDA06890F8FC1011B190F8FD1011B3D9 -:10B3100090F80611002904BF03B0F0BD90F80711A2 -:10B3200000291CBF03B0F0BD90F8640004F02CF9B4 -:10B3300000281CBF03B0F0BDA06890F8512090F821 -:10B340000811012A4DD0022A4ED0042A14BF082A1F -:10B3500004294BD05DE0B0F8FE10A0F84010B0F822 -:10B360000011A0F84210B0F80211A0F84410B0F893 -:10B370000411A0F8461080F8FC5090F864001E28D4 -:10B3800005D003B01420BDE8F040FEF767BAFEF721 -:10B39000BBFA0421A068FCF73DFFA06890F84E10AE -:10B3A000012908BF80F84E7013D00288A0F816213A -:10B3B000028EA0F81821828EA0F81A21428E00F584 -:10B3C0008671A0F81C21C08E48820E72E078F0F7DA -:10B3D00091FC1520FEF742FAA06880F8645003B093 -:10B3E000F0BD012915D101E0022912D190F85210C7 -:10B3F00090F80901012907D0022908D0042914BFB7 -:10B40000082904280BD004E0012802D107E0022813 -:10B4100005D003B01620BDE8F040FEF71FBA03B018 -:10B420000020BDE8F040FEF738BA70B5044690F849 -:10B43000630000250C2814D00D2818BF70BDB4F887 -:10B440005800D4F8F010401C8988884218BF70BD9D -:10B45000D4F83C01FE4E0178002918BFFFDF45D12A -:10B4600022E0B4F85800B4F8FA10401C884218BF23 -:10B4700070BDD4F8F400411C04F1080006F0E1FCB2 -:10B480000221204603F0C5FDD4F8F400007800281E -:10B4900008BFFFDF0121FF20FEF779FA84F863502F -:10B4A000012084F8960070BD2188C180D4F8F00096 -:10B4B000D4F83C1140890881D4F8F000D4F83C114C -:10B4C00080894881D4F8F000D4F83C11C089888183 -:10B4D000D4F83C010571D4F83C1108200870D4F868 -:10B4E0003C1120884880F078F0F704FC01212046C8 -:10B4F00003F08FFD03212046FCF78CFEB068D0F8E6 -:10B50000F0000078022818BFFFDF0221FF20FEF7BD -:10B510003EFA84F8635070BD70B5CD4CA16891F8C7 -:10B520006320162A11BF132A91F88C20002A627812 -:10B530001BBF02206070002A70BD81F8C00000258A -:10B5400081F88B5081F88650D1F8F0000988408846 -:10B55000884218BFFFDFA068D0F8F0000078032809 -:10B5600018BFFFDF0321FF20FEF711FAA068D0F813 -:10B570003C110A78002A18BFFFDF19D10288CA805F -:10B58000D0F83C2190F8C0101171D0F83C110D7228 -:10B59000D0F83C210C211170D0F83C210188518059 -:10B5A0000088F5F765FBF4F7C5FFE078F0F7A2FB3C -:10B5B000A06880F8635070BD10B5A54C207910F0DC -:10B5C000020F08BF10BD6078002818BF10BDE068EA -:10B5D000C078192880F06981DFE800F05F4F0D8F97 -:10B5E000F8F8A6223FF86F83B1F8F8F8F8F7E3E02F -:10B5F000F9F5F4F8F300A0680023012190F8662023 -:10B60000583003F0CEFF002818BF10BD0821A068F5 -:10B6100080F86610002180F8861080F88A1010BD2E -:10B62000A0680023194690F86420583003F0B9FF51 -:10B6300018B1A168002081F88A00A068002319468B -:10B6400090F86320583003F0ACFF002808BF10BD0D -:10B650000020A16881F8860010BDA068002319466B -:10B6600090F86320583003F09CFF002808BFFFDFEC -:10B670000420A16881F8630010BDA068002319466A -:10B6800090F86320583003F08CFF002808BFFFDFDC -:10B690000C20A16881F8630010BDA0680023194642 -:10B6A00090F86320583003F07CFF002808BFFFDFCC -:10B6B0000D20A16881F8630010BDA0680023194621 -:10B6C00090F86320583003F06CFF002808BFFFDFBC -:10B6D0000121A06880F88B105FF00F0180F86310E3 -:10B6E00010BDA06890F86300122818BFFFDF012189 -:10B6F000A06880F88C101121F0E7A068002319469B -:10B7000090F86320583003F04CFF28B9A06890F8F7 -:10B710008C00002808BFFFDF0121A06880F88B1093 -:10B72000132180F8631010BDA06890F863001828FA -:10B7300018BFFFDF1B20A16881F8630010BDA0685F -:10B74000D0F8F01003884A889A4204BF0978042987 -:10B7500019D190F8632000231946583003F021FFD7 -:10B76000002808BFFFDFA06890F88E1011F0020FCC -:10B7700004BF012180F8631005D0002180F88610F5 -:10B78000D0F8F0000170A0680023194690F86420FA -:10B79000583003F006FF002808BF10BD0020A16844 -:10B7A00080E0A0680023194690F86320583003F029 -:10B7B000F8FE002808BFFFDF0520A16881F86300BC -:10B7C00010BD30E01FE012E001E067E06DE0A0682E -:10B7D0000023194690F86320583003F0E2FE002859 -:10B7E00008BFFFDF1D20A16881F86300E8E7A068BB -:10B7F0000023194690F86420583003F0D2FE002848 -:10B8000008BFFFDFCAE7A0680023194690F863204D -:10B81000583003F0C6FE002808BFFFDF2020A168D3 -:10B8200081F86300CCE7A06890F8641022291DD04D -:10B8300090F86310242918BFFFDFC1D190F8E810F9 -:10B84000002906BF90F8E9100029252102E0000038 -:10B850000401002018BF80F863107FF4F9AE0021C6 -:10B8600080F863100846FEF718F8F1E690F8E81043 -:10B87000002907BF90F8E9100029252180F86410FD -:10B880008CD1002180F8641080F87B1090F80601BC -:10B8900000281CBF0020FEF700F87FE7A168002009 -:10B8A00081F8640081F88A008AE7FFDF88E70000FA -:10B8B00070B5FC4CE1680A88A1F8E62181F8E40142 -:10B8C00091F85100012808BF012508D0022808BFBF -:10B8D000022504D0042816BF08280325FFDFE068EE -:10B8E00080F8E85190F85200012808BF012508D0DF -:10B8F000022808BF022504D0042816BF0828032503 -:10B90000FFDFE068012180F8E95180F8E2110021B1 -:10B9100080F89211E078BDE87040F0F7EBB9F0B430 -:10B92000E048C06890F84E30478EC68E458FB0F81C -:10B930004010C28FB0F842C0022B1FD08D4238BFDA -:10B9400029460186624528BF62468286018FB0F88B -:10B950004430994238BF0B464386818FB0F8464049 -:10B96000A14238BF0C46C486BB4228BF1F4647864B -:10B97000B44228BF2646C686F0BC7047038E9D425F -:10B9800028BF1D46838E9A4228BF1A46A94298BFF7 -:10B990000D460586944598BF62468286002180F850 -:10B9A0004E10D3E72DE9F04FBE4C83B0207910F054 -:10B9B000010F04BF03B0BDE8F08F606901230521CA -:10B9C000C578E06890F86420583003F0EAFD00285C -:10B9D00018BF022D0BD00A2D18BF0B2D07D0032D39 -:10B9E00018BF062D03D0607840F0080060706078C2 -:10B9F00000281CBF03B0BDE8F08F60690227012654 -:10BA000090F8038000254FF02009B8F1000F1CBF0B -:10BA1000B8F1010FB8F1160F1FD1E06890F863007C -:10BA200003F0B2FDC8B1E16891F86300202814D09A -:10BA3000212808D0B8F1160F0CBF84F80190677068 -:10BA400003B0BDE8F08F262081F86300B8F1160F2F -:10BA500000F0AE822A20FFF72BFFB8F1190F80F01B -:10BA6000E282DFE808F046230DC1FEFEFDFCFBFE8E -:10BA700091B8FAFEFEFEFEF9F8F7F6F5F4FEF300D3 -:10BA8000E0680123194690F86620583003F089FDDC -:10BA9000002840F04D84606904F0EEF9E16881F817 -:10BAA0006801072081F8660000F042BCE0680123CD -:10BAB000002190F86420583003F073FD002800F056 -:10BAC000F083606904F0D3F9E168A1F87C01B1F872 -:10BAD0005820801A00B247F6FE728242A8BF0028A2 -:10BAE0004BDD01F5BF71606904F0B8F90B20E16826 -:10BAF0003FE0E0680123002190F86420583003F013 -:10BB000050FD002800F0CD83606904F083F900281F -:10BB100000F08982606904F07AF9E168A1F87C019B -:10BB2000B1F85820801A00B247F6FE728242A8BFD0 -:10BB3000002822DD606904F064F9E16881F87E0183 -:10BB4000606904F059F9E168A1F88001606904F0C6 -:10BB50003EF9E168A1F88201606904F03FF9E1680B -:10BB6000A1F88401606904F040F9E168A1F8860158 -:10BB70000D2081F8640000F0DBBB282081F8730001 -:10BB800081F8726000F0D4BBE0680123002190F8D6 -:10BB90006420583003F005FD0028E0680CD0A0F8C0 -:10BBA000885090F88A10491C80F88A105FF01001C4 -:10BBB00080F8641000F0BCBB90F8642001230521DC -:10BBC000583003F0EEFC00281CBF0820607040F0E5 -:10BBD000AF8300F066BBE06890F86410112908BFDD -:10BBE000122140F09282E3E7E0680123002190F8FF -:10BBF0006420583003F0D5FC80B9E06890F86420E8 -:10BC0000122A0BD001230521583003F0CAFC00286A -:10BC100018BF082000F0458300F0C7B9E06890F82D -:10BC20008C1031B9A0F8885090F88A10491C80F81F -:10BC30008A1000F1E001606904F037F9E06800F172 -:10BC4000B801606904F03CF9E0680BE01BE2AFE189 -:10BC500059E1F1E0CFE0DBE0EAE23AE0A2E0FFE226 -:10BC600022E072E190F8AA01002818BFFFDFE06827 -:10BC70000188A0F8AC1100F5D771606904F003F9F0 -:10BC8000E06800F5DB71606904F005F9E06880F8B0 -:10BC9000AA61142180F86410E078F0F72BF800F026 -:10BCA00047BB000024010020E06890F864101729C9 -:10BCB00040F02B8290F88A10491E49B280F88A1011 -:10BCC0000029B8BFFFDF1C20E16881F8640000F0A4 -:10BCD0002FBBE06890F8651011F0020F09D090F8C2 -:10BCE000632001230821583003F05BFC002800F09A -:10BCF000D882E06890F88E0010F0020F17D16069CA -:10BD000004F0FCF8E16881F88F00606904F0F8F84D -:10BD1000E168A1F89000606904F0F5F8E168A1F825 -:10BD2000920091F88E0040F0020081F88E00E068E9 -:10BD300090F88E1011F0010F05D0E06890F86310B4 -:10BD400006291CD114E090F8650010F0020F18BF0E -:10BD5000FFDFE06890F8651041F0020180F865109F -:10BD6000A0F8885090F88A10491C80F88A10E4E7FF -:10BD700080F8635080F88650E078EFF7BBFFE0680A -:10BD800090F87A11042940F0D38280F87A51E07853 -:10BD9000EFF7B0FFE06890F86310002940F0C88228 -:10BDA00000F043BAE06890F8650010F0010F7BD115 -:10BDB0006946606904F0B7F8E0689DF8002090F8E3 -:10BDC0009410114001F02F0180F8941090F8951014 -:10BDD0009DF80120114001F0410180F89510A0F874 -:10BDE000885090F88A10491C80F88A1090F86510E5 -:10BDF00041F001011CE0E0680123092190F8632073 -:10BE0000583003F0CEFB002800F04B8200F041BA1E -:10BE1000E06890F8651011F0040F40F04282A0F83D -:10BE2000885090F88A2041F00401521C80F88A2042 -:10BE300080F8651000F07CBAE06890F8650010F0BA -:10BE4000300F31D1606904F08BF800287DD0606933 -:10BE500004F082F8E1680887606904F079F8E16825 -:10BE60004887606904F07AF8E1688887606904F0BF -:10BE700071F8E168C887207910F0020F03D02069BB -:10BE8000C078142811D091F863001D280DD091F8C6 -:10BE90004E0001280BD091F88901002804BF91F8C9 -:10BEA000880100280AD002E074E081F84E6091F821 -:10BEB000650040F0100081F865001AE091F8650017 -:10BEC00040F0200081F865000A88A1F8CA210A8F95 -:10BED000A1F8CC214A8FA1F8CE218A8F01F5CB7031 -:10BEE000A1F8D021C98F818780F83260E078EFF720 -:10BEF00001FFE068A0F8885090F88A10491C80F88B -:10BF00008A1000F015BAE06801230A2190F8632036 -:10BF1000583003F046FBE8B3606904F021F8B8B18B -:10BF2000606904F019F8E1680887606904F010F8A6 -:10BF3000E1684887606904F011F8E1688887606902 -:10BF400004F008F8E168C88700E06CE0FFF7E7FC60 -:10BF5000E068052180F8865080F86350FDF7FBFA11 -:10BF6000E06890F84E10012908BF80F84E7000F08C -:10BF7000DF810288A0F8BE21028EA0F8C021828E47 -:10BF8000A0F8C221428E00F5CB71A0F8C421C08E6A -:10BF9000088600E006E081F82660E078EFF7AAFE68 -:10BFA00000F0C6B9607840F00100607000F0C0B9E0 -:10BFB000E06801230B2190F86420583003F0F1FA77 -:10BFC00020B100BF84F8019000F0B2B9E06801230D -:10BFD000002190F86420583003F0E3FA002800F0C4 -:10BFE0006081E06890F863002528EBD0606903F079 -:10BFF000DAFFC0B1606903F0D4FFE16800F0070028 -:10C0000081F85000606903F0C8FF00F00701E068A4 -:10C0100080F84F1090F89321002A04BF90F89221E5 -:10C02000002A04D022E001F0DEF900F081B990F896 -:10C0300052C090F8503000F151028C4502BF117887 -:10C04000994280F87B6011D000F5CB7180F8DC61FB -:10C050000288A0F8DE2190F84F2080F8E02190F8C7 -:10C06000500081F84B00E078EFF744FEE0682221B1 -:10C0700080F86410A0F8885090F88A10491C80F865 -:10C080008A1000F055B9E06890F8631021290CBFC0 -:10C090004FF001084FF0000890F86410232908BF02 -:10C0A00000F1640705D0B8F1000F18BF00F1630775 -:10C0B0002BD0606903F099FFF0B3D4F81490484690 -:10C0C00003F087FF0090484603F087FF8146E06851 -:10C0D00090F89211002907BF4FF0000BDA4690F854 -:10C0E00094B190F895A1484603F05AFBB0B1E268CC -:10C0F00092F85110814211D019EA0B0F41D0B8F1DA -:10C10000000F08BF012802D008E0677010E1022983 -:10C1100004BF92F8500010EA090F32D0009803F0E3 -:10C120003FFB68B1009803F03BFBE16891F85210C7 -:10C13000884205D0009800E023E010EA0A0F20D0E2 -:10C140006A466169E06803F03AFBD8B3606903F0BE -:10C150004AFFE168A1F87C01B1F85820801A00B2CA -:10C1600047F6FE728242A8BF00284ADD9DF8000013 -:10C1700081F87E019DF8010081F87F01252038704B -:10C1800044E0E06890F8920100281CBF1E20FFF7F1 -:10C190008FFBB8F1000F16D0606903F012FEE16862 -:10C1A00081F8C20006FA00F010F0807F08BFFFDFC0 -:10C1B0000A21E06880F8631090F88600002808BF24 -:10C1C000FFDF0DE010E03D70E16891F88A00401E4D -:10C1D00040B281F88A000028B8BFFFDF01F003F900 -:10C1E000E06880F87B50A3E0E06890F892010028B6 -:10C1F0001CBF0020FFF75CFB3D70E06880F87B50BF -:10C2000004E0282081F8730081F87260E06800F192 -:10C2100064018F4209D190F88A10491E49B280F812 -:10C220008A100029B8BFFFDF82E080F886507FE0E7 -:10C23000606903F0F6FE16287AD1E06890F8630092 -:10C24000212802D0262805D072E0606903F0EDFEB7 -:10C25000FFF72EFBE06880F8635080F8865067E0B7 -:10C26000E06890F863000E2804D1606903F054FE82 -:10C27000122805D0E06890F863001D2818D112E05C -:10C28000E0680123092190F86320583003F089F910 -:10C2900038B1E06880F87A5080F8865080F86350B2 -:10C2A00046E0667044E0606903F036FE142805D06D -:10C2B000E06890F8630021282BD125E0E068052193 -:10C2C00080F8635080F88650FDF745F9E16891F8F1 -:10C2D0004E00012808BF81F84E7029D00A88A1F8C5 -:10C2E000BE210A8EA1F8C0218A8EA1F8C2214A8EF1 -:10C2F00001F5CB70A1F8C421C98E018680F82660B3 -:10C30000E078EFF7F7FC13E0606903F005FE16280C -:10C3100005D0606903F000FE172809D113E0E0683A -:10C3200080F8635080F886505FF01A00FFF7C0FA7B -:10C33000E068D0E928134A1C43F10001C0E9282134 -:10C3400003B0BDE8F08FE06890F864102329EFD1C6 -:10C3500080F8645090F88A10491E49B280F88A101B -:10C360000029B8BFFFDFE06880F87B5090F89201A9 -:10C37000002818BF0020DBD0D8E770B5F84E05467E -:10C380000C46F06890F8C300FF2818BFFFDFF26882 -:10C390000020002C82F8C3501CBFA2F8880070BD9A -:10C3A000A2F88200012082F8860070BD10B584B02A -:10C3B00004466846F9F772F8002808BFFFDF0098C6 -:10C3C00003F03DFC0321009803F050FC0098017835 -:10C3D00021F010010170214603F0C5FCA01E1628B3 -:10C3E00073D2DFE800F00BAA4EABAB13AA5CAAAB8A -:10C3F0001B2CAAAAAAAAABAB31734B8DD848C06834 -:10C4000090F8C410009803F035FD97E0D448C06858 -:10C4100090F8C410009803F07DFD8FE0D04CA06828 -:10C420000178009803F060FDA0688188009803F00F -:10C430005DFDA0684188009803F05CFD7EE0062168 -:10C44000009803F063FD79E0C54CE068B0F8441053 -:10C45000009803F06DFDE068B0F84610009803F016 -:10C460006BFDE068B0F84010009803F069FDE068EB -:10C47000B0F84210009803F067FD5FE0B84CE06848 -:10C4800043E0B74CE06800F1E801009803F01CFDC0 -:10C49000E06800F1BC01009803F020FD4EE00020B0 -:10C4A00002900390AE48C06890F8941001F0F50136 -:10C4B0008DF8081090F8950002A900F041008DF861 -:10C4C0000900009803F05DFD38E036E0A44CE06818 -:10C4D000B0F84010009803F033FDE068B0F8421067 -:10C4E000009803F031FDE068B0F84410009803F0C4 -:10C4F0001FFDE068B0F84610009803F01DFD1DE038 -:10C50000974CE06890F8921159B190F89411009806 -:10C5100003F041FDE06890F89511009803F03FFDAD -:10C520000CE090F85110009803F035FDE06890F8A9 -:10C530005210009803F033FD00E0FFDFF8F7C1FF71 -:10C54000002808BFFFDF04B010BD70B50C460546DB -:10C550004FF4F871204605F068FB258070BDF4F7B4 -:10C560005EBB2DE9F0410D4607460721F4F776FA48 -:10C57000040008BFBDE8F08194F896010026C8B118 -:10C580006E700820287094F8960188B1268484F88B -:10C590009661D4F89801C5F80200D4F89C01C5F85A -:10C5A0000600B4F8A001688194F896010028EDD146 -:10C5B000AE7044E094F8A201002837D094F8A201AC -:10C5C0000C2818D00D2818BFFFDF38D12088F4F7C9 -:10C5D0004FFB0746F3F7C4FFA0B96E700D2028701B -:10C5E00094F8A401A8702088A88084F8A261384635 -:10C5F000F3F7B0FF23E02088F4F73AFB0746F3F7A0 -:10C60000AFFF10B10020BDE8F0816E700C202870E3 -:10C6100094F8A401A8702088A88094F8A801A871B3 -:10C6200084F8A2613846F3F795FF08E094F8DA0140 -:10C6300040B16E700F20287084F8DA616F8001209D -:10C64000BDE8F08194F8AA0180B16E7009202870CD -:10C6500020886880D4F8AE01D4F8B2116860A9606F -:10C66000B4F8B601A88184F8AA61E8E794F8B801A3 -:10C6700040B16E7017202870B4F8BA01688084F851 -:10C68000B861DCE794F8D40188B16E701820287086 -:10C6900094F8D4010028D2D084F8D461D4F8D6011B -:10C6A000C5F8020094F8D4010028F5D1C7E794F842 -:10C6B000BC01C8B16E701420287094F8BC01002829 -:10C6C000BDD000BF84F8BC61D4F8BE01C5F802003B -:10C6D000D4F8C201C5F80600B4F8C601688194F820 -:10C6E000BC010028EED1AAE794F8C80180B16E70B1 -:10C6F0001A20287084F8C861D4F8CA01C5F802006D -:10C70000D4F8CE01C5F80600B4F8D201688196E7E6 -:10C7100094F8DC0140B11B20287084F8DC61D4F867 -:10C72000DE01C5F802008AE794F8E201002808BF9C -:10C73000BDE8F0816E701520287094F8E2010028A1 -:10C740003FF47DAF84F8E261D4F8E401C5F802005B -:10C75000B4F8E801E88094F8E2010028F2D16EE72D -:10C7600024010020FA4A9060D1707047002180F8BF -:10C77000631080F8641080F8671090F8D61011B13B -:10C780000221FCF7E8BE0321FCF7E5BE2DE9F047E6 -:10C79000EF4C81460D46E0680088F4F77BFA06000E -:10C7A00008BFFFDF60782843607020794FF00005F4 -:10C7B00010F0200FE0681CBFA0F87C5080F8DC501F -:10C7C00004D1B0F87C10491CA0F87C10E068012767 -:10C7D00090F8691039B990F8642001230621583087 -:10C7E00002F0DFFE48B3A08810F4006F07D0E068C5 -:10C7F00090F86910002918BFA0F874501DD1E068A6 -:10C80000B0F87410491C89B2A0F87410B0F87630F2 -:10C810008B422CBF5A1A0022B4F806C00CF1050C4A -:10C82000624598BF80F87A70994206D3A0F8745098 -:10C8300080F8DA71E078EFF75DFA20794FF0020ABC -:10C8400010F0600F11D0E06890F8671011B1032963 -:10C8500006D00AE080F867700121FCF77CFE04E056 -:10C8600080F867A00121FCF776FEE06890F8671079 -:10C87000012905D1A18811F4807F18BF80F867A035 -:10C880004FF00808B9F1000F40F03281A18811F48F -:10C89000007F18BFA0F8F05004D1B0F8F020521C6F -:10C8A000A0F8F02011F0080F47D06178002944D19A -:10C8B00090F8C300FF2808BFFFDFFF21E06880F881 -:10C8C000C31090F86410192905D0E06890F863103F -:10C8D00020290FD028E080F88B5090F88A10491E4C -:10C8E00049B280F88A100029B8BFFFDFE06880F8FD -:10C8F0006450EAE790F8640002F046FE80B1E06818 -:10C900002621012380F8631090F864200B21583011 -:10C9100002F047FE002804BF2A20FEF7C9FF03E00B -:10C92000E168212081F86300E06890F8661008292A -:10C9300004BF84F800A080F86650FFF733F8207930 -:10C9400010F0040F09D0607838B9E06890F86610EC -:10C95000072904BF277080F8665000F0C5FB2079D6 -:10C9600010F0100F09D0607838B9E06890F86410C2 -:10C970000B2904BF0C2180F86410A07810F0080F78 -:10C9800011D0E0680123052190F86420583002F0AE -:10C9900008FE28B184F80180E06880F8A25102E026 -:10C9A000002001F07CFA00F03CFD01F06EFA002856 -:10C9B000E06818BFA0F8D05004D1B0F8D010491CDE -:10C9C000A0F8D01001F064FA40B1E16891F8DC0001 -:10C9D00002289CBF401C81F8DC0004D8E06890F875 -:10C9E000DC00022806D9E068A0F8D050A0F8D250A8 -:10C9F00080F8DC50E0680123002190F86420583072 -:10CA000002F0CFFD20B9E06890F864000C2859D1FD -:10CA1000E0680123002190F86320583002F0C1FD46 -:10CA200000284FD0E0680123002190F8662058309C -:10CA300002F0B7FDF0B3E06890F86710022904BF78 -:10CA400090F8DC0000283DD13046F3F70FFB88B3A7 -:10CA5000E06890F8C310FF2934D1B0F8CA1001295A -:10CA600030D980F8D570B0F87E10B0F87C208B1EDD -:10CA70009A42AFBF0121891A491E89B2B0F8D0305D -:10CA8000E28893422FBF0122D21A521C92B29142E5 -:10CA900088BF1146012908BF80F8D55090F8612160 -:10CAA000A2B1B0F8D220B0F8620182422CBF0120BE -:10CAB000801A00E006E03CBF401C80B2814288BF83 -:10CAC000014603E0E068012180F8D550E068B0F845 -:10CAD0005820114489B2A0F8CC1090F86730002B90 -:10CAE00018BF012B5FD0022B1CBF032BFFDF09D027 -:10CAF000A088C0F340200028E06818BFA0F8DE50EE -:10CB00005BD153E090F86630082B23D0B0F87C104E -:10CB1000B0F87E2000268B1C9A4206D3511A891E3B -:10CB20000E04360C1CBF711E8EB290F87A1051B1F3 -:10CB300090F8632001230921583002F032FD0028CB -:10CB400008BF00262BD0E06890F8691099B90AE078 -:10CB500024010020B0F87C30032B24D3B0F87E10E1 -:10CB60001144491C1FE090F864200123062158302D -:10CB700002F017FD78B1E1680020B1F87620B1F835 -:10CB800074108B1C9A4203D3501A801E18BF401E8B -:10CB9000B04238BF86B2002E1CBF701E86B2E0685D -:10CBA000B0F8CC103144A0F8C810A1E7B0F8DE10FE -:10CBB000B0F8CE201144A0F8DE10E06890F86611BD -:10CBC00039B990F8662001231946583002F0E9FC83 -:10CBD00038B1E068B0F88010B0F8CE201144A0F869 -:10CBE0008010E06890F8863033B1B0F88210B0F869 -:10CBF000CE201144A0F8821090F98AC0BCF1000F39 -:10CC000006DDB0F88810B0F8CE201144A0F88810E6 -:10CC10003D22B9F1000F18BF80F873204DD1217863 -:10CC2000022910D0012908BF90F8681143D061781B -:10CC300039B380F8727011F0140F18BF1E210CD098 -:10CC400080F8731055E090F8C410062905BF90F8DD -:10CC5000C3100229162106212DE011F0080F18BF7C -:10CC600080F8732045D111F0200F18BF2321E7D1A0 -:10CC700011F0030F08BFFFDF2A20E16881F873007D -:10CC800033E02BB1B0F88210B0F88420914211D279 -:10CC9000BCF1000F05DDB0F88810B0F88420914297 -:10CCA00008D2B0F88020B0F87E108A4208D390F8FD -:10CCB00066212AB1222180F8731080F8727018E082 -:10CCC00090F867203AB1B0F87C208A4228BF80F8FB -:10CCD0007380F2D209E0B0F87C10062905D33E211A -:10CCE00080F8731080F8727003E0E06890F87210BA -:10CCF00079B1E06880F8635080F8645080F867503C -:10CD000090F8D610002914BF02210321FCF723FC60 -:10CD100002E00021FCF71FFCE06880F8D650BDE877 -:10CD2000F047F8F7F0BBF949024648788B7818438A -:10CD30000ED10846C0684AB1097911F0080F03D036 -:10CD400090F86600082803D001207047FCF74FBB1D -:10CD5000002070472DE9F041EC4C05460E46A088B6 -:10CD60002843A08015F0020F04D015F0010F18BF62 -:10CD7000FFDF266115F0010F4FF000084FF00107AB -:10CD80001CD03046666103F01CF8062802D00B2840 -:10CD90000BD013E0E06890F8641017290ED1002141 -:10CDA000C0E9261180F8687008E0E06890F8641027 -:10CDB000112904BF80F8688080F88C7015F0020F8C -:10CDC00018D02069C078052802D00B280BD011E0BC -:10CDD000E06890F8641015290CD10021C0E92811F1 -:10CDE00080F8697006E0E06890F86410102908BFC8 -:10CDF00080F8698015F0800F1CBF0820A070BDE886 -:10CE0000F0812DE9F84FC14C00254FF00108A580B5 -:10CE10006570A5702570E06068F30709074680F823 -:10CE2000D6800088F3F736FF5FEA000A08BFFFDF0D -:10CE3000E0680088F8F72FFBE0680088F8F751FBFE -:10CE4000E068B0F8CA1071B190F8C310FF290FD193 -:10CE500090F8661191B190F8662001231946583078 -:10CE600002F09FFB98B1E06890F8C300FF2805D05E -:10CE7000E06890F8C30000BFFFF798FAD4F80CC040 -:10CE80009CF8D700002818BFE5801ED10FE0E068AD -:10CE9000A0F8805090F8671180F8C410002102209B -:10CEA000FFF76BFAE06880F8D5500220E4E79CF8C1 -:10CEB000960138B9BCF82000BCF80410884288BF3D -:10CEC000E08002D8BCF80400E080BCF8CE00401E30 -:10CED00086B2BCF8D0003044ACF8D0009CF8D40046 -:10CEE00000281CBFACF8D2508CF8D45004D1BCF848 -:10CEF000D2003044ACF8D200BCF87C003044ACF82E -:10CF00007C009CF8690040B99CF86420012306214C -:10CF10000CF1580002F045FB28B1E068B0F874103D -:10CF20003144A0F87410E068B0F8CA1001299CBF21 -:10CF3000491CA0F8CA10002E18BF80F8DC5090F8E9 -:10CF4000D510A1B1B0F8D000E18888420FD2504688 -:10CF5000F3F78CF858B1E06890F8611139B1B0F886 -:10CF6000D210B0F86201814228BF00F094FFE2685D -:10CF700082F8D55092F864000B2818BF0C2817D1FE -:10CF8000B2F85810B2F87C31C91A09B200290FDB87 -:10CF900002F5BF7102F1080004F053FF0221E068BE -:10CFA00001F0FEFEE06880F8645080F8968048E06A -:10CFB000252824D1B2F85800B2F87C11401A00B2EA -:10CFC00000281CDB92F8921192F87E01002808BF1D -:10CFD00092F8510082F8510092F87F01002808BFB2 -:10CFE00092F8520082F8520000291CBF0020FEF780 -:10CFF0005FFCE06880F8645080F87B5021E092F894 -:10D00000630025281DD1B2F85800B2F87C11401AEF -:10D0100000B2002815DB92F87E01002808BF92F8C4 -:10D02000510082F8510092F87F01002808BF92F861 -:10D03000520082F852000020FEF73AFCE06880F8C7 -:10D040006350E16801F15800B1F8CE2002F0B3F866 -:10D05000E06890F86111002918BFA0F8D2502C4860 -:10D0600000902C4B2C4A3946484600F053FEE068AD -:10D070000123052190F86420583002F092FA00282C -:10D0800008BFBDE8F88FBDE8F84F00F014BC00F011 -:10D09000E1BE10B50446B0F882214388B0F884118F -:10D0A000B0F886019A4201BFA3889942E38898426A -:10D0B0000FD02388A4F89A31A4F89C21A4F89E11DB -:10D0C000A4F8A001012084F896011048C078EEF77A -:10D0D00011FE0121204601F063FE002084F8640067 -:10D0E000032084F8670010BD70B5084C207910F05B -:10D0F000020F08BF70BD6078002818BF70BD20699E -:10D10000C178891E162980F06C8107E02401002077 -:10D110008DC7010027CD010055CD0100DFE801F0EA -:10D120000BF969758B1BF942F95BBE80F9F9F9F9C6 -:10D13000FAF7F6F5F4F3E0680123194690F8662053 -:10D14000583002F02EFA002818BF70BD0820E168A0 -:10D1500081F8660070BD02F0DFFEE16891F863209F -:10D160000A2A04BF91F8C220824205D1002081F82A -:10D17000630081F8860070BD91F8650010F0080F1B -:10D1800004BFFFDF70BD20F0080081F8650091F852 -:10D190008A00401E40B281F88A000028A8BF70BDF6 -:10D1A00000F0D8B8E06890F8650010F0010F08BFF3 -:10D1B000FFDFE16891F88A00401E40B281F88A00E2 -:10D1C0000028B8BFFFDFE06890F8651021F001018A -:10D1D00080F8651070BDE06890F86400102818BFF2 -:10D1E000FFDF0121E06880F88B10112180F86410C6 -:10D1F00070BDE06890F86400142818BFFFDF0121BB -:10D20000E06880F88B101521F0E7E06890F8640082 -:10D21000152818BFFFDF1720E16881F8640070BD92 -:10D22000E06890F86400152818BFFFDF1920E16856 -:10D2300081F8640070BDE06890F864001C2818BF95 -:10D24000FFDF0025E06880F88B5090F8A2010028ED -:10D2500018BFFFDFE06890F88C1041B180F88C5067 -:10D260000188A0F8A61180F8A4510D2108E00188DA -:10D27000A0F8A61180F8A451012180F8A8110C2172 -:10D2800080F8A2110088F3F7F3FCF3F753F9E07884 -:10D29000EEF730FDE06880F8645070BDE06890F80B -:10D2A0007A11042915D0E06890F8651011F0020F8A -:10D2B00008BF70BD90F88A10491E49B280F88A10E4 -:10D2C0000029B8BFFFDFE06890F8651021F0020187 -:10D2D0007EE790F8632001230021583002F061F9C5 -:10D2E000002808BFFFDFE06890F88E1011F0020FF1 -:10D2F00007BF062180F86310002180F8861018BF50 -:10D3000080F87A11CFE760E04FE035E024E011E0EB -:10D3100000E066E0E0680123002190F863205830C7 -:10D3200002F03FF9002808BFFFDF0E20E16881F816 -:10D33000630070BDE06890F8651021F0040180F88A -:10D34000651090F88A10491E49B280F88A100029A9 -:10D35000A8BF70BDFFDF70BDE0680123002190F819 -:10D360006320583002F01DF9002808BFFFDF1D20A0 -:10D37000E16881F8630070BDE06890F8650000F036 -:10D380003000102818BFFFDFE06890F8651021F02A -:10D39000100180F8651090F88A10491E49B280F893 -:10D3A0008A100029A8BF70BDD4E7E06801230021DE -:10D3B00090F86320583002F0F4F8002808BFFFDF2F -:10D3C0002020E16881F8630070BDE06890F8640097 -:10D3D00022281CBF0028FFDF2320E16881F86400B9 -:10D3E00070BDFFDF70BD10B5FE4CE16891F86500BF -:10D3F00010F0080F1EBF0120607010BD40F0080043 -:10D4000081F86500606902F0DCFCE16881F8C10028 -:10D410000020A1F8880091F88A00401C81F88A0059 -:10D4200010BD2DE9F041EF4CE06890F8C310FF29E2 -:10D4300006BF61780029BDE8F08190F866200123DD -:10D440001946583002F0ADF8002818BFBDE8F08149 -:10D45000E068002790F8661159B1A0F8807090F844 -:10D46000671180F8C410BDE8F04100210220FEF7EA -:10D4700084BF90F8642001230421583002F091F811 -:10D480005FEA00084FF002054FF001060CD0D4F817 -:10D490000CC09CF8640010287ED014287DD015287C -:10D4A0007CD01C287BD0E1E0E16891F8650010F0A9 -:10D4B000010F05D0BDE8F04101210920FEF75DBF55 -:10D4C00010F0020F0CD001210C20FEF756FFE0688F -:10D4D00090F88E1041F0010180F88E10BDE8F081C7 -:10D4E00010F0040F05D0BDE8F04101211320FEF734 -:10D4F00044BF10F0080F09D091F8C10081F8C400B2 -:10D50000BDE8F04101210720FEF737BF10F0100FF2 -:10D5100002D091F8890120B191F8640022287DD1D0 -:10D520009BE091F8880188B1B1F88A01A1F8400028 -:10D53000B1F88C01A1F84200B1F88E01A1F84400C5 -:10D54000B1F89001A1F8460081F88871FEF7E7F97B -:10D550000521E068FBF7FFFFE06890F84E10012915 -:10D5600008BF80F84E5014D00288A0F8BE21028E69 -:10D57000A0F8C021828EA0F8C221428E00F5CB71A6 -:10D58000A0F8C421C08E088681F82660E078EEF706 -:10D59000B1FB0121152003E006E00BE023E056E09B -:10D5A000BDE8F041FEF7E9BEBDE8F04101210B20E6 -:10D5B000FEF7E3BEF6F7D1FA0C2838BFBDE8F081DC -:10D5C0000821E068E830F6F7C9FA28B1E0680421DC -:10D5D000BC30F6F7C3FA00B9FFDFBDE8F041012126 -:10D5E0000420FEF7CABE9CF86901012817D0022862 -:10D5F00018BFBDE8F0819CF88C0000281CBF0620F5 -:10D600008CF8C4004FF0010114BF02200D20FEF77A -:10D61000B4FEE06880F86971BDE8F08126E09CF80E -:10D62000A201002818BFBDE8F0810CF1A803002278 -:10D630000CF1E0010CF5B57001F03BFF0121052074 -:10D64000FEF79BFEE06880F86971BDE8F081BDE8F7 -:10D65000F04101210620FEF790BE91F87B00C0B991 -:10D6600091F8920110B191F8930190B1E068012313 -:10D67000002190F86320583001F093FFC8B1E068B2 -:10D680000123042190F86420583001F08AFF30B162 -:10D690000FE0BDE8F04101211720FEF76EBEE06803 -:10D6A00090F87A0028B1BDE8F04100211220FEF781 -:10D6B00064BEE06890F863200A2A4DD0B8F1000FEC -:10D6C00018BFBDE8F08101230021583001F069FF47 -:10D6D00048B1E06890F87A11042904BF90F88E00F0 -:10D6E00010F0030F42D0E0680123002190F863207E -:10D6F000583001F056FF002808BFBDE8F081E0680F -:10D7000090F8881111B190F88911E1B390F8921155 -:10D71000002908BFBDE8F08190F89311002918BFD7 -:10D72000BDE8F08190F8642001230B21583001F00E -:10D7300038FF002818BFBDE8F081E06890F851205C -:10D7400090F89411012A71D0022A73D0042A14BFD0 -:10D75000082A042970D082E090F8C21080F8C41022 -:10D76000BDE8F04100210720FEF707BE00210C2094 -:10D77000FEF703FEE06890F88E1041F0010180F89A -:10D780008E10BDE8F081FFE7B0F88A11A0F84010D4 -:10D79000B0F88C11A0F84210B0F88E11A0F8441027 -:10D7A000B0F89011A0F8461080F8887190F86500E4 -:10D7B00010F0200F34D0FEF7B2F80521E068FBF737 -:10D7C000CAFEE06890F84E10012908BF80F84E505C -:10D7D00017D00288A0F8BE21028E00F5CB71A0F808 -:10D7E000C02101E024010020828EA0F8C221428ED7 -:10D7F000A0F8C421C08E088681F82660E078EEF794 -:10D8000079FA01211520FEF7B8FDE06890F865105F -:10D8100021F0200141F0100180F86510BDE8F08191 -:10D82000BDE8F04100211420FEF7A7BD012916D163 -:10D8300002E0FFE7022912D190F8522090F89511EA -:10D84000012A07D0022A08D0042A14BF082A042972 -:10D8500022D004E0012902D11EE002291CD090F858 -:10D86000642001230321583001F09BFE002818BFDB -:10D87000BDE8F081E0680123022190F8642058306F -:10D8800001F08FFE002818BFBDE8F0810021BDE83F -:10D89000F0411620FEF771BDBDE8F0410020FEF713 -:10D8A00007B8000030B5FF4C05462078002818BFA7 -:10D8B000FFDFA57230BDFB49012048727047FA486E -:10D8C00000B502784168406801F1580C91F8633066 -:10D8D00090F85100252B1CBF9CF80CC0BCF1250F03 -:10D8E00017D0202B18BF212B38D0BCF1230F18BF25 -:10D8F00000BD002A08BF00BD91F8942191F8501096 -:10D90000114011F0010F44D0082818BF04284CD052 -:10D910004EE08AB191F87E11002908BF00BD0828A9 -:10D9200018BF042841D0082918BF04293DD0012878 -:10D9300018BF01293CD036E091F8E810002908BF53 -:10D9400000BD082818BF04282FD0082918BF0429B3 -:10D950002BD0012818BF01292AD024E0BCF1230FC5 -:10D96000C7D0002A08BF00BD91F8941111F0010F33 -:10D9700004D0082818BF042817D019E011F0020FAE -:10D9800008BF00BD082818BF04280ED001280FD0FA -:10D9900009E011F0020F08BF00BD082818BF0428D5 -:10D9A00003D0012804D0022000BDFFDF082000BD05 -:10D9B000012000BD2DE9F14FBB4E4FF0010831466B -:10D9C0006FF00E0A4F686FF00D0B97F85210F88E3B -:10D9D00002290CBF0AEB90000BEBD00085B2788EC9 -:10D9E000A84238BF0546AF4C2946606BF2F77AFB78 -:10D9F000DFF8B892E06200281DBF0021A170A0628C -:10DA000084F8028008BFC4F8289030787068014616 -:10DA100000F1580890F86930428E91F85210C08E8B -:10DA200002290CBF0AEB90000BEBD00080B28242BF -:10DA300038BF1046002B1CBF001D80B2F6F756FE03 -:10DA400098F81100002838D008F15001974891E863 -:10DA50000E1000F5027A8AE80E10D8F86010C0F8AF -:10DA60002112D8F86410C0F8251200F58170F7F77C -:10DA7000B6F9307800280CBF0120002080F00101A9 -:10DA80008B480176D8E91212C0E90412C4F8289034 -:10DA90004946A581A0F58372F6F71BFD97F8520061 -:10DAA000012808BF002104D002281ABFFFDF00218F -:10DAB00001210120F6F71BFD04E0A06AF7F78FF9BA -:10DAC000F6F738FD009848B9012297F852309621B0 -:10DAD0001046F7F741F89620F7F7A9F997F82C00C8 -:10DAE000012808BFF7F726FA02202070BDE8F88F5A -:10DAF0002DE9F04FDFF8B08183B0414681464E6892 -:10DB0000A1F11400009096F85D004FF0000A012783 -:10DB100006F15804A1F1380570B3012873D002282A -:10DB200075D0032818BFFFDF7FD0686A082201780C -:10DB300021F008010170A37902EAC302114321F028 -:10DB400004010170E279042303EA8202114321F007 -:10DB50001001017094F805B0286BF2F795FA82462F -:10DB6000F7F7E3FCBBF1020F66D0BBF1010F67D002 -:10DB7000BBF1030F68D06CE0B6F834B0FFF79FFE3E -:10DB8000022819BF6FF00D0000EBDB006FF00E00F4 -:10DB900000EB9B0081B2308E884238BF0146ADF861 -:10DBA0000810A6F84C100098F7F79EFC38B1696A87 -:10DBB000EF70AA694FF48060904703201EE001AA2D -:10DBC00002A9286BF2F743F9686210B194F8331098 -:10DBD00021B10098F7F75CFC6771A6E79DF8041087 -:10DBE00031B9A0F800A080F802A0012102F03EF8AF -:10DBF000BDF80810686A02F01AFA0220607194E712 -:10DC000001E004E011E00098F7F742FC8DE7B6F878 -:10DC10004C00ADF8000001AA6946286BF2F717F92D -:10DC20006862002808BFFFDF7FE70098F7F75CFC19 -:10DC3000002808BFFFDF78E730EA0A0009D106E0D4 -:10DC400030EA0A0005D102E0BAF1000F01D001214B -:10DC500000E00021686A027842EA01110170217C2B -:10DC600000291CBF617901293CD004F150010F4803 -:10DC700091E80E1000F5027A8AE80E10216EC0F8C5 -:10DC80002112616EC0F8251200F58170F7F7A7F830 -:10DC900098F8000000280CBF0121002104480176FB -:10DCA00008E000003C01002074010020C00E0020AC -:10DCB000C8100020D4E91012C0E90412A0F5837145 -:10DCC0006A6AF6F706FC96F85100012808BF0021A1 -:10DCD00004D002281ABFFFDF002101210020F6F73F -:10DCE00006FC03E0F7F77BF8F6F724FCB9F1000F28 -:10DCF00006D196F85130012296210020F6F72CFF2C -:10DD0000AF71686A018829828078A8742F7003B087 -:10DD1000BDE8F08F2DE9F0471E46174681460C46B8 -:10DD2000FE4DDDF82080287828B9002F1CBF002E7A -:10DD3000B8F1000F00D1FFDFC5F82080C5E90E94CF -:10DD4000C5E9067600206872287268712871A8718A -:10DD5000E871F34EE870E881307804F158072088C4 -:10DD6000F2F798FF28632088F2F782FF6863F7F7DD -:10DD70002BF8F6F7DBFC04F11200F7F70EF804F1CC -:10DD80000E00F6F774FD307800280CBF0320012048 -:10DD9000F7F717F8787EF6F772FDF7F70CF830789A -:10DDA0006FF00E056FF00D09002830D0618EE08E07 -:10DDB00094F852407A7C022C0CBF05EB900009EBE2 -:10DDC000D00080B2814238BF0846002A1CBF001D27 -:10DDD00080B22146F6F78AFC3078002831D070688E -:10DDE00090F86001002818BFF6F7F2FC22460021E7 -:10DDF0000120F6F76DFE7068D0F8D800F6F7F2FF54 -:10DE00000120FFF7D7FDBDE8F047F6F7E5BF97F82B -:10DE10001080278EB4F834A0FFF751FD022814BFFC -:10DE200009EBDA0005EB9A0085B2AF4234BF384601 -:10DE30002846B8F1000F1CBF001D80B294F8514075 -:10DE4000C7E7002122460846F6F742FE0120FFF709 -:10DE50004FFED8E7B24810B501783838007831B1B4 -:10DE6000022818BFFFDFBDE81040F6F7ADBF01285C -:10DE700018BFFFDFF7E7A94810B50078022818BFE0 -:10DE8000FFDFBDE8104000F044BAA4488079704735 -:10DE9000A24840797047A1490120C87170472DE917 -:10DEA000F04706009E489D4D4FF0010740684FF037 -:10DEB000000800F15804A86A90F8019018BF012EDC -:10DEC00003D1696B03F0D0FA68706878A0B10128BB -:10DED00031D0022849D003281CBFFFDFBDE8F087FE -:10DEE000012E08BFBDE8F087686BF2F70CFBA87A3B -:10DEF000BDE8F047EDF7FEBE012E08D001224946ED -:10DF0000686BF2F74DF9022E08BFBDE8F087D4E93F -:10DF10001202411C42F10000C4E91210E07901280C -:10DF200003D100BF84F8078000E0E771A87ABDE85C -:10DF3000F047EDF7DFBE012E08D000224946686B9E -:10DF4000F2F72EF9022E08BFBDE8F087D4E91201DE -:10DF5000401C41F10001C4E91201E07901280CBF25 -:10DF600084F80780E771BDE8F087012E06D0686B62 -:10DF7000F2F7C9FA022E08BFBDE8F087D4E9120112 -:10DF8000401C41F10001C4E91201E0790128CCD123 -:10DF9000C8E72DE9F041624F4FF000083846A7F17D -:10DFA00038044068012600F158052078012818BF80 -:10DFB000FFDFA87850B185F80280E670A26941467B -:10DFC000042090473878002818BF2E71606A03211A -:10DFD000007831EA000004BFE878002805D1EE702F -:10DFE000616AE670A269022090470121002000F0DA -:10DFF000B1F918B1BDE8F04100F08BB9BDE8F041CE -:10E000000020D7E42DE9F84F454C83462046A4F183 -:10E0100038054068217800F1580A287800264FF02A -:10E020000109022818BFFFDFE88940F40070E88189 -:10E030002078676800283A48406890F868000090A7 -:10E040003C8EB7F83480FFF73AFC022807BF6FF028 -:10E050000E0000EB98006FF00D0000EBD80080B2CE -:10E06000844238BF2046009900291CBF001D80B2A1 -:10E0700097F85110F6F73AFB9AF81100BBF1000F30 -:10E0800000F0FA80F6F77CFAF6F76AFA90B99AF897 -:10E09000110078B1A86A417861B100789AF8071048 -:10E0A000C0F3C000884205D185F80490BDE8F84F60 -:10E0B00000F02FB9A86A1A4FB0460188A5F81310CE -:10E0C00080786875E88940F02000E8816E713878C2 -:10E0D0007868583000907C6894F82C00012818D19A -:10E0E000F6F71EFF2046009901F023FA88B1387830 -:10E0F000002878680CBF00F5867000F5EA7021886A -:10E1000041800099097A017180F80090A87AEDF7B2 -:10E11000F1FDA86A0078C0F3800003E03C01002014 -:10E12000740100209AF80610884237D03878786851 -:10E1300000F1580490F85D0060B3022848D000BF99 -:10E1400084F80580387840B12079414628B12171A2 -:10E1500085F80390AA6910209047E07898B184F878 -:10E160000380F7F7D0F9002808BFFFDF082085F803 -:10E170000390AA6900219047D4E91002411C42F1A2 -:10E180000000C4E91010A07901280CBF84F80680B3 -:10E1900084F80690E88940F48070E881A86A9AF8CB -:10E1A00007300178C1F3C0029A4252D13A787A68B6 -:10E1B00001F0030102F15804012918BF022935D0EA -:10E1C00003291CBF287A40F0040012D0287240E0D6 -:10E1D000286BF1F776FE002808BFFFDFD4E91002B4 -:10E1E000411C42F10000C4E91010A87AEDF782FD4D -:10E1F000A6E701F05CFDA8B184F80290E9894846E1 -:10E2000041F40061E981A96A85F80390AA69904701 -:10E21000E079012803D100BF84F8078019E084F871 -:10E22000079016E0287A40F01000CFE74078F8B168 -:10E23000E98941F40061E981A97851B9FB28F1D855 -:10E24000687A002808BF4E4603D08020AA690021C2 -:10E2500090475946012000F07DF858B39AF8110014 -:10E26000002818BFBBF1000F1BD0A87868B118E0D8 -:10E27000E0790128D3D1CFE7002818BFF6F7B9F924 -:10E28000E88940F04000E881E3E7A96AAA89487874 -:10E29000904288BF1046C21CE86A03F02DFCE86A71 -:10E2A000A862002E1CBF0020FFF7F9FDBDE8F84F63 -:10E2B00000F02FB8002E1CBF0120FFF7F0FD00205A -:10E2C000FFF716FC9AF81100002818BFBBF1000FE9 -:10E2D0000DD0A87858B9A96AAA894878904288BF11 -:10E2E0001046C21CE86A03F007FCE86AA862002E28 -:10E2F00008BFBDE8F88F0220BDE8F84FCFE5354AEA -:10E300001378526892F851200BB1FBF76ABAFAF70A -:10E310001AB970B52F4900254C68F6F7B7FDF6F726 -:10E32000A9FDF6F7DBFCF6F73EFDF6F703F9F6F785 -:10E3300053FD94F82C00012808BFF6F7F1FD264C98 -:10E340000021A269E0899047226A217A20799047CA -:10E35000257070BD70B5204C0546002908BF012D01 -:10E3600005D16079401CC0B26071012830D8E169E4 -:10E370002846884700282BD0E179184839B1012D6B -:10E3800001BF41780029017811F0100F20D0217AC7 -:10E39000F1B910490978002918BF002102D029439A -:10E3A00004D013E0012D18BF0121F8D10C490978E0 -:10E3B00011F0100F04BF007810F0100F08D0E078B3 -:10E3C00030B9A07810B111F0100F01D0002070BD4D -:10E3D000012070BD740100203C0100204F0100208D -:10E3E0004C01002010B540F2C311F94803F0FBFBCB -:10E3F000FF220821F748E4F7FAFDF74800214170B1 -:10E400004FF46171418010BD2DE9F0410F46064681 -:10E4100000F03FFBEE4C102817D004EBC00191F840 -:10E420004A1111F0010F1CBF0120BDE8F081617895 -:10E4300008291FD2617804EBC000491C61700121DA -:10E4400080F84A110846BDE8F0816178082911D2A8 -:10E450002578681C207004EBC5083868C8F84401AA -:10E46000B888A8F84801102D28BFFFDF88F843615D -:10E470002846DFE70020BDE8F081D5480178491E35 -:10E480004BB2002BB8BF704770B4002500EBC3013E -:10E4900091F84A1111F0010F3BD04278D9B2521EC7 -:10E4A000427000EBC10282F84A5190F802C000228B -:10E4B000BCF1000F0BD9841894F803618E4202D18D -:10E4C000102A26D103E0521CD2B29445F3D8027828 -:10E4D000521ED2B202708A421BD000EBC20200EB85 -:10E4E000C10CD2F84341CCF84341D2F84721CCF8D3 -:10E4F0004721847890F800C00022002C09D98618A2 -:10E5000096F8036166450AD1102A1CBF024482F8BE -:10E510000311591E4BB2002BB8DA70BC7047521C65 -:10E52000D2B29442EBD8F4E72DE9F0471F4690466B -:10E530000E46814600F0ADFAA54C0546102830D0B5 -:10E54000A2780021002A0ED9631893F80331834280 -:10E5500005D110291CBF1220BDE8F08703E0491C3B -:10E56000C9B28A42F0D8082A2FD2102D1CD0A67822 -:10E570001022701CA07004EB061909F1030041463B -:10E5800000F086FF09F183001022394600F080FF79 -:10E59000A019002180F8035180F83B110846BDE81E -:10E5A000F087A278082A10D22578681C207004EB26 -:10E5B000C50A3068CAF84401B088AAF84801102D8D -:10E5C00028BFFFDF8AF84391D1E70720BDE8F08735 -:10E5D00070B47F488178491E4BB2002BBCBF70BC21 -:10E5E000704700BF817803F0FF0C491ECAB28270E9 -:10E5F00050FA83F191F8031194453ED000EB0215D7 -:10E6000000EB0C14D5F80360C4F80360D5F807607C -:10E61000C4F80760D5F80B60C4F80B60D5F80F603C -:10E62000C4F80F60D5F88360C4F88360D5F88760BC -:10E63000C4F88760D5F88B60C4F88B60D5F88F502C -:10E64000C4F88F50851800EB0C0402EB420295F8D9 -:10E6500003610CEB4C0C00EB420284F8036100EB0D -:10E660004C0CD2F80B61CCF80B61B2F80F21ACF86E -:10E670000F2195F83B2184F83B2100EBC10292F871 -:10E680004A2112F0010F33D190F802C00022BCF1F0 -:10E69000000F0BD9841894F803518D4202D1102A2F -:10E6A00026D103E0521CD2B29445F3D80278521E10 -:10E6B000D2B202708A421BD000EBC20200EBC10C46 -:10E6C000D2F84341CCF84341D2F84721CCF8472156 -:10E6D000847890F800C00022002C09D9851895F89C -:10E6E000035165450BD1102A1CBF024482F8031167 -:10E6F000591E4BB2002BBFF675AF70BC7047521C51 -:10E70000D2B29442EAD8F3E73349487070473248AE -:10E710004078704738B14AF2B811884203D82E4980 -:10E72000488001207047002070472B484088704780 -:10E7300010B500F0AEF9102814D0254A014600208B -:10E7400092F802C0BCF1000F0CD9131893F80331F2 -:10E750008B4203D1102818BF10BD03E0401CC0B28B -:10E760008445F2D8082010BD19498A78824286BFB4 -:10E7700001EB001083300020704715498A788242EF -:10E7800086BF01EB0010C01C00207047104B93F8AF -:10E7900002C084459CBF00207047184490F80301D4 -:10E7A00003EBC00090F843310B70D0F844111160B6 -:10E7B000B0F84801908001207047054A114491F853 -:10E7C000032105490A7002684A6080880881704701 -:10E7D000F0100020860100207C01002010B5F5F724 -:10E7E00027FE002804BFFF2010BDBDE81040F5F74C -:10E7F00045BEFE498A7882429CBF0020704708448B -:10E8000090F8030101EBC00090F84A0100F001000C -:10E8100070472DE9F047F54F0026B04638780028BC -:10E8200086BF4FF0080ADFF8C893BDE8F08700BF45 -:10E8300007EBC80505F5A27195F8430100F029F929 -:10E84000102808BF544610D0B978002400290BD9ED -:10E850003A1992F80321824202D1102C05D103E02B -:10E86000621CD4B2A142F3D80824B878A04286BF73 -:10E8700007EB0410C01C002095F84A1111F0010F9D -:10E8800016D050B1082C04D2391991F83B11012946 -:10E8900003D0102100F0D9FD50B109F806403046F0 -:10E8A000731C95F8432105F5A271DEB2F5F7A8FFB8 -:10E8B00008F1010000F0FF0838784045B8D8BDE8FD -:10E8C000F0872DE9F041C94C00263546A078002894 -:10E8D0008CBFC74FBDE8F0816119C0B291F80381C8 -:10E8E000A84286BF04EB0510C01C002091F83B1124 -:10E8F000012903D0102100F0A8FD58B104EBC80095 -:10E90000BD5590F8432100F5A2713046731CDEB26C -:10E91000F5F776FF681CC5B2A078A842DCD8BDE840 -:10E92000F08110B5F5F79BFF002804BF082010BD4B -:10E93000F5F799FFAE49085C10BDAE4910B54978AE -:10E9400041B1AA4B997829B1C21CD81CF5F70DFD2D -:10E95000012010BD002010BDA44A01EB410102EBD3 -:10E9600041010268C1F80B218088A1F80F017047AE -:10E970002DE9F0419D4D07460024A878002898BF56 -:10E98000BDE8F081C0B2A04213D905EB041010F12C -:10E9900083060ED01021304600F057FD48B904EB35 -:10E9A000440005EB400000F20B113A463046F6F702 -:10E9B0003AFE601CC4B2A878A042E3D8BDE8F0815A -:10E9C000014610228C4800F063BD8B48704770B53B -:10E9D000864D0446A878A04206D905EB0410102104 -:10E9E000833000F032FD08B1002070BD04EB44001C -:10E9F00005EB400000F20B1070BD7C498A78824222 -:10EA000006D9084490F83B01002804BF0120704754 -:10EA1000002070472DE9F0410E46074615460621B5 -:10EA2000304600F012FD714C98B1A17871B104F537 -:10EA30009D7011F0010F18BF00F8015FA17849081F -:10EA400004D0457000F8025F491EFAD10120BDE8EC -:10EA5000F0813846314600F01CF8102816D0A37813 -:10EA60000021002B12D9621892F80321824209D1A9 -:10EA7000102918BF082909D0601880F83B510120DF -:10EA8000BDE8F081491CC9B28B42ECD80020BDE83A -:10EA9000F0812DE9F041554D0646002428780F46B7 -:10EAA000002811D905EBC40090F84311B14206D1FA -:10EAB0000622394600F5A27002F0F2FF38B1601C60 -:10EAC000C4B22878A042EDD81020BDE8F0812046DD -:10EAD000BDE8F081454910B44A7801EBC003521EED -:10EAE0004A70002283F84A2191F802C0BCF1000F5D -:10EAF0000DD98B1893F80341844204D1102A1CBF0E -:10EB000010BC704703E0521CD2B29445F1D80A7889 -:10EB1000521ED2B20A70824204BF10BC704701EB91 -:10EB2000C00301EBC202D2F843C1C3F843C1D2F81B -:10EB30004721C3F847218C7891F800C00022002CAF -:10EB40009CBF10BC70478B1893F80331634506D106 -:10EB5000102A1CBF114481F8030110BC7047521CDD -:10EB6000D2B29442EFD810BC704770B41F490D1850 -:10EB70008A78521ED3B28B7095F80321984247D001 -:10EB800001EB001401EB031C00EB4000DCF8036018 -:10EB9000C4F80360DCF80760C4F80760DCF80B60B9 -:10EBA000C4F80B60DCF80F60C4F80F60DCF8836019 -:10EBB000C4F88360DCF88760C4F88760DCF88B6099 -:10EBC000C4F88B60DCF88FC0C4F88FC001EB030C75 -:10EBD00003EB43039CF8034101EB430385F8034136 -:10EBE00001EB4000D3F80B4108E00000F0100020DA -:10EBF000860100207C010020B3120020C0F80B41E8 -:10EC0000B3F80F31A0F80F319CF83B0185F83B01B8 -:10EC100001EBC20090F84A0110F0010F1CBF70BC5C -:10EC2000704700208C78002C0DD90B1893F803C185 -:10EC3000944504D110281CBF70BC704703E0401CF1 -:10EC4000C0B28442F1D80878401EC0B20870904229 -:10EC500004BF70BC704701EBC20301EBC000D0F8E9 -:10EC600043C1C3F843C1D0F84701C3F847018C78CA -:10EC70000B780020002C9CBF70BC704701EB000C8F -:10EC80009CF803C19C4506D110281CBF084480F89D -:10EC9000032170BC7047401CC0B28442EED870BCE7 -:10ECA0007047000010B50A7B02F01F020A730022B1 -:10ECB000C2758B181B7A03F0010C5B0803F001048A -:10ECC000A4445B0803F00104A4445B0803F00104BE -:10ECD000A4445B0803F0010464444FEA530C0CF0B5 -:10ECE000010323444FEA5C0C0CF00104234403EBC2 -:10ECF0005C0300EB020C521C8CF8123090F817C029 -:10ED0000D2B26344C375052AD3D3D8B2252888BFAD -:10ED1000FFDF10BD00238383028401EBC202521E79 -:10ED2000B2FBF1F1C183704770B46FF01F02010CA8 -:10ED300002EA90251F23A1F5AA4054381CBFA1F573 -:10ED4000AA40B0F1550009D0A1F52850AA381EBF3D -:10ED5000A1F52A40B0F1AA00012000D100204FF017 -:10ED6000000C62464FEA0C048CEA0106F643164397 -:10ED7000B6F1FF3F11D005F001064FEA5C0C4CEAFA -:10ED8000C63C03F0010652086D085B08641C42EAA9 -:10ED9000C632162CE8D370BC704770BC0020704798 -:10EDA0002DE9F04701270025044603290FD04FF431 -:10EDB000FA43002972D0012900F0F880022918BF17 -:10EDC000BDE8F0870146BDE8F04758306AE704F136 -:10EDD00058067021304602F028FFB571F571F572C2 -:10EDE0003573B573F573757135767576F52086F8DC -:10EDF0003C00412086F83D00FF2086F86B00A4F817 -:10EE0000C850A4F8CA50A4F8CC50A4F8CE50A4F826 -:10EE1000D050A4F8D25084F8D55084F8D750A4F834 -:10EE2000DE5084F8DC50A4F8F050A4F8F25084F8D6 -:10EE30002C50258484F8517084F852704FF4486047 -:10EE400060801B21218761874FF4A470E087A08731 -:10EE500021866186E086A086A4F84410A4F84600C6 -:10EE6000A4F84010A4F84200A4F84810A4F84A10EE -:10EE7000A4F84C10677384F8885184F8895184F899 -:10EE8000925184F8935184F8615184F8665184F862 -:10EE9000695184F87A51BDE8F087FFE7A4F8DE50A5 -:10EEA00084F8D6506088FE490144B1FBF0F1A4F823 -:10EEB00076104BF68031A4F87810E288A4F87C50E4 -:10EEC000B4F880C0D2000CFB00FCB2FBF0F29CFB5B -:10EED000F0FC521CA4F880C092B202FB00FC04F1CA -:10EEE0005801A4F87E20BCF5C84FC4BF521ECA8486 -:10EEF000B3FBF0F2521C8A8500F5802202F5EE3257 -:10EF0000531EB3FBF0F2CA838B8B03FB00F2B2FB00 -:10EF1000F0F08883214604F15800FFF7C3FED4F8CF -:10EF20000E106FF01F02080C02EA9126A0F5AA410C -:10EF30004FF01F0C54391CBFA0F5AA41B1F1550187 -:10EF40000AD0A0F52851AA391EBFA0F52A41B1F177 -:10EF5000AA014FF0010901D14FF00009002211462A -:10EF60004FEA020382EA00086FEA080848EA01084B -:10EF7000B8F1FF3F16D006F00108520842EAC83245 -:10EF800049080CF0010876085B1C41EAC8314FEAD9 -:10EF90005C0C162BE6D3B9F1000F1CBF84F860514E -:10EFA000BDE8F08784F86071BDE8F087A4F8DE5012 -:10EFB000B4F88221B4F88611B4F802C004F1580004 -:10EFC000A4F87C50B4F88040C90004FB0CF4B1FBF9 -:10EFD000F2F194FBF2F4491C048589B201FB02F4BE -:10EFE000C184B4F5C84FC4BF491EC184B3FBF2F15C -:10EFF000491C8185018C02EBC101491EB1FBF2F174 -:10F00000C183818B01FB0CF1B1FBF2F18183BDE87F -:10F01000F08770B50025044603290DD04FF4FA425D -:10F02000002958D001297DD0022918BF70BD0146A2 -:10F03000BDE87040583035E604F15806702130467E -:10F0400002F0F3FDB571F571F5723573B573F573B3 -:10F05000757135767576F52086F83C00412086F886 -:10F060003D00FF2086F86B00A4F8D050202084F8E3 -:10F07000D20084F8C850C4F8CC50012284F82C5037 -:10F0800084F8512084F852201B20208760874FF499 -:10F09000A471E187A18720866086E186A186A4F815 -:10F0A0004400A4F84610A4F84000A4F84210A4F8C4 -:10F0B0004800A4F84A00A4F84C00627384F8FC509D -:10F0C00084F8FD5084F8065184F8075184F8EC5018 -:10F0D00084F8F85070BD608871490144B1FBF0F1CB -:10F0E000A4F876104BF68031A4F87810E388A4F8E1 -:10F0F0007C50B4F880C0DB000CFB00FCB3FBF0F3E9 -:10F100009CFBF0FC5B1CA4F880C09BB203FB00FCE2 -:10F1100004F15801A4F87E30BCF5C84FC4BF5B1E93 -:10F12000CB8400E017E0B2FBF0F2521C8A8500F5B8 -:10F13000802202F5EE32531EB3FBF0F2CA838B8BB2 -:10F1400003FB00F2B2FBF0F08883214604F1580083 -:10F15000BDE87040A6E5D4F8F030B4F802C004F180 -:10F1600058005989DB89A4F87C50B4F88040DB0052 -:10F1700004FB0CF4B3FBF1F394FBF1F45B1C04858A -:10F180009BB203FB01F4C384B4F5C84FC4BF5B1E3C -:10F19000C384B2FBF1F2521C8285028C01EBC202E5 -:10F1A000521EB2FBF1F2C283828B02FB0CF2B2FB65 -:10F1B000F1F1818370BD2DE9F003C47D0CB1252CE4 -:10F1C00003D9BDE8F00312207047002A02BF0020D7 -:10F1D000BDE8F003704791F80DC01F260123314DA3 -:10F1E0004FF00008BCF1000F7AD0BCF1010F1EBF38 -:10F1F0001F20BDE8F0037047B0F800C00A7C8F7B89 -:10F2000091F80F907A404F7C87EA090742EA07227B -:10F2100082EA0C0C5FF000070CF0FF094FEA1C2C8F -:10F2200099FAA9F99CFAACFC4FEA19694FEA1C6CEF -:10F2300049EA0C2C0CEB0C1C7F1C9444FFB21FFA07 -:10F240008CFC032FE8D38CEA020C164F0022ECFB57 -:10F25000057212096FF0240502FB05C2D2B201EB60 -:10F26000D207027602F007053F7A03FA05F52F422E -:10F2700018BF42767ED104FB0CF2120C521CD2B2A3 -:10F280005FF0000400EB040C9CF812C094453CBFF6 -:10F29000A2EB0C02D2B218D34FF0000C0D1903E010 -:10F2A000FFDB050053E4B36E95F8085003FA0CF742 -:10F2B0003D421CBF521ED2B2002A6AD00CF1010C92 -:10F2C0000CF0FF0CBCF1080FF0D304F1010C0CF0B2 -:10F2D000FF04052CD6D33046BDE8F0037047FFE7A6 -:10F2E00090F818C00C7E474604FB02C2FB4C4FF05E -:10F2F000000CE2FB054C4FEA1C1C6FF024040CFBD5 -:10F300000422D2B201EBD204027602F0070C247A76 -:10F3100003FA0CFC14EA0C0F1FBF42764046BDE80E -:10F32000F003704790F817C0B2FBFCF40CFB1422FA -:10F33000521CD2B25FF0000400EB040C9CF812C027 -:10F3400094453CBFA2EB0C02D2B212D30D194FF080 -:10F35000000C2D7A03FA0CF815EA080F1CBF521E98 -:10F36000D2B27AB10CF1010C0CF0FF0CBCF1080F19 -:10F37000F0D300E010E004F1010C0CF0FF04052CC8 -:10F38000DAD3A8E70CEBC40141763846BDE8F003B8 -:10F3900070470CEBC40141764046BDE8F00370476E -:10F3A000CF4A016812681140CE4A126811430160C9 -:10F3B000704730B4CC49CA4B00244FF0010C0A7896 -:10F3C000521CD2B20A70202A08BF0C700D781A683D -:10F3D0000CFA05F52A42F2D0097802680CFA01F11C -:10F3E0005140016030BC7047017931F01F0113BFFB -:10F3F000002000221146704710B4435C491C03F002 -:10F40000010C5B0803F00104A4445B0803F0010451 -:10F41000A4445B0803F00104A4445B0803F0010466 -:10F42000A4445B0803F001045B08A44403F0010456 -:10F43000A4440CEB53031A44D2B20529DDDB012AA4 -:10F440008CBF0120002010BC704730B40022A1F115 -:10F45000010CBCF1000F11DD431E11F0010F08BFBC -:10F4600013F8012F5C785FEA6C0C07D013F8025F89 -:10F4700022435C782A43BCF1010CF7D1491E5CBFE2 -:10F48000405C0243002A0CBF0120002030BC7047C2 -:10F49000130008BF704710B401EB030CD41A1CF81A -:10F4A00001CC5B1E00F804C013F0FF03F4D110BCC4 -:10F4B0007047F0B58DB0164610251C466A46AC461E -:10F4C00000EB0C03A5EB0C0713F8013CD355ACF192 -:10F4D000010313F0FF0CF3D11546103210208446BF -:10F4E0000B18ACEB000713F8013C401ED35510F08D -:10F4F000FF00F5D1284601F033FA86B1102005F15E -:10F50000200201461318A1EB000C13F8013C401E29 -:10F5100004F80C3010F0FF00F4D10DB0F0BD0898E5 -:10F520002060099860600A98A0600B98E0600DB0B8 -:10F53000F0BD38B505460C466846F5F706FD0028CF -:10F5400008BF38BD9DF90020227294F909100020EF -:10F55000511A48BF494295F82D308B42C8BF38BD7B -:10F56000FF2B08BF38BDA17A491CC9B2A17295F81A -:10F570002E30994203D8617A7F2918BF38BD627254 -:10F580000020A072012038BD0C2818BF0B2806D01F -:10F590000D281CBF2038062884BF0020704701209A -:10F5A00070470C295AD2DFE801F006090E13161B2A -:10F5B000323C4153484E002A52D04FE0072A18BF30 -:10F5C000082A4DD04AE00C2A18BF0B2A48D045E043 -:10F5D0000D2A45D042E0A2F10F000D2840D93DE0B0 -:10F5E00023B1A2F110000C283AD937E0122A18BF33 -:10F5F000112A35D090F8340020B1122A2ED31B2ABC -:10F600002ED92BE0162A29D31B2A29D926E0A2F1CC -:10F610000F01032924D990F83400F8B11C2A1FD90E -:10F620001CE0002B08BF042A18D119E013B1062AE8 -:10F6300016D013E0012A11D112E01D2A1CBF1E2A88 -:10F640001F2A0DD00AE0A2F12000062808D905E003 -:10F6500013B10E2A04D001E0052A01D00020704722 -:10F66000012070472DE9F04187680D460446204689 -:10F67000F3F7CCFB98B1D5B13846A168F3F709FF91 -:10F68000002814DD2844401EB0FBF5F606FB05F10A -:10F690003846F2F7F8FEA0603046BDE8F081F3F797 -:10F6A000E7F94FF4E661F2F7EEFEA060DFE7002035 -:10F6B000BDE8F081904228BF704770B50446101B2A -:10F6C000642838BF642025188D4205D8F3F715FF4C -:10F6D00000281CBF284670BD204670BD53E4B36EA1 -:10F6E00064230200682302008E01002091F851304B -:10F6F0000A8E022B07BF92003C32D200703292B2C7 -:10F700008B8E934238BF1A464B8E91F852C0BCF193 -:10F71000020F07BF9B003C33DB0070339BB2C98EE6 -:10F72000994238BF0B4600280CBF01210021D01898 -:10F730009830002918BF04210844704730B48388EA -:10F74000B0F808C003EB0C049834002A18BF042258 -:10F7500022444C6A944224BF30BC7047121B521C96 -:10F7600052089B1A9BB2ACEB0202838092B20281D8 -:10F7700091F851506FF00E0C6FF00D04022D0CBF7C -:10F780000CEB930304EBD303438091F8521002294E -:10F790000CBF0CEB920104EBD201C18030BC70476E -:10F7A00010F0010F1CBF0120704710F0020F1CBFAA -:10F7B0000220704710F0040018BF082070472DE9A0 -:10F7C000F0410546174688460126084600F001FC30 -:10F7D0000446404600F001FC034610F0010F18BF3C -:10F7E000012008D113F0020F18BF022003D113F03B -:10F7F000040018BF082014F0010F18BF4FF0010CCF -:10F8000021D000BF50EA0C0108BF002613F0030FFF -:10F8100008BF002014F0030F08BF4FF0000C95F84C -:10F820005110814208BF0020387095F85210614590 -:10F8300008BF4FF0000C87F801C0002808BFBCF1DA -:10F84000000F1CD10DE014F0020F18BF4FF0020C96 -:10F85000D8D114F0040F14BF4FF0080C4FF0000C77 -:10F86000D0E7404600F0BFFBB5F85810401A00B290 -:10F8700047F6FE71884201DC002800DC0026304695 -:10F88000BDE8F08101281CBF02280020704718B491 -:10F89000CBB2C1F3072CC1B2C0F30720012B07D0B4 -:10F8A000022B09D0042B08BFBCF1040F23D006E0C3 -:10F8B000BCF1010F03D11EE0BCF1020F1BD00129E6 -:10F8C00006D0022907D0042908BF042813D004E079 -:10F8D000012802D10FE002280DD001EA0C0161F3EA -:10F8E0000702184060F30F22D0B210F0020F18BFC9 -:10F8F00002200BD106E0084003EA0C01084060F347 -:10F900000702EFE710F0010018BF01208DF800009A -:10F91000C2F3072010F0020F18BF022003D110F02D -:10F92000010018BF01208DF80100BDF8000018BCCF -:10F930007047162A10D12A220C2818BF0D280FD084 -:10F940004FF0230C20280DD031B10878012818BFC2 -:10F95000002805D0162805D00020704701207047E8 -:10F960001A70FBE783F800C0F8E70000282102F0D6 -:10F970003AB930B50546007801F00F0220F00F00CB -:10F980001043287007290BD2DFE801F004060406B3 -:10F9900004080400062405E00C2403E0222401E00E -:10F9A0000024FFDF687820F03F002043687030BDFE -:10F9B000007800F00F0070470A68C0F803208988BB -:10F9C000A0F807107047D0F803200A60B0F80700CD -:10F9D000888070470A68C0F809208988A0F80D104F -:10F9E0007047D0F809200A60B0F80D008880704791 -:10F9F0000278202322F0200203EA41111143017012 -:10FA000070470278402322F0400203EA811111433B -:10FA1000017070470078C0F380107047027880232F -:10FA200022F0800203EAC11111430170704700788F -:10FA3000C0097047D0F80320C1F80920B0F80720AA -:10FA4000A1F80D200A7822F080020A70007880095F -:10FA500042EAC0100870704770B515460E4604465D -:10FA60001F2A88BFFFDF2A46314604F1090002F051 -:10FA700043F86078A91D20F03F0001F03F010843E2 -:10FA8000607070BD70B5054640780E4600F03F04CA -:10FA9000062C38BFFFDFA01FC4B21F2C88BF1F2455 -:10FAA000224605F10901304602F026F8204670BDD5 -:10FAB00070B515460E4604461F2A88BFFFDF2A464A -:10FAC000314604F1090002F017F86078A91D20F012 -:10FAD0003F0001F03F010843607070BD70B50546FE -:10FAE00040780E4600F03F04062C38BFFFDFA01F11 -:10FAF000C4B21F2C88BFFFDF224605F10901304642 -:10FB000001F0FAFF204670BD0968C0F80F10704779 -:10FB10000A88A0F813208978417570474176090A50 -:10FB200081767047C176090A017770474177090AE3 -:10FB300081777047C175090A0176704781757047F2 -:10FB400090F8242001F01F0122F01F02114380F8D9 -:10FB500024107047072988BF072190F82420E0234C -:10FB600022F0E00203EA4111114380F824107047AB -:10FB70001F3002F066B94178007801F03F0110F0C3 -:10FB80000F0006D0012808D0022809D006280BD083 -:10FB90000FE0881F1F280AD90BE00C2909D106E0C5 -:10FBA000881F1F2803D904E0881F1F2801D80120BF -:10FBB0007047002070474178007801F03F0100F065 -:10FBC0000F00042805D1062903D325299CBF012055 -:10FBD00070470020704710B4017801F00F0103292D -:10FBE00022D0052925D14478B0F81910B0F81BC0EF -:10FBF000B0F81730827D04F03F04222C19D1062979 -:10FC000017D3B1F5486F98BFBCF5FA7F11D282B116 -:10FC1000082A98BF8A420CD28B429CBFB0F81D00C4 -:10FC2000B0F5486F05D807E0407800F03F000C2899 -:10FC300002D010BC0020704710BC01207047222168 -:10FC400001F0D1BF00B5027801F0030322F00302F6 -:10FC50001A43027000224270012914BF022900BD1C -:10FC6000032912BFFFDF0121417000BD01F0030332 -:10FC700000B5027822F003021A430270002242709B -:10FC8000012914BF022900BD032912BFFFDF012192 -:10FC9000417000BD007800F0030070470278102327 -:10FCA00022F0100203EA01111143017070474178FC -:10FCB000F9B1C078192850D2DFE800F00D10131602 -:10FCC000191C1F2225282B2E31344F4F4F4C373A09 -:10FCD0003D40434649000C2941D042E008293ED02E -:10FCE0003FE002293BD03CE0172938D039E00D290C -:10FCF00035D036E0012932D033E001292FD030E071 -:10FD000002292CD02DE0092929D02AE0092926D062 -:10FD100027E0012923D024E0012920D021E0062971 -:10FD20001DD01EE002291AD01BE0012917D018E0CF -:10FD3000012914D015E0092911D012E009290ED0AB -:10FD40000FE003290BD00CE0032908D009E00529B6 -:10FD500005D006E0032902D003E0FB2901D80120E9 -:10FD600070470020704730B50546C170192924D26C -:10FD7000DFE801F00D0F11131517171119191717D7 -:10FD80001B111921211D171719191D1D1F000C24E6 -:10FD900015E0082413E0022411E017240FE00D24DD -:10FDA0000DE001240BE0092409E0062407E0032408 -:10FDB00005E0052403E0182401E00024FFDF6C7057 -:10FDC00030BDC0787047C171090A01727047B0F840 -:10FDD000070070474172090A81727047B0F8090044 -:10FDE0007047C172090A01737047B0F80B00704781 -:10FDF0004171090A81717047B0F8050070470171BF -:10FE00007047007970474173090A81737047B0F8F1 -:10FE10000D00704730B4B0F80720894DB0F809C024 -:10FE2000B0F805300179941F2D1998BFBCF5FA7F01 -:10FE30000ED269B1082998BF914209D293429FBF5F -:10FE4000B0F80B00B0F5486F012030BC98BF704788 -:10FE5000002030BC7047001D01F0F3BF021D0846B2 -:10FE6000114601F0EEBF4172090A81727047B0F885 -:10FE70000900704701717047007970470A68426055 -:10FE800049688160704742680A60806848607047CE -:10FE90000988818170478089088070470A68C0F8A6 -:10FEA0000E204968C0F812107047D0F80E200A6082 -:10FEB000D0F81200486070470968C0F81610704703 -:10FEC000D0F81600086070470A684260496881608F -:10FED000704742680A608068486070470968C1607E -:10FEE0007047C06808607047017170474171090A26 -:10FEF00081717047C171090A0172704700797047BA -:10FF0000B0F805007047B0F80700704701717047FE -:10FF10000079704701717047007970470A68426044 -:10FF200049688160704742680A608068486070472D -:10FF30000171090A417170478171090AC1717047E5 -:10FF40000172090A417270478172090AC1727047D1 -:10FF500080887047C0887047008970474089704723 -:10FF600001891B2924BF4189B1F5A47F07D381886A -:10FF70001B2921BFC088B0F5A47F01207047002055 -:10FF800070470A68426049688160704742680A6049 -:10FF9000806848607047017170470079704741710F -:10FFA000704740797047017911F0070F1BBF407906 -:10FFB00010F0070F002001207047017911F0070FA2 -:10FFC0001BBF407910F0070F00200120704701711E -:10FFD000704700797047417170474079704781716F -:10FFE000090AC1717047C088704716A282B0D2E971 -:10FFF0000012CDE900120179407901F0070269464B -:020000040002F8 -:100000001DF80220012A07D800F00700085C01282B -:100010009EBF012002B07047002002B070470171FE -:10002000704700797047417170474079704730B52B -:100030000C460546FB2988BFFFDF6C7030BD000011 -:1000400086F3FFFF000101020102020370B50446BE -:10005000C2F11005281901F04FFD15F0FF0108D07D -:10006000491EC9B2802060542046BDE8704001F0AE -:10007000BABD70BD30B505E05B1EDBB2CC5CD55CB3 -:100080006C40C454002BF7D130BD10B5002409E0FA -:100090000B78521E44EA430300F8013B11F8013B80 -:1000A000D2B2DC09002AF3D110BD2DE9F0410C4693 -:1000B00001200978FF4E92B0154602274FF006083E -:1000C0004FF0040C71B101291ED0022945D003293B -:1000D00005D12978042902D105201070002012B022 -:1000E000BDE8F081606850B1CDE9010601202070C3 -:1000F0008DF80080606A05901146684663E02770BD -:1001000085F800C0566026E029780429E7D169689F -:1001100010222069FFF7B9FF6868C07B000606D58A -:10012000E44A2069102310320146FFF7A3FFD4E907 -:1001300004101022FFF7A9FF2069C07B000606D536 -:10014000DC4A6069102310320146FFF793FF2770E5 -:1001500085F800C06E600320C1E729780429BED16C -:10016000A08910280CD9A0F1100080B2A081A1684C -:100170004FF01003014468466A68FFF77BFF18E000 -:1001800004D14FF010032269A16807E0C2B20EA8A3 -:10019000A168FFF75BFF626910230EA90AA8FFF7A9 -:1001A00069FF10230AA968466A68FFF763FF032006 -:1001B000207060680590CDF818D08DF81080606AC6 -:1001C0000990294604A8F1F759FF88E72DE9F04185 -:1001D00007460D4601200B7806213BB1012B04D1C7 -:1001E0001378052B01D11170002079E76C69012685 -:1001F00020226170E8686060686A6062A168287C9B -:100200000870A681A068A968401C01F075FCA0894F -:1002100020222030A081A0686968213001F06CFCA8 -:10022000A08921462030A0812E703846BDE8F041DB -:10023000F1F73BBF2DE9F05F0D46834601200978B9 -:10024000174606464FF00608D1B1DFF868A24FF016 -:100250000009AAF1080A012923D002297ED0032926 -:100260000CD13978052909D179681022E86901F0A3 -:1002700043FC07203870183500207D60BDE8F09FF2 -:100280002C6A8C48202284F8018020306060202075 -:10029000A081686A60626968A06801F02DFC2E7018 -:1002A000D4E039780529E9D12C6A84F80180686A9C -:1002B000606251681022E86901F01EFCE869606024 -:1002C000A0684F4680F80090A681A0684670A0897B -:1002D000401C80B2A081A1680844696951F8012FCF -:1002E000026089888180A089801D80B2A0816969AF -:1002F000A2680978C1F340011154A089401C80B262 -:10030000A081A1680844296951F8012F02608988F9 -:100310008180A089801D80B2A0812969A2680978A6 -:10032000C1F340011154A0891022401C80B2A08169 -:10033000A1680844E96801F0DFFBA08910221030B1 -:1003400080B2A081A1680844A96801F0D5FBA0890A -:10035000103080B2A081A168014400E00DE0DAF81D -:1003600004000860A089001D80B2A081A1680F541C -:10037000A089401CA081022067E03978052992D12C -:1003800051681022A86901F0B7FB2C6A84F801803B -:10039000E8696060686A6062A16881F80090A6817F -:1003A000A0684670A089401C80B2A081A168084462 -:1003B000696951F8012F026089888180A089801DB8 -:1003C00080B2A0816969A2680978C1F34001115423 -:1003D000A089401C80B2A081A1680844296951F815 -:1003E000012F026089888180A089801D80B2A08150 -:1003F0002969A2680978C1F340011154A08910222B -:10040000401C80B2A081A1680844E96801F074FB37 -:10041000A0891022103080B2A081A1680844A96888 -:1004200001F06AFBA089103080B2A081A16801446C -:10043000DAF804000860A089001D80B2A081A168DC -:100440000E54A089401CA0810320287021465846E4 -:10045000BDE8F05FF1F729BE70B50D460646097894 -:10046000012041B1012905D11178052902D10820C7 -:100470001070002070BD2C6A062060706968616091 -:10048000696A6162EA69A16852F8013F0B6092886B -:100490008A80A081E869A1680078C0F34000887173 -:1004A000A089401C80B2A081A1680844A96951F8C4 -:1004B000012F01E074230200026089888180A089F5 -:1004C000801D80B2A081A969A2680978C1F34001AA -:1004D0001154A089401C80B2A081A16808446969B8 -:1004E0000A88028089788170A0891022C01C80B29D -:1004F000A081A1680844296901F0FEFAA0891022B0 -:10050000103080B2A081A1680844E96801F0F4FAD3 -:10051000A0891022103080B2A081A1680844A96887 -:1005200001F0EAFAA08921461030A081012028704C -:100530003046BDE87040F1F7B8BD70B50D460646CF -:100540000978012059B1012908D11178052905D16F -:1005500009201070506800685060002070BD6C6900 -:10056000062010226070E8686060686A606229692D -:10057000A06801F0C1FA1020A081A06820221030EC -:10058000A96801F0B9FAA0892022203080B2A081A8 -:10059000A1680844696801F0AFFAA08921462030BB -:1005A000A081012028703046BDE87040F1F77DBD84 -:1005B00070B50C46012009788EB01546062659B153 -:1005C000012934D0022905D12978042902D10A2031 -:1005D000107000200EB070BD606910236A4600786C -:1005E000C0F340008DF80000A0690078C0F340001F -:1005F0008DF80100E0680168CDF802108188ADF83F -:10060000061080798DF8080020690168CDF809107E -:100610008188ADF80D1080798DF80F006068059025 -:100620000AA80690A168FFF725FD01201DE02978A2 -:100630000429CFD1A06910236A4650F8011F009108 -:100640008088ADF80400606950F8011FCDF80610ED -:100650008088ADF80A0000200390606805900AA821 -:1006600006906968FFF706FD022020708DF8106083 -:10067000606A0990294604A8F1F700FDAAE700B5D1 -:100680000B788BB001204BB1012B05D111780429D7 -:1006900002D10B20107000200BB000BD4868019003 -:1006A00006A80290C86803680693406807908868A7 -:1006B00003680893406809900120087006208DF8AF -:1006C0000000486A059011466846F1F7D7FCE3E759 -:1006D00000B50B788BB0012043B1012BDCD1117830 -:1006E0000429D9D10C2010700020D5E7486801906A -:1006F00006A8029088680368069340680790002067 -:10070000089009900120087006208DF80000486AC2 -:10071000059011466846F1F7B1FCBDE700B50B78CE -:100720008BB0012043B1012BB6D111780429B3D18C -:100730000D2010700020AFE748680590CDF818D064 -:1007400088680088ADF80000C8680088ADF802002D -:1007500000200190029003900120087006208DF87F -:100760001000486A0990114604A8F1F787FC93E746 -:1007700030B403460C7801205CB1012C15D0022C5A -:1007800005D111780C2902D10E201070002030BC48 -:10079000704701200870C868042242704A684260AD -:1007A0000B4A8260921EC2600BE014780D2CEED1D1 -:1007B00002200870C86803244470526842608A6846 -:1007C0008260496A4162014630BC1846F1F76DBC4F -:1007D0006E2302002DE9F0410C4611490D68104AC4 -:1007E000104908321160A0F120012A2901D301200B -:1007F0000CE03E2810D040CC0B4F94E80E0007EBE5 -:100800008000241F50F8807C3046B84720600448A0 -:10081000001D0560BDE8F0812046E0F7E1FCF5E74A -:100820001005024001000001A423020010B5524847 -:1008300000F070FA00B1FFDF4F48401C00F06AFA88 -:10084000002800D0FFDF10BD2DE9F14F4B4ED6F848 -:1008500000B00127484800F065FADFF81C8128B98C -:100860005FF0000708F1010000F072FA444C002527 -:100870004FF0030901206060C4F80051C4F804512E -:10088000009931602060DFF8FCA018E0DAF8000081 -:10089000C00614D50E2000F064F8EFF3108010F0BD -:1008A000010072B600D00120C4F80493D4F80011FE -:1008B00019B9D4F8041101B920BF00B962B6D4F84F -:1008C000000118B9D4F804010028DFD0D4F80401DD -:1008D0000028CFD137B1C6F800B008F1010000F010 -:1008E00021FA11E008F1010000F01CFA0028B9D14A -:1008F000C4F80893C4F80451C4F800510E2000F065 -:1009000030F81D4800F024FA0020BDE8F88F2DE9EA -:10091000F0438DB00D46064600240DF110090DF18F -:10092000200817E004EB4407102255F8271068460A -:1009300001F0E2F805EB870710224846796801F0DC -:10094000DBF86846FFF780FF10224146B86801F0E7 -:10095000D3F8641CB442E5DB0DB00020BDE8F083A1 -:1009600072E700F01F02012191404009800000F170 -:10097000E020C0F8801270478F01002004E500409D -:1009800000E0004010ED00E0D848002101708170C7 -:10099000704770B5D64D01232B60D64B1C68002CD8 -:1009A000FCD0002407E00E6806601E68002EFCD014 -:1009B000001D091D641C9442F5D3002028601868AE -:1009C0000028FCD070BD70B5C84E0446CA4D3078C2 -:1009D000022800D0FFDFAC4200D3FFDF7169C748B7 -:1009E000012903D847F23052944201DD03224271BB -:1009F000491C7161291BC160C0497078F2F782FA05 -:100A0000002800D1FFDF70BD70B5B84C0D4661788D -:100A1000884200D0FFDFB84E082D4ED2DFE805F047 -:100A20004D0421304D4D4D3B2078022800D0FFDF92 -:100A300003202070A078022802D0012804D008E00A -:100A4000A06800F051FD04E004F1080007C8FFF7BA -:100A5000A0FF052020700020A070BDE87040F1F7D5 -:100A600012BFF2F705F801466068F2F712FDB042D6 -:100A700002D2616902290BD30320F2F7E4FF12E0EE -:100A8000F1F7F6FF01466068F2F703FDB042F3D2DA -:100A9000BDE8704097E7207802280AD0052806D0E4 -:100AA000FFDF04202070BDE8704000F014B9022080 -:100AB00000E00320F2F7C7FFF3E7FFDF70BD70B57A -:100AC0000546F1F7D5FF894C60602078012800D0F9 -:100AD000FFDF8A4901200870002008718D60042022 -:100AE00048718548C860022020706078F2F70AFAE1 -:100AF000002800D1FFDF70BD10B57C4CA07808B98C -:100B0000207808B1112010BD7D48F1F737FF6070E3 -:100B10006078202804D0012020700020606110BD82 -:100B2000032010BD0246010B0120B2F5003F02D2A6 -:100B3000884000F071BFB2F5802F03D22039884081 -:100B400000F072BFB2F5C02F03D24039884000F0E8 -:100B500074BFB2F5002F03D26039884000F076BF31 -:100B6000002070472DE9F041144600EB84070E4643 -:100B700005463F1F00F0CBFC4FF080510A695043FF -:100B800006EB8402121FB24201D2012200E00022D1 -:100B90001CB10969B4EB910F02D90920BDE8F081BD -:100BA00058498D4216D3AF4214D3854205D28742AD -:100BB00003D245EA0600800701D01020EEE78E42FE -:100BC00008D33AB92846FFF7ADFF18B93846FFF702 -:100BD000A9FF08B10F20E1E74B484C490068884263 -:100BE00005D0224631462846FFF7D3FE10E0FFF736 -:100BF00083FF0028D2D13D4801218560C0E903640C -:100C000081704FF4A97104FB01F01830FFF757FF12 -:100C10000020C3E770B54FF0805504462869394974 -:100C2000B1FBF0F084420AD300F071FCA04201D87D -:100C3000102070BD28696043FFF774FF08B10F20D2 -:100C400070BD314831490068884204D0286960434A -:100C500000F04AFC0CE0FFF74FFF0028F0D12969B3 -:100C6000224861438160022181702948FFF727FFF4 -:100C7000002070BD2349090BB1EB401F07D940424A -:100C800001EB4011202903D34FF0FF3070470021C2 -:100C900001208840401E704770B505460C46002074 -:100CA000FFF7E8FF28420ED10120FFF7E3FF2042C3 -:100CB00009D10220FFF7DEFF104204D10320FFF725 -:100CC000D9FF184201D00F2070BD21462846BDE84B -:100CD000704000F0C4BE10B5044C6078F1F7A9FE76 -:100CE00000B9FFDF00202070A07010BD940100202B -:100CF00004E5014000E40140105C0C00C412002037 -:100D0000090A020000300200B0000020BEBAFECA8C -:100D10007C5E0100002101700846704701460020FA -:100D200008707047EFF3108101F0010172B602788C -:100D3000012A01D0012200E000220123037001B941 -:100D400062B60AB1002070474FF400507047E9E7DF -:100D5000EFF3108111F0010F72B64FF00002027034 -:100D600000D162B600207047F2E700004C490968E4 -:100D70000160002070474A49086000207047012147 -:100D80008A0720B1012804D042F20400704791671D -:100D900000E0D1670020704742490120086042F21C -:100DA0000600704708B504233E4A1907103230B1D7 -:100DB000C1F80433106840F0010010600BE01068C7 -:100DC00020F001001060C1F808330020C1F80801CC -:100DD000354800680090002008BD011F0B2909D884 -:100DE000304910310A6822F01E0242EA40000860D1 -:100DF0000020704742F205007047000100F180407A -:100E0000C0F8041900207047000100F18040C0F8CC -:100E1000081900207047000100F18040D0F8000957 -:100E2000086000207047012801D9072070471F4A39 -:100E300052F8200002680A4302600020704701282F -:100E400001D907207047194A52F8200002688A43E6 -:100E5000026000207047012801D907207047134A1B -:100E600052F8200000680860002070470200104916 -:100E70004FF0000003D0012A01D0072070470A601C -:100E800070474FF080410020C1F808014FF0E0208A -:100E9000802180F800140121C0F800117047000083 -:100EA0000004004000050040080100404C240200FE -:100EB000780500406249634B0A6863499A420968B1 -:100EC00001D1C1F310010160002070475C495D4B06 -:100ED0000A685D49091D9A4201D1C0F310000860FB -:100EE000002070475649574B0A68574908319A42C3 -:100EF00001D1C0F3100008600020704730B5504B9E -:100F0000504D1C6842F20803AC4202D0142802D2B1 -:100F100003E0112801D3184630BDC3004B481844E4 -:100F2000C0F81015C0F81425002030BD4449454BC9 -:100F30000A6842F209019A4202D0062802D203E06E -:100F4000042801D308467047404A012142F8301076 -:100F5000002070473A493B4B0A6842F209019A4225 -:100F600002D0062802D203E0042801D308467047C5 -:100F7000364A012102EBC00041600020704770B585 -:100F80002F4A304E314C156842F2090304EB8002BF -:100F9000B54204D0062804D2C2F8001807E004289D -:100FA00001D3184670BDC1F31000C2F8000800203C -:100FB00070BD70B5224A234E244C156842F20903D5 -:100FC00004EB8002B54204D0062804D2D2F800080F -:100FD00007E0042801D3184670BDD2F80008C0F31A -:100FE00010000860002070BD174910B5083118487E -:100FF00008601120154A002102EBC003C3F8101548 -:10100000C3F81415401C1428F6D3002006E0042869 -:1010100004D302EB8003C3F8001807E002EB80035F -:10102000D3F80048C4F31004C3F80048401C062855 -:10103000EDD310BD04490648083108607047000030 -:10104000B0000020BEBAFECA00F5014000F0014029 -:101050000000FEFF7D4B1B6803B19847BFF34F8F25 -:101060007B4801687B4A01F4E06111430160BFF3F2 -:101070004F8FFEE710B5EFF3108010F0010F72B63E -:1010800001D0012400E0002400F0D6F850B1E0F7D0 -:1010900041F9F1F7BCFAF2F777FCE1F7C0FE6E49CF -:1010A0000020086004B962B6002010BD70B50C467F -:1010B0000646EFF3108010F0010F72B601D0012543 -:1010C00000E0002500F0B8F818B105B962B60820B4 -:1010D00070BDE0F79BF8E0F71FF9024600204309D6 -:1010E0009B0003F1E02300F01F01D3F80031CB4057 -:1010F000D9071BD0202803D222FA00F1C90722D138 -:1011000041B2002906DA01F00F0101F1E02191F866 -:10111000141D03E001F1E02191F8001449090829A8 -:1011200011D281B101290ED004290CD0401C6428B1 -:10113000D5D3E1F74BFE4849484808602046F3F70D -:101140008FF860B904E005B962B641F2010070BDE4 -:101150003E4804602EB13046F3F7CFF818B11024A2 -:1011600029E03F4E16E03078022802D94FF480542F -:1011700021E007240028707801D0E0B908E0D0B160 -:10118000202818D8B078212815D8012813D001E0DC -:10119000B07880B93349802081F8140DE0F7BCF8AD -:1011A0003146F2F7D7FBF1F7F1F900F0E3F93046F9 -:1011B000E0F782F8044605B962B61CB1FFF75AFFA2 -:1011C000204670BD002070BD10B5044600F034F814 -:1011D00000B101202070002010BD234908600020CC -:1011E000704770B50C4621490D682049204E0831E2 -:1011F0000E60102807D011280CD012280FD0132809 -:1012000011D0012013E0D4E90001FFF74FFF35466C -:1012100020600DE0FFF72EFF0025206008E0206829 -:10122000FFF7D2FF03E0104920680860002020602B -:101230000E48001D056070BD0748084900688842D7 -:1012400001D101207047002070470000AC01002050 -:101250000CED00E00400FA05B0000020BEBAFECAA2 -:10126000542402000BE000E00400002010050240BE -:101270000100000100B5764910F1080F08BFF82001 -:1012800024D014DC10F1280F08BFD8201ED010F194 -:10129000140F08BFEC2019D010F1100F08BFF02078 -:1012A00014D010F10C0F08BFF4200FD00CE010F197 -:1012B000040F08BFFC2009D0002818BF032805D060 -:1012C000042804BF086000BDFFDF00BD086000BD4A -:1012D00000B56049012808BF032004D0022816BFCA -:1012E000FFDF042000BD086000BD5A48016801F01E -:1012F0000F01032904BF01207047006800F00F00B0 -:10130000042804BF0220704700B5FFDF012000BDA4 -:101310005149002808BF086805D0012806BF0868A1 -:1013200040F0010070470860704770B5054601291C -:1013300014D0022A07BF49484FF47A7148484FF445 -:10134000C86144181846F4F759F820444FF47A71EC -:1013500000F27120B0FBF1F0281A70BD022A14BF10 -:101360004FF4C8604FF47A7049F608514418E9E721 -:1013700070B514460546012908BF49F6CA6605D06E -:10138000022B0CBF3748364800F1FA061046F4F736 -:1013900044F8012C0CBF4FF47A714FF4FA71711AB2 -:1013A00008444FF47A7100F28920B0FBF1F0281A5A -:1013B000801E70BD70B51546064601291AD0022B55 -:1013C00007BF26484FF47A7125484FF4C861441886 -:1013D0001046F4F722F8012D0CBF4FF47A714FF448 -:1013E000FA71611A08444FF47A716438B0FBF1F075 -:1013F000301A70BD022B14BF4FF4C8604FF47A70DE -:1014000049F608514418E3E770B505460C46164600 -:101410001046F3F7F3FF05EB4501C1EBC51100EBF7 -:10142000C100012C0CBF4FF47A714FF4FA714518CA -:101430002046F3F7F2FF281A4FF47A7100F60F6096 -:10144000B0FBF1F43046F3F7CDFF2044401D70BDF2 -:101450000C15004010150040501600406836020080 -:10146000A2240200043602002DE9F04184B088462F -:101470000746FEF70FFC05467E786A4601A94046FE -:10148000EFF748F804000ED0012D1EBF032004B072 -:10149000BDE8F08102AA40460199EEF73AFF0298B2 -:1014A000B0F803000AE0022D18D1042E16D3B7F8C5 -:1014B0000300BDF80020011D8A4206D3001D80B242 -:1014C000A119814238BF012004D104B04FF00000BF -:1014D000BDE8F0813CBF04B0BDE8F0814FF00200F0 -:1014E00004B0BDE8F08100000B4A022111600B49F5 -:1014F0000B68002BFCD0084B1B1D186008680028E7 -:10150000FCD00020106008680028FCD070474FF025 -:10151000805040697047000004E5014000E401404C -:1015200002000B464FF00000014620D0012A04D0F3 -:10153000022A04D0032A0DD103E0012002E0022098 -:1015400015E00320072B05D2DFE803F00406080AA4 -:101550000C0E100007207047012108E0022106E070 -:10156000032104E0042102E0052100E00621F1F757 -:1015700022BA0000FC4805218170002101704170F1 -:10158000C17081607047F9490A78012A06D0CA689B -:101590001044C860C8684038F1F748BF8A681044F2 -:1015A00088608868F7E710B5EF4CE078F1F741FA0A -:1015B00000B9FFDF0820F2F746FA0520A0700020EE -:1015C0002070607010BD002819D00378E849E94AFE -:1015D00013B1012B0ED011E00379012B00D06BB9B0 -:1015E00043790BB1012B09D18368643B8B4205D24F -:1015F000C0680EE00379012B02D00BB100207047C8 -:1016000043790BB1012BF9D1C368643B8B42F5D20E -:1016100080689042F2D8012070472DE9F0410446DD -:101620000227F1F72FFE006800B1FFDFCE4D012643 -:101630003CB12078B0B1012805D0022810D0032891 -:1016400013D02E710CE06068C82807D3F1F755FF5E -:1016500020B16068FFF797FF012703E0002701E052 -:1016600000F0CCF93846BDE8F08128780028F7D1A1 -:101670006068FFF7A8FF0028E3D06068DFF8EC821D -:10168000007828B3A878042800D0FFDF0020464661 -:1016900088F8000060680079C8B300203071606885 -:1016A0004079A8B30420707160688168E868F0F739 -:1016B000EAFEB0606068C0685230F0600320A87035 -:1016C000AA49E878F1F71EFC0028C9D1FFDFC7E777 -:1016D000404688F8006061680979D1B10021017144 -:1016E00061684979B9B104214171616889685231F1 -:1016F00081606168C968C160C0689B4C14346060D7 -:10170000F1F7B6F920606E700220A870A8E704E037 -:1017100005E00321E3E70321E6E70120BEE703201C -:10172000C1E72DE9F047904C8846E178884200D027 -:10173000FFDFDFF83492002501278C4E09F11409F0 -:10174000B8F1080F79D2DFE808F0040D2A557E843D -:101750009199A078032803D0A078022800D0FFDF59 -:10176000BDE8F087A078032803D0A078022800D035 -:10177000FFDF0420A0702571207800287AD1FFF7C0 -:1017800002FF3078012806D0B068E06000F07BF9F5 -:101790002061002062E0E078F1F7B0FAF5E7A07888 -:1017A000032803D0A078022800D0FFDF207800288B -:1017B0006FD1A078032816D0F1F75AF901464F46A9 -:1017C000D9F80000F1F765FE00280EDB7968814248 -:1017D0000BDB081AF0606549E078F1F793FB00280D -:1017E000BED1FFDFBCE7042029E00420F2F72BF98B -:1017F000A570B5E7A078032803D0A078022800D010 -:10180000FFDF207888BBA078032817D0F1F730F9E4 -:1018100001464F46D9F80000F1F73BFE0028E4DB13 -:1018200079688142E1DB081AF0605049E078F1F70D -:1018300069FB002894D1FFDF92E740E00520F2F732 -:1018400002F9A7708CE7A078042800D0FFDF0220FF -:1018500004E0A078042800D0FFDF0120A1688847B9 -:10186000FFF7DBFE054630E004E012E0A078042834 -:1018700000D0FFDFBDE8F04700F0C0B8A078042832 -:1018800005D0607810B1A078022800D0FFDF207862 -:1018900010B1BDE8F04786E6207920B10620F2F7C6 -:1018A000D2F82571CDE7607838B13049E078F1F7AA -:1018B00029FB00B9FFDF657052E70720BFE7FFDFB4 -:1018C0004EE73DB1012D03D0FFDF022DF9D147E7EF -:1018D0000420C3E70320C1E770B5050005D0224C02 -:1018E000A078052803D0112070BD102070BD2248BB -:1018F000F1F744F8E070E078202803D0A5600020DC -:10190000A07070BD032070BD174810B5017809B1F3 -:10191000112010BD817805290CD0817801290BD0C8 -:10192000817849B1012101708178012904D0807842 -:1019300010B103E00F2010BDFFF735FE002010BDF1 -:1019400070B5094E0446B07808B101280AD1ACB18F -:101950002046FFF738FE98B12078044D90B1B0785A -:1019600001282AD00F2070BDB0010020D412002021 -:101970003D860100FF1FA107231702001020F2E798 -:101980000720F0E701202870207990B1002028710D -:10199000607980B104206871A0685230A860E06866 -:1019A000E860E8681A4C6060F1F762F82060022095 -:1019B00016E00320EBE70320EDE7002028702079F4 -:1019C000A8B100202871607998B104206871A168DD -:1019D000F068F0F758FDA860E0685230E860032036 -:1019E000B0700C49F078F1F78DFA28B903E00320C4 -:1019F000E8E70320EAE7FFDF0020B4E7044810B57A -:101A00001438006900F037F8BDE81040F0F73BBF2C -:101A1000C4010020D41200201F490968014201D0EE -:101A200001207047002070471B49091D09680142C9 -:101A300001D0012070470020704717491031096814 -:101A4000014201D001207047002070471249143133 -:101A50000968014201D0012070470020704710B58D -:101A60000D4C2060201D01600B4810300260001DED -:101A70000360002010BD09490A6848F202139A4326 -:101A800002430A607047054A116848F2021301EAEE -:101A9000030099431160704700060040C8060240E9 -:101AA00040EA010310B59B070FD1042A0DD310C8DB -:101AB00008C9121F9C42F8D020BA19BA884201D92D -:101AC000012010BD4FF0FF3010BD1AB1D30703D075 -:101AD000521C07E0002010BD10F8013B11F8014B2B -:101AE0001B1B07D110F8013B11F8014B1B1B01D147 -:101AF000921EF1D1184610BD032A40F2308010F03A -:101B0000030C00F0158011F8013BBCF1020F624498 -:101B100098BF11F801CB00F8013B38BF11F8013B29 -:101B2000A2F1040298BF00F801CB38BF00F8013BD6 -:101B300011F0030300F02580083AC0F0088051F846 -:101B4000043B083A51F804CBA0E80810F5E7121D51 -:101B50005CBF51F8043B40F8043BAFF30080D20770 -:101B600024BF11F8013B11F801CB48BF11F8012B3C -:101B700024BF00F8013B00F801CB48BF00F8012B5F -:101B8000704710B5203AC0F00B80B1E81850203AE9 -:101B9000A0E81850B1E81850A0E81850BFF4F5AF0D -:101BA0005FEA027C24BFB1E81850A0E8185044BF97 -:101BB00018C918C0BDE810405FEA827C24BF51F804 -:101BC000043B40F8043B08BF7047D20728BF31F8F8 -:101BD000023B48BF11F8012B28BF20F8023B48BF49 -:101BE00000F8012B70474FF000020429C0F012806A -:101BF00010F0030C00F01B80CCF1040CBCF1020FC0 -:101C000018BF00F8012BA8BF20F8022BA1EB0C0194 -:101C100000F00DB85FEAC17C24BF00F8012B00F88A -:101C2000012B48BF00F8012B70474FF0000200B5B0 -:101C3000134694469646203922BFA0E80C50A0E8EF -:101C40000C50B1F12001BFF4F7AF090728BFA0E89D -:101C50000C5048BF0CC05DF804EB890028BF40F869 -:101C6000042B08BF704748BF20F8022B11F0804FAB -:101C700018BF00F8012B704770477047704700008D -:101C8000FEDF04207146084219D10699124A91429A -:101C900015DC069902394878DF2810D10878FE282B -:101CA00007D0FF280BD14FF001004FF000020B4B83 -:101CB000184741F201000099019A084B1847084B58 -:101CC000002B02D01B68DB6818474FF0FF307146CD -:101CD0004FF00002014B184700300200551002007F -:101CE00004000020184819497047FFF7FBFFDFF791 -:101CF00065FA00BD4FF4805015490968884203D148 -:101D0000144A13605B68184700BD000020BFFDE760 -:101D10004FF480500E490968884210D10E4B186864 -:101D20004FF0FF318842F1D080F308884FF0202136 -:101D3000884204DD0948026802210A43026008481B -:101D4000804708488047FFDFE8120020E8120020A3 -:101D500000000020040000200030020024050040A4 -:101D600039430100F51C020004207146084202D0EC -:101D7000EFF3098101E0EFF3088188690238007808 -:101D8000102813DB20280FDB2B280BDB0A4A1268F4 -:101D90000A4B9A4203D1602804DB094A104702200B -:101DA00008607047074A1047074A1047074A1268F9 -:101DB0002C32126810470000B0000020BEBAFECAE4 -:101DC0001D130000D5070200E311020004000020EB -:101DD0000D4B0E4908470E4B0C4908470D4B0B495C -:101DE00008470D4B094908470C4B084908470C4B5D -:101DF000064908470B4B054908470B4B0349084761 -:101E00000A4B024908470000F9BA0000092F0000F8 -:101E1000812C00001D2B0000AB2A0000232D0000A8 -:101E2000391300006728000029BD0000C911000017 -:101E300000210160818070470021016041600172D2 -:101E400070470A6802600B7903717047599500006A -:101E50001B970000779800009B980000D598000021 -:101E6000099900004399000081990000D39900006E -:101E700031960000A7120000A7120000C140000028 -:101E80000541000025410000E1410000274300001A -:101E90000144000031440000F5440000153D0000FD -:101EA000274700001948000039480000DD150000F0 -:101EB00001160000311500008515000033160000E2 -:101EC000C716000003600000B561000073650000E4 -:101ED000896600000D67000087670000F967000051 -:101EE00015690000E3690000616A000053480000C2 -:101EF0005948000063480000D73C00001F4900001B -:101F0000A13C00005F4A0000B74A00001F4B0000E0 -:101F1000A7120000A7120000A7120000A7240000CB -:101F20002D2500004925000065250000F32600004E -:101F30008F25000099250000DB250000FD2500000D -:101F4000D92600001B270000A7120000CF82000046 -:101F5000F7820000F98200003383000061830000F3 -:101F60004F840000DB840000EF8400003D8500000A -:101F70002D860000D1870000F9880000D172000092 -:101F800011890000A7120000A712000049B4000048 -:101F9000B3B5000007B6000073B6000023B7000019 -:101FA00051000000000000000000000000000000E0 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000003E000000D3 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF0000000000000000000500000000000000091 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000100110013A0200001A02000432 -:102030000506000013900000F38F0000FFFFFFFF74 -:102040000000FFFF3BAC00003D39000041200000D4 -:102050001B730000EB8D0000000000000000020078 -:10206000000000000002000000000000000100006D -:10207000000000006F8000004F800000BD80000065 -:1020800029240000EB2300000B240000A7A7000078 -:10209000D3A70000DBA9000021590000DD8000006B -:1020A000000000000D810000772400000000000007 -:1020B0000000000000000000BDA8000000000000BB -:1020C000B359000000000000000000000000000004 -:1020D0000000000000000000000000000000000000 -:1020E000000000000000000000000000D5E5000036 -:1020F00059E60000000000000000000000000000A1 -:1021000059E700000000000000000000000000008F -:1021100049F800000000000000000000000000007E -:1021200005E900005DF4000000000000DDF400009F -:1021300051F500000000000037EE0000D5EE000071 -:102140000000000017F50000D1EF0000C9F1000009 -:102150003DF2000041F30000A5EA0000000000008D -:1021600000000000BFE90000000000001FE80000C0 -:1021700095E70000BDF300007BF60000E9F60000E3 -:1021800000000000A7E60000D7E6000007E6000018 -:102190000000000021E70000000000000000000037 -:1021A000000000004BF700000000000000000000ED -:1021B000000000000000000000000000EFEC000044 -:1021C000000000000000000000000000C3E8000064 -:1021D000C1E700008BE800000000000053E80000A9 -:1021E0000000000000000000B3F7000097F80000B6 -:1021F0009BFA000017F900003DE9000051FA0000C9 -:10220000000000004FEB000021EC000061F900002D -:10221000ABF9000007F80000E5F90000F1ED00005F -:1022200093560000935600009D400000E7AA00006E -:102230009F750000531F000087AA01004BC50100D5 -:10224000D9560000D9560000BF40000049AB00003D -:1022500023760000C51F0000B5AA01005FC501007C -:10226000D001D001400038005C0024004001F001A2 -:1022700001000000010000000001020304120F1021 -:102280001100000013000000B10502007F060200EB -:10229000D10602001D07020071070200AB00020018 -:1022A000CD01020035020200590402003B05020084 -:1022B000750D01008B1E01000000000006000000EB -:1022C0000A0000003200000073000000B4000000AB -:1022D000B197010045850100235F010077DE010011 -:1022E000F772010077DE01007D5F010005E001006B -:1022F000876B010005E001007B5E010093DF0100B8 -:10230000C971010093DF01004D630100FFE201008C -:102310007F730100FFE20100555555D6BE898E003E -:102320000000A606340DC21300004A03EE05920811 -:10233000000096041409920D555555252627D6BE42 -:10234000898EF401FA00960064004B0032001E00F2 -:1023500014000A00050002000100000025410000F1 -:1023600000000000AAAED7AB15412010000003000A -:10237000656C7462000000000000000000000000B6 -:1023800000000000870000000000000000000000C6 -:1023900000000000BE83605ADB0B376038A5F5AA49 -:1023A0009183886CB50E0200CD0E0200E50E02008E -:1023B000FD0E02002D0F0200550F02007F0F0200DC -:1023C000B30F0200150C0200650B0200990C02000D -:1023D000150D0200250D0200510D0200A33B010066 -:1023E000AB3B0100B93B01007F0D0200990D0200DB -:1023F0006D0D0200770D0200A50D0200DB0D02003D -:10240000FB0D0200090E0200170E0200270E02004B -:102410003F0E0200570E02006D0E02000000000089 -:10242000F7B800004DB9000063B9000021150200A3 -:10243000490802000F090200D91802000919020018 -:1024400041190200E93901000D3E01001C05004060 -:10245000200500400010020078240200080000203F -:10246000C401000044110000A8240200CC01002097 -:102470001C110000A01100000118136813024C2069 -:102480001A010222782720FB349B5F801280021EF3 -:1024900010139F0A1B205C041AE2040128237F0109 -:0824A00002A329091DFB013113 -:00000001FF diff --git a/ports/nrf/boards/feather_nrf52832/README.md b/ports/nrf/boards/feather_nrf52832/README.md deleted file mode 100644 index ef910509a3591..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/README.md +++ /dev/null @@ -1,192 +0,0 @@ -# Setup - -## Installing CircuitPython submodules - -Before you can build, you will need to run the following commands once, which -will install the submodules that are part of the CircuitPython ecosystem, and -build the `mpy-cross` tool: - -``` -$ cd circuitpython -$ git submodule update --init -$ make -C mpy-cross -``` - -You then need to download the SD and Nordic SDK files via: - -> This script relies on `wget`, which must be available from the command line. - -``` -$ cd ports/nrf -$ ./bluetooth/download_ble_stack.sh -``` - -## Installing `adafruit-nrfutil` - -The Adafruit Bluefruit nRF52 Feather ships with a serial and OTA BLE bootloader -that can be used to flash firmware images over a simple serial connection, -using the on-board USB serial converter. - -run following command to install [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) from PyPi - - $ pip3 install --user adafruit-nrfutil - -# Building and flashing firmware images - -## Building CircuitPython binaries - -#### REPL over UART (default settings) - -To build a CircuitPython binary with default settings for the -`feather_nrf52832` target enter: - -> **NOTE:** `BOARD=feather_nrf52832` is the default option and isn't stricly required. - -``` -$ make BOARD=feather_nrf52832 V=1 -``` - -#### REPL over BLE UART (AKA 'NUS') - -To build a CircuitPython binary that uses the Nordic UART Service (AKA 'NUS' or -'BLEUART'), modify `/ports/nrf/bluetooth_conf.h` to have the following macro -set to `1` in the `#elif (BLUETOOTH_SD == 132)` section: - -``` -#define MICROPY_PY_BLE_NUS (1) -``` - -... then build as normal, via: - -``` -$ make BOARD=feather52832 V=1 -``` - -You can then connect over BLE UART using an application like Bluefruit LE -Connect, available for Android, iOS and OS X, or any other application that -supports the NUS service and allows you to send the corrent EOL sequence. - -## Flashing binaries with `adafruit-nrfutil` - -### 1. **Update bootloader** to single-bank version - -The Adafruit nRF52 Feather ships, by default, with a **dual-bank** bootloader -that cuts the available flash memory in half in exchange for safer -OTA updates. - -Due to the size of CircuitPython, we must migrate this bootloader to a -**single-bank** version, doubling the amount of flash memory available to us. - -> These commands only need to be run once and will update the SoftDevice and -bootloader from the dual-bank version that ships on Arduino-based Adafruit -Feather52 boards to a single-bank CircuitPython compatible version: - -Firstly clone the [Adafruit_nRF52_Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader.git) and enter its directory - - $ git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader.git - $ cd Adafruit_nRF52_Bootloader - -#### S132 v2.0.1 single-bank (recommended): - -To flash bootloader with s132 v2.0.1 - -``` -$ make BOARD=feather_nrf52832 VERSION=2.0.1 SERIAL=/dev/tty.SLAB_USBtoUART dfu-flash -``` - -#### S132 v5.0.0 (BLE5, experimental): - -To flash bootloader with s132 v5.0.0 - -``` -$ make BOARD=feather52832 VERSION=5.0.0 SERIAL=/dev/tty.SLAB_USBtoUART dfu-flash -``` - -### 2. Generate and flash a CircuitPython DFU .zip package over serial - -The following command will package and flash the CircuitPython binary using the -appropriate bootloader mentionned above. - -This command assumes you have already built a valid circuitpython -image, as described earlier in this readme. - -> The name of the serial port target will vary, depending on your OS. - -``` -$ make BOARD=feather_nrf52832 SERIAL=/dev/tty.SLAB_USBtoUART dfu-gen dfu-flash -``` - -By default, CircuitPython will build with **BLE** support enabled using -`SD=s132` and the `SOFTDEV_VERSION=2.0.1`. If you wish to specify a different -SD family or version you can enter the optional fields as shown below: - -``` -$ make BOARD=feather_nrf52832 SERIAL=/dev/tty.SLAB_USBtoUART SD=s132 SOFTDEV_VERSION=5.0.0 dfu-gen dfu-flash -``` - -## Working with CircuitPython - -### Running local files with `ampy` - -[ampy](https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy) -is a command-line tool that can be used with the nRF52 Feather to transfer -local python files to the nRF52 for execution, rather than having to enter -the REPL manually, enter paste mode, and paste the code yourself. - -> **IMPORTANT**: You must have `ampy` version **1.0.3** or higher to use `ampy` - with the nRF52. The bootloader on the nRF52 requires a delay between the - HW reset, and the moment when the command sequance is sent to enter raw - mode. This required `-d/--delay` flag was added in release 1.0.3. - - -Save the following file as `test.py`: - -``` -import board -import digitalio -import time - -led = digitalio.DigitalInOut(board.LED2) -led.direction = digitalio.Direction.OUTPUT - -while True: - led.value = True - time.sleep(0.5) - led.value = False - time.sleep(0.5) -``` - -Then run the saved file via ampy, updating the serial port as required: - -``` -$ ampy -p /dev/tty.SLAB_USBtoUART -d 1.5 run test.py -``` - -This should give you blinky at 1 Hz on LED2 (the blue LED on the nRF52 Feather). - -### Uploading files and libraries with `ampy` - -To upload Python files or pre-compiled CircuitPython libraries to the `lib` folder, -run the following commands: - -> In this example **i2c_device.py** is used, which is part of - [Adafruit_CircuitPython_BusDevice](https://github.com/adafruit/Adafruit_CircuitPython_BusDevice) - -``` -$ ampy -p /dev/tty.SLAB_USBtoUART -d 1.5 put i2c_device.py lib/i2c_device.py -``` - -To verify that the file was uploaded correctly, you can check the contents of -the `lib` folder with: - -``` -$ ampy -p /dev/tty.SLAB_USBtoUART -d 1.5 ls /lib -i2c_device.py -``` - -### Suggested libraries - -The following libraries should be installed as a minimum on most new boards: - -- [Adafruit_CircuitPython_BusDevice](https://github.com/adafruit/Adafruit_CircuitPython_BusDevice) -- [Adafruit_CircuitPython_Register](https://github.com/adafruit/Adafruit_CircuitPython_Register/tree/master) diff --git a/ports/nrf/boards/feather_nrf52832/board.c b/ports/nrf/boards/feather_nrf52832/board.c deleted file mode 100644 index 29ee2fdcdb524..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/board.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 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 -#include - -#include "nrf.h" - -#include "boards/board.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} diff --git a/ports/nrf/boards/feather_nrf52832/custom_nrf52832_dfu_app_2.0.1.ld b/ports/nrf/boards/feather_nrf52832/custom_nrf52832_dfu_app_2.0.1.ld deleted file mode 100644 index a1c128e377e2d..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/custom_nrf52832_dfu_app_2.0.1.ld +++ /dev/null @@ -1,44 +0,0 @@ -/* - GNU linker script for NRF52 w/ s132 2.0.1 SoftDevice - - MEMORY MAP - ------------------------------------------------------------------------ - START ADDR END ADDR SIZE DESCRIPTION - ---------- ---------- ------- ----------------------------------------- - 0x0007F000..0x0007FFFF ( 4KB) Bootloader Settings - 0x0007E000..0x0007EFFF ( 4KB) Master Boot Record Params - 0x00074000..0x0007DFFF ( 40KB) Serial + OTA Bootloader - - 0x00073000..0x00073FFF ( 4KB ) Private Config Data (Bonding, Keys, etc.) - 0x00072000..0x00072FFF ( 4KB ) User NVM data - 0x00059000..0x00071FFF (100KB) User Filesystem - - 0x0001C000..0x00058FFF (244KB) Application Code - 0x00001000..0x0001BFFF (108KB) SoftDevice - 0x00000000..0x00000FFF (4KB) Master Boot Record -*/ - -/* Specify the memory areas (S132 2.0.1) */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */ - FLASH_ISR (rx) : ORIGIN = 0x0001c000, LENGTH = 0x001000 /* sector 0, 4 KiB */ - FLASH_TEXT (rx) : ORIGIN = 0x0001d000, LENGTH = 0x03C000 /* APP - ISR, 240 KiB */ - FLASH_FATFS (r) : ORIGIN = 0x00059000, LENGTH = 0x019000 /* File system 100KB KB */ - RAM (xrw) : ORIGIN = 0x20003000, LENGTH = 0x0D000 /* 52 KiB, give 8KiB headroom for softdevice */ -} - -/* produce a link error if there is not this amount of RAM for these sections */ -_minimum_stack_size = 2K; -_minimum_heap_size = 0 /*16K Circuit Python use static variable for HEAP */; - -/* top end of the stack */ - -/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/ -_estack = ORIGIN(RAM) + LENGTH(RAM); - -/* RAM extents for the garbage collector */ -_ram_end = ORIGIN(RAM) + LENGTH(RAM); -_heap_end = 0x20007000; /* tunable */ - -INCLUDE "boards/common.ld" diff --git a/ports/nrf/boards/feather_nrf52832/custom_nrf52832_dfu_app_5.0.0.ld b/ports/nrf/boards/feather_nrf52832/custom_nrf52832_dfu_app_5.0.0.ld deleted file mode 100644 index f9209bf3d1884..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/custom_nrf52832_dfu_app_5.0.0.ld +++ /dev/null @@ -1,44 +0,0 @@ -/* - GNU linker script for NRF52 w/ s132 5.0.0 SoftDevice - - MEMORY MAP - ------------------------------------------------------------------------ - START ADDR END ADDR SIZE DESCRIPTION - ---------- ---------- ------- ----------------------------------------- - 0x0007F000..0x0007FFFF ( 4KB) Bootloader Settings - 0x0007E000..0x0007EFFF ( 4KB) Master Boot Record Params - 0x00074000..0x0007DFFF ( 40KB) Serial + OTA Bootloader - - 0x00073000..0x00073FFF ( 4KB ) Private Config Data (Bonding, Keys, etc.) - 0x00072000..0x00072FFF ( 4KB ) User NVM data - 0x00059000..0x00071FFF ( 100KB) User Filesystem - - 0x00023000..0x00058FFF (216KB) Application Code - 0x00001000..0x00022FFF (136KB) SoftDevice - 0x00000000..0x00000FFF (4KB) Master Boot Record -*/ - -/* Specify the memory areas (S132 5.0.0) */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */ - FLASH_ISR (rx) : ORIGIN = 0x00023000, LENGTH = 0x001000 /* sector 0, 4 KiB */ - FLASH_TEXT (rx) : ORIGIN = 0x00024000, LENGTH = 0x036000 /* APP - ISR, 216 KiB */ - FLASH_FATFS (r) : ORIGIN = 0x00059000, LENGTH = 0x019000 /* File system 100KB KB */ - RAM (xrw) : ORIGIN = 0x200039c0, LENGTH = 0x0c640 /* 49.5 KiB, give 8KiB headroom for softdevice */ -} - -/* produce a link error if there is not this amount of RAM for these sections */ -_minimum_stack_size = 2K; -_minimum_heap_size = 0 /*16K Circuit Python use static variable for HEAP */; - -/* top end of the stack */ - -/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/ -_estack = ORIGIN(RAM) + LENGTH(RAM); - -/* RAM extents for the garbage collector */ -_ram_end = ORIGIN(RAM) + LENGTH(RAM); -_heap_end = 0x20007000; /* tunable */ - -INCLUDE "boards/common.ld" diff --git a/ports/nrf/boards/feather_nrf52832/examples/ble_scan.py b/ports/nrf/boards/feather_nrf52832/examples/ble_scan.py deleted file mode 100644 index 9cacbe6f42872..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/examples/ble_scan.py +++ /dev/null @@ -1,26 +0,0 @@ -from ubluepy import Scanner, constants - -def display_scan_results(scan_entries): - for e in scan_entries: - print("ADDR: ", e.addr()) - print("TYPE: ", e.addr_type()) - print("RSSI: ", e.rssi()) - - # Parse the contents of the advertising packet - scan = e.getScanData() - if scan: - for s in scan: - # Convert byte array to hex format string - hex = ' '.join('0x%02X' % b for b in s[2]) - # Display enum value and hex string together - print('\t{}: {}'.format(s[1], hex)) - - # Line break between record sets - print("") - -# Scan 1s for advertising devices in range -s = Scanner() -scan_res = s.scan(1000) - -# Display the scan results -display_scan_results(scan_res) diff --git a/ports/nrf/boards/feather_nrf52832/examples/blinky.py b/ports/nrf/boards/feather_nrf52832/examples/blinky.py deleted file mode 100644 index 29cca26d04038..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/examples/blinky.py +++ /dev/null @@ -1,12 +0,0 @@ -import board -import digitalio -import time - -led = digitalio.DigitalInOut(board.LED2) -led.direction = digitalio.Direction.OUTPUT - -while True: - led.value = True - time.sleep(0.5) - led.value = False - time.sleep(0.5) diff --git a/ports/nrf/boards/feather_nrf52832/examples/i2c_scan.py b/ports/nrf/boards/feather_nrf52832/examples/i2c_scan.py deleted file mode 100644 index 8e3ef557d136b..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/examples/i2c_scan.py +++ /dev/null @@ -1,20 +0,0 @@ -import board -import busio - -i2c = busio.I2C(board.SCL, board.SDA) -count = 0 - -# Wait for I2C lock -while not i2c.try_lock(): - pass - -# Scan for devices on the I2C bus -print("Scanning I2C bus") -for x in i2c.scan(): - print(hex(x)) - count += 1 - -print("%d device(s) found on I2C bus" % count) - -# Release the I2C bus -i2c.unlock() diff --git a/ports/nrf/boards/feather_nrf52832/examples/pulseio.py b/ports/nrf/boards/feather_nrf52832/examples/pulseio.py deleted file mode 100644 index cdbe16addd065..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/examples/pulseio.py +++ /dev/null @@ -1,25 +0,0 @@ -import time -from board import * -from pulseio import * - -# Setup BLUE and RED LEDs as PWM output (default frequency is 500 Hz) -ledb = PWMOut(LED2) -ledr = PWMOut(LED1) - -# Set the BLUE LED to have a duty cycle of 5000 (out of 65535, so ~7.5%) -ledb.duty_cycle = 5000 - -# Setup pin A0 as a standard PWM out @ 50% to test on the oscilloscope. -# You should see a 50% duty cycle waveform at ~500Hz on the scope when you -# connect a probe to pin A0 -a0 = PWMOut(A0) -a0.duty_cycle = int(65535/2) - -# Constantly pulse the RED LED -while True: - for i in range(100): - ledr.duty_cycle = int(i / 100 * 65535) - time.sleep(0.01) - for i in range(100, -1, -1): - ledr.duty_cycle = int(i / 100 * 65535) - time.sleep(0.01) diff --git a/ports/nrf/boards/feather_nrf52832/mpconfigboard.h b/ports/nrf/boards/feather_nrf52832/mpconfigboard.h deleted file mode 100644 index 4959e1ca95eb2..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/mpconfigboard.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 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. - */ - -#define MICROPY_HW_BOARD_NAME "Bluefruit nRF52 Feather" -#define MICROPY_HW_MCU_NAME "nRF52832" -#define MICROPY_PY_SYS_PLATFORM "nRF52" - -#define MICROPY_HW_LED_STATUS (&pin_P0_17) - -#define MICROPY_HW_UART_RX NRF_GPIO_PIN_MAP(0, 8) -#define MICROPY_HW_UART_TX NRF_GPIO_PIN_MAP(0, 6) - -#define PORT_HEAP_SIZE (32 * 1024) -#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 - -#define DEFAULT_I2C_BUS_SCL (&pin_P0_26) -#define DEFAULT_I2C_BUS_SDA (&pin_P0_25) - -#define DEFAULT_SPI_BUS_SCK (&pin_P0_12) -#define DEFAULT_SPI_BUS_MOSI (&pin_P0_13) -#define DEFAULT_SPI_BUS_MISO (&pin_P0_14) - -#define DEFAULT_UART_BUS_RX (&pin_P0_08) -#define DEFAULT_UART_BUS_TX (&pin_P0_06) diff --git a/ports/nrf/boards/feather_nrf52832/mpconfigboard.mk b/ports/nrf/boards/feather_nrf52832/mpconfigboard.mk deleted file mode 100644 index 5b1f6e939c854..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/mpconfigboard.mk +++ /dev/null @@ -1,13 +0,0 @@ -MCU_SERIES = m4 -MCU_VARIANT = nrf52 -# Historical: nrf52 means nrf52832 -MCU_SUB_VARIANT = nrf52 -MCU_CHIP = nrf52832 -SD ?= s132 -SOFTDEV_VERSION ?= 2.0.1 - -LD_FILE = boards/feather_nrf52832/custom_nrf52832_dfu_app_$(SOFTDEV_VERSION).ld -BOOT_FILE = boards/feather_nrf52832/bootloader/feather52_bootloader_$(SOFTDEV_VERSION)_s132_single - -BOOT_SETTING_ADDR = 0x7F000 -NRF_DEFINES += -DNRF52832_XXAA -DNRF52832 diff --git a/ports/nrf/boards/feather_nrf52832/pins.c b/ports/nrf/boards/feather_nrf52832/pins.c deleted file mode 100644 index 48c57defb2d47..0000000000000 --- a/ports/nrf/boards/feather_nrf52832/pins.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "shared-bindings/board/__init__.h" - -#include "board_busses.h" - -STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_05) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_28) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, - - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_12) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_14) }, - - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, - - { MP_ROM_QSTR(MP_QSTR_DFU), MP_ROM_PTR(&pin_P0_20) }, - - { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, - { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, - - { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_P0_27) }, - - { MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, - - { MP_ROM_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_31) }, - - { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_07) }, - { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_11) }, - { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_P0_15) }, - { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_P0_16) }, - - { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P0_17) }, - - { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_P0_19) }, - - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_26) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_25) }, -}; - -MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/nrf52832_512k_64k.ld b/ports/nrf/boards/nrf52832_512k_64k.ld deleted file mode 100644 index 699811ce866a1..0000000000000 --- a/ports/nrf/boards/nrf52832_512k_64k.ld +++ /dev/null @@ -1,28 +0,0 @@ -/* - GNU linker script for NRF52832 blank w/ no SoftDevice -*/ - -/* Specify the memory areas */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */ - FLASH_ISR (rx) : ORIGIN = 0x00000000, LENGTH = 0x001000 /* sector 0, 4 KiB */ - FLASH_TEXT (rx) : ORIGIN = 0x00001000, LENGTH = 0x066000 /* 408 KiB */ - FLASH_FATFS (r) : ORIGIN = 0x00067000, LENGTH = 0x019000 /* File system 100KB */ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x010000 /* 64 KiB */ -} - -/* produce a link error if there is not this amount of RAM for these sections */ -_minimum_stack_size = 2K; -_minimum_heap_size = 0; - -/* top end of the stack */ - -/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/ -_estack = ORIGIN(RAM) + LENGTH(RAM); - -/* RAM extents for the garbage collector */ -_ram_end = ORIGIN(RAM) + LENGTH(RAM); -_heap_end = 0x20008000; /* tunable */ - -INCLUDE "boards/common.ld" diff --git a/ports/nrf/boards/nrf52832_512k_64k_s132_2.0.1.ld b/ports/nrf/boards/nrf52832_512k_64k_s132_2.0.1.ld deleted file mode 100644 index dbff5f987f314..0000000000000 --- a/ports/nrf/boards/nrf52832_512k_64k_s132_2.0.1.ld +++ /dev/null @@ -1,28 +0,0 @@ -/* - GNU linker script for NRF52 w/ s132 2.0.1 SoftDevice -*/ - -/* Specify the memory areas */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */ - FLASH_ISR (rx) : ORIGIN = 0x0001c000, LENGTH = 0x001000 /* sector 0, 4 KiB */ - FLASH_TEXT (rx) : ORIGIN = 0x0001d000, LENGTH = 0x04A000 /* 296 KiB */ - FLASH_FATFS (r) : ORIGIN = 0x00067000, LENGTH = 0x019000 /* File system 100KB */ - RAM (xrw) : ORIGIN = 0x200039c0, LENGTH = 0x0c640 /* 49.5 KiB, give 8KiB headroom for softdevice */ -} - -/* produce a link error if there is not this amount of RAM for these sections */ -_minimum_stack_size = 2K; -_minimum_heap_size = 0; - -/* top end of the stack */ - -/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/ -_estack = ORIGIN(RAM) + LENGTH(RAM); - -/* RAM extents for the garbage collector */ -_ram_end = ORIGIN(RAM) + LENGTH(RAM); -_heap_end = 0x20007000; /* tunable */ - -INCLUDE "boards/common.ld" diff --git a/ports/nrf/boards/nrf52832_512k_64k_s132_5.0.0.ld b/ports/nrf/boards/nrf52832_512k_64k_s132_5.0.0.ld deleted file mode 100644 index 6d5fe63c9124f..0000000000000 --- a/ports/nrf/boards/nrf52832_512k_64k_s132_5.0.0.ld +++ /dev/null @@ -1,28 +0,0 @@ -/* - GNU linker script for NRF52 w/ s132 2.0.1 SoftDevice -*/ - -/* Specify the memory areas */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */ - FLASH_ISR (rx) : ORIGIN = 0x00023000, LENGTH = 0x001000 /* sector 0, 4 KiB */ - FLASH_TEXT (rx) : ORIGIN = 0x00024000, LENGTH = 0x043000 /* 268 KiB */ - FLASH_FATFS (r) : ORIGIN = 0x00067000, LENGTH = 0x019000 /* File system 100KB */ - RAM (xrw) : ORIGIN = 0x200039c0, LENGTH = 0x0c640 /* 49.5 KiB, give 8KiB headroom for softdevice */ -} - -/* produce a link error if there is not this amount of RAM for these sections */ -_minimum_stack_size = 2K; -_minimum_heap_size = 0; - -/* top end of the stack */ - -/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/ -_estack = ORIGIN(RAM) + LENGTH(RAM); - -/* RAM extents for the garbage collector */ -_ram_end = ORIGIN(RAM) + LENGTH(RAM); -_heap_end = 0x20007000; /* tunable */ - -INCLUDE "boards/common.ld" diff --git a/ports/nrf/boards/pca10040/board.c b/ports/nrf/boards/pca10040/board.c deleted file mode 100644 index f1a49a74a7d27..0000000000000 --- a/ports/nrf/boards/pca10040/board.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 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 -#include - -#include "nrf.h" - -#include "boards/board.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} diff --git a/ports/nrf/boards/pca10040/mpconfigboard.h b/ports/nrf/boards/pca10040/mpconfigboard.h deleted file mode 100644 index 3961028325ad5..0000000000000 --- a/ports/nrf/boards/pca10040/mpconfigboard.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Glenn Ruben Bakke - * 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. - */ - -#define MICROPY_HW_BOARD_NAME "PCA10040" -#define MICROPY_HW_MCU_NAME "nRF52832" -#define MICROPY_PY_SYS_PLATFORM "nRF52-DK" - -#define MICROPY_HW_LED_STATUS (&pin_P0_17) - -#define MICROPY_HW_UART_RX NRF_GPIO_PIN_MAP(0, 8) -#define MICROPY_HW_UART_TX NRF_GPIO_PIN_MAP(0, 6) -#define MICROPY_HW_UART_HWFC (0) - -#define PORT_HEAP_SIZE (32 * 1024) -#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 diff --git a/ports/nrf/boards/pca10040/mpconfigboard.mk b/ports/nrf/boards/pca10040/mpconfigboard.mk deleted file mode 100644 index ad11b4f7c7bc7..0000000000000 --- a/ports/nrf/boards/pca10040/mpconfigboard.mk +++ /dev/null @@ -1,15 +0,0 @@ -MCU_SERIES = m4 -MCU_VARIANT = nrf52 -# Historical: nrf52 means nrf52832 -MCU_SUB_VARIANT = nrf52 -MCU_CHIP = nrf52832 -SD ?= s132 -SOFTDEV_VERSION ?= 5.0.0 - -ifeq ($(SD),) - LD_FILE = boards/nrf52832_512k_64k.ld -else - LD_FILE = boards/nrf52832_512k_64k_s132_$(SOFTDEV_VERSION).ld -endif - -NRF_DEFINES += -DNRF52832_XXAA -DNRF52832 diff --git a/ports/nrf/boards/pca10040/pins.c b/ports/nrf/boards/pca10040/pins.c deleted file mode 100644 index 95acd8ffdf869..0000000000000 --- a/ports/nrf/boards/pca10040/pins.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "shared-bindings/board/__init__.h" - -#include "board_busses.h" - -STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, - { MP_ROM_QSTR(MP_QSTR_P0_01), MP_ROM_PTR(&pin_P0_01) }, - { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, - { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, - { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, - { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, - { MP_ROM_QSTR(MP_QSTR_P0_07), MP_ROM_PTR(&pin_P0_07) }, - { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, - { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, - { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, - { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, - { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, - { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, - { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, - { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, - { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, - { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, - { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_17) }, - { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, - { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_P0_18) }, - { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, - { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_P0_19) }, - { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, - { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_P0_20) }, - { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, - { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, - { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, - { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, - { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, - { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, - { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, - { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, - { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, - { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, -}; - -MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/common-hal/board/__init__.c b/ports/nrf/common-hal/board/__init__.c index 350f2eea5e6f4..880033ed67964 100644 --- a/ports/nrf/common-hal/board/__init__.c +++ b/ports/nrf/common-hal/board/__init__.c @@ -23,6 +23,3 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - -// Pins aren't actually defined here. They are in the board specific directory -// such as boards/feather_nrf52832/pins.csv diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c index c9da436b8ae11..76bc170e8003c 100644 --- a/ports/nrf/common-hal/neopixel_write/__init__.c +++ b/ports/nrf/common-hal/neopixel_write/__init__.c @@ -65,7 +65,7 @@ // // If there is no device available an alternative cycle-counter // implementation is tried. -// The nRF52832 runs with a fixed clock of 64Mhz. The alternative +// The nRF52840 runs with a fixed clock of 64Mhz. The alternative // implementation is the same as the one used for the Teensy 3.0/1/2 but // with the Nordic SDK HAL & registers syntax. // The number of cycles was hand picked and is guaranteed to be 100% diff --git a/ports/nrf/peripherals/nrf/nrf52832/pins.c b/ports/nrf/peripherals/nrf/nrf52832/pins.c deleted file mode 100644 index fdfa766ec8c5f..0000000000000 --- a/ports/nrf/peripherals/nrf/nrf52832/pins.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ - -// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure -// that all necessary includes are already included. - -#include "py/obj.h" -#include "py/mphal.h" -#include "nrf/pins.h" - -const mcu_pin_obj_t pin_P0_00 = PIN(P0_00, 0, 0, 0); -const mcu_pin_obj_t pin_P0_01 = PIN(P0_01, 0, 1, 0); -const mcu_pin_obj_t pin_P0_02 = PIN(P0_02, 0, 2, SAADC_CH_PSELP_PSELP_AnalogInput0); -const mcu_pin_obj_t pin_P0_03 = PIN(P0_03, 0, 3, SAADC_CH_PSELP_PSELP_AnalogInput1); -const mcu_pin_obj_t pin_P0_04 = PIN(P0_04, 0, 4, SAADC_CH_PSELP_PSELP_AnalogInput2); -const mcu_pin_obj_t pin_P0_05 = PIN(P0_05, 0, 5, SAADC_CH_PSELP_PSELP_AnalogInput3); -const mcu_pin_obj_t pin_P0_06 = PIN(P0_06, 0, 6, 0); -const mcu_pin_obj_t pin_P0_07 = PIN(P0_07, 0, 7, 0); -const mcu_pin_obj_t pin_P0_08 = PIN(P0_08, 0, 8, 0); -const mcu_pin_obj_t pin_P0_09 = PIN(P0_09, 0, 9, 0); -const mcu_pin_obj_t pin_P0_10 = PIN(P0_10, 0, 10, 0); -const mcu_pin_obj_t pin_P0_11 = PIN(P0_11, 0, 11, 0); -const mcu_pin_obj_t pin_P0_12 = PIN(P0_12, 0, 12, 0); -const mcu_pin_obj_t pin_P0_13 = PIN(P0_13, 0, 13, 0); -const mcu_pin_obj_t pin_P0_14 = PIN(P0_14, 0, 14, 0); -const mcu_pin_obj_t pin_P0_15 = PIN(P0_15, 0, 15, 0); -const mcu_pin_obj_t pin_P0_16 = PIN(P0_16, 0, 16, 0); -const mcu_pin_obj_t pin_P0_17 = PIN(P0_17, 0, 17, 0); -const mcu_pin_obj_t pin_P0_18 = PIN(P0_18, 0, 18, 0); -const mcu_pin_obj_t pin_P0_19 = PIN(P0_19, 0, 19, 0); -const mcu_pin_obj_t pin_P0_20 = PIN(P0_20, 0, 20, 0); -const mcu_pin_obj_t pin_P0_21 = PIN(P0_21, 0, 21, 0); -const mcu_pin_obj_t pin_P0_22 = PIN(P0_22, 0, 22, 0); -const mcu_pin_obj_t pin_P0_23 = PIN(P0_23, 0, 23, 0); -const mcu_pin_obj_t pin_P0_24 = PIN(P0_24, 0, 24, 0); -const mcu_pin_obj_t pin_P0_25 = PIN(P0_25, 0, 25, 0); -const mcu_pin_obj_t pin_P0_26 = PIN(P0_26, 0, 26, 0); -const mcu_pin_obj_t pin_P0_27 = PIN(P0_27, 0, 27, 0); -const mcu_pin_obj_t pin_P0_28 = PIN(P0_28, 0, 28, SAADC_CH_PSELP_PSELP_AnalogInput4); -const mcu_pin_obj_t pin_P0_29 = PIN(P0_29, 0, 29, SAADC_CH_PSELP_PSELP_AnalogInput5); -const mcu_pin_obj_t pin_P0_30 = PIN(P0_30, 0, 30, SAADC_CH_PSELP_PSELP_AnalogInput6); -const mcu_pin_obj_t pin_P0_31 = PIN(P0_31, 0, 31, SAADC_CH_PSELP_PSELP_AnalogInput7); diff --git a/ports/nrf/peripherals/nrf/nrf52832/pins.h b/ports/nrf/peripherals/nrf/nrf52832/pins.h deleted file mode 100644 index f8ef85ad09d8b..0000000000000 --- a/ports/nrf/peripherals/nrf/nrf52832/pins.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 by 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_NRF_PERIPHERALS_NRF52832_PINS_H -#define MICROPY_INCLUDED_NRF_PERIPHERALS_NRF52832_PINS_H - -extern const mcu_pin_obj_t pin_P0_00; -extern const mcu_pin_obj_t pin_P0_01; -extern const mcu_pin_obj_t pin_P0_02; -extern const mcu_pin_obj_t pin_P0_03; -extern const mcu_pin_obj_t pin_P0_04; -extern const mcu_pin_obj_t pin_P0_05; -extern const mcu_pin_obj_t pin_P0_06; -extern const mcu_pin_obj_t pin_P0_07; -extern const mcu_pin_obj_t pin_P0_08; -extern const mcu_pin_obj_t pin_P0_09; -extern const mcu_pin_obj_t pin_P0_10; -extern const mcu_pin_obj_t pin_P0_11; -extern const mcu_pin_obj_t pin_P0_12; -extern const mcu_pin_obj_t pin_P0_13; -extern const mcu_pin_obj_t pin_P0_14; -extern const mcu_pin_obj_t pin_P0_15; -extern const mcu_pin_obj_t pin_P0_16; -extern const mcu_pin_obj_t pin_P0_17; -extern const mcu_pin_obj_t pin_P0_18; -extern const mcu_pin_obj_t pin_P0_19; -extern const mcu_pin_obj_t pin_P0_20; -extern const mcu_pin_obj_t pin_P0_21; -extern const mcu_pin_obj_t pin_P0_22; -extern const mcu_pin_obj_t pin_P0_23; -extern const mcu_pin_obj_t pin_P0_24; -extern const mcu_pin_obj_t pin_P0_25; -extern const mcu_pin_obj_t pin_P0_26; -extern const mcu_pin_obj_t pin_P0_27; -extern const mcu_pin_obj_t pin_P0_28; -extern const mcu_pin_obj_t pin_P0_29; -extern const mcu_pin_obj_t pin_P0_30; -extern const mcu_pin_obj_t pin_P0_31; - -#endif // MICROPY_INCLUDED_NRF_PERIPHERALS_NRF52832_PINS_H diff --git a/ports/nrf/peripherals/nrf/nrf52832/power.c b/ports/nrf/peripherals/nrf/nrf52832/power.c deleted file mode 100644 index 942524f530104..0000000000000 --- a/ports/nrf/peripherals/nrf/nrf52832/power.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the Micro Python 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. - */ - -#include "nrfx.h" - -void nrf_peripherals_power_init(void) { -} diff --git a/ports/nrf/peripherals/nrf/pins.h b/ports/nrf/peripherals/nrf/pins.h index 33462d71143b6..3a4c995790b37 100644 --- a/ports/nrf/peripherals/nrf/pins.h +++ b/ports/nrf/peripherals/nrf/pins.h @@ -56,11 +56,7 @@ extern const mp_obj_type_t mcu_pin_type; // Use illegal pin value to mark unassigned pins. #define NO_PIN 0xff -// Choose based on chip, but not specifically revision (e.g., not NRF52832_XXAA) -#ifdef NRF52832 -#include "nrf52832/pins.h" -#endif - +// Choose based on chip, but not specifically revision (e.g., not NRF52840_XXAA) #ifdef NRF52840 #include "nrf52840/pins.h" #endif diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index d30bbbe063ac7..646d50aed0154 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -150,8 +150,8 @@ static void check_lock(busio_spi_obj_t *self) { //| speed is not guaranteed to work. 12 MHz is the next available lower speed, and is //| within spec for the SAMD21. //| -//| .. note:: On the nRF52832, these baudrates are available: 125kHz, 250kHz, 1MHz, 2MHz, 4MHz, -//| and 8MHz. On the nRF52840, 16MHz and 32MHz are also available, but only on the first +//| .. note:: On the nRF52840, these baudrates are available: 125kHz, 250kHz, 1MHz, 2MHz, 4MHz, +//| and 8MHz. 16MHz and 32MHz are also available, but only on the first //| `busio.SPI` object you create. Two more ``busio.SPI`` objects can be created, but they are restricted //| to 8MHz maximum. This is a hardware restriction: there is only one high-speed SPI peripheral. //| If you pick a a baudrate other than one of these, the nearest lower diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 5ba2198e1f086..746dfe5ee78af 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -59,9 +59,6 @@ //| has been established at any point. Will not reset if //| USB is disconnected but power remains (e.g. battery connected) //| -//| Feather52 (nRF52832): Currently returns ``True`` regardless -//| of USB connection status. -//| STATIC mp_obj_t supervisor_get_serial_connected(mp_obj_t self){ if (!common_hal_get_serial_connected()) { diff --git a/tools/build_board_info.py b/tools/build_board_info.py index 379cf55c4d51b..a4b49d16089f2 100644 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -36,10 +36,6 @@ "feather_m0_rfm69": BIN, "feather_m0_rfm9x": BIN, - # nrf52832 - "feather_nrf52832": BIN, - "pca10040": BIN, - # nRF52840 dev kits that may not have UF2 bootloaders, "makerdiary_nrf52840_mdk": HEX, "pca10056": BIN_UF2, From 941ccf87c88e9a72804b829682d842cac8f116b7 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 31 Dec 2018 09:02:43 -0500 Subject: [PATCH 046/153] don't free event handler list manually; let gc do it --- ports/nrf/bluetooth/ble_drv.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c index 57a433f7048f7..62820289b92bc 100644 --- a/ports/nrf/bluetooth/ble_drv.c +++ b/ports/nrf/bluetooth/ble_drv.c @@ -48,12 +48,7 @@ typedef struct event_handler { static event_handler_t *m_event_handlers = NULL; void ble_drv_reset() { - event_handler_t *handler = m_event_handlers; - while (handler != NULL) { - event_handler_t *next = handler->next; - m_free(handler); - handler = next; - } + // Linked list items will be gc'd. m_event_handlers = NULL; } From 87c6f33bccc38548ec1b811885cd974aadf6804e Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 1 Jan 2019 14:11:59 -0500 Subject: [PATCH 047/153] Broadcaster now takes whole packet. Also should be scannable --- ports/nrf/common-hal/bleio/Broadcaster.c | 27 ++++++------------------ shared-bindings/bleio/Broadcaster.c | 10 +++------ 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Broadcaster.c b/ports/nrf/common-hal/bleio/Broadcaster.c index 508ede1d6da4c..a70209a7fc242 100644 --- a/ports/nrf/common-hal/bleio/Broadcaster.c +++ b/ports/nrf/common-hal/bleio/Broadcaster.c @@ -38,12 +38,6 @@ static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; -STATIC void check_data_fit(size_t pos, size_t data_len) { - if (pos + data_len >= BLE_GAP_ADV_SET_DATA_SIZE_MAX) { - mp_raise_ValueError(translate("Data too large for advertisement packet")); - } -} - void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_float_t interval) { common_hal_bleio_adapter_set_enabled(true); // TODO -- Do this somewhere else maybe bleio __init__ const mp_float_t min = BLE_GAP_ADV_INTERVAL_MIN * ADV_INTERVAL_UNIT_FLOAT_SECS; @@ -58,25 +52,16 @@ void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_fl void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *self, mp_buffer_info_t *data) { - size_t adv_data_pos = 0; uint32_t err_code; - // Build up advertising packet. - check_data_fit(adv_data_pos, 1 + 1 + 1); - self->adv_data[adv_data_pos++] = 2; - self->adv_data[adv_data_pos++] = BLE_GAP_AD_TYPE_FLAGS; - self->adv_data[adv_data_pos++] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; - - // Data is always send as manufacturer-specific data - check_data_fit(adv_data_pos, 1 + 1 + data->len); - self->adv_data[adv_data_pos++] = 1 + data->len; - self->adv_data[adv_data_pos++] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA; - memcpy(&(self->adv_data[adv_data_pos]), data->buf, data->len); - adv_data_pos += data->len; + if (data->len >= BLE_GAP_ADV_SET_DATA_SIZE_MAX) { + mp_raise_ValueError(translate("Data too large for advertisement packet")); + } + memcpy(self->adv_data, data->buf, data->len); ble_gap_adv_params_t m_adv_params = { .interval = (uint32_t) (self->interval / ADV_INTERVAL_UNIT_FLOAT_SECS), - .properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED, + .properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED, .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED, .filter_policy = BLE_GAP_ADV_FP_ANY, .primary_phy = BLE_GAP_PHY_1MBPS, @@ -86,7 +71,7 @@ void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *sel const ble_gap_adv_data_t ble_gap_adv_data = { .adv_data.p_data = self->adv_data, - .adv_data.len = adv_data_pos, + .adv_data.len = data->len, }; err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params); diff --git a/shared-bindings/bleio/Broadcaster.c b/shared-bindings/bleio/Broadcaster.c index ae4f28b74ad84..c4524e8fc65c9 100644 --- a/shared-bindings/bleio/Broadcaster.c +++ b/shared-bindings/bleio/Broadcaster.c @@ -42,18 +42,14 @@ //| import bleio //| import time //| -//| //| # Broadcast once a second. //| broadcaster = bleio.Broadcaster(interval=1) //| i = 0 -//| data = bytearray(1) //| # Broadcast a byte of data that's incremented once a minute //| while True: -//| data[0] = i -//| bytearray +//| # data is an entire advertising data packet, starting with flags. //| broadcaster.start_advertising(data) //| time.sleep(60) -//| i += 1 //| //| .. class:: Broadcaster(interval=1) //| @@ -88,9 +84,9 @@ STATIC mp_obj_t bleio_broadcaster_make_new(const mp_obj_type_t *type, size_t n_a //| .. method:: start_advertising(data) //| -//| Start advertising the given manufacturer-specific data. +//| Start advertising using the given data packet. //| -//| :param buf data: Send data bytes in advertising packets, labeled as manufacturer-specific data +//| :param buf data: advertising data packet, starting with advertising data flags (0x01) //| STATIC mp_obj_t bleio_broadcaster_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); From c46d06f34c07e843844c3af658a7ff98c6992edc Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 2 Jan 2019 23:11:03 -0500 Subject: [PATCH 048/153] Move 128-bit UUID string parsing to Python; simplify UUID API --- shared-bindings/bleio/UUID.c | 106 ++++++++--------------------------- 1 file changed, 23 insertions(+), 83 deletions(-) diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 472014a4c5ecb..5726d5aba9ca3 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -26,21 +26,13 @@ * THE SOFTWARE. */ +#include + #include "py/objproperty.h" #include "py/objstr.h" #include "py/runtime.h" #include "shared-bindings/bleio/UUID.h" -// Including hyphens. -#define UUID128_STR_LEN 36 -// Number of bytes -#define UUID128_BYTE_LEN 16 - -STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { - return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4); -} - - //| .. currentmodule:: bleio //| //| :class:`UUID` -- BLE UUID @@ -49,101 +41,49 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { //| A 16-bit or 128-bit UUID. Can be used for services, characteristics, descriptors and more. //| -//| .. class:: UUID(value, *, base_uuid=None) +//| .. class:: UUID(value) //| //| Create a new UUID or UUID object encapsulating the uuid value. //| The value can be one of: //| //| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID) -//| - a `str` value in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', where the X's are hex digits. -//| (128 bit UUID) //| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID) //| -//| :param int/str/buffer value: The uuid value to encapsulate -//| +//| :param int/buffer value: The uuid value to encapsulate STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); + mp_arg_check_num(n_args, n_kw, 1, 1, false); bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); self->base.type = type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - - enum { ARG_value, ARG_base_uuid }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_base_uuid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - 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); - - const mp_obj_t value = args[ARG_value].u_obj; - const mp_obj_t base_uuid = args[ARG_base_uuid].u_obj; + const mp_obj_t value = pos_args[0]; uint8_t uuid128[16]; - if (base_uuid != mp_const_none) { - if (MP_OBJ_IS_TYPE(base_uuid, &bleio_uuid_type)) { - if (!common_hal_bleio_uuid_get_uuid128(base_uuid, uuid128)) { - mp_raise_ValueError(translate("base_uuid is not 128 bits")); - } - } else { - mp_raise_ValueError(translate("base_uuid is not a UUID")); - } - } - if (MP_OBJ_IS_INT(value)) { mp_int_t uuid16 = mp_obj_get_int(value); if (uuid16 < 0 || uuid16 > 0xffff) { mp_raise_ValueError(translate("UUID integer value not in range 0 to 0xffff")); } - // If a base_uuid was supplied, merge the uuid16 into it. Otherwise - // it's a 16-bit Bluetooth SIG UUID. NULL means no 128-bit value. - common_hal_bleio_uuid_construct(self, uuid16, base_uuid == mp_const_none ? NULL : uuid128); - - } else if (MP_OBJ_IS_STR(value)) { - uint8_t uuid128[UUID128_BYTE_LEN]; - GET_STR_DATA_LEN(value, str, str_len); - if (str_len == UUID128_STR_LEN && - str[8] == '-' && str[13] == '-' && str[18] == '-' && str[23] == '-') { - int str_index = UUID128_STR_LEN - 1; - size_t uuid128_index = 0; - bool error = false; - - // Loop until fewer than two characters left. - while (str_index >= 1 && uuid128_index < UUID128_BYTE_LEN) { - if (str[str_index] == '-') { - // Skip hyphen separators. - str_index--; - continue; - } - - if (!unichar_isxdigit(str[str_index]) || - !unichar_isxdigit(str[str_index-1])) { - error = true; - break; - } - - uuid128[uuid128_index] = xdigit_8b_value(str[str_index], - str[str_index-1]); - uuid128_index += 1; - str_index -= 2; - } - // Check for correct number of hex digits and no parsing errors. - if (!error && uuid128_index == UUID128_BYTE_LEN && str_index == -1) { - uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12]; - uuid128[12] = 0; - uuid128[13] = 0; - common_hal_bleio_uuid_construct(self, uuid16, uuid128); - } else { - mp_raise_ValueError(translate("UUID string must be of the form xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); - } - } + // NULL means no 128-bit value. + common_hal_bleio_uuid_construct(self, uuid16, NULL); + } else { - mp_raise_ValueError(translate("UUID value is not int or string")); + mp_buffer_info_t bufinfo; + if (!mp_get_buffer(value, &bufinfo, MP_BUFFER_READ)) { + mp_raise_ValueError(translate("UUID value is not int or byte buffer")); + } + + if (bufinfo.len != 16) { + mp_raise_ValueError(translate("Byte buffer must be 16 bytes.")); + } + + memcpy(uuid128, bufinfo.buf, 16); + uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12]; + uuid128[12] = 0; + uuid128[13] = 0; + common_hal_bleio_uuid_construct(self, uuid16, bufinfo.buf); } return MP_OBJ_FROM_PTR(self); From ccb3c6fac688eb71724f6874c4436e659451100c Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 3 Jan 2019 10:51:49 -0500 Subject: [PATCH 049/153] Remove print methods from bleio; Python lib will do it --- shared-bindings/bleio/Characteristic.c | 9 --------- shared-bindings/bleio/UUID.c | 13 ------------- 2 files changed, 22 deletions(-) diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index d6ae4dfe45f39..7cffd2261b7ad 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -89,14 +89,6 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t return MP_OBJ_FROM_PTR(self); } -STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_printf(print, "Characteristic("); - bleio_uuid_print(print, self->uuid, kind); - mp_printf(print, ")"); -} - //| .. attribute:: broadcast //| //| A `bool` specifying if the characteristic allows broadcasting its value. (read-only) @@ -274,7 +266,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characterist const mp_obj_type_t bleio_characteristic_type = { { &mp_type_type }, .name = MP_QSTR_Characteristic, - .print = bleio_characteristic_print, .make_new = bleio_characteristic_make_new, .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict }; diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 5726d5aba9ca3..7cef8c47f8f4c 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -89,18 +89,6 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si return MP_OBJ_FROM_PTR(self); } -void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (common_hal_bleio_uuid_get_size(self) == 128) { - mp_printf(print, "UUID(uuid16=0x%04x, uuid128_reference=0x%02x)", - common_hal_bleio_uuid_get_uuid16(self), - common_hal_bleio_uuid_get_uuid128_reference(self)); - } else { - mp_printf(print, "UUID(0x%04x)", common_hal_bleio_uuid_get_uuid16(self)); - } -} - //| .. attribute:: uuid16 //| //| The 16-bit part of the UUID. (read-only) @@ -236,7 +224,6 @@ STATIC mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_ const mp_obj_type_t bleio_uuid_type = { { &mp_type_type }, .name = MP_QSTR_UUID, - .print = bleio_uuid_print, .make_new = bleio_uuid_make_new, .unary_op = bleio_uuid_unary_op, .binary_op = bleio_uuid_binary_op, From 8dea6f53bbba5b76a5ed0965b44ad1bde4640609 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 3 Jan 2019 14:16:41 -0500 Subject: [PATCH 050/153] forgot to store data when reading a gatts value --- ports/nrf/common-hal/bleio/Characteristic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 7a32e4928cd19..9d7007d7da8fd 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -78,6 +78,7 @@ STATIC void gatts_read(bleio_characteristic_obj_t *characteristic) { if (err_code == NRF_SUCCESS) { characteristic->value_data = mp_obj_new_bytearray_of_zeros(gatts_value.len); mp_get_buffer_raise(characteristic->value_data, &bufinfo, MP_BUFFER_WRITE); + gatts_value.p_value = bufinfo.buf; // Read again, with the correct size of buffer. err_code = sd_ble_gatts_value_get(conn_handle, characteristic->handle, &gatts_value); From a77b2363eff14ae5b19c50a7d25b3db4ef6b200c Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 3 Jan 2019 21:42:42 -0500 Subject: [PATCH 051/153] evt handler list bugs; unique evt handler names; remove uuid128_reference --- ports/nrf/bluetooth/ble_drv.c | 23 ++++++++----------- ports/nrf/common-hal/bleio/Characteristic.c | 8 +++---- ports/nrf/common-hal/bleio/Peripheral.c | 4 ++-- shared-bindings/bleio/Characteristic.c | 12 +++++++--- shared-bindings/bleio/UUID.c | 25 ++------------------- 5 files changed, 26 insertions(+), 46 deletions(-) diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c index 62820289b92bc..7082b1e59cbbd 100644 --- a/ports/nrf/bluetooth/ble_drv.c +++ b/ports/nrf/bluetooth/ble_drv.c @@ -53,27 +53,22 @@ void ble_drv_reset() { } void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { - event_handler_t *handler = m_new_ll(event_handler_t, 1); - handler->next = NULL; - handler->param = param; - handler->func = func; - - if (m_event_handlers == NULL) { - m_event_handlers = handler; - return; - } - event_handler_t *it = m_event_handlers; - while (it->next != NULL) { + while (it != NULL) { + // If event handler and its corresponding param are already on the list, don't add again. if ((it->func == func) && (it->param == param)) { - m_free(handler); return; } - it = it->next; } - it->next = handler; + // Add a new handler to the front of the list + event_handler_t *handler = m_new_ll(event_handler_t, 1); + handler->next = m_event_handlers; + handler->param = param; + handler->func = func; + + m_event_handlers = handler; } void SD_EVT_IRQHandler(void) { diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 9d7007d7da8fd..a955395bd55c5 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -55,7 +55,7 @@ STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) { // CCCD is not set, so say that neither Notify nor Indicate is enabled. cccd = 0; } else if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to read CCD value, err 0x%04x"), err_code); + mp_raise_OSError_msg_varg(translate("Failed to read CCCD value, err 0x%04x"), err_code); } return cccd; @@ -126,7 +126,7 @@ STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params); if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to notify attribute value, err %0x04x"), err_code); + mp_raise_OSError_msg_varg(translate("Failed to notify or indicate attribute value, err %0x04x"), err_code); } m_tx_in_progress += 1; @@ -188,7 +188,7 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in } } -STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) { +STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) { switch (ble_evt->header.evt_id) { case BLE_GATTS_EVT_HVN_TX_COMPLETE: m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; @@ -211,7 +211,7 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) { } void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self) { - ble_drv_add_event_handler(on_ble_evt, NULL); + ble_drv_add_event_handler(characteristic_on_ble_evt, NULL); } void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) { diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index d2eef596d47f5..7d5d6a6a6c86e 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -221,7 +221,7 @@ STATIC uint32_t set_advertisement_data(bleio_peripheral_obj_t *self, bool connec return err_code; } -STATIC void on_ble_evt(ble_evt_t *ble_evt, void *self_in) { +STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in; switch (ble_evt->header.evt_id) { @@ -311,7 +311,7 @@ bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) { void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) { if (connectable) { - ble_drv_add_event_handler(on_ble_evt, self); + ble_drv_add_event_handler(peripheral_on_ble_evt, self); } const uint32_t err_code = set_advertisement_data(self, connectable, raw_data); diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 7cffd2261b7ad..1d414b6d30ac0 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -35,15 +35,21 @@ //| :class:`Characteristic` -- BLE service characteristic //| ========================================================= //| -//| Stores information about a BLE service characteristic and allows to read -//| and write the characteristic's value. +//| Stores information about a BLE service characteristic and allows reading +//| and writing of the characteristic's value. //| //| //| .. class:: Characteristic(uuid, *, broadcast=False, indicate=False, notify=False, read=False, write=False, write_no_response=False) //| //| Create a new Characteristic object identified by the specified UUID. //| -//| :param bleio.UUID uuid: The uuid of the characteristic (read_only) +//| :param bleio.UUID uuid: The uuid of the characteristic +//| :param bool broadcast: Allowed in advertising packets +//| :param bool indicate: Server will indicate to the client when the value is set and wait for a response +//| :param bool notify: Server will notify the client when the value is set +//| :param bool read: Clients may read this characteristic +//| :param bool write: Clients may write this characteristic; a response will be sent back +//| :param bool write_no_response: Clients may write this characteristic; no response will be sent back //| STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 7cef8c47f8f4c..2b42ab05cca14 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -109,8 +109,8 @@ const mp_obj_property_t bleio_uuid_uuid16_obj = { //| .. attribute:: uuid128 //| -//| The 128-bit value of the UUID, return as a bytes(). -//| Throws AttributeError if this is a 16-bit UUID. (read-only) +//| The 128-bit value of the UUID, returned as bytes. +//| Raises AttributeError if this is a 16-bit UUID. (read-only) //| STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -131,26 +131,6 @@ const mp_obj_property_t bleio_uuid_uuid128_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| .. attribute:: uuid128_reference -//| -//| An opaque reference representing the 128-bit UUID. (read-only) -//| Returns None if this is a 16-bit UUID. -//| -STATIC mp_obj_t bleio_uuid_get_uuid128_reference(mp_obj_t self_in) { - bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint32_t reference = common_hal_bleio_uuid_get_uuid128_reference(self); - return reference == 0 ? mp_const_none : MP_OBJ_NEW_SMALL_INT(reference); -} - -MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid128_reference_obj, bleio_uuid_get_uuid128_reference); - -const mp_obj_property_t bleio_uuid_uuid128_reference_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&bleio_uuid_get_uuid128_reference_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - //| .. attribute:: size //| //| Returns 128 if this UUID represents a 128-bit vendor-specific UUID. @@ -174,7 +154,6 @@ const mp_obj_property_t bleio_uuid_size_obj = { STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid_uuid16_obj) }, { MP_ROM_QSTR(MP_QSTR_uuid128), MP_ROM_PTR(&bleio_uuid_uuid128_obj) }, - { MP_ROM_QSTR(MP_QSTR_uuid128_reference), MP_ROM_PTR(&bleio_uuid_uuid128_reference_obj) }, { MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&bleio_uuid_size_obj) }, }; From 215008f78cbd30739b7899f3aa8f56940fa471ad Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jan 2019 00:21:31 +0700 Subject: [PATCH 052/153] clean up neopixel write !! --- ports/nrf/common-hal/neopixel_write/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c index c9da436b8ae11..f810a44cc3797 100644 --- a/ports/nrf/common-hal/neopixel_write/__init__.c +++ b/ports/nrf/common-hal/neopixel_write/__init__.c @@ -141,7 +141,7 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout for ( uint16_t n = 0; n < numBytes; n++ ) { uint8_t pix = pixels[n]; - for ( uint8_t mask = 0x80, i = 0; mask > 0; mask >>= 1, i++ ) { + for ( uint8_t mask = 0x80; mask > 0; mask >>= 1 ) { pixels_pattern[pos] = (pix & mask) ? MAGIC_T1H : MAGIC_T0H; pos++; } From 2df3e7b0fc9de04ff10ef07b26c8db0711802fcb Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Mon, 7 Jan 2019 16:25:34 -0600 Subject: [PATCH 053/153] Updated README with embedded spreadsheet --- ports/atmel-samd/README.rst | 48 +++---------------------------------- 1 file changed, 3 insertions(+), 45 deletions(-) diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 6037c7d3b1c7a..7b14feff4079e 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -22,51 +22,9 @@ different names. The table below matches the pin order in and omits the pins only available on the largest package because all supported boards use smaller version. -===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ -`microcontroller.pin` `board` ---------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -Datasheet arduino_mkrzero arduino_zero circuitplayground_express feather_m0_adalogger feather_m0_basic feather_m0_express gemma_m0 metro_m0_express trinket_m0 -===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ -PA00 ``ACCELEROMETER_SDA`` ``APA102_MOSI`` ``APA102_MOSI`` -PA01 ``ACCELEROMETER_SCL`` ``APA102_SCK`` ``APA102_SCK`` -PA02 ``A0`` ``A0`` ``A0`` / ``SPEAKER`` ``A0`` ``A0`` ``A0`` ``A0`` / ``D1`` ``A0`` ``D1`` / ``A0`` -PA03 -PB08 ``L`` ``A1`` ``A7`` / ``TX`` ``A1`` ``A1`` ``A1`` ``A1`` -PB09 ``BATTERY`` ``A2`` ``A6`` / ``RX`` ``A2`` ``A2`` ``A2`` ``A2`` -PA04 ``A3`` ``A3`` ``IR_PROXIMITY`` ``A3`` ``A3`` ``A3`` ``D0`` / ``TX`` / ``SDA`` ``A3`` -PA05 ``A4`` ``A4`` ``A1`` ``A4`` ``A4`` ``A4`` ``D2`` / ``RX`` / ``SCL`` ``A4`` -PA06 ``A5`` ``D8`` ``A2`` ``D8`` / ``GREEN_LED`` ``NEOPIXEL`` ``D8`` ``D4`` / ``TX`` -PA07 ``A6`` ``D9`` ``A3`` ``D9`` ``D9`` ``D9`` ``D9`` ``D3`` / ``RX`` -PA08 ``D11`` / ``SDA`` ``D4`` ``MICROPHONE_DO`` ``D4`` / ``SD_CS`` ``D4`` ``D0`` / ``SDA`` -PA09 ``D12`` / ``SCL`` ``D3`` ``TEMPERATURE`` / ``A9`` ``D3`` ``D2`` / ``SCL`` -PA10 ``D2`` ``D1`` / ``TX`` ``MICROPHONE_SCK`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D13`` -PA11 ``D3`` ``D0`` / ``RX`` ``LIGHT`` / ``A8`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` -PB10 ``D4`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` -PB11 ``D5`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` -PA12 ``SD_MOSI`` ``MISO`` ``REMOTEIN`` / ``IR_RX`` ``MISO`` ``MISO`` ``MISO`` ``MISO`` -PA13 ``SD_SCK`` ``ACCELEROMETER_INTERRUPT`` ``FLASH_CS`` -PA14 ``SD_CS`` ``D2`` ``BUTTON_B`` / ``D5`` ``D2`` -PA15 ``SD_MISO`` ``D5`` ``SLIDE_SWITCH`` / ``D7`` ``D5`` ``D5`` ``D5`` ``D5`` -PA16 ``D8`` / ``MOSI`` ``D11`` ``MISO`` ``D11`` ``D11`` ``D11`` ``D11`` -PA17 ``D9`` / ``SCK`` ``D13`` ``D13`` ``D13`` / ``RED_LED`` ``D13`` ``D13`` ``D13`` -PA18 ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` -PA19 ``D10`` / ``MISO`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` -PA20 ``D6`` ``D6`` ``MOSI`` ``D6`` ``D6`` ``D6`` ``D6`` -PA21 ``D7`` ``D7`` ``SCK`` ``D7`` / ``SD_CD`` ``D7`` -PA22 ``D0`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` -PA23 ``D1`` ``SCL`` ``REMOTEOUT`` / ``IR_TX`` ``SCL`` ``SCL`` ``SCL`` ``L`` / ``D13`` ``SCL`` -PA24 -PA25 -PB22 ``D14`` / ``TX`` ``FLASH_CS`` -PB23 ``D13`` / ``RX`` ``NEOPIXEL`` / ``D8`` -PA27 ``SD_CD`` -PA28 ``BUTTON_A`` / ``D4`` -PA29 -PA30 ``SPEAKER_ENABLE`` ``NEOPIXEL`` -PA31 -PB02 ``A1`` ``A5`` ``A5`` / ``SDA`` ``A5`` ``A5`` ``A5`` ``A5`` -PB03 ``A2`` ``A4`` / ``SCL`` -===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ + + +The full pinout spreadsheet can be found `here `_. Here is a table about which pins can do what in CircuitPython terms. However, just because something is listed, doesn't mean it will always work. Existing use From 04b9a789ffc74102a040227633cb95f745adacf5 Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Mon, 7 Jan 2019 16:28:14 -0600 Subject: [PATCH 054/153] Trying iframe in rst again. --- ports/atmel-samd/README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 7b14feff4079e..1e9edb2a90104 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -22,7 +22,9 @@ different names. The table below matches the pin order in and omits the pins only available on the largest package because all supported boards use smaller version. - +.. raw:: html + + The full pinout spreadsheet can be found `here `_. From 4d3ae04e2b1f76eb9e9c4924080509102e8fa51d Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Mon, 7 Jan 2019 16:31:52 -0600 Subject: [PATCH 055/153] Trying iframe in rst again again. --- ports/atmel-samd/README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 1e9edb2a90104..acfc7ac4fa9f4 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -24,7 +24,9 @@ boards use smaller version. .. raw:: html - +
+ +
The full pinout spreadsheet can be found `here `_. From 180c7b4b790cc8345655010aa27c1c02b35ef685 Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Mon, 7 Jan 2019 16:35:47 -0600 Subject: [PATCH 056/153] Trying iframe in rst again^3. --- ports/atmel-samd/README.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index acfc7ac4fa9f4..572961505b6f4 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -24,9 +24,7 @@ boards use smaller version. .. raw:: html -
- -
+ The full pinout spreadsheet can be found `here `_. From d3aeca104e007abf0620db53faf6f694a951c8c6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 7 Jan 2019 14:50:09 -0800 Subject: [PATCH 057/153] Initial pass at pyportal board define. --- ports/atmel-samd/boards/pyportal/board.c | 39 +++++++++++++ .../boards/pyportal/mpconfigboard.h | 40 ++++++++++++++ .../boards/pyportal/mpconfigboard.mk | 14 +++++ ports/atmel-samd/boards/pyportal/pins.c | 55 +++++++++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 ports/atmel-samd/boards/pyportal/board.c create mode 100644 ports/atmel-samd/boards/pyportal/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/pyportal/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/pyportal/pins.c diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c new file mode 100644 index 0000000000000..7599f02b8efee --- /dev/null +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 "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/pyportal/mpconfigboard.h b/ports/atmel-samd/boards/pyportal/mpconfigboard.h new file mode 100644 index 0000000000000..16b104297192f --- /dev/null +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.h @@ -0,0 +1,40 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit PyPortal" +#define MICROPY_HW_MCU_NAME "samd51j20" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev B + +#define MICROPY_HW_LED_STATUS (&pin_PA27) + +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 ) +// QSPI CS, and QSPI SCK +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 ) +#define MICROPY_PORT_C ( 0 ) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +#define DEFAULT_UART_BUS_RX (&pin_PB13) +#define DEFAULT_UART_BUS_TX (&pin_PB12) + +// 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/pyportal/mpconfigboard.mk b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk new file mode 100644 index 0000000000000..649bbb6489883 --- /dev/null +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd51x20-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8032 +USB_PRODUCT = "PyPortal" +USB_MANUFACTURER = "Adafruit Industries LLC" + +QSPI_FLASH_FILESYSTEM = 1 + +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q64C" +LONGINT_IMPL = MPZ + +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c new file mode 100644 index 0000000000000..84ecbaffff58f --- /dev/null +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -0,0 +1,55 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_AUDIO_OUT), (mp_obj_t)&pin_PA02 }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA27 }, + + // LCD pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), (mp_obj_t)&pin_PA00 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RD), (mp_obj_t)&pin_PB04 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RS), (mp_obj_t)&pin_PB05 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_CS), (mp_obj_t)&pin_PB06 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_TE), (mp_obj_t)&pin_PB07 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_WR), (mp_obj_t)&pin_PB09 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_BACKLIGHT), (mp_obj_t)&pin_PB31 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA0), (mp_obj_t)&pin_PA16 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA1), (mp_obj_t)&pin_PA17 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA2), (mp_obj_t)&pin_PA18 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA3), (mp_obj_t)&pin_PA19 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA4), (mp_obj_t)&pin_PA20 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA5), (mp_obj_t)&pin_PA21 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA6), (mp_obj_t)&pin_PA22 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA7), (mp_obj_t)&pin_PA23 }, + + // Touch pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YD), (mp_obj_t)&pin_PA04 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XL), (mp_obj_t)&pin_PA05 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YU), (mp_obj_t)&pin_PA06 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XR), (mp_obj_t)&pin_PB08 }, + + // ESP control + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), (mp_obj_t)&pin_PA15 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), (mp_obj_t)&pin_PB14 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), (mp_obj_t)&pin_PB15 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), (mp_obj_t)&pin_PB16 }, + + + // SD Card + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MOSI), (mp_obj_t)&pin_PA12 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SCK), (mp_obj_t)&pin_PA13 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), (mp_obj_t)&pin_PB30 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MISO), (mp_obj_t)&pin_PA14 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), (mp_obj_t)&pin_PA01 }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB22 }, + + { 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_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); From a49683e93f1b8cb11cca7ca58bf3eb43c4fcc50c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 7 Jan 2019 15:00:23 -0800 Subject: [PATCH 058/153] Build with Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2eab28a0b8c93..d3e9f4bf188e1 100755 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ env: - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm - - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick" TRAVIS_SDK=arm + - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick pyportal" TRAVIS_SDK=arm addons: artifacts: From a00420bafd4d4668e2e9a756ecef24f5bed2e725 Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Mon, 7 Jan 2019 17:26:38 -0600 Subject: [PATCH 059/153] Added pinout for SparkFun SAMD21 Mini Breakout on README. --- ports/atmel-samd/README.rst | 52 ++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 572961505b6f4..3e0bb56b0dc4c 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -22,11 +22,51 @@ different names. The table below matches the pin order in and omits the pins only available on the largest package because all supported boards use smaller version. -.. raw:: html - - - -The full pinout spreadsheet can be found `here `_. +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ================ +`microcontroller.pin` `board` +--------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Datasheet arduino_mkrzero arduino_zero circuitplayground_express feather_m0_adalogger feather_m0_basic feather_m0_express gemma_m0 metro_m0_express sparkfun_samd21_mini trinket_m0 +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ================ +PA00 ``ACCELEROMETER_SDA`` ``APA102_MOSI`` ``APA102_MOSI`` +PA01 ``ACCELEROMETER_SCL`` ``APA102_SCK`` ``APA102_SCK`` +PA02 ``A0`` ``A0`` ``A0`` / ``SPEAKER`` ``A0`` ``A0`` ``A0`` ``A0`` / ``D1`` ``A0`` ``A0`` ``D1`` / ``A0`` +PA03 +PB08 ``L`` ``A1`` ``A7`` / ``TX`` ``A1`` ``A1`` ``A1`` ``A1`` ``A1`` +PB09 ``BATTERY`` ``A2`` ``A6`` / ``RX`` ``A2`` ``A2`` ``A2`` ``A2`` ``A2`` +PA04 ``A3`` ``A3`` ``IR_PROXIMITY`` ``A3`` ``A3`` ``A3`` ``D0`` / ``TX`` / ``SDA`` ``A3`` ``A3`` +PA05 ``A4`` ``A4`` ``A1`` ``A4`` ``A4`` ``A4`` ``D2`` / ``RX`` / ``SCL`` ``A4`` +PA06 ``A5`` ``D8`` ``A2`` ``D8`` / ``GREEN_LED`` ``NEOPIXEL`` ``D8`` ``D8`` ``D4`` / ``TX`` +PA07 ``A6`` ``D9`` ``A3`` ``D9`` ``D9`` ``D9`` ``D9`` ``D9`` ``D3`` / ``RX`` +PA08 ``D11`` / ``SDA`` ``D4`` ``MICROPHONE_DO`` ``D4`` / ``SD_CS`` ``D4`` ``D4`` ``D0`` / ``SDA`` +PA09 ``D12`` / ``SCL`` ``D3`` ``TEMPERATURE`` / ``A9`` ``D3`` ``D3`` ``D2`` / ``SCL`` +PA10 ``D2`` ``D1`` / ``TX`` ``MICROPHONE_SCK`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D13`` +PA11 ``D3`` ``D0`` / ``RX`` ``LIGHT`` / ``A8`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` +PB10 ``D4`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` +PB11 ``D5`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` +PA12 ``SD_MOSI`` ``MISO`` ``REMOTEIN`` / ``IR_RX`` ``MISO`` ``MISO`` ``MISO`` ``MISO`` +PA13 ``SD_SCK`` ``ACCELEROMETER_INTERRUPT`` ``FLASH_CS`` +PA14 ``SD_CS`` ``D2`` ``BUTTON_B`` / ``D5`` ``D2`` ``D2`` +PA15 ``SD_MISO`` ``D5`` ``SLIDE_SWITCH`` / ``D7`` ``D5`` ``D5`` ``D5`` ``D5`` ``D5`` +PA16 ``D8`` / ``MOSI`` ``D11`` ``MISO`` ``D11`` ``D11`` ``D11`` ``D11`` ``D11`` / ``MOSI`` +PA17 ``D9`` / ``SCK`` ``D13`` ``D13`` ``D13`` / ``RED_LED`` ``D13`` ``D13`` ``D13`` ``D13`` / ``SCK`` / ``BLUE_LED`` +PA18 ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` +PA19 ``D10`` / ``MISO`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` / ``MISO`` +PA20 ``D6`` ``D6`` ``MOSI`` ``D6`` ``D6`` ``D6`` ``D6`` ``D6`` +PA21 ``D7`` ``D7`` ``SCK`` ``D7`` / ``SD_CD`` ``D7`` ``D7`` +PA22 ``D0`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` +PA23 ``D1`` ``SCL`` ``REMOTEOUT`` / ``IR_TX`` ``SCL`` ``SCL`` ``SCL`` ``L`` / ``D13`` ``SCL`` ``SCL`` +PA24 +PA25 +PB22 ``D14`` / ``TX`` ``FLASH_CS`` +PB23 ``D13`` / ``RX`` ``NEOPIXEL`` / ``D8`` +PA27 ``SD_CD`` ``GREEN_LED`` +PA28 ``BUTTON_A`` / ``D4`` +PA29 +PA30 ``SPEAKER_ENABLE`` ``NEOPIXEL`` +PA31 +PB02 ``A1`` ``A5`` ``A5`` / ``SDA`` ``A5`` ``A5`` ``A5`` ``A5`` +PB03 ``A2`` ``A4`` / ``SCL`` ``YELLOW_LED`` +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ================ Here is a table about which pins can do what in CircuitPython terms. However, just because something is listed, doesn't mean it will always work. Existing use @@ -197,4 +237,4 @@ Port Specific modules --------------------- .. toctree:: - bindings/samd/__init__ + bindings/samd/__init__ \ No newline at end of file From f66f55b4ed4a008fd328a377acbf731e5f22d6de Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 7 Jan 2019 22:46:20 -0500 Subject: [PATCH 060/153] add CharacteristicBuffer; UART seems to work! --- ports/nrf/.gitignore | 4 +- ports/nrf/Makefile | 1 + ports/nrf/bluetooth/ble_drv.c | 14 +++ ports/nrf/bluetooth/ble_drv.h | 1 + ports/nrf/bluetooth/download_ble_stack.sh | 32 ----- ports/nrf/common-hal/bleio/Characteristic.c | 50 +++++--- ports/nrf/common-hal/bleio/Characteristic.h | 46 +++++++ .../common-hal/bleio/CharacteristicBuffer.c | 75 +++++++++++ .../common-hal/bleio/CharacteristicBuffer.h | 41 ++++++ ports/nrf/common-hal/bleio/Peripheral.c | 2 +- ports/nrf/common-hal/bleio/Service.c | 5 + shared-bindings/bleio/Characteristic.c | 22 ++-- shared-bindings/bleio/Characteristic.h | 4 +- shared-bindings/bleio/CharacteristicBuffer.c | 119 ++++++++++++++++++ shared-bindings/bleio/CharacteristicBuffer.h | 39 ++++++ shared-bindings/bleio/__init__.c | 2 + shared-module/bleio/Characteristic.h | 17 +-- 17 files changed, 395 insertions(+), 79 deletions(-) delete mode 100755 ports/nrf/bluetooth/download_ble_stack.sh create mode 100644 ports/nrf/common-hal/bleio/Characteristic.h create mode 100644 ports/nrf/common-hal/bleio/CharacteristicBuffer.c create mode 100644 ports/nrf/common-hal/bleio/CharacteristicBuffer.h create mode 100644 shared-bindings/bleio/CharacteristicBuffer.c create mode 100644 shared-bindings/bleio/CharacteristicBuffer.h diff --git a/ports/nrf/.gitignore b/ports/nrf/.gitignore index fc9f24b50d9af..cda23c7a9019b 100644 --- a/ports/nrf/.gitignore +++ b/ports/nrf/.gitignore @@ -1,8 +1,8 @@ # Old Nordic soft devices that don't allow redistribution ######################################################### -bluetooth/s132_nrf52_2.0.1/ +drivers/bluetooth/s132_nrf52_2.0.1/ -!bluetooth/*/*.hex +!drivers/bluetooth/*/*.hex # Build files ##################### diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index f7e4a29884f29..2e345b9c7bd69 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -174,6 +174,7 @@ SRC_COMMON_HAL += \ bleio/Adapter.c \ bleio/Broadcaster.c \ bleio/Characteristic.c \ + bleio/CharacteristicBuffer.c \ bleio/Descriptor.c \ bleio/Peripheral.c \ bleio/Scanner.c \ diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c index 7082b1e59cbbd..cdc56319bd797 100644 --- a/ports/nrf/bluetooth/ble_drv.c +++ b/ports/nrf/bluetooth/ble_drv.c @@ -71,6 +71,20 @@ void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { m_event_handlers = handler; } +void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param) { + event_handler_t *it = m_event_handlers; + event_handler_t **prev = &m_event_handlers; + while (it != NULL) { + if ((it->func == func) && (it->param == param)) { + // Splice out the matching handler. + *prev = it->next; + return; + } + prev = &(it->next); + it = it->next; + } +} + void SD_EVT_IRQHandler(void) { uint32_t evt_id; while (sd_evt_get(&evt_id) != NRF_ERROR_NOT_FOUND) { diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h index 696aff1da144d..3d1f551c5383a 100644 --- a/ports/nrf/bluetooth/ble_drv.h +++ b/ports/nrf/bluetooth/ble_drv.h @@ -52,5 +52,6 @@ typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*); void ble_drv_reset(); void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param); +void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param); #endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H diff --git a/ports/nrf/bluetooth/download_ble_stack.sh b/ports/nrf/bluetooth/download_ble_stack.sh deleted file mode 100755 index 7e35c0680b38b..0000000000000 --- a/ports/nrf/bluetooth/download_ble_stack.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -function download_s132_nrf52_2_0_1 -{ - echo "" - echo "####################################" - echo "### Downloading s132_nrf52_2.0.1 ###" - echo "####################################" - echo "" - - mkdir -p "${1}/s132_nrf52_2.0.1" - cd "${1}/s132_nrf52_2.0.1" - wget https://www.nordicsemi.com/api/sitecore/Products/MedialibraryZipDownload2 --post-data="ids=863031714A574444AADFE444EBE5BA9B|&fileName=DeviceDownload" -O temp.zip - unzip -u temp.zip - unzip -u s132nrf52201.zip - rm temp.zip s132nrf52201.zip - cd - -} - -SCRIPT_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -if [ $# -eq 0 ]; then - echo "No Bluetooth LE stack defined, downloading all." - download_s132_nrf52_2_0_1 "${SCRIPT_DIR}" -else - case $1 in - "s132_nrf52_2_0_1" ) - download_s132_nrf52_2_0_1 "${SCRIPT_DIR}" ;; - esac -fi - -exit 0 diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index a955395bd55c5..bebdb31fa2cba 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -33,6 +33,7 @@ #include "py/runtime.h" #include "common-hal/bleio/__init__.h" +#include "common-hal/bleio/Characteristic.h" #include "shared-module/bleio/Characteristic.h" // TODO - should these be per object?? ***** @@ -190,28 +191,41 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) { switch (ble_evt->header.evt_id) { - case BLE_GATTS_EVT_HVN_TX_COMPLETE: - m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; - break; - - case BLE_GATTC_EVT_READ_RSP: - { - ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; - m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data); - // Flag to busy-wait loop that we've read the characteristic. - m_read_characteristic = NULL; - break; - } + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; + break; + + case BLE_GATTC_EVT_READ_RSP: + { + ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; + m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data); + // Flag to busy-wait loop that we've read the characteristic. + m_read_characteristic = NULL; + break; + } + + case BLE_GATTC_EVT_WRITE_RSP: + // Someone else can write now. + sd_mutex_release(m_write_mutex); + break; - case BLE_GATTC_EVT_WRITE_RSP: - // Someone else can write now. - sd_mutex_release(m_write_mutex); - break; + // For debugging. + default: + mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id); + break; } + } -void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self) { - ble_drv_add_event_handler(characteristic_on_ble_evt, NULL); +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props) { + self->service = NULL; + self->uuid = uuid; + self->value_data = NULL; + self->props = props; + self->handle = BLE_GATT_HANDLE_INVALID; + + ble_drv_add_event_handler(characteristic_on_ble_evt, self); + } void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) { diff --git a/ports/nrf/common-hal/bleio/Characteristic.h b/ports/nrf/common-hal/bleio/Characteristic.h new file mode 100644 index 0000000000000..bce1eec1d38a6 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Characteristic.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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_COMMON_HAL_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTIC_H + +#include "shared-module/bleio/Characteristic.h" +#include "shared-module/bleio/Service.h" +#include "common-hal/bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + bleio_service_obj_t *service; + bleio_uuid_obj_t *uuid; + mp_obj_t value_data; + uint16_t handle; + bleio_characteristic_properties_t props; + uint16_t user_desc_handle; + uint16_t cccd_handle; + uint16_t sccd_handle; +} bleio_characteristic_obj_t; + +#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTIC_H diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c new file mode 100644 index 0000000000000..4bd3e147ff813 --- /dev/null +++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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 +#include + +#include "ble_drv.h" +#include "ble_gatts.h" +#include "nrf_soc.h" + +#include "py/runtime.h" + +#include "common-hal/bleio/__init__.h" +#include "common-hal/bleio/CharacteristicBuffer.h" + +STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) { + bleio_characteristic_buffer_obj_t *self = (bleio_characteristic_buffer_obj_t *) param; + switch (ble_evt->header.evt_id) { + case BLE_GATTS_EVT_WRITE: { + 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 == self->characteristic->handle) { + // Push all the data onto the ring buffer. + for (size_t i = 0; i < evt_write->len; i++) { + ringbuf_put(&self->ringbuf, evt_write->data[i]); + } + break; + } + } + } + +} + +// Assumes that buffer_size has been validated before call. +void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, size_t buffer_size) { + + self->characteristic = characteristic; + // This is a macro. + ringbuf_alloc(&self->ringbuf, buffer_size); + + ble_drv_add_event_handler(characteristic_buffer_on_ble_evt, self); + +} + +// Returns a uint8_t byte value, or -1 if no data is available. +int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self) { + return ringbuf_get(&self->ringbuf); +} + +void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) { + ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self); +} diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h b/ports/nrf/common-hal/bleio/CharacteristicBuffer.h new file mode 100644 index 0000000000000..f9ff7dd66da0b --- /dev/null +++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H +#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_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; +} bleio_characteristic_buffer_obj_t; + +#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index 7d5d6a6a6c86e..0f2506de01b47 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -268,7 +268,7 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { } default: - mp_printf(&mp_plat_print, "Unhandled event: 0x%04x\n", ble_evt->header.evt_id); + mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id); break; } } diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index c913c02aea358..26a1f1cff52a9 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -28,6 +28,7 @@ #include "ble.h" #include "py/runtime.h" #include "common-hal/bleio/__init__.h" +#include "common-hal/bleio/Characteristic.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/Adapter.h" @@ -87,6 +88,10 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code); } + if (characteristic->handle != BLE_GATT_HANDLE_INVALID) { + mp_raise_ValueError(translate("Characteristic already in use by another Service.")); + } + characteristic->user_desc_handle = handles.user_desc_handle; characteristic->cccd_handle = handles.cccd_handle; characteristic->sccd_handle = handles.sccd_handle; diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 1d414b6d30ac0..0a3fada139256 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -55,13 +55,13 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t mp_arg_check_num(n_args, n_kw, 1, 1, true); bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); self->base.type = &bleio_characteristic_type; - self->service = NULL; - self->value_data = NULL; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_uuid, ARG_broadcast, ARG_indicate, ARG_notify, ARG_read, ARG_write, ARG_write_no_response }; + enum { + ARG_uuid, ARG_broadcast, ARG_indicate, ARG_notify, ARG_read, ARG_write, ARG_write_no_response, + }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_broadcast, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, @@ -83,14 +83,16 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t self->uuid = MP_OBJ_TO_PTR(uuid); - self->props.broadcast = args[ARG_broadcast].u_bool; - self->props.indicate = args[ARG_indicate].u_bool; - self->props.notify = args[ARG_notify].u_bool; - self->props.read = args[ARG_read].u_bool; - self->props.write = args[ARG_write].u_bool; - self->props.write_no_response = args[ARG_write_no_response].u_bool; + bleio_characteristic_properties_t properties; + + properties.broadcast = args[ARG_broadcast].u_bool; + properties.indicate = args[ARG_indicate].u_bool; + properties.notify = args[ARG_notify].u_bool; + properties.read = args[ARG_read].u_bool; + properties.write = args[ARG_write].u_bool; + properties.write_no_response = args[ARG_write_no_response].u_bool; - common_hal_bleio_characteristic_construct(self); + common_hal_bleio_characteristic_construct(self, uuid, properties); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h index aec60ebbcabad..206cbcd403ec9 100644 --- a/shared-bindings/bleio/Characteristic.h +++ b/shared-bindings/bleio/Characteristic.h @@ -27,11 +27,11 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H -#include "shared-module/bleio/Characteristic.h" +#include "common-hal/bleio/Characteristic.h" extern const mp_obj_type_t bleio_characteristic_type; -extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self); +extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props); extern void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self); extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c new file mode 100644 index 0000000000000..770594d3a556b --- /dev/null +++ b/shared-bindings/bleio/CharacteristicBuffer.c @@ -0,0 +1,119 @@ +/* + * 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. + */ + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/CharacteristicBuffer.h" +#include "shared-bindings/bleio/UUID.h" + +//| .. currentmodule:: bleio +//| +//| :class:`CharacteristicBuffer` -- GATT Service incoming values buffer. +//| ========================================================= +//| +//| Accumulates a Characteristic's incoming values in a FIFO buffer. +//| +//| .. class:: CharacteristicBuffer(Characteristic, buffer_size=0) +//| +//| Create a new Characteristic object identified by the specified UUID. +//| +//| :param bleio.Characteristic characteristic: The characteristic to monitor +//| :param int buffer_size: Size of ring buffer that stores incoming data coming from client. +//| Must be >= 1. +STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 2, true); + bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t); + self->base.type = &bleio_characteristic_buffer_type; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_characteristic, ARG_buffer_size, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_buffer_size, MP_ARG_REQUIRED | MP_ARG_INT }, + }; + + 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); + + const mp_obj_t characteristic = args[ARG_characteristic].u_obj; + const int buffer_size = args[ARG_buffer_size].u_int; + + if (buffer_size < 1) { + mp_raise_ValueError(translate("buffer_size must be >= 1")); + } + + if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) { + mp_raise_ValueError(translate("Expected a Characteristic")); + } + + self->characteristic = MP_OBJ_TO_PTR(characteristic); + + common_hal_bleio_characteristic_buffer_construct(self, self->characteristic, buffer_size); + + return MP_OBJ_FROM_PTR(self); +} + + +//| .. method:: read() +//| +//| Read a single byte from the buffer. If no character is available, return None. +STATIC mp_obj_t bleio_characteristic_buffer_read(mp_obj_t self_in) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + + int byte = common_hal_bleio_characteristic_buffer_read(self); + if (byte == -1) { + return mp_const_none; + } + + return MP_OBJ_NEW_SMALL_INT(byte); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_read_obj, bleio_characteristic_buffer_read); + +//| .. method:: deinit() +//| +//| Disable permanently. +STATIC mp_obj_t bleio_characteristic_buffer_deinit(mp_obj_t self_in) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_bleio_characteristic_buffer_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_deinit_obj, bleio_characteristic_buffer_deinit); + +STATIC const mp_rom_map_elem_t bleio_characteristic_buffer_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_buffer_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_characteristic_buffer_deinit_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_buffer_locals_dict, bleio_characteristic_buffer_locals_dict_table); + +const mp_obj_type_t bleio_characteristic_buffer_type = { + { &mp_type_type }, + .name = MP_QSTR_CharacteristicBuffer, + .make_new = bleio_characteristic_buffer_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_buffer_locals_dict +}; diff --git a/shared-bindings/bleio/CharacteristicBuffer.h b/shared-bindings/bleio/CharacteristicBuffer.h new file mode 100644 index 0000000000000..c5d7580da348d --- /dev/null +++ b/shared-bindings/bleio/CharacteristicBuffer.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H + +#include "common-hal/bleio/CharacteristicBuffer.h" + +extern const mp_obj_type_t bleio_characteristic_buffer_type; + +extern void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, size_t buffer_size); +// Returns a uint8_t byte value, or -1 if no data is available. +int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self); +int common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index d30d599421db4..e23efe36c7d82 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -31,6 +31,7 @@ #include "shared-bindings/bleio/AdvertisementData.h" #include "shared-bindings/bleio/Broadcaster.h" #include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/CharacteristicBuffer.h" #include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/Peripheral.h" #include "shared-bindings/bleio/ScanEntry.h" @@ -77,6 +78,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) }, { MP_ROM_QSTR(MP_QSTR_Broadcaster), MP_ROM_PTR(&bleio_broadcaster_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_Peripheral), MP_ROM_PTR(&bleio_peripheral_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h index 977ec8197653e..958837e64f9a4 100644 --- a/shared-module/bleio/Characteristic.h +++ b/shared-module/bleio/Characteristic.h @@ -27,26 +27,15 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H -#include "shared-module/bleio/Service.h" -#include "common-hal/bleio/UUID.h" - +// Flags for each characteristic property. Common across ports. typedef struct { - mp_obj_base_t base; - bleio_service_obj_t *service; - bleio_uuid_obj_t *uuid; - mp_obj_t value_data; - uint16_t handle; - struct { bool broadcast : 1; bool read : 1; bool write_no_response : 1; bool write : 1; bool notify : 1; bool indicate : 1; - } props; - uint16_t user_desc_handle; - uint16_t cccd_handle; - uint16_t sccd_handle; -} bleio_characteristic_obj_t; +} bleio_characteristic_properties_t; + #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H From ea7791f66ec42906f9903dbaa6ce573a49534a19 Mon Sep 17 00:00:00 2001 From: Hendra Kusumah Date: Wed, 9 Jan 2019 02:00:45 +0700 Subject: [PATCH 061/153] Create ID.po try to merge --- locale/ID.po | 2523 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2523 insertions(+) create mode 100644 locale/ID.po diff --git a/locale/ID.po b/locale/ID.po new file mode 100644 index 0000000000000..76bb14893a18c --- /dev/null +++ b/locale/ID.po @@ -0,0 +1,2523 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: extmod/machine_i2c.c:299 +msgid "invalid I2C peripheral" +msgstr "perangkat I2C tidak valid" + +#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 +#: extmod/machine_i2c.c:392 +msgid "I2C operation not supported" +msgstr "operasi I2C tidak didukung" + +#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53 +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "alamat %08x tidak selaras dengan %d bytes" + +#: extmod/machine_spi.c:57 +msgid "invalid SPI peripheral" +msgstr "perangkat SPI tidak valid" + +#: extmod/machine_spi.c:124 +msgid "buffers must be the same length" +msgstr "buffers harus mempunyai panjang yang sama" + +#: extmod/machine_spi.c:207 +msgid "bits must be 8" +msgstr "bits harus memilki nilai 8" + +#: extmod/machine_spi.c:210 +msgid "firstbit must be MSB" +msgstr "bit pertama(firstbit) harus berupa MSB" + +#: extmod/machine_spi.c:215 +msgid "must specify all of sck/mosi/miso" +msgstr "harus menentukan semua pin sck/mosi/miso" + +#: extmod/modframebuf.c:299 +msgid "invalid format" +msgstr "format tidak valid" + +#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102 +msgid "a bytes-like object is required" +msgstr "sebuah objek menyerupai byte (bytes-like) dibutuhkan" + +#: extmod/modubinascii.c:90 +msgid "odd-length string" +msgstr "panjang data string memiliki keganjilan (odd-length)" + +#: extmod/modubinascii.c:101 +msgid "non-hex digit found" +msgstr "digit non-hex ditemukan" + +#: extmod/modubinascii.c:169 +msgid "incorrect padding" +msgstr "lapisan (padding) tidak benar" + +#: extmod/moductypes.c:122 +msgid "syntax error in uctypes descriptor" +msgstr "sintaksis error pada pendeskripsi uctypes" + +#: extmod/moductypes.c:219 +msgid "Cannot unambiguously get sizeof scalar" +msgstr "tidak dapat mendapatkan ukuran scalar secara tidak ambigu" + +#: extmod/moductypes.c:397 +msgid "struct: no fields" +msgstr "struct: tidak ada fields" + +#: extmod/moductypes.c:530 +msgid "struct: cannot index" +msgstr "struct: tidak bisa melakukan index" + +#: extmod/moductypes.c:544 +msgid "struct: index out of range" +msgstr "struct: index keluar dari jangkauan" + +#: extmod/moduheapq.c:38 +msgid "heap must be a list" +msgstr "heap harus berupa sebuah list" + +#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172 +msgid "empty heap" +msgstr "heap kosong" + +#: extmod/modujson.c:281 +msgid "syntax error in JSON" +msgstr "sintaksis error pada JSON" + +#: extmod/modure.c:161 +msgid "Splitting with sub-captures" +msgstr "Memisahkan dengan menggunakan sub-captures" + +#: extmod/modure.c:207 +msgid "Error in regex" +msgstr "Error pada regex" + +#: extmod/modussl_axtls.c:81 +msgid "invalid key" +msgstr "key tidak valid" + +#: extmod/modussl_axtls.c:87 +msgid "invalid cert" +msgstr "cert tidak valid" + +#: extmod/modutimeq.c:131 +msgid "queue overflow" +msgstr "antrian meluap (overflow)" + +#: extmod/moduzlib.c:98 +msgid "compression header" +msgstr "kompresi header" + +#: extmod/uos_dupterm.c:120 +msgid "invalid dupterm index" +msgstr "indeks dupterm tidak valid" + +#: extmod/vfs_fat.c:426 py/moduerrno.c:150 +msgid "Read-only filesystem" +msgstr "sistem file (filesystem) bersifat Read-only" + +#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43 +msgid "I/O operation on closed file" +msgstr "operasi I/O pada file tertutup" + +#: lib/embed/abort_.c:8 +msgid "abort() called" +msgstr "abort() dipanggil" + +#: lib/netutils/netutils.c:83 +msgid "invalid arguments" +msgstr "argumen-argumen tidak valid" + +#: lib/utils/pyexec.c:97 py/builtinimport.c:251 +msgid "script compilation not supported" +msgstr "kompilasi script tidak didukung" + +#: main.c:154 +msgid " output:\n" +msgstr "output:\n" + +#: main.c:168 main.c:241 +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk menjalankannya atau masuk ke REPL untuk" +"menonaktifkan.\n" + +#: main.c:170 +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Berjalan di mode aman(safe mode)! Auto-reload tidak aktif.\n" + +#: main.c:172 main.c:243 +msgid "Auto-reload is off.\n" +msgstr "Auto-reload tidak aktif.\n" + +#: main.c:186 +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" + +#: main.c:202 +msgid "WARNING: Your code filename has two extensions\n" +msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" + +#: main.c:250 +msgid "You requested starting safe mode by " +msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " + +#: main.c:253 +msgid "To exit, please reset the board without " +msgstr "Untuk keluar, silahkan reset board tanpa " + +#: main.c:260 +msgid "" +"You are running in safe mode which means something really bad happened.\n" +msgstr "Anda sedang menjalankan mode aman (safe mode) yang berarti sesuatu yang sangat buruk telah terjadi.\n" + +#: main.c:262 +msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +msgstr "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" + +#: main.c:263 +msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" +msgstr "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" + +#: main.c:266 +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +msgstr "Tegangan dari mikrokontroler turun atau mati. Pastikan sumber tegangan " +"memberikan daya\n" + +#: main.c:267 +msgid "" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " +"CIRCUITPY).\n" + +#: main.c:271 +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset (Reload)" + +#: main.c:429 +msgid "soft reboot\n" +msgstr "memulai ulang software(soft reboot)\n" + +#: ports/atmel-samd/audio_dma.c:209 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 +msgid "All sync event channels in use" +msgstr "Semua channel event yang disinkronisasi sedang digunakan" + +#: ports/atmel-samd/bindings/samd/Clock.c:135 +msgid "calibration is read only" +msgstr "kalibrasi adalah read only" + +#: ports/atmel-samd/bindings/samd/Clock.c:137 +msgid "calibration is out of range" +msgstr "kalibrasi keluar dari jangkauan" + +#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 +msgid "No default I2C bus" +msgstr "Tidak ada standar bus I2C" + +#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 +msgid "No default SPI bus" +msgstr "Tidak ada standar bus SPI" + +#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 +msgid "No default UART bus" +msgstr "Tidak ada standar bus UART" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 +#: ports/nrf/common-hal/analogio/AnalogIn.c:39 +msgid "Pin does not have ADC capabilities" +msgstr "Pin tidak mempunya kemampuan untuk ADC (Analog Digital Converter)" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49 +msgid "No DAC on chip" +msgstr "Tidak ada DAC (Digital Analog Converter) di dalam chip" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56 +msgid "AnalogOut not supported on given pin" +msgstr "pin yang dipakai tidak mendukung AnalogOut" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 +msgid "Invalid bit clock pin" +msgstr "Bit clock pada pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 +msgid "Bit clock and word select must share a clock unit" +msgstr "Bit clock dan word harus memiliki kesamaan pada clock unit" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 +msgid "Invalid data pin" +msgstr "data pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:169 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:174 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150 +msgid "Serializer in use" +msgstr "Serializer sedang digunakan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230 +msgid "Clock unit in use" +msgstr "Clock unit sedang digunakan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172 +msgid "Unable to find free GCLK" +msgstr "Tidak dapat menemukan GCLK yang kosong" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254 +msgid "Too many channels in sample." +msgstr "Terlalu banyak channel dalam sampel" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 +msgid "No DMA channel found" +msgstr "tidak ada channel DMA ditemukan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 +msgid "Unable to allocate buffers for signed conversion" +msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:109 +msgid "Invalid clock pin" +msgstr "Clock pada pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134 +msgid "Only 8 or 16 bit mono with " +msgstr "Hanya 8 atau 16 bit mono dengan " + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167 +msgid "sampling rate out of range" +msgstr "nilai sampling keluar dari jangkauan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 +msgid "DAC already in use" +msgstr "DAC sudah digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 +msgid "Right channel unsupported" +msgstr "Channel Kanan tidak didukung" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 +msgid "Invalid pin" +msgstr "Pin tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 +msgid "Invalid pin for left channel" +msgstr "Pin untuk channel kiri tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 +msgid "Invalid pin for right channel" +msgstr "Pin untuk channel kanan tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 +msgid "Cannot output both channels on the same pin" +msgstr "Tidak dapat menggunakan output di kedua channel dengan menggunakan pin yang sama" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 +msgid "All timers in use" +msgstr "Semua timer sedang digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 +msgid "All event channels in use" +msgstr "Semua channel event sedang digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Nilai sampel terlalu tinggi. Nilai harus kurang dari %d" + +#: ports/atmel-samd/common-hal/busio/I2C.c:71 +msgid "Not enough pins available" +msgstr "Pin yang tersedia tidak cukup" + +#: ports/atmel-samd/common-hal/busio/I2C.c:78 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/UART.c:119 +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 +#: ports/nrf/common-hal/busio/I2C.c:82 +msgid "Invalid pins" +msgstr "Pin-pin tidak valid" + +#: ports/atmel-samd/common-hal/busio/I2C.c:101 +msgid "SDA or SCL needs a pull up" +msgstr "SDA atau SCL membutuhkan pull up" + +#: ports/atmel-samd/common-hal/busio/I2C.c:121 +msgid "Unsupported baudrate" +msgstr "Baudrate tidak didukung" + +#: ports/atmel-samd/common-hal/busio/UART.c:66 +msgid "bytes > 8 bits not supported" +msgstr "byte > 8 bit tidak didukung" + +#: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 +msgid "tx and rx cannot both be None" +msgstr "tx dan rx keduanya tidak boleh kosong" + +#: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 +msgid "Failed to allocate RX buffer" +msgstr "Gagal untuk mengalokasikan buffer RX" + +#: ports/atmel-samd/common-hal/busio/UART.c:153 +msgid "Could not initialize UART" +msgstr "Tidak dapat menginisialisasi UART" + +#: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 +msgid "No RX pin" +msgstr "Tidak pin RX" + +#: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 +msgid "No TX pin" +msgstr "Tidak ada pin TX" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 +msgid "Cannot get pull while in output mode" +msgstr "Tidak bisa mendapatkan pull pada saat mode output" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 +#: ports/esp8266/common-hal/microcontroller/__init__.c:64 +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "Tidak dapat melakukan reset ke bootloader karena tidak ada bootloader yang terisi" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 +msgid "Invalid PWM frequency" +msgstr "Frekuensi PWM tidak valid" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:187 +msgid "All timers for this pin are in use" +msgstr "Semua timer untuk pin ini sedang digunakan" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 +msgid "No hardware support on pin" +msgstr "Tidak ada dukungan hardware untuk pin" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 +msgid "EXTINT channel already in use" +msgstr "Channel EXTINT sedang digunakan" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +msgid "pop from an empty PulseIn" +msgstr "Muncul dari PulseIn yang kosong" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 +msgid "index out of range" +msgstr "index keluar dari jangkauan" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178 +msgid "Another send is already active" +msgstr "Send yang lain sudah aktif" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38 +msgid "Both pins must support hardware interrupts" +msgstr "Kedua pin harus mendukung hardware interrut" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:46 +msgid "A hardware interrupt channel is already in use" +msgstr "Sebuah channel hardware interrupt sedang digunakan" + +#: ports/atmel-samd/common-hal/rtc/RTC.c:101 +msgid "calibration value out of range +/-127" +msgstr "nilai kalibrasi keluar dari jangkauan +/-127" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 +msgid "No free GCLKs" +msgstr "Tidak ada GCLK yang kosong" + +#: ports/esp8266/common-hal/analogio/AnalogIn.c:43 +msgid "Pin %q does not have ADC capabilities" +msgstr "Pin %q tidak memiliki kemampuan ADC" + +#: ports/esp8266/common-hal/analogio/AnalogOut.c:39 +msgid "No hardware support for analog out." +msgstr "Tidak dukungan hardware untuk analog out." + +#: ports/esp8266/common-hal/busio/SPI.c:72 +msgid "Pins not valid for SPI" +msgstr "Pin-pin tidak valid untuk SPI" + +#: ports/esp8266/common-hal/busio/UART.c:45 +msgid "Only tx supported on UART1 (GPIO2)." +msgstr "Hanya tx yang mendukung pada UART1 (GPIO2)." + +#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 +msgid "invalid data bits" +msgstr "bit data tidak valid" + +#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144 +msgid "invalid stop bits" +msgstr "stop bit tidak valid" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 +msgid "ESP8266 does not support pull down." +msgstr "ESP866 tidak mendukung pull down" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 +msgid "GPIO16 does not support pull up." +msgstr "GPIO16 tidak mendukung pull up" + +#: ports/esp8266/common-hal/microcontroller/__init__.c:66 +msgid "ESP8226 does not support safe mode." +msgstr "ESP8266 tidak mendukung safe mode" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:54 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:113 +#, c-format +msgid "Maximum PWM frequency is %dhz." +msgstr "Nilai maksimum frekuensi PWM adalah %dhz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:57 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:116 +msgid "Minimum PWM frequency is 1hz." +msgstr "Nilai minimum frekuensi PWM is 1hz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:68 +#, c-format +msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +msgstr "Nilai Frekuensi PWM ganda tidak didukung. PWM sudah diatur pada %dhz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 +#, c-format +msgid "PWM not supported on pin %d" +msgstr "PWM tidak didukung pada pin %d" + +#: ports/esp8266/common-hal/pulseio/PulseIn.c:78 +msgid "No PulseIn support for %q" +msgstr "Tidak ada dukungan PulseIn untuk %q" + +#: ports/esp8266/common-hal/storage/__init__.c:34 +msgid "Unable to remount filesystem" +msgstr "Tidak dapat memasang filesystem kembali" + +#: ports/esp8266/common-hal/storage/__init__.c:38 +msgid "Use esptool to erase flash and re-upload Python instead" +msgstr "Gunakan esptool untuk menghapus flash dan upload ulang Python sebagai gantinya" + +#: ports/esp8266/esp_mphal.c:154 +msgid "C-level assert" +msgstr "Dukungan C-level" + +#: ports/esp8266/machine_adc.c:57 +#, c-format +msgid "not a valid ADC Channel: %d" +msgstr "tidak valid channel ADC: %d" + +#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 +msgid "impossible baudrate" +msgstr "baudrate tidak memungkinkan" + +#: ports/esp8266/machine_pin.c:129 +msgid "expecting a pin" +msgstr "mengharapkan sebuah pin" + +#: ports/esp8266/machine_pin.c:284 +msgid "Pin(16) doesn't support pull" +msgstr "Pin(16) tidak mendukung pull" + +#: ports/esp8266/machine_pin.c:323 +msgid "invalid pin" +msgstr "pin tidak valid" + +#: ports/esp8266/machine_pin.c:389 +msgid "pin does not have IRQ capabilities" +msgstr "pin tidak memiliki kemampuan IRQ" + +#: ports/esp8266/machine_rtc.c:185 +msgid "buffer too long" +msgstr "buffer terlalu panjang" + +#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 +#: ports/esp8266/machine_rtc.c:246 +msgid "invalid alarm" +msgstr "alarm tidak valid" + +#: ports/esp8266/machine_uart.c:169 +#, c-format +msgid "UART(%d) does not exist" +msgstr "UART(%d) tidak ada" + +#: ports/esp8266/machine_uart.c:219 +msgid "UART(1) can't read" +msgstr "UART(1) tidak dapat dibaca" + +#: ports/esp8266/modesp.c:119 +msgid "len must be multiple of 4" +msgstr "len harus kelipatan dari 4" + +#: ports/esp8266/modesp.c:274 +#, c-format +msgid "memory allocation failed, allocating %u bytes for native code" +msgstr "alokasi memori gagal, mengalokasikan %u byte untuk kode native" + +#: ports/esp8266/modesp.c:317 +msgid "flash location must be below 1MByte" +msgstr "alokasi flash harus dibawah 1MByte" + +#: ports/esp8266/modmachine.c:63 +msgid "frequency can only be either 80Mhz or 160MHz" +msgstr "frekuensi hanya bisa didefinisikan 80Mhz atau 160Mhz" + +#: ports/esp8266/modnetwork.c:61 +msgid "AP required" +msgstr "AP dibutuhkan" + +#: ports/esp8266/modnetwork.c:61 +msgid "STA required" +msgstr "STA dibutuhkan" + +#: ports/esp8266/modnetwork.c:87 +msgid "Cannot update i/f status" +msgstr "Tidak dapat memperbarui status i/f" + +#: ports/esp8266/modnetwork.c:142 +msgid "Cannot set STA config" +msgstr "Tidak dapat mengatur konfigurasi STA" + +#: ports/esp8266/modnetwork.c:144 +msgid "Cannot connect to AP" +msgstr "Tidak dapat menyambungkan ke AP" + +#: ports/esp8266/modnetwork.c:152 +msgid "Cannot disconnect from AP" +msgstr "Tidak dapat memutuskna dari AP" + +#: ports/esp8266/modnetwork.c:173 +msgid "unknown status param" +msgstr "status param tidak diketahui" + +#: ports/esp8266/modnetwork.c:222 +msgid "STA must be active" +msgstr "STA harus aktif" + +#: ports/esp8266/modnetwork.c:239 +msgid "scan failed" +msgstr "scan gagal" + +#: ports/esp8266/modnetwork.c:306 +msgid "wifi_set_ip_info() failed" +msgstr "wifi_set_ip_info() gagal" + +#: ports/esp8266/modnetwork.c:319 +msgid "either pos or kw args are allowed" +msgstr "hanya antar pos atau kw args yang diperbolehkan" + +#: ports/esp8266/modnetwork.c:329 +msgid "can't get STA config" +msgstr "tidak bisa mendapatkan konfigurasi STA" + +#: ports/esp8266/modnetwork.c:331 +msgid "can't get AP config" +msgstr "tidak bisa mendapatkan konfigurasi AP" + +#: ports/esp8266/modnetwork.c:346 +msgid "invalid buffer length" +msgstr "panjang buffer tidak valid" + +#: ports/esp8266/modnetwork.c:405 +msgid "can't set STA config" +msgstr "tidak bisa mendapatkan konfigurasi STA" + +#: ports/esp8266/modnetwork.c:407 +msgid "can't set AP config" +msgstr "tidak bisa mendapatkan konfigurasi AP" + +#: ports/esp8266/modnetwork.c:416 +msgid "can query only one param" +msgstr "hanya bisa melakukan query satu param" + +#: ports/esp8266/modnetwork.c:469 +msgid "unknown config param" +msgstr "konfigurasi param tidak diketahui" + +#: ports/nrf/common-hal/analogio/AnalogOut.c:37 +msgid "AnalogOut functionality not supported" +msgstr "fungsionalitas AnalogOut tidak didukung" + +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "Gagal untuk mendapatkan alamat lokal, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" +msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover services, status: 0x%08lX" +msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Gagal untuk menyambungkan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Gagal untuk membuat mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Panjang string UUID tidak valid" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parameter UUID tidak valid" + +#: ports/nrf/common-hal/busio/I2C.c:96 +msgid "All I2C peripherals are in use" +msgstr "Semua perangkat I2C sedang digunakan" + +#: ports/nrf/common-hal/busio/SPI.c:133 +msgid "All SPI peripherals are in use" +msgstr "Semua perangkat SPI sedang digunakan" + +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "error = 0x%08lX" + +#: ports/nrf/common-hal/busio/UART.c:86 +msgid "Invalid buffer size" +msgstr "Ukuran buffer tidak valid" + +#: ports/nrf/common-hal/busio/UART.c:90 +msgid "Odd parity is not supported" +msgstr "Parity ganjil tidak didukung" + +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +msgid "busio.UART not available" +msgstr "busio.UART tidak tersedia" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "Tidak bisa mendapatkan temperatur. status: 0x%02x" + +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 +msgid "All PWM peripherals are in use" +msgstr "Semua perangkat PWM sedang digunakan" + +#: ports/unix/modffi.c:138 +msgid "Unknown type" +msgstr "Tipe tidak diketahui" + +#: ports/unix/modffi.c:207 ports/unix/modffi.c:265 +msgid "Error in ffi_prep_cif" +msgstr "Errod pada ffi_prep_cif" + +#: ports/unix/modffi.c:270 +msgid "ffi_prep_closure_loc" +msgstr "ffi_prep_closure_loc" + +#: ports/unix/modffi.c:413 +msgid "Don't know how to pass object to native function" +msgstr "Tidak tahu cara meloloskan objek ke fungsi native" + +#: ports/unix/modusocket.c:474 +#, c-format +msgid "[addrinfo error %d]" +msgstr "[addrinfo error %d]" + +#: py/argcheck.c:44 +msgid "function does not take keyword arguments" +msgstr "fungsi tidak dapat mengambil argumen keyword" + +#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "fungsi mengambil posisi argumen %d tapi %d yang diberikan" + +#: py/argcheck.c:64 +#, c-format +msgid "function missing %d required positional arguments" +msgstr "fungsi kehilangan %d argumen posisi yang dibutuhkan" + +#: py/argcheck.c:72 +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "fungsi diharapkan setidaknya %d argumen, hanya mendapatkan %d" + +#: py/argcheck.c:97 +msgid "'%q' argument required" +msgstr "'%q' argumen dibutuhkan" + +#: py/argcheck.c:122 +msgid "extra positional arguments given" +msgstr "argumen posisi ekstra telah diberikan" + +#: py/argcheck.c:130 +msgid "extra keyword arguments given" +msgstr "argumen keyword ekstra telah diberikan" + +#: py/argcheck.c:142 +msgid "argument num/types mismatch" +msgstr "argumen num/types tidak cocok" + +#: py/argcheck.c:147 +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "argumen keyword belum diimplementasi - gunakan args normal" + +#: py/bc.c:88 py/objnamedtuple.c:108 +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" + +#: py/bc.c:197 py/bc.c:215 +msgid "unexpected keyword argument" +msgstr "argumen keyword tidak diharapkan" + +#: py/bc.c:199 +msgid "keywords must be strings" +msgstr "keyword harus berupa string" + +#: py/bc.c:206 py/objnamedtuple.c:138 +msgid "function got multiple values for argument '%q'" +msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" + +#: py/bc.c:218 py/objnamedtuple.c:130 +msgid "unexpected keyword argument '%q'" +msgstr "keyword argumen '%q' tidak diharapkan" + +#: py/bc.c:244 +#, c-format +msgid "function missing required positional argument #%d" +msgstr "fungsi kehilangan argumen posisi #%d yang dibutuhkan" + +#: py/bc.c:260 +msgid "function missing required keyword argument '%q'" +msgstr "fungsi kehilangan argumen keyword '%q' yang dibutuhkan" + +#: py/bc.c:269 +msgid "function missing keyword-only argument" +msgstr "fungsi kehilangan argumen keyword-only" + +#: py/binary.c:112 +msgid "bad typecode" +msgstr "typecode buruk" + +#: py/builtinevex.c:99 +msgid "bad compile mode" +msgstr "mode compile buruk" + +#: py/builtinhelp.c:137 +msgid "Plus any modules on the filesystem\n" +msgstr "Tambahkan module apapun pada filesystem\n" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Selamat datang ke Adafruit CircuitPython %s!\n" +"\n" +"Silahkan kunjungi learn.adafruit.com/category/circuitpython untuk panduan project.\n" +"\n" +"Untuk menampilkan modul built-in silahkan ketik `help(\"modules\")`.\n" + +#: py/builtinimport.c:336 +msgid "cannot perform relative import" +msgstr "tidak dapat melakukan relative import" + +#: py/builtinimport.c:420 py/builtinimport.c:532 +msgid "module not found" +msgstr "modul tidak ditemukan" + +#: py/builtinimport.c:423 py/builtinimport.c:535 +msgid "no module named '%q'" +msgstr "tidak ada modul yang bernama '%q'" + +#: py/builtinimport.c:510 +msgid "relative import" +msgstr "relative import" + +#: py/compile.c:397 py/compile.c:542 +msgid "can't assign to expression" +msgstr "tidak dapat menetapkan ke ekspresi" + +#: py/compile.c:416 +msgid "multiple *x in assignment" +msgstr "perkalian *x dalam assignment" + +#: py/compile.c:642 +msgid "non-default argument follows default argument" +msgstr "argumen non-default mengikuti argumen standar(default)" + +#: py/compile.c:771 py/compile.c:789 +msgid "invalid micropython decorator" +msgstr "micropython decorator tidak valid" + +#: py/compile.c:943 +msgid "can't delete expression" +msgstr "tidak bisa menghapus ekspresi" + +#: py/compile.c:955 +msgid "'break' outside loop" +msgstr "'break' diluar loop" + +#: py/compile.c:958 +msgid "'continue' outside loop" +msgstr "'continue' diluar loop" + +#: py/compile.c:969 +msgid "'return' outside function" +msgstr "'return' diluar fungsi" + +#: py/compile.c:1169 +msgid "identifier redefined as global" +msgstr "identifier didefinisi ulang sebagai global" + +#: py/compile.c:1185 +msgid "no binding for nonlocal found" +msgstr "tidak ada ikatan/bind pada temuan nonlocal" + +#: py/compile.c:1188 +msgid "identifier redefined as nonlocal" +msgstr "identifier didefinisi ulang sebagai nonlocal" + +#: py/compile.c:1197 +msgid "can't declare nonlocal in outer code" +msgstr "tidak dapat mendeklarasikan nonlocal diluar jangkauan kode" + +#: py/compile.c:1542 +msgid "default 'except' must be last" +msgstr "'except' standar harus terakhir" + +#: py/compile.c:2095 +msgid "*x must be assignment target" +msgstr "*x harus menjadi target assignment" + +#: py/compile.c:2193 +msgid "super() can't find self" +msgstr "super() tidak dapat menemukan dirinya sendiri" + +#: py/compile.c:2256 +msgid "can't have multiple *x" +msgstr "tidak bisa memiliki *x ganda" + +#: py/compile.c:2263 +msgid "can't have multiple **x" +msgstr "tidak bisa memiliki **x ganda" + +#: py/compile.c:2271 +msgid "LHS of keyword arg must be an id" +msgstr "LHS dari keyword arg harus menjadi sebuah id" + +#: py/compile.c:2287 +msgid "non-keyword arg after */**" +msgstr "non-keyword arg setelah */**" + +#: py/compile.c:2291 +msgid "non-keyword arg after keyword arg" +msgstr "non-keyword arg setelah keyword arg" + +#: py/compile.c:2463 py/compile.c:2473 py/compile.c:2712 py/compile.c:2742 +#: py/parse.c:1176 +msgid "invalid syntax" +msgstr "syntax tidak valid" + +#: py/compile.c:2465 +msgid "expecting key:value for dict" +msgstr "key:value diharapkan untuk dict" + +#: py/compile.c:2475 +msgid "expecting just a value for set" +msgstr "hanya mengharapkan sebuah nilai (value) untuk set" + +#: py/compile.c:2600 +msgid "'yield' outside function" +msgstr "'yield' diluar fungsi" + +#: py/compile.c:2619 +msgid "'await' outside function" +msgstr "'await' diluar fungsi" + +#: py/compile.c:2774 +msgid "name reused for argument" +msgstr "nama digunakan kembali untuk argumen" + +#: py/compile.c:2827 +msgid "parameter annotation must be an identifier" +msgstr "anotasi parameter haruse sebuah identifier" + +#: py/compile.c:2969 py/compile.c:3137 +msgid "return annotation must be an identifier" +msgstr "anotasi return harus sebuah identifier" + +#: py/compile.c:3097 +msgid "inline assembler must be a function" +msgstr "inline assembler harus sebuah fungsi" + +#: py/compile.c:3134 +msgid "unknown type" +msgstr "tipe tidak diketahui" + +#: py/compile.c:3154 +msgid "expecting an assembler instruction" +msgstr "sebuah instruksi assembler diharapkan" + +#: py/compile.c:3184 +msgid "'label' requires 1 argument" +msgstr "'label' membutuhkan 1 argumen" + +#: py/compile.c:3190 +msgid "label redefined" +msgstr "label didefinis ulang" + +#: py/compile.c:3196 +msgid "'align' requires 1 argument" +msgstr "'align' membutuhkan 1 argumen" + +#: py/compile.c:3205 +msgid "'data' requires at least 2 arguments" +msgstr "'data' membutuhkan setidaknya 2 argumen" + +#: py/compile.c:3212 +msgid "'data' requires integer arguments" +msgstr "'data' membutuhkan argumen integer" + +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "hanya mampu memiliki hingga 4 parameter untuk Thumb assembly" + +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +msgid "parameters must be registers in sequence r0 to r3" +msgstr "parameter harus menjadi register dalam urutan r0 sampai r3" + +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' mengharapkan setidaknya r%d" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' mengharapkan sebuah register" + +#: py/emitinlinethumb.c:211 +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' mengharapkan sebuah register spesial" + +#: py/emitinlinethumb.c:239 +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' mengharapkan sebuah FPU register" + +#: py/emitinlinethumb.c:292 +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' mengharapkan {r0, r1, ...}" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' mengharapkan integer" + +#: py/emitinlinethumb.c:304 +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' integer 0x%x tidak cukup didalam mask 0x%x" + +#: py/emitinlinethumb.c:328 +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' mengharapkan sebuah alamat dengan bentuk [a, b]" + +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 +msgid "label '%q' not defined" +msgstr "" + +#: py/emitinlinethumb.c:806 +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinethumb.c:810 +msgid "branch not in range" +msgstr "" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinextensa.c:327 +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/emitnative.c:183 +msgid "unknown type '%q'" +msgstr "" + +#: py/emitnative.c:260 +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: py/emitnative.c:742 +msgid "conversion to object" +msgstr "" + +#: py/emitnative.c:921 +msgid "local '%q' used before type known" +msgstr "" + +#: py/emitnative.c:1118 py/emitnative.c:1156 +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c:1128 +msgid "can't load with '%q' index" +msgstr "" + +#: py/emitnative.c:1188 +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c:1289 py/emitnative.c:1379 +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c:1358 py/emitnative.c:1419 +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c:1369 +msgid "can't store with '%q' index" +msgstr "" + +#: py/emitnative.c:1540 +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c:1774 +msgid "unary op %q not implemented" +msgstr "" + +#: py/emitnative.c:1930 +msgid "binary op %q not implemented" +msgstr "" + +#: py/emitnative.c:1951 +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/emitnative.c:2126 +msgid "casting" +msgstr "" + +#: py/emitnative.c:2173 +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/emitnative.c:2191 +msgid "must raise an object" +msgstr "" + +#: py/emitnative.c:2201 +msgid "native yield" +msgstr "" + +#: py/lexer.c:345 +msgid "unicode name escapes" +msgstr "" + +#: py/modbuiltins.c:162 +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c:171 +msgid "chr() arg not in range(256)" +msgstr "" + +#: py/modbuiltins.c:285 +msgid "arg is an empty sequence" +msgstr "" + +#: py/modbuiltins.c:350 +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c:353 +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/modbuiltins.c:363 +msgid "3-arg pow() not supported" +msgstr "" + +#: py/modbuiltins.c:517 +msgid "must use keyword argument for key function" +msgstr "" + +#: py/modmath.c:41 shared-bindings/math/__init__.c:53 +msgid "math domain error" +msgstr "" + +#: py/modmath.c:196 py/objfloat.c:270 py/objint_longlong.c:222 +#: py/objint_mpz.c:230 py/runtime.c:619 shared-bindings/math/__init__.c:346 +msgid "division by zero" +msgstr "" + +#: py/modmicropython.c:155 +msgid "schedule stack full" +msgstr "" + +#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 +#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 +#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +msgid "buffer too small" +msgstr "" + +#: py/modthread.c:240 +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/moduerrno.c:143 py/moduerrno.c:146 +msgid "Permission denied" +msgstr "" + +#: py/moduerrno.c:144 +msgid "No such file/directory" +msgstr "" + +#: py/moduerrno.c:145 +msgid "Input/output error" +msgstr "" + +#: py/moduerrno.c:147 +msgid "File exists" +msgstr "" + +#: py/moduerrno.c:148 +msgid "Unsupported operation" +msgstr "" + +#: py/moduerrno.c:149 +msgid "Invalid argument" +msgstr "" + +#: py/obj.c:90 +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: py/obj.c:94 +msgid " File \"%q\", line %d" +msgstr "" + +#: py/obj.c:96 +msgid " File \"%q\"" +msgstr "" + +#: py/obj.c:100 +msgid ", in %q\n" +msgstr "" + +#: py/obj.c:257 +msgid "can't convert to int" +msgstr "" + +#: py/obj.c:260 +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/obj.c:320 +msgid "can't convert to float" +msgstr "" + +#: py/obj.c:323 +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c:353 +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c:356 +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c:371 +msgid "expected tuple/list" +msgstr "" + +#: py/obj.c:374 +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c:385 +msgid "tuple/list has wrong length" +msgstr "" + +#: py/obj.c:387 +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/obj.c:400 +msgid "indices must be integers" +msgstr "" + +#: py/obj.c:403 +msgid "%q indices must be integers, not %s" +msgstr "" + +#: py/obj.c:423 +msgid "%q index out of range" +msgstr "" + +#: py/obj.c:455 +msgid "object has no len" +msgstr "" + +#: py/obj.c:458 +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c:496 +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c:499 +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/obj.c:503 +msgid "object is not subscriptable" +msgstr "" + +#: py/obj.c:506 +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/obj.c:510 +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c:513 +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c:544 +msgid "object with buffer protocol required" +msgstr "" + +#: py/objarray.c:413 py/objstr.c:427 py/objstrunicode.c:191 py/objtuple.c:187 +#: shared-bindings/nvm/ByteArray.c:85 +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/objarray.c:426 +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/objarray.c:444 shared-bindings/nvm/ByteArray.c:107 +msgid "array/bytes required on right side" +msgstr "" + +#: py/objcomplex.c:203 +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/objcomplex.c:209 +msgid "complex division by zero" +msgstr "" + +#: py/objcomplex.c:237 +msgid "0.0 to a complex power" +msgstr "" + +#: py/objdeque.c:107 +msgid "full" +msgstr "" + +#: py/objdeque.c:127 +msgid "empty" +msgstr "" + +#: py/objdict.c:314 +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objdict.c:357 +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/objfloat.c:308 py/parsenum.c:331 +msgid "complex values not supported" +msgstr "" + +#: py/objgenerator.c:108 +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objgenerator.c:126 +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c:229 +msgid "generator ignored GeneratorExit" +msgstr "" + +#: py/objgenerator.c:251 +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objint.c:144 +msgid "can't convert inf to int" +msgstr "" + +#: py/objint.c:146 +msgid "can't convert NaN to int" +msgstr "" + +#: py/objint.c:163 +msgid "float too big" +msgstr "" + +#: py/objint.c:328 +msgid "long int not supported in this build" +msgstr "" + +#: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 +msgid "small int overflow" +msgstr "" + +#: py/objint_longlong.c:189 py/objint_mpz.c:283 py/runtime.c:486 +msgid "negative power with no float support" +msgstr "" + +#: py/objint_longlong.c:251 +msgid "ulonglong too large" +msgstr "" + +#: py/objint_mpz.c:267 py/runtime.c:396 py/runtime.c:411 +msgid "negative shift count" +msgstr "" + +#: py/objint_mpz.c:336 +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: py/objint_mpz.c:347 +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c:415 +msgid "overflow converting long int to machine word" +msgstr "" + +#: py/objlist.c:273 +msgid "pop from empty list" +msgstr "" + +#: py/objnamedtuple.c:92 +msgid "can't set attribute" +msgstr "" + +#: py/objobject.c:55 +msgid "__new__ arg must be a user-type" +msgstr "" + +#: py/objrange.c:110 +msgid "zero step" +msgstr "" + +#: py/objset.c:371 +msgid "pop from an empty set" +msgstr "" + +#: py/objslice.c:66 +msgid "Length must be an int" +msgstr "" + +#: py/objslice.c:71 +msgid "Length must be non-negative" +msgstr "" + +#: py/objslice.c:86 py/sequence.c:57 +msgid "slice step cannot be zero" +msgstr "" + +#: py/objslice.c:159 +msgid "Cannot subclass slice" +msgstr "" + +#: py/objstr.c:261 +msgid "bytes value out of range" +msgstr "" + +#: py/objstr.c:270 +msgid "wrong number of arguments" +msgstr "" + +#: py/objstr.c:467 +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744 +msgid "empty separator" +msgstr "" + +#: py/objstr.c:641 +msgid "rsplit(None,n)" +msgstr "" + +#: py/objstr.c:713 +msgid "substring not found" +msgstr "" + +#: py/objstr.c:770 +msgid "start/end indices" +msgstr "" + +#: py/objstr.c:931 +msgid "bad format string" +msgstr "" + +#: py/objstr.c:953 +msgid "single '}' encountered in format string" +msgstr "" + +#: py/objstr.c:992 +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c:996 +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: py/objstr.c:998 +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c:1029 +msgid "unmatched '{' in format" +msgstr "" + +#: py/objstr.c:1036 +msgid "expected ':' after format specifier" +msgstr "" + +#: py/objstr.c:1050 +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c:1055 py/objstr.c:1083 +msgid "tuple index out of range" +msgstr "" + +#: py/objstr.c:1071 +msgid "attributes not supported yet" +msgstr "" + +#: py/objstr.c:1079 +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objstr.c:1171 +msgid "invalid format specifier" +msgstr "" + +#: py/objstr.c:1192 +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1200 +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c:1259 +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c:1331 +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c:1343 +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1367 +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/objstr.c:1415 +msgid "format requires a dict" +msgstr "" + +#: py/objstr.c:1424 +msgid "incomplete format key" +msgstr "" + +#: py/objstr.c:1482 +msgid "incomplete format" +msgstr "" + +#: py/objstr.c:1490 +msgid "not enough arguments for format string" +msgstr "" + +#: py/objstr.c:1500 +#, c-format +msgid "%%c requires int or char" +msgstr "" + +#: py/objstr.c:1507 +msgid "integer required" +msgstr "" + +#: py/objstr.c:1570 +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/objstr.c:1577 +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c:2102 +msgid "can't convert to str implicitly" +msgstr "" + +#: py/objstr.c:2106 +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objstrunicode.c:134 +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/objstrunicode.c:145 py/objstrunicode.c:164 +msgid "string index out of range" +msgstr "" + +#: py/objtype.c:358 +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c:360 +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +msgid "unreadable attribute" +msgstr "" + +#: py/objtype.c:868 py/runtime.c:653 +msgid "object not callable" +msgstr "" + +#: py/objtype.c:870 py/runtime.c:655 +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/objtype.c:978 +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objtype.c:989 +msgid "cannot create instance" +msgstr "" + +#: py/objtype.c:991 +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c:1047 +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/objtype.c:1091 py/objtype.c:1097 +msgid "type is not an acceptable base type" +msgstr "" + +#: py/objtype.c:1100 +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c:1137 +msgid "multiple inheritance not supported" +msgstr "" + +#: py/objtype.c:1164 +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c:1205 +msgid "first argument to super() must be type" +msgstr "" + +#: py/objtype.c:1370 +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objtype.c:1384 +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/parse.c:726 +msgid "constant must be an integer" +msgstr "" + +#: py/parse.c:868 +msgid "Unable to init parser" +msgstr "" + +#: py/parse.c:1170 +msgid "unexpected indent" +msgstr "" + +#: py/parse.c:1173 +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/parsenum.c:60 +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/parsenum.c:151 +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c:155 +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c:339 +msgid "invalid syntax for number" +msgstr "" + +#: py/parsenum.c:342 +msgid "decimal numbers not supported" +msgstr "" + +#: py/persistentcode.c:223 +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: py/persistentcode.c:326 +msgid "can only save bytecode" +msgstr "" + +#: py/runtime.c:206 +msgid "name not defined" +msgstr "" + +#: py/runtime.c:209 +msgid "name '%q' is not defined" +msgstr "" + +#: py/runtime.c:304 py/runtime.c:611 +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c:307 +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c:614 +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/runtime.c:881 py/runtime.c:888 py/runtime.c:945 +msgid "wrong number of values to unpack" +msgstr "" + +#: py/runtime.c:883 py/runtime.c:947 +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/runtime.c:890 +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/runtime.c:984 +msgid "argument has wrong type" +msgstr "" + +#: py/runtime.c:986 +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/runtime.c:1123 py/runtime.c:1197 +msgid "no such attribute" +msgstr "" + +#: py/runtime.c:1128 +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/runtime.c:1132 py/runtime.c:1200 +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c:1238 +msgid "object not iterable" +msgstr "" + +#: py/runtime.c:1241 +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/runtime.c:1260 py/runtime.c:1296 +msgid "object not an iterator" +msgstr "" + +#: py/runtime.c:1262 py/runtime.c:1298 +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/runtime.c:1401 +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/runtime.c:1430 +msgid "cannot import name %q" +msgstr "" + +#: py/runtime.c:1535 +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/runtime.c:1539 +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c:1609 +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/sequence.c:264 +msgid "object not in sequence" +msgstr "" + +#: py/stream.c:96 +msgid "stream operation not supported" +msgstr "" + +#: py/vm.c:255 +msgid "local variable referenced before assignment" +msgstr "" + +#: py/vm.c:1142 +msgid "no active exception to reraise" +msgstr "" + +#: py/vm.c:1284 +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_stage/Layer.c:71 +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: shared-bindings/_stage/Layer.c:77 shared-bindings/_stage/Text.c:75 +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/_stage/Layer.c:84 +msgid "map buffer too small" +msgstr "" + +#: shared-bindings/_stage/Text.c:69 +msgid "font must be 2048 bytes long" +msgstr "" + +#: shared-bindings/_stage/Text.c:81 +msgid "chars buffer too small" +msgstr "" + +#: shared-bindings/analogio/AnalogOut.c:118 +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: shared-bindings/audiobusio/I2SOut.c:225 +#: shared-bindings/audioio/AudioOut.c:226 +msgid "Not playing" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:124 +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:128 +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:136 +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:193 +msgid "destination_length must be an int >= 0" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:199 +msgid "Cannot record to a file" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:202 +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:206 +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:208 +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:94 +msgid "Invalid voice count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:99 +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:103 +msgid "Sample rate must be positive" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:107 +msgid "bits_per_sample must be 8 or 16" +msgstr "" + +#: shared-bindings/audioio/RawSample.c:98 +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: shared-bindings/audioio/RawSample.c:104 +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-bindings/audioio/WaveFile.c:78 +#: shared-bindings/displayio/OnDiskBitmap.c:85 +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 +#: shared-bindings/busio/SPI.c:133 +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +msgid "Buffer must be at least length 1" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +msgid "Invalid phase" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +msgid "Invalid number of bits" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +msgid "buffer slices must be of equal length" +msgstr "" + +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + +#: shared-bindings/busio/I2C.c:120 +msgid "Function requires lock." +msgstr "" + +#: shared-bindings/busio/UART.c:102 +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: shared-bindings/busio/UART.c:114 +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:211 +msgid "Invalid direction." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:240 +msgid "Cannot set value when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:266 +#: shared-bindings/digitalio/DigitalInOut.c:281 +msgid "Drive mode not used when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:314 +#: shared-bindings/digitalio/DigitalInOut.c:331 +msgid "Pull not used when direction is output." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:340 +msgid "Unsupported pull value." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:84 +msgid "y should be an int" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:89 +msgid "row buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:94 +msgid "row data must be a buffer" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c:72 +msgid "color should be an int" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:55 +#: shared-bindings/displayio/FourWire.c:64 +msgid "displayio is a work in progress" +msgstr "" + +#: shared-bindings/displayio/Group.c:65 +msgid "Group must have size at least 1" +msgstr "" + +#: shared-bindings/displayio/Palette.c:96 +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c:102 +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c:106 +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/Palette.c:110 +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c:123 +#: shared-bindings/displayio/Palette.c:137 +msgid "palette_index should be an int" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:48 +msgid "position must be 2-tuple" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:97 +msgid "unsupported bitmap type" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:162 +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: shared-bindings/gamepad/GamePad.c:100 +msgid "too many arguments" +msgstr "" + +#: shared-bindings/gamepad/GamePad.c:104 +msgid "expected a DigitalInOut" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:98 +msgid "can't convert address to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:101 +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:107 +msgid "addresses is empty" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c:89 +#: shared-bindings/neopixel_write/__init__.c:67 +#: shared-bindings/pulseio/PulseOut.c:76 +msgid "Expected a %q" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c:100 +msgid "%q in use" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c:126 +msgid "Invalid run mode." +msgstr "" + +#: shared-bindings/multiterminal/__init__.c:68 +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:99 +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:104 +msgid "Array values should be single bytes." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141 +msgid "Unable to write to nvm." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:137 +msgid "Bytes must be between 0 and 255." +msgstr "" + +#: shared-bindings/os/__init__.c:200 +msgid "No hardware random available" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c:164 +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c:195 +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:275 +msgid "Cannot delete values" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:281 +msgid "Slices not supported" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:287 +msgid "index must be int" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:293 +msgid "Read-only" +msgstr "" + +#: shared-bindings/pulseio/PulseOut.c:135 +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100 +msgid "stop not reachable from start" +msgstr "" + +#: shared-bindings/random/__init__.c:111 +msgid "step must be non-zero" +msgstr "" + +#: shared-bindings/random/__init__.c:114 +msgid "invalid step" +msgstr "" + +#: shared-bindings/random/__init__.c:146 +msgid "empty sequence" +msgstr "" + +#: shared-bindings/rtc/RTC.c:40 shared-bindings/rtc/RTC.c:44 +#: shared-bindings/time/__init__.c:190 +msgid "RTC is not supported on this board" +msgstr "" + +#: shared-bindings/rtc/RTC.c:52 +msgid "RTC calibration is not supported on this board" +msgstr "" + +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:81 +msgid "no available NIC" +msgstr "" + +#: shared-bindings/storage/__init__.c:77 +msgid "filesystem must provide mount method" +msgstr "" + +#: shared-bindings/supervisor/__init__.c:93 +msgid "Brightness must be between 0 and 255" +msgstr "" + +#: shared-bindings/supervisor/__init__.c:119 +msgid "Stack size must be at least 256" +msgstr "" + +#: shared-bindings/time/__init__.c:78 +msgid "sleep length must be non-negative" +msgstr "" + +#: shared-bindings/time/__init__.c:88 +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/time/__init__.c:91 +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:264 +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:269 +msgid "function takes exactly 9 arguments" +msgstr "" + +#: shared-bindings/time/__init__.c:240 shared-bindings/time/__init__.c:273 +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-bindings/touchio/TouchIn.c:173 +msgid "threshold must be in the range 0-65536" +msgstr "" + +#: shared-bindings/util.c:38 +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" + +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-module/audioio/WaveFile.c:61 +msgid "Invalid wave file" +msgstr "" + +#: shared-module/audioio/WaveFile.c:69 +msgid "Invalid format chunk size" +msgstr "" + +#: shared-module/audioio/WaveFile.c:83 +msgid "Unsupported format" +msgstr "" + +#: shared-module/audioio/WaveFile.c:99 +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: shared-module/audioio/WaveFile.c:107 +msgid "Invalid file" +msgstr "" + +#: shared-module/bitbangio/I2C.c:58 +msgid "Clock stretch too long" +msgstr "" + +#: shared-module/bitbangio/SPI.c:44 +msgid "Clock pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:50 +msgid "MOSI pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:61 +msgid "MISO pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:121 +msgid "Cannot write without MOSI pin." +msgstr "" + +#: shared-module/bitbangio/SPI.c:176 +msgid "Cannot read without MISO pin." +msgstr "" + +#: shared-module/bitbangio/SPI.c:240 +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "" + +#: shared-module/displayio/Bitmap.c:49 +msgid "Only bit maps of 8 bit color or less are supported" +msgstr "" + +#: shared-module/displayio/Bitmap.c:69 +msgid "row must be packed and word aligned" +msgstr "" + +#: shared-module/displayio/Group.c:39 +msgid "Group full" +msgstr "" + +#: shared-module/displayio/Group.c:48 +msgid "Group empty" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:49 +msgid "Invalid BMP file" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:59 +#, c-format +msgid "Only Windows format, uncompressed BMP supported %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:64 +#, c-format +msgid "Only true color (24 bpp or higher) BMP supported %x" +msgstr "" + +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "" + +#: shared-module/struct/__init__.c:39 +msgid "'S' and 'O' are not supported format types" +msgstr "" + +#: shared-module/struct/__init__.c:83 +msgid "too many arguments provided with the given format" +msgstr "" + +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "" From dda139a557f240ec3b66b319c4d4ae944aece87f Mon Sep 17 00:00:00 2001 From: Hendra Kusumah Date: Wed, 9 Jan 2019 02:19:18 +0700 Subject: [PATCH 062/153] Delete ID.po --- locale/ID.po | 2523 -------------------------------------------------- 1 file changed, 2523 deletions(-) delete mode 100644 locale/ID.po diff --git a/locale/ID.po b/locale/ID.po deleted file mode 100644 index 76bb14893a18c..0000000000000 --- a/locale/ID.po +++ /dev/null @@ -1,2523 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-09 16:20-0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: extmod/machine_i2c.c:299 -msgid "invalid I2C peripheral" -msgstr "perangkat I2C tidak valid" - -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 -msgid "I2C operation not supported" -msgstr "operasi I2C tidak didukung" - -#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53 -#, c-format -msgid "address %08x is not aligned to %d bytes" -msgstr "alamat %08x tidak selaras dengan %d bytes" - -#: extmod/machine_spi.c:57 -msgid "invalid SPI peripheral" -msgstr "perangkat SPI tidak valid" - -#: extmod/machine_spi.c:124 -msgid "buffers must be the same length" -msgstr "buffers harus mempunyai panjang yang sama" - -#: extmod/machine_spi.c:207 -msgid "bits must be 8" -msgstr "bits harus memilki nilai 8" - -#: extmod/machine_spi.c:210 -msgid "firstbit must be MSB" -msgstr "bit pertama(firstbit) harus berupa MSB" - -#: extmod/machine_spi.c:215 -msgid "must specify all of sck/mosi/miso" -msgstr "harus menentukan semua pin sck/mosi/miso" - -#: extmod/modframebuf.c:299 -msgid "invalid format" -msgstr "format tidak valid" - -#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102 -msgid "a bytes-like object is required" -msgstr "sebuah objek menyerupai byte (bytes-like) dibutuhkan" - -#: extmod/modubinascii.c:90 -msgid "odd-length string" -msgstr "panjang data string memiliki keganjilan (odd-length)" - -#: extmod/modubinascii.c:101 -msgid "non-hex digit found" -msgstr "digit non-hex ditemukan" - -#: extmod/modubinascii.c:169 -msgid "incorrect padding" -msgstr "lapisan (padding) tidak benar" - -#: extmod/moductypes.c:122 -msgid "syntax error in uctypes descriptor" -msgstr "sintaksis error pada pendeskripsi uctypes" - -#: extmod/moductypes.c:219 -msgid "Cannot unambiguously get sizeof scalar" -msgstr "tidak dapat mendapatkan ukuran scalar secara tidak ambigu" - -#: extmod/moductypes.c:397 -msgid "struct: no fields" -msgstr "struct: tidak ada fields" - -#: extmod/moductypes.c:530 -msgid "struct: cannot index" -msgstr "struct: tidak bisa melakukan index" - -#: extmod/moductypes.c:544 -msgid "struct: index out of range" -msgstr "struct: index keluar dari jangkauan" - -#: extmod/moduheapq.c:38 -msgid "heap must be a list" -msgstr "heap harus berupa sebuah list" - -#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172 -msgid "empty heap" -msgstr "heap kosong" - -#: extmod/modujson.c:281 -msgid "syntax error in JSON" -msgstr "sintaksis error pada JSON" - -#: extmod/modure.c:161 -msgid "Splitting with sub-captures" -msgstr "Memisahkan dengan menggunakan sub-captures" - -#: extmod/modure.c:207 -msgid "Error in regex" -msgstr "Error pada regex" - -#: extmod/modussl_axtls.c:81 -msgid "invalid key" -msgstr "key tidak valid" - -#: extmod/modussl_axtls.c:87 -msgid "invalid cert" -msgstr "cert tidak valid" - -#: extmod/modutimeq.c:131 -msgid "queue overflow" -msgstr "antrian meluap (overflow)" - -#: extmod/moduzlib.c:98 -msgid "compression header" -msgstr "kompresi header" - -#: extmod/uos_dupterm.c:120 -msgid "invalid dupterm index" -msgstr "indeks dupterm tidak valid" - -#: extmod/vfs_fat.c:426 py/moduerrno.c:150 -msgid "Read-only filesystem" -msgstr "sistem file (filesystem) bersifat Read-only" - -#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43 -msgid "I/O operation on closed file" -msgstr "operasi I/O pada file tertutup" - -#: lib/embed/abort_.c:8 -msgid "abort() called" -msgstr "abort() dipanggil" - -#: lib/netutils/netutils.c:83 -msgid "invalid arguments" -msgstr "argumen-argumen tidak valid" - -#: lib/utils/pyexec.c:97 py/builtinimport.c:251 -msgid "script compilation not supported" -msgstr "kompilasi script tidak didukung" - -#: main.c:154 -msgid " output:\n" -msgstr "output:\n" - -#: main.c:168 main.c:241 -msgid "" -"Auto-reload is on. Simply save files over USB to run them or enter REPL to " -"disable.\n" -msgstr "Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk menjalankannya atau masuk ke REPL untuk" -"menonaktifkan.\n" - -#: main.c:170 -msgid "Running in safe mode! Auto-reload is off.\n" -msgstr "Berjalan di mode aman(safe mode)! Auto-reload tidak aktif.\n" - -#: main.c:172 main.c:243 -msgid "Auto-reload is off.\n" -msgstr "Auto-reload tidak aktif.\n" - -#: main.c:186 -msgid "Running in safe mode! Not running saved code.\n" -msgstr "Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" - -#: main.c:202 -msgid "WARNING: Your code filename has two extensions\n" -msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" - -#: main.c:250 -msgid "You requested starting safe mode by " -msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " - -#: main.c:253 -msgid "To exit, please reset the board without " -msgstr "Untuk keluar, silahkan reset board tanpa " - -#: main.c:260 -msgid "" -"You are running in safe mode which means something really bad happened.\n" -msgstr "Anda sedang menjalankan mode aman (safe mode) yang berarti sesuatu yang sangat buruk telah terjadi.\n" - -#: main.c:262 -msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -msgstr "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" - -#: main.c:263 -msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" -msgstr "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" - -#: main.c:266 -msgid "" -"The microcontroller's power dipped. Please make sure your power supply " -"provides\n" -msgstr "Tegangan dari mikrokontroler turun atau mati. Pastikan sumber tegangan " -"memberikan daya\n" - -#: main.c:267 -msgid "" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY).\n" -msgstr "" -"tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " -"CIRCUITPY).\n" - -#: main.c:271 -msgid "Press any key to enter the REPL. Use CTRL-D to reload." -msgstr "Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset (Reload)" - -#: main.c:429 -msgid "soft reboot\n" -msgstr "memulai ulang software(soft reboot)\n" - -#: ports/atmel-samd/audio_dma.c:209 -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 -msgid "All sync event channels in use" -msgstr "Semua channel event yang disinkronisasi sedang digunakan" - -#: ports/atmel-samd/bindings/samd/Clock.c:135 -msgid "calibration is read only" -msgstr "kalibrasi adalah read only" - -#: ports/atmel-samd/bindings/samd/Clock.c:137 -msgid "calibration is out of range" -msgstr "kalibrasi keluar dari jangkauan" - -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "Tidak ada standar bus I2C" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "Tidak ada standar bus SPI" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "Tidak ada standar bus UART" - -#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 -#: ports/nrf/common-hal/analogio/AnalogIn.c:39 -msgid "Pin does not have ADC capabilities" -msgstr "Pin tidak mempunya kemampuan untuk ADC (Analog Digital Converter)" - -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49 -msgid "No DAC on chip" -msgstr "Tidak ada DAC (Digital Analog Converter) di dalam chip" - -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56 -msgid "AnalogOut not supported on given pin" -msgstr "pin yang dipakai tidak mendukung AnalogOut" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 -msgid "Invalid bit clock pin" -msgstr "Bit clock pada pin tidak valid" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 -msgid "Bit clock and word select must share a clock unit" -msgstr "Bit clock dan word harus memiliki kesamaan pada clock unit" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 -msgid "Invalid data pin" -msgstr "data pin tidak valid" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:169 -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:174 -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145 -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150 -msgid "Serializer in use" -msgstr "Serializer sedang digunakan" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230 -msgid "Clock unit in use" -msgstr "Clock unit sedang digunakan" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240 -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172 -msgid "Unable to find free GCLK" -msgstr "Tidak dapat menemukan GCLK yang kosong" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254 -msgid "Too many channels in sample." -msgstr "Terlalu banyak channel dalam sampel" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 -msgid "No DMA channel found" -msgstr "tidak ada channel DMA ditemukan" - -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 -msgid "Unable to allocate buffers for signed conversion" -msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion" - -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:109 -msgid "Invalid clock pin" -msgstr "Clock pada pin tidak valid" - -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134 -msgid "Only 8 or 16 bit mono with " -msgstr "Hanya 8 atau 16 bit mono dengan " - -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167 -msgid "sampling rate out of range" -msgstr "nilai sampling keluar dari jangkauan" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 -msgid "DAC already in use" -msgstr "DAC sudah digunakan" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 -msgid "Right channel unsupported" -msgstr "Channel Kanan tidak didukung" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 -#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 -#: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 -msgid "Invalid pin" -msgstr "Pin tidak valid" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 -msgid "Invalid pin for left channel" -msgstr "Pin untuk channel kiri tidak valid" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 -msgid "Invalid pin for right channel" -msgstr "Pin untuk channel kanan tidak valid" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 -msgid "Cannot output both channels on the same pin" -msgstr "Tidak dapat menggunakan output di kedua channel dengan menggunakan pin yang sama" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 -#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 -#: ports/nrf/common-hal/pulseio/PulseOut.c:107 -msgid "All timers in use" -msgstr "Semua timer sedang digunakan" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 -msgid "All event channels in use" -msgstr "Semua channel event sedang digunakan" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 -#, c-format -msgid "Sample rate too high. It must be less than %d" -msgstr "Nilai sampel terlalu tinggi. Nilai harus kurang dari %d" - -#: ports/atmel-samd/common-hal/busio/I2C.c:71 -msgid "Not enough pins available" -msgstr "Pin yang tersedia tidak cukup" - -#: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 -#: ports/atmel-samd/common-hal/busio/UART.c:119 -#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 -msgid "Invalid pins" -msgstr "Pin-pin tidak valid" - -#: ports/atmel-samd/common-hal/busio/I2C.c:101 -msgid "SDA or SCL needs a pull up" -msgstr "SDA atau SCL membutuhkan pull up" - -#: ports/atmel-samd/common-hal/busio/I2C.c:121 -msgid "Unsupported baudrate" -msgstr "Baudrate tidak didukung" - -#: ports/atmel-samd/common-hal/busio/UART.c:66 -msgid "bytes > 8 bits not supported" -msgstr "byte > 8 bit tidak didukung" - -#: ports/atmel-samd/common-hal/busio/UART.c:72 -#: ports/nrf/common-hal/busio/UART.c:82 -msgid "tx and rx cannot both be None" -msgstr "tx dan rx keduanya tidak boleh kosong" - -#: ports/atmel-samd/common-hal/busio/UART.c:145 -#: ports/nrf/common-hal/busio/UART.c:115 -msgid "Failed to allocate RX buffer" -msgstr "Gagal untuk mengalokasikan buffer RX" - -#: ports/atmel-samd/common-hal/busio/UART.c:153 -msgid "Could not initialize UART" -msgstr "Tidak dapat menginisialisasi UART" - -#: ports/atmel-samd/common-hal/busio/UART.c:240 -#: ports/nrf/common-hal/busio/UART.c:149 -msgid "No RX pin" -msgstr "Tidak pin RX" - -#: ports/atmel-samd/common-hal/busio/UART.c:294 -#: ports/nrf/common-hal/busio/UART.c:195 -msgid "No TX pin" -msgstr "Tidak ada pin TX" - -#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 -msgid "Cannot get pull while in output mode" -msgstr "Tidak bisa mendapatkan pull pada saat mode output" - -#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 -#: ports/esp8266/common-hal/microcontroller/__init__.c:64 -msgid "Cannot reset into bootloader because no bootloader is present." -msgstr "Tidak dapat melakukan reset ke bootloader karena tidak ada bootloader yang terisi" - -#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 -#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:119 -#: ports/nrf/common-hal/pulseio/PWMOut.c:233 -msgid "Invalid PWM frequency" -msgstr "Frekuensi PWM tidak valid" - -#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:187 -msgid "All timers for this pin are in use" -msgstr "Semua timer untuk pin ini sedang digunakan" - -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 -msgid "No hardware support on pin" -msgstr "Tidak ada dukungan hardware untuk pin" - -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 -msgid "EXTINT channel already in use" -msgstr "Channel EXTINT sedang digunakan" - -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:86 -#, c-format -msgid "Failed to allocate RX buffer of %d bytes" -msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" - -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:151 -msgid "pop from an empty PulseIn" -msgstr "Muncul dari PulseIn yang kosong" - -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 -msgid "index out of range" -msgstr "index keluar dari jangkauan" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178 -msgid "Another send is already active" -msgstr "Send yang lain sudah aktif" - -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38 -msgid "Both pins must support hardware interrupts" -msgstr "Kedua pin harus mendukung hardware interrut" - -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:46 -msgid "A hardware interrupt channel is already in use" -msgstr "Sebuah channel hardware interrupt sedang digunakan" - -#: ports/atmel-samd/common-hal/rtc/RTC.c:101 -msgid "calibration value out of range +/-127" -msgstr "nilai kalibrasi keluar dari jangkauan +/-127" - -#: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 -msgid "No free GCLKs" -msgstr "Tidak ada GCLK yang kosong" - -#: ports/esp8266/common-hal/analogio/AnalogIn.c:43 -msgid "Pin %q does not have ADC capabilities" -msgstr "Pin %q tidak memiliki kemampuan ADC" - -#: ports/esp8266/common-hal/analogio/AnalogOut.c:39 -msgid "No hardware support for analog out." -msgstr "Tidak dukungan hardware untuk analog out." - -#: ports/esp8266/common-hal/busio/SPI.c:72 -msgid "Pins not valid for SPI" -msgstr "Pin-pin tidak valid untuk SPI" - -#: ports/esp8266/common-hal/busio/UART.c:45 -msgid "Only tx supported on UART1 (GPIO2)." -msgstr "Hanya tx yang mendukung pada UART1 (GPIO2)." - -#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 -msgid "invalid data bits" -msgstr "bit data tidak valid" - -#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144 -msgid "invalid stop bits" -msgstr "stop bit tidak valid" - -#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 -msgid "ESP8266 does not support pull down." -msgstr "ESP866 tidak mendukung pull down" - -#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 -msgid "GPIO16 does not support pull up." -msgstr "GPIO16 tidak mendukung pull up" - -#: ports/esp8266/common-hal/microcontroller/__init__.c:66 -msgid "ESP8226 does not support safe mode." -msgstr "ESP8266 tidak mendukung safe mode" - -#: ports/esp8266/common-hal/pulseio/PWMOut.c:54 -#: ports/esp8266/common-hal/pulseio/PWMOut.c:113 -#, c-format -msgid "Maximum PWM frequency is %dhz." -msgstr "Nilai maksimum frekuensi PWM adalah %dhz" - -#: ports/esp8266/common-hal/pulseio/PWMOut.c:57 -#: ports/esp8266/common-hal/pulseio/PWMOut.c:116 -msgid "Minimum PWM frequency is 1hz." -msgstr "Nilai minimum frekuensi PWM is 1hz" - -#: ports/esp8266/common-hal/pulseio/PWMOut.c:68 -#, c-format -msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." -msgstr "Nilai Frekuensi PWM ganda tidak didukung. PWM sudah diatur pada %dhz" - -#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 -#, c-format -msgid "PWM not supported on pin %d" -msgstr "PWM tidak didukung pada pin %d" - -#: ports/esp8266/common-hal/pulseio/PulseIn.c:78 -msgid "No PulseIn support for %q" -msgstr "Tidak ada dukungan PulseIn untuk %q" - -#: ports/esp8266/common-hal/storage/__init__.c:34 -msgid "Unable to remount filesystem" -msgstr "Tidak dapat memasang filesystem kembali" - -#: ports/esp8266/common-hal/storage/__init__.c:38 -msgid "Use esptool to erase flash and re-upload Python instead" -msgstr "Gunakan esptool untuk menghapus flash dan upload ulang Python sebagai gantinya" - -#: ports/esp8266/esp_mphal.c:154 -msgid "C-level assert" -msgstr "Dukungan C-level" - -#: ports/esp8266/machine_adc.c:57 -#, c-format -msgid "not a valid ADC Channel: %d" -msgstr "tidak valid channel ADC: %d" - -#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 -msgid "impossible baudrate" -msgstr "baudrate tidak memungkinkan" - -#: ports/esp8266/machine_pin.c:129 -msgid "expecting a pin" -msgstr "mengharapkan sebuah pin" - -#: ports/esp8266/machine_pin.c:284 -msgid "Pin(16) doesn't support pull" -msgstr "Pin(16) tidak mendukung pull" - -#: ports/esp8266/machine_pin.c:323 -msgid "invalid pin" -msgstr "pin tidak valid" - -#: ports/esp8266/machine_pin.c:389 -msgid "pin does not have IRQ capabilities" -msgstr "pin tidak memiliki kemampuan IRQ" - -#: ports/esp8266/machine_rtc.c:185 -msgid "buffer too long" -msgstr "buffer terlalu panjang" - -#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 -#: ports/esp8266/machine_rtc.c:246 -msgid "invalid alarm" -msgstr "alarm tidak valid" - -#: ports/esp8266/machine_uart.c:169 -#, c-format -msgid "UART(%d) does not exist" -msgstr "UART(%d) tidak ada" - -#: ports/esp8266/machine_uart.c:219 -msgid "UART(1) can't read" -msgstr "UART(1) tidak dapat dibaca" - -#: ports/esp8266/modesp.c:119 -msgid "len must be multiple of 4" -msgstr "len harus kelipatan dari 4" - -#: ports/esp8266/modesp.c:274 -#, c-format -msgid "memory allocation failed, allocating %u bytes for native code" -msgstr "alokasi memori gagal, mengalokasikan %u byte untuk kode native" - -#: ports/esp8266/modesp.c:317 -msgid "flash location must be below 1MByte" -msgstr "alokasi flash harus dibawah 1MByte" - -#: ports/esp8266/modmachine.c:63 -msgid "frequency can only be either 80Mhz or 160MHz" -msgstr "frekuensi hanya bisa didefinisikan 80Mhz atau 160Mhz" - -#: ports/esp8266/modnetwork.c:61 -msgid "AP required" -msgstr "AP dibutuhkan" - -#: ports/esp8266/modnetwork.c:61 -msgid "STA required" -msgstr "STA dibutuhkan" - -#: ports/esp8266/modnetwork.c:87 -msgid "Cannot update i/f status" -msgstr "Tidak dapat memperbarui status i/f" - -#: ports/esp8266/modnetwork.c:142 -msgid "Cannot set STA config" -msgstr "Tidak dapat mengatur konfigurasi STA" - -#: ports/esp8266/modnetwork.c:144 -msgid "Cannot connect to AP" -msgstr "Tidak dapat menyambungkan ke AP" - -#: ports/esp8266/modnetwork.c:152 -msgid "Cannot disconnect from AP" -msgstr "Tidak dapat memutuskna dari AP" - -#: ports/esp8266/modnetwork.c:173 -msgid "unknown status param" -msgstr "status param tidak diketahui" - -#: ports/esp8266/modnetwork.c:222 -msgid "STA must be active" -msgstr "STA harus aktif" - -#: ports/esp8266/modnetwork.c:239 -msgid "scan failed" -msgstr "scan gagal" - -#: ports/esp8266/modnetwork.c:306 -msgid "wifi_set_ip_info() failed" -msgstr "wifi_set_ip_info() gagal" - -#: ports/esp8266/modnetwork.c:319 -msgid "either pos or kw args are allowed" -msgstr "hanya antar pos atau kw args yang diperbolehkan" - -#: ports/esp8266/modnetwork.c:329 -msgid "can't get STA config" -msgstr "tidak bisa mendapatkan konfigurasi STA" - -#: ports/esp8266/modnetwork.c:331 -msgid "can't get AP config" -msgstr "tidak bisa mendapatkan konfigurasi AP" - -#: ports/esp8266/modnetwork.c:346 -msgid "invalid buffer length" -msgstr "panjang buffer tidak valid" - -#: ports/esp8266/modnetwork.c:405 -msgid "can't set STA config" -msgstr "tidak bisa mendapatkan konfigurasi STA" - -#: ports/esp8266/modnetwork.c:407 -msgid "can't set AP config" -msgstr "tidak bisa mendapatkan konfigurasi AP" - -#: ports/esp8266/modnetwork.c:416 -msgid "can query only one param" -msgstr "hanya bisa melakukan query satu param" - -#: ports/esp8266/modnetwork.c:469 -msgid "unknown config param" -msgstr "konfigurasi param tidak diketahui" - -#: ports/nrf/common-hal/analogio/AnalogOut.c:37 -msgid "AnalogOut functionality not supported" -msgstr "fungsionalitas AnalogOut tidak didukung" - -#: ports/nrf/common-hal/bleio/Adapter.c:41 -#, c-format -msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" -msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l" - -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" -msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" -msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" -msgstr "Gagal untuk mendapatkan alamat lokal, error: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Characteristic.c:52 -#, c-format -msgid "Failed to write gatts value, status: 0x%08lX" -msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Characteristic.c:76 -#, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" -msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Characteristic.c:91 -#, c-format -msgid "Failed to read attribute value, status: 0x%08lX" -msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 -#, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" -msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Characteristic.c:126 -#, c-format -msgid "Failed to write attribute value, status: 0x%08lX" -msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 -#, c-format -msgid "Failed to release mutex, status: 0x%08lX" -msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 -msgid "Can not fit data into the advertisment packet" -msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" - -#: ports/nrf/common-hal/bleio/Device.c:266 -#, c-format -msgid "Failed to discover services, status: 0x%08lX" -msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 -#, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" -msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Device.c:436 -#, c-format -msgid "Failed to connect, status: 0x%08lX" -msgstr "Gagal untuk menyambungkan, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Device.c:513 -#, c-format -msgid "Failed to add service, status: 0x%08lX" -msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Device.c:531 -#, c-format -msgid "Failed to start advertisment, status: 0x%08lX" -msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Device.c:549 -#, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" -msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 -#, c-format -msgid "Failed to start scanning, status: 0x%0xlX" -msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Device.c:592 -#, c-format -msgid "Failed to create mutex, status: 0x%0xlX" -msgstr "Gagal untuk membuat mutex, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/Service.c:83 -#, c-format -msgid "Failed to add characteristic, status: 0x%08lX" -msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/UUID.c:97 -#, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" -msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX" - -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" -msgstr "Panjang string UUID tidak valid" - -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" -msgstr "Parameter UUID tidak valid" - -#: ports/nrf/common-hal/busio/I2C.c:96 -msgid "All I2C peripherals are in use" -msgstr "Semua perangkat I2C sedang digunakan" - -#: ports/nrf/common-hal/busio/SPI.c:133 -msgid "All SPI peripherals are in use" -msgstr "Semua perangkat SPI sedang digunakan" - -#: ports/nrf/common-hal/busio/UART.c:48 -#, c-format -msgid "error = 0x%08lX" -msgstr "error = 0x%08lX" - -#: ports/nrf/common-hal/busio/UART.c:86 -msgid "Invalid buffer size" -msgstr "Ukuran buffer tidak valid" - -#: ports/nrf/common-hal/busio/UART.c:90 -msgid "Odd parity is not supported" -msgstr "Parity ganjil tidak didukung" - -#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 -#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 -#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 -#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 -#: ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not available" -msgstr "busio.UART tidak tersedia" - -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" -msgstr "Tidak bisa mendapatkan temperatur. status: 0x%02x" - -#: ports/nrf/common-hal/pulseio/PWMOut.c:161 -msgid "All PWM peripherals are in use" -msgstr "Semua perangkat PWM sedang digunakan" - -#: ports/unix/modffi.c:138 -msgid "Unknown type" -msgstr "Tipe tidak diketahui" - -#: ports/unix/modffi.c:207 ports/unix/modffi.c:265 -msgid "Error in ffi_prep_cif" -msgstr "Errod pada ffi_prep_cif" - -#: ports/unix/modffi.c:270 -msgid "ffi_prep_closure_loc" -msgstr "ffi_prep_closure_loc" - -#: ports/unix/modffi.c:413 -msgid "Don't know how to pass object to native function" -msgstr "Tidak tahu cara meloloskan objek ke fungsi native" - -#: ports/unix/modusocket.c:474 -#, c-format -msgid "[addrinfo error %d]" -msgstr "[addrinfo error %d]" - -#: py/argcheck.c:44 -msgid "function does not take keyword arguments" -msgstr "fungsi tidak dapat mengambil argumen keyword" - -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 -#, c-format -msgid "function takes %d positional arguments but %d were given" -msgstr "fungsi mengambil posisi argumen %d tapi %d yang diberikan" - -#: py/argcheck.c:64 -#, c-format -msgid "function missing %d required positional arguments" -msgstr "fungsi kehilangan %d argumen posisi yang dibutuhkan" - -#: py/argcheck.c:72 -#, c-format -msgid "function expected at most %d arguments, got %d" -msgstr "fungsi diharapkan setidaknya %d argumen, hanya mendapatkan %d" - -#: py/argcheck.c:97 -msgid "'%q' argument required" -msgstr "'%q' argumen dibutuhkan" - -#: py/argcheck.c:122 -msgid "extra positional arguments given" -msgstr "argumen posisi ekstra telah diberikan" - -#: py/argcheck.c:130 -msgid "extra keyword arguments given" -msgstr "argumen keyword ekstra telah diberikan" - -#: py/argcheck.c:142 -msgid "argument num/types mismatch" -msgstr "argumen num/types tidak cocok" - -#: py/argcheck.c:147 -msgid "keyword argument(s) not yet implemented - use normal args instead" -msgstr "argumen keyword belum diimplementasi - gunakan args normal" - -#: py/bc.c:88 py/objnamedtuple.c:108 -msgid "%q() takes %d positional arguments but %d were given" -msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" - -#: py/bc.c:197 py/bc.c:215 -msgid "unexpected keyword argument" -msgstr "argumen keyword tidak diharapkan" - -#: py/bc.c:199 -msgid "keywords must be strings" -msgstr "keyword harus berupa string" - -#: py/bc.c:206 py/objnamedtuple.c:138 -msgid "function got multiple values for argument '%q'" -msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" - -#: py/bc.c:218 py/objnamedtuple.c:130 -msgid "unexpected keyword argument '%q'" -msgstr "keyword argumen '%q' tidak diharapkan" - -#: py/bc.c:244 -#, c-format -msgid "function missing required positional argument #%d" -msgstr "fungsi kehilangan argumen posisi #%d yang dibutuhkan" - -#: py/bc.c:260 -msgid "function missing required keyword argument '%q'" -msgstr "fungsi kehilangan argumen keyword '%q' yang dibutuhkan" - -#: py/bc.c:269 -msgid "function missing keyword-only argument" -msgstr "fungsi kehilangan argumen keyword-only" - -#: py/binary.c:112 -msgid "bad typecode" -msgstr "typecode buruk" - -#: py/builtinevex.c:99 -msgid "bad compile mode" -msgstr "mode compile buruk" - -#: py/builtinhelp.c:137 -msgid "Plus any modules on the filesystem\n" -msgstr "Tambahkan module apapun pada filesystem\n" - -#: py/builtinhelp.c:183 -#, c-format -msgid "" -"Welcome to Adafruit CircuitPython %s!\n" -"\n" -"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" -"\n" -"To list built-in modules please do `help(\"modules\")`.\n" -msgstr "" -"Selamat datang ke Adafruit CircuitPython %s!\n" -"\n" -"Silahkan kunjungi learn.adafruit.com/category/circuitpython untuk panduan project.\n" -"\n" -"Untuk menampilkan modul built-in silahkan ketik `help(\"modules\")`.\n" - -#: py/builtinimport.c:336 -msgid "cannot perform relative import" -msgstr "tidak dapat melakukan relative import" - -#: py/builtinimport.c:420 py/builtinimport.c:532 -msgid "module not found" -msgstr "modul tidak ditemukan" - -#: py/builtinimport.c:423 py/builtinimport.c:535 -msgid "no module named '%q'" -msgstr "tidak ada modul yang bernama '%q'" - -#: py/builtinimport.c:510 -msgid "relative import" -msgstr "relative import" - -#: py/compile.c:397 py/compile.c:542 -msgid "can't assign to expression" -msgstr "tidak dapat menetapkan ke ekspresi" - -#: py/compile.c:416 -msgid "multiple *x in assignment" -msgstr "perkalian *x dalam assignment" - -#: py/compile.c:642 -msgid "non-default argument follows default argument" -msgstr "argumen non-default mengikuti argumen standar(default)" - -#: py/compile.c:771 py/compile.c:789 -msgid "invalid micropython decorator" -msgstr "micropython decorator tidak valid" - -#: py/compile.c:943 -msgid "can't delete expression" -msgstr "tidak bisa menghapus ekspresi" - -#: py/compile.c:955 -msgid "'break' outside loop" -msgstr "'break' diluar loop" - -#: py/compile.c:958 -msgid "'continue' outside loop" -msgstr "'continue' diluar loop" - -#: py/compile.c:969 -msgid "'return' outside function" -msgstr "'return' diluar fungsi" - -#: py/compile.c:1169 -msgid "identifier redefined as global" -msgstr "identifier didefinisi ulang sebagai global" - -#: py/compile.c:1185 -msgid "no binding for nonlocal found" -msgstr "tidak ada ikatan/bind pada temuan nonlocal" - -#: py/compile.c:1188 -msgid "identifier redefined as nonlocal" -msgstr "identifier didefinisi ulang sebagai nonlocal" - -#: py/compile.c:1197 -msgid "can't declare nonlocal in outer code" -msgstr "tidak dapat mendeklarasikan nonlocal diluar jangkauan kode" - -#: py/compile.c:1542 -msgid "default 'except' must be last" -msgstr "'except' standar harus terakhir" - -#: py/compile.c:2095 -msgid "*x must be assignment target" -msgstr "*x harus menjadi target assignment" - -#: py/compile.c:2193 -msgid "super() can't find self" -msgstr "super() tidak dapat menemukan dirinya sendiri" - -#: py/compile.c:2256 -msgid "can't have multiple *x" -msgstr "tidak bisa memiliki *x ganda" - -#: py/compile.c:2263 -msgid "can't have multiple **x" -msgstr "tidak bisa memiliki **x ganda" - -#: py/compile.c:2271 -msgid "LHS of keyword arg must be an id" -msgstr "LHS dari keyword arg harus menjadi sebuah id" - -#: py/compile.c:2287 -msgid "non-keyword arg after */**" -msgstr "non-keyword arg setelah */**" - -#: py/compile.c:2291 -msgid "non-keyword arg after keyword arg" -msgstr "non-keyword arg setelah keyword arg" - -#: py/compile.c:2463 py/compile.c:2473 py/compile.c:2712 py/compile.c:2742 -#: py/parse.c:1176 -msgid "invalid syntax" -msgstr "syntax tidak valid" - -#: py/compile.c:2465 -msgid "expecting key:value for dict" -msgstr "key:value diharapkan untuk dict" - -#: py/compile.c:2475 -msgid "expecting just a value for set" -msgstr "hanya mengharapkan sebuah nilai (value) untuk set" - -#: py/compile.c:2600 -msgid "'yield' outside function" -msgstr "'yield' diluar fungsi" - -#: py/compile.c:2619 -msgid "'await' outside function" -msgstr "'await' diluar fungsi" - -#: py/compile.c:2774 -msgid "name reused for argument" -msgstr "nama digunakan kembali untuk argumen" - -#: py/compile.c:2827 -msgid "parameter annotation must be an identifier" -msgstr "anotasi parameter haruse sebuah identifier" - -#: py/compile.c:2969 py/compile.c:3137 -msgid "return annotation must be an identifier" -msgstr "anotasi return harus sebuah identifier" - -#: py/compile.c:3097 -msgid "inline assembler must be a function" -msgstr "inline assembler harus sebuah fungsi" - -#: py/compile.c:3134 -msgid "unknown type" -msgstr "tipe tidak diketahui" - -#: py/compile.c:3154 -msgid "expecting an assembler instruction" -msgstr "sebuah instruksi assembler diharapkan" - -#: py/compile.c:3184 -msgid "'label' requires 1 argument" -msgstr "'label' membutuhkan 1 argumen" - -#: py/compile.c:3190 -msgid "label redefined" -msgstr "label didefinis ulang" - -#: py/compile.c:3196 -msgid "'align' requires 1 argument" -msgstr "'align' membutuhkan 1 argumen" - -#: py/compile.c:3205 -msgid "'data' requires at least 2 arguments" -msgstr "'data' membutuhkan setidaknya 2 argumen" - -#: py/compile.c:3212 -msgid "'data' requires integer arguments" -msgstr "'data' membutuhkan argumen integer" - -#: py/emitinlinethumb.c:102 -msgid "can only have up to 4 parameters to Thumb assembly" -msgstr "hanya mampu memiliki hingga 4 parameter untuk Thumb assembly" - -#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 -msgid "parameters must be registers in sequence r0 to r3" -msgstr "parameter harus menjadi register dalam urutan r0 sampai r3" - -#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 -#, c-format -msgid "'%s' expects at most r%d" -msgstr "'%s' mengharapkan setidaknya r%d" - -#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 -#, c-format -msgid "'%s' expects a register" -msgstr "'%s' mengharapkan sebuah register" - -#: py/emitinlinethumb.c:211 -#, c-format -msgid "'%s' expects a special register" -msgstr "'%s' mengharapkan sebuah register spesial" - -#: py/emitinlinethumb.c:239 -#, c-format -msgid "'%s' expects an FPU register" -msgstr "'%s' mengharapkan sebuah FPU register" - -#: py/emitinlinethumb.c:292 -#, c-format -msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' mengharapkan {r0, r1, ...}" - -#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 -#, c-format -msgid "'%s' expects an integer" -msgstr "'%s' mengharapkan integer" - -#: py/emitinlinethumb.c:304 -#, c-format -msgid "'%s' integer 0x%x does not fit in mask 0x%x" -msgstr "'%s' integer 0x%x tidak cukup didalam mask 0x%x" - -#: py/emitinlinethumb.c:328 -#, c-format -msgid "'%s' expects an address of the form [a, b]" -msgstr "'%s' mengharapkan sebuah alamat dengan bentuk [a, b]" - -#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 -#, c-format -msgid "'%s' expects a label" -msgstr "" - -#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 -msgid "label '%q' not defined" -msgstr "" - -#: py/emitinlinethumb.c:806 -#, c-format -msgid "unsupported Thumb instruction '%s' with %d arguments" -msgstr "" - -#: py/emitinlinethumb.c:810 -msgid "branch not in range" -msgstr "" - -#: py/emitinlinextensa.c:86 -msgid "can only have up to 4 parameters to Xtensa assembly" -msgstr "" - -#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 -msgid "parameters must be registers in sequence a2 to a5" -msgstr "" - -#: py/emitinlinextensa.c:174 -#, c-format -msgid "'%s' integer %d is not within range %d..%d" -msgstr "" - -#: py/emitinlinextensa.c:327 -#, c-format -msgid "unsupported Xtensa instruction '%s' with %d arguments" -msgstr "" - -#: py/emitnative.c:183 -msgid "unknown type '%q'" -msgstr "" - -#: py/emitnative.c:260 -msgid "Viper functions don't currently support more than 4 arguments" -msgstr "" - -#: py/emitnative.c:742 -msgid "conversion to object" -msgstr "" - -#: py/emitnative.c:921 -msgid "local '%q' used before type known" -msgstr "" - -#: py/emitnative.c:1118 py/emitnative.c:1156 -msgid "can't load from '%q'" -msgstr "" - -#: py/emitnative.c:1128 -msgid "can't load with '%q' index" -msgstr "" - -#: py/emitnative.c:1188 -msgid "local '%q' has type '%q' but source is '%q'" -msgstr "" - -#: py/emitnative.c:1289 py/emitnative.c:1379 -msgid "can't store '%q'" -msgstr "" - -#: py/emitnative.c:1358 py/emitnative.c:1419 -msgid "can't store to '%q'" -msgstr "" - -#: py/emitnative.c:1369 -msgid "can't store with '%q' index" -msgstr "" - -#: py/emitnative.c:1540 -msgid "can't implicitly convert '%q' to 'bool'" -msgstr "" - -#: py/emitnative.c:1774 -msgid "unary op %q not implemented" -msgstr "" - -#: py/emitnative.c:1930 -msgid "binary op %q not implemented" -msgstr "" - -#: py/emitnative.c:1951 -msgid "can't do binary op between '%q' and '%q'" -msgstr "" - -#: py/emitnative.c:2126 -msgid "casting" -msgstr "" - -#: py/emitnative.c:2173 -msgid "return expected '%q' but got '%q'" -msgstr "" - -#: py/emitnative.c:2191 -msgid "must raise an object" -msgstr "" - -#: py/emitnative.c:2201 -msgid "native yield" -msgstr "" - -#: py/lexer.c:345 -msgid "unicode name escapes" -msgstr "" - -#: py/modbuiltins.c:162 -msgid "chr() arg not in range(0x110000)" -msgstr "" - -#: py/modbuiltins.c:171 -msgid "chr() arg not in range(256)" -msgstr "" - -#: py/modbuiltins.c:285 -msgid "arg is an empty sequence" -msgstr "" - -#: py/modbuiltins.c:350 -msgid "ord expects a character" -msgstr "" - -#: py/modbuiltins.c:353 -#, c-format -msgid "ord() expected a character, but string of length %d found" -msgstr "" - -#: py/modbuiltins.c:363 -msgid "3-arg pow() not supported" -msgstr "" - -#: py/modbuiltins.c:517 -msgid "must use keyword argument for key function" -msgstr "" - -#: py/modmath.c:41 shared-bindings/math/__init__.c:53 -msgid "math domain error" -msgstr "" - -#: py/modmath.c:196 py/objfloat.c:270 py/objint_longlong.c:222 -#: py/objint_mpz.c:230 py/runtime.c:619 shared-bindings/math/__init__.c:346 -msgid "division by zero" -msgstr "" - -#: py/modmicropython.c:155 -msgid "schedule stack full" -msgstr "" - -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 -msgid "buffer too small" -msgstr "" - -#: py/modthread.c:240 -msgid "expecting a dict for keyword args" -msgstr "" - -#: py/moduerrno.c:143 py/moduerrno.c:146 -msgid "Permission denied" -msgstr "" - -#: py/moduerrno.c:144 -msgid "No such file/directory" -msgstr "" - -#: py/moduerrno.c:145 -msgid "Input/output error" -msgstr "" - -#: py/moduerrno.c:147 -msgid "File exists" -msgstr "" - -#: py/moduerrno.c:148 -msgid "Unsupported operation" -msgstr "" - -#: py/moduerrno.c:149 -msgid "Invalid argument" -msgstr "" - -#: py/obj.c:90 -msgid "Traceback (most recent call last):\n" -msgstr "" - -#: py/obj.c:94 -msgid " File \"%q\", line %d" -msgstr "" - -#: py/obj.c:96 -msgid " File \"%q\"" -msgstr "" - -#: py/obj.c:100 -msgid ", in %q\n" -msgstr "" - -#: py/obj.c:257 -msgid "can't convert to int" -msgstr "" - -#: py/obj.c:260 -#, c-format -msgid "can't convert %s to int" -msgstr "" - -#: py/obj.c:320 -msgid "can't convert to float" -msgstr "" - -#: py/obj.c:323 -#, c-format -msgid "can't convert %s to float" -msgstr "" - -#: py/obj.c:353 -msgid "can't convert to complex" -msgstr "" - -#: py/obj.c:356 -#, c-format -msgid "can't convert %s to complex" -msgstr "" - -#: py/obj.c:371 -msgid "expected tuple/list" -msgstr "" - -#: py/obj.c:374 -#, c-format -msgid "object '%s' is not a tuple or list" -msgstr "" - -#: py/obj.c:385 -msgid "tuple/list has wrong length" -msgstr "" - -#: py/obj.c:387 -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - -#: py/obj.c:400 -msgid "indices must be integers" -msgstr "" - -#: py/obj.c:403 -msgid "%q indices must be integers, not %s" -msgstr "" - -#: py/obj.c:423 -msgid "%q index out of range" -msgstr "" - -#: py/obj.c:455 -msgid "object has no len" -msgstr "" - -#: py/obj.c:458 -#, c-format -msgid "object of type '%s' has no len()" -msgstr "" - -#: py/obj.c:496 -msgid "object does not support item deletion" -msgstr "" - -#: py/obj.c:499 -#, c-format -msgid "'%s' object does not support item deletion" -msgstr "" - -#: py/obj.c:503 -msgid "object is not subscriptable" -msgstr "" - -#: py/obj.c:506 -#, c-format -msgid "'%s' object is not subscriptable" -msgstr "" - -#: py/obj.c:510 -msgid "object does not support item assignment" -msgstr "" - -#: py/obj.c:513 -#, c-format -msgid "'%s' object does not support item assignment" -msgstr "" - -#: py/obj.c:544 -msgid "object with buffer protocol required" -msgstr "" - -#: py/objarray.c:413 py/objstr.c:427 py/objstrunicode.c:191 py/objtuple.c:187 -#: shared-bindings/nvm/ByteArray.c:85 -msgid "only slices with step=1 (aka None) are supported" -msgstr "" - -#: py/objarray.c:426 -msgid "lhs and rhs should be compatible" -msgstr "" - -#: py/objarray.c:444 shared-bindings/nvm/ByteArray.c:107 -msgid "array/bytes required on right side" -msgstr "" - -#: py/objcomplex.c:203 -msgid "can't do truncated division of a complex number" -msgstr "" - -#: py/objcomplex.c:209 -msgid "complex division by zero" -msgstr "" - -#: py/objcomplex.c:237 -msgid "0.0 to a complex power" -msgstr "" - -#: py/objdeque.c:107 -msgid "full" -msgstr "" - -#: py/objdeque.c:127 -msgid "empty" -msgstr "" - -#: py/objdict.c:314 -msgid "popitem(): dictionary is empty" -msgstr "" - -#: py/objdict.c:357 -msgid "dict update sequence has wrong length" -msgstr "" - -#: py/objfloat.c:308 py/parsenum.c:331 -msgid "complex values not supported" -msgstr "" - -#: py/objgenerator.c:108 -msgid "can't send non-None value to a just-started generator" -msgstr "" - -#: py/objgenerator.c:126 -msgid "generator already executing" -msgstr "" - -#: py/objgenerator.c:229 -msgid "generator ignored GeneratorExit" -msgstr "" - -#: py/objgenerator.c:251 -msgid "can't pend throw to just-started generator" -msgstr "" - -#: py/objint.c:144 -msgid "can't convert inf to int" -msgstr "" - -#: py/objint.c:146 -msgid "can't convert NaN to int" -msgstr "" - -#: py/objint.c:163 -msgid "float too big" -msgstr "" - -#: py/objint.c:328 -msgid "long int not supported in this build" -msgstr "" - -#: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 -msgid "small int overflow" -msgstr "" - -#: py/objint_longlong.c:189 py/objint_mpz.c:283 py/runtime.c:486 -msgid "negative power with no float support" -msgstr "" - -#: py/objint_longlong.c:251 -msgid "ulonglong too large" -msgstr "" - -#: py/objint_mpz.c:267 py/runtime.c:396 py/runtime.c:411 -msgid "negative shift count" -msgstr "" - -#: py/objint_mpz.c:336 -msgid "pow() with 3 arguments requires integers" -msgstr "" - -#: py/objint_mpz.c:347 -msgid "pow() 3rd argument cannot be 0" -msgstr "" - -#: py/objint_mpz.c:415 -msgid "overflow converting long int to machine word" -msgstr "" - -#: py/objlist.c:273 -msgid "pop from empty list" -msgstr "" - -#: py/objnamedtuple.c:92 -msgid "can't set attribute" -msgstr "" - -#: py/objobject.c:55 -msgid "__new__ arg must be a user-type" -msgstr "" - -#: py/objrange.c:110 -msgid "zero step" -msgstr "" - -#: py/objset.c:371 -msgid "pop from an empty set" -msgstr "" - -#: py/objslice.c:66 -msgid "Length must be an int" -msgstr "" - -#: py/objslice.c:71 -msgid "Length must be non-negative" -msgstr "" - -#: py/objslice.c:86 py/sequence.c:57 -msgid "slice step cannot be zero" -msgstr "" - -#: py/objslice.c:159 -msgid "Cannot subclass slice" -msgstr "" - -#: py/objstr.c:261 -msgid "bytes value out of range" -msgstr "" - -#: py/objstr.c:270 -msgid "wrong number of arguments" -msgstr "" - -#: py/objstr.c:467 -msgid "join expects a list of str/bytes objects consistent with self object" -msgstr "" - -#: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744 -msgid "empty separator" -msgstr "" - -#: py/objstr.c:641 -msgid "rsplit(None,n)" -msgstr "" - -#: py/objstr.c:713 -msgid "substring not found" -msgstr "" - -#: py/objstr.c:770 -msgid "start/end indices" -msgstr "" - -#: py/objstr.c:931 -msgid "bad format string" -msgstr "" - -#: py/objstr.c:953 -msgid "single '}' encountered in format string" -msgstr "" - -#: py/objstr.c:992 -msgid "bad conversion specifier" -msgstr "" - -#: py/objstr.c:996 -msgid "end of format while looking for conversion specifier" -msgstr "" - -#: py/objstr.c:998 -#, c-format -msgid "unknown conversion specifier %c" -msgstr "" - -#: py/objstr.c:1029 -msgid "unmatched '{' in format" -msgstr "" - -#: py/objstr.c:1036 -msgid "expected ':' after format specifier" -msgstr "" - -#: py/objstr.c:1050 -msgid "" -"can't switch from automatic field numbering to manual field specification" -msgstr "" - -#: py/objstr.c:1055 py/objstr.c:1083 -msgid "tuple index out of range" -msgstr "" - -#: py/objstr.c:1071 -msgid "attributes not supported yet" -msgstr "" - -#: py/objstr.c:1079 -msgid "" -"can't switch from manual field specification to automatic field numbering" -msgstr "" - -#: py/objstr.c:1171 -msgid "invalid format specifier" -msgstr "" - -#: py/objstr.c:1192 -msgid "sign not allowed in string format specifier" -msgstr "" - -#: py/objstr.c:1200 -msgid "sign not allowed with integer format specifier 'c'" -msgstr "" - -#: py/objstr.c:1259 -#, c-format -msgid "unknown format code '%c' for object of type '%s'" -msgstr "" - -#: py/objstr.c:1331 -#, c-format -msgid "unknown format code '%c' for object of type 'float'" -msgstr "" - -#: py/objstr.c:1343 -msgid "'=' alignment not allowed in string format specifier" -msgstr "" - -#: py/objstr.c:1367 -#, c-format -msgid "unknown format code '%c' for object of type 'str'" -msgstr "" - -#: py/objstr.c:1415 -msgid "format requires a dict" -msgstr "" - -#: py/objstr.c:1424 -msgid "incomplete format key" -msgstr "" - -#: py/objstr.c:1482 -msgid "incomplete format" -msgstr "" - -#: py/objstr.c:1490 -msgid "not enough arguments for format string" -msgstr "" - -#: py/objstr.c:1500 -#, c-format -msgid "%%c requires int or char" -msgstr "" - -#: py/objstr.c:1507 -msgid "integer required" -msgstr "" - -#: py/objstr.c:1570 -#, c-format -msgid "unsupported format character '%c' (0x%x) at index %d" -msgstr "" - -#: py/objstr.c:1577 -msgid "not all arguments converted during string formatting" -msgstr "" - -#: py/objstr.c:2102 -msgid "can't convert to str implicitly" -msgstr "" - -#: py/objstr.c:2106 -msgid "can't convert '%q' object to %q implicitly" -msgstr "" - -#: py/objstrunicode.c:134 -#, c-format -msgid "string indices must be integers, not %s" -msgstr "" - -#: py/objstrunicode.c:145 py/objstrunicode.c:164 -msgid "string index out of range" -msgstr "" - -#: py/objtype.c:358 -msgid "__init__() should return None" -msgstr "" - -#: py/objtype.c:360 -#, c-format -msgid "__init__() should return None, not '%s'" -msgstr "" - -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 -msgid "unreadable attribute" -msgstr "" - -#: py/objtype.c:868 py/runtime.c:653 -msgid "object not callable" -msgstr "" - -#: py/objtype.c:870 py/runtime.c:655 -#, c-format -msgid "'%s' object is not callable" -msgstr "" - -#: py/objtype.c:978 -msgid "type takes 1 or 3 arguments" -msgstr "" - -#: py/objtype.c:989 -msgid "cannot create instance" -msgstr "" - -#: py/objtype.c:991 -msgid "cannot create '%q' instances" -msgstr "" - -#: py/objtype.c:1047 -msgid "can't add special method to already-subclassed class" -msgstr "" - -#: py/objtype.c:1091 py/objtype.c:1097 -msgid "type is not an acceptable base type" -msgstr "" - -#: py/objtype.c:1100 -msgid "type '%q' is not an acceptable base type" -msgstr "" - -#: py/objtype.c:1137 -msgid "multiple inheritance not supported" -msgstr "" - -#: py/objtype.c:1164 -msgid "multiple bases have instance lay-out conflict" -msgstr "" - -#: py/objtype.c:1205 -msgid "first argument to super() must be type" -msgstr "" - -#: py/objtype.c:1370 -msgid "issubclass() arg 2 must be a class or a tuple of classes" -msgstr "" - -#: py/objtype.c:1384 -msgid "issubclass() arg 1 must be a class" -msgstr "" - -#: py/parse.c:726 -msgid "constant must be an integer" -msgstr "" - -#: py/parse.c:868 -msgid "Unable to init parser" -msgstr "" - -#: py/parse.c:1170 -msgid "unexpected indent" -msgstr "" - -#: py/parse.c:1173 -msgid "unindent does not match any outer indentation level" -msgstr "" - -#: py/parsenum.c:60 -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - -#: py/parsenum.c:151 -msgid "invalid syntax for integer" -msgstr "" - -#: py/parsenum.c:155 -#, c-format -msgid "invalid syntax for integer with base %d" -msgstr "" - -#: py/parsenum.c:339 -msgid "invalid syntax for number" -msgstr "" - -#: py/parsenum.c:342 -msgid "decimal numbers not supported" -msgstr "" - -#: py/persistentcode.c:223 -msgid "" -"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" -"mpy-update for more info." -msgstr "" - -#: py/persistentcode.c:326 -msgid "can only save bytecode" -msgstr "" - -#: py/runtime.c:206 -msgid "name not defined" -msgstr "" - -#: py/runtime.c:209 -msgid "name '%q' is not defined" -msgstr "" - -#: py/runtime.c:304 py/runtime.c:611 -msgid "unsupported type for operator" -msgstr "" - -#: py/runtime.c:307 -msgid "unsupported type for %q: '%s'" -msgstr "" - -#: py/runtime.c:614 -msgid "unsupported types for %q: '%s', '%s'" -msgstr "" - -#: py/runtime.c:881 py/runtime.c:888 py/runtime.c:945 -msgid "wrong number of values to unpack" -msgstr "" - -#: py/runtime.c:883 py/runtime.c:947 -#, c-format -msgid "need more than %d values to unpack" -msgstr "" - -#: py/runtime.c:890 -#, c-format -msgid "too many values to unpack (expected %d)" -msgstr "" - -#: py/runtime.c:984 -msgid "argument has wrong type" -msgstr "" - -#: py/runtime.c:986 -msgid "argument should be a '%q' not a '%q'" -msgstr "" - -#: py/runtime.c:1123 py/runtime.c:1197 -msgid "no such attribute" -msgstr "" - -#: py/runtime.c:1128 -msgid "type object '%q' has no attribute '%q'" -msgstr "" - -#: py/runtime.c:1132 py/runtime.c:1200 -msgid "'%s' object has no attribute '%q'" -msgstr "" - -#: py/runtime.c:1238 -msgid "object not iterable" -msgstr "" - -#: py/runtime.c:1241 -#, c-format -msgid "'%s' object is not iterable" -msgstr "" - -#: py/runtime.c:1260 py/runtime.c:1296 -msgid "object not an iterator" -msgstr "" - -#: py/runtime.c:1262 py/runtime.c:1298 -#, c-format -msgid "'%s' object is not an iterator" -msgstr "" - -#: py/runtime.c:1401 -msgid "exceptions must derive from BaseException" -msgstr "" - -#: py/runtime.c:1430 -msgid "cannot import name %q" -msgstr "" - -#: py/runtime.c:1535 -msgid "memory allocation failed, heap is locked" -msgstr "" - -#: py/runtime.c:1539 -#, c-format -msgid "memory allocation failed, allocating %u bytes" -msgstr "" - -#: py/runtime.c:1609 -msgid "maximum recursion depth exceeded" -msgstr "" - -#: py/sequence.c:264 -msgid "object not in sequence" -msgstr "" - -#: py/stream.c:96 -msgid "stream operation not supported" -msgstr "" - -#: py/vm.c:255 -msgid "local variable referenced before assignment" -msgstr "" - -#: py/vm.c:1142 -msgid "no active exception to reraise" -msgstr "" - -#: py/vm.c:1284 -msgid "byte code not implemented" -msgstr "" - -#: shared-bindings/_stage/Layer.c:71 -msgid "graphic must be 2048 bytes long" -msgstr "" - -#: shared-bindings/_stage/Layer.c:77 shared-bindings/_stage/Text.c:75 -msgid "palette must be 32 bytes long" -msgstr "" - -#: shared-bindings/_stage/Layer.c:84 -msgid "map buffer too small" -msgstr "" - -#: shared-bindings/_stage/Text.c:69 -msgid "font must be 2048 bytes long" -msgstr "" - -#: shared-bindings/_stage/Text.c:81 -msgid "chars buffer too small" -msgstr "" - -#: shared-bindings/analogio/AnalogOut.c:118 -msgid "AnalogOut is only 16 bits. Value must be less than 65536." -msgstr "" - -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 -msgid "Not playing" -msgstr "" - -#: shared-bindings/audiobusio/PDMIn.c:124 -msgid "Bit depth must be multiple of 8." -msgstr "" - -#: shared-bindings/audiobusio/PDMIn.c:128 -msgid "Oversample must be multiple of 8." -msgstr "" - -#: shared-bindings/audiobusio/PDMIn.c:136 -msgid "Microphone startup delay must be in range 0.0 to 1.0" -msgstr "" - -#: shared-bindings/audiobusio/PDMIn.c:193 -msgid "destination_length must be an int >= 0" -msgstr "" - -#: shared-bindings/audiobusio/PDMIn.c:199 -msgid "Cannot record to a file" -msgstr "" - -#: shared-bindings/audiobusio/PDMIn.c:202 -msgid "Destination capacity is smaller than destination_length." -msgstr "" - -#: shared-bindings/audiobusio/PDMIn.c:206 -msgid "destination buffer must be an array of type 'H' for bit_depth = 16" -msgstr "" - -#: shared-bindings/audiobusio/PDMIn.c:208 -msgid "" -"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" -msgstr "" - -#: shared-bindings/audioio/Mixer.c:94 -msgid "Invalid voice count" -msgstr "" - -#: shared-bindings/audioio/Mixer.c:99 -msgid "Invalid channel count" -msgstr "" - -#: shared-bindings/audioio/Mixer.c:103 -msgid "Sample rate must be positive" -msgstr "" - -#: shared-bindings/audioio/Mixer.c:107 -msgid "bits_per_sample must be 8 or 16" -msgstr "" - -#: shared-bindings/audioio/RawSample.c:98 -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - -#: shared-bindings/audioio/RawSample.c:104 -msgid "buffer must be a bytes-like object" -msgstr "" - -#: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 -msgid "file must be a file opened in byte mode" -msgstr "" - -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 -msgid "Function requires lock" -msgstr "" - -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 -msgid "Buffer must be at least length 1" -msgstr "" - -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 -msgid "Invalid polarity" -msgstr "" - -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 -msgid "Invalid phase" -msgstr "" - -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 -msgid "Invalid number of bits" -msgstr "" - -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 -msgid "buffer slices must be of equal length" -msgstr "" - -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" -msgstr "" - -#: shared-bindings/bleio/Address.c:107 -msgid "Wrong number of bytes provided" -msgstr "" - -#: shared-bindings/bleio/Device.c:210 -msgid "Can't add services in Central mode" -msgstr "" - -#: shared-bindings/bleio/Device.c:226 -msgid "Can't connect in Peripheral mode" -msgstr "" - -#: shared-bindings/bleio/Device.c:256 -msgid "Can't change the name in Central mode" -msgstr "" - -#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 -msgid "Can't advertise in Central mode" -msgstr "" - -#: shared-bindings/busio/I2C.c:120 -msgid "Function requires lock." -msgstr "" - -#: shared-bindings/busio/UART.c:102 -msgid "bits must be 7, 8 or 9" -msgstr "" - -#: shared-bindings/busio/UART.c:114 -msgid "stop must be 1 or 2" -msgstr "" - -#: shared-bindings/digitalio/DigitalInOut.c:211 -msgid "Invalid direction." -msgstr "" - -#: shared-bindings/digitalio/DigitalInOut.c:240 -msgid "Cannot set value when direction is input." -msgstr "" - -#: shared-bindings/digitalio/DigitalInOut.c:266 -#: shared-bindings/digitalio/DigitalInOut.c:281 -msgid "Drive mode not used when direction is input." -msgstr "" - -#: shared-bindings/digitalio/DigitalInOut.c:314 -#: shared-bindings/digitalio/DigitalInOut.c:331 -msgid "Pull not used when direction is output." -msgstr "" - -#: shared-bindings/digitalio/DigitalInOut.c:340 -msgid "Unsupported pull value." -msgstr "" - -#: shared-bindings/displayio/Bitmap.c:84 -msgid "y should be an int" -msgstr "" - -#: shared-bindings/displayio/Bitmap.c:89 -msgid "row buffer must be a bytearray or array of type 'b' or 'B'" -msgstr "" - -#: shared-bindings/displayio/Bitmap.c:94 -msgid "row data must be a buffer" -msgstr "" - -#: shared-bindings/displayio/ColorConverter.c:72 -msgid "color should be an int" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 -msgid "displayio is a work in progress" -msgstr "" - -#: shared-bindings/displayio/Group.c:65 -msgid "Group must have size at least 1" -msgstr "" - -#: shared-bindings/displayio/Palette.c:96 -msgid "color buffer must be a bytearray or array of type 'b' or 'B'" -msgstr "" - -#: shared-bindings/displayio/Palette.c:102 -msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" -msgstr "" - -#: shared-bindings/displayio/Palette.c:106 -msgid "color must be between 0x000000 and 0xffffff" -msgstr "" - -#: shared-bindings/displayio/Palette.c:110 -msgid "color buffer must be a buffer or int" -msgstr "" - -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 -msgid "palette_index should be an int" -msgstr "" - -#: shared-bindings/displayio/Sprite.c:48 -msgid "position must be 2-tuple" -msgstr "" - -#: shared-bindings/displayio/Sprite.c:97 -msgid "unsupported bitmap type" -msgstr "" - -#: shared-bindings/displayio/Sprite.c:162 -msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" -msgstr "" - -#: shared-bindings/gamepad/GamePad.c:100 -msgid "too many arguments" -msgstr "" - -#: shared-bindings/gamepad/GamePad.c:104 -msgid "expected a DigitalInOut" -msgstr "" - -#: shared-bindings/i2cslave/I2CSlave.c:98 -msgid "can't convert address to int" -msgstr "" - -#: shared-bindings/i2cslave/I2CSlave.c:101 -msgid "address out of bounds" -msgstr "" - -#: shared-bindings/i2cslave/I2CSlave.c:107 -msgid "addresses is empty" -msgstr "" - -#: shared-bindings/microcontroller/Pin.c:89 -#: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:76 -msgid "Expected a %q" -msgstr "" - -#: shared-bindings/microcontroller/Pin.c:100 -msgid "%q in use" -msgstr "" - -#: shared-bindings/microcontroller/__init__.c:126 -msgid "Invalid run mode." -msgstr "" - -#: shared-bindings/multiterminal/__init__.c:68 -msgid "Stream missing readinto() or write() method." -msgstr "" - -#: shared-bindings/nvm/ByteArray.c:99 -msgid "Slice and value different lengths." -msgstr "" - -#: shared-bindings/nvm/ByteArray.c:104 -msgid "Array values should be single bytes." -msgstr "" - -#: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141 -msgid "Unable to write to nvm." -msgstr "" - -#: shared-bindings/nvm/ByteArray.c:137 -msgid "Bytes must be between 0 and 255." -msgstr "" - -#: shared-bindings/os/__init__.c:200 -msgid "No hardware random available" -msgstr "" - -#: shared-bindings/pulseio/PWMOut.c:164 -msgid "" -"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" -msgstr "" - -#: shared-bindings/pulseio/PWMOut.c:195 -msgid "" -"PWM frequency not writable when variable_frequency is False on construction." -msgstr "" - -#: shared-bindings/pulseio/PulseIn.c:275 -msgid "Cannot delete values" -msgstr "" - -#: shared-bindings/pulseio/PulseIn.c:281 -msgid "Slices not supported" -msgstr "" - -#: shared-bindings/pulseio/PulseIn.c:287 -msgid "index must be int" -msgstr "" - -#: shared-bindings/pulseio/PulseIn.c:293 -msgid "Read-only" -msgstr "" - -#: shared-bindings/pulseio/PulseOut.c:135 -msgid "Array must contain halfwords (type 'H')" -msgstr "" - -#: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100 -msgid "stop not reachable from start" -msgstr "" - -#: shared-bindings/random/__init__.c:111 -msgid "step must be non-zero" -msgstr "" - -#: shared-bindings/random/__init__.c:114 -msgid "invalid step" -msgstr "" - -#: shared-bindings/random/__init__.c:146 -msgid "empty sequence" -msgstr "" - -#: shared-bindings/rtc/RTC.c:40 shared-bindings/rtc/RTC.c:44 -#: shared-bindings/time/__init__.c:190 -msgid "RTC is not supported on this board" -msgstr "" - -#: shared-bindings/rtc/RTC.c:52 -msgid "RTC calibration is not supported on this board" -msgstr "" - -#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:81 -msgid "no available NIC" -msgstr "" - -#: shared-bindings/storage/__init__.c:77 -msgid "filesystem must provide mount method" -msgstr "" - -#: shared-bindings/supervisor/__init__.c:93 -msgid "Brightness must be between 0 and 255" -msgstr "" - -#: shared-bindings/supervisor/__init__.c:119 -msgid "Stack size must be at least 256" -msgstr "" - -#: shared-bindings/time/__init__.c:78 -msgid "sleep length must be non-negative" -msgstr "" - -#: shared-bindings/time/__init__.c:88 -msgid "time.struct_time() takes exactly 1 argument" -msgstr "" - -#: shared-bindings/time/__init__.c:91 -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - -#: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:264 -msgid "Tuple or struct_time argument required" -msgstr "" - -#: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:269 -msgid "function takes exactly 9 arguments" -msgstr "" - -#: shared-bindings/time/__init__.c:240 shared-bindings/time/__init__.c:273 -msgid "timestamp out of range for platform time_t" -msgstr "" - -#: shared-bindings/touchio/TouchIn.c:173 -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/util.c:38 -msgid "" -"Object has been deinitialized and can no longer be used. Create a new object." -msgstr "" - -#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "" - -#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "" - -#: shared-module/audioio/Mixer.c:82 -msgid "Voice index too high" -msgstr "" - -#: shared-module/audioio/Mixer.c:85 -msgid "The sample's sample rate does not match the mixer's" -msgstr "" - -#: shared-module/audioio/Mixer.c:88 -msgid "The sample's channel count does not match the mixer's" -msgstr "" - -#: shared-module/audioio/Mixer.c:91 -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" - -#: shared-module/audioio/Mixer.c:100 -msgid "The sample's signedness does not match the mixer's" -msgstr "" - -#: shared-module/audioio/WaveFile.c:61 -msgid "Invalid wave file" -msgstr "" - -#: shared-module/audioio/WaveFile.c:69 -msgid "Invalid format chunk size" -msgstr "" - -#: shared-module/audioio/WaveFile.c:83 -msgid "Unsupported format" -msgstr "" - -#: shared-module/audioio/WaveFile.c:99 -msgid "Data chunk must follow fmt chunk" -msgstr "" - -#: shared-module/audioio/WaveFile.c:107 -msgid "Invalid file" -msgstr "" - -#: shared-module/bitbangio/I2C.c:58 -msgid "Clock stretch too long" -msgstr "" - -#: shared-module/bitbangio/SPI.c:44 -msgid "Clock pin init failed." -msgstr "" - -#: shared-module/bitbangio/SPI.c:50 -msgid "MOSI pin init failed." -msgstr "" - -#: shared-module/bitbangio/SPI.c:61 -msgid "MISO pin init failed." -msgstr "" - -#: shared-module/bitbangio/SPI.c:121 -msgid "Cannot write without MOSI pin." -msgstr "" - -#: shared-module/bitbangio/SPI.c:176 -msgid "Cannot read without MISO pin." -msgstr "" - -#: shared-module/bitbangio/SPI.c:240 -msgid "Cannot transfer without MOSI and MISO pins." -msgstr "" - -#: shared-module/displayio/Bitmap.c:49 -msgid "Only bit maps of 8 bit color or less are supported" -msgstr "" - -#: shared-module/displayio/Bitmap.c:69 -msgid "row must be packed and word aligned" -msgstr "" - -#: shared-module/displayio/Group.c:39 -msgid "Group full" -msgstr "" - -#: shared-module/displayio/Group.c:48 -msgid "Group empty" -msgstr "" - -#: shared-module/displayio/OnDiskBitmap.c:49 -msgid "Invalid BMP file" -msgstr "" - -#: shared-module/displayio/OnDiskBitmap.c:59 -#, c-format -msgid "Only Windows format, uncompressed BMP supported %d" -msgstr "" - -#: shared-module/displayio/OnDiskBitmap.c:64 -#, c-format -msgid "Only true color (24 bpp or higher) BMP supported %x" -msgstr "" - -#: shared-module/storage/__init__.c:155 -msgid "Cannot remount '/' when USB is active." -msgstr "" - -#: shared-module/struct/__init__.c:39 -msgid "'S' and 'O' are not supported format types" -msgstr "" - -#: shared-module/struct/__init__.c:83 -msgid "too many arguments provided with the given format" -msgstr "" - -#: shared-module/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "" - -#: shared-module/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "" - -#: shared-module/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "" From 1c47cb24af811d400eab22e01bb8bf21a1619588 Mon Sep 17 00:00:00 2001 From: Hendra Kusumah Date: Wed, 9 Jan 2019 02:21:20 +0700 Subject: [PATCH 063/153] Create ID.po --- locale/ID.po | 2523 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2523 insertions(+) create mode 100644 locale/ID.po diff --git a/locale/ID.po b/locale/ID.po new file mode 100644 index 0000000000000..76bb14893a18c --- /dev/null +++ b/locale/ID.po @@ -0,0 +1,2523 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: extmod/machine_i2c.c:299 +msgid "invalid I2C peripheral" +msgstr "perangkat I2C tidak valid" + +#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 +#: extmod/machine_i2c.c:392 +msgid "I2C operation not supported" +msgstr "operasi I2C tidak didukung" + +#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53 +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "alamat %08x tidak selaras dengan %d bytes" + +#: extmod/machine_spi.c:57 +msgid "invalid SPI peripheral" +msgstr "perangkat SPI tidak valid" + +#: extmod/machine_spi.c:124 +msgid "buffers must be the same length" +msgstr "buffers harus mempunyai panjang yang sama" + +#: extmod/machine_spi.c:207 +msgid "bits must be 8" +msgstr "bits harus memilki nilai 8" + +#: extmod/machine_spi.c:210 +msgid "firstbit must be MSB" +msgstr "bit pertama(firstbit) harus berupa MSB" + +#: extmod/machine_spi.c:215 +msgid "must specify all of sck/mosi/miso" +msgstr "harus menentukan semua pin sck/mosi/miso" + +#: extmod/modframebuf.c:299 +msgid "invalid format" +msgstr "format tidak valid" + +#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102 +msgid "a bytes-like object is required" +msgstr "sebuah objek menyerupai byte (bytes-like) dibutuhkan" + +#: extmod/modubinascii.c:90 +msgid "odd-length string" +msgstr "panjang data string memiliki keganjilan (odd-length)" + +#: extmod/modubinascii.c:101 +msgid "non-hex digit found" +msgstr "digit non-hex ditemukan" + +#: extmod/modubinascii.c:169 +msgid "incorrect padding" +msgstr "lapisan (padding) tidak benar" + +#: extmod/moductypes.c:122 +msgid "syntax error in uctypes descriptor" +msgstr "sintaksis error pada pendeskripsi uctypes" + +#: extmod/moductypes.c:219 +msgid "Cannot unambiguously get sizeof scalar" +msgstr "tidak dapat mendapatkan ukuran scalar secara tidak ambigu" + +#: extmod/moductypes.c:397 +msgid "struct: no fields" +msgstr "struct: tidak ada fields" + +#: extmod/moductypes.c:530 +msgid "struct: cannot index" +msgstr "struct: tidak bisa melakukan index" + +#: extmod/moductypes.c:544 +msgid "struct: index out of range" +msgstr "struct: index keluar dari jangkauan" + +#: extmod/moduheapq.c:38 +msgid "heap must be a list" +msgstr "heap harus berupa sebuah list" + +#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172 +msgid "empty heap" +msgstr "heap kosong" + +#: extmod/modujson.c:281 +msgid "syntax error in JSON" +msgstr "sintaksis error pada JSON" + +#: extmod/modure.c:161 +msgid "Splitting with sub-captures" +msgstr "Memisahkan dengan menggunakan sub-captures" + +#: extmod/modure.c:207 +msgid "Error in regex" +msgstr "Error pada regex" + +#: extmod/modussl_axtls.c:81 +msgid "invalid key" +msgstr "key tidak valid" + +#: extmod/modussl_axtls.c:87 +msgid "invalid cert" +msgstr "cert tidak valid" + +#: extmod/modutimeq.c:131 +msgid "queue overflow" +msgstr "antrian meluap (overflow)" + +#: extmod/moduzlib.c:98 +msgid "compression header" +msgstr "kompresi header" + +#: extmod/uos_dupterm.c:120 +msgid "invalid dupterm index" +msgstr "indeks dupterm tidak valid" + +#: extmod/vfs_fat.c:426 py/moduerrno.c:150 +msgid "Read-only filesystem" +msgstr "sistem file (filesystem) bersifat Read-only" + +#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43 +msgid "I/O operation on closed file" +msgstr "operasi I/O pada file tertutup" + +#: lib/embed/abort_.c:8 +msgid "abort() called" +msgstr "abort() dipanggil" + +#: lib/netutils/netutils.c:83 +msgid "invalid arguments" +msgstr "argumen-argumen tidak valid" + +#: lib/utils/pyexec.c:97 py/builtinimport.c:251 +msgid "script compilation not supported" +msgstr "kompilasi script tidak didukung" + +#: main.c:154 +msgid " output:\n" +msgstr "output:\n" + +#: main.c:168 main.c:241 +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk menjalankannya atau masuk ke REPL untuk" +"menonaktifkan.\n" + +#: main.c:170 +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Berjalan di mode aman(safe mode)! Auto-reload tidak aktif.\n" + +#: main.c:172 main.c:243 +msgid "Auto-reload is off.\n" +msgstr "Auto-reload tidak aktif.\n" + +#: main.c:186 +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" + +#: main.c:202 +msgid "WARNING: Your code filename has two extensions\n" +msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" + +#: main.c:250 +msgid "You requested starting safe mode by " +msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " + +#: main.c:253 +msgid "To exit, please reset the board without " +msgstr "Untuk keluar, silahkan reset board tanpa " + +#: main.c:260 +msgid "" +"You are running in safe mode which means something really bad happened.\n" +msgstr "Anda sedang menjalankan mode aman (safe mode) yang berarti sesuatu yang sangat buruk telah terjadi.\n" + +#: main.c:262 +msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +msgstr "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" + +#: main.c:263 +msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" +msgstr "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" + +#: main.c:266 +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +msgstr "Tegangan dari mikrokontroler turun atau mati. Pastikan sumber tegangan " +"memberikan daya\n" + +#: main.c:267 +msgid "" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " +"CIRCUITPY).\n" + +#: main.c:271 +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset (Reload)" + +#: main.c:429 +msgid "soft reboot\n" +msgstr "memulai ulang software(soft reboot)\n" + +#: ports/atmel-samd/audio_dma.c:209 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 +msgid "All sync event channels in use" +msgstr "Semua channel event yang disinkronisasi sedang digunakan" + +#: ports/atmel-samd/bindings/samd/Clock.c:135 +msgid "calibration is read only" +msgstr "kalibrasi adalah read only" + +#: ports/atmel-samd/bindings/samd/Clock.c:137 +msgid "calibration is out of range" +msgstr "kalibrasi keluar dari jangkauan" + +#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 +msgid "No default I2C bus" +msgstr "Tidak ada standar bus I2C" + +#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 +msgid "No default SPI bus" +msgstr "Tidak ada standar bus SPI" + +#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 +msgid "No default UART bus" +msgstr "Tidak ada standar bus UART" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 +#: ports/nrf/common-hal/analogio/AnalogIn.c:39 +msgid "Pin does not have ADC capabilities" +msgstr "Pin tidak mempunya kemampuan untuk ADC (Analog Digital Converter)" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49 +msgid "No DAC on chip" +msgstr "Tidak ada DAC (Digital Analog Converter) di dalam chip" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56 +msgid "AnalogOut not supported on given pin" +msgstr "pin yang dipakai tidak mendukung AnalogOut" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 +msgid "Invalid bit clock pin" +msgstr "Bit clock pada pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 +msgid "Bit clock and word select must share a clock unit" +msgstr "Bit clock dan word harus memiliki kesamaan pada clock unit" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 +msgid "Invalid data pin" +msgstr "data pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:169 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:174 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150 +msgid "Serializer in use" +msgstr "Serializer sedang digunakan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230 +msgid "Clock unit in use" +msgstr "Clock unit sedang digunakan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172 +msgid "Unable to find free GCLK" +msgstr "Tidak dapat menemukan GCLK yang kosong" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254 +msgid "Too many channels in sample." +msgstr "Terlalu banyak channel dalam sampel" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 +msgid "No DMA channel found" +msgstr "tidak ada channel DMA ditemukan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 +msgid "Unable to allocate buffers for signed conversion" +msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:109 +msgid "Invalid clock pin" +msgstr "Clock pada pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134 +msgid "Only 8 or 16 bit mono with " +msgstr "Hanya 8 atau 16 bit mono dengan " + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167 +msgid "sampling rate out of range" +msgstr "nilai sampling keluar dari jangkauan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 +msgid "DAC already in use" +msgstr "DAC sudah digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 +msgid "Right channel unsupported" +msgstr "Channel Kanan tidak didukung" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 +msgid "Invalid pin" +msgstr "Pin tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 +msgid "Invalid pin for left channel" +msgstr "Pin untuk channel kiri tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 +msgid "Invalid pin for right channel" +msgstr "Pin untuk channel kanan tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 +msgid "Cannot output both channels on the same pin" +msgstr "Tidak dapat menggunakan output di kedua channel dengan menggunakan pin yang sama" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 +msgid "All timers in use" +msgstr "Semua timer sedang digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 +msgid "All event channels in use" +msgstr "Semua channel event sedang digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Nilai sampel terlalu tinggi. Nilai harus kurang dari %d" + +#: ports/atmel-samd/common-hal/busio/I2C.c:71 +msgid "Not enough pins available" +msgstr "Pin yang tersedia tidak cukup" + +#: ports/atmel-samd/common-hal/busio/I2C.c:78 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/UART.c:119 +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 +#: ports/nrf/common-hal/busio/I2C.c:82 +msgid "Invalid pins" +msgstr "Pin-pin tidak valid" + +#: ports/atmel-samd/common-hal/busio/I2C.c:101 +msgid "SDA or SCL needs a pull up" +msgstr "SDA atau SCL membutuhkan pull up" + +#: ports/atmel-samd/common-hal/busio/I2C.c:121 +msgid "Unsupported baudrate" +msgstr "Baudrate tidak didukung" + +#: ports/atmel-samd/common-hal/busio/UART.c:66 +msgid "bytes > 8 bits not supported" +msgstr "byte > 8 bit tidak didukung" + +#: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 +msgid "tx and rx cannot both be None" +msgstr "tx dan rx keduanya tidak boleh kosong" + +#: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 +msgid "Failed to allocate RX buffer" +msgstr "Gagal untuk mengalokasikan buffer RX" + +#: ports/atmel-samd/common-hal/busio/UART.c:153 +msgid "Could not initialize UART" +msgstr "Tidak dapat menginisialisasi UART" + +#: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 +msgid "No RX pin" +msgstr "Tidak pin RX" + +#: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 +msgid "No TX pin" +msgstr "Tidak ada pin TX" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 +msgid "Cannot get pull while in output mode" +msgstr "Tidak bisa mendapatkan pull pada saat mode output" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 +#: ports/esp8266/common-hal/microcontroller/__init__.c:64 +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "Tidak dapat melakukan reset ke bootloader karena tidak ada bootloader yang terisi" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 +msgid "Invalid PWM frequency" +msgstr "Frekuensi PWM tidak valid" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:187 +msgid "All timers for this pin are in use" +msgstr "Semua timer untuk pin ini sedang digunakan" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 +msgid "No hardware support on pin" +msgstr "Tidak ada dukungan hardware untuk pin" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 +msgid "EXTINT channel already in use" +msgstr "Channel EXTINT sedang digunakan" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +msgid "pop from an empty PulseIn" +msgstr "Muncul dari PulseIn yang kosong" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 +msgid "index out of range" +msgstr "index keluar dari jangkauan" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178 +msgid "Another send is already active" +msgstr "Send yang lain sudah aktif" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38 +msgid "Both pins must support hardware interrupts" +msgstr "Kedua pin harus mendukung hardware interrut" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:46 +msgid "A hardware interrupt channel is already in use" +msgstr "Sebuah channel hardware interrupt sedang digunakan" + +#: ports/atmel-samd/common-hal/rtc/RTC.c:101 +msgid "calibration value out of range +/-127" +msgstr "nilai kalibrasi keluar dari jangkauan +/-127" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 +msgid "No free GCLKs" +msgstr "Tidak ada GCLK yang kosong" + +#: ports/esp8266/common-hal/analogio/AnalogIn.c:43 +msgid "Pin %q does not have ADC capabilities" +msgstr "Pin %q tidak memiliki kemampuan ADC" + +#: ports/esp8266/common-hal/analogio/AnalogOut.c:39 +msgid "No hardware support for analog out." +msgstr "Tidak dukungan hardware untuk analog out." + +#: ports/esp8266/common-hal/busio/SPI.c:72 +msgid "Pins not valid for SPI" +msgstr "Pin-pin tidak valid untuk SPI" + +#: ports/esp8266/common-hal/busio/UART.c:45 +msgid "Only tx supported on UART1 (GPIO2)." +msgstr "Hanya tx yang mendukung pada UART1 (GPIO2)." + +#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 +msgid "invalid data bits" +msgstr "bit data tidak valid" + +#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144 +msgid "invalid stop bits" +msgstr "stop bit tidak valid" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 +msgid "ESP8266 does not support pull down." +msgstr "ESP866 tidak mendukung pull down" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 +msgid "GPIO16 does not support pull up." +msgstr "GPIO16 tidak mendukung pull up" + +#: ports/esp8266/common-hal/microcontroller/__init__.c:66 +msgid "ESP8226 does not support safe mode." +msgstr "ESP8266 tidak mendukung safe mode" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:54 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:113 +#, c-format +msgid "Maximum PWM frequency is %dhz." +msgstr "Nilai maksimum frekuensi PWM adalah %dhz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:57 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:116 +msgid "Minimum PWM frequency is 1hz." +msgstr "Nilai minimum frekuensi PWM is 1hz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:68 +#, c-format +msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +msgstr "Nilai Frekuensi PWM ganda tidak didukung. PWM sudah diatur pada %dhz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 +#, c-format +msgid "PWM not supported on pin %d" +msgstr "PWM tidak didukung pada pin %d" + +#: ports/esp8266/common-hal/pulseio/PulseIn.c:78 +msgid "No PulseIn support for %q" +msgstr "Tidak ada dukungan PulseIn untuk %q" + +#: ports/esp8266/common-hal/storage/__init__.c:34 +msgid "Unable to remount filesystem" +msgstr "Tidak dapat memasang filesystem kembali" + +#: ports/esp8266/common-hal/storage/__init__.c:38 +msgid "Use esptool to erase flash and re-upload Python instead" +msgstr "Gunakan esptool untuk menghapus flash dan upload ulang Python sebagai gantinya" + +#: ports/esp8266/esp_mphal.c:154 +msgid "C-level assert" +msgstr "Dukungan C-level" + +#: ports/esp8266/machine_adc.c:57 +#, c-format +msgid "not a valid ADC Channel: %d" +msgstr "tidak valid channel ADC: %d" + +#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 +msgid "impossible baudrate" +msgstr "baudrate tidak memungkinkan" + +#: ports/esp8266/machine_pin.c:129 +msgid "expecting a pin" +msgstr "mengharapkan sebuah pin" + +#: ports/esp8266/machine_pin.c:284 +msgid "Pin(16) doesn't support pull" +msgstr "Pin(16) tidak mendukung pull" + +#: ports/esp8266/machine_pin.c:323 +msgid "invalid pin" +msgstr "pin tidak valid" + +#: ports/esp8266/machine_pin.c:389 +msgid "pin does not have IRQ capabilities" +msgstr "pin tidak memiliki kemampuan IRQ" + +#: ports/esp8266/machine_rtc.c:185 +msgid "buffer too long" +msgstr "buffer terlalu panjang" + +#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 +#: ports/esp8266/machine_rtc.c:246 +msgid "invalid alarm" +msgstr "alarm tidak valid" + +#: ports/esp8266/machine_uart.c:169 +#, c-format +msgid "UART(%d) does not exist" +msgstr "UART(%d) tidak ada" + +#: ports/esp8266/machine_uart.c:219 +msgid "UART(1) can't read" +msgstr "UART(1) tidak dapat dibaca" + +#: ports/esp8266/modesp.c:119 +msgid "len must be multiple of 4" +msgstr "len harus kelipatan dari 4" + +#: ports/esp8266/modesp.c:274 +#, c-format +msgid "memory allocation failed, allocating %u bytes for native code" +msgstr "alokasi memori gagal, mengalokasikan %u byte untuk kode native" + +#: ports/esp8266/modesp.c:317 +msgid "flash location must be below 1MByte" +msgstr "alokasi flash harus dibawah 1MByte" + +#: ports/esp8266/modmachine.c:63 +msgid "frequency can only be either 80Mhz or 160MHz" +msgstr "frekuensi hanya bisa didefinisikan 80Mhz atau 160Mhz" + +#: ports/esp8266/modnetwork.c:61 +msgid "AP required" +msgstr "AP dibutuhkan" + +#: ports/esp8266/modnetwork.c:61 +msgid "STA required" +msgstr "STA dibutuhkan" + +#: ports/esp8266/modnetwork.c:87 +msgid "Cannot update i/f status" +msgstr "Tidak dapat memperbarui status i/f" + +#: ports/esp8266/modnetwork.c:142 +msgid "Cannot set STA config" +msgstr "Tidak dapat mengatur konfigurasi STA" + +#: ports/esp8266/modnetwork.c:144 +msgid "Cannot connect to AP" +msgstr "Tidak dapat menyambungkan ke AP" + +#: ports/esp8266/modnetwork.c:152 +msgid "Cannot disconnect from AP" +msgstr "Tidak dapat memutuskna dari AP" + +#: ports/esp8266/modnetwork.c:173 +msgid "unknown status param" +msgstr "status param tidak diketahui" + +#: ports/esp8266/modnetwork.c:222 +msgid "STA must be active" +msgstr "STA harus aktif" + +#: ports/esp8266/modnetwork.c:239 +msgid "scan failed" +msgstr "scan gagal" + +#: ports/esp8266/modnetwork.c:306 +msgid "wifi_set_ip_info() failed" +msgstr "wifi_set_ip_info() gagal" + +#: ports/esp8266/modnetwork.c:319 +msgid "either pos or kw args are allowed" +msgstr "hanya antar pos atau kw args yang diperbolehkan" + +#: ports/esp8266/modnetwork.c:329 +msgid "can't get STA config" +msgstr "tidak bisa mendapatkan konfigurasi STA" + +#: ports/esp8266/modnetwork.c:331 +msgid "can't get AP config" +msgstr "tidak bisa mendapatkan konfigurasi AP" + +#: ports/esp8266/modnetwork.c:346 +msgid "invalid buffer length" +msgstr "panjang buffer tidak valid" + +#: ports/esp8266/modnetwork.c:405 +msgid "can't set STA config" +msgstr "tidak bisa mendapatkan konfigurasi STA" + +#: ports/esp8266/modnetwork.c:407 +msgid "can't set AP config" +msgstr "tidak bisa mendapatkan konfigurasi AP" + +#: ports/esp8266/modnetwork.c:416 +msgid "can query only one param" +msgstr "hanya bisa melakukan query satu param" + +#: ports/esp8266/modnetwork.c:469 +msgid "unknown config param" +msgstr "konfigurasi param tidak diketahui" + +#: ports/nrf/common-hal/analogio/AnalogOut.c:37 +msgid "AnalogOut functionality not supported" +msgstr "fungsionalitas AnalogOut tidak didukung" + +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "Gagal untuk mendapatkan alamat lokal, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" +msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover services, status: 0x%08lX" +msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Gagal untuk menyambungkan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Gagal untuk membuat mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Panjang string UUID tidak valid" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parameter UUID tidak valid" + +#: ports/nrf/common-hal/busio/I2C.c:96 +msgid "All I2C peripherals are in use" +msgstr "Semua perangkat I2C sedang digunakan" + +#: ports/nrf/common-hal/busio/SPI.c:133 +msgid "All SPI peripherals are in use" +msgstr "Semua perangkat SPI sedang digunakan" + +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "error = 0x%08lX" + +#: ports/nrf/common-hal/busio/UART.c:86 +msgid "Invalid buffer size" +msgstr "Ukuran buffer tidak valid" + +#: ports/nrf/common-hal/busio/UART.c:90 +msgid "Odd parity is not supported" +msgstr "Parity ganjil tidak didukung" + +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +msgid "busio.UART not available" +msgstr "busio.UART tidak tersedia" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "Tidak bisa mendapatkan temperatur. status: 0x%02x" + +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 +msgid "All PWM peripherals are in use" +msgstr "Semua perangkat PWM sedang digunakan" + +#: ports/unix/modffi.c:138 +msgid "Unknown type" +msgstr "Tipe tidak diketahui" + +#: ports/unix/modffi.c:207 ports/unix/modffi.c:265 +msgid "Error in ffi_prep_cif" +msgstr "Errod pada ffi_prep_cif" + +#: ports/unix/modffi.c:270 +msgid "ffi_prep_closure_loc" +msgstr "ffi_prep_closure_loc" + +#: ports/unix/modffi.c:413 +msgid "Don't know how to pass object to native function" +msgstr "Tidak tahu cara meloloskan objek ke fungsi native" + +#: ports/unix/modusocket.c:474 +#, c-format +msgid "[addrinfo error %d]" +msgstr "[addrinfo error %d]" + +#: py/argcheck.c:44 +msgid "function does not take keyword arguments" +msgstr "fungsi tidak dapat mengambil argumen keyword" + +#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "fungsi mengambil posisi argumen %d tapi %d yang diberikan" + +#: py/argcheck.c:64 +#, c-format +msgid "function missing %d required positional arguments" +msgstr "fungsi kehilangan %d argumen posisi yang dibutuhkan" + +#: py/argcheck.c:72 +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "fungsi diharapkan setidaknya %d argumen, hanya mendapatkan %d" + +#: py/argcheck.c:97 +msgid "'%q' argument required" +msgstr "'%q' argumen dibutuhkan" + +#: py/argcheck.c:122 +msgid "extra positional arguments given" +msgstr "argumen posisi ekstra telah diberikan" + +#: py/argcheck.c:130 +msgid "extra keyword arguments given" +msgstr "argumen keyword ekstra telah diberikan" + +#: py/argcheck.c:142 +msgid "argument num/types mismatch" +msgstr "argumen num/types tidak cocok" + +#: py/argcheck.c:147 +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "argumen keyword belum diimplementasi - gunakan args normal" + +#: py/bc.c:88 py/objnamedtuple.c:108 +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" + +#: py/bc.c:197 py/bc.c:215 +msgid "unexpected keyword argument" +msgstr "argumen keyword tidak diharapkan" + +#: py/bc.c:199 +msgid "keywords must be strings" +msgstr "keyword harus berupa string" + +#: py/bc.c:206 py/objnamedtuple.c:138 +msgid "function got multiple values for argument '%q'" +msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" + +#: py/bc.c:218 py/objnamedtuple.c:130 +msgid "unexpected keyword argument '%q'" +msgstr "keyword argumen '%q' tidak diharapkan" + +#: py/bc.c:244 +#, c-format +msgid "function missing required positional argument #%d" +msgstr "fungsi kehilangan argumen posisi #%d yang dibutuhkan" + +#: py/bc.c:260 +msgid "function missing required keyword argument '%q'" +msgstr "fungsi kehilangan argumen keyword '%q' yang dibutuhkan" + +#: py/bc.c:269 +msgid "function missing keyword-only argument" +msgstr "fungsi kehilangan argumen keyword-only" + +#: py/binary.c:112 +msgid "bad typecode" +msgstr "typecode buruk" + +#: py/builtinevex.c:99 +msgid "bad compile mode" +msgstr "mode compile buruk" + +#: py/builtinhelp.c:137 +msgid "Plus any modules on the filesystem\n" +msgstr "Tambahkan module apapun pada filesystem\n" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Selamat datang ke Adafruit CircuitPython %s!\n" +"\n" +"Silahkan kunjungi learn.adafruit.com/category/circuitpython untuk panduan project.\n" +"\n" +"Untuk menampilkan modul built-in silahkan ketik `help(\"modules\")`.\n" + +#: py/builtinimport.c:336 +msgid "cannot perform relative import" +msgstr "tidak dapat melakukan relative import" + +#: py/builtinimport.c:420 py/builtinimport.c:532 +msgid "module not found" +msgstr "modul tidak ditemukan" + +#: py/builtinimport.c:423 py/builtinimport.c:535 +msgid "no module named '%q'" +msgstr "tidak ada modul yang bernama '%q'" + +#: py/builtinimport.c:510 +msgid "relative import" +msgstr "relative import" + +#: py/compile.c:397 py/compile.c:542 +msgid "can't assign to expression" +msgstr "tidak dapat menetapkan ke ekspresi" + +#: py/compile.c:416 +msgid "multiple *x in assignment" +msgstr "perkalian *x dalam assignment" + +#: py/compile.c:642 +msgid "non-default argument follows default argument" +msgstr "argumen non-default mengikuti argumen standar(default)" + +#: py/compile.c:771 py/compile.c:789 +msgid "invalid micropython decorator" +msgstr "micropython decorator tidak valid" + +#: py/compile.c:943 +msgid "can't delete expression" +msgstr "tidak bisa menghapus ekspresi" + +#: py/compile.c:955 +msgid "'break' outside loop" +msgstr "'break' diluar loop" + +#: py/compile.c:958 +msgid "'continue' outside loop" +msgstr "'continue' diluar loop" + +#: py/compile.c:969 +msgid "'return' outside function" +msgstr "'return' diluar fungsi" + +#: py/compile.c:1169 +msgid "identifier redefined as global" +msgstr "identifier didefinisi ulang sebagai global" + +#: py/compile.c:1185 +msgid "no binding for nonlocal found" +msgstr "tidak ada ikatan/bind pada temuan nonlocal" + +#: py/compile.c:1188 +msgid "identifier redefined as nonlocal" +msgstr "identifier didefinisi ulang sebagai nonlocal" + +#: py/compile.c:1197 +msgid "can't declare nonlocal in outer code" +msgstr "tidak dapat mendeklarasikan nonlocal diluar jangkauan kode" + +#: py/compile.c:1542 +msgid "default 'except' must be last" +msgstr "'except' standar harus terakhir" + +#: py/compile.c:2095 +msgid "*x must be assignment target" +msgstr "*x harus menjadi target assignment" + +#: py/compile.c:2193 +msgid "super() can't find self" +msgstr "super() tidak dapat menemukan dirinya sendiri" + +#: py/compile.c:2256 +msgid "can't have multiple *x" +msgstr "tidak bisa memiliki *x ganda" + +#: py/compile.c:2263 +msgid "can't have multiple **x" +msgstr "tidak bisa memiliki **x ganda" + +#: py/compile.c:2271 +msgid "LHS of keyword arg must be an id" +msgstr "LHS dari keyword arg harus menjadi sebuah id" + +#: py/compile.c:2287 +msgid "non-keyword arg after */**" +msgstr "non-keyword arg setelah */**" + +#: py/compile.c:2291 +msgid "non-keyword arg after keyword arg" +msgstr "non-keyword arg setelah keyword arg" + +#: py/compile.c:2463 py/compile.c:2473 py/compile.c:2712 py/compile.c:2742 +#: py/parse.c:1176 +msgid "invalid syntax" +msgstr "syntax tidak valid" + +#: py/compile.c:2465 +msgid "expecting key:value for dict" +msgstr "key:value diharapkan untuk dict" + +#: py/compile.c:2475 +msgid "expecting just a value for set" +msgstr "hanya mengharapkan sebuah nilai (value) untuk set" + +#: py/compile.c:2600 +msgid "'yield' outside function" +msgstr "'yield' diluar fungsi" + +#: py/compile.c:2619 +msgid "'await' outside function" +msgstr "'await' diluar fungsi" + +#: py/compile.c:2774 +msgid "name reused for argument" +msgstr "nama digunakan kembali untuk argumen" + +#: py/compile.c:2827 +msgid "parameter annotation must be an identifier" +msgstr "anotasi parameter haruse sebuah identifier" + +#: py/compile.c:2969 py/compile.c:3137 +msgid "return annotation must be an identifier" +msgstr "anotasi return harus sebuah identifier" + +#: py/compile.c:3097 +msgid "inline assembler must be a function" +msgstr "inline assembler harus sebuah fungsi" + +#: py/compile.c:3134 +msgid "unknown type" +msgstr "tipe tidak diketahui" + +#: py/compile.c:3154 +msgid "expecting an assembler instruction" +msgstr "sebuah instruksi assembler diharapkan" + +#: py/compile.c:3184 +msgid "'label' requires 1 argument" +msgstr "'label' membutuhkan 1 argumen" + +#: py/compile.c:3190 +msgid "label redefined" +msgstr "label didefinis ulang" + +#: py/compile.c:3196 +msgid "'align' requires 1 argument" +msgstr "'align' membutuhkan 1 argumen" + +#: py/compile.c:3205 +msgid "'data' requires at least 2 arguments" +msgstr "'data' membutuhkan setidaknya 2 argumen" + +#: py/compile.c:3212 +msgid "'data' requires integer arguments" +msgstr "'data' membutuhkan argumen integer" + +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "hanya mampu memiliki hingga 4 parameter untuk Thumb assembly" + +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +msgid "parameters must be registers in sequence r0 to r3" +msgstr "parameter harus menjadi register dalam urutan r0 sampai r3" + +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' mengharapkan setidaknya r%d" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' mengharapkan sebuah register" + +#: py/emitinlinethumb.c:211 +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' mengharapkan sebuah register spesial" + +#: py/emitinlinethumb.c:239 +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' mengharapkan sebuah FPU register" + +#: py/emitinlinethumb.c:292 +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' mengharapkan {r0, r1, ...}" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' mengharapkan integer" + +#: py/emitinlinethumb.c:304 +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' integer 0x%x tidak cukup didalam mask 0x%x" + +#: py/emitinlinethumb.c:328 +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' mengharapkan sebuah alamat dengan bentuk [a, b]" + +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 +msgid "label '%q' not defined" +msgstr "" + +#: py/emitinlinethumb.c:806 +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinethumb.c:810 +msgid "branch not in range" +msgstr "" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinextensa.c:327 +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/emitnative.c:183 +msgid "unknown type '%q'" +msgstr "" + +#: py/emitnative.c:260 +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: py/emitnative.c:742 +msgid "conversion to object" +msgstr "" + +#: py/emitnative.c:921 +msgid "local '%q' used before type known" +msgstr "" + +#: py/emitnative.c:1118 py/emitnative.c:1156 +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c:1128 +msgid "can't load with '%q' index" +msgstr "" + +#: py/emitnative.c:1188 +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c:1289 py/emitnative.c:1379 +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c:1358 py/emitnative.c:1419 +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c:1369 +msgid "can't store with '%q' index" +msgstr "" + +#: py/emitnative.c:1540 +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c:1774 +msgid "unary op %q not implemented" +msgstr "" + +#: py/emitnative.c:1930 +msgid "binary op %q not implemented" +msgstr "" + +#: py/emitnative.c:1951 +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/emitnative.c:2126 +msgid "casting" +msgstr "" + +#: py/emitnative.c:2173 +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/emitnative.c:2191 +msgid "must raise an object" +msgstr "" + +#: py/emitnative.c:2201 +msgid "native yield" +msgstr "" + +#: py/lexer.c:345 +msgid "unicode name escapes" +msgstr "" + +#: py/modbuiltins.c:162 +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c:171 +msgid "chr() arg not in range(256)" +msgstr "" + +#: py/modbuiltins.c:285 +msgid "arg is an empty sequence" +msgstr "" + +#: py/modbuiltins.c:350 +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c:353 +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/modbuiltins.c:363 +msgid "3-arg pow() not supported" +msgstr "" + +#: py/modbuiltins.c:517 +msgid "must use keyword argument for key function" +msgstr "" + +#: py/modmath.c:41 shared-bindings/math/__init__.c:53 +msgid "math domain error" +msgstr "" + +#: py/modmath.c:196 py/objfloat.c:270 py/objint_longlong.c:222 +#: py/objint_mpz.c:230 py/runtime.c:619 shared-bindings/math/__init__.c:346 +msgid "division by zero" +msgstr "" + +#: py/modmicropython.c:155 +msgid "schedule stack full" +msgstr "" + +#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 +#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 +#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +msgid "buffer too small" +msgstr "" + +#: py/modthread.c:240 +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/moduerrno.c:143 py/moduerrno.c:146 +msgid "Permission denied" +msgstr "" + +#: py/moduerrno.c:144 +msgid "No such file/directory" +msgstr "" + +#: py/moduerrno.c:145 +msgid "Input/output error" +msgstr "" + +#: py/moduerrno.c:147 +msgid "File exists" +msgstr "" + +#: py/moduerrno.c:148 +msgid "Unsupported operation" +msgstr "" + +#: py/moduerrno.c:149 +msgid "Invalid argument" +msgstr "" + +#: py/obj.c:90 +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: py/obj.c:94 +msgid " File \"%q\", line %d" +msgstr "" + +#: py/obj.c:96 +msgid " File \"%q\"" +msgstr "" + +#: py/obj.c:100 +msgid ", in %q\n" +msgstr "" + +#: py/obj.c:257 +msgid "can't convert to int" +msgstr "" + +#: py/obj.c:260 +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/obj.c:320 +msgid "can't convert to float" +msgstr "" + +#: py/obj.c:323 +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c:353 +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c:356 +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c:371 +msgid "expected tuple/list" +msgstr "" + +#: py/obj.c:374 +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c:385 +msgid "tuple/list has wrong length" +msgstr "" + +#: py/obj.c:387 +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/obj.c:400 +msgid "indices must be integers" +msgstr "" + +#: py/obj.c:403 +msgid "%q indices must be integers, not %s" +msgstr "" + +#: py/obj.c:423 +msgid "%q index out of range" +msgstr "" + +#: py/obj.c:455 +msgid "object has no len" +msgstr "" + +#: py/obj.c:458 +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c:496 +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c:499 +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/obj.c:503 +msgid "object is not subscriptable" +msgstr "" + +#: py/obj.c:506 +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/obj.c:510 +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c:513 +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c:544 +msgid "object with buffer protocol required" +msgstr "" + +#: py/objarray.c:413 py/objstr.c:427 py/objstrunicode.c:191 py/objtuple.c:187 +#: shared-bindings/nvm/ByteArray.c:85 +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/objarray.c:426 +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/objarray.c:444 shared-bindings/nvm/ByteArray.c:107 +msgid "array/bytes required on right side" +msgstr "" + +#: py/objcomplex.c:203 +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/objcomplex.c:209 +msgid "complex division by zero" +msgstr "" + +#: py/objcomplex.c:237 +msgid "0.0 to a complex power" +msgstr "" + +#: py/objdeque.c:107 +msgid "full" +msgstr "" + +#: py/objdeque.c:127 +msgid "empty" +msgstr "" + +#: py/objdict.c:314 +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objdict.c:357 +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/objfloat.c:308 py/parsenum.c:331 +msgid "complex values not supported" +msgstr "" + +#: py/objgenerator.c:108 +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objgenerator.c:126 +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c:229 +msgid "generator ignored GeneratorExit" +msgstr "" + +#: py/objgenerator.c:251 +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objint.c:144 +msgid "can't convert inf to int" +msgstr "" + +#: py/objint.c:146 +msgid "can't convert NaN to int" +msgstr "" + +#: py/objint.c:163 +msgid "float too big" +msgstr "" + +#: py/objint.c:328 +msgid "long int not supported in this build" +msgstr "" + +#: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 +msgid "small int overflow" +msgstr "" + +#: py/objint_longlong.c:189 py/objint_mpz.c:283 py/runtime.c:486 +msgid "negative power with no float support" +msgstr "" + +#: py/objint_longlong.c:251 +msgid "ulonglong too large" +msgstr "" + +#: py/objint_mpz.c:267 py/runtime.c:396 py/runtime.c:411 +msgid "negative shift count" +msgstr "" + +#: py/objint_mpz.c:336 +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: py/objint_mpz.c:347 +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c:415 +msgid "overflow converting long int to machine word" +msgstr "" + +#: py/objlist.c:273 +msgid "pop from empty list" +msgstr "" + +#: py/objnamedtuple.c:92 +msgid "can't set attribute" +msgstr "" + +#: py/objobject.c:55 +msgid "__new__ arg must be a user-type" +msgstr "" + +#: py/objrange.c:110 +msgid "zero step" +msgstr "" + +#: py/objset.c:371 +msgid "pop from an empty set" +msgstr "" + +#: py/objslice.c:66 +msgid "Length must be an int" +msgstr "" + +#: py/objslice.c:71 +msgid "Length must be non-negative" +msgstr "" + +#: py/objslice.c:86 py/sequence.c:57 +msgid "slice step cannot be zero" +msgstr "" + +#: py/objslice.c:159 +msgid "Cannot subclass slice" +msgstr "" + +#: py/objstr.c:261 +msgid "bytes value out of range" +msgstr "" + +#: py/objstr.c:270 +msgid "wrong number of arguments" +msgstr "" + +#: py/objstr.c:467 +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744 +msgid "empty separator" +msgstr "" + +#: py/objstr.c:641 +msgid "rsplit(None,n)" +msgstr "" + +#: py/objstr.c:713 +msgid "substring not found" +msgstr "" + +#: py/objstr.c:770 +msgid "start/end indices" +msgstr "" + +#: py/objstr.c:931 +msgid "bad format string" +msgstr "" + +#: py/objstr.c:953 +msgid "single '}' encountered in format string" +msgstr "" + +#: py/objstr.c:992 +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c:996 +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: py/objstr.c:998 +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c:1029 +msgid "unmatched '{' in format" +msgstr "" + +#: py/objstr.c:1036 +msgid "expected ':' after format specifier" +msgstr "" + +#: py/objstr.c:1050 +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c:1055 py/objstr.c:1083 +msgid "tuple index out of range" +msgstr "" + +#: py/objstr.c:1071 +msgid "attributes not supported yet" +msgstr "" + +#: py/objstr.c:1079 +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objstr.c:1171 +msgid "invalid format specifier" +msgstr "" + +#: py/objstr.c:1192 +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1200 +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c:1259 +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c:1331 +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c:1343 +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1367 +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/objstr.c:1415 +msgid "format requires a dict" +msgstr "" + +#: py/objstr.c:1424 +msgid "incomplete format key" +msgstr "" + +#: py/objstr.c:1482 +msgid "incomplete format" +msgstr "" + +#: py/objstr.c:1490 +msgid "not enough arguments for format string" +msgstr "" + +#: py/objstr.c:1500 +#, c-format +msgid "%%c requires int or char" +msgstr "" + +#: py/objstr.c:1507 +msgid "integer required" +msgstr "" + +#: py/objstr.c:1570 +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/objstr.c:1577 +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c:2102 +msgid "can't convert to str implicitly" +msgstr "" + +#: py/objstr.c:2106 +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objstrunicode.c:134 +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/objstrunicode.c:145 py/objstrunicode.c:164 +msgid "string index out of range" +msgstr "" + +#: py/objtype.c:358 +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c:360 +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +msgid "unreadable attribute" +msgstr "" + +#: py/objtype.c:868 py/runtime.c:653 +msgid "object not callable" +msgstr "" + +#: py/objtype.c:870 py/runtime.c:655 +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/objtype.c:978 +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objtype.c:989 +msgid "cannot create instance" +msgstr "" + +#: py/objtype.c:991 +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c:1047 +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/objtype.c:1091 py/objtype.c:1097 +msgid "type is not an acceptable base type" +msgstr "" + +#: py/objtype.c:1100 +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c:1137 +msgid "multiple inheritance not supported" +msgstr "" + +#: py/objtype.c:1164 +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c:1205 +msgid "first argument to super() must be type" +msgstr "" + +#: py/objtype.c:1370 +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objtype.c:1384 +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/parse.c:726 +msgid "constant must be an integer" +msgstr "" + +#: py/parse.c:868 +msgid "Unable to init parser" +msgstr "" + +#: py/parse.c:1170 +msgid "unexpected indent" +msgstr "" + +#: py/parse.c:1173 +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/parsenum.c:60 +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/parsenum.c:151 +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c:155 +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c:339 +msgid "invalid syntax for number" +msgstr "" + +#: py/parsenum.c:342 +msgid "decimal numbers not supported" +msgstr "" + +#: py/persistentcode.c:223 +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: py/persistentcode.c:326 +msgid "can only save bytecode" +msgstr "" + +#: py/runtime.c:206 +msgid "name not defined" +msgstr "" + +#: py/runtime.c:209 +msgid "name '%q' is not defined" +msgstr "" + +#: py/runtime.c:304 py/runtime.c:611 +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c:307 +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c:614 +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/runtime.c:881 py/runtime.c:888 py/runtime.c:945 +msgid "wrong number of values to unpack" +msgstr "" + +#: py/runtime.c:883 py/runtime.c:947 +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/runtime.c:890 +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/runtime.c:984 +msgid "argument has wrong type" +msgstr "" + +#: py/runtime.c:986 +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/runtime.c:1123 py/runtime.c:1197 +msgid "no such attribute" +msgstr "" + +#: py/runtime.c:1128 +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/runtime.c:1132 py/runtime.c:1200 +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c:1238 +msgid "object not iterable" +msgstr "" + +#: py/runtime.c:1241 +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/runtime.c:1260 py/runtime.c:1296 +msgid "object not an iterator" +msgstr "" + +#: py/runtime.c:1262 py/runtime.c:1298 +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/runtime.c:1401 +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/runtime.c:1430 +msgid "cannot import name %q" +msgstr "" + +#: py/runtime.c:1535 +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/runtime.c:1539 +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c:1609 +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/sequence.c:264 +msgid "object not in sequence" +msgstr "" + +#: py/stream.c:96 +msgid "stream operation not supported" +msgstr "" + +#: py/vm.c:255 +msgid "local variable referenced before assignment" +msgstr "" + +#: py/vm.c:1142 +msgid "no active exception to reraise" +msgstr "" + +#: py/vm.c:1284 +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_stage/Layer.c:71 +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: shared-bindings/_stage/Layer.c:77 shared-bindings/_stage/Text.c:75 +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/_stage/Layer.c:84 +msgid "map buffer too small" +msgstr "" + +#: shared-bindings/_stage/Text.c:69 +msgid "font must be 2048 bytes long" +msgstr "" + +#: shared-bindings/_stage/Text.c:81 +msgid "chars buffer too small" +msgstr "" + +#: shared-bindings/analogio/AnalogOut.c:118 +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: shared-bindings/audiobusio/I2SOut.c:225 +#: shared-bindings/audioio/AudioOut.c:226 +msgid "Not playing" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:124 +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:128 +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:136 +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:193 +msgid "destination_length must be an int >= 0" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:199 +msgid "Cannot record to a file" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:202 +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:206 +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:208 +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:94 +msgid "Invalid voice count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:99 +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:103 +msgid "Sample rate must be positive" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:107 +msgid "bits_per_sample must be 8 or 16" +msgstr "" + +#: shared-bindings/audioio/RawSample.c:98 +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: shared-bindings/audioio/RawSample.c:104 +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-bindings/audioio/WaveFile.c:78 +#: shared-bindings/displayio/OnDiskBitmap.c:85 +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 +#: shared-bindings/busio/SPI.c:133 +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +msgid "Buffer must be at least length 1" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +msgid "Invalid phase" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +msgid "Invalid number of bits" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +msgid "buffer slices must be of equal length" +msgstr "" + +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + +#: shared-bindings/busio/I2C.c:120 +msgid "Function requires lock." +msgstr "" + +#: shared-bindings/busio/UART.c:102 +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: shared-bindings/busio/UART.c:114 +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:211 +msgid "Invalid direction." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:240 +msgid "Cannot set value when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:266 +#: shared-bindings/digitalio/DigitalInOut.c:281 +msgid "Drive mode not used when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:314 +#: shared-bindings/digitalio/DigitalInOut.c:331 +msgid "Pull not used when direction is output." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:340 +msgid "Unsupported pull value." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:84 +msgid "y should be an int" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:89 +msgid "row buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:94 +msgid "row data must be a buffer" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c:72 +msgid "color should be an int" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:55 +#: shared-bindings/displayio/FourWire.c:64 +msgid "displayio is a work in progress" +msgstr "" + +#: shared-bindings/displayio/Group.c:65 +msgid "Group must have size at least 1" +msgstr "" + +#: shared-bindings/displayio/Palette.c:96 +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c:102 +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c:106 +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/Palette.c:110 +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c:123 +#: shared-bindings/displayio/Palette.c:137 +msgid "palette_index should be an int" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:48 +msgid "position must be 2-tuple" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:97 +msgid "unsupported bitmap type" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:162 +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: shared-bindings/gamepad/GamePad.c:100 +msgid "too many arguments" +msgstr "" + +#: shared-bindings/gamepad/GamePad.c:104 +msgid "expected a DigitalInOut" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:98 +msgid "can't convert address to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:101 +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:107 +msgid "addresses is empty" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c:89 +#: shared-bindings/neopixel_write/__init__.c:67 +#: shared-bindings/pulseio/PulseOut.c:76 +msgid "Expected a %q" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c:100 +msgid "%q in use" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c:126 +msgid "Invalid run mode." +msgstr "" + +#: shared-bindings/multiterminal/__init__.c:68 +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:99 +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:104 +msgid "Array values should be single bytes." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141 +msgid "Unable to write to nvm." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:137 +msgid "Bytes must be between 0 and 255." +msgstr "" + +#: shared-bindings/os/__init__.c:200 +msgid "No hardware random available" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c:164 +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c:195 +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:275 +msgid "Cannot delete values" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:281 +msgid "Slices not supported" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:287 +msgid "index must be int" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:293 +msgid "Read-only" +msgstr "" + +#: shared-bindings/pulseio/PulseOut.c:135 +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100 +msgid "stop not reachable from start" +msgstr "" + +#: shared-bindings/random/__init__.c:111 +msgid "step must be non-zero" +msgstr "" + +#: shared-bindings/random/__init__.c:114 +msgid "invalid step" +msgstr "" + +#: shared-bindings/random/__init__.c:146 +msgid "empty sequence" +msgstr "" + +#: shared-bindings/rtc/RTC.c:40 shared-bindings/rtc/RTC.c:44 +#: shared-bindings/time/__init__.c:190 +msgid "RTC is not supported on this board" +msgstr "" + +#: shared-bindings/rtc/RTC.c:52 +msgid "RTC calibration is not supported on this board" +msgstr "" + +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:81 +msgid "no available NIC" +msgstr "" + +#: shared-bindings/storage/__init__.c:77 +msgid "filesystem must provide mount method" +msgstr "" + +#: shared-bindings/supervisor/__init__.c:93 +msgid "Brightness must be between 0 and 255" +msgstr "" + +#: shared-bindings/supervisor/__init__.c:119 +msgid "Stack size must be at least 256" +msgstr "" + +#: shared-bindings/time/__init__.c:78 +msgid "sleep length must be non-negative" +msgstr "" + +#: shared-bindings/time/__init__.c:88 +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/time/__init__.c:91 +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:264 +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:269 +msgid "function takes exactly 9 arguments" +msgstr "" + +#: shared-bindings/time/__init__.c:240 shared-bindings/time/__init__.c:273 +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-bindings/touchio/TouchIn.c:173 +msgid "threshold must be in the range 0-65536" +msgstr "" + +#: shared-bindings/util.c:38 +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" + +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-module/audioio/WaveFile.c:61 +msgid "Invalid wave file" +msgstr "" + +#: shared-module/audioio/WaveFile.c:69 +msgid "Invalid format chunk size" +msgstr "" + +#: shared-module/audioio/WaveFile.c:83 +msgid "Unsupported format" +msgstr "" + +#: shared-module/audioio/WaveFile.c:99 +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: shared-module/audioio/WaveFile.c:107 +msgid "Invalid file" +msgstr "" + +#: shared-module/bitbangio/I2C.c:58 +msgid "Clock stretch too long" +msgstr "" + +#: shared-module/bitbangio/SPI.c:44 +msgid "Clock pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:50 +msgid "MOSI pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:61 +msgid "MISO pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:121 +msgid "Cannot write without MOSI pin." +msgstr "" + +#: shared-module/bitbangio/SPI.c:176 +msgid "Cannot read without MISO pin." +msgstr "" + +#: shared-module/bitbangio/SPI.c:240 +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "" + +#: shared-module/displayio/Bitmap.c:49 +msgid "Only bit maps of 8 bit color or less are supported" +msgstr "" + +#: shared-module/displayio/Bitmap.c:69 +msgid "row must be packed and word aligned" +msgstr "" + +#: shared-module/displayio/Group.c:39 +msgid "Group full" +msgstr "" + +#: shared-module/displayio/Group.c:48 +msgid "Group empty" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:49 +msgid "Invalid BMP file" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:59 +#, c-format +msgid "Only Windows format, uncompressed BMP supported %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:64 +#, c-format +msgid "Only true color (24 bpp or higher) BMP supported %x" +msgstr "" + +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "" + +#: shared-module/struct/__init__.c:39 +msgid "'S' and 'O' are not supported format types" +msgstr "" + +#: shared-module/struct/__init__.c:83 +msgid "too many arguments provided with the given format" +msgstr "" + +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "" From 50641c41527de0ba6f1d8f67605c8e999d15eb73 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 8 Jan 2019 15:52:21 -0500 Subject: [PATCH 064/153] remove debugging printf's --- ports/nrf/common-hal/bleio/Characteristic.c | 2 +- ports/nrf/common-hal/bleio/Peripheral.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index bebdb31fa2cba..751f029399a10 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -211,7 +211,7 @@ STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) { // For debugging. default: - mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id); + // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id); break; } diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index 0f2506de01b47..85f3b6b6c3661 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -268,7 +268,8 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { } default: - mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id); + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id); break; } } From 13d607698ebffa228ca8b507d6137b925d18ed48 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 8 Jan 2019 16:37:14 -0500 Subject: [PATCH 065/153] m_tx_in_progress might underflow (check on this) --- ports/nrf/common-hal/bleio/Characteristic.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 751f029399a10..0bade8d015577 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -125,12 +125,13 @@ STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp } const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); + m_tx_in_progress++; const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params); if (err_code != NRF_SUCCESS) { + m_tx_in_progress--; mp_raise_OSError_msg_varg(translate("Failed to notify or indicate attribute value, err %0x04x"), err_code); } - m_tx_in_progress += 1; } STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { @@ -192,8 +193,16 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) { switch (ble_evt->header.evt_id) { case BLE_GATTS_EVT_HVN_TX_COMPLETE: - m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; + { + uint8_t count = ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; + // Don't underflow the count. + if (count >= m_tx_in_progress) { + m_tx_in_progress = 0; + } else { + m_tx_in_progress -= count; + } break; + } case BLE_GATTC_EVT_READ_RSP: { From db82160eefa620d889d4e9df9b04bb476b103951 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Jan 2019 15:15:30 +0700 Subject: [PATCH 066/153] fix pulsein incorrect compute --- ports/nrf/common-hal/pulseio/PulseIn.c | 4 +++- ports/nrf/common-hal/pulseio/PulseIn.h | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c index fa05de148ce21..6e5825af624e9 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.c +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -59,6 +59,9 @@ static void _pulsein_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action uint64_t current_ms; current_tick(¤t_ms, ¤t_us); + // current_tick gives us the remaining us until the next tick but we want the number since the last ms. + current_us = 1000 - current_us; + pulseio_pulsein_obj_t* self = NULL; for(int i = 0; i < NRFX_ARRAY_SIZE(_objs); i++ ) { if ( _objs[i] && _objs[i]->pin == pin ) { @@ -66,7 +69,6 @@ static void _pulsein_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action break; } } - if ( !self ) return; if (self->first_edge) { diff --git a/ports/nrf/common-hal/pulseio/PulseIn.h b/ports/nrf/common-hal/pulseio/PulseIn.h index a029129ac6ecd..432506418a05c 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.h +++ b/ports/nrf/common-hal/pulseio/PulseIn.h @@ -35,15 +35,17 @@ typedef struct { mp_obj_base_t base; uint8_t pin; + bool idle_state; + bool paused; + uint16_t* buffer; uint16_t maxlen; - bool idle_state; + volatile uint16_t start; volatile uint16_t len; volatile bool first_edge; - bool paused; - volatile uint64_t last_ms; volatile uint16_t last_us; + volatile uint64_t last_ms; } pulseio_pulsein_obj_t; void pulsein_reset(void); From cfc4c8cbfa8c6f197aaa3da3e78cfdcced06619a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Jan 2019 15:43:54 +0700 Subject: [PATCH 067/153] minor clean up --- ports/nrf/common-hal/pulseio/PulseIn.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/pulseio/PulseIn.h b/ports/nrf/common-hal/pulseio/PulseIn.h index 432506418a05c..4b2c6eee3f6c7 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.h +++ b/ports/nrf/common-hal/pulseio/PulseIn.h @@ -37,13 +37,13 @@ typedef struct { uint8_t pin; bool idle_state; bool paused; + volatile bool first_edge; uint16_t* buffer; uint16_t maxlen; volatile uint16_t start; volatile uint16_t len; - volatile bool first_edge; volatile uint16_t last_us; volatile uint64_t last_ms; } pulseio_pulsein_obj_t; From 5fc28970b4e7f849cf95daacfecf534596de6c68 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 9 Jan 2019 09:13:56 -0500 Subject: [PATCH 068/153] Remove download_ble_stack.sh from .travis.yml; it was deleted because we don't need it anymore. --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index bab5a24562944..073c21a89af2c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -66,9 +66,6 @@ before_script: - (! var_search "${TRAVIS_SDK-}" arm || (wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~xenial1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb)) - # For nrf builds - - (! var_search "${TRAVIS_SDK-}" nrf || sudo ports/nrf/bluetooth/download_ble_stack.sh) - # For huzzah builds - (! var_search "${TRAVIS_SDK-}" esp8266 || (wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar -C .. -xaf xtensa-lx106-elf-standalone.tar.gz)) - if var_search "${TRAVIS_SDK-}" esp8266 ; then PATH=$(readlink -f ../xtensa-lx106-elf/bin):$PATH; fi From 89af6660930ab977a491c7662458cc2d8ee37ee9 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 9 Jan 2019 10:36:38 -0500 Subject: [PATCH 069/153] fix sphinx complaint; more travis fold status reporting --- .travis.yml | 24 +++++++++++++------- ports/nrf/README.md | 2 +- shared-bindings/bleio/CharacteristicBuffer.c | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 073c21a89af2c..9ffa4eaa6a821 100755 --- a/.travis.yml +++ b/.travis.yml @@ -86,8 +86,9 @@ before_script: script: # Build mpy-cross first because other builds depend on it. - echo 'Building mpy-cross' && echo -en 'travis_fold:start:mpy-cross\\r' - - make -C mpy-cross -j2 + - make -C mpy-cross -j2 ; echo "Building mpy-cross status $?" > status - echo -en 'travis_fold:end:mpy-cross\\r' + - cat status # Use unbuffered output because building all the releases can take a long time. # Travis will cancel the job if it sees no output for >10 minutes. @@ -95,8 +96,9 @@ script: - cd .. - echo 'Building unix' && echo -en 'travis_fold:start:unix\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) + - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; echo "Building unix status: $?" > status - echo -en 'travis_fold:end:unix\\r' + - cat status # run tests without coverage info #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1) @@ -104,28 +106,34 @@ script: # run tests with coverage info - echo 'Test all' && echo -en 'travis_fold:start:test_all\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; echo "Test all status: $?" > status - echo -en 'travis_fold:end:test_all\\r' + - cat status - echo 'Test threads' && echo -en 'travis_fold:start:test_threads\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; echo "Test threads status: $?" >status - echo -en 'travis_fold:end:test_threads\\r' + - cat status - echo 'Testing with native' && echo -en 'travis_fold:start:test_native\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; echo "Testing with native: $?" >status - echo -en 'travis_fold:end:test_native\\r' + - cat status - (echo 'Testing with mpy' && echo -en 'travis_fold:start:test_mpy\\r') - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; echo "Testing with mpy status: $?" >status - echo -en 'travis_fold:end:test_mpy\\r' + - cat status - (echo 'Building docs' && echo -en 'travis_fold:start:build_docs\\r') - - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) + - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; echo "Building docs status: $?" >status - echo -en 'travis_fold:end:build_docs\\r' + - cat status - (echo 'Building translations' && echo -en 'travis_fold:start:build_translations\\r') - - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) + - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; echo "Building translations status: $?" >status - echo -en 'travis_fold:end:build_translations\\r' + - cat status # run coveralls coverage analysis (try to, even if some builds/tests failed) #- (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod) diff --git a/ports/nrf/README.md b/ports/nrf/README.md index c385459c3fc10..e909368b6381a 100644 --- a/ports/nrf/README.md +++ b/ports/nrf/README.md @@ -103,7 +103,7 @@ run follow command to install [adafruit-nrfutil](https://github.com/adafruit/Ada * dfu-gen: Generates a Firmware zip to be used by the DFU flash application. * dfu-flash: Triggers the DFU flash application to upload the firmware from the generated Firmware zip file. -Example on how to generate and flash feather_nrf52832 target: +Example on how to generate and flash feather_nrf52840 target: make BOARD=feather_nrf52840 SD=s140 make BOARD=feather_nrf52840 SD=s140 dfu-gen dfu-flash diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c index 770594d3a556b..74ca609f0df68 100644 --- a/shared-bindings/bleio/CharacteristicBuffer.c +++ b/shared-bindings/bleio/CharacteristicBuffer.c @@ -32,7 +32,7 @@ //| .. currentmodule:: bleio //| //| :class:`CharacteristicBuffer` -- GATT Service incoming values buffer. -//| ========================================================= +//| ===================================================================== //| //| Accumulates a Characteristic's incoming values in a FIFO buffer. //| From 47a9d14ba6888ee53ae4fed95ae4d02b93dd8416 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 9 Jan 2019 12:07:50 -0500 Subject: [PATCH 070/153] try to fix travis fold status reporting --- .travis.yml | 64 +++++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9ffa4eaa6a821..a9c908ab465d1 100755 --- a/.travis.yml +++ b/.travis.yml @@ -85,55 +85,47 @@ before_script: script: # Build mpy-cross first because other builds depend on it. - - echo 'Building mpy-cross' && echo -en 'travis_fold:start:mpy-cross\\r' - - make -C mpy-cross -j2 ; echo "Building mpy-cross status $?" > status - - echo -en 'travis_fold:end:mpy-cross\\r' - - cat status + - echo 'Building mpy-cross' && echo 'travis_fold:start:mpy-cross' + - make -C mpy-cross -j2 ; echo status $? > status + - echo 'travis_fold:end:mpy-cross' && cat status # Use unbuffered output because building all the releases can take a long time. # Travis will cancel the job if it sees no output for >10 minutes. - cd tools && python3 -u build_release_files.py - cd .. - - echo 'Building unix' && echo -en 'travis_fold:start:unix\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; echo "Building unix status: $?" > status - - echo -en 'travis_fold:end:unix\\r' - - cat status + - echo 'Building unix' && echo 'travis_fold:start:unix' + - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; echo status $? > status + - echo 'travis_fold:end:unix' && cat status # run tests without coverage info #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1) #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1 --emit native) # run tests with coverage info - - echo 'Test all' && echo -en 'travis_fold:start:test_all\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; echo "Test all status: $?" > status - - echo -en 'travis_fold:end:test_all\\r' - - cat status - - - echo 'Test threads' && echo -en 'travis_fold:start:test_threads\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; echo "Test threads status: $?" >status - - echo -en 'travis_fold:end:test_threads\\r' - - cat status - - - echo 'Testing with native' && echo -en 'travis_fold:start:test_native\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; echo "Testing with native: $?" >status - - echo -en 'travis_fold:end:test_native\\r' - - cat status - - - (echo 'Testing with mpy' && echo -en 'travis_fold:start:test_mpy\\r') + - echo 'Test all' && echo 'travis_fold:start:test_all' + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; echo status $? > status + - echo 'travis_fold:end:test_all' && cat status + + - echo 'Test threads' && echo 'travis_fold:start:test_threads' + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; echo status $? >status + - echo 'travis_fold:end:test_threads' && cat status + + - echo 'Testing with native' && echo 'travis_fold:start:test_native' + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; echo status $? >status + - echo 'travis_fold:end:test_native' && cat status + + - (echo 'Testing with mpy' && echo 'travis_fold:start:test_mpy') - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; echo "Testing with mpy status: $?" >status - - echo -en 'travis_fold:end:test_mpy\\r' - - cat status - - - (echo 'Building docs' && echo -en 'travis_fold:start:build_docs\\r') - - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; echo "Building docs status: $?" >status - - echo -en 'travis_fold:end:build_docs\\r' - - cat status - - - (echo 'Building translations' && echo -en 'travis_fold:start:build_translations\\r') - - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; echo "Building translations status: $?" >status - - echo -en 'travis_fold:end:build_translations\\r' - - cat status + - echo 'travis_fold:end:test_mpy' && cat status + + - (echo 'Building docs' && echo 'travis_fold:start:build_docs') + - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; echo status $? >status + - echo 'travis_fold:end:build_docs' && cat status + + - (echo 'Building translations' && echo 'travis_fold:start:build_translations') + - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; echo status $? >status + - echo 'travis_fold:end:build_translations' && cat status # run coveralls coverage analysis (try to, even if some builds/tests failed) #- (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod) From e47decbdc567aaa7ce4de0d1b7ea8ebc46b09732 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 9 Jan 2019 13:31:32 -0500 Subject: [PATCH 071/153] improve travis fold status reporting; fix sphinx build; fix sphinx errors --- .travis.yml | 32 ++++++++++---------- README.rst | 2 +- shared-bindings/bleio/CharacteristicBuffer.c | 3 +- shared-bindings/bleio/Device.c | 6 ++-- shared-bindings/bleio/UUID.c | 2 +- shared-bindings/bleio/__init__.c | 3 ++ tools/print_status.py | 15 +++++++++ 7 files changed, 41 insertions(+), 22 deletions(-) create mode 100755 tools/print_status.py diff --git a/.travis.yml b/.travis.yml index a9c908ab465d1..4f89bd92c79f6 100755 --- a/.travis.yml +++ b/.travis.yml @@ -74,7 +74,7 @@ before_script: - sudo apt-get install -y python3-pip - pip3 install --user sh click - ([[ -z "$TRAVIS_TESTS" ]] || sudo pip install --upgrade cpp-coveralls) - - (! var_search "${TRAVIS_TESTS-}" docs || pip install --user 'Sphinx<1.8.0' sphinx-rtd-theme recommonmark) + - (! var_search "${TRAVIS_TESTS-}" docs || pip install --user 'Sphinx<1.8.0' sphinx-rtd-theme 'recommonmark<0.5.0') - (! var_search "${TRAVIS_TESTS-}" translations || pip3 install --user polib) # report some good version numbers to the build @@ -86,8 +86,8 @@ before_script: script: # Build mpy-cross first because other builds depend on it. - echo 'Building mpy-cross' && echo 'travis_fold:start:mpy-cross' - - make -C mpy-cross -j2 ; echo status $? > status - - echo 'travis_fold:end:mpy-cross' && cat status + - make -C mpy-cross -j2 ; echo $? > status + - echo 'travis_fold:end:mpy-cross' && tools/print_status.py status # Use unbuffered output because building all the releases can take a long time. # Travis will cancel the job if it sees no output for >10 minutes. @@ -95,8 +95,8 @@ script: - cd .. - echo 'Building unix' && echo 'travis_fold:start:unix' - - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; echo status $? > status - - echo 'travis_fold:end:unix' && cat status + - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; echo $? > status + - echo 'travis_fold:end:unix' && tools/print_status.py status # run tests without coverage info #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1) @@ -104,28 +104,28 @@ script: # run tests with coverage info - echo 'Test all' && echo 'travis_fold:start:test_all' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; echo status $? > status - - echo 'travis_fold:end:test_all' && cat status + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; echo $? > status + - echo 'travis_fold:end:test_all' && tools/print_status.py status - echo 'Test threads' && echo 'travis_fold:start:test_threads' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; echo status $? >status - - echo 'travis_fold:end:test_threads' && cat status + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; echo $? >status + - echo 'travis_fold:end:test_threads' && tools/print_status.py status - echo 'Testing with native' && echo 'travis_fold:start:test_native' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; echo status $? >status - - echo 'travis_fold:end:test_native' && cat status + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; echo $? >status + - echo 'travis_fold:end:test_native' && tools/print_status.py status - (echo 'Testing with mpy' && echo 'travis_fold:start:test_mpy') - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; echo "Testing with mpy status: $?" >status - - echo 'travis_fold:end:test_mpy' && cat status + - echo 'travis_fold:end:test_mpy' && tools/print_status.py status - (echo 'Building docs' && echo 'travis_fold:start:build_docs') - - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; echo status $? >status - - echo 'travis_fold:end:build_docs' && cat status + - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; echo $? >status + - echo 'travis_fold:end:build_docs' && tools/print_status.py status - (echo 'Building translations' && echo 'travis_fold:start:build_translations') - - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; echo status $? >status - - echo 'travis_fold:end:build_translations' && cat status + - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; echo $? >status + - echo 'travis_fold:end:build_translations' && tools/print_status.py status # run coveralls coverage analysis (try to, even if some builds/tests failed) #- (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod) diff --git a/README.rst b/README.rst index 13672b689ca14..deb085522e887 100644 --- a/README.rst +++ b/README.rst @@ -157,7 +157,7 @@ Behavior API ~~~ -- Unified hardware APIs: `audioio `_, `analogio `_, `busio `_, `digitalio `_, `pulseio `_, `touchio `_, `microcontroller `_, `board `_, `bitbangio `_ +- Unified hardware APIs: `audioio `_, `analogio `_, `bleio `_, `busio `_, `digitalio `_, `pulseio `_, `touchio `_, `microcontroller `_, `board `_, `bitbangio `_ - No ``machine`` API on Atmel SAMD21 port. Modules diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c index 74ca609f0df68..d28cd54cf0c9f 100644 --- a/shared-bindings/bleio/CharacteristicBuffer.c +++ b/shared-bindings/bleio/CharacteristicBuffer.c @@ -42,7 +42,8 @@ //| //| :param bleio.Characteristic characteristic: The characteristic to monitor //| :param int buffer_size: Size of ring buffer that stores incoming data coming from client. -//| Must be >= 1. +//| Must be >= 1. +//| STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 1, 2, true); bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t); diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index cf5eb687370c5..cbad9fb7ea892 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -52,10 +52,10 @@ //| When a device is created without any parameter passed to the constructor, //| it will be set to the Peripheral role. If a address is passed, the device //| will be a Central. For a Peripheral you can set the `name`, add services -//| via `add_service` and then start and stop advertising via `start_advertising` -//| and `stop_advertising`. For the Central, you can `bleio.Device.connect` and `bleio.Device.disconnect` +//| via `add_service` and then start and stop advertising via `bleio.Device.start_advertising` +//| and `bleio.Device.stop_advertising`. For the Central, you can `bleio.Device.connect` and `bleio.Device.disconnect` //| to the device, once a connection is established, the device's services can -//| be accessed using `services`. +//| be accessed using `bleio.Device.services`. //| //| Usage:: //| diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 2b42ab05cca14..703bc1c654cbb 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -50,7 +50,7 @@ //| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID) //| //| :param int/buffer value: The uuid value to encapsulate - +//| STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index e23efe36c7d82..42bd093f19b55 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -57,9 +57,12 @@ //| AddressType //| AdvertisementData //| Adapter +//| Broadcaster //| Characteristic +//| CharacteristicBuffer //| Descriptor //| Device +//| Peripheral //| ScanEntry //| Scanner //| Service diff --git a/tools/print_status.py b/tools/print_status.py new file mode 100755 index 0000000000000..ed563fd68bd9f --- /dev/null +++ b/tools/print_status.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import sys +if len(sys.argv) != 2: + print("""\ +Usage: print_status.py STATUS_FILENAME + STATUS_FILENAME contains one line with an integer status.""" + ) + sys.exit(1) +with open(sys.argv[1], 'r') as status_in: + status = int(status_in.readline()) + +print('{} with status {}'.format( + "\033[32msucceeded\033[0m" if status == 0 else "\033[31mfailed\033[0m", + status)) From 617c23618bf7037af46aa9a6e1f17f8120215baf Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 9 Jan 2019 14:00:17 -0500 Subject: [PATCH 072/153] make translate --- locale/circuitpython.pot | 257 +++++++++++++++++-------- locale/de_DE.po | 355 +++++++++++++++++++++++------------ locale/en_US.po | 257 +++++++++++++++++-------- locale/es.po | 378 ++++++++++++++++++++++++------------- locale/fil.po | 394 +++++++++++++++++++++++++-------------- locale/fr.po | 372 +++++++++++++++++++++++------------- locale/it_IT.po | 367 ++++++++++++++++++++++++------------ locale/pt_BR.po | 336 ++++++++++++++++++++++----------- 8 files changed, 1805 insertions(+), 911 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 92e1813025bdc..b2ed435abd193 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: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-09 14:00-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -329,7 +329,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "" @@ -648,125 +648,172 @@ msgstr "" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +msgid "Failed to change softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +msgid "Failed to get softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:138 +msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 -#, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 -#, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +msgid "Data too large for advertisement packet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:320 #, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +msgid "Failed to start advertising, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:332 #, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" +msgid "Failed to stop advertising, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#: ports/nrf/common-hal/bleio/Characteristic.c:59 #, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +msgid "Failed to read CCCD value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 +#: ports/nrf/common-hal/bleio/Characteristic.c:89 #, c-format -msgid "Failed to release mutex, status: 0x%08lX" +msgid "Failed to read gatts value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 -msgid "Can not fit data into the advertisment packet" +#: ports/nrf/common-hal/bleio/Characteristic.c:106 +#, c-format +msgid "Failed to write gatts value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:266 +#: ports/nrf/common-hal/bleio/Characteristic.c:132 #, c-format -msgid "Failed to discover serivices, status: 0x%08lX" +msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 +#: ports/nrf/common-hal/bleio/Characteristic.c:144 #, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +msgid "Failed to read attribute value, err %0x04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:436 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 #, c-format -msgid "Failed to connect, status: 0x%08lX" +msgid "Failed to acquire mutex, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:513 +#: ports/nrf/common-hal/bleio/Characteristic.c:178 #, c-format -msgid "Failed to add service, status: 0x%08lX" +msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:531 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 #, c-format -msgid "Failed to start advertisment, status: 0x%08lX" +msgid "Failed to release mutex, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 +msgid "Data too large for the advertisement packet" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:262 +msgid "Failed to discover services" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +msgid "Failed to acquire mutex" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +msgid "Failed to release mutex" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:387 +msgid "Failed to continue scanning" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:419 +msgid "Failed to connect:" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:489 +msgid "Failed to add service" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:506 +msgid "Failed to start advertising" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:523 +msgid "Failed to stop advertising" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:548 +msgid "Failed to start scanning" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:564 +msgid "Failed to create mutex" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:549 +#: ports/nrf/common-hal/bleio/Peripheral.c:300 #, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +msgid "Failed to add service, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 +#: ports/nrf/common-hal/bleio/Scanner.c:75 #, c-format -msgid "Failed to start scanning, status: 0x%0xlX" +msgid "Failed to continue scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:592 +#: ports/nrf/common-hal/bleio/Scanner.c:101 #, c-format -msgid "Failed to create mutex, status: 0x%0xlX" +msgid "Failed to start scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Service.c:83 +#: ports/nrf/common-hal/bleio/Service.c:88 #, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +msgid "Failed to add characteristic, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:97 +#: ports/nrf/common-hal/bleio/UUID.c:54 #, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" +#: ports/nrf/common-hal/bleio/UUID.c:88 +msgid "Unexpected nrfx uuid type" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "" @@ -779,25 +826,24 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +msgid "Cannot get temperature" msgstr "" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 @@ -1929,7 +1975,7 @@ msgstr "" msgid "memory allocation failed, allocating %u bytes" msgstr "" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "" @@ -2079,12 +2125,27 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:107 -msgid "Wrong number of bytes provided" +#: shared-bindings/bleio/Address.c:126 +#, c-format +msgid "Address must be %d bytes long" +msgstr "" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +msgid "Expected a UUID" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +msgid "buffer_size must be >= 1" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:72 +msgid "Expected a Characteristic" msgstr "" #: shared-bindings/bleio/Device.c:210 @@ -2103,6 +2164,38 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +msgid "name must be a string" +msgstr "" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +msgid "Byte buffer must be 16 bytes." +msgstr "" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index e9f81e0b13c84..4a2244f6e42d5 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-09 14:00-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -333,7 +333,7 @@ msgstr "Nicht genug Pins vorhanden" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Ungültige Pins" @@ -350,12 +350,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Konnte keinen RX Buffer allozieren" @@ -364,12 +364,12 @@ msgid "Could not initialize UART" msgstr "Konnte UART nicht initialisieren" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Kein RX Pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Kein TX Pin" @@ -655,126 +655,186 @@ msgstr "" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +#, fuzzy +msgid "Failed to change softdevice state" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +#, fuzzy +msgid "Failed to get softdevice state" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Adapter.c:138 +msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Daten können nicht in das advertisement packet eingefügt werden." + +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Kann advertisement nicht starten. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:59 #, fuzzy, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:89 +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#: ports/nrf/common-hal/bleio/Characteristic.c:106 #, fuzzy, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:132 +#, fuzzy, c-format +msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#: ports/nrf/common-hal/bleio/Characteristic.c:144 #, fuzzy, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +msgid "Failed to read attribute value, err %0x04x" msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 -#, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#: ports/nrf/common-hal/bleio/Characteristic.c:178 #, fuzzy, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +msgid "Failed to write attribute value, err 0x%04x" msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 -#, c-format -msgid "Failed to release mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 #, fuzzy -msgid "Can not fit data into the advertisment packet" +msgid "Data too large for the advertisement packet" msgstr "Daten können nicht in das advertisement packet eingefügt werden." -#: ports/nrf/common-hal/bleio/Device.c:266 -#, c-format -msgid "Failed to discover serivices, status: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Device.c:262 +#, fuzzy +msgid "Failed to discover services" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 -#, fuzzy, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +#, fuzzy +msgid "Failed to acquire mutex" +msgstr "Konnte keinen RX Buffer allozieren" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +#, fuzzy +msgid "Failed to release mutex" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:387 +#, fuzzy +msgid "Failed to continue scanning" msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:436 -#, fuzzy, c-format -msgid "Failed to connect, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:419 +#, fuzzy +msgid "Failed to connect:" msgstr "Kann nicht verbinden. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:513 -#, fuzzy, c-format -msgid "Failed to add service, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:489 +#, fuzzy +msgid "Failed to add service" msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:531 -#, fuzzy, c-format -msgid "Failed to start advertisment, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:506 +#, fuzzy +msgid "Failed to start advertising" msgstr "Kann advertisement nicht starten. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:549 +#: ports/nrf/common-hal/bleio/Device.c:523 +#, fuzzy +msgid "Failed to stop advertising" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:548 +#, fuzzy +msgid "Failed to start scanning" +msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:564 +#, fuzzy +msgid "Failed to create mutex" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Peripheral.c:300 #, fuzzy, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +msgid "Failed to add service, err 0x%04x" msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 +#: ports/nrf/common-hal/bleio/Scanner.c:75 #, fuzzy, c-format -msgid "Failed to start scanning, status: 0x%0xlX" +msgid "Failed to continue scanning, err 0x%04x" msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:592 +#: ports/nrf/common-hal/bleio/Scanner.c:101 #, fuzzy, c-format -msgid "Failed to create mutex, status: 0x%0xlX" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" +msgid "Failed to start scanning, err 0x%04x" +msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Service.c:83 -#, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Service.c:88 +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:97 +#: ports/nrf/common-hal/bleio/UUID.c:54 #, fuzzy, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "Kann keine herstellerspezifische 128-Bit-UUID hinzufügen." -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" -msgstr "Ungültige UUID-Stringlänge" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" -msgstr "Ungültiger UUID-Parameter" +#: ports/nrf/common-hal/bleio/UUID.c:88 +msgid "Unexpected nrfx uuid type" +msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Alle timer werden benutzt" @@ -789,28 +849,28 @@ msgstr "Alle timer werden benutzt" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" msgstr "ungültiger dupterm index" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" -msgstr "" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +#, fuzzy +msgid "Cannot get temperature" +msgstr "Kann PPCP Parameter nicht setzen." #: ports/nrf/common-hal/pulseio/PWMOut.c:161 #, fuzzy @@ -1944,7 +2004,7 @@ msgstr "" msgid "memory allocation failed, allocating %u bytes" msgstr "" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "" @@ -2097,14 +2157,31 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:107 -msgid "Wrong number of bytes provided" +#: shared-bindings/bleio/Address.c:126 +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "Buffer müssen gleich lang sein" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +msgid "Expected a UUID" msgstr "" +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#, fuzzy +msgid "buffer_size must be >= 1" +msgstr "Buffer müssen gleich lang sein" + +#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#, fuzzy +msgid "Expected a Characteristic" +msgstr "Kann das Merkmal nicht hinzufügen." + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "" @@ -2121,6 +2198,40 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +#, fuzzy +msgid "name must be a string" +msgstr "heap muss eine Liste sein" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "Buffer müssen gleich lang sein" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2571,20 +2682,25 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Kann PPCP Parameter nicht setzen." +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2593,25 +2709,20 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." - -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Ungültiger UUID-Parameter" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" +#~ msgid "Invalid UUID string length" +#~ msgstr "Ungültige UUID-Stringlänge" diff --git a/locale/en_US.po b/locale/en_US.po index 119dde3d68cec..ed29bd0af219a 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-09 14:00-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -329,7 +329,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "" @@ -648,125 +648,172 @@ msgstr "" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +msgid "Failed to change softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +msgid "Failed to get softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:138 +msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 -#, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 -#, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +msgid "Data too large for advertisement packet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:320 #, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +msgid "Failed to start advertising, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:332 #, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" +msgid "Failed to stop advertising, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#: ports/nrf/common-hal/bleio/Characteristic.c:59 #, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +msgid "Failed to read CCCD value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 +#: ports/nrf/common-hal/bleio/Characteristic.c:89 #, c-format -msgid "Failed to release mutex, status: 0x%08lX" +msgid "Failed to read gatts value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 -msgid "Can not fit data into the advertisment packet" +#: ports/nrf/common-hal/bleio/Characteristic.c:106 +#, c-format +msgid "Failed to write gatts value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:266 +#: ports/nrf/common-hal/bleio/Characteristic.c:132 #, c-format -msgid "Failed to discover serivices, status: 0x%08lX" +msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 +#: ports/nrf/common-hal/bleio/Characteristic.c:144 #, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +msgid "Failed to read attribute value, err %0x04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:436 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 #, c-format -msgid "Failed to connect, status: 0x%08lX" +msgid "Failed to acquire mutex, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:513 +#: ports/nrf/common-hal/bleio/Characteristic.c:178 #, c-format -msgid "Failed to add service, status: 0x%08lX" +msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:531 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 #, c-format -msgid "Failed to start advertisment, status: 0x%08lX" +msgid "Failed to release mutex, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 +msgid "Data too large for the advertisement packet" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:262 +msgid "Failed to discover services" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +msgid "Failed to acquire mutex" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +msgid "Failed to release mutex" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:387 +msgid "Failed to continue scanning" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:419 +msgid "Failed to connect:" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:489 +msgid "Failed to add service" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:506 +msgid "Failed to start advertising" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:523 +msgid "Failed to stop advertising" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:548 +msgid "Failed to start scanning" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:564 +msgid "Failed to create mutex" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:549 +#: ports/nrf/common-hal/bleio/Peripheral.c:300 #, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +msgid "Failed to add service, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 +#: ports/nrf/common-hal/bleio/Scanner.c:75 #, c-format -msgid "Failed to start scanning, status: 0x%0xlX" +msgid "Failed to continue scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:592 +#: ports/nrf/common-hal/bleio/Scanner.c:101 #, c-format -msgid "Failed to create mutex, status: 0x%0xlX" +msgid "Failed to start scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Service.c:83 +#: ports/nrf/common-hal/bleio/Service.c:88 #, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +msgid "Failed to add characteristic, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:97 +#: ports/nrf/common-hal/bleio/UUID.c:54 #, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" +#: ports/nrf/common-hal/bleio/UUID.c:88 +msgid "Unexpected nrfx uuid type" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "" @@ -779,25 +826,24 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +msgid "Cannot get temperature" msgstr "" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 @@ -1929,7 +1975,7 @@ msgstr "" msgid "memory allocation failed, allocating %u bytes" msgstr "" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "" @@ -2079,12 +2125,27 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:107 -msgid "Wrong number of bytes provided" +#: shared-bindings/bleio/Address.c:126 +#, c-format +msgid "Address must be %d bytes long" +msgstr "" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +msgid "Expected a UUID" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +msgid "buffer_size must be >= 1" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:72 +msgid "Expected a Characteristic" msgstr "" #: shared-bindings/bleio/Device.c:210 @@ -2103,6 +2164,38 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +msgid "name must be a string" +msgstr "" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +msgid "Byte buffer must be 16 bytes." +msgstr "" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" diff --git a/locale/es.po b/locale/es.po index 29c69d49c2535..b41231e5f2f97 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-09 14:00-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -335,7 +335,7 @@ msgstr "No hay suficientes pines disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "pines inválidos" @@ -352,12 +352,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits no soportados" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "Ambos tx y rx no pueden ser None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Ha fallado la asignación del buffer RX" @@ -366,12 +366,12 @@ msgid "Could not initialize UART" msgstr "No se puede inicializar la UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Sin pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Sin pin TX" @@ -655,126 +655,187 @@ msgstr "Funcionalidad AnalogOut no soportada" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +#, fuzzy +msgid "Failed to change softdevice state" msgstr "No se puede cambiar el estado del softdevice, error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +#, fuzzy +msgid "Failed to get softdevice state" msgstr "No se puede obtener el estado del softdevice, error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:138 +#, fuzzy +msgid "Failed to get local address" msgstr "No se puede obtener la dirección local, error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" +msgstr "" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Los datos no caben en el paquete de anuncio." + +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:320 #, fuzzy, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +msgid "Failed to start advertising, err 0x%04x" +msgstr "No se puede inicar el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "No se puede detener el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:59 +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "No se puede leer el valor del atributo. status 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:89 +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" msgstr "No se puede escribir el valor del atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#: ports/nrf/common-hal/bleio/Characteristic.c:106 #, fuzzy, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +msgid "Failed to write gatts value, err 0x%04x" +msgstr "No se puede escribir el valor del atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:132 +#, fuzzy, c-format +msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "No se puede notificar el valor del anuncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#: ports/nrf/common-hal/bleio/Characteristic.c:144 #, fuzzy, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +msgid "Failed to read attribute value, err %0x04x" msgstr "No se puede leer el valor del atributo. status 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 -#, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" msgstr "No se puede adquirir el mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#: ports/nrf/common-hal/bleio/Characteristic.c:178 #, fuzzy, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +msgid "Failed to write attribute value, err 0x%04x" msgstr "No se puede escribir el valor del atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 -#, c-format -msgid "Failed to release mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" msgstr "No se puede liberar el mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 #, fuzzy -msgid "Can not fit data into the advertisment packet" +msgid "Data too large for the advertisement packet" msgstr "Los datos no caben en el paquete de anuncio." -#: ports/nrf/common-hal/bleio/Device.c:266 -#, c-format -msgid "Failed to discover serivices, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:262 +#, fuzzy +msgid "Failed to discover services" msgstr "No se puede descubrir servicios, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 -#, fuzzy, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +#, fuzzy +msgid "Failed to acquire mutex" +msgstr "No se puede adquirir el mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +#, fuzzy +msgid "Failed to release mutex" +msgstr "No se puede liberar el mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:387 +#, fuzzy +msgid "Failed to continue scanning" msgstr "No se puede iniciar el escaneo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:436 -#, fuzzy, c-format -msgid "Failed to connect, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:419 +#, fuzzy +msgid "Failed to connect:" msgstr "No se puede conectar. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:513 -#, fuzzy, c-format -msgid "Failed to add service, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:489 +#, fuzzy +msgid "Failed to add service" msgstr "No se puede detener el anuncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:531 -#, fuzzy, c-format -msgid "Failed to start advertisment, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:506 +#, fuzzy +msgid "Failed to start advertising" msgstr "No se puede inicar el anuncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:549 +#: ports/nrf/common-hal/bleio/Device.c:523 +#, fuzzy +msgid "Failed to stop advertising" +msgstr "No se puede detener el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:548 +#, fuzzy +msgid "Failed to start scanning" +msgstr "No se puede iniciar el escaneo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:564 +#, fuzzy +msgid "Failed to create mutex" +msgstr "No se puede leer el valor del atributo. status 0x%02x" + +#: ports/nrf/common-hal/bleio/Peripheral.c:300 #, fuzzy, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +msgid "Failed to add service, err 0x%04x" msgstr "No se puede detener el anuncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 +#: ports/nrf/common-hal/bleio/Scanner.c:75 #, fuzzy, c-format -msgid "Failed to start scanning, status: 0x%0xlX" +msgid "Failed to continue scanning, err 0x%04x" msgstr "No se puede iniciar el escaneo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:592 +#: ports/nrf/common-hal/bleio/Scanner.c:101 #, fuzzy, c-format -msgid "Failed to create mutex, status: 0x%0xlX" -msgstr "No se puede leer el valor del atributo. status 0x%02x" +msgid "Failed to start scanning, err 0x%04x" +msgstr "No se puede iniciar el escaneo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Service.c:83 -#, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Service.c:88 +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" msgstr "No se puede añadir caracteristica, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/UUID.c:97 +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:54 #, fuzzy, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "No se puede agregar el Vendor Specific 128-bit UUID." -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" -msgstr "Longitud de string UUID inválida" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" -msgstr "Parámetro UUID inválido" +#: ports/nrf/common-hal/bleio/UUID.c:88 +msgid "Unexpected nrfx uuid type" +msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Todos los timers están siendo usados" @@ -787,25 +848,25 @@ msgstr "Todos los timers están siendo usados" msgid "error = 0x%08lX" msgstr "error = 0x%08lx" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "Tamaño de buffer inválido" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "Paridad impar no soportada" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "busio.UART no disponible" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +#, fuzzy +msgid "Cannot get temperature" msgstr "No se puede obtener la temperatura. status: 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 @@ -1955,7 +2016,7 @@ msgstr "la asignación de memoria falló, el heap está bloqueado" msgid "memory allocation failed, allocating %u bytes" msgstr "la asignación de memoria falló, asignando %u bytes" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "profundidad máxima de recursión excedida" @@ -2109,13 +2170,31 @@ msgstr "Numero inválido de bits" msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" -msgstr "Longitud de address erronea" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" +msgstr "" + +#: shared-bindings/bleio/Address.c:126 +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "palette debe ser 32 bytes de largo" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#, fuzzy +msgid "Expected a UUID" +msgstr "Se espera un %q" + +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#, fuzzy +msgid "buffer_size must be >= 1" +msgstr "los buffers deben de tener la misma longitud" -#: shared-bindings/bleio/Address.c:107 -msgid "Wrong number of bytes provided" -msgstr "Numero erroneo de bytes dados" +#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#, fuzzy +msgid "Expected a Characteristic" +msgstr "No se puede agregar la Característica." #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" @@ -2133,6 +2212,40 @@ msgstr "No se puede cambiar el nombre en modo Central" msgid "Can't advertise in Central mode" msgstr "" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +#, fuzzy +msgid "name must be a string" +msgstr "palabras clave deben ser strings" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "buffer debe de ser un objeto bytes-like" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "La función requiere lock" @@ -2585,53 +2698,62 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#, fuzzy +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " +#~ "unidad de almacenamiento CIRCUITPY:\n" -#~ msgid "Can not add Characteristic." -#~ msgstr "No se puede agregar la Característica." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "suficiente poder para todo el circuito y presiona reset (después de " +#~ "expulsar CIRCUITPY).\n" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de Servicio inválido" +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" + +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." #~ msgid "Can not add Service." #~ msgstr "No se puede agregar el Servicio." -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Baud rate demasiado alto para este periférico SPI" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "No se puede codificar el UUID, para revisar la longitud." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "No se pueden establecer los parámetros PPCP." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "suficiente poder para todo el circuito y presiona reset (después de " -#~ "expulsar CIRCUITPY).\n" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Numero erroneo de bytes dados" -#, fuzzy -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " -#~ "unidad de almacenamiento CIRCUITPY:\n" +#~ msgid "Wrong address length" +#~ msgstr "Longitud de address erronea" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parámetro UUID inválido" + +#~ msgid "Invalid UUID string length" +#~ msgstr "Longitud de string UUID inválida" diff --git a/locale/fil.po b/locale/fil.po index 53ca5d22a9a3b..1c2a321361ff0 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-09 14:00-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -333,7 +333,7 @@ msgstr "Hindi sapat ang magagamit na pins" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Mali ang pins" @@ -350,12 +350,12 @@ msgid "bytes > 8 bits not supported" msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx at rx hindi pwedeng parehas na None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Nabigong ilaan ang RX buffer" @@ -364,12 +364,12 @@ msgid "Could not initialize UART" msgstr "Hindi ma-initialize ang UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Walang RX pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Walang TX pin" @@ -655,125 +655,188 @@ msgstr "Hindi supportado ang AnalogOut" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +#, fuzzy +msgid "Failed to change softdevice state" msgstr "Nabigo sa pagbago ng softdevice state, error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +#, fuzzy +msgid "Failed to get softdevice state" msgstr "Nabigo sa pagkuha ng softdevice state, error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:138 +#, fuzzy +msgid "Failed to get local address" msgstr "Nabigo sa pagkuha ng local na address, , error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 -#, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" +msgstr "" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Hindi makasya ang data sa loob ng advertisement packet" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Hindi mahinto ang advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:59 +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:89 +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" msgstr "Hindi maisulat ang gatts value, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 -#, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:106 +#, fuzzy, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Hindi maisulat ang gatts value, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:132 +#, fuzzy, c-format +msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "Hindi mabalitaan ang attribute value, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 -#, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:144 +#, fuzzy, c-format +msgid "Failed to read attribute value, err %0x04x" msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 -#, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 -#, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:178 +#, fuzzy, c-format +msgid "Failed to write attribute value, err 0x%04x" msgstr "Hindi maisulat ang attribute value, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 -#, c-format -msgid "Failed to release mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 -msgid "Can not fit data into the advertisment packet" +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 +#, fuzzy +msgid "Data too large for the advertisement packet" msgstr "Hindi makasya ang data sa loob ng advertisement packet" -#: ports/nrf/common-hal/bleio/Device.c:266 -#, c-format -msgid "Failed to discover serivices, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:262 +#, fuzzy +msgid "Failed to discover services" msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 -#, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +#, fuzzy +msgid "Failed to acquire mutex" +msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +#, fuzzy +msgid "Failed to release mutex" +msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:387 +#, fuzzy +msgid "Failed to continue scanning" msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:436 -#, c-format -msgid "Failed to connect, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:419 +#, fuzzy +msgid "Failed to connect:" msgstr "Hindi makaconnect, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:513 -#, c-format -msgid "Failed to add service, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:489 +#, fuzzy +msgid "Failed to add service" msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:531 -#, c-format -msgid "Failed to start advertisment, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:506 +#, fuzzy +msgid "Failed to start advertising" msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:549 -#, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:523 +#, fuzzy +msgid "Failed to stop advertising" msgstr "Hindi mahinto ang advertisement, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 -#, c-format -msgid "Failed to start scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:548 +#, fuzzy +msgid "Failed to start scanning" msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:592 -#, c-format -msgid "Failed to create mutex, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:564 +#, fuzzy +msgid "Failed to create mutex" msgstr "Hindi matagumpay ang pagbuo ng mutex, status: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Service.c:83 -#, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#, fuzzy, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Scanner.c:75 +#, fuzzy, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX" + +#: ports/nrf/common-hal/bleio/Scanner.c:101 +#, fuzzy, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX" + +#: ports/nrf/common-hal/bleio/Service.c:88 +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" msgstr "Nabigo sa paglagay ng characteristic, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/UUID.c:97 -#, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:54 +#, fuzzy, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "Hindi matagumpay ang paglagay ng Vender Specific UUID, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" -msgstr "Mali ang UUID string length" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" -msgstr "Mali ang UUID parameter" +#: ports/nrf/common-hal/bleio/UUID.c:88 +#, fuzzy +msgid "Unexpected nrfx uuid type" +msgstr "hindi inaasahang indent" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Lahat ng I2C peripherals ginagamit" @@ -786,25 +849,25 @@ msgstr "Lahat ng SPI peripherals ay ginagamit" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "Mali ang buffer size" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "Odd na parity ay hindi supportado" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "busio.UART hindi available" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +#, fuzzy +msgid "Cannot get temperature" msgstr "Hindi makuha ang temperatura. status 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 @@ -1958,7 +2021,7 @@ msgstr "abigo ang paglalaan ng memorya, ang heap ay naka-lock" msgid "memory allocation failed, allocating %u bytes" msgstr "nabigo ang paglalaan ng memorya, paglalaan ng %u bytes" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "lumagpas ang maximum recursion depth" @@ -2115,13 +2178,31 @@ msgstr "Mali ang bilang ng bits" msgid "buffer slices must be of equal length" msgstr "aarehas na haba dapat ang buffer slices" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" -msgstr "Mali ang address length" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" +msgstr "" + +#: shared-bindings/bleio/Address.c:126 +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "ang palette ay dapat 32 bytes ang haba" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#, fuzzy +msgid "Expected a UUID" +msgstr "Umasa ng %q" + +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#, fuzzy +msgid "buffer_size must be >= 1" +msgstr "aarehas na haba dapat ang buffer slices" -#: shared-bindings/bleio/Address.c:107 -msgid "Wrong number of bytes provided" -msgstr "Mali ang bilang ng bytes" +#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#, fuzzy +msgid "Expected a Characteristic" +msgstr "Hindi mabasa and Characteristic." #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" @@ -2139,6 +2220,40 @@ msgstr "Hindi mapalitan ang pangalan sa Central mode" msgid "Can't advertise in Central mode" msgstr "Hindi ma advertise habang nasa Central mode" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +#, fuzzy +msgid "name must be a string" +msgstr "ang keywords dapat strings" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "buffer ay dapat bytes-like object" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "Kailangan ng lock ang function." @@ -2600,53 +2715,62 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " +#~ "drive:\n" -#~ msgid "Can not add Characteristic." -#~ msgstr "Hindi mabasa and Characteristic." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " +#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" -#~ msgid "Invalid Service type" -#~ msgstr "Mali ang tipo ng serbisyo" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "ang palette ay dapat 32 bytes ang haba" + +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." #~ msgid "Can not add Service." #~ msgstr "Hindi maidaragdag ang serbisyo." -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "ang palette ay dapat 32 bytes ang haba" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Hindi ma-set ang PPCP parameters." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " -#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Mali ang bilang ng bytes" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " -#~ "drive:\n" +#~ msgid "Wrong address length" +#~ msgstr "Mali ang address length" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Mali ang UUID parameter" + +#~ msgid "Invalid UUID string length" +#~ msgstr "Mali ang UUID string length" diff --git a/locale/fr.po b/locale/fr.po index 61781fe5bd359..3b369d6f505b5 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: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-09 14:00-0500\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -330,7 +330,7 @@ msgstr "Pas assez de broches disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Broches invalides" @@ -347,12 +347,12 @@ msgid "bytes > 8 bits not supported" msgstr "octets > 8 bits non supporté" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx et rx ne peuvent être None tous les deux" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Echec de l'allocation du tampon RX" @@ -361,12 +361,12 @@ msgid "Could not initialize UART" msgstr "L'UART n'a pu être initialisé" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Pas de broche RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Pas de broche TX" @@ -653,125 +653,186 @@ msgstr "AnalogOut non supporté" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +#, fuzzy +msgid "Failed to change softdevice state" msgstr "Echec de la modification de l'état du périph., erreur: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +#, fuzzy +msgid "Failed to get softdevice state" msgstr "Echec de l'obtention de l'état du périph., erreur: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:138 +#, fuzzy +msgid "Failed to get local address" msgstr "Echec de l'obtention de l'adresse locale, erreur: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" +msgstr "" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +msgid "Data too large for advertisement packet" +msgstr "" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Impossible de commencer à scanner, statut: 0x%0xlX" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Echec de l'ajout de service, statut: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:59 +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Impossible de lire la valeur de l'attribut. status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:89 +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "Impossible d'écrire la valeur de gatts. status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:106 #, fuzzy, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +msgid "Failed to write gatts value, err 0x%04x" msgstr "Impossible d'écrire la valeur de gatts. status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#: ports/nrf/common-hal/bleio/Characteristic.c:132 #, fuzzy, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#: ports/nrf/common-hal/bleio/Characteristic.c:144 #, fuzzy, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +msgid "Failed to read attribute value, err %0x04x" msgstr "Impossible de lire la valeur de l'attribut. status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 -#, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" msgstr "Echec de l'obtention de mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#: ports/nrf/common-hal/bleio/Characteristic.c:178 #, fuzzy, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +msgid "Failed to write attribute value, err 0x%04x" msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 -#, c-format -msgid "Failed to release mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" msgstr "Impossible de libérer mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 -msgid "Can not fit data into the advertisment packet" +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:266 -#, fuzzy, c-format -msgid "Failed to discover serivices, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 +msgid "Data too large for the advertisement packet" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:262 +#, fuzzy +msgid "Failed to discover services" msgstr "Echec de la découverte de services, statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 -#, fuzzy, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +#, fuzzy +msgid "Failed to acquire mutex" +msgstr "Echec de l'obtention de mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +#, fuzzy +msgid "Failed to release mutex" +msgstr "Impossible de libérer mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:387 +#, fuzzy +msgid "Failed to continue scanning" msgstr "Impossible de commencer à scanner. statut: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:436 -#, fuzzy, c-format -msgid "Failed to connect, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:419 +#, fuzzy +msgid "Failed to connect:" msgstr "Connection impossible. statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:513 -#, c-format -msgid "Failed to add service, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:489 +#, fuzzy +msgid "Failed to add service" msgstr "Echec de l'ajout de service, statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:531 -#, c-format -msgid "Failed to start advertisment, status: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Device.c:506 +#, fuzzy +msgid "Failed to start advertising" +msgstr "Echec de l'ajout de service, statut: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:523 +#, fuzzy +msgid "Failed to stop advertising" +msgstr "Echec de l'ajout de service, statut: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:548 +#, fuzzy +msgid "Failed to start scanning" +msgstr "Impossible de commencer à scanner, statut: 0x%0xlX" + +#: ports/nrf/common-hal/bleio/Device.c:564 +#, fuzzy +msgid "Failed to create mutex" +msgstr "Echec de la création de mutex, statut: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:549 +#: ports/nrf/common-hal/bleio/Peripheral.c:300 #, fuzzy, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +msgid "Failed to add service, err 0x%04x" msgstr "Echec de l'ajout de service, statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 +#: ports/nrf/common-hal/bleio/Scanner.c:75 #, fuzzy, c-format -msgid "Failed to start scanning, status: 0x%0xlX" -msgstr "Impossible de commencer à scanner, statut: 0x%0xlX" +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Impossible de commencer à scanner. statut: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:592 +#: ports/nrf/common-hal/bleio/Scanner.c:101 #, fuzzy, c-format -msgid "Failed to create mutex, status: 0x%0xlX" -msgstr "Echec de la création de mutex, statut: 0x%0xlX" +msgid "Failed to start scanning, err 0x%04x" +msgstr "Impossible de commencer à scanner, statut: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Service.c:83 -#, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Service.c:88 +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" msgstr "Echec de l'ajout de caractéristique, statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/UUID.c:97 +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:54 #, fuzzy, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "Echec de l'ajout de l'UUID Vendor Specific, , statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" -msgstr "Longeur de chaîne UUID invalide" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" -msgstr "Paramètre UUID invalide" +#: ports/nrf/common-hal/bleio/UUID.c:88 +#, fuzzy +msgid "Unexpected nrfx uuid type" +msgstr "indentation inattendue" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Tous les périphériques I2C sont utilisés" @@ -786,28 +847,28 @@ msgstr "Tous les périphériques SPI sont utilisés" msgid "error = 0x%08lX" msgstr "erreur = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" msgstr "longueur de tampon invalide" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" msgstr "parité impaire non supportée" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART n'est pas disponible" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +#, fuzzy +msgid "Cannot get temperature" msgstr "Impossible de lire la température. status: 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 @@ -1960,7 +2021,7 @@ msgstr "l'allocation de mémoire a échoué, la pile est vérrouillé" msgid "memory allocation failed, allocating %u bytes" msgstr "l'allocation de mémoire a échoué en allouant %u octets" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "profondeur maximale de récursivité dépassée" @@ -2119,14 +2180,31 @@ msgstr "Nombre de bits invalide" msgid "buffer slices must be of equal length" msgstr "les slices de tampon doivent être de longueurs égales" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" -msgstr "Mauvaise longueur d'adresse" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" +msgstr "" + +#: shared-bindings/bleio/Address.c:126 +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "la palette doit être longue de 32 octets" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#, fuzzy +msgid "Expected a UUID" +msgstr "Attendu : %q" + +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#, fuzzy +msgid "buffer_size must be >= 1" +msgstr "les slices de tampon doivent être de longueurs égales" -#: shared-bindings/bleio/Address.c:107 +#: shared-bindings/bleio/CharacteristicBuffer.c:72 #, fuzzy -msgid "Wrong number of bytes provided" -msgstr "mauvais nombre d'octets fourni'" +msgid "Expected a Characteristic" +msgstr "Impossible d'ajouter la Characteristic." #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" @@ -2144,6 +2222,40 @@ msgstr "Modification du nom impossible en mode Central" msgid "Can't advertise in Central mode" msgstr "" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +#, fuzzy +msgid "name must be a string" +msgstr "les noms doivent être des chaînes de caractère" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "le tampon doit être un objet bytes-like" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "La fonction nécessite un verrou." @@ -2632,29 +2744,22 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer denouveau pour quitter de le mode sans-échec.\n" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" - -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" - -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2663,19 +2768,36 @@ msgstr "" #~ "assez de puissance pour l'ensemble du circuit et appuyez sur " #~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size doit être une puissance de 2" +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" #, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être une displayio.Palette" +#~ msgid "Wrong number of bytes provided" +#~ msgstr "mauvais nombre d'octets fourni'" + +#~ msgid "Wrong address length" +#~ msgstr "Mauvaise longueur d'adresse" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Paramètre UUID invalide" + +#~ msgid "Invalid UUID string length" +#~ msgstr "Longeur de chaîne UUID invalide" diff --git a/locale/it_IT.po b/locale/it_IT.po index 4cb328319d408..f1e43712a927b 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-09 14:00-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -334,7 +334,7 @@ msgstr "Non sono presenti abbastanza pin" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Pin non validi" @@ -351,12 +351,12 @@ msgid "bytes > 8 bits not supported" msgstr "byte > 8 bit non supportati" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx e rx non possono essere entrambi None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Impossibile allocare buffer RX" @@ -365,12 +365,12 @@ msgid "Could not initialize UART" msgstr "Impossibile inizializzare l'UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Nessun pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Nessun pin TX" @@ -655,126 +655,187 @@ msgstr "funzionalità AnalogOut non supportata" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +#, fuzzy +msgid "Failed to change softdevice state" +msgstr "Impossibile fermare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +#, fuzzy +msgid "Failed to get softdevice state" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Adapter.c:138 +msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Impossibile inserire dati nel pacchetto di advertisement." + +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Impossibile avviare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:59 +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:89 #, fuzzy, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +msgid "Failed to read gatts value, err 0x%04x" msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#: ports/nrf/common-hal/bleio/Characteristic.c:106 #, fuzzy, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:132 +#, fuzzy, c-format +msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#: ports/nrf/common-hal/bleio/Characteristic.c:144 #, fuzzy, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +msgid "Failed to read attribute value, err %0x04x" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 -#, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#: ports/nrf/common-hal/bleio/Characteristic.c:178 #, fuzzy, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +msgid "Failed to write attribute value, err 0x%04x" msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 -#, c-format -msgid "Failed to release mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 #, fuzzy -msgid "Can not fit data into the advertisment packet" +msgid "Data too large for the advertisement packet" msgstr "Impossibile inserire dati nel pacchetto di advertisement." -#: ports/nrf/common-hal/bleio/Device.c:266 -#, c-format -msgid "Failed to discover serivices, status: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Device.c:262 +#, fuzzy +msgid "Failed to discover services" +msgstr "Impossibile fermare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 -#, fuzzy, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +#, fuzzy +msgid "Failed to acquire mutex" +msgstr "Impossibile allocare buffer RX" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +#, fuzzy +msgid "Failed to release mutex" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:387 +#, fuzzy +msgid "Failed to continue scanning" msgstr "Impossible iniziare la scansione. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:436 -#, fuzzy, c-format -msgid "Failed to connect, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:419 +#, fuzzy +msgid "Failed to connect:" msgstr "Impossibile connettersi. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:513 -#, fuzzy, c-format -msgid "Failed to add service, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:489 +#, fuzzy +msgid "Failed to add service" msgstr "Impossibile fermare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:531 -#, fuzzy, c-format -msgid "Failed to start advertisment, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:506 +#, fuzzy +msgid "Failed to start advertising" msgstr "Impossibile avviare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:549 +#: ports/nrf/common-hal/bleio/Device.c:523 +#, fuzzy +msgid "Failed to stop advertising" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:548 +#, fuzzy +msgid "Failed to start scanning" +msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:564 +#, fuzzy +msgid "Failed to create mutex" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Peripheral.c:300 #, fuzzy, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +msgid "Failed to add service, err 0x%04x" msgstr "Impossibile fermare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 +#: ports/nrf/common-hal/bleio/Scanner.c:75 #, fuzzy, c-format -msgid "Failed to start scanning, status: 0x%0xlX" +msgid "Failed to continue scanning, err 0x%04x" msgstr "Impossible iniziare la scansione. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:592 +#: ports/nrf/common-hal/bleio/Scanner.c:101 #, fuzzy, c-format -msgid "Failed to create mutex, status: 0x%0xlX" -msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" +msgid "Failed to start scanning, err 0x%04x" +msgstr "Impossible iniziare la scansione. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Service.c:83 -#, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Service.c:88 +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:97 +#: ports/nrf/common-hal/bleio/UUID.c:54 #, fuzzy, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit" -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" -msgstr "Lunghezza della stringa UUID non valida" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" -msgstr "Parametro UUID non valido" +#: ports/nrf/common-hal/bleio/UUID.c:88 +#, fuzzy +msgid "Unexpected nrfx uuid type" +msgstr "indentazione inaspettata" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Tutte le periferiche I2C sono in uso" @@ -787,28 +848,28 @@ msgstr "Tutte le periferiche SPI sono in uso" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" msgstr "lunghezza del buffer non valida" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" msgstr "operazione I2C non supportata" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART non ancora implementato" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +#, fuzzy +msgid "Cannot get temperature" msgstr "Impossibile leggere la temperatura. status: 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 @@ -1956,7 +2017,7 @@ msgstr "allocazione di memoria fallita, l'heap è bloccato" msgid "memory allocation failed, allocating %u bytes" msgstr "allocazione di memoria fallita, allocando %u byte" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "profondità massima di ricorsione superata" @@ -2116,14 +2177,31 @@ msgstr "Numero di bit non valido" msgid "buffer slices must be of equal length" msgstr "slice del buffer devono essere della stessa lunghezza" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:107 +#: shared-bindings/bleio/Address.c:126 +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "la palette deve essere lunga 32 byte" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 #, fuzzy -msgid "Wrong number of bytes provided" -msgstr "numero di argomenti errato" +msgid "Expected a UUID" +msgstr "Atteso un %q" + +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#, fuzzy +msgid "buffer_size must be >= 1" +msgstr "slice del buffer devono essere della stessa lunghezza" + +#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#, fuzzy +msgid "Expected a Characteristic" +msgstr "Non è possibile aggiungere Characteristic." #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" @@ -2141,6 +2219,40 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +#, fuzzy +msgid "name must be a string" +msgstr "argomenti nominati devono essere stringhe" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "i buffer devono essere della stessa lunghezza" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2601,20 +2713,28 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid Service type" -#~ msgstr "Tipo di servizio non valido" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " +#~ "Whoops!\n" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " +#~ "CIRCUITPY:\n" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossibile applicare i parametri GAP." +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." + +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2623,28 +2743,27 @@ msgstr "" #~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " #~ "espulso CIRCUITPY).\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." -#~ msgid "Can not add Characteristic." -#~ msgstr "Non è possibile aggiungere Characteristic." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" -#~ msgid "Can not add Service." -#~ msgstr "Non è possibile aggiungere Service." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " -#~ "CIRCUITPY:\n" +#, fuzzy +#~ msgid "Wrong number of bytes provided" +#~ msgstr "numero di argomenti errato" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " -#~ "Whoops!\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parametro UUID non valido" + +#~ msgid "Invalid UUID string length" +#~ msgstr "Lunghezza della stringa UUID non valida" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 1b35b48247537..3974fe50e8ced 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-09 14:00-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -329,7 +329,7 @@ msgstr "Não há pinos suficientes disponíveis" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Pinos inválidos" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits não suportado" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "TX e RX não podem ser ambos" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Falha ao alocar buffer RX" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "Não foi possível inicializar o UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Nenhum pino RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Nenhum pino TX" @@ -648,126 +648,184 @@ msgstr "Funcionalidade AnalogOut não suportada" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +#, fuzzy +msgid "Failed to change softdevice state" +msgstr "Não pode parar propaganda. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +#, fuzzy +msgid "Failed to get softdevice state" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Adapter.c:138 +msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Não é possível ajustar dados no pacote de anúncios." + +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:332 #, fuzzy, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:59 +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:89 +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#: ports/nrf/common-hal/bleio/Characteristic.c:106 #, fuzzy, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +msgid "Failed to write gatts value, err 0x%04x" msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#: ports/nrf/common-hal/bleio/Characteristic.c:132 #, fuzzy, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +msgid "Failed to notify or indicate attribute value, err %0x04x" +msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:144 +#, fuzzy, c-format +msgid "Failed to read attribute value, err %0x04x" msgstr "Não é possível ler o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 -#, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#: ports/nrf/common-hal/bleio/Characteristic.c:178 #, fuzzy, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +msgid "Failed to write attribute value, err 0x%04x" msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 -#, c-format -msgid "Failed to release mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 #, fuzzy -msgid "Can not fit data into the advertisment packet" +msgid "Data too large for the advertisement packet" msgstr "Não é possível ajustar dados no pacote de anúncios." -#: ports/nrf/common-hal/bleio/Device.c:266 -#, c-format -msgid "Failed to discover serivices, status: 0x%08lX" -msgstr "" +#: ports/nrf/common-hal/bleio/Device.c:262 +#, fuzzy +msgid "Failed to discover services" +msgstr "Não pode parar propaganda. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 -#, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +#, fuzzy +msgid "Failed to acquire mutex" +msgstr "Falha ao alocar buffer RX" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +#, fuzzy +msgid "Failed to release mutex" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:387 +msgid "Failed to continue scanning" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:436 -#, c-format -msgid "Failed to connect, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:419 +msgid "Failed to connect:" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:513 -#, fuzzy, c-format -msgid "Failed to add service, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:489 +#, fuzzy +msgid "Failed to add service" msgstr "Não pode parar propaganda. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:531 -#, fuzzy, c-format -msgid "Failed to start advertisment, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:506 +#, fuzzy +msgid "Failed to start advertising" msgstr "Não é possível iniciar o anúncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:549 +#: ports/nrf/common-hal/bleio/Device.c:523 +#, fuzzy +msgid "Failed to stop advertising" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:548 +#, fuzzy +msgid "Failed to start scanning" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:564 +#, fuzzy +msgid "Failed to create mutex" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Peripheral.c:300 #, fuzzy, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +msgid "Failed to add service, err 0x%04x" msgstr "Não pode parar propaganda. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 +#: ports/nrf/common-hal/bleio/Scanner.c:75 #, fuzzy, c-format -msgid "Failed to start scanning, status: 0x%0xlX" +msgid "Failed to continue scanning, err 0x%04x" msgstr "Não é possível iniciar o anúncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:592 +#: ports/nrf/common-hal/bleio/Scanner.c:101 #, fuzzy, c-format -msgid "Failed to create mutex, status: 0x%0xlX" -msgstr "Não é possível ler o valor do atributo. status: 0x%02x" +msgid "Failed to start scanning, err 0x%04x" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Service.c:83 -#, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Service.c:88 +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:97 +#: ports/nrf/common-hal/bleio/UUID.c:54 #, fuzzy, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor." -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" -msgstr "Parâmetro UUID inválido" +#: ports/nrf/common-hal/bleio/UUID.c:88 +msgid "Unexpected nrfx uuid type" +msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Todos os periféricos I2C estão em uso" @@ -780,27 +838,27 @@ msgstr "Todos os periféricos SPI estão em uso" msgid "error = 0x%08lX" msgstr "erro = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" msgstr "Arquivo inválido" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" msgstr "I2C operação não suportada" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "busio.UART não disponível" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +#, fuzzy +msgid "Cannot get temperature" msgstr "Não pode obter a temperatura. status: 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 @@ -1935,7 +1993,7 @@ msgstr "" msgid "memory allocation failed, allocating %u bytes" msgstr "" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "" @@ -2088,13 +2146,31 @@ msgstr "Número inválido de bits" msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:107 -msgid "Wrong number of bytes provided" -msgstr "" +#: shared-bindings/bleio/Address.c:126 +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "buffers devem ser o mesmo tamanho" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#, fuzzy +msgid "Expected a UUID" +msgstr "Esperado um" + +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#, fuzzy +msgid "buffer_size must be >= 1" +msgstr "buffers devem ser o mesmo tamanho" + +#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#, fuzzy +msgid "Expected a Characteristic" +msgstr "Não é possível adicionar Característica." #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" @@ -2112,6 +2188,40 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +#, fuzzy +msgid "name must be a string" +msgstr "heap deve ser uma lista" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "buffers devem ser o mesmo tamanho" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2557,32 +2667,32 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." - -#~ msgid "Can not add Characteristic." -#~ msgstr "Não é possível adicionar Característica." +#~ msgid "Can not add Service." +#~ msgstr "Não é possível adicionar o serviço." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Não é possível aplicar parâmetros GAP." +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." #~ msgid "Cannot set PPCP parameters." #~ msgstr "Não é possível definir parâmetros PPCP." -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possível aplicar parâmetros GAP." -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." -#~ msgid "Can not add Service." -#~ msgstr "Não é possível adicionar o serviço." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parâmetro UUID inválido" From 382467904a139161fec2230a6ac7e320772315f1 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 9 Jan 2019 14:42:24 -0500 Subject: [PATCH 073/153] bad status check in .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4f89bd92c79f6..eb1a41e649410 100755 --- a/.travis.yml +++ b/.travis.yml @@ -116,7 +116,7 @@ script: - echo 'travis_fold:end:test_native' && tools/print_status.py status - (echo 'Testing with mpy' && echo 'travis_fold:start:test_mpy') - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; echo "Testing with mpy status: $?" >status + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; echo $? >status - echo 'travis_fold:end:test_mpy' && tools/print_status.py status - (echo 'Building docs' && echo 'travis_fold:start:build_docs') From d41ed768dc4e9adee5748d3d4d6a8c8678f97173 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 9 Jan 2019 16:18:52 -0500 Subject: [PATCH 074/153] Fix sphinx build issues; add better travis fold reporting; update author info --- .travis.yml | 50 +++++++++++++++++++++---------------------- conf.py | 6 +++--- ports/nrf/README.md | 8 +++---- tools/print_status.py | 15 +++++++++++++ 4 files changed, 47 insertions(+), 32 deletions(-) create mode 100755 tools/print_status.py diff --git a/.travis.yml b/.travis.yml index d3e9f4bf188e1..613afa6772501 100755 --- a/.travis.yml +++ b/.travis.yml @@ -77,7 +77,7 @@ before_script: - sudo apt-get install -y python3-pip - pip3 install --user sh click - ([[ -z "$TRAVIS_TESTS" ]] || sudo pip install --upgrade cpp-coveralls) - - (! var_search "${TRAVIS_TESTS-}" docs || pip install --user 'Sphinx<1.8.0' sphinx-rtd-theme recommonmark) + - (! var_search "${TRAVIS_TESTS-}" docs || pip install --user Sphinx sphinx-rtd-theme recommonmark) - (! var_search "${TRAVIS_TESTS-}" translations || pip3 install --user polib) # report some good version numbers to the build @@ -88,47 +88,47 @@ before_script: script: # Build mpy-cross first because other builds depend on it. - - echo 'Building mpy-cross' && echo -en 'travis_fold:start:mpy-cross\\r' - - make -C mpy-cross -j2 - - echo -en 'travis_fold:end:mpy-cross\\r' + - echo 'Building mpy-cross' && echo 'travis_fold:start:mpy-cross' + - make -C mpy-cross -j2 ; echo $? > status + - echo 'travis_fold:end:mpy-cross' && tools/print_status.py status # Use unbuffered output because building all the releases can take a long time. # Travis will cancel the job if it sees no output for >10 minutes. - cd tools && python3 -u build_release_files.py - cd .. - - echo 'Building unix' && echo -en 'travis_fold:start:unix\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) - - echo -en 'travis_fold:end:unix\\r' + - echo 'Building unix' && echo 'travis_fold:start:unix' + - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; echo $? > status + - echo 'travis_fold:end:unix' && tools/print_status.py status # run tests without coverage info #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1) #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1 --emit native) # run tests with coverage info - - echo 'Test all' && echo -en 'travis_fold:start:test_all\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) - - echo -en 'travis_fold:end:test_all\\r' + - echo 'Test all' && echo 'travis_fold:start:test_all' + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; echo $? > status + - echo 'travis_fold:end:test_all' && tools/print_status.py status - - echo 'Test threads' && echo -en 'travis_fold:start:test_threads\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) - - echo -en 'travis_fold:end:test_threads\\r' + - echo 'Test threads' && echo 'travis_fold:start:test_threads' + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; echo $? >status + - echo 'travis_fold:end:test_threads' && tools/print_status.py status - - echo 'Testing with native' && echo -en 'travis_fold:start:test_native\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) - - echo -en 'travis_fold:end:test_native\\r' + - echo 'Testing with native' && echo 'travis_fold:start:test_native' + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; echo $? >status + - echo 'travis_fold:end:test_native' && tools/print_status.py status - - (echo 'Testing with mpy' && echo -en 'travis_fold:start:test_mpy\\r') - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) - - echo -en 'travis_fold:end:test_mpy\\r' + - (echo 'Testing with mpy' && echo 'travis_fold:start:test_mpy') + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; echo $? >status + - echo 'travis_fold:end:test_mpy' && tools/print_status.py status - - (echo 'Building docs' && echo -en 'travis_fold:start:build_docs\\r') - - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) - - echo -en 'travis_fold:end:build_docs\\r' + - (echo 'Building docs' && echo 'travis_fold:start:build_docs') + - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; echo $? >status + - echo 'travis_fold:end:build_docs' && tools/print_status.py status - - (echo 'Building translations' && echo -en 'travis_fold:start:build_translations\\r') - - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) - - echo -en 'travis_fold:end:build_translations\\r' + - (echo 'Building translations' && echo 'travis_fold:start:build_translations') + - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; echo $? >status + - echo 'travis_fold:end:build_translations' && tools/print_status.py status # run coveralls coverage analysis (try to, even if some builds/tests failed) #- (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod) diff --git a/conf.py b/conf.py index dcfaa267812db..4da3c268609ae 100644 --- a/conf.py +++ b/conf.py @@ -284,7 +284,7 @@ # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'CircuitPython.tex', 'CircuitPython Documentation', - 'Damien P. George, Paul Sokolovsky, and contributors', 'manual'), + 'CircuitPython Contributors', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -314,7 +314,7 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'CircuitPython', 'CircuitPython Documentation', - ['Damien P. George, Paul Sokolovsky, and contributors'], 1), + ['CircuitPython contributors'], 1), ] # If true, show URL addresses after external links. @@ -328,7 +328,7 @@ # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'CircuitPython', 'CircuitPython Documentation', - 'Damien P. George, Paul Sokolovsky, and contributors', 'CircuitPython', 'One line description of project.', + 'CircuitPython contributors', 'CircuitPython', 'Python for Microcontrollers.', 'Miscellaneous'), ] diff --git a/ports/nrf/README.md b/ports/nrf/README.md index 34e58cb78eb9e..11a7b028de233 100644 --- a/ports/nrf/README.md +++ b/ports/nrf/README.md @@ -36,10 +36,10 @@ the following links: > **NOTE**: These board specific readmes may be more up to date than the generic board-neutral documentation further down. -* Adafruit [Feather nRF52](boards/feather_nrf52832/README.md): 512KB Flash, 64KB SRAM -* Adafruit [Feather nRF52840](boards/feather_nrf52840_express/README.md): 1MB Flash, 256KB SRAM -* Nordic PCA10056 see [Feather nRF52840](boards/pca10056/README.md) -* MakerDiary NRF52840 MDK see [its README](boards/makerdiary_nrf52840_mdk/README.md) +* Adafruit Feather nRF52: boards/feather_nrf52832/README.md: 512KB Flash, 64KB SRAM +* Adafruit Feather nRF52840: boards/feather_nrf52840_express/README.md: 1MB Flash, 256KB SRAM +* Nordic PCA10056 (uses nRF52840): boards/pca10056/README.md +* MakerDiary NRF52840 MDK: boards/makerdiary_nrf52840_mdk/README.md For all other board targets, see the generic notes below. diff --git a/tools/print_status.py b/tools/print_status.py new file mode 100755 index 0000000000000..ed563fd68bd9f --- /dev/null +++ b/tools/print_status.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import sys +if len(sys.argv) != 2: + print("""\ +Usage: print_status.py STATUS_FILENAME + STATUS_FILENAME contains one line with an integer status.""" + ) + sys.exit(1) +with open(sys.argv[1], 'r') as status_in: + status = int(status_in.readline()) + +print('{} with status {}'.format( + "\033[32msucceeded\033[0m" if status == 0 else "\033[31mfailed\033[0m", + status)) From b5e40f52c2b1c2890c866d7305e0e99b4811b7f5 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 16 Nov 2018 17:04:42 -0800 Subject: [PATCH 075/153] Add USB MIDI support for SAMD and nRF. The API should be identical to using a UART for MIDI. Fixes #672 --- lib/tinyusb | 2 +- ports/atmel-samd/Makefile | 9 +- ports/atmel-samd/mpconfigport.h | 3 + ports/nrf/Makefile | 2 +- ports/nrf/mpconfigport.h | 2 + shared-bindings/usb_midi/PortIn.c | 125 ++++++++++++++++++++++++++++ shared-bindings/usb_midi/PortIn.h | 44 ++++++++++ shared-bindings/usb_midi/PortOut.c | 107 ++++++++++++++++++++++++ shared-bindings/usb_midi/PortOut.h | 44 ++++++++++ shared-bindings/usb_midi/__init__.c | 78 +++++++++++++++++ shared-bindings/usb_midi/__init__.h | 34 ++++++++ shared-module/usb_midi/PortIn.c | 40 +++++++++ shared-module/usb_midi/PortIn.h | 39 +++++++++ shared-module/usb_midi/PortOut.c | 40 +++++++++ shared-module/usb_midi/PortOut.h | 39 +++++++++ shared-module/usb_midi/__init__.c | 70 ++++++++++++++++ shared-module/usb_midi/__init__.h | 32 +++++++ supervisor/shared/usb/tusb_config.h | 1 + supervisor/shared/usb/usb.c | 5 +- supervisor/supervisor.mk | 7 ++ tools/gen_usb_descriptor.py | 72 ++++++++-------- tools/usb_descriptor | 2 +- 22 files changed, 754 insertions(+), 43 deletions(-) create mode 100644 shared-bindings/usb_midi/PortIn.c create mode 100644 shared-bindings/usb_midi/PortIn.h create mode 100644 shared-bindings/usb_midi/PortOut.c create mode 100644 shared-bindings/usb_midi/PortOut.h create mode 100644 shared-bindings/usb_midi/__init__.c create mode 100644 shared-bindings/usb_midi/__init__.h create mode 100644 shared-module/usb_midi/PortIn.c create mode 100644 shared-module/usb_midi/PortIn.h create mode 100644 shared-module/usb_midi/PortOut.c create mode 100644 shared-module/usb_midi/PortOut.h create mode 100644 shared-module/usb_midi/__init__.c create mode 100644 shared-module/usb_midi/__init__.h diff --git a/lib/tinyusb b/lib/tinyusb index 3bb53273cd377..5804e56e3c2ab 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 3bb53273cd3770328f55ba317af3df0cce4333c1 +Subproject commit 5804e56e3c2ab4480bf72d94d997f769a645af47 diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 9a31eb42aeb25..4ac579441b3ba 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -89,13 +89,13 @@ BASE_CFLAGS = \ ifeq ($(CHIP_FAMILY), samd21) CFLAGS += -Os -DNDEBUG # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512 endif ifeq ($(CHIP_FAMILY), samd51) CFLAGS += -Os -DNDEBUG # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 endif #Debugging/Optimization @@ -103,9 +103,9 @@ ifeq ($(DEBUG), 1) # Turn on Python modules useful for debugging (e.g. uheap, ustack). CFLAGS += -ggdb # You may want to disable -flto if it interferes with debugging. - CFLAGS += -flto + # CFLAGS += -flto # You may want to enable these flags to make setting breakpoints easier. - # CFLAGS += -fno-inline -fno-ipa-sra + CFLAGS += -fno-inline -fno-ipa-sra ifeq ($(CHIP_FAMILY), samd21) CFLAGS += -DENABLE_MICRO_TRACE_BUFFER endif @@ -266,7 +266,6 @@ SRC_C = \ lib/oofatfs/option/ccsbcs.c \ lib/timeutils/timeutils.c \ lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c \ - lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c \ lib/utils/buffer_helper.c \ lib/utils/context_manager_helpers.c \ lib/utils/interrupt_char.c \ diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index d0ebbfa39edf3..65b8c94c5bb1a 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -237,6 +237,7 @@ extern const struct _mp_obj_module_t gamepad_module; extern const struct _mp_obj_module_t stage_module; extern const struct _mp_obj_module_t touchio_module; extern const struct _mp_obj_module_t usb_hid_module; +extern const struct _mp_obj_module_t usb_midi_module; extern const struct _mp_obj_module_t network_module; extern const struct _mp_obj_module_t socket_module; extern const struct _mp_obj_module_t wiznet_module; @@ -382,6 +383,7 @@ extern const struct _mp_obj_module_t wiznet_module; { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR__time), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \ TOUCHIO_MODULE \ EXTRA_BUILTIN_MODULES @@ -410,6 +412,7 @@ extern const struct _mp_obj_module_t wiznet_module; { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \ TOUCHIO_MODULE \ EXTRA_BUILTIN_MODULES #endif diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index b8d186621f867..165cf614a4371 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -75,7 +75,7 @@ LDFLAGS += -mthumb -mabi=aapcs -T $(LD_FILE) -L boards/ LDFLAGS += -Wl,--gc-sections # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 #Debugging/Optimization ifeq ($(DEBUG), 1) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 25710cea27927..d38b145783031 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -175,6 +175,7 @@ extern const struct _mp_obj_module_t supervisor_module; extern const struct _mp_obj_module_t gamepad_module; extern const struct _mp_obj_module_t neopixel_write_module; extern const struct _mp_obj_module_t usb_hid_module; +extern const struct _mp_obj_module_t usb_midi_module; extern const struct _mp_obj_module_t bleio_module; #if MICROPY_PY_BLEIO @@ -207,6 +208,7 @@ extern const struct _mp_obj_module_t bleio_module; { MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_json ), (mp_obj_t)&mp_module_ujson }, \ USBHID_MODULE \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \ BLEIO_MODULE // extra built in names to add to the global namespace diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c new file mode 100644 index 0000000000000..0309b70f76422 --- /dev/null +++ b/shared-bindings/usb_midi/PortIn.c @@ -0,0 +1,125 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 + +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: usb_midi +//| +//| :class:`PortIn` -- receives midi commands over USB +//| =================================================== +//| +//| .. class:: PortIn() +//| +//| Not currently dynamically supported. +//| + +STATIC mp_obj_t usb_midi_portin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + return mp_const_none; +} + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: read(nbytes=None) +//| +//| Read characters. If ``nbytes`` is specified then read at most that many +//| bytes. Otherwise, read everything that arrives until the connection +//| times out. Providing the number of bytes expected is highly recommended +//| because it will be faster. +//| +//| :return: Data read +//| :rtype: bytes or None +//| +//| .. method:: readinto(buf, nbytes=None) +//| +//| Read bytes into the ``buf``. If ``nbytes`` is specified then read at most +//| that many bytes. Otherwise, read at most ``len(buf)`` bytes. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: bytes or None +//| + +// These three methods are used by the shared stream methods. +STATIC mp_uint_t usb_midi_portin_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in); + byte *buf = buf_in; + + // make sure we want at least 1 char + if (size == 0) { + return 0; + } + + return common_hal_usb_midi_portin_read(self, buf, size, errcode); +} + +STATIC mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_midi_portin_bytes_available(self) > 0) { + ret |= MP_IOCTL_POLL_RD; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_rom_map_elem_t usb_midi_portin_locals_dict_table[] = { + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(usb_midi_portin_locals_dict, usb_midi_portin_locals_dict_table); + +STATIC const mp_stream_p_t usb_midi_portin_stream_p = { + .read = usb_midi_portin_read, + .write = NULL, + .ioctl = usb_midi_portin_ioctl, + .is_text = false, +}; + +const mp_obj_type_t usb_midi_portin_type = { + { &mp_type_type }, + .name = MP_QSTR_PortIn, + .make_new = usb_midi_portin_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &usb_midi_portin_stream_p, + .locals_dict = (mp_obj_dict_t*)&usb_midi_portin_locals_dict, +}; diff --git a/shared-bindings/usb_midi/PortIn.h b/shared-bindings/usb_midi/PortIn.h new file mode 100644 index 0000000000000..89bb59b712a4e --- /dev/null +++ b/shared-bindings/usb_midi/PortIn.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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_SHARED_BINDINGS_USB_MIDI_PORTIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H + +#include "shared-module/usb_midi/PortIn.h" + +extern const mp_obj_type_t usb_midi_portin_type; + +// Construct an underlying UART object. +extern void common_hal_usb_midi_portin_construct(usb_midi_portin_obj_t *self, + uint8_t receiver_buffer_size); +// Read characters. +extern size_t common_hal_usb_midi_portin_read(usb_midi_portin_obj_t *self, + uint8_t *data, size_t len, int *errcode); + +extern uint32_t common_hal_usb_midi_portin_bytes_available(usb_midi_portin_obj_t *self); +extern void common_hal_usb_midi_portin_clear_buffer(usb_midi_portin_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c new file mode 100644 index 0000000000000..156a092e048b5 --- /dev/null +++ b/shared-bindings/usb_midi/PortOut.c @@ -0,0 +1,107 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 + +#include "shared-bindings/usb_midi/PortOut.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: usb_midi +//| +//| :class:`PortOut` -- sends midi messages to a computer over USB +//| ============================================================== +//| +//| .. class:: PortOut() +//| +//| Not currently dynamically supported. +//| + +STATIC mp_obj_t usb_midi_portout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + return mp_const_none; +} + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: write(buf) +//| +//| Write the buffer of bytes to the bus. +//| +//| :return: the number of bytes written +//| :rtype: int or None +//| + +STATIC mp_uint_t usb_midi_portout_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); + const byte *buf = buf_in; + + return common_hal_usb_midi_portout_write(self, buf, size, errcode); +} + +STATIC mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_midi_portout_ready_to_tx(self)) { + ret |= MP_IOCTL_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_rom_map_elem_t usb_midi_portout_locals_dict_table[] = { + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(usb_midi_portout_locals_dict, usb_midi_portout_locals_dict_table); + +STATIC const mp_stream_p_t usb_midi_portout_stream_p = { + .read = NULL, + .write = usb_midi_portout_write, + .ioctl = usb_midi_portout_ioctl, + .is_text = false, +}; + +const mp_obj_type_t usb_midi_portout_type = { + { &mp_type_type }, + .name = MP_QSTR_PortOut, + .make_new = usb_midi_portout_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &usb_midi_portout_stream_p, + .locals_dict = (mp_obj_dict_t*)&usb_midi_portout_locals_dict, +}; diff --git a/shared-bindings/usb_midi/PortOut.h b/shared-bindings/usb_midi/PortOut.h new file mode 100644 index 0000000000000..dd42d7cdb9052 --- /dev/null +++ b/shared-bindings/usb_midi/PortOut.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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_SHARED_BINDINGS_USB_MIDI_PORTOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H + +#include "shared-module/usb_midi/PortOut.h" + +extern const mp_obj_type_t usb_midi_portout_type; + +// Construct an underlying UART object. +extern void common_hal_usb_midi_portout_construct(usb_midi_portout_obj_t *self, + uint8_t receiver_buffer_size); + +// Write characters. len is in characters NOT bytes! +extern size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, + const uint8_t *data, size_t len, int *errcode); + +extern bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c new file mode 100644 index 0000000000000..f57d3631bc4e5 --- /dev/null +++ b/shared-bindings/usb_midi/__init__.c @@ -0,0 +1,78 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/usb_midi/__init__.h" +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/usb_midi/PortOut.h" + +#include "py/runtime.h" + +//| :mod:`usb_midi` --- MIDI over USB +//| ================================================= +//| +//| .. module:: usb_midi +//| :synopsis: MIDI over USB +//| +//| The `usb_midi` module contains classes to transmit and receive MIDI messages over USB +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PortIn +//| PortOut +//| +//| +mp_map_elem_t usb_midi_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_midi) }, + { MP_ROM_QSTR(MP_QSTR_ports), mp_const_empty_tuple }, + { MP_ROM_QSTR(MP_QSTR_PortIn), MP_OBJ_FROM_PTR(&usb_midi_portin_type) }, + { MP_ROM_QSTR(MP_QSTR_PortOut), MP_OBJ_FROM_PTR(&usb_midi_portout_type) }, +}; + +// 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, + }, +}; + +const mp_obj_module_t usb_midi_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&usb_midi_module_globals, +}; diff --git a/shared-bindings/usb_midi/__init__.h b/shared-bindings/usb_midi/__init__.h new file mode 100644 index 0000000000000..e81818e04cb7a --- /dev/null +++ b/shared-bindings/usb_midi/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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_SHARED_BINDINGS_USB_MIDI___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H + +#include "py/obj.h" + +extern mp_obj_dict_t usb_midi_module_globals; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H diff --git a/shared-module/usb_midi/PortIn.c b/shared-module/usb_midi/PortIn.c new file mode 100644 index 0000000000000..b256c59370b63 --- /dev/null +++ b/shared-module/usb_midi/PortIn.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 "shared-module/usb_midi/PortIn.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +void common_hal_usb_midi_portin_construct(usb_midi_portin_obj_t *self, uint8_t receiver_buffer_size) { +} + +size_t common_hal_usb_midi_portin_read(usb_midi_portin_obj_t *self, uint8_t *data, size_t len, int *errcode) { + return tud_midi_read(data, len); +} + +uint32_t common_hal_usb_midi_portin_bytes_available(usb_midi_portin_obj_t *self) { + return tud_midi_available(); +} diff --git a/shared-module/usb_midi/PortIn.h b/shared-module/usb_midi/PortIn.h new file mode 100644 index 0000000000000..2f72aa4c211a6 --- /dev/null +++ b/shared-module/usb_midi/PortIn.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 SHARED_MODULE_USB_MIDI_PORTIN_H +#define SHARED_MODULE_USB_MIDI_PORTIN_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} usb_midi_portin_obj_t; + +#endif /* SHARED_MODULE_USB_MIDI_PORTIN_H */ diff --git a/shared-module/usb_midi/PortOut.c b/shared-module/usb_midi/PortOut.c new file mode 100644 index 0000000000000..3b9998c73a1e1 --- /dev/null +++ b/shared-module/usb_midi/PortOut.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 "shared-module/usb_midi/PortOut.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +void common_hal_usb_midi_portout_construct(usb_midi_portout_obj_t *self) { +} + +size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + return tud_midi_write(0, data, len); +} + +bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self) { + return tud_midi_connected(); +} diff --git a/shared-module/usb_midi/PortOut.h b/shared-module/usb_midi/PortOut.h new file mode 100644 index 0000000000000..6b1b8846474bb --- /dev/null +++ b/shared-module/usb_midi/PortOut.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 SHARED_MODULE_USB_MIDI_PORTOUT_H +#define SHARED_MODULE_USB_MIDI_PORTOUT_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} usb_midi_portout_obj_t; + +#endif /* SHARED_MODULE_USB_MIDI_PORTOUT_H */ diff --git a/shared-module/usb_midi/__init__.c b/shared-module/usb_midi/__init__.c new file mode 100644 index 0000000000000..60afeeef1d4a1 --- /dev/null +++ b/shared-module/usb_midi/__init__.c @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach 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 "shared-bindings/usb_midi/__init__.h" + +#include "genhdr/autogen_usb_descriptor.h" +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/objtuple.h" +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/usb_midi/PortOut.h" +#include "supervisor/memory.h" +#include "tusb.h" + +supervisor_allocation* usb_midi_allocation; + +static inline uint16_t word_align(uint16_t size) { + if (size % 4 != 0) { + return (size & 0xfffc) + 0x4; + } + return size; +} + +void usb_midi_init(void) { + // TODO(tannewt): Make this dynamic. + uint16_t tuple_size = word_align(sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t*) * 2); + uint16_t portin_size = word_align(sizeof(usb_midi_portin_obj_t)); + uint16_t portout_size = word_align(sizeof(usb_midi_portout_obj_t)); + + // For each embedded MIDI Jack in the descriptor we create a Port + usb_midi_allocation = allocate_memory(tuple_size + portin_size + portout_size, false); + + mp_obj_tuple_t *ports = (mp_obj_tuple_t *) usb_midi_allocation->ptr; + ports->base.type = &mp_type_tuple; + ports->len = 2; + + usb_midi_portin_obj_t* in = (usb_midi_portin_obj_t *) (usb_midi_allocation->ptr + tuple_size / 4); + in->base.type = &usb_midi_portin_type; + ports->items[0] = MP_OBJ_FROM_PTR(in); + + usb_midi_portout_obj_t* out = (usb_midi_portout_obj_t *) (usb_midi_allocation->ptr + tuple_size / 4 + portin_size / 4); + out->base.type = &usb_midi_portout_type; + ports->items[1] = MP_OBJ_FROM_PTR(out); + + mp_map_lookup(&usb_midi_module_globals.map, MP_ROM_QSTR(MP_QSTR_ports), MP_MAP_LOOKUP)->value = MP_OBJ_FROM_PTR(ports); +} diff --git a/shared-module/usb_midi/__init__.h b/shared-module/usb_midi/__init__.h new file mode 100644 index 0000000000000..e1ad1fbafbdfa --- /dev/null +++ b/shared-module/usb_midi/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 SHARED_MODULE_USB_MIDI___INIT___H +#define SHARED_MODULE_USB_MIDI___INIT___H + +void usb_midi_init(void); + +#endif /* SHARED_MODULE_USB_MIDI___INIT___H */ diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index 649c390ac7c47..301805275a716 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -75,6 +75,7 @@ #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 1 #define CFG_TUD_HID 1 +#define CFG_TUD_MIDI 1 #define CFG_TUD_CUSTOM_CLASS 0 /*------------------------------------------------------------------*/ diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 1aa34e9e6f312..5898323e8e6be 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -26,6 +26,7 @@ #include "tick.h" #include "shared-bindings/microcontroller/Processor.h" +#include "shared-module/usb_midi/__init__.h" #include "supervisor/port.h" #include "supervisor/usb.h" #include "lib/utils/interrupt_char.h" @@ -71,11 +72,13 @@ void usb_init(void) { // This callback always got invoked regardless of mp_interrupt_char value since we only set it once here tud_cdc_set_wanted_char(CHAR_CTRL_C); #endif + + usb_midi_init(); } void usb_background(void) { if (usb_enabled()) { - tusb_task(); + tud_task(); tud_cdc_write_flush(); } } diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 56ad8a3ba60dd..191af7b255c99 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -49,6 +49,7 @@ else lib/tinyusb/src/class/msc/msc_device.c \ lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/class/hid/hid_device.c \ + lib/tinyusb/src/class/midi/midi_device.c \ lib/tinyusb/src/tusb.c \ supervisor/shared/serial.c \ supervisor/usb.c \ @@ -57,8 +58,14 @@ else supervisor/shared/usb/usb_msc_flash.c \ shared-bindings/usb_hid/__init__.c \ shared-bindings/usb_hid/Device.c \ + shared-bindings/usb_midi/__init__.c \ + shared-bindings/usb_midi/PortIn.c \ + shared-bindings/usb_midi/PortOut.c \ shared-module/usb_hid/__init__.c \ shared-module/usb_hid/Device.c \ + shared-module/usb_midi/__init__.c \ + shared-module/usb_midi/PortIn.c \ + shared-module/usb_midi/PortOut.c \ $(BUILD)/autogen_usb_descriptor.c CFLAGS += -DUSB_AVAILABLE endif diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index 2cb06ec2f25d9..e8d66443d838d 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -176,16 +176,33 @@ def strings_in_order(cls): ] # Audio! -midi_in_jack = midi.InJackDescriptor( - description="MIDI PC <- CircuitPython internals", +# In and out here are relative to CircuitPython + +# USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython +midi_in_jack_emb = midi.InJackDescriptor( + description="MIDI PC -> CircuitPython", bJackType=midi.JACK_TYPE_EMBEDDED, - iJack=0) -midi_out_jack = midi.OutJackDescriptor( - description="MIDI PC -> CircuitPython internals", + iJack=StringIndex.index("CircuitPython usb_midi.ports[0]")) +midi_out_jack_ext = midi.OutJackDescriptor( + description="MIDI data out to user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, + input_pins=[(midi_in_jack_emb, 1)], + iJack=0) + +# USB IN <- midi_out_jack_emb <- midi_in_jack_ext <- CircuitPython +midi_in_jack_ext = midi.InJackDescriptor( + description="MIDI data in from user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, + iJack=0) +midi_out_jack_emb = midi.OutJackDescriptor( + description="MIDI PC <- CircuitPython", bJackType=midi.JACK_TYPE_EMBEDDED, - iJack=0) + input_pins=[(midi_in_jack_ext, 1)], + iJack=StringIndex.index("CircuitPython usb_midi.ports[1]")) + + audio_midi_interface = standard.InterfaceDescriptor( - description="All the audio", + description="Midi goodness", bInterfaceClass=audio.AUDIO_CLASS_DEVICE, bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING, bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1, @@ -193,26 +210,23 @@ def strings_in_order(cls): subdescriptors=[ midi.Header( jacks_and_elements=[ - midi_in_jack, - midi.InJackDescriptor( - description="MIDI data in from user code.", - bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0), - midi_out_jack, - midi.OutJackDescriptor( - description="MIDI data out to user code.", - bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0), - ] + midi_in_jack_emb, + midi_in_jack_ext, + midi_out_jack_emb, + midi_out_jack_ext + ], ), standard.EndpointDescriptor( - description="MIDI data out", + description="MIDI data out to CircuitPython", bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, bmAttributes=standard.EndpointDescriptor.TYPE_BULK), - midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack]), + midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]), standard.EndpointDescriptor( - description="MIDI data in", + description="MIDI data in from CircuitPython", bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK), - midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack]), + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval = 0x0), + midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack_emb]), ]) cs_ac_interface = audio10.AudioControlInterface( @@ -234,12 +248,12 @@ def strings_in_order(cls): ]) # Audio streaming interfaces must occur before MIDI ones. -# audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces +audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces # This will renumber the endpoints to make them unique across descriptors, # and renumber the interfaces in order. But we still need to fix up certain # interface cross-references. -interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces) +interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces, audio_interfaces) # Now adjust the CDC interface cross-references. @@ -256,21 +270,11 @@ def strings_in_order(cls): bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model bFunctionProtocol=cdc.CDC_PROTOCOL_NONE) -# audio_iad = standard.InterfaceAssociationDescriptor( -# description="Audio IAD", -# bFirstInterface=audio_control_interface.bInterfaceNumber, -# bInterfaceCount=len(audio_interfaces), -# bFunctionClass=audio.AUDIO_CLASS_DEVICE, -# bFunctionSubClass=audio.AUDIO_SUBCLASS_UNKNOWN, -# bFunctionProtocol=audio.AUDIO_PROTOCOL_V1) - - descriptor_list = [] descriptor_list.append(cdc_iad) -# descriptor_list.append(audio_iad) descriptor_list.extend(cdc_interfaces) descriptor_list.extend(msc_interfaces) -# descriptor_list.append(audio_control_interface) +descriptor_list.append(audio_control_interface) # Put the CDC IAD just before the CDC interfaces. # There appears to be a bug in the Windows composite USB driver that requests the # HID report descriptor with the wrong interface number if the HID interface is not given diff --git a/tools/usb_descriptor b/tools/usb_descriptor index 57bf602dac9cb..e2e79566a807b 160000 --- a/tools/usb_descriptor +++ b/tools/usb_descriptor @@ -1 +1 @@ -Subproject commit 57bf602dac9cba8c4226f764c286cbc60103d67d +Subproject commit e2e79566a807b7230dddbc53a103c19b2f65e2cb From 5c15a19c3209eb45f8d7d2692b95f7e728e24a89 Mon Sep 17 00:00:00 2001 From: ShawnHymel Date: Wed, 9 Jan 2019 16:12:43 -0600 Subject: [PATCH 076/153] Added SparkFun SAMD21 Mini port --- ports/atmel-samd/README.rst | 2 +- .../boards/sparkfun_samd21_mini/board.c | 39 ++++++++++++++ .../sparkfun_samd21_mini/mpconfigboard.h | 24 +++++++++ .../sparkfun_samd21_mini/mpconfigboard.mk | 11 ++++ .../boards/sparkfun_samd21_mini/pins.c | 53 +++++++++++++++++++ 5 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 ports/atmel-samd/boards/sparkfun_samd21_mini/board.c create mode 100644 ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 3e0bb56b0dc4c..b0b3bb40e24ac 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -237,4 +237,4 @@ Port Specific modules --------------------- .. toctree:: - bindings/samd/__init__ \ No newline at end of file + bindings/samd/__init__ diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c new file mode 100644 index 0000000000000..0f60736a24006 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 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 "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/sparkfun_samd21_mini/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h new file mode 100644 index 0000000000000..aec54ddfbd368 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h @@ -0,0 +1,24 @@ +#define MICROPY_HW_BOARD_NAME "SparkFun SAMD21 Mini Breakout" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA19) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// 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/sparkfun_samd21_mini/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk new file mode 100644 index 0000000000000..0cba15d7077d9 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk @@ -0,0 +1,11 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x1B4F +USB_PID = 0x8D22 +USB_PRODUCT = "SparkFun SAMD21 Mini Breakout" +USB_MANUFACTURER = "SparkFun" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c new file mode 100644 index 0000000000000..abe63d0644d80 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c @@ -0,0 +1,53 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + + // Analog pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + + // Digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + + // UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + + // SPI pins + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, + + // I2C pins + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + + // LED pins + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_YELLOW_LED), MP_ROM_PTR(&pin_PB03) }, + + // Comm objects + { 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); From 62ea1bd43e784114fbba8bd0816e3f6c80c18418 Mon Sep 17 00:00:00 2001 From: Shawn Hymel Date: Thu, 10 Jan 2019 12:48:13 -0600 Subject: [PATCH 077/153] Added SparkFun SAMD21 mini to travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2eab28a0b8c93..72d3830024bdc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ env: - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm - - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick" TRAVIS_SDK=arm + - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick sparkfun_samd21_mini" TRAVIS_SDK=arm addons: artifacts: From 3dd59c3d5fa59f5bea3acc8e55c4d4a5091e66eb Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 10 Jan 2019 11:00:40 -0800 Subject: [PATCH 078/153] Polish thanks to Dan's feedback --- .travis.yml | 2 +- shared-bindings/usb_midi/PortIn.c | 3 +++ shared-bindings/usb_midi/PortOut.c | 3 +++ shared-module/usb_midi/__init__.c | 13 +++---------- supervisor/memory.h | 9 +++++++++ tools/gen_usb_descriptor.py | 2 ++ 6 files changed, 21 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3e9f4bf188e1..bab5a24562944 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ git: # that SDK is shortest and add it there. In the case of major re-organizations, # just try to make the builds "about equal in run time" env: - - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf:esp8266 + - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf:esp8266 - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c index 0309b70f76422..3c4d4f73f699d 100644 --- a/shared-bindings/usb_midi/PortIn.c +++ b/shared-bindings/usb_midi/PortIn.c @@ -45,6 +45,9 @@ //| //| Not currently dynamically supported. //| +//| PortIn objects are constructed for every corresponding entry in the USB descriptor and added +//| to the `usb_midi.ports` tuple. +//| STATIC mp_obj_t usb_midi_portin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { return mp_const_none; diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c index 156a092e048b5..8b26b8ffc4f82 100644 --- a/shared-bindings/usb_midi/PortOut.c +++ b/shared-bindings/usb_midi/PortOut.c @@ -45,6 +45,9 @@ //| //| Not currently dynamically supported. //| +//| PortOut objects are constructed for every corresponding entry in the USB descriptor and added +//| to the `usb_midi.ports` tuple. +//| STATIC mp_obj_t usb_midi_portout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { return mp_const_none; diff --git a/shared-module/usb_midi/__init__.c b/shared-module/usb_midi/__init__.c index 60afeeef1d4a1..73a314b9972a3 100644 --- a/shared-module/usb_midi/__init__.c +++ b/shared-module/usb_midi/__init__.c @@ -38,18 +38,11 @@ supervisor_allocation* usb_midi_allocation; -static inline uint16_t word_align(uint16_t size) { - if (size % 4 != 0) { - return (size & 0xfffc) + 0x4; - } - return size; -} - void usb_midi_init(void) { // TODO(tannewt): Make this dynamic. - uint16_t tuple_size = word_align(sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t*) * 2); - uint16_t portin_size = word_align(sizeof(usb_midi_portin_obj_t)); - uint16_t portout_size = word_align(sizeof(usb_midi_portout_obj_t)); + uint16_t tuple_size = align32_size(sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t*) * 2); + uint16_t portin_size = align32_size(sizeof(usb_midi_portin_obj_t)); + uint16_t portout_size = align32_size(sizeof(usb_midi_portout_obj_t)); // For each embedded MIDI Jack in the descriptor we create a Port usb_midi_allocation = allocate_memory(tuple_size + portin_size + portout_size, false); diff --git a/supervisor/memory.h b/supervisor/memory.h index 4f8317a2df5c9..c89f14bd9e48f 100755 --- a/supervisor/memory.h +++ b/supervisor/memory.h @@ -39,6 +39,8 @@ typedef struct { uint32_t length; // in bytes } supervisor_allocation; + + void memory_init(void); void free_memory(supervisor_allocation* allocation); supervisor_allocation* allocate_remaining_memory(void); @@ -48,4 +50,11 @@ supervisor_allocation* allocate_remaining_memory(void); // statically allocated memory. supervisor_allocation* allocate_memory(uint32_t length, bool high_address); +static inline uint16_t align32_size(uint16_t size) { + if (size % 4 != 0) { + return (size & 0xfffc) + 0x4; + } + return size; +} + #endif // MICROPY_INCLUDED_SUPERVISOR_MEMORY_H diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index e8d66443d838d..10bbf5066343f 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -274,6 +274,8 @@ def strings_in_order(cls): descriptor_list.append(cdc_iad) descriptor_list.extend(cdc_interfaces) descriptor_list.extend(msc_interfaces) +# Only add the control interface because other audio interfaces are managed by it to ensure the +# correct ordering. descriptor_list.append(audio_control_interface) # Put the CDC IAD just before the CDC interfaces. # There appears to be a bug in the Windows composite USB driver that requests the From 41d3ea231b2f62d136112c4dc5b9fe57d9b33d86 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 10 Jan 2019 11:06:45 -0800 Subject: [PATCH 079/153] Add new translation messages --- locale/ID.po | 294 ++++++++++++++++++++++++--------------- locale/circuitpython.pot | 28 ++-- locale/de_DE.po | 68 ++++----- locale/en_US.po | 28 ++-- locale/es.po | 68 ++++----- locale/fil.po | 68 ++++----- locale/fr.po | 72 +++++----- locale/it_IT.po | 74 +++++----- locale/pt_BR.po | 60 ++++---- 9 files changed, 412 insertions(+), 348 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 76bb14893a18c..405b3a0e3ff8f 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-09 16:20-0800\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -131,7 +131,7 @@ msgstr "kompresi header" msgid "invalid dupterm index" msgstr "indeks dupterm tidak valid" -#: extmod/vfs_fat.c:426 py/moduerrno.c:150 +#: extmod/vfs_fat.c:426 py/moduerrno.c:154 msgid "Read-only filesystem" msgstr "sistem file (filesystem) bersifat Read-only" @@ -151,74 +151,42 @@ msgstr "argumen-argumen tidak valid" msgid "script compilation not supported" msgstr "kompilasi script tidak didukung" -#: main.c:154 +#: main.c:150 msgid " output:\n" msgstr "output:\n" -#: main.c:168 main.c:241 +#: main.c:164 main.c:237 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" -msgstr "Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk menjalankannya atau masuk ke REPL untuk" -"menonaktifkan.\n" +msgstr "" +"Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk " +"menjalankannya atau masuk ke REPL untukmenonaktifkan.\n" -#: main.c:170 +#: main.c:166 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Berjalan di mode aman(safe mode)! Auto-reload tidak aktif.\n" -#: main.c:172 main.c:243 +#: main.c:168 main.c:239 msgid "Auto-reload is off.\n" msgstr "Auto-reload tidak aktif.\n" -#: main.c:186 +#: main.c:182 msgid "Running in safe mode! Not running saved code.\n" -msgstr "Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" +msgstr "" +"Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" -#: main.c:202 +#: main.c:198 msgid "WARNING: Your code filename has two extensions\n" msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" -#: main.c:250 -msgid "You requested starting safe mode by " -msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " - -#: main.c:253 -msgid "To exit, please reset the board without " -msgstr "Untuk keluar, silahkan reset board tanpa " - -#: main.c:260 -msgid "" -"You are running in safe mode which means something really bad happened.\n" -msgstr "Anda sedang menjalankan mode aman (safe mode) yang berarti sesuatu yang sangat buruk telah terjadi.\n" - -#: main.c:262 -msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -msgstr "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" - -#: main.c:263 -msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" -msgstr "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" - -#: main.c:266 -msgid "" -"The microcontroller's power dipped. Please make sure your power supply " -"provides\n" -msgstr "Tegangan dari mikrokontroler turun atau mati. Pastikan sumber tegangan " -"memberikan daya\n" - -#: main.c:267 -msgid "" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY).\n" -msgstr "" -"tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " -"CIRCUITPY).\n" - -#: main.c:271 +#: main.c:244 msgid "Press any key to enter the REPL. Use CTRL-D to reload." -msgstr "Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset (Reload)" +msgstr "" +"Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset " +"(Reload)" -#: main.c:429 +#: main.c:407 msgid "soft reboot\n" msgstr "memulai ulang software(soft reboot)\n" @@ -340,7 +308,9 @@ msgstr "Pin untuk channel kanan tidak valid" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" -msgstr "Tidak dapat menggunakan output di kedua channel dengan menggunakan pin yang sama" +msgstr "" +"Tidak dapat menggunakan output di kedua channel dengan menggunakan pin yang " +"sama" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 @@ -364,9 +334,9 @@ msgstr "Pin yang tersedia tidak cukup" #: ports/atmel-samd/common-hal/busio/I2C.c:78 #: ports/atmel-samd/common-hal/busio/SPI.c:171 -#: ports/atmel-samd/common-hal/busio/UART.c:119 +#: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Pin-pin tidak valid" @@ -378,31 +348,31 @@ msgstr "SDA atau SCL membutuhkan pull up" msgid "Unsupported baudrate" msgstr "Baudrate tidak didukung" -#: ports/atmel-samd/common-hal/busio/UART.c:66 +#: ports/atmel-samd/common-hal/busio/UART.c:67 msgid "bytes > 8 bits not supported" msgstr "byte > 8 bit tidak didukung" -#: ports/atmel-samd/common-hal/busio/UART.c:72 -#: ports/nrf/common-hal/busio/UART.c:82 +#: ports/atmel-samd/common-hal/busio/UART.c:73 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx dan rx keduanya tidak boleh kosong" -#: ports/atmel-samd/common-hal/busio/UART.c:145 -#: ports/nrf/common-hal/busio/UART.c:115 +#: ports/atmel-samd/common-hal/busio/UART.c:146 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Gagal untuk mengalokasikan buffer RX" -#: ports/atmel-samd/common-hal/busio/UART.c:153 +#: ports/atmel-samd/common-hal/busio/UART.c:154 msgid "Could not initialize UART" msgstr "Tidak dapat menginisialisasi UART" -#: ports/atmel-samd/common-hal/busio/UART.c:240 -#: ports/nrf/common-hal/busio/UART.c:149 +#: ports/atmel-samd/common-hal/busio/UART.c:241 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Tidak pin RX" -#: ports/atmel-samd/common-hal/busio/UART.c:294 -#: ports/nrf/common-hal/busio/UART.c:195 +#: ports/atmel-samd/common-hal/busio/UART.c:300 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Tidak ada pin TX" @@ -414,7 +384,9 @@ msgstr "Tidak bisa mendapatkan pull pada saat mode output" #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." -msgstr "Tidak dapat melakukan reset ke bootloader karena tidak ada bootloader yang terisi" +msgstr "" +"Tidak dapat melakukan reset ke bootloader karena tidak ada bootloader yang " +"terisi" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 @@ -447,7 +419,7 @@ msgid "pop from an empty PulseIn" msgstr "Muncul dari PulseIn yang kosong" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 msgid "index out of range" msgstr "index keluar dari jangkauan" @@ -538,7 +510,9 @@ msgstr "Tidak dapat memasang filesystem kembali" #: ports/esp8266/common-hal/storage/__init__.c:38 msgid "Use esptool to erase flash and re-upload Python instead" -msgstr "Gunakan esptool untuk menghapus flash dan upload ulang Python sebagai gantinya" +msgstr "" +"Gunakan esptool untuk menghapus flash dan upload ulang Python sebagai " +"gantinya" #: ports/esp8266/esp_mphal.c:154 msgid "C-level assert" @@ -742,8 +716,8 @@ msgid "Can not fit data into the advertisment packet" msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" #: ports/nrf/common-hal/bleio/Device.c:266 -#, c-format -msgid "Failed to discover services, status: 0x%08lX" +#, fuzzy, c-format +msgid "Failed to discover serivices, status: 0x%08lX" msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Device.c:403 @@ -803,7 +777,7 @@ msgstr "Panjang string UUID tidak valid" msgid "Invalid UUID parameter" msgstr "Parameter UUID tidak valid" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Semua perangkat I2C sedang digunakan" @@ -811,24 +785,24 @@ msgstr "Semua perangkat I2C sedang digunakan" msgid "All SPI peripherals are in use" msgstr "Semua perangkat SPI sedang digunakan" -#: ports/nrf/common-hal/busio/UART.c:48 +#: ports/nrf/common-hal/busio/UART.c:49 #, c-format msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:86 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "Ukuran buffer tidak valid" -#: ports/nrf/common-hal/busio/UART.c:90 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "Parity ganjil tidak didukung" -#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 -#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 -#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 -#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 -#: ports/nrf/common-hal/busio/UART.c:364 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "busio.UART tidak tersedia" @@ -957,7 +931,8 @@ msgid "" msgstr "" "Selamat datang ke Adafruit CircuitPython %s!\n" "\n" -"Silahkan kunjungi learn.adafruit.com/category/circuitpython untuk panduan project.\n" +"Silahkan kunjungi learn.adafruit.com/category/circuitpython untuk panduan " +"project.\n" "\n" "Untuk menampilkan modul built-in silahkan ketik `help(\"modules\")`.\n" @@ -1334,140 +1309,140 @@ msgstr "" msgid "expecting a dict for keyword args" msgstr "" -#: py/moduerrno.c:143 py/moduerrno.c:146 +#: py/moduerrno.c:147 py/moduerrno.c:150 msgid "Permission denied" msgstr "" -#: py/moduerrno.c:144 +#: py/moduerrno.c:148 msgid "No such file/directory" msgstr "" -#: py/moduerrno.c:145 +#: py/moduerrno.c:149 msgid "Input/output error" msgstr "" -#: py/moduerrno.c:147 +#: py/moduerrno.c:151 msgid "File exists" msgstr "" -#: py/moduerrno.c:148 +#: py/moduerrno.c:152 msgid "Unsupported operation" msgstr "" -#: py/moduerrno.c:149 +#: py/moduerrno.c:153 msgid "Invalid argument" msgstr "" -#: py/obj.c:90 +#: py/obj.c:92 msgid "Traceback (most recent call last):\n" msgstr "" -#: py/obj.c:94 +#: py/obj.c:96 msgid " File \"%q\", line %d" msgstr "" -#: py/obj.c:96 +#: py/obj.c:98 msgid " File \"%q\"" msgstr "" -#: py/obj.c:100 +#: py/obj.c:102 msgid ", in %q\n" msgstr "" -#: py/obj.c:257 +#: py/obj.c:259 msgid "can't convert to int" msgstr "" -#: py/obj.c:260 +#: py/obj.c:262 #, c-format msgid "can't convert %s to int" msgstr "" -#: py/obj.c:320 +#: py/obj.c:322 msgid "can't convert to float" msgstr "" -#: py/obj.c:323 +#: py/obj.c:325 #, c-format msgid "can't convert %s to float" msgstr "" -#: py/obj.c:353 +#: py/obj.c:355 msgid "can't convert to complex" msgstr "" -#: py/obj.c:356 +#: py/obj.c:358 #, c-format msgid "can't convert %s to complex" msgstr "" -#: py/obj.c:371 +#: py/obj.c:373 msgid "expected tuple/list" msgstr "" -#: py/obj.c:374 +#: py/obj.c:376 #, c-format msgid "object '%s' is not a tuple or list" msgstr "" -#: py/obj.c:385 +#: py/obj.c:387 msgid "tuple/list has wrong length" msgstr "" -#: py/obj.c:387 +#: py/obj.c:389 #, c-format msgid "requested length %d but object has length %d" msgstr "" -#: py/obj.c:400 +#: py/obj.c:402 msgid "indices must be integers" msgstr "" -#: py/obj.c:403 +#: py/obj.c:405 msgid "%q indices must be integers, not %s" msgstr "" -#: py/obj.c:423 +#: py/obj.c:425 msgid "%q index out of range" msgstr "" -#: py/obj.c:455 +#: py/obj.c:457 msgid "object has no len" msgstr "" -#: py/obj.c:458 +#: py/obj.c:460 #, c-format msgid "object of type '%s' has no len()" msgstr "" -#: py/obj.c:496 +#: py/obj.c:500 msgid "object does not support item deletion" msgstr "" -#: py/obj.c:499 +#: py/obj.c:503 #, c-format msgid "'%s' object does not support item deletion" msgstr "" -#: py/obj.c:503 +#: py/obj.c:507 msgid "object is not subscriptable" msgstr "" -#: py/obj.c:506 +#: py/obj.c:510 #, c-format msgid "'%s' object is not subscriptable" msgstr "" -#: py/obj.c:510 +#: py/obj.c:514 msgid "object does not support item assignment" msgstr "" -#: py/obj.c:513 +#: py/obj.c:517 #, c-format msgid "'%s' object does not support item assignment" msgstr "" -#: py/obj.c:544 +#: py/obj.c:548 msgid "object with buffer protocol required" msgstr "" @@ -1983,6 +1958,14 @@ msgstr "" msgid "stream operation not supported" msgstr "" +#: py/stream.c:254 +msgid "string not supported; use bytes or bytearray" +msgstr "" + +#: py/stream.c:289 +msgid "length argument not allowed for this type" +msgstr "" + #: py/vm.c:255 msgid "local variable referenced before assignment" msgstr "" @@ -2141,14 +2124,18 @@ msgstr "" msgid "Function requires lock." msgstr "" -#: shared-bindings/busio/UART.c:102 +#: shared-bindings/busio/UART.c:106 msgid "bits must be 7, 8 or 9" msgstr "" -#: shared-bindings/busio/UART.c:114 +#: shared-bindings/busio/UART.c:118 msgid "stop must be 1 or 2" msgstr "" +#: shared-bindings/busio/UART.c:123 +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c:211 msgid "Invalid direction." msgstr "" @@ -2370,15 +2357,15 @@ msgstr "" msgid "time.struct_time() takes a 9-sequence" msgstr "" -#: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:264 +#: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:263 msgid "Tuple or struct_time argument required" msgstr "" -#: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:269 +#: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:268 msgid "function takes exactly 9 arguments" msgstr "" -#: shared-bindings/time/__init__.c:240 shared-bindings/time/__init__.c:273 +#: shared-bindings/time/__init__.c:239 shared-bindings/time/__init__.c:272 msgid "timestamp out of range for platform time_t" msgstr "" @@ -2521,3 +2508,80 @@ msgstr "" #: shared-module/usb_hid/Device.c:59 msgid "USB Error" msgstr "" + +#: supervisor/shared/safe_mode.c:97 +msgid "You requested starting safe mode by " +msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " + +#: supervisor/shared/safe_mode.c:100 +msgid "To exit, please reset the board without " +msgstr "Untuk keluar, silahkan reset board tanpa " + +#: supervisor/shared/safe_mode.c:107 +#, fuzzy +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"Anda sedang menjalankan mode aman (safe mode) yang berarti sesuatu yang " +"sangat buruk telah terjadi.\n" + +#: supervisor/shared/safe_mode.c:109 +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:111 +msgid "Crash into the HardFault_Handler.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:113 +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:115 +msgid "MicroPython fatal error.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:118 +#, fuzzy +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"Tegangan dari mikrokontroler turun atau mati. Pastikan sumber tegangan " +"memberikan daya\n" + +#: supervisor/shared/safe_mode.c:120 +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:123 +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" + +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " +#~ "CIRCUITPY).\n" + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 92e1813025bdc..dd7df915ffec3 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: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -329,7 +329,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "" @@ -766,7 +766,7 @@ msgstr "" msgid "Invalid UUID parameter" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "" @@ -779,19 +779,19 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index e9f81e0b13c84..8792ce8347250 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -333,7 +333,7 @@ msgstr "Nicht genug Pins vorhanden" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Ungültige Pins" @@ -350,12 +350,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Konnte keinen RX Buffer allozieren" @@ -364,12 +364,12 @@ msgid "Could not initialize UART" msgstr "Konnte UART nicht initialisieren" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Kein RX Pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Kein TX Pin" @@ -774,7 +774,7 @@ msgstr "Ungültige UUID-Stringlänge" msgid "Invalid UUID parameter" msgstr "Ungültiger UUID-Parameter" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Alle timer werden benutzt" @@ -789,21 +789,21 @@ msgstr "Alle timer werden benutzt" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" msgstr "ungültiger dupterm index" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "" @@ -2577,15 +2577,26 @@ msgstr "" #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" #~ msgid "Cannot set PPCP parameters." #~ msgstr "Kann PPCP Parameter nicht setzen." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." + #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " #~ "CIRCUITPY).\n" @@ -2593,25 +2604,14 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." - -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." - #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." + #~ msgid "Can not add Service." #~ msgstr "Kann den Dienst nicht hinzufügen." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." diff --git a/locale/en_US.po b/locale/en_US.po index 119dde3d68cec..1b3707917b4a7 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -329,7 +329,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "" @@ -766,7 +766,7 @@ msgstr "" msgid "Invalid UUID parameter" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "" @@ -779,19 +779,19 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "" diff --git a/locale/es.po b/locale/es.po index 29c69d49c2535..397056797132c 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -335,7 +335,7 @@ msgstr "No hay suficientes pines disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "pines inválidos" @@ -352,12 +352,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits no soportados" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "Ambos tx y rx no pueden ser None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Ha fallado la asignación del buffer RX" @@ -366,12 +366,12 @@ msgid "Could not initialize UART" msgstr "No se puede inicializar la UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Sin pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Sin pin TX" @@ -774,7 +774,7 @@ msgstr "Longitud de string UUID inválida" msgid "Invalid UUID parameter" msgstr "Parámetro UUID inválido" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Todos los timers están siendo usados" @@ -787,19 +787,19 @@ msgstr "Todos los timers están siendo usados" msgid "error = 0x%08lX" msgstr "error = 0x%08lx" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "Tamaño de buffer inválido" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "Paridad impar no soportada" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "busio.UART no disponible" @@ -2585,18 +2585,35 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." - #~ msgid "Can not add Characteristic." #~ msgstr "No se puede agregar la Característica." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." + #~ msgid "Can not apply device name in the stack." #~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" + +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" + #~ msgid "Can not encode UUID, to check length." #~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." + +#, fuzzy +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " +#~ "unidad de almacenamiento CIRCUITPY:\n" + #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Se puede codificar el UUID en el paquete de anuncio." @@ -2606,12 +2623,6 @@ msgstr "" #~ msgid "Can not add Service." #~ msgstr "No se puede agregar el Servicio." -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." - -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Baud rate demasiado alto para este periférico SPI" - #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" @@ -2624,14 +2635,3 @@ msgstr "" #~ msgstr "" #~ "suficiente poder para todo el circuito y presiona reset (después de " #~ "expulsar CIRCUITPY).\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" - -#, fuzzy -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " -#~ "unidad de almacenamiento CIRCUITPY:\n" diff --git a/locale/fil.po b/locale/fil.po index 53ca5d22a9a3b..0755ad8a7ae11 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -333,7 +333,7 @@ msgstr "Hindi sapat ang magagamit na pins" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Mali ang pins" @@ -350,12 +350,12 @@ msgid "bytes > 8 bits not supported" msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx at rx hindi pwedeng parehas na None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Nabigong ilaan ang RX buffer" @@ -364,12 +364,12 @@ msgid "Could not initialize UART" msgstr "Hindi ma-initialize ang UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Walang RX pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Walang TX pin" @@ -773,7 +773,7 @@ msgstr "Mali ang UUID string length" msgid "Invalid UUID parameter" msgstr "Mali ang UUID parameter" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Lahat ng I2C peripherals ginagamit" @@ -786,19 +786,19 @@ msgstr "Lahat ng SPI peripherals ay ginagamit" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "Mali ang buffer size" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" msgstr "Odd na parity ay hindi supportado" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "busio.UART hindi available" @@ -2600,18 +2600,35 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." - #~ msgid "Can not add Characteristic." #~ msgstr "Hindi mabasa and Characteristic." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." + #~ msgid "Can not apply device name in the stack." #~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "ang palette ay dapat 32 bytes ang haba" + #~ msgid "Can not encode UUID, to check length." #~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " +#~ "drive:\n" + #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Maaring i-encode ang UUID sa advertisement packet." @@ -2621,13 +2638,6 @@ msgstr "" #~ msgid "Can not add Service." #~ msgstr "Hindi maidaragdag ang serbisyo." -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." - -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "ang palette ay dapat 32 bytes ang haba" - #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" @@ -2640,13 +2650,3 @@ msgstr "" #~ msgstr "" #~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " #~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" - -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " -#~ "drive:\n" diff --git a/locale/fr.po b/locale/fr.po index 61781fe5bd359..6c41ffaea1130 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: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -330,7 +330,7 @@ msgstr "Pas assez de broches disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Broches invalides" @@ -347,12 +347,12 @@ msgid "bytes > 8 bits not supported" msgstr "octets > 8 bits non supporté" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx et rx ne peuvent être None tous les deux" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Echec de l'allocation du tampon RX" @@ -361,12 +361,12 @@ msgid "Could not initialize UART" msgstr "L'UART n'a pu être initialisé" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Pas de broche RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Pas de broche TX" @@ -771,7 +771,7 @@ msgstr "Longeur de chaîne UUID invalide" msgid "Invalid UUID parameter" msgstr "Paramètre UUID invalide" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Tous les périphériques I2C sont utilisés" @@ -786,21 +786,21 @@ msgstr "Tous les périphériques SPI sont utilisés" msgid "error = 0x%08lX" msgstr "erreur = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" msgstr "longueur de tampon invalide" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" msgstr "parité impaire non supportée" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART n'est pas disponible" @@ -2641,20 +2641,12 @@ msgstr "" #~ msgstr "" #~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" - -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." - -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2663,19 +2655,27 @@ msgstr "" #~ "assez de puissance pour l'ensemble du circuit et appuyez sur " #~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." + +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" + +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." #~ msgid "Can not apply device name in the stack." #~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" + #~ msgid "Cannot apply GAP parameters." #~ msgstr "Impossible d'appliquer les paramètres GAP" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size doit être une puissance de 2" - -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être une displayio.Palette" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" diff --git a/locale/it_IT.po b/locale/it_IT.po index 4cb328319d408..3003d8c915d18 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -334,7 +334,7 @@ msgstr "Non sono presenti abbastanza pin" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Pin non validi" @@ -351,12 +351,12 @@ msgid "bytes > 8 bits not supported" msgstr "byte > 8 bit non supportati" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx e rx non possono essere entrambi None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Impossibile allocare buffer RX" @@ -365,12 +365,12 @@ msgid "Could not initialize UART" msgstr "Impossibile inizializzare l'UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Nessun pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Nessun pin TX" @@ -774,7 +774,7 @@ msgstr "Lunghezza della stringa UUID non valida" msgid "Invalid UUID parameter" msgstr "Parametro UUID non valido" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Tutte le periferiche I2C sono in uso" @@ -787,21 +787,21 @@ msgstr "Tutte le periferiche SPI sono in uso" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" msgstr "lunghezza del buffer non valida" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" msgstr "operazione I2C non supportata" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART non ancora implementato" @@ -2607,15 +2607,29 @@ msgstr "" #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossibile applicare i parametri GAP." +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " +#~ "CIRCUITPY:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " +#~ "Whoops!\n" #~ msgid "Cannot set PPCP parameters." #~ msgstr "Impossibile impostare i parametri PPCP." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." + #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " #~ "CIRCUITPY).\n" @@ -2623,28 +2637,14 @@ msgstr "" #~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " #~ "espulso CIRCUITPY).\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." - -#~ msgid "Can not add Characteristic." -#~ msgstr "Non è possibile aggiungere Characteristic." - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." - #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." + #~ msgid "Can not add Service." #~ msgstr "Non è possibile aggiungere Service." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " -#~ "CIRCUITPY:\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " -#~ "Whoops!\n" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 1b35b48247537..56810874abb68 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-26 20:49+0100\n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -329,7 +329,7 @@ msgstr "Não há pinos suficientes disponíveis" #: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:82 +#: ports/nrf/common-hal/busio/I2C.c:84 msgid "Invalid pins" msgstr "Pinos inválidos" @@ -346,12 +346,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits não suportado" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:106 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "TX e RX não podem ser ambos" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:140 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Falha ao alocar buffer RX" @@ -360,12 +360,12 @@ msgid "Could not initialize UART" msgstr "Não foi possível inicializar o UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:185 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Nenhum pino RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:220 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Nenhum pino TX" @@ -767,7 +767,7 @@ msgstr "" msgid "Invalid UUID parameter" msgstr "Parâmetro UUID inválido" -#: ports/nrf/common-hal/busio/I2C.c:96 +#: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" msgstr "Todos os periféricos I2C estão em uso" @@ -780,21 +780,21 @@ msgstr "Todos os periféricos SPI estão em uso" msgid "error = 0x%08lX" msgstr "erro = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:110 +#: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" msgstr "Arquivo inválido" -#: ports/nrf/common-hal/busio/UART.c:114 +#: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" msgstr "I2C operação não suportada" -#: ports/nrf/common-hal/busio/UART.c:346 ports/nrf/common-hal/busio/UART.c:350 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:366 ports/nrf/common-hal/busio/UART.c:371 -#: ports/nrf/common-hal/busio/UART.c:376 ports/nrf/common-hal/busio/UART.c:380 -#: ports/nrf/common-hal/busio/UART.c:388 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "busio.UART não disponível" @@ -2557,32 +2557,32 @@ msgid "" "exit safe mode.\n" msgstr "" +#~ msgid "Can not add Service." +#~ msgstr "Não é possível adicionar o serviço." + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" + #~ msgid "Can not apply device name in the stack." #~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Can not add Characteristic." -#~ msgstr "Não é possível adicionar Característica." +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possível aplicar parâmetros GAP." #~ msgid "Invalid Service type" #~ msgstr "Tipo de serviço inválido" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Não é possível aplicar parâmetros GAP." - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." #~ msgid "Can not query for the device address." #~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possível adicionar Característica." -#~ msgid "Can not add Service." -#~ msgstr "Não é possível adicionar o serviço." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." From 19db8866459dbad728318fca5eec1d7ff1cadf00 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 9 Jan 2019 10:19:07 -0800 Subject: [PATCH 080/153] Support the display on the pyportal. Also fix #1390, reload during sleep broken. --- ports/atmel-samd/boards/pyportal/board.c | 79 +++++++++++++++++++ .../boards/pyportal/mpconfigboard.h | 2 + ports/atmel-samd/boards/pyportal/pins.c | 3 + .../common-hal/displayio/FourWire.c | 6 ++ .../common-hal/microcontroller/__init__.c | 12 +++ ports/atmel-samd/mphalport.c | 3 +- ports/nrf/mphalport.c | 3 +- 7 files changed, 106 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index 7599f02b8efee..c361b5659543c 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -28,7 +28,85 @@ #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/mipi_constants.h" + +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0xEF, 3, 0x03, 0x80, 0x02, + 0xCF, 3, 0x00, 0xC1, 0x30, + 0xED, 4, 0x64, 0x03, 0x12, 0x81, + 0xE8, 3, 0x85, 0x00, 0x78, + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, + 0xF7, 1, 0x20, + 0xEA, 2, 0x00, 0x00, + 0xc0, 1, 0x23, // Power control VRH[5:0] + 0xc1, 1, 0x10, // Power control SAP[2:0];BT[3:0] + 0xc5, 2, 0x3e, 0x28, // VCM control + 0xc7, 1, 0x86, // VCM control2 + 0x36, 1, 0x48, // Memory Access Control + 0x37, 1, 0x00, // Vertical scroll zero + 0x3a, 1, 0x55, // COLMOD: Pixel Format Set + 0xb1, 2, 0x00, 0x18, // Frame Rate Control (In Normal Mode/Full Colors) + 0xb6, 3, 0x08, 0x82, 0x27, // Display Function Control + 0xF2, 1, 0x00, // 3Gamma Function Disable + 0x26, 1, 0x01, // Gamma curve selected + 0xe0, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma + 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, + 0xe1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma + 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, + 0x11, DELAY, 120, // Exit Sleep + 0x29, DELAY, 120, // Display on +}; + + void board_init(void) { + board_display_obj.base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(&board_display_obj, + &pin_PA13, // Clock + &pin_PA12, // Data + &pin_PB09, // Command or data + &pin_PB06, // Chip select + &pin_PB05, // Reset + 240, // Width + 320, // Height + 0, // column start + 0, // row start + 16, // Color depth + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START); // Write memory command + + uint32_t i = 0; + common_hal_displayio_fourwire_begin_transaction(&board_display_obj); + while (i < sizeof(display_init_sequence)) { + uint8_t *cmd = display_init_sequence + i; + uint8_t data_size = *(cmd + 1); + bool delay = (data_size & DELAY) != 0; + data_size &= ~DELAY; + uint8_t *data = cmd + 2; + common_hal_displayio_fourwire_send(&board_display_obj, true, cmd, 1); + common_hal_displayio_fourwire_send(&board_display_obj, false, data, data_size); + if (delay) { + data_size++; + uint16_t delay_length_ms = *(cmd + 1 + data_size); + if (delay_length_ms == 255) { + delay_length_ms = 500; + } + uint64_t start = ticks_ms; + while (ticks_ms - start < delay_length_ms) {} + } else { + uint64_t start = ticks_ms; + while (ticks_ms - start < 10) {} + } + i += 2 + data_size; + } + common_hal_displayio_fourwire_end_transaction(&board_display_obj); } bool board_requests_safe_mode(void) { @@ -36,4 +114,5 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { + common_hal_displayio_fourwire_show(&board_display_obj, NULL); } diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.h b/ports/atmel-samd/boards/pyportal/mpconfigboard.h index 16b104297192f..847e2ba7641c1 100644 --- a/ports/atmel-samd/boards/pyportal/mpconfigboard.h +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.h @@ -38,3 +38,5 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 + +#define CIRCUITPY_DISPLAYIO (1) diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index 84ecbaffff58f..7d4bc2a46a2d6 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -1,5 +1,6 @@ #include "shared-bindings/board/__init__.h" +#include "boards/board.h" #include "board_busses.h" // This mapping only includes functional names because pins broken @@ -51,5 +52,7 @@ STATIC const mp_map_elem_t board_global_dict_table[] = { { 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_DISPLAY), MP_ROM_PTR(&board_display_obj)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.c b/ports/atmel-samd/common-hal/displayio/FourWire.c index 6c3b75a85b4a5..b550f1c907803 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.c +++ b/ports/atmel-samd/common-hal/displayio/FourWire.c @@ -40,6 +40,8 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command) { common_hal_busio_spi_construct(&self->bus, clock, data, mp_const_none); + common_hal_busio_spi_never_reset(&self->bus); + common_hal_digitalio_digitalinout_construct(&self->command, command); common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); @@ -48,6 +50,10 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, common_hal_digitalio_digitalinout_construct(&self->reset, reset); common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); + never_reset_pin_number(reset->number); + self->width = width; self->height = height; self->color_depth = color_depth; diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index 0ca3a083555b6..d1d0eae8db485 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -252,6 +252,18 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { #if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17) { MP_ROM_QSTR(MP_QSTR_PB17), MP_ROM_PTR(&pin_PB17) }, #endif +#if defined(PIN_PB18) && !defined(IGNORE_PIN_PB18) + { MP_ROM_QSTR(MP_QSTR_PB18), MP_ROM_PTR(&pin_PB18) }, +#endif +#if defined(PIN_PB19) && !defined(IGNORE_PIN_PB19) + { MP_ROM_QSTR(MP_QSTR_PB19), MP_ROM_PTR(&pin_PB19) }, +#endif +#if defined(PIN_PB20) && !defined(IGNORE_PIN_PB20) + { MP_ROM_QSTR(MP_QSTR_PB20), MP_ROM_PTR(&pin_PB20) }, +#endif +#if defined(PIN_PB21) && !defined(IGNORE_PIN_PB21) + { MP_ROM_QSTR(MP_QSTR_PB21), MP_ROM_PTR(&pin_PB21) }, +#endif #if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22) { MP_ROM_QSTR(MP_QSTR_PB22), MP_ROM_PTR(&pin_PB22) }, #endif diff --git a/ports/atmel-samd/mphalport.c b/ports/atmel-samd/mphalport.c index ac5b0fbcab5f0..5c34a576a8392 100644 --- a/ports/atmel-samd/mphalport.c +++ b/ports/atmel-samd/mphalport.c @@ -57,7 +57,8 @@ void mp_hal_delay_ms(mp_uint_t delay) { MICROPY_VM_HOOK_LOOP #endif // Check to see if we've been CTRL-Ced by autoreload or the user. - if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))) { + if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) || + MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { break; } duration = (ticks_ms - start_tick); diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c index 73f38bada84d8..ea864e7ceb5a5 100644 --- a/ports/nrf/mphalport.c +++ b/ports/nrf/mphalport.c @@ -42,7 +42,8 @@ void mp_hal_delay_ms(mp_uint_t delay) { MICROPY_VM_HOOK_LOOP #endif // Check to see if we've been CTRL-Ced by autoreload or the user. - if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))) { + if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) || + MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { break; } duration = (ticks_ms - start_tick); From 6594937a6504727940903fe1080e7aab9e89145d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 10 Jan 2019 17:22:08 -0800 Subject: [PATCH 081/153] Support rendering groups inside groups --- shared-module/displayio/Group.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 655376da0a522..93ac3596438b1 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -71,6 +71,10 @@ bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, ui if (displayio_sprite_get_pixel(layer, x, y, pixel)) { return true; } + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + if (displayio_group_get_pixel(layer, x, y, pixel)) { + return true; + } } // TODO: Tiled layer } From c80b5f4f4c2df7ca5175792ccbf0572c4d937b7e Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 10 Jan 2019 20:56:48 -0500 Subject: [PATCH 082/153] make translate --- locale/circuitpython.pot | 2 +- locale/de_DE.po | 54 +++++++++++++------------- locale/es.po | 84 ++++++++++++++++++++-------------------- locale/fil.po | 84 ++++++++++++++++++++-------------------- locale/fr.po | 76 ++++++++++++++++++------------------ locale/it_IT.po | 74 +++++++++++++++++------------------ locale/pt_BR.po | 40 +++++++++---------- 7 files changed, 207 insertions(+), 207 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index b2ed435abd193..b18108661dcd5 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: 2019-01-09 14:00-0500\n" +"POT-Creation-Date: 2019-01-10 20:56-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/locale/de_DE.po b/locale/de_DE.po index 4a2244f6e42d5..691d83762413a 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-09 14:00-0500\n" +"POT-Creation-Date: 2019-01-10 20:56-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -2682,25 +2682,23 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" +#~ msgid "Invalid UUID string length" +#~ msgstr "Ungültige UUID-Stringlänge" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Ungültiger UUID-Parameter" -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2709,20 +2707,22 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Ungültiger UUID-Parameter" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#~ msgid "Invalid UUID string length" -#~ msgstr "Ungültige UUID-Stringlänge" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" diff --git a/locale/es.po b/locale/es.po index b41231e5f2f97..f9debc7f4a891 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-09 14:00-0500\n" +"POT-Creation-Date: 2019-01-10 20:56-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -2698,62 +2698,62 @@ msgid "" "exit safe mode.\n" msgstr "" -#, fuzzy -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " -#~ "unidad de almacenamiento CIRCUITPY:\n" +#~ msgid "Invalid UUID string length" +#~ msgstr "Longitud de string UUID inválida" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parámetro UUID inválido" -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "suficiente poder para todo el circuito y presiona reset (después de " -#~ "expulsar CIRCUITPY).\n" +#~ msgid "Wrong address length" +#~ msgstr "Longitud de address erronea" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "No se pueden establecer los parámetros PPCP." +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Numero erroneo de bytes dados" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Baud rate demasiado alto para este periférico SPI" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "No se puede codificar el UUID, para revisar la longitud." -#~ msgid "Can not add Service." -#~ msgstr "No se puede agregar el Servicio." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." #~ msgid "Invalid Service type" #~ msgstr "Tipo de Servicio inválido" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." +#~ msgid "Can not add Service." +#~ msgstr "No se puede agregar el Servicio." -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" -#~ msgid "Wrong number of bytes provided" -#~ msgstr "Numero erroneo de bytes dados" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." -#~ msgid "Wrong address length" -#~ msgstr "Longitud de address erronea" +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "suficiente poder para todo el circuito y presiona reset (después de " +#~ "expulsar CIRCUITPY).\n" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parámetro UUID inválido" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" -#~ msgid "Invalid UUID string length" -#~ msgstr "Longitud de string UUID inválida" +#, fuzzy +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " +#~ "unidad de almacenamiento CIRCUITPY:\n" diff --git a/locale/fil.po b/locale/fil.po index 1c2a321361ff0..ffcdef1dc1d9c 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-09 14:00-0500\n" +"POT-Creation-Date: 2019-01-10 20:56-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -2715,62 +2715,62 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " -#~ "drive:\n" +#~ msgid "Invalid UUID string length" +#~ msgstr "Mali ang UUID string length" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Mali ang UUID parameter" -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " -#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" +#~ msgid "Wrong address length" +#~ msgstr "Mali ang address length" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Hindi ma-set ang PPCP parameters." +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Mali ang bilang ng bytes" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "ang palette ay dapat 32 bytes ang haba" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." -#~ msgid "Can not add Service." -#~ msgstr "Hindi maidaragdag ang serbisyo." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." #~ msgid "Invalid Service type" #~ msgstr "Mali ang tipo ng serbisyo" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." +#~ msgid "Can not add Service." +#~ msgstr "Hindi maidaragdag ang serbisyo." -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "ang palette ay dapat 32 bytes ang haba" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" -#~ msgid "Wrong number of bytes provided" -#~ msgstr "Mali ang bilang ng bytes" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." -#~ msgid "Wrong address length" -#~ msgstr "Mali ang address length" +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " +#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Mali ang UUID parameter" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" -#~ msgid "Invalid UUID string length" -#~ msgstr "Mali ang UUID string length" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " +#~ "drive:\n" diff --git a/locale/fr.po b/locale/fr.po index 3b369d6f505b5..4cca9d8d4b063 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: 2019-01-09 14:00-0500\n" +"POT-Creation-Date: 2019-01-10 20:56-0500\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -2744,60 +2744,60 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer denouveau pour quitter de le mode sans-échec.\n" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être une displayio.Palette" +#~ msgid "Invalid UUID string length" +#~ msgstr "Longeur de chaîne UUID invalide" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size doit être une puissance de 2" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Paramètre UUID invalide" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" +#~ msgid "Wrong address length" +#~ msgstr "Mauvaise longueur d'adresse" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#, fuzzy +#~ msgid "Wrong number of bytes provided" +#~ msgstr "mauvais nombre d'octets fourni'" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" #~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" -#~ "assez de puissance pour l'ensemble du circuit et appuyez sur " -#~ "'reset' (après avoir éjecter CIRCUITPY).\n" - -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" #~ msgid "Invalid Service type" #~ msgstr "Type de service invalide" -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." + +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" #~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" #~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" +#~ "assez de puissance pour l'ensemble du circuit et appuyez sur " +#~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" -#, fuzzy -#~ msgid "Wrong number of bytes provided" -#~ msgstr "mauvais nombre d'octets fourni'" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" -#~ msgid "Wrong address length" -#~ msgstr "Mauvaise longueur d'adresse" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Paramètre UUID invalide" +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" -#~ msgid "Invalid UUID string length" -#~ msgstr "Longeur de chaîne UUID invalide" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" diff --git a/locale/it_IT.po b/locale/it_IT.po index f1e43712a927b..d08d2d3568c3c 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-09 14:00-0500\n" +"POT-Creation-Date: 2019-01-10 20:56-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -2713,28 +2713,30 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " -#~ "Whoops!\n" +#~ msgid "Invalid UUID string length" +#~ msgstr "Lunghezza della stringa UUID non valida" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " -#~ "CIRCUITPY:\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parametro UUID non valido" -#~ msgid "Can not add Service." -#~ msgstr "Non è possibile aggiungere Service." +#, fuzzy +#~ msgid "Wrong number of bytes provided" +#~ msgstr "numero di argomenti errato" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2743,27 +2745,25 @@ msgstr "" #~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " #~ "espulso CIRCUITPY).\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." - -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossibile applicare i parametri GAP." +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo di servizio non valido" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." -#, fuzzy -#~ msgid "Wrong number of bytes provided" -#~ msgstr "numero di argomenti errato" +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parametro UUID non valido" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " +#~ "CIRCUITPY:\n" -#~ msgid "Invalid UUID string length" -#~ msgstr "Lunghezza della stringa UUID non valida" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " +#~ "Whoops!\n" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 3974fe50e8ced..955a8e1981de8 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-09 14:00-0500\n" +"POT-Creation-Date: 2019-01-10 20:56-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -2667,32 +2667,32 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Can not add Service." -#~ msgstr "Não é possível adicionar o serviço." - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parâmetro UUID inválido" -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" #~ msgid "Cannot apply GAP parameters." #~ msgstr "Não é possível aplicar parâmetros GAP." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parâmetro UUID inválido" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" + +#~ msgid "Can not add Service." +#~ msgstr "Não é possível adicionar o serviço." From c863ad442fe826125fffc93a4077aa13c124c3b5 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 10 Jan 2019 21:32:21 -0500 Subject: [PATCH 083/153] Remove duplicate msg from pt_BR.po --- locale/ID.po | 293 +++++++++++++++++++++++++++------------ locale/circuitpython.pot | 13 +- locale/de_DE.po | 13 +- locale/en_US.po | 13 +- locale/es.po | 14 +- locale/fil.po | 14 +- locale/fr.po | 13 +- locale/it_IT.po | 13 +- locale/pt_BR.po | 52 +++---- 9 files changed, 289 insertions(+), 149 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 405b3a0e3ff8f..952e12d4d3ede 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 11:05-0800\n" +"POT-Creation-Date: 2019-01-10 21:32-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -409,17 +409,20 @@ msgstr "Channel EXTINT sedang digunakan" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "Muncul dari PulseIn yang kosong" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "index keluar dari jangkauan" @@ -659,123 +662,185 @@ msgstr "fungsionalitas AnalogOut tidak didukung" msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l" -#: ports/nrf/common-hal/bleio/Adapter.c:125 -#, c-format -msgid "Failed to change softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:110 +#, fuzzy +msgid "Failed to change softdevice state" msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:135 -#, c-format -msgid "Failed to get softdevice state, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:119 +#, fuzzy +msgid "Failed to get softdevice state" msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Adapter.c:155 -#, c-format -msgid "Failed to get local address, error: 0x%08lX" +#: ports/nrf/common-hal/bleio/Adapter.c:138 +#, fuzzy +msgid "Failed to get local address" msgstr "Gagal untuk mendapatkan alamat lokal, error: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:52 -#, c-format -msgid "Failed to write gatts value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Broadcaster.c:48 +msgid "interval not in range 0.0020 to 10.24" +msgstr "" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:58 +#: ports/nrf/common-hal/bleio/Peripheral.c:56 +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:83 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Broadcaster.c:96 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:59 +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:89 +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:76 -#, c-format -msgid "Failed to notify attribute value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:106 +#, fuzzy, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:132 +#, fuzzy, c-format +msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:91 -#, c-format -msgid "Failed to read attribute value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:144 +#, fuzzy, c-format +msgid "Failed to read attribute value, err %0x04x" msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:119 -#: ports/nrf/common-hal/bleio/Device.c:272 -#: ports/nrf/common-hal/bleio/Device.c:307 -#, c-format -msgid "Failed to acquire mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:126 -#, c-format -msgid "Failed to write attribute value, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:178 +#, fuzzy, c-format +msgid "Failed to write attribute value, err 0x%04x" msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:138 -#: ports/nrf/common-hal/bleio/Device.c:284 -#: ports/nrf/common-hal/bleio/Device.c:319 -#: ports/nrf/common-hal/bleio/Device.c:354 -#: ports/nrf/common-hal/bleio/Device.c:391 -#, c-format -msgid "Failed to release mutex, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:81 -#: ports/nrf/common-hal/bleio/Device.c:114 -msgid "Can not fit data into the advertisment packet" +#: ports/nrf/common-hal/bleio/Characteristic.c:251 +#: ports/nrf/common-hal/bleio/Characteristic.c:284 +msgid "bad GATT role" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:80 +#: ports/nrf/common-hal/bleio/Device.c:112 +#, fuzzy +msgid "Data too large for the advertisement packet" msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" -#: ports/nrf/common-hal/bleio/Device.c:266 -#, fuzzy, c-format -msgid "Failed to discover serivices, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:262 +#, fuzzy +msgid "Failed to discover services" msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:403 -#: ports/nrf/common-hal/bleio/Scanner.c:76 -#, c-format -msgid "Failed to continue scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 +#, fuzzy +msgid "Failed to acquire mutex" +msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 +#, fuzzy +msgid "Failed to release mutex" +msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:387 +#, fuzzy +msgid "Failed to continue scanning" msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:436 -#, c-format -msgid "Failed to connect, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:419 +#, fuzzy +msgid "Failed to connect:" msgstr "Gagal untuk menyambungkan, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:513 -#, c-format -msgid "Failed to add service, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:489 +#, fuzzy +msgid "Failed to add service" msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:531 -#, c-format -msgid "Failed to start advertisment, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:506 +#, fuzzy +msgid "Failed to start advertising" msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:549 -#, c-format -msgid "Failed to stop advertisment, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Device.c:523 +#, fuzzy +msgid "Failed to stop advertising" msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:575 -#: ports/nrf/common-hal/bleio/Scanner.c:103 -#, c-format -msgid "Failed to start scanning, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:548 +#, fuzzy +msgid "Failed to start scanning" msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:592 -#, c-format -msgid "Failed to create mutex, status: 0x%0xlX" +#: ports/nrf/common-hal/bleio/Device.c:564 +#, fuzzy +msgid "Failed to create mutex" msgstr "Gagal untuk membuat mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Service.c:83 -#, c-format -msgid "Failed to add characteristic, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Peripheral.c:304 +#, fuzzy, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Scanner.c:75 +#, fuzzy, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Scanner.c:101 +#, fuzzy, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Service.c:88 +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/UUID.c:97 -#, c-format -msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +#: ports/nrf/common-hal/bleio/Service.c:92 +msgid "Characteristic already in use by another Service." +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:54 +#, fuzzy, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/UUID.c:102 -msgid "Invalid UUID string length" -msgstr "Panjang string UUID tidak valid" +#: ports/nrf/common-hal/bleio/UUID.c:73 +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c:109 -#: shared-bindings/bleio/Characteristic.c:125 -#: shared-bindings/bleio/Service.c:105 -msgid "Invalid UUID parameter" -msgstr "Parameter UUID tidak valid" +#: ports/nrf/common-hal/bleio/UUID.c:88 +msgid "Unexpected nrfx uuid type" +msgstr "" #: ports/nrf/common-hal/busio/I2C.c:98 msgid "All I2C peripherals are in use" @@ -806,9 +871,9 @@ msgstr "Parity ganjil tidak didukung" msgid "busio.UART not available" msgstr "busio.UART tidak tersedia" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 -#, c-format -msgid "Can not get temperature. status: 0x%02x" +#: ports/nrf/common-hal/microcontroller/Processor.c:48 +#, fuzzy +msgid "Cannot get temperature" msgstr "Tidak bisa mendapatkan temperatur. status: 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 @@ -1946,7 +2011,7 @@ msgstr "" msgid "memory allocation failed, allocating %u bytes" msgstr "" -#: py/runtime.c:1609 +#: py/runtime.c:1620 msgid "maximum recursion depth exceeded" msgstr "" @@ -2096,12 +2161,28 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:101 -msgid "Wrong address length" +#: shared-bindings/bleio/Address.c:119 +#, c-format +msgid "Address is not %d bytes long or is in wrong format" +msgstr "" + +#: shared-bindings/bleio/Address.c:126 +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "buffers harus mempunyai panjang yang sama" + +#: shared-bindings/bleio/Characteristic.c:81 +#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/Address.c:107 -msgid "Wrong number of bytes provided" +#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#, fuzzy +msgid "buffer_size must be >= 1" +msgstr "buffers harus mempunyai panjang yang sama" + +#: shared-bindings/bleio/CharacteristicBuffer.c:72 +msgid "Expected a Characteristic" msgstr "" #: shared-bindings/bleio/Device.c:210 @@ -2120,6 +2201,40 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" +#: shared-bindings/bleio/Peripheral.c:111 +msgid "services includes an object that is not a Service" +msgstr "" + +#: shared-bindings/bleio/Peripheral.c:124 +#, fuzzy +msgid "name must be a string" +msgstr "keyword harus berupa string" + +#: shared-bindings/bleio/Service.c:90 +msgid "characteristics includes an object that is not a Characteristic" +msgstr "" + +#: shared-bindings/bleio/Service.c:96 +msgid "Characteristic UUID doesn't match Service UUID" +msgstr "" + +#: shared-bindings/bleio/UUID.c:66 +msgid "UUID integer value not in range 0 to 0xffff" +msgstr "" + +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:79 +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "buffers harus mempunyai panjang yang sama" + +#: shared-bindings/bleio/UUID.c:120 +msgid "not a 128-bit UUID" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2570,6 +2685,12 @@ msgid "" "exit safe mode.\n" msgstr "" +#~ msgid "Invalid UUID string length" +#~ msgstr "Panjang string UUID tidak valid" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parameter UUID tidak valid" + #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" #~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index b18108661dcd5..5c85d09a8035a 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: 2019-01-10 20:56-0500\n" +"POT-Creation-Date: 2019-01-10 21:32-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -400,17 +400,20 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "" @@ -670,13 +673,13 @@ msgid "Data too large for advertisement packet" msgstr "" #: ports/nrf/common-hal/bleio/Broadcaster.c:83 -#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 #, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 -#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 #, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "" @@ -775,7 +778,7 @@ msgstr "" msgid "Failed to create mutex" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#: ports/nrf/common-hal/bleio/Peripheral.c:304 #, c-format msgid "Failed to add service, err 0x%04x" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 88471e09073d5..47098b66acb35 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 20:56-0500\n" +"POT-Creation-Date: 2019-01-10 21:32-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -404,17 +404,20 @@ msgstr "EXTINT Kanal wird benutzt" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "Konnte keine RX Buffer mit %d allozieren" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "pop von einem leeren PulseIn" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "index außerhalb der Reichweite" @@ -680,13 +683,13 @@ msgid "Data too large for advertisement packet" msgstr "Daten können nicht in das advertisement packet eingefügt werden." #: ports/nrf/common-hal/bleio/Broadcaster.c:83 -#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 #, fuzzy, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "Kann advertisement nicht starten. Status: 0x%02x" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 -#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 #, fuzzy, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" @@ -796,7 +799,7 @@ msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" msgid "Failed to create mutex" msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" -#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#: ports/nrf/common-hal/bleio/Peripheral.c:304 #, fuzzy, c-format msgid "Failed to add service, err 0x%04x" msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" diff --git a/locale/en_US.po b/locale/en_US.po index ed29bd0af219a..ee47b08eab9bb 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-09 14:00-0500\n" +"POT-Creation-Date: 2019-01-10 21:31-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -400,17 +400,20 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "" @@ -670,13 +673,13 @@ msgid "Data too large for advertisement packet" msgstr "" #: ports/nrf/common-hal/bleio/Broadcaster.c:83 -#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 #, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 -#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 #, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "" @@ -775,7 +778,7 @@ msgstr "" msgid "Failed to create mutex" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#: ports/nrf/common-hal/bleio/Peripheral.c:304 #, c-format msgid "Failed to add service, err 0x%04x" msgstr "" diff --git a/locale/es.po b/locale/es.po index be9f47c9deba4..11827e0b622be 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 20:56-0500\n" +"POT-Creation-Date: 2019-01-10 21:32-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -406,17 +406,20 @@ msgstr "El canal EXTINT ya está siendo utilizado" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "Falló la asignación del buffer RX de %d bytes" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "pop de un PulseIn vacío" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "index fuera de rango" @@ -681,13 +684,13 @@ msgid "Data too large for advertisement packet" msgstr "Los datos no caben en el paquete de anuncio." #: ports/nrf/common-hal/bleio/Broadcaster.c:83 -#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 #, fuzzy, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "No se puede inicar el anuncio. status: 0x%02x" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 -#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 #, fuzzy, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "No se puede detener el anuncio. status: 0x%02x" @@ -797,7 +800,7 @@ msgstr "No se puede iniciar el escaneo. status: 0x%02x" msgid "Failed to create mutex" msgstr "No se puede leer el valor del atributo. status 0x%02x" -#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#: ports/nrf/common-hal/bleio/Peripheral.c:304 #, fuzzy, c-format msgid "Failed to add service, err 0x%04x" msgstr "No se puede detener el anuncio. status: 0x%02x" @@ -2710,7 +2713,6 @@ msgstr "" #~ msgid "Wrong number of bytes provided" #~ msgstr "Numero erroneo de bytes dados" - #~ msgid "Cannot apply GAP parameters." #~ msgstr "No se pueden aplicar los parámetros GAP." diff --git a/locale/fil.po b/locale/fil.po index a25f6dfb0d7eb..5daa673f70058 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 20:56-0500\n" +"POT-Creation-Date: 2019-01-10 21:32-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -404,17 +404,20 @@ msgstr "Ginagamit na ang EXTINT channel" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "Nabigong ilaan ang RX buffer ng %d bytes" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "pop mula sa walang laman na PulseIn" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "index wala sa sakop" @@ -681,13 +684,13 @@ msgid "Data too large for advertisement packet" msgstr "Hindi makasya ang data sa loob ng advertisement packet" #: ports/nrf/common-hal/bleio/Broadcaster.c:83 -#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 #, fuzzy, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 -#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 #, fuzzy, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "Hindi mahinto ang advertisement, status: 0x%08lX" @@ -797,7 +800,7 @@ msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX" msgid "Failed to create mutex" msgstr "Hindi matagumpay ang pagbuo ng mutex, status: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#: ports/nrf/common-hal/bleio/Peripheral.c:304 #, fuzzy, c-format msgid "Failed to add service, err 0x%04x" msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX" @@ -2727,7 +2730,6 @@ msgstr "" #~ msgid "Wrong number of bytes provided" #~ msgstr "Mali ang bilang ng bytes" - #~ msgid "Cannot apply GAP parameters." #~ msgstr "Hindi ma-apply ang GAP parameters." diff --git a/locale/fr.po b/locale/fr.po index af90c6f6f8735..b27cfeb7996ce 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: 2019-01-10 20:56-0500\n" +"POT-Creation-Date: 2019-01-10 21:32-0500\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -402,17 +402,20 @@ msgstr "Canal EXTINT déjà utilisé" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "Echec de l'allocation de %d octets du tampon RX" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "'pop' d'une entrée PulseIn vide" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "index hors gamme" @@ -678,13 +681,13 @@ msgid "Data too large for advertisement packet" msgstr "" #: ports/nrf/common-hal/bleio/Broadcaster.c:83 -#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 #, fuzzy, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "Impossible de commencer à scanner, statut: 0x%0xlX" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 -#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 #, fuzzy, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "Echec de l'ajout de service, statut: 0x%08lX" @@ -793,7 +796,7 @@ msgstr "Impossible de commencer à scanner, statut: 0x%0xlX" msgid "Failed to create mutex" msgstr "Echec de la création de mutex, statut: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#: ports/nrf/common-hal/bleio/Peripheral.c:304 #, fuzzy, c-format msgid "Failed to add service, err 0x%04x" msgstr "Echec de l'ajout de service, statut: 0x%08lX" diff --git a/locale/it_IT.po b/locale/it_IT.po index cbb497e570d9e..9b54d5dc9ae3c 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 20:56-0500\n" +"POT-Creation-Date: 2019-01-10 21:32-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -406,17 +406,20 @@ msgstr "Canale EXTINT già in uso" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "Fallita allocazione del buffer RX di %d byte" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "pop sun un PulseIn vuoto" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "indice fuori intervallo" @@ -680,13 +683,13 @@ msgid "Data too large for advertisement packet" msgstr "Impossibile inserire dati nel pacchetto di advertisement." #: ports/nrf/common-hal/bleio/Broadcaster.c:83 -#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 #, fuzzy, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "Impossibile avviare advertisement. status: 0x%02x" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 -#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 #, fuzzy, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "Impossibile fermare advertisement. status: 0x%02x" @@ -796,7 +799,7 @@ msgstr "Impossible iniziare la scansione. status: 0x%02x" msgid "Failed to create mutex" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#: ports/nrf/common-hal/bleio/Peripheral.c:304 #, fuzzy, c-format msgid "Failed to add service, err 0x%04x" msgstr "Impossibile fermare advertisement. status: 0x%02x" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 974bdb41b8861..85fe90909cd07 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 20:56-0500\n" +"POT-Creation-Date: 2019-01-10 21:32-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -400,17 +400,20 @@ msgstr "Canal EXTINT em uso" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#: ports/nrf/common-hal/pulseio/PulseIn.c:129 #, c-format msgid "Failed to allocate RX buffer of %d bytes" msgstr "Falha ao alocar buffer RX de %d bytes" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +#: ports/nrf/common-hal/pulseio/PulseIn.c:254 msgid "pop from an empty PulseIn" msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 -#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 +#: ports/nrf/common-hal/pulseio/PulseIn.c:241 py/obj.c:422 msgid "index out of range" msgstr "Índice fora do intervalo" @@ -673,13 +676,13 @@ msgid "Data too large for advertisement packet" msgstr "Não é possível ajustar dados no pacote de anúncios." #: ports/nrf/common-hal/bleio/Broadcaster.c:83 -#: ports/nrf/common-hal/bleio/Peripheral.c:320 +#: ports/nrf/common-hal/bleio/Peripheral.c:324 #, fuzzy, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "Não é possível iniciar o anúncio. status: 0x%02x" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 -#: ports/nrf/common-hal/bleio/Peripheral.c:332 +#: ports/nrf/common-hal/bleio/Peripheral.c:336 #, fuzzy, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "Não pode parar propaganda. status: 0x%02x" @@ -787,7 +790,7 @@ msgstr "Não é possível iniciar o anúncio. status: 0x%02x" msgid "Failed to create mutex" msgstr "Não é possível ler o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Peripheral.c:300 +#: ports/nrf/common-hal/bleio/Peripheral.c:304 #, fuzzy, c-format msgid "Failed to add service, err 0x%04x" msgstr "Não pode parar propaganda. status: 0x%02x" @@ -2667,35 +2670,32 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parâmetro UUID inválido" - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possível adicionar Característica." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Não é possível aplicar parâmetros GAP." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." #~ msgid "Invalid Service type" #~ msgstr "Tipo de serviço inválido" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possível aplicar parâmetros GAP." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Can not add Characteristic." -#~ msgstr "Não é possível adicionar Característica." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parâmetro UUID inválido" From b2cec6275c66a4854e2386a5b65644a4a72ae57e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 11 Jan 2019 00:10:41 -0800 Subject: [PATCH 084/153] Fix screen rotation and reset pin --- ports/atmel-samd/boards/pyportal/board.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index c361b5659543c..9cf3ee8c2272e 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = { 0xc1, 1, 0x10, // Power control SAP[2:0];BT[3:0] 0xc5, 2, 0x3e, 0x28, // VCM control 0xc7, 1, 0x86, // VCM control2 - 0x36, 1, 0x48, // Memory Access Control + 0x36, 1, 0x38, // Memory Access Control 0x37, 1, 0x00, // Vertical scroll zero 0x3a, 1, 0x55, // COLMOD: Pixel Format Set 0xb1, 2, 0x00, 0x18, // Frame Rate Control (In Normal Mode/Full Colors) @@ -72,9 +72,9 @@ void board_init(void) { &pin_PA12, // Data &pin_PB09, // Command or data &pin_PB06, // Chip select - &pin_PB05, // Reset - 240, // Width - 320, // Height + &pin_PA00, // Reset + 320, // Width + 240, // Height 0, // column start 0, // row start 16, // Color depth From 135b50a650b17042a29afe785daf5826a7d3a78c Mon Sep 17 00:00:00 2001 From: Juan Biondi Date: Fri, 11 Jan 2019 09:53:51 +0100 Subject: [PATCH 085/153] Update es.po --- locale/es.po | 101 +++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/locale/es.po b/locale/es.po index 29c69d49c2535..6f76ac3bb4de6 100644 --- a/locale/es.po +++ b/locale/es.po @@ -1287,7 +1287,7 @@ msgstr "pow() con 3 argumentos no soportado" #: py/modbuiltins.c:517 msgid "must use keyword argument for key function" -msgstr "" +msgstr "debe utilizar argumento de palabra clave para la función clave" #: py/modmath.c:41 shared-bindings/math/__init__.c:53 msgid "math domain error" @@ -1338,7 +1338,7 @@ msgstr "Argumento inválido" #: py/obj.c:92 msgid "Traceback (most recent call last):\n" -msgstr "" +msgstr "Traceback (ultima llamada reciente):\n" #: py/obj.c:96 msgid " File \"%q\", line %d" @@ -1429,12 +1429,12 @@ msgstr "objeto '%s' no soporta la eliminación de elementos" #: py/obj.c:507 msgid "object is not subscriptable" -msgstr "" +msgstr "el objeto no es suscriptable" #: py/obj.c:510 #, c-format msgid "'%s' object is not subscriptable" -msgstr "" +msgstr "el objeto '%s' no es suscriptable" #: py/obj.c:514 msgid "object does not support item assignment" @@ -1529,19 +1529,19 @@ msgstr "long int no soportado en esta compilación" #: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 msgid "small int overflow" -msgstr "" +msgstr "pequeño int desbordamiento" #: py/objint_longlong.c:189 py/objint_mpz.c:283 py/runtime.c:486 msgid "negative power with no float support" -msgstr "" +msgstr "potencia negativa sin float support" #: py/objint_longlong.c:251 msgid "ulonglong too large" -msgstr "" +msgstr "ulonglong muy largo" #: py/objint_mpz.c:267 py/runtime.c:396 py/runtime.c:411 msgid "negative shift count" -msgstr "" +msgstr "cuenta negativa de turnos" #: py/objint_mpz.c:336 msgid "pow() with 3 arguments requires integers" @@ -1553,11 +1553,11 @@ msgstr "el 3er argumento de pow() no puede ser 0" #: py/objint_mpz.c:415 msgid "overflow converting long int to machine word" -msgstr "" +msgstr "desbordamiento convirtiendo long int a palabra de máquina" #: py/objlist.c:273 msgid "pop from empty list" -msgstr "" +msgstr "pop desde una lista vacía" #: py/objnamedtuple.c:92 msgid "can't set attribute" @@ -1569,11 +1569,11 @@ msgstr "__new__ arg debe ser un user-type" #: py/objrange.c:110 msgid "zero step" -msgstr "" +msgstr "paso cero" #: py/objset.c:371 msgid "pop from an empty set" -msgstr "" +msgstr "pop desde un set vacío" #: py/objslice.c:66 msgid "Length must be an int" @@ -1585,7 +1585,7 @@ msgstr "Longitud no deberia ser negativa" #: py/objslice.c:86 py/sequence.c:57 msgid "slice step cannot be zero" -msgstr "" +msgstr "slice step no puede ser cero" #: py/objslice.c:159 msgid "Cannot subclass slice" @@ -1610,7 +1610,7 @@ msgstr "separator vacío" #: py/objstr.c:641 msgid "rsplit(None,n)" -msgstr "" +msgstr "rsplit(None,n)" #: py/objstr.c:713 msgid "substring not found" @@ -1618,7 +1618,7 @@ msgstr "substring no encontrado" #: py/objstr.c:770 msgid "start/end indices" -msgstr "" +msgstr "índices inicio/final" #: py/objstr.c:931 msgid "bad format string" @@ -1626,7 +1626,7 @@ msgstr "formato de string erroneo" #: py/objstr.c:953 msgid "single '}' encountered in format string" -msgstr "" +msgstr "un solo '}' encontrado en format string" #: py/objstr.c:992 msgid "bad conversion specifier" @@ -1643,7 +1643,7 @@ msgstr "especificador de conversión %c desconocido" #: py/objstr.c:1029 msgid "unmatched '{' in format" -msgstr "" +msgstr "No coinciden '{' en format" #: py/objstr.c:1036 msgid "expected ':' after format specifier" @@ -1667,7 +1667,7 @@ msgstr "atributos aún no soportados" #: py/objstr.c:1079 msgid "" "can't switch from manual field specification to automatic field numbering" -msgstr "" +msgstr "no se puede cambiar de especificación de campo manual a numeración automática de campos" #: py/objstr.c:1171 msgid "invalid format specifier" @@ -1675,34 +1675,34 @@ msgstr "especificador de formato inválido" #: py/objstr.c:1192 msgid "sign not allowed in string format specifier" -msgstr "" +msgstr "signo no permitido en el espeficador de string format" #: py/objstr.c:1200 msgid "sign not allowed with integer format specifier 'c'" -msgstr "" +msgstr "signo no permitido con el especificador integer format 'c'" #: py/objstr.c:1259 #, c-format msgid "unknown format code '%c' for object of type '%s'" -msgstr "" +msgstr "codigo format desconocido '%c' para el typo de objeto '%s'" #: py/objstr.c:1331 #, c-format msgid "unknown format code '%c' for object of type 'float'" -msgstr "" +msgstr "codigo format desconocido '%c' para el typo de objeto 'float'" #: py/objstr.c:1343 msgid "'=' alignment not allowed in string format specifier" -msgstr "" +msgstr "'=' alineación no permitida en el especificador string format" #: py/objstr.c:1367 #, c-format msgid "unknown format code '%c' for object of type 'str'" -msgstr "" +msgstr "codigo format desconocido '%c' para objeto de tipo 'str'" #: py/objstr.c:1415 msgid "format requires a dict" -msgstr "" +msgstr "format requiere un dict" #: py/objstr.c:1424 msgid "incomplete format key" @@ -1714,38 +1714,38 @@ msgstr "formato incompleto" #: py/objstr.c:1490 msgid "not enough arguments for format string" -msgstr "" +msgstr "no suficientes argumentos para format string" #: py/objstr.c:1500 #, c-format msgid "%%c requires int or char" -msgstr "" +msgstr "%%c requiere int o char" #: py/objstr.c:1507 msgid "integer required" -msgstr "" +msgstr "Entero requerido" #: py/objstr.c:1570 #, c-format msgid "unsupported format character '%c' (0x%x) at index %d" -msgstr "" +msgstr "carácter no soportado '%c' (0x%x) en índice %d" #: py/objstr.c:1577 msgid "not all arguments converted during string formatting" -msgstr "" +msgstr "no todos los argumentos fueron convertidos durante el formato de string" #: py/objstr.c:2102 msgid "can't convert to str implicitly" -msgstr "" +msgstr "no se puede convertir a str implícitamente" #: py/objstr.c:2106 msgid "can't convert '%q' object to %q implicitly" -msgstr "" +msgstr "no se puede convertir el objeto '%q' a %q implícitamente" #: py/objstrunicode.c:134 #, c-format msgid "string indices must be integers, not %s" -msgstr "" +msgstr "índices de string deben ser enteros, no %s" #: py/objstrunicode.c:145 py/objstrunicode.c:164 msgid "string index out of range" @@ -1766,12 +1766,12 @@ msgstr "atributo no legible" #: py/objtype.c:868 py/runtime.c:653 msgid "object not callable" -msgstr "" +msgstr "objeto no puede ser llamado" #: py/objtype.c:870 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" -msgstr "" +msgstr "objeto '%s' no puede ser llamado" #: py/objtype.c:978 msgid "type takes 1 or 3 arguments" @@ -1811,11 +1811,11 @@ msgstr "primer argumento para super() debe ser de tipo" #: py/objtype.c:1370 msgid "issubclass() arg 2 must be a class or a tuple of classes" -msgstr "" +msgstr "issubclass() arg 2 debe ser una clase o tuple de clases" #: py/objtype.c:1384 msgid "issubclass() arg 1 must be a class" -msgstr "" +msgstr "issubclass() arg 1 debe ser una clase" #: py/parse.c:726 msgid "constant must be an integer" @@ -1827,15 +1827,15 @@ msgstr "Incapaz de inicializar el parser" #: py/parse.c:1170 msgid "unexpected indent" -msgstr "" +msgstr "sangría inesperada" #: py/parse.c:1173 msgid "unindent does not match any outer indentation level" -msgstr "" +msgstr "no coincide con ningún nivel de sangría exterior" #: py/parsenum.c:60 msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" +msgstr "int() arg 2 debe ser >= 2 y <= 36" #: py/parsenum.c:151 msgid "invalid syntax for integer" @@ -1969,11 +1969,11 @@ msgstr "operación stream no soportada" #: py/stream.c:254 msgid "string not supported; use bytes or bytearray" -msgstr "" +msgstr "string no soportado; usa bytes o bytearray" #: py/stream.c:289 msgid "length argument not allowed for this type" -msgstr "" +msgstr "argumento length no permitido para este tipo" #: py/vm.c:255 msgid "local variable referenced before assignment" @@ -1981,7 +1981,7 @@ msgstr "variable local referenciada antes de la asignación" #: py/vm.c:1142 msgid "no active exception to reraise" -msgstr "" +msgstr "exception no activa para reraise" #: py/vm.c:1284 msgid "byte code not implemented" @@ -2038,11 +2038,11 @@ msgstr "No se puede grabar en un archivo" #: shared-bindings/audiobusio/PDMIn.c:202 msgid "Destination capacity is smaller than destination_length." -msgstr "" +msgstr "Capacidad de destino es mas pequeña que destination_length." #: shared-bindings/audiobusio/PDMIn.c:206 msgid "destination buffer must be an array of type 'H' for bit_depth = 16" -msgstr "" +msgstr "el buffer de destino debe ser un array de tipo 'H' para bit_depth = 16" #: shared-bindings/audiobusio/PDMIn.c:208 msgid "" @@ -2285,7 +2285,7 @@ msgstr "Bytes debe estar entre 0 y 255." #: shared-bindings/os/__init__.c:200 msgid "No hardware random available" -msgstr "" +msgstr "No hay hardware random disponible" #: shared-bindings/pulseio/PWMOut.c:164 msgid "" @@ -2546,6 +2546,9 @@ msgid "" "Please file an issue at https://github.com/adafruit/circuitpython/issues\n" " with the contents of your CIRCUITPY drive and this message:\n" msgstr "" +"Parece que nuestro código de CircuitPython ha fallado con fuerza. Whoops!\n" +"Por favor, crea un issue en https://github.com/adafruit/circuitpython/issues\n" +" con el contenido de su unidad CIRCUITPY y este mensaje:\n" #: supervisor/shared/safe_mode.c:111 msgid "Crash into the HardFault_Handler.\n" @@ -2557,7 +2560,7 @@ msgstr "" #: supervisor/shared/safe_mode.c:115 msgid "MicroPython fatal error.\n" -msgstr "" +msgstr "MicroPython fatal error.\n" #: supervisor/shared/safe_mode.c:118 #, fuzzy @@ -2569,6 +2572,8 @@ msgid "" msgstr "" "La alimentación del microcontrolador cayó. Por favor asegurate de que tu " "fuente de alimentación provee\n" +"suficiente energia para todo el circuito y presiona el botón de reset (despues" +"de expulsar CIRCUITPY).\n" #: supervisor/shared/safe_mode.c:120 msgid "" @@ -2584,6 +2589,8 @@ msgid "" "The reset button was pressed while booting CircuitPython. Press again to " "exit safe mode.\n" msgstr "" +"El botón reset fue presionado mientras arrancaba CircuitPython. Presiona otra" +" vez para salir del modo seguro.\n" #~ msgid "Cannot apply GAP parameters." #~ msgstr "No se pueden aplicar los parámetros GAP." From 948cc03031d6e13f2212758b596f9e152684d3c5 Mon Sep 17 00:00:00 2001 From: Juan Biondi Date: Fri, 11 Jan 2019 17:12:01 +0100 Subject: [PATCH 086/153] Update es.po --- locale/es.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/es.po b/locale/es.po index 6f76ac3bb4de6..afca3f6fe32e8 100644 --- a/locale/es.po +++ b/locale/es.po @@ -1831,7 +1831,7 @@ msgstr "sangría inesperada" #: py/parse.c:1173 msgid "unindent does not match any outer indentation level" -msgstr "no coincide con ningún nivel de sangría exterior" +msgstr "sangría no coincide con ningún nivel exterior" #: py/parsenum.c:60 msgid "int() arg 2 must be >= 2 and <= 36" From 6eecf96710f7edc6bb981eaf221a6d949fb24a63 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 11 Jan 2019 19:06:46 -0500 Subject: [PATCH 087/153] Use correct SERCOM for SDA/SCL on Grand Central --- ports/atmel-samd/peripherals | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index f3bd5b1fd96f2..235cb97d72648 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit f3bd5b1fd96f2ab0dde5cad61d41e607061ed46c +Subproject commit 235cb97d72648ec2889aba25ff4a34c4f32e2ac3 From 5f9980fb6b268fc99f7c94c15f45434dbd9729d6 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 12 Jan 2019 13:19:11 -0500 Subject: [PATCH 088/153] support winbond 8MB chips on all boards that might use them --- .../boards/grandcentral_m4_express/mpconfigboard.mk | 4 ++-- ports/atmel-samd/boards/pyportal/mpconfigboard.mk | 4 ++-- ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk index 2605c9f5557fc..bb8a2b0d95486 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk @@ -6,8 +6,8 @@ USB_MANUFACTURER = "Adafruit Industries LLC" QSPI_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICE_COUNT = 1 -EXTERNAL_FLASH_DEVICES = "GD25Q64C" +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51P20A diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk index 649bbb6489883..aad81e94ef396 100644 --- a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk @@ -6,8 +6,8 @@ USB_MANUFACTURER = "Adafruit Industries LLC" QSPI_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICE_COUNT = 1 -EXTERNAL_FLASH_DEVICES = "GD25Q64C" +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51J20A diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk index 7094b79be8527..5c310cfda296d 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk @@ -5,8 +5,8 @@ USB_PRODUCT = "Trellis M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" QSPI_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICE_COUNT = 1 -EXTERNAL_FLASH_DEVICES = GD25Q64C +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51G19A From 309a02efa16e25a6d5eef7290b54f2f7f1031205 Mon Sep 17 00:00:00 2001 From: TG-Techie Date: Sat, 12 Jan 2019 23:06:12 -0500 Subject: [PATCH 089/153] added datalore ip m4 to boards --- .../atmel-samd/boards/datalore_ip_m4/board.c | 39 +++++++++++++++ .../boards/datalore_ip_m4/mpconfigboard.h | 47 ++++++++++++++++++ .../boards/datalore_ip_m4/mpconfigboard.mk | 17 +++++++ ports/atmel-samd/boards/datalore_ip_m4/pins.c | 48 +++++++++++++++++++ 4 files changed, 151 insertions(+) create mode 100644 ports/atmel-samd/boards/datalore_ip_m4/board.c create mode 100644 ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/datalore_ip_m4/pins.c diff --git a/ports/atmel-samd/boards/datalore_ip_m4/board.c b/ports/atmel-samd/boards/datalore_ip_m4/board.c new file mode 100644 index 0000000000000..0f60736a24006 --- /dev/null +++ b/ports/atmel-samd/boards/datalore_ip_m4/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 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 "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/datalore_ip_m4/mpconfigboard.h b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.h new file mode 100644 index 0000000000000..a565435d1ce11 --- /dev/null +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.h @@ -0,0 +1,47 @@ +#define MICROPY_HW_BOARD_NAME "TG-Boards' Datalore IP M4" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev F which is green + +#define MICROPY_HW_LED_TX (&pin_PA27) +#define MICROPY_HW_LED_RX (&pin_PB06) + +#define MICROPY_HW_LED_STATUS (&pin_PA16) + +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// QSPI CS, QSPI SCK and NeoPixel pin +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11 | PORT_PB22) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +#define CIRCUITPY_I2CSLAVE diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk new file mode 100644 index 0000000000000..eb3b1ec55796d --- /dev/null +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk @@ -0,0 +1,17 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8021 +USB_PRODUCT = "Metro M4 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 3 +EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JV_IQ, W25Q16JV_IM" + +LONGINT_IMPL = MPZ + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +MICROPY_PY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 diff --git a/ports/atmel-samd/boards/datalore_ip_m4/pins.c b/ports/atmel-samd/boards/datalore_ip_m4/pins.c new file mode 100644 index 0000000000000..ed607db19b4f4 --- /dev/null +++ b/ports/atmel-samd/boards/datalore_ip_m4/pins.c @@ -0,0 +1,48 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PA05 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PA06 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PA04 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PB08 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PB09 }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), (mp_obj_t)&pin_PA23 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PA23 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), (mp_obj_t)&pin_PA22 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PA22 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PB17 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PB16 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PB13 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), (mp_obj_t)&pin_PB14 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), (mp_obj_t)&pin_PB15 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PB12 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PA21 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PA20 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), (mp_obj_t)&pin_PA18 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), (mp_obj_t)&pin_PA19 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PA17 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA16 }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB02 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB03 }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB22 }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PA13 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA14 }, + +// { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), (mp_obj_t)&pin_PB06 }, +// { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), (mp_obj_t)&pin_PA27 }, + { 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); From ef6c9e7df6e2d3c1abd34881b7e4a3e203a89bb9 Mon Sep 17 00:00:00 2001 From: TG-Techie Date: Sat, 12 Jan 2019 23:19:40 -0500 Subject: [PATCH 090/153] removed commented code --- ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk | 4 ++-- ports/atmel-samd/boards/datalore_ip_m4/pins.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk index eb3b1ec55796d..407026c202a12 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk @@ -1,8 +1,8 @@ LD_FILE = boards/samd51x19-bootloader-external-flash.ld USB_VID = 0x239A USB_PID = 0x8021 -USB_PRODUCT = "Metro M4 Express" -USB_MANUFACTURER = "Adafruit Industries LLC" +USB_PRODUCT = "Datalore IP M4" +USB_MANUFACTURER = "TG-Boards" QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 3 diff --git a/ports/atmel-samd/boards/datalore_ip_m4/pins.c b/ports/atmel-samd/boards/datalore_ip_m4/pins.c index ed607db19b4f4..460fd6fefa5e5 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/pins.c +++ b/ports/atmel-samd/boards/datalore_ip_m4/pins.c @@ -39,8 +39,6 @@ STATIC const mp_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 }, { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA14 }, -// { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), (mp_obj_t)&pin_PB06 }, -// { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), (mp_obj_t)&pin_PA27 }, { 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) }, From ffe734edf72392743e423b8acda3cc7d75960bd1 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sun, 13 Jan 2019 23:51:13 -0500 Subject: [PATCH 091/153] Fresh combined checkin of _pixelbuf library. --- docs/library/builtins.rst | 4 +- ports/atmel-samd/Makefile | 9 + .../boards/arduino_zero/mpconfigboard.mk | 2 + .../mpconfigboard.mk | 2 + .../feather_m0_adalogger/mpconfigboard.mk | 2 + .../boards/pirkey_m0/mpconfigboard.mk | 2 + .../boards/trinket_m0/mpconfigboard.mk | 2 + ports/atmel-samd/mpconfigport.h | 11 +- ports/esp8266/Makefile | 5 + ports/nrf/Makefile | 8 +- shared-bindings/_pixelbuf/PixelBuf.c | 506 ++++++++++++++++++ shared-bindings/_pixelbuf/PixelBuf.h | 60 +++ shared-bindings/_pixelbuf/__init__.c | 326 +++++++++++ shared-bindings/_pixelbuf/__init__.h | 35 ++ shared-bindings/_pixelbuf/types.h | 48 ++ shared-bindings/index.rst | 2 + shared-module/_pixelbuf/PixelBuf.c | 120 +++++ shared-module/_pixelbuf/PixelBuf.h | 50 ++ shared-module/_pixelbuf/__init__.c | 0 19 files changed, 1190 insertions(+), 4 deletions(-) create mode 100644 shared-bindings/_pixelbuf/PixelBuf.c create mode 100644 shared-bindings/_pixelbuf/PixelBuf.h create mode 100644 shared-bindings/_pixelbuf/__init__.c create mode 100644 shared-bindings/_pixelbuf/__init__.h create mode 100644 shared-bindings/_pixelbuf/types.h create mode 100644 shared-module/_pixelbuf/PixelBuf.c create mode 100644 shared-module/_pixelbuf/PixelBuf.h create mode 100644 shared-module/_pixelbuf/__init__.c diff --git a/docs/library/builtins.rst b/docs/library/builtins.rst index 36a84bc0c5b2e..0061a8cea08a0 100644 --- a/docs/library/builtins.rst +++ b/docs/library/builtins.rst @@ -78,12 +78,12 @@ Not all of these functions and types are turned on in all CircuitPython ports, f .. classmethod:: from_bytes(bytes, byteorder) - In CircuitPython, `byteorder` parameter must be positional (this is + In CircuitPython, ``byteorder`` parameter must be positional (this is compatible with CPython). .. method:: to_bytes(size, byteorder) - In CircuitPython, `byteorder` parameter must be positional (this is + In CircuitPython, ``byteorder`` parameter must be positional (this is compatible with CPython). .. function:: isinstance() diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 852de75f39abd..9244ccc739477 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -191,6 +191,10 @@ LDFLAGS += -mthumb -mcpu=cortex-m4 BOOTLOADER_SIZE := 0x4000 endif +ifdef EXCLUDE_PIXELBUF +CFLAGS += -DEXCLUDE_PIXELBUF +endif + SRC_ASF := \ gcc/gcc/startup_$(CHIP_FAMILY).c \ gcc/system_$(CHIP_FAMILY).c \ @@ -419,6 +423,11 @@ ifneq ($(CHIP_VARIANT),SAMR21G18A) audioio/WaveFile.c endif +ifndef EXCLUDE_PIXELBUF + SRC_SHARED_MODULE += _pixelbuf/__init__.c \ + _pixelbuf/PixelBuf.c +endif + # The smallest SAMD51 packages don't have I2S. Everything else does. ifneq ($(CHIP_VARIANT),SAMD51G18A) ifneq ($(CHIP_VARIANT),SAMD51G19A) diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk index 017e66ddffe1c..28c79d6e40509 100644 --- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk @@ -9,3 +9,5 @@ LONGINT_IMPL = NONE CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 + +EXCLUDE_PIXELBUF = 1 diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk index b07d63984d5db..e1e7484d50212 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk @@ -9,6 +9,8 @@ EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" # Turn off longints for Crickit build to make room for additional frozen libs. LONGINT_IMPL = NONE +# Disable pixelbuf to save room +EXCLUDE_PIXELBUF = 1 CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk index 4f2855d732186..687a27df3302e 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk @@ -9,3 +9,5 @@ LONGINT_IMPL = NONE CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 + +EXCLUDE_PIXELBUF = 1 diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk index ddc262a570290..69250626f9dbf 100644 --- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk @@ -16,3 +16,5 @@ CFLAGS_INLINE_LIMIT = 45 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_IRRemote + +EXCLUDE_PIXELBUF = 1 diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk index c9c45152bead8..9b93719efdb5f 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk @@ -9,3 +9,5 @@ LONGINT_IMPL = NONE CHIP_VARIANT = SAMD21E18A CHIP_FAMILY = samd21 + +EXCLUDE_PIXELBUF = 1 diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 65b8c94c5bb1a..4e3d6073c8555 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -241,6 +241,9 @@ extern const struct _mp_obj_module_t usb_midi_module; extern const struct _mp_obj_module_t network_module; extern const struct _mp_obj_module_t socket_module; extern const struct _mp_obj_module_t wiznet_module; +#ifndef EXCLUDE_PIXELBUF +extern const struct _mp_obj_module_t pixelbuf_module; +#endif // Internal flash size dependent settings. #if BOARD_FLASH_SIZE > 192000 @@ -308,6 +311,11 @@ extern const struct _mp_obj_module_t wiznet_module; #define JSON_MODULE #endif + #ifndef EXCLUDE_PIXELBUF + #define PIXELBUF_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__pixelbuf),(mp_obj_t)&pixelbuf_module } + #else + #define PIXELBUF_MODULE + #endif #ifndef EXTRA_BUILTIN_MODULES #define EXTRA_BUILTIN_MODULES \ @@ -321,7 +329,8 @@ extern const struct _mp_obj_module_t wiznet_module; WIZNET_MODULE \ JSON_MODULE \ { MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module } + { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, \ + PIXELBUF_MODULE #endif #define EXPRESS_BOARD diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index d38285c914401..67316b55aec94 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -148,6 +148,11 @@ SRC_SHARED_MODULE = \ os/__init__.c \ random/__init__.c \ struct/__init__.c + +ifndef EXCLUDE_PIXELBUF + SRC_SHARED_MODULE += _pixelbuf/__init__.c \ + _pixelbuf/PixelBuf.c +endif SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ $(addprefix shared-module/, $(SRC_SHARED_MODULE)) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 2bc5084754617..164cd9abcedba 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -214,7 +214,13 @@ SRC_SHARED_MODULE = \ bitbangio/OneWire.c \ bitbangio/SPI.c \ busio/OneWire.c \ - storage/__init__.c + storage/__init__.c + + +ifndef EXCLUDE_PIXELBUF + SRC_SHARED_MODULE += _pixelbuf/__init__.c \ + _pixelbuf/PixelBuf.c +endif # uheap/__init__.c \ ustack/__init__.c diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c new file mode 100644 index 0000000000000..545166724f318 --- /dev/null +++ b/shared-bindings/_pixelbuf/PixelBuf.c @@ -0,0 +1,506 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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/obj.h" +#include "py/objarray.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/gc.h" + +#include + +#include "PixelBuf.h" +#include "shared-bindings/_pixelbuf/types.h" +#include "../../shared-module/_pixelbuf/PixelBuf.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +extern const pixelbuf_byteorder_obj_t byteorder_BGR; +extern const mp_obj_type_t pixelbuf_byteorder_type; +extern const int32_t colorwheel(float pos); + +//| .. currentmodule:: pixelbuf +//| +//| :class:`PixelBuf` -- A fast RGB[W] pixel buffer for LED and similar devices +//| =========================================================================== +//| +//| :class:`~_pixelbuf.PixelBuf` implements an RGB[W] bytearray abstraction. +//| +//| .. class:: PixelBuf(size, buf, byteorder=BGR, bpp=3) +//| +//| Create a PixelBuf object of the specified size, byteorder, and bits per pixel. +//| +//| When given a second bytearray (``rawbuf``), changing brightness adjusts the +//| brightness of all members of ``buf``. +//| +//| When only given ``buf``, ``brightness`` applies to the next pixel assignment. +//| +//| When ``dotstar`` is True, and ``bpp`` is 4, the 4th value in a tuple/list +//| is the individual pixel brightness (0-1). Not compatible with RGBW Byteorders. +//| Compatible `ByteOrder` classes are bpp=3, or bpp=4 and has_luminosity=True (g LBGR). +//| +//| :param ~int size: Number of pixelsx +//| :param ~bytearray buf: Bytearray to store pixel data in +//| :param ~_pixelbuf.ByteOrder byteorder: Byte order constant from `_pixelbuf` (also sets the bpp) +//| :param ~float brightness: Brightness (0 to 1.0, default 1.0) +//| :param ~bytearray rawbuf: Bytearray to store raw pixel colors in +//| :param ~int offset: Offset from start of buffer (default 0) +//| :param ~bool dotstar: Dotstar mode (default False) +//| :param ~bool auto_write: Whether to automatically write pixels (Default False) +//| :param ~callable write_function: (optional) Callable to use to send pixels +//| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The +//| PixelBuf instance is appended after these args. +//| +STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 2, MP_OBJ_FUN_ARGS_MAX, true); + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + enum { ARG_size, ARG_buf, ARG_byteorder, ARG_brightness, ARG_rawbuf, ARG_offset, ARG_dotstar, + ARG_auto_write, ARG_write_function, ARG_write_args }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_size, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_byteorder, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_brightness, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_rawbuf, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_offset, MP_ARG_INT, { .u_int = 0 } }, + { MP_QSTR_dotstar, MP_ARG_BOOL, { .u_bool = false } }, + { MP_QSTR_auto_write, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_write_function, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_write_args, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + 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); + + if (mp_obj_is_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type)) + mp_raise_TypeError_varg(translate("byteorder is not an instance of ByteOrder (got a %s)"), mp_obj_get_type_str(args[ARG_byteorder].u_obj)); + + pixelbuf_byteorder_obj_t *byteorder = (args[ARG_byteorder].u_obj == mp_const_none) ? MP_OBJ_FROM_PTR(&byteorder_BGR) : args[ARG_byteorder].u_obj; + + if (byteorder->has_white && args[ARG_dotstar].u_bool) + mp_raise_ValueError_varg(translate("Can not use dotstar with %s"), mp_obj_get_type_str(byteorder)); + + size_t effective_bpp = args[ARG_dotstar].u_bool ? 4 : byteorder->bpp; // Always 4 for DotStar + size_t bytes = args[ARG_size].u_int * effective_bpp; + size_t offset = args[ARG_offset].u_int; + mp_buffer_info_t bufinfo, rawbufinfo; + + mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_READ | MP_BUFFER_WRITE); + bool two_buffers = args[ARG_rawbuf].u_obj != mp_const_none; + if (two_buffers) { + mp_get_buffer_raise(args[ARG_rawbuf].u_obj, &rawbufinfo, MP_BUFFER_READ | MP_BUFFER_WRITE); + if (rawbufinfo.len != bufinfo.len) { + mp_raise_ValueError(translate("rawbuf is not the same size as buf")); + } + } + + if (bytes + offset > bufinfo.len) + mp_raise_ValueError_varg(translate("buf is too small. need %d bytes"), bytes + offset); + + if (!MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_list) && + !MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_tuple) && + args[ARG_write_args].u_obj != mp_const_none) + { + mp_raise_ValueError(translate("write_args must be a list, tuple, or None")); + } + + // Validation complete, allocate and populate object. + pixelbuf_pixelbuf_obj_t *self = m_new_obj(pixelbuf_pixelbuf_obj_t); + + self->base.type = &pixelbuf_pixelbuf_type; + self->pixels = args[ARG_size].u_int; + self->bytes = bytes; + self->byteorder = *byteorder; // Copied because we modify for dotstar + self->bytearray = args[ARG_buf].u_obj; + self->two_buffers = two_buffers; + self->rawbytearray = two_buffers ? args[ARG_rawbuf].u_obj : NULL; + self->offset = offset; + self->dotstar_mode = args[ARG_dotstar].u_bool; + self->buf = (uint8_t *)bufinfo.buf + offset; + self->rawbuf = two_buffers ? (uint8_t *)rawbufinfo.buf + offset : NULL; + self->pixel_step = effective_bpp; + self->auto_write = args[ARG_auto_write].u_bool; + + if (self->dotstar_mode) { + // Ensure sane configuration + if (!self->byteorder.has_luminosity) { + self->byteorder.has_luminosity = true; + self->byteorder.byteorder.b += 1; + self->byteorder.byteorder.g += 1; + self->byteorder.byteorder.r += 1; + } + self->byteorder.byteorder.w = 0; + } + + // Show/auto-write callbacks + self->write_function = args[ARG_write_function].u_obj; + mp_obj_t function_args = args[ARG_write_args].u_obj; + mp_obj_t *src_objs = (mp_obj_t *)&mp_const_none_obj; + size_t num_items = 0; + if (function_args != mp_const_none) { + if (MP_OBJ_IS_TYPE(function_args, &mp_type_list)) { + mp_obj_list_t *t = MP_OBJ_TO_PTR(function_args); + num_items = t->len; + src_objs = t->items; + } else { + mp_obj_tuple_t *l = MP_OBJ_TO_PTR(function_args); + num_items = l->len; + src_objs = l->items; + } + } + self->write_function_args = mp_obj_new_tuple(num_items + 1, NULL); + for (size_t i = 0; i < num_items; i++) { + self->write_function_args->items[i] = src_objs[i]; + } + self->write_function_args->items[num_items] = self; + + if (args[ARG_brightness].u_obj == mp_const_none) { + self->brightness = 1.0; + } else { + self->brightness = mp_obj_get_float(args[ARG_brightness].u_obj); + if (self->brightness < 0) + self->brightness = 0; + else if (self->brightness > 1) + self->brightness = 1; + } + + if (self->dotstar_mode) { + // Initialize the buffer with the dotstar start bytes. + // Header and end must be setup by caller + for (uint i = 0; i < self->pixels * 4; i += 4) { + self->buf[i] = DOTSTAR_LED_START_FULL_BRIGHT; + if (two_buffers) { + self->rawbuf[i] = DOTSTAR_LED_START_FULL_BRIGHT; + } + } + } + + return MP_OBJ_FROM_PTR(self); +} + +//| .. attribute:: bpp +//| +//| The number of bytes per pixel in the buffer (read-only) +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_bpp(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(self->byteorder.bpp); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_bpp_obj, pixelbuf_pixelbuf_obj_get_bpp); + +const mp_obj_property_t pixelbuf_pixelbuf_bpp_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_bpp_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: brightness +//| +//| Float value between 0 and 1. Output brightness. +//| If the PixelBuf was allocated with two both a buf and a rawbuf, +//| setting this value causes a recomputation of the values in buf. +//| If only a buf was provided, then the brightness only applies to +//| future pixel changes. +//| In DotStar mode +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_brightness(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_float(self->brightness); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_brightness_obj, pixelbuf_pixelbuf_obj_get_brightness); + + +STATIC mp_obj_t pixelbuf_pixelbuf_obj_set_brightness(mp_obj_t self_in, mp_obj_t value) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + self->brightness = mp_obj_float_get(value); + if (self->brightness > 1) + self->brightness = 1; + else if (self->brightness < 0) + self->brightness = 0; + if (self->two_buffers) + pixelbuf_recalculate_brightness(self); + if (self->auto_write) + call_write_function(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_set_brightness_obj, pixelbuf_pixelbuf_obj_set_brightness); + +const mp_obj_property_t pixelbuf_pixelbuf_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_brightness_obj, + (mp_obj_t)&pixelbuf_pixelbuf_set_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +void pixelbuf_recalculate_brightness(pixelbuf_pixelbuf_obj_t *self) { + uint8_t *buf = (uint8_t *)self->buf; + uint8_t *rawbuf = (uint8_t *)self->rawbuf; + // Compensate for shifted buffer (bpp=3 dotstar) + for (uint i = 0; i < self->bytes; i++) { + // Don't adjust per-pixel luminance bytes in dotstar mode + if (!self->dotstar_mode || (i % 4 != 0)) + buf[i] = rawbuf[i] * self->brightness; + } +} + +//| .. attribute:: auto_write +//| +//| Whether to automatically write the pixels after each update. +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_auto_write(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->auto_write); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_auto_write_obj, pixelbuf_pixelbuf_obj_get_auto_write); + + +STATIC mp_obj_t pixelbuf_pixelbuf_obj_set_auto_write(mp_obj_t self_in, mp_obj_t value) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + self->auto_write = mp_obj_is_true(value); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_set_auto_write_obj, pixelbuf_pixelbuf_obj_set_auto_write); + +const mp_obj_property_t pixelbuf_pixelbuf_auto_write_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_auto_write_obj, + (mp_obj_t)&pixelbuf_pixelbuf_set_auto_write_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: buf +//| +//| (read-only) bytearray of pixel data after brightness adjustment. If an offset was provided +//| then this bytearray is the subset of the bytearray passed in that represents the +//| actual pixels. +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_buf(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bytearray_by_ref(self->bytes, self->buf); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_buf_obj, pixelbuf_pixelbuf_obj_get_buf); + +const mp_obj_property_t pixelbuf_pixelbuf_buf_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_buf_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: byteorder +//| +//| `ByteOrder` class for the buffer (read-only) +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_byteorder(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return &self->byteorder; +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_byteorder_obj, pixelbuf_pixelbuf_obj_get_byteorder); + +const mp_obj_property_t pixelbuf_pixelbuf_byteorder_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_byteorder_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC mp_obj_t pixelbuf_pixelbuf_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_const_true; + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(self->pixels); + default: return MP_OBJ_NULL; // op not supported + } +} + +//| .. method:: show() +//| +//| Call the associated write function to display the pixels. +//| + +STATIC mp_obj_t pixelbuf_pixelbuf_show(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + call_write_function(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_show_obj, pixelbuf_pixelbuf_show); + +void call_write_function(pixelbuf_pixelbuf_obj_t *self) { + // execute function if it's set + if (self->write_function != mp_const_none) { + mp_call_function_n_kw(self->write_function, self->write_function_args->len, 0, self->write_function_args->items); + } +} + + + +//| .. method:: [] +//| +//| Get or set pixels. Supports individual pixels and slices. +//| +STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + + if (value == MP_OBJ_NULL) { + // delete item + // slice deletion + return MP_OBJ_NULL; // op not supported + } + + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (0) { +#if MICROPY_PY_BUILTINS_SLICE + } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + mp_bound_slice_t slice; + + if (!mp_seq_get_fast_slice_indexes(self->bytes, index_in, &slice)) + mp_raise_NotImplementedError(translate("Only slices with step=1 (aka None) are supported")); + if ((slice.stop * self->pixel_step) > self->bytes) + mp_raise_IndexError(translate("Range out of bounds")); + + if (value == MP_OBJ_SENTINEL) { // Get + size_t len = slice.stop - slice.start; + return pixelbuf_get_pixel_array((uint8_t *) self->buf + slice.start, len, &self->byteorder, self->pixel_step, self->dotstar_mode); + } else { // Set + #if MICROPY_PY_ARRAY_SLICE_ASSIGN + + if (!(MP_OBJ_IS_TYPE(value, &mp_type_list) || MP_OBJ_IS_TYPE(value, &mp_type_tuple))) + mp_raise_ValueError(translate("tuple/list required on RHS")); + + size_t dst_len = slice.stop - slice.start; + + mp_obj_t *src_objs; + size_t num_items; + if (MP_OBJ_IS_TYPE(value, &mp_type_list)) { + mp_obj_list_t *t = MP_OBJ_TO_PTR(value); + num_items = t->len; + src_objs = t->items; + } else { + mp_obj_tuple_t *l = MP_OBJ_TO_PTR(value); + num_items = l->len; + src_objs = l->items; + } + if (num_items != dst_len) + mp_raise_ValueError_varg(translate("Unmatched number of items on RHS (expected %d, got %d)."), + dst_len, num_items); + + for (size_t i = slice.start; i < slice.stop; i++) { + mp_obj_t *item = src_objs[i-slice.start]; + if (MP_OBJ_IS_TYPE(value, &mp_type_list) || MP_OBJ_IS_TYPE(value, &mp_type_tuple) || MP_OBJ_IS_INT(value)) { + pixelbuf_set_pixel(self->buf + (i * self->pixel_step), + self->two_buffers ? self->rawbuf + (i * self->pixel_step) : NULL, + self->brightness, item, &self->byteorder, self->dotstar_mode); + } + } + if (self->auto_write) + call_write_function(self); + return mp_const_none; + #else + return MP_OBJ_NULL; // op not supported + #endif + } +#endif + } else { // Single index rather than slice. + size_t index = mp_get_index(self->base.type, self->pixels, index_in, false); + size_t offset = (index * self->pixel_step); + if (offset > self->bytes) + mp_raise_IndexError(translate("Pixel beyond bounds of buffer")); + + if (value == MP_OBJ_SENTINEL) { // Get + uint8_t *pixelstart = (uint8_t *)(self->two_buffers ? self->rawbuf : self->buf) + offset; + return pixelbuf_get_pixel(pixelstart, &self->byteorder, self->dotstar_mode); + } else { // Store + pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL, + self->brightness, value, &self->byteorder, self->dotstar_mode); + if (self->auto_write) + call_write_function(self); + return mp_const_none; + } + } +} + +//| .. method:: fill_wheel(start=0, step=1) +//| +//| fill the buffer with a colorwheel starting at offset n, and stepping by step +//| + +STATIC mp_obj_t pixelbuf_pixelbuf_fill_wheel(mp_obj_t self_in, mp_obj_t start, mp_obj_t step) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + float i = MP_OBJ_IS_SMALL_INT(start) ? MP_OBJ_SMALL_INT_VALUE(start) : mp_obj_float_get(start); + float incr = MP_OBJ_IS_SMALL_INT(step) ? MP_OBJ_SMALL_INT_VALUE(step) : mp_obj_float_get(step); + + bool auto_write = self->auto_write; + self->auto_write = false; + for (size_t n = 0; n < self->pixels; n++) { + mp_obj_t value = MP_OBJ_NEW_SMALL_INT(colorwheel(i)); + pixelbuf_pixelbuf_subscr(self_in, MP_OBJ_NEW_SMALL_INT(n), value); + i += incr; + } + self->auto_write = auto_write; + if (auto_write) + call_write_function(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(pixelbuf_pixelbuf_fill_wheel_obj, pixelbuf_pixelbuf_fill_wheel); + +STATIC const mp_rom_map_elem_t pixelbuf_pixelbuf_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_auto_write), MP_ROM_PTR(&pixelbuf_pixelbuf_auto_write_obj)}, + { MP_ROM_QSTR(MP_QSTR_bpp), MP_ROM_PTR(&pixelbuf_pixelbuf_bpp_obj)}, + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&pixelbuf_pixelbuf_brightness_obj)}, + { MP_ROM_QSTR(MP_QSTR_buf), MP_ROM_PTR(&pixelbuf_pixelbuf_buf_obj)}, + { MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_PTR(&pixelbuf_pixelbuf_byteorder_obj)}, + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&pixelbuf_pixelbuf_show_obj)}, + { MP_ROM_QSTR(MP_QSTR_fill_wheel), MP_ROM_PTR(&pixelbuf_pixelbuf_fill_wheel_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(pixelbuf_pixelbuf_locals_dict, pixelbuf_pixelbuf_locals_dict_table); + + +const mp_obj_type_t pixelbuf_pixelbuf_type = { + { &mp_type_type }, + .name = MP_QSTR_PixelBuf, + .subscr = pixelbuf_pixelbuf_subscr, + .make_new = pixelbuf_pixelbuf_make_new, + .unary_op = pixelbuf_pixelbuf_unary_op, + .print = NULL, + .locals_dict = (mp_obj_t)&pixelbuf_pixelbuf_locals_dict, +}; diff --git a/shared-bindings/_pixelbuf/PixelBuf.h b/shared-bindings/_pixelbuf/PixelBuf.h new file mode 100644 index 0000000000000..b35e3ff9083c2 --- /dev/null +++ b/shared-bindings/_pixelbuf/PixelBuf.h @@ -0,0 +1,60 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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 CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H +#define CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H + +#include "shared-bindings/_pixelbuf/types.h" + +const mp_obj_type_t pixelbuf_pixelbuf_type; + +typedef struct { + mp_obj_base_t base; + size_t pixels; + size_t bytes; + size_t pixel_step; + pixelbuf_byteorder_obj_t byteorder; + mp_obj_t bytearray; + mp_obj_t rawbytearray; + mp_float_t brightness; + bool two_buffers; + size_t offset; + bool dotstar_mode; + uint8_t *rawbuf; + uint8_t *buf; + mp_obj_t write_function; + mp_obj_tuple_t *write_function_args; + bool auto_write; +} pixelbuf_pixelbuf_obj_t; + +void pixelbuf_recalculate_brightness(pixelbuf_pixelbuf_obj_t *self); +void call_write_function(pixelbuf_pixelbuf_obj_t *self); + + +#include "common-hal/digitalio/DigitalInOut.h" +extern void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* gpio, uint8_t *pixels, uint32_t numBytes); + +#endif // CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c new file mode 100644 index 0000000000000..58fccfd91c251 --- /dev/null +++ b/shared-bindings/_pixelbuf/__init__.c @@ -0,0 +1,326 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/objproperty.h" + +#include "types.h" +#include "__init__.h" + +#include "PixelBuf.h" +#include "../../shared-module/_pixelbuf/PixelBuf.h" + + +//| :mod:`_pixelbuf` --- Fast RGB(W) pixel buffer and helpers +//| =========================================================== + +//| .. module:: _pixelbuf +//| :synopsis: A fast RGB(W) pixel buffer library for like NeoPixel and DotStar. +//| +//| The `_pixelbuf` module provides :py:class:`PixelBuf` and :py:class:`ByteOrder` classes to accelerate +//| Dotstar and Neopixel manipulation. +//| + +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PixelBuf + +//| .. class:: ByteOrder +//| +//| Classes representing byteorders for circuitpython + + +//| .. attribute:: bpp +//| +//| The number of bytes per pixel (read-only) +//| + +//| .. attribute:: has_white +//| +//| Whether the pixel has white (in addition to RGB) +//| + +//| .. attribute:: has_luminosity +//| +//| Whether the pixel has luminosity (in addition to RGB) +//| + +//| .. attribute:: byteorder +//| +//| Tuple of byte order (r, g, b) or (r, g, b, w) or (r, g, b, l) +//| + + +STATIC void pixelbuf_byteorder_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_byteorder_type)); + pixelbuf_byteorder_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (dest[0] == MP_OBJ_NULL) { + // load attribute + mp_obj_t val; + if (attr == MP_QSTR_bpp) { + val = MP_OBJ_NEW_SMALL_INT(self->bpp); + } else if (attr == MP_QSTR_has_white) { + val = mp_obj_new_bool(self->has_white); + } else if (attr == MP_QSTR_has_luminosity) { + val = mp_obj_new_bool(self->has_luminosity); + } else if (attr == MP_QSTR_byteorder) { + mp_obj_t items[4]; + uint8_t n = self->bpp; + if (self->has_luminosity || self->has_white) { + n = 4; + } + uint8_t *values = (uint8_t *)&(self->byteorder); + for (uint8_t i=0; ibpp); + default: return MP_OBJ_NULL; // op not supported + } +} + +const mp_obj_type_t pixelbuf_byteorder_type = { + { &mp_type_type }, + .name = MP_QSTR_ByteOrder, + .print = pixelbuf_byteorder_print, + .unary_op = pixelbuf_byteorder_unary_op, + .attr = pixelbuf_byteorder_attr, +}; + + +// This macro is used to simplify RGB subclass definition +#define PIXELBUF_BYTEORDER(p_name, p_bpp, p_r, p_g, p_b, p_w, p_has_white, p_has_luminosity) \ +const pixelbuf_byteorder_obj_t byteorder_## p_name = { \ + { &pixelbuf_byteorder_type }, \ + .name = MP_QSTR_## p_name, \ + .bpp = p_bpp, \ + .byteorder = { p_r, p_g, p_b, p_w }, \ + .has_white = p_has_white, \ + .has_luminosity = p_has_luminosity, \ +}; + +//| .. function:: wheel(n) +//| +//| C implementation of the common wheel() function found in many examples. +//| Returns the colorwheel RGB value as an integer value for n (usable in :py:class:`PixelBuf`, neopixel, and dotstar). +//| + +STATIC mp_obj_t pixelbuf_wheel(mp_obj_t n) { + return MP_OBJ_NEW_SMALL_INT(colorwheel(MP_OBJ_IS_SMALL_INT(n) ? MP_OBJ_SMALL_INT_VALUE(n) : mp_obj_float_get(n))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_wheel_obj, pixelbuf_wheel); + +const int32_t colorwheel(float pos) { + if (pos > 255) { + pos = pos - ((uint32_t)(pos / 256) * 256); + } + if (pos < 85) + return (uint8_t)(pos * 3) << 16 | (uint8_t)(255 - (pos * 3)) << 8; + else if (pos < 170) { + pos -= 85; + return (uint8_t)(255 - (pos * 3)) << 16 | (uint8_t)(pos * 3); + } else { + pos -= 170; + return (uint8_t)(pos * 3) << 8 | (uint8_t)(255 - pos * 3); + } +} + + +/// RGB +//| .. class:: RGB +//| +//| * **order** Red, Green, Blue +//| * **bpp** 3 +PIXELBUF_BYTEORDER(RGB, 3, 0, 1, 2, 3, false, false) +//| .. class:: RBG +//| +//| * **order** Red, Blue, Green +//| * **bpp** 3 +PIXELBUF_BYTEORDER(RBG, 3, 0, 2, 1, 3, false, false) +//| .. class:: GRB +//| +//| * **order** Green, Red, Blue +//| * **bpp** 3 +//| +//| Commonly used by NeoPixel. +PIXELBUF_BYTEORDER(GRB, 3, 1, 0, 2, 3, false, false) +//| .. class:: GBR +//| +//| * **order** Green, Blue, Red +//| * **bpp** 3 +PIXELBUF_BYTEORDER(GBR, 3, 1, 2, 0, 3, false, false) +//| .. class:: BRG +//| +//| * **order** Blue, Red, Green +//| * **bpp** 3 +PIXELBUF_BYTEORDER(BRG, 3, 2, 0, 1, 3, false, false) +//| .. class:: BGR +//| +//| * **order** Blue, Green, Red +//| * **bpp** 3 +//| +//| Commonly used by Dotstar. +PIXELBUF_BYTEORDER(BGR, 3, 2, 1, 0, 3, false, false) + +// RGBW +//| .. class:: RGBW +//| +//| * **order** Red, Green, Blue, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(RGBW, 4, 0, 1, 2, 3, true, false) +//| .. class:: RBGW +//| +//| * **order** Red, Blue, Green, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(RBGW, 4, 0, 2, 1, 3, true, false) +//| .. class:: GRBW +//| +//| * **order** Green, Red, Blue, White +//| * **bpp** 4 +//| * **has_white** True +//| +//| Commonly used by RGBW NeoPixels. +PIXELBUF_BYTEORDER(GRBW, 4, 1, 0, 2, 3, true, false) +//| .. class:: GBRW +//| +//| * **order** Green, Blue, Red, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(GBRW, 4, 1, 2, 0, 3, true, false) +//| .. class:: BRGW +//| +//| * **order** Blue, Red, Green, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(BRGW, 4, 2, 0, 1, 3, true, false) +//| .. class:: BGRW +//| +//| * **order** Blue, Green, Red, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(BGRW, 4, 2, 1, 0, 3, true, false) + +// Luminosity + RGB (eg for Dotstar) +// Luminosity chosen because the luminosity of a Dotstar at full bright +// burns the eyes like looking at the Sun. +// https://www.thesaurus.com/browse/luminosity?s=t +//| .. class:: LRGB +//| +//| * **order** *Luminosity*, Red, Green, Blue +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LRGB, 4, 1, 2, 3, 0, false, true) +//| .. class:: LRBG +//| +//| * **order** *Luminosity*, Red, Blue, Green +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LRBG, 4, 1, 3, 2, 0, false, true) +//| .. class:: LGRB +//| +//| * **order** *Luminosity*, Green, Red, Blue +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LGRB, 4, 2, 1, 3, 0, false, true) +//| .. class:: LGBR +//| +//| * **order** *Luminosity*, Green, Blue, Red +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LGBR, 4, 2, 3, 1, 0, false, true) +//| .. class:: LBRG +//| +//| * **order** *Luminosity*, Blue, Red, Green +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LBRG, 4, 3, 1, 2, 0, false, true) +//| .. class:: LBGR +//| +//| * **order** *Luminosity*, Blue, Green, Red +//| * **bpp** 4 +//| * **has_luminosity** True +//| +//| Actual format commonly used by DotStar (5 bit luninance value) +PIXELBUF_BYTEORDER(LBGR, 4, 3, 2, 1, 0, false, true) + +STATIC const mp_rom_map_elem_t pixelbuf_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pixelbuf) }, + { MP_ROM_QSTR(MP_QSTR_PixelBuf), MP_ROM_PTR(&pixelbuf_pixelbuf_type) }, + { MP_ROM_QSTR(MP_QSTR_ByteOrder), MP_ROM_PTR(&pixelbuf_byteorder_type) }, + { MP_ROM_QSTR(MP_QSTR_RGB), MP_ROM_PTR(&byteorder_RGB) }, + { MP_ROM_QSTR(MP_QSTR_RBG), MP_ROM_PTR(&byteorder_RBG) }, + { MP_ROM_QSTR(MP_QSTR_GRB), MP_ROM_PTR(&byteorder_GRB) }, + { MP_ROM_QSTR(MP_QSTR_GBR), MP_ROM_PTR(&byteorder_GBR) }, + { MP_ROM_QSTR(MP_QSTR_BRG), MP_ROM_PTR(&byteorder_BRG) }, + { MP_ROM_QSTR(MP_QSTR_BGR), MP_ROM_PTR(&byteorder_BGR) }, + { MP_ROM_QSTR(MP_QSTR_RGBW), MP_ROM_PTR(&byteorder_RGBW) }, + { MP_ROM_QSTR(MP_QSTR_RBGW), MP_ROM_PTR(&byteorder_RBGW) }, + { MP_ROM_QSTR(MP_QSTR_GRBW), MP_ROM_PTR(&byteorder_GRBW) }, + { MP_ROM_QSTR(MP_QSTR_GBRW), MP_ROM_PTR(&byteorder_GBRW) }, + { MP_ROM_QSTR(MP_QSTR_BRGW), MP_ROM_PTR(&byteorder_BRGW) }, + { MP_ROM_QSTR(MP_QSTR_BGRW), MP_ROM_PTR(&byteorder_BGRW) }, + { MP_ROM_QSTR(MP_QSTR_LRGB), MP_ROM_PTR(&byteorder_LRGB) }, + { MP_ROM_QSTR(MP_QSTR_LRBG), MP_ROM_PTR(&byteorder_LRBG) }, + { MP_ROM_QSTR(MP_QSTR_LGRB), MP_ROM_PTR(&byteorder_LGRB) }, + { MP_ROM_QSTR(MP_QSTR_LGBR), MP_ROM_PTR(&byteorder_LGBR) }, + { MP_ROM_QSTR(MP_QSTR_LBRG), MP_ROM_PTR(&byteorder_LBRG) }, + { MP_ROM_QSTR(MP_QSTR_LBGR), MP_ROM_PTR(&byteorder_LBGR) }, + { MP_ROM_QSTR(MP_QSTR_wheel), MP_ROM_PTR(&pixelbuf_wheel_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(pixelbuf_module_globals, pixelbuf_module_globals_table); + +STATIC void pixelbuf_byteorder_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + pixelbuf_byteorder_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "%q.%q", MP_QSTR__pixelbuf, self->name); + return; +} + +const mp_obj_module_t pixelbuf_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&pixelbuf_module_globals, +}; diff --git a/shared-bindings/_pixelbuf/__init__.h b/shared-bindings/_pixelbuf/__init__.h new file mode 100644 index 0000000000000..5049ea38d2bf8 --- /dev/null +++ b/shared-bindings/_pixelbuf/__init__.h @@ -0,0 +1,35 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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 CP_SHARED_BINDINGS_PIXELBUF_INIT_H +#define CP_SHARED_BINDINGS_PIXELBUF_INIT_H + +STATIC void pixelbuf_byteorder_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); +const int32_t colorwheel(float pos); + +const mp_obj_type_t pixelbuf_byteorder_type; + +#endif //CP_SHARED_BINDINGS_PIXELBUF_INIT_H diff --git a/shared-bindings/_pixelbuf/types.h b/shared-bindings/_pixelbuf/types.h new file mode 100644 index 0000000000000..f7d757791bf70 --- /dev/null +++ b/shared-bindings/_pixelbuf/types.h @@ -0,0 +1,48 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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 CIRCUITPYTHON_PIXELBUF_TYPES_H +#define CIRCUITPYTHON_PIXELBUF_TYPES_H + +//| :orphan: + +typedef struct { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t w; +} pixelbuf_rgbw_t; + +typedef struct { + mp_obj_base_t base; + qstr name; + uint8_t bpp; + pixelbuf_rgbw_t byteorder; + bool has_white; + bool has_luminosity; +} pixelbuf_byteorder_obj_t; + +#endif // CIRCUITPYTHON_PIXELBUF_TYPES_H diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst index 44b3492e67312..9641d73d14663 100644 --- a/shared-bindings/index.rst +++ b/shared-bindings/index.rst @@ -61,4 +61,6 @@ Module Supported Ports `touchio` **SAMD/SAMD Express** `uheap` **Debug (All)** `usb_hid` **SAMD/SAMD Express** +`_pixelbuf` **SAMD Express** +`_stage` **SAMD/SAMD Express** ================= ============================== diff --git a/shared-module/_pixelbuf/PixelBuf.c b/shared-module/_pixelbuf/PixelBuf.c new file mode 100644 index 0000000000000..d326972391934 --- /dev/null +++ b/shared-module/_pixelbuf/PixelBuf.c @@ -0,0 +1,120 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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/obj.h" +#include "py/objarray.h" +#include "py/runtime.h" +#include "PixelBuf.h" +#include + +void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_obj_t *byteorder) { + buf[byteorder->byteorder.r] = value >> 16 & 0xff; + buf[byteorder->byteorder.g] = (value >> 8) & 0xff; + buf[byteorder->byteorder.b] = value & 0xff; + if (byteorder->bpp == 4 && byteorder->has_white && + (buf[byteorder->byteorder.r] == buf[byteorder->byteorder.g] && + buf[byteorder->byteorder.r] == buf[byteorder->byteorder.b])) { + buf[byteorder->byteorder.w] = buf[byteorder->byteorder.r]; + buf[byteorder->byteorder.r] = buf[byteorder->byteorder.g] = buf[byteorder->byteorder.b] = 0; + } +} + +void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_t *item, pixelbuf_byteorder_obj_t *byteorder, bool dotstar) { + if (MP_OBJ_IS_INT(item)) { + uint8_t *target = rawbuf ? rawbuf : buf; + pixelbuf_set_pixel_int(target, mp_obj_get_int_truncated(item), byteorder); + if (dotstar) { + buf[0] = DOTSTAR_LED_START_FULL_BRIGHT; + if (rawbuf) + rawbuf[0] = DOTSTAR_LED_START_FULL_BRIGHT; + } + if (rawbuf) { + buf[byteorder->byteorder.r] = rawbuf[byteorder->byteorder.r] * brightness; + buf[byteorder->byteorder.g] = rawbuf[byteorder->byteorder.g] * brightness; + buf[byteorder->byteorder.b] = rawbuf[byteorder->byteorder.b] * brightness; + } else { + buf[byteorder->byteorder.r] *= brightness; + buf[byteorder->byteorder.g] *= brightness; + buf[byteorder->byteorder.b] *= brightness; + } + } else { + mp_obj_t *items; + size_t len; + mp_obj_get_array(item, &len, &items); + if (len != byteorder->bpp && !dotstar) + mp_raise_ValueError_varg(translate("Expected tuple of length %d, got %d"), byteorder->bpp, len); + + buf[byteorder->byteorder.r] = mp_obj_get_int_truncated(items[PIXEL_R]) * brightness; + buf[byteorder->byteorder.g] = mp_obj_get_int_truncated(items[PIXEL_G]) * brightness; + buf[byteorder->byteorder.b] = mp_obj_get_int_truncated(items[PIXEL_B]) * brightness; + if (rawbuf) { + rawbuf[byteorder->byteorder.r] = mp_obj_get_int_truncated(items[PIXEL_R]); + rawbuf[byteorder->byteorder.g] = mp_obj_get_int_truncated(items[PIXEL_G]); + rawbuf[byteorder->byteorder.b] = mp_obj_get_int_truncated(items[PIXEL_B]); + } + if (len > 3) { + if (dotstar) { + buf[byteorder->byteorder.w] = DOTSTAR_LED_START | DOTSTAR_BRIGHTNESS(mp_obj_get_float(items[PIXEL_W])); + if (rawbuf) + rawbuf[byteorder->byteorder.w] = buf[byteorder->byteorder.w]; + } else { + buf[byteorder->byteorder.w] = mp_obj_get_int_truncated(items[PIXEL_W]) * brightness; + if (rawbuf) + rawbuf[byteorder->byteorder.w] = mp_obj_get_int_truncated(items[PIXEL_W]); + } + } else if (dotstar) { + buf[byteorder->byteorder.w] = DOTSTAR_LED_START_FULL_BRIGHT; + if (rawbuf) + rawbuf[byteorder->byteorder.w] = DOTSTAR_LED_START_FULL_BRIGHT; + } + } +} + +mp_obj_t *pixelbuf_get_pixel_array(uint8_t *buf, uint len, pixelbuf_byteorder_obj_t *byteorder, uint8_t step, bool dotstar) { + mp_obj_t elems[len]; + for (uint i = 0; i < len; i++) { + elems[i] = pixelbuf_get_pixel(buf + (i * step), byteorder, dotstar); + } + return mp_obj_new_tuple(len, elems); +} + +mp_obj_t *pixelbuf_get_pixel(uint8_t *buf, pixelbuf_byteorder_obj_t *byteorder, bool dotstar) { + mp_obj_t elems[byteorder->bpp]; + + elems[0] = mp_obj_new_int(buf[byteorder->byteorder.r]); + elems[1] = mp_obj_new_int(buf[byteorder->byteorder.g]); + elems[2] = mp_obj_new_int(buf[byteorder->byteorder.b]); + if (byteorder->bpp > 3) + { + if (dotstar) + elems[3] = mp_obj_new_float(DOTSTAR_GET_BRIGHTNESS(buf[byteorder->byteorder.w])); + else + elems[3] = mp_obj_new_int(buf[byteorder->byteorder.w]); + } + + return mp_obj_new_tuple(byteorder->bpp, elems); +} diff --git a/shared-module/_pixelbuf/PixelBuf.h b/shared-module/_pixelbuf/PixelBuf.h new file mode 100644 index 0000000000000..9e115fe0cf0c7 --- /dev/null +++ b/shared-module/_pixelbuf/PixelBuf.h @@ -0,0 +1,50 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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/obj.h" +#include "py/objarray.h" +#include "../../shared-bindings/_pixelbuf/types.h" + +#ifndef PIXELBUF_SHARED_MODULE_H +#define PIXELBUF_SHARED_MODULE_H + +#define PIXEL_R 0 +#define PIXEL_G 1 +#define PIXEL_B 2 +#define PIXEL_W 3 + +#define DOTSTAR_LED_START 0b11100000 +#define DOTSTAR_BRIGHTNESS(brightness) ((32 - (uint8_t)(32 - brightness * 31)) & 0b00011111) +#define DOTSTAR_GET_BRIGHTNESS(value) ((value & 0b00011111) / 31.0) +#define DOTSTAR_LED_START_FULL_BRIGHT 0xFF + +void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_t *item, pixelbuf_byteorder_obj_t *byteorder, bool dotstar); +mp_obj_t *pixelbuf_get_pixel(uint8_t *buf, pixelbuf_byteorder_obj_t *byteorder, bool dotstar); +mp_obj_t *pixelbuf_get_pixel_array(uint8_t *buf, uint len, pixelbuf_byteorder_obj_t *byteorder, uint8_t step, bool dotstar); +void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_obj_t *byteorder); + +#endif diff --git a/shared-module/_pixelbuf/__init__.c b/shared-module/_pixelbuf/__init__.c new file mode 100644 index 0000000000000..e69de29bb2d1d From be9caeb9150df3ff8a30b2e7ab20f32b7fc9b5f7 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sun, 13 Jan 2019 23:52:05 -0500 Subject: [PATCH 092/153] update translations --- locale/ID.po | 71 +++++++++++++++++--- locale/circuitpython.pot | 57 +++++++++++++++- locale/de_DE.po | 91 ++++++++++++++++++++------ locale/en_US.po | 57 +++++++++++++++- locale/es.po | 136 ++++++++++++++++++++++++++++----------- locale/fil.po | 116 ++++++++++++++++++++++++--------- locale/fr.po | 108 +++++++++++++++++++++++-------- locale/it_IT.po | 106 +++++++++++++++++++++++------- locale/pt_BR.po | 90 ++++++++++++++++++++------ 9 files changed, 663 insertions(+), 169 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 952e12d4d3ede..ec91aad8065bd 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1964,7 +1964,7 @@ msgstr "" msgid "argument should be a '%q' not a '%q'" msgstr "" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "" @@ -2043,6 +2043,54 @@ msgstr "" msgid "byte code not implemented" msgstr "" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +msgid "readonly attribute" +msgstr "" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "" @@ -2493,6 +2541,11 @@ msgid "" "Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "" @@ -2688,13 +2741,6 @@ msgstr "" #~ msgid "Invalid UUID string length" #~ msgstr "Panjang string UUID tidak valid" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parameter UUID tidak valid" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" - #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " #~ "CIRCUITPY).\n" @@ -2702,6 +2748,13 @@ msgstr "" #~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " #~ "CIRCUITPY).\n" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parameter UUID tidak valid" + #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 5c85d09a8035a..37b403826a8e3 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: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1931,7 +1931,7 @@ msgstr "" msgid "argument should be a '%q' not a '%q'" msgstr "" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "" @@ -2010,6 +2010,54 @@ msgstr "" msgid "byte code not implemented" msgstr "" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +msgid "readonly attribute" +msgstr "" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "" @@ -2457,6 +2505,11 @@ msgid "" "Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 47098b66acb35..b8a8a43b651b9 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -1960,7 +1960,7 @@ msgstr "" msgid "argument should be a '%q' not a '%q'" msgstr "" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "" @@ -2039,6 +2039,54 @@ msgstr "" msgid "byte code not implemented" msgstr "" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +msgid "readonly attribute" +msgstr "" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "" @@ -2494,6 +2542,11 @@ msgid "" "Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "" @@ -2691,12 +2744,24 @@ msgstr "" #~ msgid "Invalid UUID parameter" #~ msgstr "Ungültiger UUID-Parameter" -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." + +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" + #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" @@ -2705,15 +2770,6 @@ msgstr "" #~ msgid "Can not encode UUID, to check length." #~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." - #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " #~ "CIRCUITPY).\n" @@ -2721,14 +2777,11 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." + #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Kann UUID in das advertisement packet kodieren." #~ msgid "Can not query for the device address." #~ msgstr "Kann nicht nach der Geräteadresse suchen." - -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." - -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." diff --git a/locale/en_US.po b/locale/en_US.po index ee47b08eab9bb..b485fa0785a70 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:31-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -1931,7 +1931,7 @@ msgstr "" msgid "argument should be a '%q' not a '%q'" msgstr "" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "" @@ -2010,6 +2010,54 @@ msgstr "" msgid "byte code not implemented" msgstr "" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +msgid "readonly attribute" +msgstr "" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "" @@ -2457,6 +2505,11 @@ msgid "" "Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "" diff --git a/locale/es.po b/locale/es.po index 1278e92cbdce9..2dd8e0105152b 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -1731,7 +1731,9 @@ msgstr "atributos aún no soportados" #: py/objstr.c:1079 msgid "" "can't switch from manual field specification to automatic field numbering" -msgstr "no se puede cambiar de especificación de campo manual a numeración automática de campos" +msgstr "" +"no se puede cambiar de especificación de campo manual a numeración " +"automática de campos" #: py/objstr.c:1171 msgid "invalid format specifier" @@ -1796,7 +1798,8 @@ msgstr "carácter no soportado '%c' (0x%x) en índice %d" #: py/objstr.c:1577 msgid "not all arguments converted during string formatting" -msgstr "no todos los argumentos fueron convertidos durante el formato de string" +msgstr "" +"no todos los argumentos fueron convertidos durante el formato de string" #: py/objstr.c:2102 msgid "can't convert to str implicitly" @@ -1972,7 +1975,7 @@ msgstr "el argumento tiene un tipo erroneo" msgid "argument should be a '%q' not a '%q'" msgstr "argumento deberia ser un '%q' no un '%q'" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "no hay tal atributo" @@ -2051,6 +2054,57 @@ msgstr "exception no activa para reraise" msgid "byte code not implemented" msgstr "codigo byte no implementado" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +#, fuzzy +msgid "Only slices with step=1 (aka None) are supported" +msgstr "solo se admiten segmentos con step=1 (alias None)" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +#, fuzzy +msgid "Range out of bounds" +msgstr "address fuera de límites" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +#, fuzzy +msgid "readonly attribute" +msgstr "atributo no legible" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "graphic debe ser 2048 bytes de largo" @@ -2509,6 +2563,11 @@ msgstr "" "El objeto se ha desinicializado y ya no se puede utilizar. Crea un nuevo " "objeto" +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "No se pudo asignar el primer buffer" @@ -2663,7 +2722,8 @@ msgid "" " with the contents of your CIRCUITPY drive and this message:\n" msgstr "" "Parece que nuestro código de CircuitPython ha fallado con fuerza. Whoops!\n" -"Por favor, crea un issue en https://github.com/adafruit/circuitpython/issues\n" +"Por favor, crea un issue en https://github.com/adafruit/circuitpython/" +"issues\n" " con el contenido de su unidad CIRCUITPY y este mensaje:\n" #: supervisor/shared/safe_mode.c:111 @@ -2688,8 +2748,8 @@ msgid "" msgstr "" "La alimentación del microcontrolador cayó. Por favor asegurate de que tu " "fuente de alimentación provee\n" -"suficiente energia para todo el circuito y presiona el botón de reset (despues" -"de expulsar CIRCUITPY).\n" +"suficiente energia para todo el circuito y presiona el botón de reset " +"(despuesde expulsar CIRCUITPY).\n" #: supervisor/shared/safe_mode.c:120 msgid "" @@ -2705,8 +2765,11 @@ msgid "" "The reset button was pressed while booting CircuitPython. Press again to " "exit safe mode.\n" msgstr "" -"El botón reset fue presionado mientras arrancaba CircuitPython. Presiona otra" -" vez para salir del modo seguro.\n" +"El botón reset fue presionado mientras arrancaba CircuitPython. Presiona " +"otra vez para salir del modo seguro.\n" + +#~ msgid "Wrong address length" +#~ msgstr "Longitud de address erronea" #~ msgid "Invalid UUID string length" #~ msgstr "Longitud de string UUID inválida" @@ -2714,17 +2777,34 @@ msgstr "" #~ msgid "Invalid UUID parameter" #~ msgstr "Parámetro UUID inválido" -#~ msgid "Wrong address length" -#~ msgstr "Longitud de address erronea" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." #~ msgid "Wrong number of bytes provided" #~ msgstr "Numero erroneo de bytes dados" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#, fuzzy +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " +#~ "unidad de almacenamiento CIRCUITPY:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "suficiente poder para todo el circuito y presiona reset (después de " +#~ "expulsar CIRCUITPY).\n" #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" @@ -2736,34 +2816,14 @@ msgstr "" #~ msgid "Can not encode UUID, to check length." #~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." + #~ msgid "Can not query for the device address." #~ msgstr "No se puede consultar la dirección del dispositivo." -#, fuzzy -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " -#~ "unidad de almacenamiento CIRCUITPY:\n" - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." - -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de Servicio inválido" - #~ msgid "Can not add Service." #~ msgstr "No se puede agregar el Servicio." #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "No se pueden establecer los parámetros PPCP." - -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "suficiente poder para todo el circuito y presiona reset (después de " -#~ "expulsar CIRCUITPY).\n" diff --git a/locale/fil.po b/locale/fil.po index 5daa673f70058..efab7c8be5da0 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -1977,7 +1977,7 @@ msgstr "may maling type ang argument" msgid "argument should be a '%q' not a '%q'" msgstr "argument ay dapat na '%q' hindi '%q'" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "walang ganoon na attribute" @@ -2056,6 +2056,57 @@ msgstr "walang aktibong exception para i-reraise" msgid "byte code not implemented" msgstr "byte code hindi pa implemented" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +#, fuzzy +msgid "Only slices with step=1 (aka None) are supported" +msgstr "ang mga slices lamang na may hakbang = 1 (aka None) ang sinusuportahan" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +#, fuzzy +msgid "Range out of bounds" +msgstr "wala sa sakop ang address" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +#, fuzzy +msgid "readonly attribute" +msgstr "hindi mabasa ang attribute" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "graphic ay dapat 2048 bytes ang haba" @@ -2518,6 +2569,11 @@ msgstr "" "Object ay deinitialized at hindi na magagamit. Lumikha ng isang bagong " "Object." +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "Hindi ma-iallocate ang first buffer" @@ -2718,23 +2774,42 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" +#~ msgid "Wrong address length" +#~ msgstr "Mali ang address length" + #~ msgid "Invalid UUID string length" #~ msgstr "Mali ang UUID string length" #~ msgid "Invalid UUID parameter" #~ msgstr "Mali ang UUID parameter" -#~ msgid "Wrong address length" -#~ msgstr "Mali ang address length" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." + +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." #~ msgid "Wrong number of bytes provided" #~ msgstr "Mali ang bilang ng bytes" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " +#~ "drive:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " +#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" @@ -2747,33 +2822,14 @@ msgstr "" #~ msgid "Can not encode UUID, to check length." #~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." + #~ msgid "Can not query for the device address." #~ msgstr "Hindi maaaring mag-query para sa address ng device." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " -#~ "drive:\n" - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." - -#~ msgid "Invalid Service type" -#~ msgstr "Mali ang tipo ng serbisyo" - #~ msgid "Can not add Service." #~ msgstr "Hindi maidaragdag ang serbisyo." #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Hindi ma-set ang PPCP parameters." - -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " -#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" diff --git a/locale/fr.po b/locale/fr.po index b27cfeb7996ce..18e50e084073d 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: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -1977,7 +1977,7 @@ msgstr "l'argument est d'un mauvais type" msgid "argument should be a '%q' not a '%q'" msgstr "l'argument devrait être un(e) '%q', pas '%q'" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "pas de tel attribut" @@ -2057,6 +2057,57 @@ msgstr "aucune exception active à relever" msgid "byte code not implemented" msgstr "bytecode non implémenté" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +#, fuzzy +msgid "Only slices with step=1 (aka None) are supported" +msgstr "seuls les slices avec 'step=1' (cad None) sont supportées" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +#, fuzzy +msgid "Range out of bounds" +msgstr "adresse hors limites" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +#, fuzzy +msgid "readonly attribute" +msgstr "attribut illisible" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "le graphic doit être long de 2048 octets" @@ -2540,6 +2591,11 @@ msgstr "" "L'objet a été désinitialisé et ne peut plus être utilisé. Créez un nouvel " "objet." +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "Impossible d'allouer le 1er tampon" @@ -2747,27 +2803,37 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer denouveau pour quitter de le mode sans-échec.\n" +#~ msgid "Wrong address length" +#~ msgstr "Mauvaise longueur d'adresse" + #~ msgid "Invalid UUID string length" #~ msgstr "Longeur de chaîne UUID invalide" #~ msgid "Invalid UUID parameter" #~ msgstr "Paramètre UUID invalide" -#~ msgid "Wrong address length" -#~ msgstr "Mauvaise longueur d'adresse" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" + +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." + +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" #, fuzzy #~ msgid "Wrong number of bytes provided" #~ msgstr "mauvais nombre d'octets fourni'" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" #, fuzzy #~ msgid "value_size must be power of two" @@ -2783,27 +2849,17 @@ msgstr "" #~ "assez de puissance pour l'ensemble du circuit et appuyez sur " #~ "'reset' (après avoir éjecter CIRCUITPY).\n" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" + #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "la palette doit être une displayio.Palette" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." - -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" - -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." - #~ msgid "Can not apply device name in the stack." #~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" #~ msgid "Can not query for the device address." #~ msgstr "Impossible d'obtenir l'adresse du périphérique" - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" - -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" diff --git a/locale/it_IT.po b/locale/it_IT.po index 9b54d5dc9ae3c..10fd1a2c609b0 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -1973,7 +1973,7 @@ msgstr "il tipo dell'argomento è errato" msgid "argument should be a '%q' not a '%q'" msgstr "l'argomento dovrebbe essere un '%q' e non un '%q'" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "attributo inesistente" @@ -2052,6 +2052,57 @@ msgstr "nessuna eccezione attiva da rilanciare" msgid "byte code not implemented" msgstr "byte code non implementato" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +#, fuzzy +msgid "Only slices with step=1 (aka None) are supported" +msgstr "solo slice con step=1 (aka None) sono supportate" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +#, fuzzy +msgid "Range out of bounds" +msgstr "indirizzo fuori limite" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +#, fuzzy +msgid "readonly attribute" +msgstr "attributo non leggibile" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "graphic deve essere lunga 2048 byte" @@ -2524,6 +2575,11 @@ msgstr "" "L'oggetto è stato deinizializzato e non può essere più usato. Crea un nuovo " "oggetto." +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "Impossibile allocare il primo buffer" @@ -2716,28 +2772,44 @@ msgid "" "exit safe mode.\n" msgstr "" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parametro UUID non valido" + #~ msgid "Invalid UUID string length" #~ msgstr "Lunghezza della stringa UUID non valida" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parametro UUID non valido" +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" #, fuzzy #~ msgid "Wrong number of bytes provided" #~ msgstr "numero di argomenti errato" -#~ msgid "Invalid Service type" -#~ msgstr "Tipo di servizio non valido" - #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." + +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " +#~ "espulso CIRCUITPY).\n" + #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" #~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " #~ "CIRCUITPY:\n" +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." + #~ msgid "Can not encode UUID, to check length." #~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." @@ -2749,27 +2821,11 @@ msgstr "" #~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " #~ "Whoops!\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." - #~ msgid "Cannot apply GAP parameters." #~ msgstr "Impossibile applicare i parametri GAP." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " -#~ "espulso CIRCUITPY).\n" - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." - -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." - -#~ msgid "Can not add Service." -#~ msgstr "Non è possibile aggiungere Service." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." #~ msgid "Can not apply device name in the stack." #~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 85fe90909cd07..5239e3e51c005 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-13 23:51-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -1949,7 +1949,7 @@ msgstr "argumento tem tipo errado" msgid "argument should be a '%q' not a '%q'" msgstr "" -#: py/runtime.c:1123 py/runtime.c:1197 +#: py/runtime.c:1123 py/runtime.c:1197 shared-bindings/_pixelbuf/__init__.c:106 msgid "no such attribute" msgstr "" @@ -2028,6 +2028,55 @@ msgstr "" msgid "byte code not implemented" msgstr "" +#: shared-bindings/_pixelbuf/PixelBuf.c:101 +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:106 +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:118 +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:123 +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:129 +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:394 +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:396 +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:405 +msgid "tuple/list required on RHS" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:421 +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c:444 +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c:112 +#, fuzzy +msgid "readonly attribute" +msgstr "atributo ilegível" + #: shared-bindings/_stage/Layer.c:71 msgid "graphic must be 2048 bytes long" msgstr "" @@ -2484,6 +2533,11 @@ msgid "" msgstr "" "Objeto foi desinicializado e não pode ser mais usaado. Crie um novo objeto." +#: shared-module/_pixelbuf/PixelBuf.c:69 +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" msgstr "Não pôde alocar primeiro buffer" @@ -2670,32 +2724,32 @@ msgid "" "exit safe mode.\n" msgstr "" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parâmetro UUID inválido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" + #~ msgid "Can not add Characteristic." #~ msgstr "Não é possível adicionar Característica." -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Pode codificar o UUID no pacote de anúncios." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Não é possível aplicar parâmetros GAP." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." #~ msgid "Baud rate too high for this SPI peripheral" #~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parâmetro UUID inválido" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possível aplicar parâmetros GAP." From f667d4d887bac4481af373d6d859c969edd81622 Mon Sep 17 00:00:00 2001 From: TG-Techie <39284876+TG-Techie@users.noreply.github.com> Date: Mon, 14 Jan 2019 14:43:34 -0500 Subject: [PATCH 093/153] Update mpconfigboard.mk oops, forgot to change those when i copied the folder --- ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk index 407026c202a12..162b2ca48c4cf 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk @@ -1,6 +1,6 @@ LD_FILE = boards/samd51x19-bootloader-external-flash.ld -USB_VID = 0x239A -USB_PID = 0x8021 +USB_VID = 0x4097 +USB_PID = 0x0001 USB_PRODUCT = "Datalore IP M4" USB_MANUFACTURER = "TG-Boards" From 3aeadb9f0c1bbf678d4289ec36489078543a503c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 14 Jan 2019 12:02:33 -0800 Subject: [PATCH 094/153] Remove ESP8266 build We're removing support in 4.0 because it doesn't have native usb. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 06231a594592c..16d094b47ddf0 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ git: # that SDK is shortest and add it there. In the case of major re-organizations, # just try to make the builds "about equal in run time" env: - - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="feather_huzzah circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf:esp8266 + - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm From b5f35b82e18ba1208fd5d5a66f304cbd4d2af999 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 14 Jan 2019 13:30:09 -0800 Subject: [PATCH 095/153] Remove from build info too --- tools/build_board_info.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/build_board_info.py b/tools/build_board_info.py index a4b49d16089f2..163ebf6240099 100644 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -12,7 +12,7 @@ sys.path.append("adabot") import adabot.github_requests as github -SUPPORTED_PORTS = ["nrf", "esp8266", "atmel-samd"] +SUPPORTED_PORTS = ["nrf", "atmel-samd"] BIN = ('bin',) UF2 = ('uf2',) @@ -22,7 +22,6 @@ # Default extensions extension_by_port = { "nrf": UF2, - "esp8266": BIN, "atmel-samd": UF2, } From a14762a16ca6e60fc2d26f028a08bcced597553b Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Sat, 12 Jan 2019 00:44:34 -0800 Subject: [PATCH 096/153] Add support for rendering a shape. Fixes #1171 --- ports/atmel-samd/Makefile | 1 + .../common-hal/displayio/FourWire.c | 2 +- shared-bindings/displayio/Shape.c | 117 ++++++++++++++++++ shared-bindings/displayio/Shape.h | 41 ++++++ shared-bindings/displayio/Sprite.c | 5 + shared-bindings/displayio/__init__.c | 3 + shared-module/displayio/Shape.c | 90 ++++++++++++++ shared-module/displayio/Shape.h | 46 +++++++ shared-module/displayio/Sprite.c | 3 + 9 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 shared-bindings/displayio/Shape.c create mode 100644 shared-bindings/displayio/Shape.h create mode 100644 shared-module/displayio/Shape.c create mode 100644 shared-module/displayio/Shape.h diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 852de75f39abd..04e42a971a8d6 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -382,6 +382,7 @@ SRC_SHARED_MODULE = \ displayio/Group.c \ displayio/OnDiskBitmap.c \ displayio/Palette.c \ + displayio/Shape.c \ displayio/Sprite.c \ gamepad/__init__.c \ gamepad/GamePad.c \ diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.c b/ports/atmel-samd/common-hal/displayio/FourWire.c index b550f1c907803..51e6de5a221d7 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.c +++ b/ports/atmel-samd/common-hal/displayio/FourWire.c @@ -70,7 +70,7 @@ bool common_hal_displayio_fourwire_begin_transaction(displayio_fourwire_obj_t* s return false; } // TODO(tannewt): Stop hardcoding SPI frequency, polarity and phase. - common_hal_busio_spi_configure(&self->bus, 12000000, 0, 0, 8); + common_hal_busio_spi_configure(&self->bus, 48000000, 0, 0, 8); common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); return true; } diff --git a/shared-bindings/displayio/Shape.c b/shared-bindings/displayio/Shape.c new file mode 100644 index 0000000000000..37a049d0c8148 --- /dev/null +++ b/shared-bindings/displayio/Shape.c @@ -0,0 +1,117 @@ +/* + * This file is part of the Micro Python 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 "shared-bindings/displayio/Shape.h" + +#include + +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`Shape` -- Represents a shape by defining its bounds on each row +//| ========================================================================== +//| +//| Represents any shape made by defining boundaries that may be mirrored. +//| +//| .. warning:: This will likely be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: Shape(width, height, *, mirror_x=False, mirrored_y=False) +//| +//| Create a Shape object with the given fixed size. Each pixel is one bit and is stored by the +//| column boundaries of the shape on each row. Each row's boundary defaults to the full row. +//| +//| :param int width: The number of pixels wide +//| :param int height: The number of pixels high +//| :param bool mirror_x: When true the left boundary is mirrored to the right. +//| :param bool mirror_y: When true the top boundary is mirrored to the bottom. +//| +STATIC mp_obj_t displayio_shape_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 2, 4, true); + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + enum { ARG_width, ARG_height, ARG_mirror_x, ARG_mirror_y }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_mirror_x, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_mirror_y, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + 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); + + displayio_shape_t *self = m_new_obj(displayio_shape_t); + self->base.type = &displayio_shape_type; + common_hal_displayio_shape_construct(self, + args[ARG_width].u_int, + args[ARG_height].u_int, + args[ARG_mirror_x].u_bool, + args[ARG_mirror_y].u_bool); + + return MP_OBJ_FROM_PTR(self); +} + + +//| .. method:: set_boundary(y, start_x, end_x) +//| +//| Loads pre-packed data into the given row. +//| +STATIC mp_obj_t displayio_shape_obj_set_boundary(size_t n_args, const mp_obj_t *args) { + (void) n_args; + displayio_shape_t *self = MP_OBJ_TO_PTR(args[0]); + mp_int_t y; + if (!mp_obj_get_int_maybe(args[1], &y)) { + mp_raise_ValueError(translate("y should be an int")); + } + mp_int_t start_x; + if (!mp_obj_get_int_maybe(args[2], &start_x)) { + mp_raise_ValueError(translate("start_x should be an int")); + } + mp_int_t end_x; + if (!mp_obj_get_int_maybe(args[3], &end_x)) { + mp_raise_ValueError(translate("end_x should be an int")); + } + common_hal_displayio_shape_set_boundary(self, y, start_x, end_x); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(displayio_shape_set_boundary_obj, 4, 4, displayio_shape_obj_set_boundary); + +STATIC const mp_rom_map_elem_t displayio_shape_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_set_boundary), MP_ROM_PTR(&displayio_shape_set_boundary_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_shape_locals_dict, displayio_shape_locals_dict_table); + +const mp_obj_type_t displayio_shape_type = { + { &mp_type_type }, + .name = MP_QSTR_Shape, + .make_new = displayio_shape_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_shape_locals_dict, +}; diff --git a/shared-bindings/displayio/Shape.h b/shared-bindings/displayio/Shape.h new file mode 100644 index 0000000000000..d08a38782295a --- /dev/null +++ b/shared-bindings/displayio/Shape.h @@ -0,0 +1,41 @@ +/* + * This file is part of the Micro Python 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_SHARED_BINDINGS_DISPLAYIO_SHAPE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SHAPE_H + +#include "shared-module/displayio/Shape.h" + +extern const mp_obj_type_t displayio_shape_type; + +void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t width, + uint32_t height, bool mirror_x, bool mirror_y); + +void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x, + uint16_t end_x); +uint32_t common_hal_displayio_shape_get_pixel(void *shape, int16_t x, int16_t y); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SHAPE_H diff --git a/shared-bindings/displayio/Sprite.c b/shared-bindings/displayio/Sprite.c index 69c1a58965efb..e739b48b7c76e 100644 --- a/shared-bindings/displayio/Sprite.c +++ b/shared-bindings/displayio/Sprite.c @@ -36,6 +36,7 @@ #include "shared-bindings/displayio/ColorConverter.h" #include "shared-bindings/displayio/OnDiskBitmap.h" #include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Shape.h" #include "supervisor/shared/translate.h" void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) { @@ -93,6 +94,10 @@ STATIC mp_obj_t displayio_sprite_make_new(const mp_obj_type_t *type, size_t n_ar displayio_ondiskbitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); width = bmp->width; height = bmp->height; + } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_shape_type)) { + displayio_shape_t* bmp = MP_OBJ_TO_PTR(bitmap); + width = bmp->width; + height = bmp->height; } else { mp_raise_TypeError(translate("unsupported bitmap type")); } diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 0610d71f6316a..d485d8095e0c8 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -36,6 +36,7 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/OnDiskBitmap.h" #include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Shape.h" #include "shared-bindings/displayio/Sprite.h" //| :mod:`displayio` --- Native display driving @@ -64,6 +65,7 @@ //| Group //| OnDiskBitmap //| Palette +//| Shape //| Sprite //| //| All libraries change hardware state but are never deinit @@ -76,6 +78,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) }, { MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) }, { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, + { MP_ROM_QSTR(MP_QSTR_Shape), MP_ROM_PTR(&displayio_shape_type) }, { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) }, { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c new file mode 100644 index 0000000000000..c0c52a279b740 --- /dev/null +++ b/shared-module/displayio/Shape.c @@ -0,0 +1,90 @@ +/* + * This file is part of the Micro Python 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 "shared-bindings/displayio/Shape.h" + +#include + +#include "py/runtime.h" + +void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t width, + uint32_t height, bool mirror_x, bool mirror_y) { + self->mirror_x = mirror_x; + self->mirror_y = mirror_y; + self->width = width; + if (self->mirror_x) { + width /= 2; + width += self->width % 2 - 1; + } + self->half_width = width; + + self->height = height; + if (self->mirror_y) { + height /= 2; + height += self->height % 2 - 1; + } + self->half_height = height; + + self->data = m_malloc(height * sizeof(uint32_t), false); + for (uint16_t i = 0; i < height; i++) { + self->data[2 * i] = 0; + self->data[2 * i + 1] = width; + } +} + +void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x, uint16_t end_x) { + if (y < 0 || y >= self->height || (self->mirror_y && y > self->half_height)) { + mp_raise_ValueError(translate("y value out of bounds")); + } + if (start_x < 0 || start_x > self->width || end_x < 0 || end_x > self->height) { + mp_raise_ValueError(translate("x value out of bounds")); + } + uint16_t half_width = self->width / 2 - 1 + self->width % 2; + if (self->mirror_x && (start_x > half_width || end_x > half_width)) { + mp_raise_ValueError_varg(translate("Maximum x value when mirrored is %d"), half_width); + } + self->data[2 * y] = start_x; + self->data[2 * y + 1] = end_x; +} + +uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) { + displayio_shape_t *self = obj; + if (x >= self->width || x < 0 || y >= self->height || y < 0) { + return 0; + } + if (self->mirror_x && x > self->half_width) { + x = self->width - 1 - x; + } + if (self->mirror_y && y > self->half_height) { + y = self->height - y - 1; + } + uint16_t start_x = self->data[2 * y]; + uint16_t end_x = self->data[2 * y + 1]; + if (x < start_x || x > end_x) { + return 0; + } + return 1; +} diff --git a/shared-module/displayio/Shape.h b/shared-module/displayio/Shape.h new file mode 100644 index 0000000000000..ca054fe0085e4 --- /dev/null +++ b/shared-module/displayio/Shape.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python 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_SHARED_MODULE_DISPLAYIO_SHAPE_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint16_t width; + uint16_t height; + uint16_t half_width; + uint16_t half_height; + uint16_t* data; + bool mirror_x; + bool mirror_y; +} displayio_shape_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H diff --git a/shared-module/displayio/Sprite.c b/shared-module/displayio/Sprite.c index 87600f721c437..da6eff896b8c1 100644 --- a/shared-module/displayio/Sprite.c +++ b/shared-module/displayio/Sprite.c @@ -30,6 +30,7 @@ #include "shared-bindings/displayio/ColorConverter.h" #include "shared-bindings/displayio/OnDiskBitmap.h" #include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Shape.h" void common_hal_displayio_sprite_construct(displayio_sprite_t *self, mp_obj_t bitmap, mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t x, uint16_t y) { @@ -71,6 +72,8 @@ bool displayio_sprite_get_pixel(displayio_sprite_t *self, int16_t x, int16_t y, uint32_t value = 0; if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { value = common_hal_displayio_bitmap_get_pixel(self->bitmap, x, y); + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + value = common_hal_displayio_shape_get_pixel(self->bitmap, x, y); } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, x, y); } From 619bc4caae15ceb7b6de547a5264c9eca9086fe9 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 14 Jan 2019 13:56:04 -0800 Subject: [PATCH 097/153] Support subclasses of Shape as bitmaps. --- shared-bindings/displayio/Sprite.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/shared-bindings/displayio/Sprite.c b/shared-bindings/displayio/Sprite.c index e739b48b7c76e..8aa9586ea6adf 100644 --- a/shared-bindings/displayio/Sprite.c +++ b/shared-bindings/displayio/Sprite.c @@ -86,16 +86,19 @@ STATIC mp_obj_t displayio_sprite_make_new(const mp_obj_type_t *type, size_t n_ar uint16_t width; uint16_t height; - if (MP_OBJ_IS_TYPE(bitmap, &displayio_bitmap_type)) { + mp_obj_t native = mp_instance_cast_to_native_base(bitmap, &displayio_shape_type); + if (native != MP_OBJ_NULL) { + displayio_shape_t* bmp = MP_OBJ_TO_PTR(native); + width = bmp->width; + height = bmp->height; + } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_bitmap_type)) { displayio_bitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); + native = bitmap; width = bmp->width; height = bmp->height; } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_ondiskbitmap_type)) { displayio_ondiskbitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); - width = bmp->width; - height = bmp->height; - } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_shape_type)) { - displayio_shape_t* bmp = MP_OBJ_TO_PTR(bitmap); + native = bitmap; width = bmp->width; height = bmp->height; } else { @@ -108,7 +111,7 @@ STATIC mp_obj_t displayio_sprite_make_new(const mp_obj_type_t *type, size_t n_ar displayio_sprite_t *self = m_new_obj(displayio_sprite_t); self->base.type = &displayio_sprite_type; - common_hal_displayio_sprite_construct(self, bitmap, args[ARG_pixel_shader].u_obj, + common_hal_displayio_sprite_construct(self, native, args[ARG_pixel_shader].u_obj, width, height, x, y); return MP_OBJ_FROM_PTR(self); } From 72d993d60c5e5238942491df00776ca31f9758a1 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 14 Jan 2019 15:14:40 -0800 Subject: [PATCH 098/153] py changes for supporting superclass constructors that take kwargs --- extmod/vfs.c | 2 +- extmod/vfs_fat.c | 6 ++--- extmod/vfs_fat_file.c | 4 ++-- py/argcheck.c | 13 ++++++++-- py/modbuiltins.c | 2 +- py/obj.h | 6 ++--- py/objarray.c | 12 +++++----- py/objbool.c | 4 ++-- py/objcomplex.c | 4 ++-- py/objdict.c | 10 ++++---- py/objenumerate.c | 4 ++-- py/objexcept.c | 14 +++++------ py/objfilter.c | 4 ++-- py/objfloat.c | 4 ++-- py/objfun.c | 10 ++++---- py/objint.c | 4 ++-- py/objlist.c | 4 ++-- py/objmap.c | 4 ++-- py/objnamedtuple.c | 9 +++---- py/objnamedtuple.h | 2 +- py/objobject.c | 4 ++-- py/objproperty.c | 4 ++-- py/objrange.c | 4 ++-- py/objreversed.c | 4 ++-- py/objset.c | 8 +++---- py/objslice.c | 6 ++--- py/objstr.c | 16 ++++++------- py/objstr.h | 2 +- py/objstringio.c | 4 ++-- py/objtuple.c | 4 ++-- py/objtype.c | 55 +++++++++++++++++++++++++++---------------- py/objtype.h | 2 +- py/objzip.c | 4 ++-- py/runtime.h | 3 ++- 34 files changed, 133 insertions(+), 109 deletions(-) diff --git a/extmod/vfs.c b/extmod/vfs.c index cc794aad5bcd0..7d6e6999bdf15 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -176,7 +176,7 @@ mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args // auto-detect the filesystem and create the corresponding VFS entity. // (At the moment we only support FAT filesystems.) #if MICROPY_VFS_FAT - vfs_obj = mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, 0, &vfs_obj); + vfs_obj = mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, &vfs_obj, NULL); #endif } diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 945ba9e8041ef..95dd6819aeef0 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -65,8 +65,8 @@ mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) { return MP_IMPORT_STAT_NO_EXIST; } -STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); +STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); // create new object fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t); @@ -111,7 +111,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_del_obj, fat_vfs_del); STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) { // create new object - fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, 0, &bdev_in)); + fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, &bdev_in, NULL)); // make the filesystem uint8_t working_buf[_MAX_SS]; diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index e3eebc9c482c3..75fa2fbd49f83 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -206,9 +206,9 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar return MP_OBJ_FROM_PTR(o); } -STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); + mp_arg_parse_all(n_args, args, kw_args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); return file_open(NULL, type, arg_vals); } diff --git a/py/argcheck.c b/py/argcheck.c index 5cc18d6a2bbb4..a8df206e280e1 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -31,13 +31,22 @@ #include "supervisor/shared/translate.h" -void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { + +void mp_arg_check_num(size_t n_args, mp_map_t *kw_args, size_t n_args_min, size_t n_args_max, bool takes_kw) { + size_t n_kw = 0; + if (kw_args != NULL) { + n_kw = kw_args->used; + } + mp_arg_check_num_kw_array(n_args, n_kw, n_args_min, n_args_max, takes_kw); +} + +void mp_arg_check_num_kw_array(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { // NOTE(tannewt): This prevents this function from being optimized away. // Without it, functions can crash when reading invalid args. __asm volatile (""); // TODO maybe take the function name as an argument so we can print nicer error messages - if (n_kw && !takes_kw) { + if (n_kw > 0 && !takes_kw) { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else diff --git a/py/modbuiltins.c b/py/modbuiltins.c index fc7ec24c74b56..e7ce7f9981d41 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -516,7 +516,7 @@ STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t if (n_args > 1) { mp_raise_TypeError(translate("must use keyword argument for key function")); } - mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args); + mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, args, NULL); mp_obj_list_sort(1, &self, kwargs); return self; diff --git a/py/obj.h b/py/obj.h index ece3b0ee0dd1f..74ce6a0a98d48 100644 --- a/py/obj.h +++ b/py/obj.h @@ -432,7 +432,7 @@ typedef struct _mp_obj_iter_buf_t { #define MP_OBJ_ITER_BUF_NSLOTS ((sizeof(mp_obj_iter_buf_t) + sizeof(mp_obj_t) - 1) / sizeof(mp_obj_t)) typedef void (*mp_print_fun_t)(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind); -typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); +typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, const mp_obj_t *args); typedef mp_obj_t (*mp_unary_op_fun_t)(mp_unary_op_t op, mp_obj_t); typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t); @@ -671,7 +671,7 @@ mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items); mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in); const char *mp_obj_get_type_str(mp_const_obj_t o_in); bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo); // arguments should be type objects -mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t native_type); +mp_obj_t mp_instance_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type); void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_print(mp_obj_t o, mp_print_kind_t kind); @@ -720,7 +720,7 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values); mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in); mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in); -mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in); void mp_init_emergency_exception_buf(void); diff --git a/py/objarray.c b/py/objarray.c index 0c8c7d855620e..9114a63c5a397 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -157,9 +157,9 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { #endif #if MICROPY_PY_ARRAY -STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 1, 2, false); + mp_arg_check_num(n_args, kw_args, 1, 2, false); // get typecode const char *typecode = mp_obj_str_get_str(args[0]); @@ -175,9 +175,9 @@ STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, size #endif #if MICROPY_PY_BUILTINS_BYTEARRAY -STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); if (n_args == 0) { // no args: construct an empty bytearray @@ -207,13 +207,13 @@ mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items) { return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; // TODO possibly allow memoryview constructor to take start/stop so that one // can do memoryview(b, 4, 8) instead of memoryview(b)[4:8] (uses less RAM) - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num(n_args, kw_args, 1, 1, false); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); diff --git a/py/objbool.c b/py/objbool.c index 5755b188e98cd..cd7d7100c9c68 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -50,9 +50,9 @@ STATIC void bool_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ } } -STATIC mp_obj_t bool_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t bool_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); if (n_args == 0) { return mp_const_false; diff --git a/py/objcomplex.c b/py/objcomplex.c index 3336d7b055f30..b38e2c5fa6268 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -75,9 +75,9 @@ STATIC void complex_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_ } } -STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 2, false); + mp_arg_check_num(n_args, kw_args, 0, 2, false); switch (n_args) { case 0: diff --git a/py/objdict.c b/py/objdict.c index cd110f1c17bc4..f672ac039e51c 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -81,7 +81,7 @@ STATIC void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ } } -STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_obj_t dict_out = mp_obj_new_dict(0); mp_obj_dict_t *dict = MP_OBJ_TO_PTR(dict_out); dict->base.type = type; @@ -90,11 +90,9 @@ STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n dict->map.is_ordered = 1; } #endif - if (n_args > 0 || n_kw > 0) { + if (n_args > 0 || kw_args != NULL) { mp_obj_t args2[2] = {dict_out, args[0]}; // args[0] is always valid, even if it's not a positional arg - mp_map_t kwargs; - mp_map_init_fixed_table(&kwargs, n_kw, args + n_args); - dict_update(n_args + 1, args2, &kwargs); // dict_update will check that n_args + 1 == 1 or 2 + dict_update(n_args + 1, args2, kw_args); // dict_update will check that n_args + 1 == 1 or 2 } return dict_out; } @@ -328,7 +326,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg mp_obj_dict_t *self = MP_OBJ_TO_PTR(args[0]); mp_ensure_not_fixed(self); - mp_arg_check_num(n_args, kwargs->used, 1, 2, true); + mp_arg_check_num(n_args, kwargs, 1, 2, true); if (n_args == 2) { // given a positional argument diff --git a/py/objenumerate.c b/py/objenumerate.c index 1a9d30f8368fd..4919a9b8f0599 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -39,7 +39,7 @@ typedef struct _mp_obj_enumerate_t { STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in); -STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { #if MICROPY_CPYTHON_COMPAT static const mp_arg_t allowed_args[] = { { MP_QSTR_iterable, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, @@ -50,7 +50,7 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz struct { mp_arg_val_t iterable, start; } arg_vals; - mp_arg_parse_all_kw_array(n_args, n_kw, args, + mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&arg_vals); // create enumerate object diff --git a/py/objexcept.c b/py/objexcept.c index c54e5fd4a5c59..0e9255db73c22 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -130,8 +130,8 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind); } -mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); +mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, MP_OBJ_FUN_ARGS_MAX, false); // Try to allocate memory for the exception, with fallback to emergency exception object mp_obj_exception_t *o_exc = m_new_obj_maybe(mp_obj_exception_t); @@ -336,7 +336,7 @@ mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args) { assert(exc_type->make_new == mp_obj_exception_make_new); - return exc_type->make_new(exc_type, n_args, 0, args); + return exc_type->make_new(exc_type, n_args, args, NULL); } mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) { @@ -438,7 +438,7 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const com o_str->base.type = &mp_type_str; o_str->hash = qstr_compute_hash(o_str->data, o_str->len); mp_obj_t arg = MP_OBJ_FROM_PTR(o_str); - return mp_obj_exception_make_new(exc_type, 1, 0, &arg); + return mp_obj_exception_make_new(exc_type, 1, &arg, NULL); } // return true if the given object is an exception type @@ -607,7 +607,7 @@ STATIC mp_obj_t code_make_new(qstr file, qstr block) { mp_obj_new_bytearray(0, NULL), // co_lnotab }; - return namedtuple_make_new((const mp_obj_type_t*)&code_type_obj, 15, 0, elems); + return namedtuple_make_new((const mp_obj_type_t*)&code_type_obj, 15, elems, NULL); } STATIC const mp_obj_namedtuple_type_t frame_type_obj = { @@ -650,7 +650,7 @@ STATIC mp_obj_t frame_make_new(mp_obj_t f_code, int f_lineno) { mp_const_none, // f_trace }; - return namedtuple_make_new((const mp_obj_type_t*)&frame_type_obj, 8, 0, elems); + return namedtuple_make_new((const mp_obj_type_t*)&frame_type_obj, 8, elems, NULL); } STATIC const mp_obj_namedtuple_type_t traceback_type_obj = { @@ -687,7 +687,7 @@ STATIC mp_obj_t traceback_from_values(size_t *values, mp_obj_t tb_next) { tb_next, }; - return namedtuple_make_new((const mp_obj_type_t*)&traceback_type_obj, 4, 0, elems); + return namedtuple_make_new((const mp_obj_type_t*)&traceback_type_obj, 4, elems, NULL); }; mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in) { diff --git a/py/objfilter.c b/py/objfilter.c index cb965d8c32350..af95326e6097c 100644 --- a/py/objfilter.c +++ b/py/objfilter.c @@ -34,8 +34,8 @@ typedef struct _mp_obj_filter_t { mp_obj_t iter; } mp_obj_filter_t; -STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, 2, false); +STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, 2, false); mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t); o->base.type = type; o->fun = args[0]; diff --git a/py/objfloat.c b/py/objfloat.c index c3f47018c65bf..f544ade0530f8 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -133,9 +133,9 @@ STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t } } -STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); switch (n_args) { case 0: diff --git a/py/objfun.c b/py/objfun.c index 8c51d92e0680e..2ada0b3f1678b 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -52,7 +52,7 @@ STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw, (void)args; assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_0)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_check_num(n_args, n_kw, 0, 0, false); + mp_arg_check_num_kw_array(n_args, n_kw, 0, 0, false); return self->fun._0(); } @@ -66,7 +66,7 @@ const mp_obj_type_t mp_type_fun_builtin_0 = { STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_1)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num_kw_array(n_args, n_kw, 1, 1, false); return self->fun._1(args[0]); } @@ -80,7 +80,7 @@ const mp_obj_type_t mp_type_fun_builtin_1 = { STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_2)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_check_num(n_args, n_kw, 2, 2, false); + mp_arg_check_num_kw_array(n_args, n_kw, 2, 2, false); return self->fun._2(args[0], args[1]); } @@ -94,7 +94,7 @@ const mp_obj_type_t mp_type_fun_builtin_2 = { STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_3)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_check_num(n_args, n_kw, 3, 3, false); + mp_arg_check_num_kw_array(n_args, n_kw, 3, 3, false); return self->fun._3(args[0], args[1], args[2]); } @@ -110,7 +110,7 @@ STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_k mp_obj_fun_builtin_var_t *self = MP_OBJ_TO_PTR(self_in); // check number of arguments - mp_arg_check_num(n_args, n_kw, self->n_args_min, self->n_args_max, self->is_kw); + mp_arg_check_num_kw_array(n_args, n_kw, self->n_args_min, self->n_args_max, self->is_kw); if (self->is_kw) { // function allows keywords diff --git a/py/objint.c b/py/objint.c index 2ac370d17b33f..fd746d3310366 100644 --- a/py/objint.c +++ b/py/objint.c @@ -42,9 +42,9 @@ #endif // This dispatcher function is expected to be independent of the implementation of long int -STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 2, false); + mp_arg_check_num(n_args, kw_args, 0, 2, false); switch (n_args) { case 0: diff --git a/py/objlist.c b/py/objlist.c index d4f9b022240a9..67940e44c883f 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -68,9 +68,9 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) { return list; } -STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); switch (n_args) { case 0: diff --git a/py/objmap.c b/py/objmap.c index 908c61507e77e..cf71f99eeb07d 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -36,8 +36,8 @@ typedef struct _mp_obj_map_t { mp_obj_t iters[]; } mp_obj_map_t; -STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, MP_OBJ_FUN_ARGS_MAX, false); +STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, MP_OBJ_FUN_ARGS_MAX, false); mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1); o->base.type = type; o->n_iters = n_args - 1; diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 800991c432d73..781a1871bfe54 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -93,9 +93,10 @@ void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { const mp_obj_namedtuple_type_t *type = (const mp_obj_namedtuple_type_t*)type_in; size_t num_fields = type->n_fields; + size_t n_kw = kw_args->used; if (n_args + n_kw != num_fields) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); @@ -119,8 +120,8 @@ mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t // Fill in the remaining slots with the keyword args memset(&tuple->items[n_args], 0, sizeof(mp_obj_t) * n_kw); - for (size_t i = n_args; i < n_args + 2 * n_kw; i += 2) { - qstr kw = mp_obj_str_get_qstr(args[i]); + for (size_t i = 0; i < n_kw; i++) { + qstr kw = mp_obj_str_get_qstr(kw_args->table[i].key); size_t id = mp_obj_namedtuple_find_field(type, kw); if (id == (size_t)-1) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { @@ -138,7 +139,7 @@ mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t translate("function got multiple values for argument '%q'"), kw); } } - tuple->items[id] = args[i + 1]; + tuple->items[id] = kw_args->table[i].value; } return MP_OBJ_FROM_PTR(tuple); diff --git a/py/objnamedtuple.h b/py/objnamedtuple.h index deac7107be5fa..0ea0d28622d80 100644 --- a/py/objnamedtuple.h +++ b/py/objnamedtuple.h @@ -51,7 +51,7 @@ void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t ki size_t mp_obj_namedtuple_find_field(const mp_obj_namedtuple_type_t *type, qstr name); void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields); -mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); #endif // MICROPY_PY_COLLECTIONS diff --git a/py/objobject.c b/py/objobject.c index fa8c29cffce32..a42edde3c6cd4 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -35,9 +35,9 @@ typedef struct _mp_obj_object_t { mp_obj_base_t base; } mp_obj_object_t; -STATIC mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)args; - mp_arg_check_num(n_args, n_kw, 0, 0, false); + mp_arg_check_num(n_args, kw_args, 0, 0, false); mp_obj_object_t *o = m_new_obj(mp_obj_object_t); o->base.type = type; return MP_OBJ_FROM_PTR(o); diff --git a/py/objproperty.c b/py/objproperty.c index 4aba6c7a12b65..ddf484af2b9c7 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -33,7 +33,7 @@ #if MICROPY_PY_BUILTINS_PROPERTY -STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { enum { ARG_fget, ARG_fset, ARG_fdel, ARG_doc }; static const mp_arg_t allowed_args[] = { { MP_QSTR_, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, @@ -42,7 +42,7 @@ STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size { MP_QSTR_doc, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, }; mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals); + mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals); mp_obj_property_t *o = m_new_obj(mp_obj_property_t); o->base.type = type; diff --git a/py/objrange.c b/py/objrange.c index 33c0d9b11cb06..30d55c56cdd26 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -91,8 +91,8 @@ STATIC void range_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind } } -STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 3, false); +STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 3, false); mp_obj_range_t *o = m_new_obj(mp_obj_range_t); o->base.type = type; diff --git a/py/objreversed.c b/py/objreversed.c index e498b553de8f4..4937d0818963e 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -37,8 +37,8 @@ typedef struct _mp_obj_reversed_t { mp_uint_t cur_index; // current index, plus 1; 0=no more, 1=last one (index 0) } mp_obj_reversed_t; -STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); +STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); // check if __reversed__ exists, and if so delegate to it mp_obj_t dest[2]; diff --git a/py/objset.c b/py/objset.c index 00d6eae0e00f9..5d1608c7ea9e6 100644 --- a/py/objset.c +++ b/py/objset.c @@ -103,8 +103,8 @@ STATIC void set_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t #endif } -STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); switch (n_args) { case 0: { @@ -299,7 +299,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool if (is_set_or_frozenset(self_in)) { self = MP_OBJ_TO_PTR(self_in); } else { - self = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, 0, &self_in)); + self = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, &self_in, NULL)); cleanup_self = true; } @@ -308,7 +308,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool if (is_set_or_frozenset(other_in)) { other = MP_OBJ_TO_PTR(other_in); } else { - other = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, 0, &other_in)); + other = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, &other_in, NULL)); cleanup_other = true; } mp_obj_t out = mp_const_true; diff --git a/py/objslice.c b/py/objslice.c index 08f18935bb7bd..5a15be55aac25 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -130,7 +130,7 @@ STATIC void slice_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type, - size_t n_args, size_t n_kw, const mp_obj_t *args); + size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); #endif const mp_obj_type_t mp_type_slice = { @@ -154,12 +154,12 @@ mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) { #if MICROPY_PY_BUILTINS_SLICE_ATTRS STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type, - size_t n_args, size_t n_kw, const mp_obj_t *args) { + size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { if (type != &mp_type_slice) { mp_raise_NotImplementedError(translate("Cannot subclass slice")); } // check number of arguments - mp_arg_check_num(n_args, n_kw, 1, 3, false); + mp_arg_check_num(n_args, kw_args, 1, 3, false); // 1st argument is the pin mp_obj_t start = mp_const_none; diff --git a/py/objstr.c b/py/objstr.c index 621f1b837c150..637323f4cbadc 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -132,14 +132,14 @@ STATIC void str_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t } } -mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { #if MICROPY_CPYTHON_COMPAT - if (n_kw != 0) { + if (kw_args != NULL && kw_args->used != 0) { mp_arg_error_unimpl_kw(); } #endif - mp_arg_check_num(n_args, n_kw, 0, 3, false); + mp_arg_check_num(n_args, kw_args, 0, 3, false); switch (n_args) { case 0: @@ -190,11 +190,11 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ } } -STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; #if MICROPY_CPYTHON_COMPAT - if (n_kw != 0) { + if (kw_args != NULL && kw_args->used != 0) { mp_arg_error_unimpl_kw(); } #else @@ -455,7 +455,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { if (!MP_OBJ_IS_TYPE(arg, &mp_type_list) && !MP_OBJ_IS_TYPE(arg, &mp_type_tuple)) { // arg is not a list nor a tuple, try to convert it to a list // TODO: Try to optimize? - arg = mp_type_list.make_new(&mp_type_list, 1, 0, &arg); + arg = mp_type_list.make_new(&mp_type_list, 1, &arg, NULL); } mp_obj_get_array(arg, &seq_len, &seq_items); @@ -1875,7 +1875,7 @@ STATIC mp_obj_t bytes_decode(size_t n_args, const mp_obj_t *args) { args = new_args; n_args++; } - return mp_obj_str_make_new(&mp_type_str, n_args, 0, args); + return mp_obj_str_make_new(&mp_type_str, n_args, args, NULL); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj, 1, 3, bytes_decode); @@ -1888,7 +1888,7 @@ STATIC mp_obj_t str_encode(size_t n_args, const mp_obj_t *args) { args = new_args; n_args++; } - return bytes_make_new(NULL, n_args, 0, args); + return bytes_make_new(NULL, n_args, args, NULL); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj, 1, 3, str_encode); #endif diff --git a/py/objstr.h b/py/objstr.h index 4e55cad0913e1..89513044617d2 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -61,7 +61,7 @@ const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len); else { str_len = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->len; str_data = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->data; } #endif -mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); void mp_str_print_json(const mp_print_t *print, const byte *str_data, size_t str_len); mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args); diff --git a/py/objstringio.c b/py/objstringio.c index d21248ad7286c..d2ca6decdbaf0 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -186,8 +186,8 @@ STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type) { return o; } -STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - (void)n_kw; // TODO check n_kw==0 +STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + (void)kw_args; // TODO check kw_args->used == 0 mp_uint_t sz = 16; bool initdata = false; diff --git a/py/objtuple.c b/py/objtuple.c index b4f5b1bdff783..d3262cebd44e9 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -59,10 +59,10 @@ void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t } } -STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); switch (n_args) { case 0: diff --git a/py/objtype.c b/py/objtype.c index 95dfc2a15c52c..f7fe3b3f69be5 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -50,7 +50,7 @@ #define TYPE_FLAG_IS_SUBCLASSED (0x0001) #define TYPE_FLAG_HAS_SPECIAL_ACCESSORS (0x0002) -STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); /******************************************************************************/ // instance object @@ -90,14 +90,14 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t // This wrapper function is allows a subclass of a native type to call the // __init__() method (corresponding to type->make_new) of the native type. -STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *args) { - mp_obj_instance_t *self = MP_OBJ_TO_PTR(args[0]); +STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_obj_instance_t *self = MP_OBJ_TO_PTR(pos_args[0]); const mp_obj_type_t *native_base = NULL; instance_count_native_bases(self->base.type, &native_base); - self->subobj[0] = native_base->make_new(native_base, n_args - 1, 0, args + 1); + self->subobj[0] = native_base->make_new(native_base, n_args - 1, pos_args + 1, kw_args); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(native_base_init_wrapper_obj, 1, MP_OBJ_FUN_ARGS_MAX, native_base_init_wrapper); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(native_base_init_wrapper_obj, 1, native_base_init_wrapper); #if !MICROPY_CPYTHON_COMPAT STATIC @@ -281,7 +281,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k mp_printf(print, "<%s object at %p>", mp_obj_get_type_str(self_in), self); } -mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { assert(mp_obj_is_instance_type(self)); // look for __new__ function @@ -297,6 +297,10 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size const mp_obj_type_t *native_base = NULL; mp_obj_instance_t *o; + size_t n_kw = 0; + if (kw_args != 0) { + n_kw = kw_args->used; + } if (init_fn[0] == MP_OBJ_NULL || init_fn[0] == MP_OBJ_SENTINEL) { // Either there is no __new__() method defined or there is a native // constructor. In both cases create a blank instance. @@ -315,9 +319,12 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size mp_obj_t args2[1] = {MP_OBJ_FROM_PTR(self)}; new_ret = mp_call_function_n_kw(init_fn[0], 1, 0, args2); } else { + // TODO(tannewt): Could this be on the stack? It's deleted below. mp_obj_t *args2 = m_new(mp_obj_t, 1 + n_args + 2 * n_kw); args2[0] = MP_OBJ_FROM_PTR(self); - memcpy(args2 + 1, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t)); + memcpy(args2 + 1, args, n_args * sizeof(mp_obj_t)); + // copy in kwargs + memcpy(args2 + 1 + n_args, kw_args->table, 2 * n_kw * sizeof(mp_obj_t)); new_ret = mp_call_function_n_kw(init_fn[0], n_args + 1, n_kw, args2); m_del(mp_obj_t, args2, 1 + n_args + 2 * n_kw); } @@ -343,13 +350,16 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size mp_obj_class_lookup(&lookup, self); if (init_fn[0] != MP_OBJ_NULL) { mp_obj_t init_ret; - if (n_args == 0 && n_kw == 0) { + if (n_args == 0 && kw_args == NULL) { init_ret = mp_call_method_n_kw(0, 0, init_fn); } else { + // TODO(tannewt): Could this be on the stack? It's deleted below. mp_obj_t *args2 = m_new(mp_obj_t, 2 + n_args + 2 * n_kw); args2[0] = init_fn[0]; args2[1] = init_fn[1]; - memcpy(args2 + 2, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t)); + // copy in kwargs + memcpy(args2 + 2, args, n_args * sizeof(mp_obj_t)); + memcpy(args2 + 2 + n_args, kw_args->table, 2 * n_kw * sizeof(mp_obj_t)); init_ret = mp_call_method_n_kw(n_args, n_kw, args2); m_del(mp_obj_t, args2, 2 + n_args + 2 * n_kw); } @@ -367,7 +377,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size // If the type had a native base that was not explicitly initialised // (constructed) by the Python __init__() method then construct it now. if (native_base != NULL && o->subobj[0] == MP_OBJ_FROM_PTR(&native_base_init_wrapper_obj)) { - o->subobj[0] = native_base->make_new(native_base, n_args, n_kw, args); + o->subobj[0] = native_base->make_new(native_base, n_args, args, kw_args); } return MP_OBJ_FROM_PTR(o); @@ -959,10 +969,10 @@ STATIC void type_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ mp_printf(print, "", self->name); } -STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 1, 3, false); + mp_arg_check_num(n_args, kw_args, 1, 3, false); switch (n_args) { case 1: @@ -992,8 +1002,10 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp } } - // make new instance - mp_obj_t o = self->make_new(self, n_args, n_kw, args); + // create a map directly from the given args array and make a new instance + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + mp_obj_t o = self->make_new(self, n_args, args, &kw_args); // return new instance return o; @@ -1170,7 +1182,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) // __new__ slot exists; check if it is a function if (MP_OBJ_IS_FUN(elem->value)) { // __new__ is a function, wrap it in a staticmethod decorator - elem->value = static_class_method_make_new(&mp_type_staticmethod, 1, 0, &elem->value); + elem->value = static_class_method_make_new(&mp_type_staticmethod, 1, &elem->value, NULL); } } @@ -1196,11 +1208,11 @@ STATIC void super_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind mp_print_str(print, ">"); } -STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; // 0 arguments are turned into 2 in the compiler // 1 argument is not yet implemented - mp_arg_check_num(n_args, n_kw, 2, 2, false); + mp_arg_check_num(n_args, kw_args, 2, 2, false); if(!MP_OBJ_IS_TYPE(args[0], &mp_type_type)) { mp_raise_TypeError(translate("first argument to super() must be type")); } @@ -1394,11 +1406,14 @@ STATIC mp_obj_t mp_builtin_isinstance(mp_obj_t object, mp_obj_t classinfo) { MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_isinstance_obj, mp_builtin_isinstance); -mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t native_type) { +mp_obj_t mp_instance_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type) { mp_obj_type_t *self_type = mp_obj_get_type(self_in); if (!mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(self_type), native_type)) { return MP_OBJ_NULL; } + if (MP_OBJ_FROM_PTR(self_type) == native_type) { + return self_in; + } mp_obj_instance_t *self = (mp_obj_instance_t*)MP_OBJ_TO_PTR(self_in); return self->subobj[0]; } @@ -1406,10 +1421,10 @@ mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t /******************************************************************************/ // staticmethod and classmethod types (probably should go in a different file) -STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { assert(self == &mp_type_staticmethod || self == &mp_type_classmethod); - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num(n_args, kw_args, 1, 1, false); mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t); *o = (mp_obj_static_class_method_t){{self}, args[0]}; diff --git a/py/objtype.h b/py/objtype.h index 3fc8c6e1b0f4b..13613f01f8347 100644 --- a/py/objtype.h +++ b/py/objtype.h @@ -49,6 +49,6 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons #define mp_obj_is_instance_type(type) ((type)->make_new == mp_obj_instance_make_new) #define mp_obj_is_native_type(type) ((type)->make_new != mp_obj_instance_make_new) // this needs to be exposed for the above macros to work correctly -mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); #endif // MICROPY_INCLUDED_PY_OBJTYPE_H diff --git a/py/objzip.c b/py/objzip.c index 0183925e3c523..ce9afd55dec44 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -36,8 +36,8 @@ typedef struct _mp_obj_zip_t { mp_obj_t iters[]; } mp_obj_zip_t; -STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); +STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, MP_OBJ_FUN_ARGS_MAX, false); mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args); o->base.type = type; diff --git a/py/runtime.h b/py/runtime.h index ece226e7ab3e9..e52d3232ee300 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -77,8 +77,9 @@ bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg); // extra printing method specifically for mp_obj_t's which are integral type int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char, int flags, char fill, int width, int prec); -void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw); +void mp_arg_check_num(size_t n_args, mp_map_t *kw_args, size_t n_args_min, size_t n_args_max, bool takes_kw); void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); +void mp_arg_check_num_kw_array(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw); void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); NORETURN void mp_arg_error_terse_mismatch(void); NORETURN void mp_arg_error_unimpl_kw(void); From 747f2cfe267628fda8487c533ce7a5ab10a9388f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 14 Jan 2019 17:26:36 -0800 Subject: [PATCH 099/153] Add subclass support to displayio. Also, swap make_news to accept a kwarg map and refine param checking. Fixes #1237 --- shared-bindings/_stage/Layer.c | 4 +-- shared-bindings/_stage/Text.c | 4 +-- shared-bindings/analogio/AnalogIn.c | 4 +-- shared-bindings/analogio/AnalogOut.c | 4 +-- shared-bindings/audiobusio/I2SOut.c | 7 ++--- shared-bindings/audiobusio/PDMIn.c | 16 +++++------ shared-bindings/audioio/AudioOut.c | 7 ++--- shared-bindings/audioio/Mixer.c | 7 ++--- shared-bindings/audioio/RawSample.c | 7 ++--- shared-bindings/audioio/WaveFile.c | 4 +-- shared-bindings/bitbangio/I2C.c | 14 ++++------ shared-bindings/bitbangio/OneWire.c | 7 ++--- shared-bindings/bitbangio/SPI.c | 12 ++++---- shared-bindings/busio/I2C.c | 7 ++--- shared-bindings/busio/OneWire.c | 7 ++--- shared-bindings/busio/SPI.c | 7 ++--- shared-bindings/busio/UART.c | 7 ++--- shared-bindings/digitalio/DigitalInOut.c | 4 +-- shared-bindings/displayio/Bitmap.c | 4 +-- shared-bindings/displayio/ColorConverter.c | 4 +-- shared-bindings/displayio/FourWire.c | 9 ++++-- shared-bindings/displayio/Group.c | 7 ++--- shared-bindings/displayio/OnDiskBitmap.c | 4 +-- shared-bindings/displayio/Palette.c | 9 ++---- shared-bindings/displayio/Shape.c | 11 +++----- shared-bindings/displayio/Sprite.c | 9 ++---- shared-bindings/gamepad/GamePad.c | 2 +- shared-bindings/i2cslave/I2CSlave.c | 11 +++----- shared-bindings/pulseio/PWMOut.c | 28 +++++++++---------- shared-bindings/pulseio/PulseIn.c | 7 ++--- shared-bindings/pulseio/PulseOut.c | 4 +-- shared-bindings/rotaryio/IncrementalEncoder.c | 7 ++--- shared-bindings/rtc/RTC.c | 4 +-- shared-bindings/time/__init__.c | 8 +++--- shared-bindings/touchio/TouchIn.c | 4 +-- shared-bindings/usb_hid/Device.c | 2 +- shared-bindings/usb_midi/PortIn.c | 2 +- shared-bindings/usb_midi/PortOut.c | 2 +- shared-module/displayio/Group.c | 7 +++++ shared-module/displayio/__init__.c | 17 +++++++++-- supervisor/shared/flash.c | 4 +-- 41 files changed, 132 insertions(+), 163 deletions(-) diff --git a/shared-bindings/_stage/Layer.c b/shared-bindings/_stage/Layer.c index a3334f635fb3a..12028b131976a 100644 --- a/shared-bindings/_stage/Layer.c +++ b/shared-bindings/_stage/Layer.c @@ -51,8 +51,8 @@ //| it shouldn't be used on its own. //| STATIC mp_obj_t layer_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 4, 5, false); + const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 4, 5, false); layer_obj_t *self = m_new_obj(layer_obj_t); self->base.type = type; diff --git a/shared-bindings/_stage/Text.c b/shared-bindings/_stage/Text.c index 7a406271dfb62..49c1d00ca8a48 100644 --- a/shared-bindings/_stage/Text.c +++ b/shared-bindings/_stage/Text.c @@ -51,8 +51,8 @@ //| it shouldn't be used on its own. //| STATIC mp_obj_t text_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 5, 5, false); + const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 5, 5, false); text_obj_t *self = m_new_obj(text_obj_t); self->base.type = type; diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index b5f9d7a4eab96..116f82a0341c9 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -58,9 +58,9 @@ //| :param ~microcontroller.Pin pin: the pin to read from //| STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check number of arguments - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num(n_args, kw_args, 1, 1, false); // 1st argument is the pin mp_obj_t pin_obj = args[0]; diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index 58ed5b6b2fb98..dcbd7ecfb7b80 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -58,9 +58,9 @@ //| //| :param ~microcontroller.Pin pin: the pin to output to //| -STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check arguments - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + mp_arg_check_num(n_args, kw_args, 1, 1, false); assert_pin(args[0], false); const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index e3eef924d0c9f..48424d0734174 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -93,10 +93,7 @@ //| pass //| print("stopped") //| -STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 3, 4, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_left_justified }; static const mp_arg_t allowed_args[] = { { MP_QSTR_bit_clock, MP_ARG_OBJ | MP_ARG_REQUIRED }, @@ -105,7 +102,7 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a { MP_QSTR_left_justified, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = false} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t bit_clock_obj = args[ARG_bit_clock].u_obj; assert_pin(bit_clock_obj, false); diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 8bfa4c15bf516..40f2147b5666f 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -87,12 +87,12 @@ //| with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16) as mic: //| mic.record(b, len(b)) //| -STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - enum { ARG_sample_rate, ARG_bit_depth, ARG_mono, ARG_oversample, ARG_startup_delay }; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_clock_pin, ARG_data_pin, ARG_sample_rate, ARG_bit_depth, ARG_mono, ARG_oversample, ARG_startup_delay }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_sample_rate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16000} }, + { MP_QSTR_clock_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_data_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_sample_rate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16000} }, { MP_QSTR_bit_depth, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, { MP_QSTR_mono, MP_ARG_KW_ONLY | MP_ARG_BOOL,{.u_bool = true} }, { MP_QSTR_oversample, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, @@ -102,14 +102,14 @@ STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar static const float STARTUP_DELAY_DEFAULT = 0.110F; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 2, pos_args + 2, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - mp_obj_t clock_pin_obj = pos_args[0]; + mp_obj_t clock_pin_obj = args[ARG_clock_pin].u_obj; assert_pin(clock_pin_obj, false); const mcu_pin_obj_t *clock_pin = MP_OBJ_TO_PTR(clock_pin_obj); assert_pin_free(clock_pin); - mp_obj_t data_pin_obj = pos_args[1]; + mp_obj_t data_pin_obj = args[ARG_data_pin].u_obj; assert_pin(data_pin_obj, false); const mcu_pin_obj_t *data_pin = MP_OBJ_TO_PTR(data_pin_obj); assert_pin_free(data_pin); diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 94340d62cfc1b..9cb98d1f8d5a6 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -93,10 +93,7 @@ //| pass //| print("stopped") //| -STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 2, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value }; static const mp_arg_t allowed_args[] = { { MP_QSTR_left_channel, MP_ARG_OBJ | MP_ARG_REQUIRED }, @@ -104,7 +101,7 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar { MP_QSTR_quiescent_value, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x8000} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t left_channel_obj = args[ARG_left_channel].u_obj; assert_pin(left_channel_obj, false); diff --git a/shared-bindings/audioio/Mixer.c b/shared-bindings/audioio/Mixer.c index dc7a12ebc0288..43ef2c524d135 100644 --- a/shared-bindings/audioio/Mixer.c +++ b/shared-bindings/audioio/Mixer.c @@ -73,10 +73,7 @@ //| time.sleep(1) //| print("stopped") //| -STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, 2, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_voice_count, ARG_buffer_size, ARG_channel_count, ARG_bits_per_sample, ARG_samples_signed, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { { MP_QSTR_voice_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 2} }, @@ -87,7 +84,7 @@ STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_int_t voice_count = args[ARG_voice_count].u_int; if (voice_count < 1 || voice_count > 255) { diff --git a/shared-bindings/audioio/RawSample.c b/shared-bindings/audioio/RawSample.c index 28b6027c3ea26..7fc896449330e 100644 --- a/shared-bindings/audioio/RawSample.c +++ b/shared-bindings/audioio/RawSample.c @@ -73,10 +73,7 @@ //| time.sleep(1) //| dac.stop() //| -STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 2, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_channel_count, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED }, @@ -84,7 +81,7 @@ STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); audioio_rawsample_obj_t *self = m_new_obj(audioio_rawsample_obj_t); self->base.type = &audioio_rawsample_type; diff --git a/shared-bindings/audioio/WaveFile.c b/shared-bindings/audioio/WaveFile.c index 2d2ef578becd8..cddeef7695bce 100644 --- a/shared-bindings/audioio/WaveFile.c +++ b/shared-bindings/audioio/WaveFile.c @@ -67,8 +67,8 @@ //| pass //| print("stopped") //| -STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); +STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); audioio_wavefile_obj_t *self = m_new_obj(audioio_wavefile_obj_t); self->base.type = &audioio_wavefile_type; diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 7f42153ec8de1..374268e3db43d 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -53,13 +53,7 @@ //| :param int frequency: The clock frequency of the bus //| :param int timeout: The maximum clock stretching timeout in microseconds //| -STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); - bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); - raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); - self->base.type = &bitbangio_i2c_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -68,11 +62,15 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_scl].u_obj, false); assert_pin(args[ARG_sda].u_obj, false); const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); + + bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); + raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); + self->base.type = &bitbangio_i2c_type; shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); return (mp_obj_t)self; } diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c index 608c98100b09e..a3c53d2a5366d 100644 --- a/shared-bindings/bitbangio/OneWire.c +++ b/shared-bindings/bitbangio/OneWire.c @@ -62,16 +62,13 @@ //| onewire.write_bit(False) //| print(onewire.read_bit()) //| -STATIC mp_obj_t bitbangio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t bitbangio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_pin }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_pin].u_obj, false); const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); assert_pin_free(pin); diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 5fcfcb1206456..974ec99e2be82 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -62,12 +62,7 @@ //| // TODO(tannewt): Support LSB SPI. -STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); - bitbangio_spi_obj_t *self = m_new_obj(bitbangio_spi_obj_t); - self->base.type = &bitbangio_spi_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -75,13 +70,16 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_clock].u_obj, false); assert_pin(args[ARG_MOSI].u_obj, true); assert_pin(args[ARG_MISO].u_obj, true); const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(args[ARG_clock].u_obj); const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(args[ARG_MOSI].u_obj); const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(args[ARG_MISO].u_obj); + + bitbangio_spi_obj_t *self = m_new_obj(bitbangio_spi_obj_t); + self->base.type = &bitbangio_spi_type; shared_module_bitbangio_spi_construct(self, clock, mosi, miso); return (mp_obj_t)self; } diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 9581f3a3d0da0..e792d25757432 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -60,12 +60,9 @@ //| :param int frequency: The clock frequency in Hertz //| :param int timeout: The maximum clock stretching timeut - (used only for bitbangio.I2C; ignored for busio.I2C) //| -STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); +STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); self->base.type = &busio_i2c_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -74,7 +71,7 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_scl].u_obj, false); assert_pin(args[ARG_sda].u_obj, false); const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c index 95fce68f3200a..ceba4f8eee0c1 100644 --- a/shared-bindings/busio/OneWire.c +++ b/shared-bindings/busio/OneWire.c @@ -62,16 +62,13 @@ //| onewire.write_bit(False) //| print(onewire.read_bit()) //| -STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_pin }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_pin].u_obj, false); const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); assert_pin_free(pin); diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index 646d50aed0154..f690eea18902a 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -71,12 +71,9 @@ //| // TODO(tannewt): Support LSB SPI. -STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); +STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); self->base.type = &busio_spi_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); enum { ARG_clock, ARG_MOSI, ARG_MISO }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -84,7 +81,7 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_clock].u_obj, false); assert_pin(args[ARG_MOSI].u_obj, true); assert_pin(args[ARG_MISO].u_obj, true); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 1cba386d214c0..cd0ca3f360d38 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -69,16 +69,13 @@ typedef struct { extern const busio_uart_parity_obj_t busio_uart_parity_even_obj; extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj; -STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); +STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // Always initially allocate the UART object within the long-lived heap. // This is needed to avoid crashes with certain UART implementations which // cannot accomodate being moved after creation. (See // https://github.com/adafruit/circuitpython/issues/1056) busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t); self->base.type = &busio_uart_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size}; static const mp_arg_t allowed_args[] = { { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -91,7 +88,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, si { MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_rx].u_obj, true); const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(args[ARG_rx].u_obj); diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index 2a1cd7761a0d8..2fcbefe1199b4 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -62,8 +62,8 @@ //| :param ~microcontroller.Pin pin: The pin to control //| STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); digitalio_digitalinout_obj_t *self = m_new_obj(digitalio_digitalinout_obj_t); self->base.type = &digitalio_digitalinout_type; diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index d415127d2f50c..cee3998dc1c38 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -55,8 +55,8 @@ //| :param int height: The number of values high //| :param int value_count: The number of possible pixel values. //| -STATIC mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 3, 3, false); +STATIC mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 3, 3, false); uint32_t width = mp_obj_get_int(pos_args[0]); uint32_t height = mp_obj_get_int(pos_args[1]); uint32_t value_count = mp_obj_get_int(pos_args[2]); diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c index 6705788889cb7..f146784e9de90 100644 --- a/shared-bindings/displayio/ColorConverter.c +++ b/shared-bindings/displayio/ColorConverter.c @@ -52,8 +52,8 @@ //| // TODO(tannewt): Add support for other color formats. //| -STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, 0, true); +STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 0, false); displayio_colorconverter_t *self = m_new_obj(displayio_colorconverter_t); self->base.type = &displayio_colorconverter_type; diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index c0d60bd3b4554..80aa814df2134 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -32,6 +32,7 @@ #include "py/binary.h" #include "py/objproperty.h" #include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" @@ -51,7 +52,7 @@ //| //| Create a FourWire object associated with the given pins. //| -STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { +STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_raise_NotImplementedError(translate("displayio is a work in progress")); return mp_const_none; } @@ -73,7 +74,11 @@ MP_DEFINE_CONST_FUN_OBJ_KW(displayio_fourwire_send_obj, 1, displayio_fourwire_ob //| STATIC mp_obj_t displayio_fourwire_obj_show(mp_obj_t self_in, mp_obj_t group_in) { displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - displayio_group_t* group = MP_OBJ_TO_PTR(group_in); + mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); + if (native_layer == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Must be a Group subclass.")); + } + displayio_group_t* group = MP_OBJ_TO_PTR(native_layer); common_hal_displayio_fourwire_show(self, group); return mp_const_none; } diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 98257673b9ea2..253812e002427 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -49,16 +49,13 @@ //| //| :param int max_size: The maximum group size. //| -STATIC mp_obj_t displayio_group_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, 0, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t displayio_group_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_max_size }; static const mp_arg_t allowed_args[] = { { MP_QSTR_max_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 4} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_int_t max_size = args[ARG_max_size].u_int; if (max_size < 1) { diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c index d3d413da1d3c1..46cb5913c1642 100644 --- a/shared-bindings/displayio/OnDiskBitmap.c +++ b/shared-bindings/displayio/OnDiskBitmap.c @@ -78,8 +78,8 @@ //| //| :param file file: The open bitmap file //| -STATIC mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); +STATIC mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); if (!MP_OBJ_IS_TYPE(pos_args[0], &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index 7086d0ab11acc..c412674e10fdb 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -54,16 +54,13 @@ // TODO(tannewt): Add support for other color formats. // TODO(tannewt): Add support for 8-bit alpha blending. //| -STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_color_count }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_color_count, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_color_count, MP_ARG_REQUIRED | MP_ARG_INT }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); displayio_palette_t *self = m_new_obj(displayio_palette_t); self->base.type = &displayio_palette_type; diff --git a/shared-bindings/displayio/Shape.c b/shared-bindings/displayio/Shape.c index 37a049d0c8148..e60d670b7ea28 100644 --- a/shared-bindings/displayio/Shape.c +++ b/shared-bindings/displayio/Shape.c @@ -53,19 +53,16 @@ //| :param bool mirror_x: When true the left boundary is mirrored to the right. //| :param bool mirror_y: When true the top boundary is mirrored to the bottom. //| -STATIC mp_obj_t displayio_shape_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 2, 4, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t displayio_shape_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_width, ARG_height, ARG_mirror_x, ARG_mirror_y }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED }, - { MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_mirror_x, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_mirror_y, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); displayio_shape_t *self = m_new_obj(displayio_shape_t); self->base.type = &displayio_shape_type; diff --git a/shared-bindings/displayio/Sprite.c b/shared-bindings/displayio/Sprite.c index 8aa9586ea6adf..6f4704e45019c 100644 --- a/shared-bindings/displayio/Sprite.c +++ b/shared-bindings/displayio/Sprite.c @@ -67,20 +67,17 @@ void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) { //| palette lookup, a gradient, a pattern or a color transformer. //| //| -STATIC mp_obj_t displayio_sprite_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 4, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t displayio_sprite_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bitmap, ARG_pixel_shader, ARG_position, ARG_width, ARG_height }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_bitmap, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY }, { MP_QSTR_position, MP_ARG_OBJ | MP_ARG_KW_ONLY }, { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t bitmap = args[ARG_bitmap].u_obj; diff --git a/shared-bindings/gamepad/GamePad.c b/shared-bindings/gamepad/GamePad.c index 21da4fab90e82..4458c972f71ea 100644 --- a/shared-bindings/gamepad/GamePad.c +++ b/shared-bindings/gamepad/GamePad.c @@ -95,7 +95,7 @@ //| button presses start to be recorded. //| STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args) { + const mp_obj_t *args, mp_map_t *kw_args) { if (n_args > 8) { mp_raise_TypeError(translate("too many arguments")); } diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c index d2e001e4cefff..090a535810713 100644 --- a/shared-bindings/i2cslave/I2CSlave.c +++ b/shared-bindings/i2cslave/I2CSlave.c @@ -64,12 +64,9 @@ STATIC mp_obj_t mp_obj_new_i2cslave_i2c_slave_request(i2cslave_i2c_slave_obj_t * //| :param tuple addresses: The I2C addresses to respond to (how many is hw dependent). //| :param bool smbus: Use SMBUS timings if the hardware supports it //| -STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); +STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { i2cslave_i2c_slave_obj_t *self = m_new_obj(i2cslave_i2c_slave_obj_t); self->base.type = &i2cslave_i2c_slave_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus }; static const mp_arg_t allowed_args[] = { { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -78,7 +75,7 @@ STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_ { MP_QSTR_smbus, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_scl].u_obj, false); assert_pin(args[ARG_sda].u_obj, false); @@ -247,8 +244,8 @@ const mp_obj_type_t i2cslave_i2c_slave_type = { //| :param bool is_read: I2C Master read request //| :param bool is_restart: Repeated Start Condition //| -STATIC mp_obj_t i2cslave_i2c_slave_request_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 4, 4, false); +STATIC mp_obj_t i2cslave_i2c_slave_request_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 4, 4, false); return mp_obj_new_i2cslave_i2c_slave_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3])); } diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c index 362b8123d805b..ed3acd8047d58 100644 --- a/shared-bindings/pulseio/PWMOut.c +++ b/shared-bindings/pulseio/PWMOut.c @@ -85,31 +85,29 @@ //| pwm.frequency = 880 //| time.sleep(0.1) //| -STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - mp_obj_t pin_obj = args[0]; - assert_pin(pin_obj, false); - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); - assert_pin_free(pin); - - // create PWM object from the given pin - pulseio_pwmout_obj_t *self = m_new_obj(pulseio_pwmout_obj_t); - self->base.type = &pulseio_pwmout_type; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - enum { ARG_duty_cycle, ARG_frequency, ARG_variable_frequency }; +STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + enum { ARG_pin, ARG_duty_cycle, ARG_frequency, ARG_variable_frequency }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ, }, { MP_QSTR_duty_cycle, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 500} }, { MP_QSTR_variable_frequency, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, args + 1, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); + mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); + + mp_obj_t pin_obj = parsed_args[ARG_pin].u_obj; + assert_pin(pin_obj, false); + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + assert_pin_free(pin); + uint16_t duty_cycle = parsed_args[ARG_duty_cycle].u_int; uint32_t frequency = parsed_args[ARG_frequency].u_int; bool variable_frequency = parsed_args[ARG_variable_frequency].u_int; + // create PWM object from the given pin + pulseio_pwmout_obj_t *self = m_new_obj(pulseio_pwmout_obj_t); + self->base.type = &pulseio_pwmout_type; common_hal_pulseio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index acf88b9fbeae0..d30abf28faf47 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -81,10 +81,7 @@ //| # Resume with an 80 microsecond active pulse //| pulses.resume(80) //| -STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_pin, ARG_maxlen, ARG_idle_state }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -92,7 +89,7 @@ STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg { MP_QSTR_idle_state, MP_ARG_BOOL, {.u_bool = false} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_pin].u_obj, false); const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); assert_pin_free(pin); diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index e9834c12a781d..493b7e2fff9ff 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -68,8 +68,8 @@ //| pulses[0] = 200 //| pulse.send(pulses) //| -STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); +STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); mp_obj_t carrier_obj = args[0]; if (!MP_OBJ_IS_TYPE(carrier_obj, &pulseio_pwmout_type)) { diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index 65d4ba98bde5f..5d2264ffc0e77 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -64,17 +64,14 @@ //| print(position) //| last_position = position //| -STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 2, 2, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_pin_a, ARG_pin_b }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin_a, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_pin_b, 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); assert_pin(args[ARG_pin_a].u_obj, false); const mcu_pin_obj_t* pin_a = MP_OBJ_TO_PTR(args[ARG_pin_a].u_obj); diff --git a/shared-bindings/rtc/RTC.c b/shared-bindings/rtc/RTC.c index a0e9be3020427..474d4a399a022 100644 --- a/shared-bindings/rtc/RTC.c +++ b/shared-bindings/rtc/RTC.c @@ -63,9 +63,9 @@ const rtc_rtc_obj_t rtc_rtc_obj = {{&rtc_rtc_type}}; //| //| This class represents the onboard Real Time Clock. It is a singleton and will always return the same instance. //| -STATIC mp_obj_t rtc_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t rtc_rtc_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // No arguments - mp_arg_check_num(n_args, n_kw, 0, 0, false); + mp_arg_check_num(n_args, kw_args, 0, 0, false); // return constant object return (mp_obj_t)&rtc_rtc_obj; diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index f97ad4a5de2b8..f19b972d0449f 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -83,8 +83,8 @@ STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); #if MICROPY_PY_COLLECTIONS -mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - if (n_args != 1) { +mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + if (n_args != 1 || kw_args != NULL || kw_args->used > 0) { mp_raise_TypeError(translate("time.struct_time() takes exactly 1 argument")); } if (!MP_OBJ_IS_TYPE(args[0], &mp_type_tuple) || ((mp_obj_tuple_t*) MP_OBJ_TO_PTR(args[0]))->len != 9) { @@ -92,7 +92,7 @@ mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, size_t n } mp_obj_tuple_t* tuple = MP_OBJ_TO_PTR(args[0]); - return namedtuple_make_new(type, 9, 0, tuple->items); + return namedtuple_make_new(type, 9, tuple->items, NULL); } //| .. class:: struct_time((tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)) @@ -158,7 +158,7 @@ mp_obj_t struct_time_from_tm(timeutils_struct_time_t *tm) { mp_obj_new_int(-1), // tm_isdst is not supported }; - return namedtuple_make_new((const mp_obj_type_t*)&struct_time_type_obj, 9, 0, elems); + return namedtuple_make_new((const mp_obj_type_t*)&struct_time_type_obj, 9, elems, NULL); }; void struct_time_to_tm(mp_obj_t t, timeutils_struct_time_t *tm) { diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 326b0212eff1b..3b26aca8c0637 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -61,9 +61,9 @@ //| :param ~microcontroller.Pin pin: the pin to read from //| STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check number of arguments - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num(n_args, kw_args, 1, 1, false); // 1st argument is the pin mp_obj_t pin_obj = args[0]; diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 21dbc7a2cb509..f0c8795cc4c8b 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -46,7 +46,7 @@ //| Not currently dynamically supported. //| STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { return mp_const_none; } diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c index e1e6eabccf68e..6177cfa8d7cb1 100644 --- a/shared-bindings/usb_midi/PortIn.c +++ b/shared-bindings/usb_midi/PortIn.c @@ -49,7 +49,7 @@ //| to the ``usb_midi.ports`` tuple. //| -STATIC mp_obj_t usb_midi_portin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { +STATIC mp_obj_t usb_midi_portin_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { return mp_const_none; } diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c index 0588eed90aa8e..e8cea56e86768 100644 --- a/shared-bindings/usb_midi/PortOut.c +++ b/shared-bindings/usb_midi/PortOut.c @@ -49,7 +49,7 @@ //| to the ``usb_midi.ports`` tuple. //| -STATIC mp_obj_t usb_midi_portout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { +STATIC mp_obj_t usb_midi_portout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { return mp_const_none; } diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 93ac3596438b1..b9923128a0a59 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -38,6 +38,13 @@ void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer) if (self->size == self->max_size) { mp_raise_RuntimeError(translate("Group full")); } + mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); + if (native_layer == MP_OBJ_NULL) { + native_layer = mp_instance_cast_to_native_base(layer, &displayio_sprite_type); + } + if (native_layer == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Layer must be a Group or Sprite subclass.")); + } self->children[self->size] = layer; self->size++; self->needs_refresh = true; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index df9c2963ab4c2..f1a00db9f7b73 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -39,6 +39,8 @@ void displayio_refresh_display(void) { return; } if (refresh_queued(display)) { + PORT->Group[1].DIRSET.reg = 1 << 22; + // We compute the pixels uint16_t x0 = 0; uint16_t y0 = 0; @@ -53,10 +55,19 @@ void displayio_refresh_display(void) { for (uint16_t x = x0; x < x1; ++x) { uint16_t* pixel = &(((uint16_t*)buffer)[index]); *pixel = 0; - if (display->current_group != NULL) { - displayio_group_get_pixel(display->current_group, x, y, pixel); - } + PORT->Group[1].OUTTGL.reg = 1 << 22; + + //if (index == 0) { + if (display->current_group != NULL) { + displayio_group_get_pixel(display->current_group, x, y, pixel); + } + // } else { + // *pixel = (((uint16_t*)buffer)[0]); + // } + + + PORT->Group[1].OUTTGL.reg = 1 << 22; index += 1; // The buffer is full, send it. diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c index c8921aa8543ba..8be21e5d0656a 100644 --- a/supervisor/shared/flash.c +++ b/supervisor/shared/flash.c @@ -57,9 +57,9 @@ void supervisor_flash_set_usb_writable(bool usb_writable) { const mp_obj_type_t supervisor_flash_type; STATIC const mp_obj_base_t supervisor_flash_obj = {&supervisor_flash_type}; -STATIC mp_obj_t supervisor_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t supervisor_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check arguments - mp_arg_check_num(n_args, n_kw, 0, 0, false); + mp_arg_check_num(n_args, kw_args, 0, 0, false); // return singleton object return (mp_obj_t)&supervisor_flash_obj; From 12c8b00556859bd9dc97b4f11761f45ad23098a3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 14 Jan 2019 17:30:01 -0800 Subject: [PATCH 100/153] Don't build machine class we don't use. --- py/py.mk | 6 ------ 1 file changed, 6 deletions(-) diff --git a/py/py.mk b/py/py.mk index 69ad4e9b902b6..11dd7a1e12c0d 100644 --- a/py/py.mk +++ b/py/py.mk @@ -233,12 +233,6 @@ PY_EXTMOD_O_BASENAME = \ extmod/moduhashlib.o \ extmod/modubinascii.o \ extmod/virtpin.o \ - extmod/machine_mem.o \ - extmod/machine_pinbase.o \ - extmod/machine_signal.o \ - extmod/machine_pulse.o \ - extmod/machine_i2c.o \ - extmod/machine_spi.o \ extmod/modussl_axtls.o \ extmod/modussl_mbedtls.o \ extmod/modurandom.o \ From bd3c36ce6d3b440dcb7591cacccbd2bc72a2268c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 14 Jan 2019 18:08:45 -0800 Subject: [PATCH 101/153] fixup m0 and nrf --- shared-bindings/bleio/Address.c | 16 ++++++-------- shared-bindings/bleio/Broadcaster.c | 13 ++++-------- shared-bindings/bleio/Characteristic.c | 13 ++++-------- shared-bindings/bleio/CharacteristicBuffer.c | 13 ++++-------- shared-bindings/bleio/Descriptor.c | 13 ++++-------- shared-bindings/bleio/Peripheral.c | 17 ++++++--------- shared-bindings/bleio/ScanEntry.c | 2 +- shared-bindings/bleio/Scanner.c | 5 ++++- shared-bindings/bleio/Service.c | 22 +++++++------------- shared-bindings/bleio/UUID.c | 4 ++-- shared-bindings/socket/__init__.c | 20 +++++++++--------- shared-bindings/wiznet/wiznet5k.c | 10 ++++----- 12 files changed, 58 insertions(+), 90 deletions(-) diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index 9109388445d1c..6cf495d8399d6 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -69,22 +69,18 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { //| - `bleio.AddressType.RANDOM_PRIVATE_RESOLVABLE` //| - `bleio.AddressType.RANDOM_PRIVATE_NON_RESOLVABLE` //| -STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); - bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t); - self->base.type = &bleio_address_type; - self->type = ADDRESS_PUBLIC; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - +STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address }; static const mp_arg_t allowed_args[] = { { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t); + self->base.type = &bleio_address_type; + self->type = ADDRESS_PUBLIC; const mp_obj_t address = args[ARG_address].u_obj; diff --git a/shared-bindings/bleio/Broadcaster.c b/shared-bindings/bleio/Broadcaster.c index c46de1d356db7..209e6649028ae 100644 --- a/shared-bindings/bleio/Broadcaster.c +++ b/shared-bindings/bleio/Broadcaster.c @@ -59,24 +59,19 @@ //| :param float interval: how often to broadcast //| -STATIC mp_obj_t bleio_broadcaster_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, 1, true); - bleio_broadcaster_obj_t *self = m_new_obj(bleio_broadcaster_obj_t); - self->base.type = &bleio_broadcaster_type; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - +STATIC mp_obj_t bleio_broadcaster_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_interval }; static const mp_arg_t allowed_args[] = { { MP_QSTR_interval, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj); + bleio_broadcaster_obj_t *self = m_new_obj(bleio_broadcaster_obj_t); + self->base.type = &bleio_broadcaster_type; // Do port-specific initialization. interval will be validated. common_hal_bleio_broadcaster_construct(self, interval); diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 0a3fada139256..ae83de8643659 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -51,14 +51,7 @@ //| :param bool write: Clients may write this characteristic; a response will be sent back //| :param bool write_no_response: Clients may write this characteristic; no response will be sent back //| -STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); - bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); - self->base.type = &bleio_characteristic_type; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - +STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_uuid, ARG_broadcast, ARG_indicate, ARG_notify, ARG_read, ARG_write, ARG_write_no_response, }; @@ -73,7 +66,7 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mp_obj_t uuid = args[ARG_uuid].u_obj; @@ -81,6 +74,8 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t mp_raise_ValueError(translate("Expected a UUID")); } + bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); + self->base.type = &bleio_characteristic_type; self->uuid = MP_OBJ_TO_PTR(uuid); bleio_characteristic_properties_t properties; diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c index f0578a7adf224..2bb4448c4a84e 100644 --- a/shared-bindings/bleio/CharacteristicBuffer.c +++ b/shared-bindings/bleio/CharacteristicBuffer.c @@ -44,14 +44,7 @@ //| :param int buffer_size: Size of ring buffer that stores incoming data coming from client. //| Must be >= 1. //| -STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 2, true); - bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t); - self->base.type = &bleio_characteristic_buffer_type; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - +STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_characteristic, ARG_buffer_size, }; static const mp_arg_t allowed_args[] = { { MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -59,7 +52,7 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mp_obj_t characteristic = args[ARG_characteristic].u_obj; const int buffer_size = args[ARG_buffer_size].u_int; @@ -72,6 +65,8 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, mp_raise_ValueError(translate("Expected a Characteristic")); } + bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t); + self->base.type = &bleio_characteristic_buffer_type; self->characteristic = MP_OBJ_TO_PTR(characteristic); common_hal_bleio_characteristic_buffer_construct(self, self->characteristic, buffer_size); diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c index 4022632ad2248..9fcfc2dfd9c39 100644 --- a/shared-bindings/bleio/Descriptor.c +++ b/shared-bindings/bleio/Descriptor.c @@ -71,21 +71,14 @@ enum { //| //| The descriptor uuid. (read-only) //| -STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, 1, true); - bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t); - self->base.type = type; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - +STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_uuid }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mp_obj_t uuid_arg = args[ARG_uuid].u_obj; @@ -93,6 +86,8 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar mp_raise_ValueError(translate("Expected a UUID")); } + bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t); + self->base.type = type; bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_arg); common_hal_bleio_descriptor_construct(self, uuid); diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c index cea44486f6d3d..eff4ca7f2606c 100644 --- a/shared-bindings/bleio/Peripheral.c +++ b/shared-bindings/bleio/Peripheral.c @@ -82,16 +82,7 @@ static const char default_name[] = "CIRCUITPY"; //| :param str name: The name used when advertising this peripheral //| -STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, 1, true); - bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t); - self->base.type = &bleio_peripheral_type; - self->service_list = mp_obj_new_list(0, NULL); - self->notif_handler = mp_const_none; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - +STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_services, ARG_name }; static const mp_arg_t allowed_args[] = { { MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_none} }, @@ -99,13 +90,17 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // If services is not an iterable, an exception will be thrown. mp_obj_iter_buf_t iter_buf; mp_obj_t iterable = mp_getiter(args[ARG_services].u_obj, &iter_buf); mp_obj_t service; + bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t); + self->base.type = &bleio_peripheral_type; + self->service_list = mp_obj_new_list(0, NULL); + self->notif_handler = mp_const_none; while ((service = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (!MP_OBJ_IS_TYPE(service, &bleio_service_type)) { mp_raise_ValueError(translate("services includes an object that is not a Service")); diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c index e452c72670617..b4a3c55044b2d 100644 --- a/shared-bindings/bleio/ScanEntry.c +++ b/shared-bindings/bleio/ScanEntry.c @@ -248,7 +248,7 @@ STATIC mp_obj_t scanentry_get_service_uuids(mp_obj_t self_in) { mp_obj_t entries = mp_obj_new_list(0, NULL); for (size_t i = 0; i < uuids_len / sizeof(uint16_t); ++i) { const mp_obj_t uuid_int = mp_obj_new_int(uuids[sizeof(uint16_t) * i] | (uuids[sizeof(uint16_t) * i + 1] << 8)); - const mp_obj_t uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_int); + const mp_obj_t uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, &uuid_int, NULL); mp_obj_list_append(entries, uuid_obj); } diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/bleio/Scanner.c index 5d19778f69a59..dba455b2f537c 100644 --- a/shared-bindings/bleio/Scanner.c +++ b/shared-bindings/bleio/Scanner.c @@ -25,6 +25,7 @@ */ #include "py/objproperty.h" +#include "py/runtime.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" @@ -77,7 +78,9 @@ STATIC void bleio_scanner_print(const mp_print_t *print, mp_obj_t self_in, mp_pr mp_printf(print, "Scanner(interval: %d window: %d)", self->interval, self->window); } -STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { +STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 0, false); + bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t); self->base.type = type; diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index a0673bb2d0c5e..c3be262602833 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -49,17 +49,7 @@ //| :param bool secondary: If the service is a secondary one //| -STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 2, 3, true); - bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); - self->char_list = mp_obj_new_list(0, NULL); - self->base.type = &bleio_service_type; - self->device = mp_const_none; - self->handle = 0xFFFF; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - +STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_uuid, ARG_characteristics, ARG_secondary }; static const mp_arg_t allowed_args[] = { { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, @@ -68,9 +58,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, }; 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); - - self->is_secondary = args[ARG_secondary].u_bool; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mp_obj_t uuid = args[ARG_uuid].u_obj; @@ -78,6 +66,12 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, mp_raise_ValueError(translate("Expected a UUID")); } + bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); + self->char_list = mp_obj_new_list(0, NULL); + self->base.type = &bleio_service_type; + self->device = mp_const_none; + self->handle = 0xFFFF; + self->is_secondary = args[ARG_secondary].u_bool; self->uuid = MP_OBJ_TO_PTR(uuid); // If characteristics is not an iterable, an exception will be thrown. diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 703bc1c654cbb..f2df9d0952a81 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -51,8 +51,8 @@ //| //| :param int/buffer value: The uuid value to encapsulate //| -STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); +STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); self->base.type = type; diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c index d860c40c8d905..29d47de568078 100644 --- a/shared-bindings/socket/__init__.c +++ b/shared-bindings/socket/__init__.c @@ -39,20 +39,20 @@ //| :mod:`socket` --- TCP, UDP and RAW socket support //| ================================================= -//| +//| //| .. module:: socket //| :synopsis: TCP, UDP and RAW sockets //| :platform: SAMD21, SAMD51 //| //| Create TCP, UDP and RAW sockets for communicating over the Internet. -//| +//| STATIC const mp_obj_type_t socket_type; //| .. currentmodule:: socket //| //| .. class:: socket(family, type, proto, ...) -//| +//| //| Create a new socket //| //| :param ~int family: AF_INET or AF_INET6 @@ -60,8 +60,8 @@ STATIC const mp_obj_type_t socket_type; //| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored) //| -STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 4, false); +STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 4, false); // create socket object (not bound to any NIC yet) mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t); @@ -245,8 +245,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send); //| Reads some bytes from the connected remote address. //| Suits sockets of type SOCK_STREAM //| Returns a bytes() of length <= bufsize -//| -//| :param ~int bufsize: maximum number of bytes to receive +//| +//| :param ~int bufsize: maximum number of bytes to receive STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -313,7 +313,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto); //| * a bytes() of length <= bufsize //| * a remote_address, which is a tuple of ip address and port number //| -//| :param ~int bufsize: maximum number of bytes to receive +//| :param ~int bufsize: maximum number of bytes to receive //| STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { @@ -469,10 +469,10 @@ STATIC const mp_obj_type_t socket_type = { }; //| .. function:: getaddrinfo(host, port) -//| +//| //| Gets the address information for a hostname and port //| -//| Returns the appropriate family, socket type, socket protocol and +//| Returns the appropriate family, socket type, socket protocol and //| address information to call socket.socket() and socket.connect() with, //| as a tuple. //| diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 4e5fff86934dd..6d43e8992d82a 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -46,22 +46,22 @@ #include "shared-module/wiznet/wiznet5k.h" //| .. currentmodule:: wiznet -//| +//| //| :class:`WIZNET5K` -- wrapper for Wiznet 5500 Ethernet interface //| =============================================================== //| //| .. class:: WIZNET5K(spi, cs, rst) //| //| Create a new WIZNET5500 interface using the specified pins -//| +//| //| :param spi: spi bus to use //| :param cs: pin to use for Chip Select -//| :param rst: pin to sue for Reset +//| :param rst: pin to sue for Reset //| -STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check arguments - mp_arg_check_num(n_args, n_kw, 3, 3, false); + mp_arg_check_num(n_args, kw_args, 3, 3, false); return wiznet5k_create(args[0], args[1], args[2]); } From c27175496248424c0581211aa53a5371f44a37ce Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 14 Jan 2019 18:09:02 -0800 Subject: [PATCH 102/153] fixup micropy --- extmod/moduhashlib.c | 12 ++++++------ py/objenumerate.c | 2 +- py/objstr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 1618594e97ac9..970c63da82ae3 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -66,8 +66,8 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg); #if MICROPY_SSL_MBEDTLS -STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context)); o->base.type = type; mbedtls_sha256_init((mbedtls_sha256_context*)&o->state); @@ -104,8 +104,8 @@ static void check_not_unicode(const mp_obj_t arg) { #endif } -STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); o->base.type = type; sha256_init((CRYAL_SHA256_CTX*)o->state); @@ -155,8 +155,8 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = { STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg); #if MICROPY_SSL_AXTLS -STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX)); o->base.type = type; SHA1_Init((SHA1_CTX*)o->state); diff --git a/py/objenumerate.c b/py/objenumerate.c index 4919a9b8f0599..818725d856c9f 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -59,7 +59,7 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, con o->iter = mp_getiter(arg_vals.iterable.u_obj, NULL); o->cur = arg_vals.start.u_int; #else - (void)n_kw; + (void)kw_args; mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t); o->base.type = type; o->iter = mp_getiter(args[0], NULL); diff --git a/py/objstr.c b/py/objstr.c index 637323f4cbadc..9b6cb0cf4d8b2 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -198,7 +198,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, cons mp_arg_error_unimpl_kw(); } #else - (void)n_kw; + (void)kw_args; #endif if (n_args == 0) { From 6962c04f66519a592ba9a2e52453fee6b0c4d6fa Mon Sep 17 00:00:00 2001 From: vgoodwinv <46117260+vgoodwinv@users.noreply.github.com> Date: Mon, 14 Jan 2019 21:21:48 -0500 Subject: [PATCH 103/153] Update build_release_files.py added language directories under exist board directories for #1441 --- tools/build_release_files.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/build_release_files.py b/tools/build_release_files.py index 6bf418fe66bb8..5ad886e50ed20 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -34,6 +34,8 @@ board_info = all_boards[board] for language in languages: + bin_directory = "../bin/{}/-{board}/-{language}".format(board=board, language=language) + os.makedirs(bin_directory, exist_ok=True) start_time = time.monotonic() make_result = subprocess.run("make -C ../ports/" + board_info["port"] + " TRANSLATION=" + language + " BOARD=" + board, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) build_duration = time.monotonic() - start_time From d1204c7cf3533f5fe68d652e290d03555c0ea9aa Mon Sep 17 00:00:00 2001 From: vgoodwinv <46117260+vgoodwinv@users.noreply.github.com> Date: Mon, 14 Jan 2019 21:27:14 -0500 Subject: [PATCH 104/153] Update build_release_files.py --- tools/build_release_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_release_files.py b/tools/build_release_files.py index 5ad886e50ed20..f60ebee35c67b 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -34,7 +34,7 @@ board_info = all_boards[board] for language in languages: - bin_directory = "../bin/{}/-{board}/-{language}".format(board=board, language=language) + bin_directory = "../bin/-{board}/-{language}".format(board=board, language=language) os.makedirs(bin_directory, exist_ok=True) start_time = time.monotonic() make_result = subprocess.run("make -C ../ports/" + board_info["port"] + " TRANSLATION=" + language + " BOARD=" + board, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) From c1cfe5f5f0bf7487f243e894916dc93cf5df6017 Mon Sep 17 00:00:00 2001 From: vgoodwinv <46117260+vgoodwinv@users.noreply.github.com> Date: Mon, 14 Jan 2019 21:35:21 -0500 Subject: [PATCH 105/153] Update build_release_files.py --- tools/build_release_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_release_files.py b/tools/build_release_files.py index f60ebee35c67b..37e827eb1c6d7 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -34,7 +34,7 @@ board_info = all_boards[board] for language in languages: - bin_directory = "../bin/-{board}/-{language}".format(board=board, language=language) + bin_directory = "../bin/{board}/{language}".format(board=board, language=language) os.makedirs(bin_directory, exist_ok=True) start_time = time.monotonic() make_result = subprocess.run("make -C ../ports/" + board_info["port"] + " TRANSLATION=" + language + " BOARD=" + board, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) From 7296b647ef0f797665fe37c601522b352df326b5 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Tue, 15 Jan 2019 01:37:22 -0800 Subject: [PATCH 106/153] Add MDK nRF52840 MDK USB Dongle support. Adds support for https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/. A cheap nRF52840 USB stick with optional headers, very Trinket and Itsy like. --- .../README.md | 96 +++++++++++++++++++ .../board.c | 38 ++++++++ .../mpconfigboard.h | 49 ++++++++++ .../mpconfigboard.mk | 22 +++++ .../makerdiary_nrf52840_mdk_usb_dongle/pins.c | 41 ++++++++ tools/build_board_info.py | 1 + 6 files changed, 247 insertions(+) create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/README.md create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/README.md b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/README.md new file mode 100644 index 0000000000000..e3e50f905dca0 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/README.md @@ -0,0 +1,96 @@ +# MakerDiary NRF52840 MDK USB Dongle + +Refer to [The makerdiary Github repo](https://github.com/makerdiary/nrf52840-mdk-usb-dongle) +or [The nrf52840-mdk-usb-dongle wiki](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/) +for more details about the device. + +This is pretty much just the nRF52840 with a useful number of pins exposed for +your pleasure along with one RGB LED and an onboard antenna in a USB stick form +factor with room for headers on the sides. + +Note that all three LEDs on this device are wired through sinks, not sources, +so flip your boolean expectations when dealing with `DigitalInOut` or `PWMOut` +on this device -- +`led.value = True` or `led.duty_cycle = 0xffff` turns the LED off! + +The onboard button is hard wired to the Reset pin so you cannot use it yourself. + +## Installing CircuitPython submodules + +Before you can build, you will need to run the following commands once, which +will install the submodules that are part of the CircuitPython ecosystem, and +build the `mpy-cross` tool: + +``` +$ cd circuitpython +$ git submodule update --init +$ make -C mpy-cross +``` + +## Note about bootloaders + +While most Adafruit devices come with (or can easily be flashed with) an +Adafruit-provided bootloader (supporting niceties like UF2 flashing), this +board comes with one that supports DFU via nrfutil. If you ever need to +restore the DFU bootloader via a SWD debugger, use +[the nRF52 open bootloader hex file](https://github.com/makerdiary/nrf52840-mdk-usb-dongle/tree/master/firmware/open_bootloader). + +## Building and Flashing CircuitPython + +``` +$ cd ports/nrf +``` + +### Build CircuitPython for the MDK USB Dongle + +``` +make BOARD=makerdiary_nrf52840_mdk_usb_dongle SD=s140 V=1 -j4 hex +``` + +This should produce a `build-makerdiary_nrf52840_mdk_usb_dongle-s140/firmware.hex` file. + +### Install nrfutil + +You'll need to have [nrfutil](https://pypi.org/project/nrfutil/) installed as +appropriate for your system. +As of 2019-01, _nrfutil still requires Python 2.7_... ugh! + +### Flash the nRF52 Radio Soft Device + +Build a DFU package from the softdevice hex file and flash it: + +```sh +nrfutil pkg generate --hw-version 52 --sd-req 0x00 --sd-id 0xAE --softdevice bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_softdevice.hex dfu_sd140-6.1.0.zip +nrfutil dfu usb-serial -pkg dfu_sd140-6.1.0.zip -p /dev/tty.usbmodemABRACADBRA # likely /dev/ttyACM0 on Linux +``` + +Note that the `--sd=id 0xAE` comes from the Nordic nRF52 manual for SoftDevice +6.1.0. When the SoftDevice is changed, read the Nordic manual to find the +correct value and use it on all of the `nrfutil pkg generate` commands. + +`/dev/tty.usbmodem*` is a macOS name. On Linux it'll likely be `/dev/ttyACM*`. On Windows probably a COM port. + +### Flash CircuitPython + +Build a DFU package from the hex application file and flash it: + +``` +nrfutil pkg generate --sd-req 0xAE --application build-makerdiary_nrf52840_mdk_usb_dongle-s140/firmware.hex --hw-version 52 --application-version 1 dfu_circuitpython.zip +nrfutil dfu usb-serial -pkg dfu_circuitpython.zip -p /dev/tty.usbmodemABRACADBRA +``` + +I'm not sure if `--application-version 1` is actually meaningful or required. + +After this, your device should be up and running CircuitPython. When it +resets, you'll see the CIRCUITPY USB filesystem and a new console usb modem +serial port show up. + +``` +Adafruit CircuitPython 4.0.0-alpha.5-139-g10ceb6716 on 2019-01-14; MakerDiary nRF52840 MDK USB Dongle with nRF52840 +>>> +``` + +### TODO items + +* Update the Makefile to do the above DFU .zip building and nrfutil flashing. +* Create a UF2 bootloader for this. It is already a USB stick form factor, it deserves to behave like one. diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c new file mode 100644 index 0000000000000..4421970eefe4d --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 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" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h new file mode 100644 index 0000000000000..8321abb96be68 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * 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. + */ + +#include "nrfx/hal/nrf_gpio.h" + +#define MAKERDIARY_NRF52840_MDK_DONGLE + +#define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK USB Dongle" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "MakerDiary52840MDKDongle" + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define PORT_HEAP_SIZE (128 * 1024) +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 // according to the schematic we do + +// See https://github.com/adafruit/circuitpython/issues/1300, circuitpython +// doesn't yet support NFC so just force those pins to be GPIO. +#define CONFIG_NFCT_PINS_AS_GPIOS diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk new file mode 100644 index 0000000000000..54fa0617b31d6 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk @@ -0,0 +1,22 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "nRF52840-MDK-Dongle" +USB_MANUFACTURER = "makerdiary" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 +BOOT_FILE = boards/$(BOARD)/bootloader/$(SOFTDEV_VERSION)/$(BOARD)_bootloader_$(SOFTDEV_VERSION)_s140 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c new file mode 100644 index 0000000000000..6049ac0538af5 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c @@ -0,0 +1,41 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_AIN1), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_AIN2), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_AIN3), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_04) }, // User must connect manually. + { MP_ROM_QSTR(MP_QSTR_VDIV), MP_ROM_PTR(&pin_P0_05) }, // User must connect manually. + +// Not defining the NFC names until CircuitPython supports NFC. +// { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, +// { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P9), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P18), MP_ROM_PTR(&pin_P0_18) }, // !Reset button. + { MP_ROM_QSTR(MP_QSTR_P19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_P22), MP_ROM_PTR(&pin_P0_22) }, // green led, low is on. + { MP_ROM_QSTR(MP_QSTR_P23), MP_ROM_PTR(&pin_P0_23) }, // red led, low is on. + { MP_ROM_QSTR(MP_QSTR_P24), MP_ROM_PTR(&pin_P0_24) }, // blue led, low is on. + + { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_P0_23) }, // Low is on. + { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_P0_22) }, // Low is on. + { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_P0_24) }, // Low is on. + + // BUT this is the RESET pin so we can't really use it. + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P0_18) }, // Low is pressed. +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/tools/build_board_info.py b/tools/build_board_info.py index 163ebf6240099..e8c4d963c3c5f 100644 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -37,6 +37,7 @@ # nRF52840 dev kits that may not have UF2 bootloaders, "makerdiary_nrf52840_mdk": HEX, + "makerdiary_nrf52840_mdk_usb_dongle": HEX, "pca10056": BIN_UF2, "pca10059": BIN_UF2 } From 7669ab83e1eca880d19a1f681cdad134245dab25 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 15 Jan 2019 09:44:28 -0800 Subject: [PATCH 107/153] Tweak artifact path for upload --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 16d094b47ddf0..87263bf8f0bc7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ env: addons: artifacts: paths: - - $(ls -d1 bin/*/* | tr "\n" ":") + - $(ls -d1 bin/*/*/* | tr "\n" ":") target_paths: / deploy: @@ -38,7 +38,7 @@ deploy: api_key: secure: "jdqVFw6itRY4qwQF4ReXo0uaymT+Mob6RhYX0lw8KWFNqBgHnLVuKmKKcGMEuRvBVMPkvxF7bMuOQzSBOunqwlHFse3oMzdWvQODv1zwV7pSRXGwTdIvTPbBjKWxnBG9uSNRf2R5AMflJFUxy2CbtBpgvNzr+4VLREZDrrjEu8C1iTtXGpSm5AQ5iIp2fkMAWD85FP7CQPpkqRoxhSIFZmTdurfYRmenq1OZ/4SeD5TESKcyvqJNzVT9z210B3cg3eAkP6ukvelW4qE2zgIANqUkGqvDEnAvEII9M89kuwhCMAekdfwnUSPrry+g77i1dUZHoRN1+MFj+waYtPaqxdYo2G1sysa6enxlu4jHMR5MfMk9eKHgaNgL3PiyANusYSS44amh8QIiVaX5nw82myZDCpQOZW7YqJKE6WX70Lbs4mS+wIs+ig4KIXO1B0p9kMb0OeVjHRl+KcXsWGRu/ECG/ExpqlVIssSPU407LohMXT2cJ37CY/R/EeK2XSDsQ2M3L3EAGUjCJdBGuwsOJ+2lG+HQpAVu9vAB4kq5jy9Ye+MG+8Xlkly3XZZ5+FkXyYxKnXb26/QVv0e5sIG5OmdJCPYFaH2J1QdKo7CdhEcBtrf6DMPWaimGMldShFqzLjOz3b3qLysRxFF0aGb7ipKPa57vawNzYHoPAViOcXQ=" file_glob: true - file: "$TRAVIS_BUILD_DIR/bin/*/*" + file: "$TRAVIS_BUILD_DIR/bin/*/*/*" skip_cleanup: true draft: true on: From bfd531281a64c5f93eead33c916a26528e062745 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 15 Jan 2019 10:15:55 -0800 Subject: [PATCH 108/153] Fix default values on last line. --- shared-module/displayio/Shape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c index c0c52a279b740..2ae955a14910b 100644 --- a/shared-module/displayio/Shape.c +++ b/shared-module/displayio/Shape.c @@ -49,7 +49,7 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt self->half_height = height; self->data = m_malloc(height * sizeof(uint32_t), false); - for (uint16_t i = 0; i < height; i++) { + for (uint16_t i = 0; i <= height; i++) { self->data[2 * i] = 0; self->data[2 * i + 1] = width; } From ac238838f25fa629b35587b4b4eea00b766ca2ff Mon Sep 17 00:00:00 2001 From: dsiee <38460825+dsiee@users.noreply.github.com> Date: Wed, 16 Jan 2019 14:48:41 +1100 Subject: [PATCH 109/153] Update pins.c add declaration for RED_LED as D3 to match silkscreen. --- ports/nrf/boards/feather_nrf52840_express/pins.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c index 56e4253744aa7..134d78cf56734 100644 --- a/ports/nrf/boards/feather_nrf52840_express/pins.c +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -21,6 +21,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, From c2d39a7ab778442648a28ee2f23ad54a89850e25 Mon Sep 17 00:00:00 2001 From: dsiee <38460825+dsiee@users.noreply.github.com> Date: Wed, 16 Jan 2019 14:58:16 +1100 Subject: [PATCH 110/153] Update pins.c --- ports/nrf/boards/feather_nrf52840_express/pins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c index 134d78cf56734..263316fb80d27 100644 --- a/ports/nrf/boards/feather_nrf52840_express/pins.c +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -21,7 +21,6 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, @@ -44,6 +43,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, }; From af0f1a7542dbcad1373c6d1e8dfd326ebb9d69ad Mon Sep 17 00:00:00 2001 From: dsiee <38460825+dsiee@users.noreply.github.com> Date: Wed, 16 Jan 2019 15:02:48 +1100 Subject: [PATCH 111/153] Update pins.c whitespace --- ports/nrf/boards/feather_nrf52840_express/pins.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c index 263316fb80d27..2f8ac02599fff 100644 --- a/ports/nrf/boards/feather_nrf52840_express/pins.c +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -44,6 +44,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, }; From 4d9f138e324f1c5a5736b420a4e86f2a620c80ba Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Tue, 15 Jan 2019 21:24:15 -0800 Subject: [PATCH 112/153] Add the dongle to the Travis build. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 16d094b47ddf0..6d32e0ac06295 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ git: # that SDK is shortest and add it there. In the case of major re-organizations, # just try to make the builds "about equal in run time" env: - - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf + - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="circuitplayground_express mini_sam_m4 grandcentral_m4_express pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk makerdiary_nrf52840_mdk_usb_dongle particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm:nrf - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm From 91452ec9cb6815f5fa0f2812e3dfdb837551c458 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Tue, 15 Jan 2019 21:24:36 -0800 Subject: [PATCH 113/153] Mention the MDK USB Dongle. --- ports/nrf/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/nrf/README.md b/ports/nrf/README.md index 9413174bfb215..49c9fbe297a1b 100644 --- a/ports/nrf/README.md +++ b/ports/nrf/README.md @@ -35,7 +35,8 @@ the following links: * Adafruit Feather nRF52840: `boards/feather_nrf52840_express/README.md`: 1MB Flash, 256KB SRAM * Nordic PCA10056 (uses nRF52840): `boards/pca10056/README.md` -* MakerDiary NRF52840 MDK: `boards/makerdiary_nrf52840_mdk/README.md` +* MakerDiary nRF52840 MDK: `boards/makerdiary_nrf52840_mdk/README.md` +* MakerDiary nRF52840 MDK USB Dongle: `boards/makerdiary_nrf52840_mdk_usb_dongle/README.md` For all other board targets, see the generic notes below. @@ -76,6 +77,7 @@ Target Board (BOARD) | Bluetooth Stack (SD) | Bluetooth Support | Fl pca10056 | s140 | Peripheral and Scanner | [Segger](#segger-targets) feather_nrf52840_express | s140 | Peripheral and Scanner | UF2 bootloader makerdiary_nrf52840_mdk | s140 | Peripheral and Scanner | pyocd or ARM mbed DAPLink +makerdiary_nrf52840_mdk_usb_dongle | s140 | Peripheral and Scanner | DFU bootloader & nrfutil ## Segger Targets From 19b6c5c802f4e9af39d84003661b91524f61721c Mon Sep 17 00:00:00 2001 From: ladyada Date: Wed, 16 Jan 2019 01:49:12 -0500 Subject: [PATCH 114/153] more pins! --- ports/atmel-samd/boards/pyportal/pins.c | 30 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index 7d4bc2a46a2d6..ddb8fa08a2b69 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -8,8 +8,20 @@ // microcontroller.pin. STATIC const mp_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_AUDIO_OUT), (mp_obj_t)&pin_PA02 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 }, // analog out/in + // STEMMA connectors + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PB02 }, // SDA + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PB03 }, // SCL + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PB00 }, // D3 + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PB00 }, // D3 + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PB01 }, // D4 + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PB01 }, // D4 + + // Indicator LED { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA27 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_L), (mp_obj_t)&pin_PA27 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB22 }, // LCD pins { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), (mp_obj_t)&pin_PA00 }, @@ -40,18 +52,26 @@ STATIC const mp_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), (mp_obj_t)&pin_PB15 }, { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), (mp_obj_t)&pin_PB16 }, + // UART + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PB12 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PB13 }, + + // SPI + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PA13 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA14 }, + + // I2C + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB02 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB03 }, // SD Card - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MOSI), (mp_obj_t)&pin_PA12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SCK), (mp_obj_t)&pin_PA13 }, { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), (mp_obj_t)&pin_PB30 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MISO), (mp_obj_t)&pin_PA14 }, { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), (mp_obj_t)&pin_PA01 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB22 }, - { 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_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&board_display_obj)} }; From 05d8885a1ab959fabdbb77f99408b2e7dc78b97c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 16 Jan 2019 12:04:42 -0800 Subject: [PATCH 115/153] Rework displays in prep for dynamic support and 8bit parallel. --- main.c | 5 + ports/atmel-samd/Makefile | 3 +- ports/atmel-samd/boards/board.h | 6 - .../boards/feather_m4_express/board.c | 9 +- .../boards/feather_m4_express/mpconfigboard.h | 1 + .../boards/feather_m4_express/pins.c | 3 +- ports/atmel-samd/boards/pyportal/board.c | 79 +--------- ports/atmel-samd/common-hal/busio/SPI.c | 6 - .../common-hal/displayio/FourWire.c | 96 ++--------- .../common-hal/displayio/FourWire.h | 13 +- .../common-hal/displayio/ParallelBus.c | 98 ++++++++++++ .../common-hal/displayio/ParallelBus.h | 41 +++++ .../common-hal/microcontroller/Pin.c | 26 +-- .../common-hal/microcontroller/Pin.h | 1 + ports/atmel-samd/supervisor/port.c | 3 - shared-bindings/displayio/Display.c | 149 ++++++++++++++++++ shared-bindings/displayio/Display.h | 59 +++++++ shared-bindings/displayio/FourWire.c | 83 +++++----- shared-bindings/displayio/FourWire.h | 29 +--- shared-bindings/displayio/ParallelBus.c | 79 ++++++++++ shared-bindings/displayio/ParallelBus.h | 47 ++++++ shared-module/displayio/Display.c | 149 ++++++++++++++++++ shared-module/displayio/Display.h | 55 +++++++ shared-module/displayio/__init__.c | 57 ++----- shared-module/displayio/__init__.h | 16 ++ .../shared}/board_busses.c | 7 +- .../shared}/board_busses.h | 14 +- supervisor/supervisor.mk | 1 + 28 files changed, 817 insertions(+), 318 deletions(-) create mode 100644 ports/atmel-samd/common-hal/displayio/ParallelBus.c create mode 100644 ports/atmel-samd/common-hal/displayio/ParallelBus.h create mode 100644 shared-bindings/displayio/Display.c create mode 100644 shared-bindings/displayio/Display.h create mode 100644 shared-bindings/displayio/ParallelBus.c create mode 100644 shared-bindings/displayio/ParallelBus.h create mode 100644 shared-module/displayio/Display.c create mode 100644 shared-module/displayio/Display.h rename {ports/atmel-samd => supervisor/shared}/board_busses.c (97%) rename {ports/atmel-samd => supervisor/shared}/board_busses.h (83%) diff --git a/main.c b/main.c index 4e0b77cfd54f0..d328fcaa4e9f3 100755 --- a/main.c +++ b/main.c @@ -27,6 +27,7 @@ #include #include +#include "shared-module/displayio/__init__.h" #include "extmod/vfs.h" #include "extmod/vfs_fat.h" @@ -49,6 +50,7 @@ #include "supervisor/port.h" #include "supervisor/filesystem.h" #include "supervisor/shared/autoreload.h" +#include "supervisor/shared/board_busses.h" #include "supervisor/shared/translate.h" #include "supervisor/shared/rgb_led_status.h" #include "supervisor/shared/safe_mode.h" @@ -198,10 +200,13 @@ bool run_code_py(safe_mode_t safe_mode) { serial_write_compressed(translate("WARNING: Your code filename has two extensions\n")); } } + // Turn off the display before the heap disappears. + reset_primary_display(); stop_mp(); free_memory(heap); reset_port(); + reset_board_busses(); reset_board(); reset_status_led(); diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 04e42a971a8d6..088288fbdcea5 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -238,7 +238,6 @@ SRC_ASF := $(addprefix asf4/$(CHIP_FAMILY)/, $(SRC_ASF)) SRC_C = \ audio_dma.c \ - board_busses.c \ background.c \ fatfs_port.c \ mphalport.c \ @@ -307,6 +306,7 @@ SRC_COMMON_HAL = \ digitalio/__init__.c \ digitalio/DigitalInOut.c \ displayio/FourWire.c \ + displayio/ParallelBus.c \ i2cslave/__init__.c \ i2cslave/I2CSlave.c \ microcontroller/__init__.c \ @@ -379,6 +379,7 @@ SRC_SHARED_MODULE = \ displayio/__init__.c \ displayio/Bitmap.c \ displayio/ColorConverter.c \ + displayio/Display.c \ displayio/Group.c \ displayio/OnDiskBitmap.c \ displayio/Palette.c \ diff --git a/ports/atmel-samd/boards/board.h b/ports/atmel-samd/boards/board.h index 61acc730ef96b..4f0ae9d728e72 100644 --- a/ports/atmel-samd/boards/board.h +++ b/ports/atmel-samd/boards/board.h @@ -33,12 +33,6 @@ #include "py/mpconfig.h" -#ifdef CIRCUITPY_DISPLAYIO -#include "common-hal/displayio/FourWire.h" - -extern displayio_fourwire_obj_t board_display_obj; -#endif - // Initializes board related state once on start up. void board_init(void); diff --git a/ports/atmel-samd/boards/feather_m4_express/board.c b/ports/atmel-samd/boards/feather_m4_express/board.c index 8096b9b8ea6d8..85e9959c9cc73 100644 --- a/ports/atmel-samd/boards/feather_m4_express/board.c +++ b/ports/atmel-samd/boards/feather_m4_express/board.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2018 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 @@ -26,6 +26,13 @@ #include "boards/board.h" #include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +#include "shared-bindings/displayio/Display.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/mipi_constants.h" + +#include "tick.h" void board_init(void) { } diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h index ed1dfe763a480..8510a7daee5a5 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h @@ -43,3 +43,4 @@ #define IGNORE_PIN_PA25 1 #define CIRCUITPY_I2CSLAVE +#define CIRCUITPY_DISPLAYIO (1) diff --git a/ports/atmel-samd/boards/feather_m4_express/pins.c b/ports/atmel-samd/boards/feather_m4_express/pins.c index 5004254c525c0..23b55e9577c92 100644 --- a/ports/atmel-samd/boards/feather_m4_express/pins.c +++ b/ports/atmel-samd/boards/feather_m4_express/pins.c @@ -1,6 +1,7 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "boards/board.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index 9cf3ee8c2272e..8ec498e8cdbe8 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -25,88 +25,15 @@ */ #include "boards/board.h" +#include "board_busses.h" #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" -#include "shared-bindings/displayio/FourWire.h" -#include "shared-module/displayio/mipi_constants.h" +#include "shared-module/displayio/__init__.h" #include "tick.h" -displayio_fourwire_obj_t board_display_obj; - -#define DELAY 0x80 - -uint8_t display_init_sequence[] = { - 0xEF, 3, 0x03, 0x80, 0x02, - 0xCF, 3, 0x00, 0xC1, 0x30, - 0xED, 4, 0x64, 0x03, 0x12, 0x81, - 0xE8, 3, 0x85, 0x00, 0x78, - 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, - 0xF7, 1, 0x20, - 0xEA, 2, 0x00, 0x00, - 0xc0, 1, 0x23, // Power control VRH[5:0] - 0xc1, 1, 0x10, // Power control SAP[2:0];BT[3:0] - 0xc5, 2, 0x3e, 0x28, // VCM control - 0xc7, 1, 0x86, // VCM control2 - 0x36, 1, 0x38, // Memory Access Control - 0x37, 1, 0x00, // Vertical scroll zero - 0x3a, 1, 0x55, // COLMOD: Pixel Format Set - 0xb1, 2, 0x00, 0x18, // Frame Rate Control (In Normal Mode/Full Colors) - 0xb6, 3, 0x08, 0x82, 0x27, // Display Function Control - 0xF2, 1, 0x00, // 3Gamma Function Disable - 0x26, 1, 0x01, // Gamma curve selected - 0xe0, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma - 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, - 0xe1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma - 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, - 0x11, DELAY, 120, // Exit Sleep - 0x29, DELAY, 120, // Display on -}; - - void board_init(void) { - board_display_obj.base.type = &displayio_fourwire_type; - common_hal_displayio_fourwire_construct(&board_display_obj, - &pin_PA13, // Clock - &pin_PA12, // Data - &pin_PB09, // Command or data - &pin_PB06, // Chip select - &pin_PA00, // Reset - 320, // Width - 240, // Height - 0, // column start - 0, // row start - 16, // Color depth - MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command - MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command - MIPI_COMMAND_WRITE_MEMORY_START); // Write memory command - - uint32_t i = 0; - common_hal_displayio_fourwire_begin_transaction(&board_display_obj); - while (i < sizeof(display_init_sequence)) { - uint8_t *cmd = display_init_sequence + i; - uint8_t data_size = *(cmd + 1); - bool delay = (data_size & DELAY) != 0; - data_size &= ~DELAY; - uint8_t *data = cmd + 2; - common_hal_displayio_fourwire_send(&board_display_obj, true, cmd, 1); - common_hal_displayio_fourwire_send(&board_display_obj, false, data, data_size); - if (delay) { - data_size++; - uint16_t delay_length_ms = *(cmd + 1 + data_size); - if (delay_length_ms == 255) { - delay_length_ms = 500; - } - uint64_t start = ticks_ms; - while (ticks_ms - start < delay_length_ms) {} - } else { - uint64_t start = ticks_ms; - while (ticks_ms - start < 10) {} - } - i += 2 + data_size; - } - common_hal_displayio_fourwire_end_transaction(&board_display_obj); } bool board_requests_safe_mode(void) { @@ -114,5 +41,5 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { - common_hal_displayio_fourwire_show(&board_display_obj, NULL); + common_hal_displayio_display_show(&primary_display_obj, NULL); } diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 4de34c975c021..68382d405d58d 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -65,12 +65,6 @@ void reset_sercoms(void) { if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) { continue; } - #endif - #ifdef CIRCUITPY_DISPLAYIO - // TODO(tannewt): Make this dynamic. - if (sercom_instances[i] == board_display_obj.bus.spi_desc.dev.prvt) { - continue; - } #endif // SWRST is same for all modes of SERCOMs. sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1; diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.c b/ports/atmel-samd/common-hal/displayio/FourWire.c index 51e6de5a221d7..7a0bdd0c163f8 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.c +++ b/ports/atmel-samd/common-hal/displayio/FourWire.c @@ -34,13 +34,11 @@ #include "tick.h" void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, - const mcu_pin_obj_t* clock, const mcu_pin_obj_t* data, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint16_t width, - uint16_t height, int16_t colstart, int16_t rowstart, uint16_t color_depth, - uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command) { + busio_spi_obj_t* spi, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset) { - common_hal_busio_spi_construct(&self->bus, clock, data, mp_const_none); - common_hal_busio_spi_never_reset(&self->bus); + self->bus = spi; + common_hal_busio_spi_never_reset(self->bus); common_hal_digitalio_digitalinout_construct(&self->command, command); common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); @@ -53,93 +51,27 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, never_reset_pin_number(command->number); never_reset_pin_number(chip_select->number); never_reset_pin_number(reset->number); - - self->width = width; - self->height = height; - self->color_depth = color_depth; - self->set_column_command = set_column_command; - self->set_row_command = set_row_command; - self->write_ram_command = write_ram_command; - self->current_group = NULL; - self->colstart = colstart; - self->rowstart = rowstart; } -bool common_hal_displayio_fourwire_begin_transaction(displayio_fourwire_obj_t* self) { - if (!common_hal_busio_spi_try_lock(&self->bus)) { +bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + if (!common_hal_busio_spi_try_lock(self->bus)) { return false; } // TODO(tannewt): Stop hardcoding SPI frequency, polarity and phase. - common_hal_busio_spi_configure(&self->bus, 48000000, 0, 0, 8); + common_hal_busio_spi_configure(self->bus, 12000000, 0, 0, 8); common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); return true; } -void common_hal_displayio_fourwire_send(displayio_fourwire_obj_t* self, bool command, uint8_t *data, uint32_t data_length) { +void common_hal_displayio_fourwire_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); common_hal_digitalio_digitalinout_set_value(&self->command, !command); - common_hal_busio_spi_write(&self->bus, data, data_length); + common_hal_busio_spi_write(self->bus, data, data_length); } -void common_hal_displayio_fourwire_end_transaction(displayio_fourwire_obj_t* self) { +void common_hal_displayio_fourwire_end_transaction(mp_obj_t obj) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); - common_hal_busio_spi_unlock(&self->bus); -} - -void common_hal_displayio_fourwire_show(displayio_fourwire_obj_t* self, displayio_group_t* root_group) { - self->current_group = root_group; - common_hal_displayio_fourwire_refresh_soon(self); -} - -void common_hal_displayio_fourwire_refresh_soon(displayio_fourwire_obj_t* self) { - self->refresh = true; -} - -int32_t common_hal_displayio_fourwire_wait_for_frame(displayio_fourwire_obj_t* self) { - uint64_t last_refresh = self->last_refresh; - while (last_refresh == self->last_refresh) { - MICROPY_VM_HOOK_LOOP - } - return 0; -} - -void displayio_fourwire_start_region_update(displayio_fourwire_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { - // TODO(tannewt): Handle displays with single byte bounds. - common_hal_displayio_fourwire_begin_transaction(self); - uint16_t data[2]; - common_hal_displayio_fourwire_send(self, true, &self->set_column_command, 1); - data[0] = __builtin_bswap16(x0 + self->colstart); - data[1] = __builtin_bswap16(x1-1 + self->colstart); - common_hal_displayio_fourwire_send(self, false, (uint8_t*) data, 4); - common_hal_displayio_fourwire_send(self, true, &self->set_row_command, 1); - data[0] = __builtin_bswap16(y0 + 1 + self->rowstart); - data[1] = __builtin_bswap16(y1 + self->rowstart); - common_hal_displayio_fourwire_send(self, false, (uint8_t*) data, 4); - common_hal_displayio_fourwire_send(self, true, &self->write_ram_command, 1); -} - -bool displayio_fourwire_send_pixels(displayio_fourwire_obj_t* self, uint32_t* pixels, uint32_t length) { - // TODO: Set this up so its async and 32 bit DMA transfers. - common_hal_displayio_fourwire_send(self, false, (uint8_t*) pixels, length*4); - return true; -} - -void displayio_fourwire_finish_region_update(displayio_fourwire_obj_t* self) { - common_hal_displayio_fourwire_end_transaction(self); -} - -bool displayio_fourwire_frame_queued(displayio_fourwire_obj_t* self) { - // Refresh at ~30 fps. - return (ticks_ms - self->last_refresh) > 32; -} - -bool displayio_fourwire_refresh_queued(displayio_fourwire_obj_t* self) { - return self->refresh || (self->current_group != NULL && displayio_group_needs_refresh(self->current_group)); -} - -void displayio_fourwire_finish_refresh(displayio_fourwire_obj_t* self) { - if (self->current_group != NULL) { - displayio_group_finish_refresh(self->current_group); - } - self->refresh = false; - self->last_refresh = ticks_ms; + common_hal_busio_spi_unlock(self->bus); } diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.h b/ports/atmel-samd/common-hal/displayio/FourWire.h index b997176701712..e3ae5781b52d3 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.h +++ b/ports/atmel-samd/common-hal/displayio/FourWire.h @@ -33,21 +33,10 @@ typedef struct { mp_obj_base_t base; - busio_spi_obj_t bus; + busio_spi_obj_t* bus; digitalio_digitalinout_obj_t command; digitalio_digitalinout_obj_t chip_select; digitalio_digitalinout_obj_t reset; - uint16_t width; - uint16_t height; - uint16_t color_depth; - uint8_t set_column_command; - uint8_t set_row_command; - uint8_t write_ram_command; - displayio_group_t *current_group; - bool refresh; - uint64_t last_refresh; - int16_t colstart; - int16_t rowstart; } displayio_fourwire_obj_t; #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.c b/ports/atmel-samd/common-hal/displayio/ParallelBus.c new file mode 100644 index 0000000000000..f852647a4b675 --- /dev/null +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.c @@ -0,0 +1,98 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "common-hal/microcontroller/Pin.h" +#include "py/runtime.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "tick.h" + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write) { + + uint8_t data_pin = data0->number; + if (data_pin % 8 != 0 || data_pin % 32 >= 24) { + mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); + } + for (uint8_t i = 0; i < 8; i++) { + if (!pin_number_is_free(data_pin + i)) { + mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i); + } + } + PortGroup *const g = &PORT->Group[data0->number % 32]; + g->DIRSET.reg = 0xff << data_pin; + self->bus = ((uint8_t*) &g->OUT.reg) + (data0->number % 32 / 8); + + self->command.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->command, command); + common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + + self->chip_select.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + + self->reset.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + + self->write.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->write, write); + common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); + + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); + never_reset_pin_number(reset->number); + never_reset_pin_number(write->number); + for (uint8_t i = 0; i < 8; i++) { + never_reset_pin_number(data_pin + i); + } +} + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + return true; +} + +void common_hal_displayio_parallelbus_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->command, !command); + for (uint32_t i = 0; i < data_length; i++) { + common_hal_digitalio_digitalinout_set_value(&self->write, false); + *self->bus = data[i]; + common_hal_digitalio_digitalinout_set_value(&self->write, true); + } +} + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); +} diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.h b/ports/atmel-samd/common-hal/displayio/ParallelBus.h new file mode 100644 index 0000000000000..cc45598c5b01a --- /dev/null +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.h @@ -0,0 +1,41 @@ +/* + * 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_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_PARALLELBUS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_PARALLELBUS_H + +#include "common-hal/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + uint8_t* bus; + digitalio_digitalinout_obj_t command; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t reset; + digitalio_digitalinout_obj_t write; +} displayio_parallelbus_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_PARALLELBUS_H diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 7dd9c6b09ae7c..7d0d97758c068 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -169,6 +169,20 @@ void claim_pin(const mcu_pin_obj_t* pin) { #endif } +bool pin_number_is_free(uint8_t pin_number) { + PortGroup *const port = &PORT->Group[(enum gpio_port)GPIO_PORT(pin_number)]; + uint8_t pin_index = GPIO_PIN(pin_number); + volatile PORT_PINCFG_Type *state = &port->PINCFG[pin_index]; + volatile PORT_PMUX_Type *pmux = &port->PMUX[pin_index / 2]; + + if (pin_number == PIN_PA30 || pin_number == PIN_PA31) { + return state->bit.PMUXEN == 1 && ((pmux->reg >> (4 * pin_index % 2)) & 0xf) == 0x6; + } + + return state->bit.PMUXEN == 0 && state->bit.INEN == 0 && + state->bit.PULLEN == 0 && (port->DIR.reg & (1 << pin_index)) == 0; +} + bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { #ifdef MICROPY_HW_NEOPIXEL if (pin == MICROPY_HW_NEOPIXEL) { @@ -190,15 +204,5 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { } #endif - PortGroup *const port = &PORT->Group[(enum gpio_port)GPIO_PORT(pin->number)]; - uint8_t pin_index = GPIO_PIN(pin->number); - volatile PORT_PINCFG_Type *state = &port->PINCFG[pin_index]; - volatile PORT_PMUX_Type *pmux = &port->PMUX[pin_index / 2]; - - if (pin->number == PIN_PA30 || pin->number == PIN_PA31) { - return state->bit.PMUXEN == 1 && ((pmux->reg >> (4 * pin_index % 2)) & 0xf) == 0x6; - } - - return state->bit.PMUXEN == 0 && state->bit.INEN == 0 && - state->bit.PULLEN == 0 && (port->DIR.reg & (1 << pin_index)) == 0; + return pin_number_is_free(pin->number); } diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.h b/ports/atmel-samd/common-hal/microcontroller/Pin.h index f798ea300c29d..14887207aa1b5 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.h +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.h @@ -45,5 +45,6 @@ void reset_all_pins(void); void reset_pin_number(uint8_t pin_number); void never_reset_pin_number(uint8_t pin_number); void claim_pin(const mcu_pin_obj_t* pin); +bool pin_number_is_free(uint8_t pin_number); #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 941838618536c..7e7e894cbe72d 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -60,7 +60,6 @@ #include "samd/external_interrupts.h" #include "samd/dma.h" #include "shared-bindings/rtc/__init__.h" -#include "board_busses.h" #include "reset.h" #include "tick.h" @@ -226,8 +225,6 @@ void reset_port(void) { reset_all_pins(); - reset_board_busses(); - // Output clocks for debugging. // not supported by SAMD51G; uncomment for SAMD51J or update for 51G // #ifdef SAMD51 diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c new file mode 100644 index 0000000000000..5db4704179c7c --- /dev/null +++ b/shared-bindings/displayio/Display.c @@ -0,0 +1,149 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 "shared-bindings/displayio/Display.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`FourWire` -- Manage updating a display over SPI four wire protocol +//| ========================================================================== +//| +//| Manage updating a display over SPI four wire protocol in the background while Python code runs. +//| It doesn't handle display initialization. +//| +//| .. warning:: This will be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: Display(display_bus, *, width, height, colstart=0, rowstart=0, color_depth=16, +//| set_column_command=0x2a set_row_command=0x2b, write_ram_command=0x2c) +//| +//| Create a FourWire object associated with the given pins. +//| +STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, + { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} }, + { MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} }, + { MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} }, + }; + 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); + + mp_obj_t display_bus = args[ARG_display_bus].u_obj; + + mp_int_t width = args[ARG_width].u_int; + mp_int_t height = args[ARG_height].u_int; + if (width == -1 || height == -1) { + mp_raise_ValueError(translate("Width and height kwargs required")); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); + + displayio_display_obj_t *self; + if (display_bus == &primary_display.fourwire_bus) { + self = &primary_display.display; + } else { + self = m_new_obj(displayio_display_obj_t); + } + self->base.type = &displayio_display_type; + common_hal_displayio_display_construct(self, + display_bus, width, height, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, + args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, + args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len); + + return self; +} + +//| .. method:: show(group) +//| +//| Switches to displaying the given group of layers. +//| +STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); + if (native_layer == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Must be a Group subclass.")); + } + displayio_group_t* group = MP_OBJ_TO_PTR(native_layer); + common_hal_displayio_display_show(self, group); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show); + +//| .. method:: refresh_soon() +//| +//| Queues up a display refresh that happens in the background. +//| +STATIC mp_obj_t displayio_display_obj_refresh_soon(mp_obj_t self_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_displayio_display_refresh_soon(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_refresh_soon_obj, displayio_display_obj_refresh_soon); + +//| .. method:: wait_for_frame() +//| +//| Waits until the next frame has been transmitted to the display unless the wait count is +//| behind the rendered frames. In that case, this will return immediately with the wait count. +//| +STATIC mp_obj_t displayio_display_obj_wait_for_frame(mp_obj_t self_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_wait_for_frame(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame); + + +STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) }, + { MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_display_wait_for_frame_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table); + +const mp_obj_type_t displayio_display_type = { + { &mp_type_type }, + .name = MP_QSTR_Display, + .make_new = displayio_display_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_display_locals_dict, +}; diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h new file mode 100644 index 0000000000000..4cec660586ad4 --- /dev/null +++ b/shared-bindings/displayio/Display.h @@ -0,0 +1,59 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 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_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H + +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/Display.h" +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_display_type; + +#define DELAY 0x80 + +void common_hal_displayio_display_construct(displayio_display_obj_t* self, + mp_obj_t bus, uint16_t width, uint16_t height, + int16_t colstart, int16_t rowstart, uint16_t color_depth, + uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, + uint8_t* init_sequence, uint16_t init_sequence_len); + +int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self); + +void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group); + +void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self); + +void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); +void displayio_display_finish_region_update(displayio_display_obj_t* self); +bool displayio_display_frame_queued(displayio_display_obj_t* self); + +bool displayio_display_refresh_queued(displayio_display_obj_t* self); +void displayio_display_finish_refresh(displayio_display_obj_t* self); +bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 80aa814df2134..674d1c9008838 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2018-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 @@ -35,6 +35,7 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" #include "supervisor/shared/translate.h" //| .. currentmodule:: displayio @@ -47,14 +48,44 @@ //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| -//| .. class:: FourWire(*, clock, data, command, chip_select, width, height, colstart, rowstart, -//| color_depth, set_column_command, set_row_command, write_ram_command) +//| .. class:: FourWire(spi_bus, *, command, chip_select, reset) //| //| Create a FourWire object associated with the given pins. //| STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_raise_NotImplementedError(translate("displayio is a work in progress")); - return mp_const_none; + enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + }; + 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); + + mp_obj_t command = args[ARG_command].u_obj; + mp_obj_t chip_select = args[ARG_chip_select].u_obj; + mp_obj_t reset = args[ARG_reset].u_obj; + if (command == mp_const_none || chip_select == mp_const_none) { + mp_raise_ValueError(translate("Command and chip_select required")); + } + + displayio_fourwire_obj_t* self; + mp_obj_t spi = args[ARG_spi_bus].u_obj; + if (board_spi() == spi && primary_display.bus_type == NULL) { + self = &primary_display.fourwire_bus; + primary_display.bus_type = &displayio_fourwire_type; + } else { + // TODO(tannewt): Always check pin free. For now we ignore the primary display. + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(reset); + self = m_new_obj(displayio_fourwire_obj_t); + } + + common_hal_displayio_fourwire_construct(self, + MP_OBJ_TO_PTR(spi), command, chip_select, reset); + return self; } @@ -68,50 +99,8 @@ STATIC mp_obj_t displayio_fourwire_obj_send(size_t n_args, const mp_obj_t *pos_a } MP_DEFINE_CONST_FUN_OBJ_KW(displayio_fourwire_send_obj, 1, displayio_fourwire_obj_send); -//| .. method:: show(group) -//| -//| Switches do displaying the given group of elements. -//| -STATIC mp_obj_t displayio_fourwire_obj_show(mp_obj_t self_in, mp_obj_t group_in) { - displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); - if (native_layer == MP_OBJ_NULL) { - mp_raise_ValueError(translate("Must be a Group subclass.")); - } - displayio_group_t* group = MP_OBJ_TO_PTR(native_layer); - common_hal_displayio_fourwire_show(self, group); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(displayio_fourwire_show_obj, displayio_fourwire_obj_show); - -//| .. method:: refresh_soon() -//| -//| Queues up a display refresh that happens in the background. -//| -STATIC mp_obj_t displayio_fourwire_obj_refresh_soon(mp_obj_t self_in) { - displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_displayio_fourwire_refresh_soon(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_refresh_soon_obj, displayio_fourwire_obj_refresh_soon); - -//| .. method:: wait_for_frame() -//| -//| Waits until the next frame has been transmitted to the display unless the wait count is -//| behind the rendered frames. In that case, this will return immediately with the wait count. -//| -STATIC mp_obj_t displayio_fourwire_obj_wait_for_frame(mp_obj_t self_in) { - displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_fourwire_wait_for_frame(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_wait_for_frame_obj, displayio_fourwire_obj_wait_for_frame); - - STATIC const mp_rom_map_elem_t displayio_fourwire_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_fourwire_send_obj) }, - { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_fourwire_show_obj) }, - { MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_fourwire_refresh_soon_obj) }, - { MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_fourwire_wait_for_frame_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_fourwire_locals_dict, displayio_fourwire_locals_dict_table); diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index fc51f558dd132..a9e1bf566a95d 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -31,35 +31,18 @@ #include "common-hal/microcontroller/Pin.h" #include "shared-module/displayio/Group.h" +#include "supervisor/shared/board_busses.h" extern const mp_obj_type_t displayio_fourwire_type; -// TODO(tannewt): Split this apart into FourWire and a Display object because the dimensions and -// commands are also used for the parallel buses. void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, - const mcu_pin_obj_t* clock, const mcu_pin_obj_t* data, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint16_t width, uint16_t height, - int16_t colstart, int16_t rowstart, uint16_t color_depth, - uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command); + busio_spi_obj_t* spi, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset); -int32_t common_hal_displayio_fourwire_wait_for_frame(displayio_fourwire_obj_t* self); +bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self); -bool common_hal_displayio_fourwire_begin_transaction(displayio_fourwire_obj_t* self); +void common_hal_displayio_fourwire_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); -void common_hal_displayio_fourwire_send(displayio_fourwire_obj_t* self, bool command, uint8_t *data, uint32_t data_length); - -void common_hal_displayio_fourwire_end_transaction(displayio_fourwire_obj_t* self); - -void common_hal_displayio_fourwire_show(displayio_fourwire_obj_t* self, displayio_group_t* root_group); - -void common_hal_displayio_fourwire_refresh_soon(displayio_fourwire_obj_t* self); - -void displayio_fourwire_start_region_update(displayio_fourwire_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); -void displayio_fourwire_finish_region_update(displayio_fourwire_obj_t* self); -bool displayio_fourwire_frame_queued(displayio_fourwire_obj_t* self); - -bool displayio_fourwire_refresh_queued(displayio_fourwire_obj_t* self); -void displayio_fourwire_finish_refresh(displayio_fourwire_obj_t* self); -bool displayio_fourwire_send_pixels(displayio_fourwire_obj_t* self, uint32_t* pixels, uint32_t length); +void common_hal_displayio_fourwire_end_transaction(mp_obj_t self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c new file mode 100644 index 0000000000000..dddb4ce8ac2f8 --- /dev/null +++ b/shared-bindings/displayio/ParallelBus.c @@ -0,0 +1,79 @@ +/* + * This file is part of the Micro Python 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 "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`ParallelBus` -- Manage updating a display over SPI four wire protocol +//| ========================================================================== +//| +//| Manage updating a display over SPI four wire protocol in the background while Python code runs. +//| It doesn't handle display initialization. +//| +//| .. warning:: This will be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: ParallelBus(*, data0, command, chip_select, reset, write, bus_width=8) +//| +//| Create a ParallelBus object associated with the given pins. +//| +STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_raise_NotImplementedError(translate("displayio is a work in progress")); + return mp_const_none; +} + + +//| .. method:: send(command, data) +//| +//| +STATIC mp_obj_t displayio_parallelbus_obj_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_raise_NotImplementedError(translate("displayio is a work in progress")); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(displayio_parallelbus_send_obj, 1, displayio_parallelbus_obj_send); + +STATIC const mp_rom_map_elem_t displayio_parallelbus_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_parallelbus_send_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_parallelbus_locals_dict, displayio_parallelbus_locals_dict_table); + +const mp_obj_type_t displayio_parallelbus_type = { + { &mp_type_type }, + .name = MP_QSTR_ParallelBus, + .make_new = displayio_parallelbus_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_parallelbus_locals_dict, +}; diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h new file mode 100644 index 0000000000000..f1d1656b111aa --- /dev/null +++ b/shared-bindings/displayio/ParallelBus.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python 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_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H + +#include "common-hal/displayio/ParallelBus.h" +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_parallelbus_type; + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write); + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self); + +void common_hal_displayio_parallelbus_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c new file mode 100644 index 0000000000000..0a14e74bb3c4a --- /dev/null +++ b/shared-module/displayio/Display.c @@ -0,0 +1,149 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 "shared-bindings/displayio/Display.h" + +#include "py/runtime.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "tick.h" + +#define DELAY 0x80 + +void common_hal_displayio_display_construct(displayio_display_obj_t* self, + mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, + uint16_t color_depth, uint8_t set_column_command, uint8_t set_row_command, + uint8_t write_ram_command, uint8_t* init_sequence, uint16_t init_sequence_len) { + self->width = width; + self->height = height; + self->color_depth = color_depth; + self->set_column_command = set_column_command; + self->set_row_command = set_row_command; + self->write_ram_command = write_ram_command; + self->current_group = NULL; + self->colstart = colstart; + self->rowstart = rowstart; + + if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { + self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; + self->send = common_hal_displayio_parallelbus_send; + self->end_transaction = common_hal_displayio_parallelbus_end_transaction; + } else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) { + self->begin_transaction = common_hal_displayio_fourwire_begin_transaction; + self->send = common_hal_displayio_fourwire_send; + self->end_transaction = common_hal_displayio_fourwire_end_transaction; + } else { + mp_raise_ValueError(translate("Unsupported display bus type")); + } + self->bus = bus; + + uint32_t i = 0; + self->begin_transaction(self->bus); + while (i < init_sequence_len) { + uint8_t *cmd = init_sequence + i; + uint8_t data_size = *(cmd + 1); + bool delay = (data_size & DELAY) != 0; + data_size &= ~DELAY; + uint8_t *data = cmd + 2; + self->send(self->bus, true, cmd, 1); + self->send(self->bus, false, data, data_size); + if (delay) { + data_size++; + uint16_t delay_length_ms = *(cmd + 1 + data_size); + if (delay_length_ms == 255) { + delay_length_ms = 500; + } + uint64_t start = ticks_ms; + while (ticks_ms - start < delay_length_ms) {} + } else { + uint64_t start = ticks_ms; + while (ticks_ms - start < 10) {} + } + i += 2 + data_size; + } + self->end_transaction(self->bus); +} + +void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { + self->current_group = root_group; + common_hal_displayio_display_refresh_soon(self); +} + +void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self) { + self->refresh = true; +} + +int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self) { + uint64_t last_refresh = self->last_refresh; + while (last_refresh == self->last_refresh) { + MICROPY_VM_HOOK_LOOP + } + return 0; +} + +void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { + // TODO(tannewt): Handle displays with single byte bounds. + self->begin_transaction(self->bus); + uint16_t data[2]; + self->send(self->bus, true, &self->set_column_command, 1); + data[0] = __builtin_bswap16(x0 + self->colstart); + data[1] = __builtin_bswap16(x1 + self->colstart); + self->send(self->bus, false, (uint8_t*) data, 4); + self->send(self->bus, true, &self->set_row_command, 1); + data[0] = __builtin_bswap16(y0 + self->rowstart); + data[1] = __builtin_bswap16(y1 + self->rowstart); + self->send(self->bus, false, (uint8_t*) data, 4); + self->send(self->bus, true, &self->write_ram_command, 1); +} + +void displayio_display_finish_region_update(displayio_display_obj_t* self) { + self->end_transaction(self->bus); +} + +bool displayio_display_frame_queued(displayio_display_obj_t* self) { + // Refresh at ~30 fps. + return (ticks_ms - self->last_refresh) > 32; +} + +bool displayio_display_refresh_queued(displayio_display_obj_t* self) { + return self->refresh || (self->current_group != NULL && displayio_group_needs_refresh(self->current_group)); +} + +void displayio_display_finish_refresh(displayio_display_obj_t* self) { + if (self->current_group != NULL) { + displayio_group_finish_refresh(self->current_group); + } + self->refresh = false; + self->last_refresh = ticks_ms; +} + +bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length) { + self->send(self->bus, false, (uint8_t*) pixels, length * 4); + return true; +} diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h new file mode 100644 index 0000000000000..1f1355d31b521 --- /dev/null +++ b/shared-module/displayio/Display.h @@ -0,0 +1,55 @@ +/* + * 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_SHARED_MODULE_DISPLAYIO_DISPLAY_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H + +#include "shared-module/displayio/Group.h" + +typedef bool (*display_bus_begin_transaction)(mp_obj_t bus); +typedef void (*display_bus_send)(mp_obj_t bus, bool command, uint8_t *data, uint32_t data_length); +typedef void (*display_bus_end_transaction)(mp_obj_t bus); + +typedef struct { + mp_obj_base_t base; + mp_obj_t bus; + uint16_t width; + uint16_t height; + uint16_t color_depth; + uint8_t set_column_command; + uint8_t set_row_command; + uint8_t write_ram_command; + displayio_group_t *current_group; + bool refresh; + uint64_t last_refresh; + int16_t colstart; + int16_t rowstart; + display_bus_begin_transaction begin_transaction; + display_bus_send send; + display_bus_end_transaction end_transaction; +} displayio_display_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index f1a00db9f7b73..b528c328964b3 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -1,44 +1,17 @@ -#include "shared-bindings/displayio/FourWire.h" -extern displayio_fourwire_obj_t board_display_obj; +#include "shared-module/displayio/__init__.h" -void start_region_update(displayio_fourwire_obj_t* display, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { - // TODO delegate between different display types - displayio_fourwire_start_region_update(display, x0, y0, x1, y1); -} - -void finish_region_update(displayio_fourwire_obj_t* display) { - // TODO delegate between different display types - displayio_fourwire_finish_region_update(display); -} - -void finish_refresh(displayio_fourwire_obj_t* display) { - // TODO delegate between different display types - displayio_fourwire_finish_refresh(display); -} - -bool frame_queued(displayio_fourwire_obj_t* display) { - // TODO delegate between different display types - return displayio_fourwire_frame_queued(display); -} - -bool refresh_queued(displayio_fourwire_obj_t* display) { - // TODO delegate between different display types - return displayio_fourwire_refresh_queued(display); -} +#include "shared-bindings/displayio/Display.h" -bool send_pixels(displayio_fourwire_obj_t* display, uint32_t* pixels, uint32_t length) { - // TODO delegate between different display types - return displayio_fourwire_send_pixels(display, pixels, length); -} +primary_display_t primary_display; void displayio_refresh_display(void) { - displayio_fourwire_obj_t* display = &board_display_obj; + displayio_display_obj_t* display = &primary_display.display; - if (!frame_queued(display)) { + if (!displayio_display_frame_queued(display)) { return; } - if (refresh_queued(display)) { + if (displayio_display_refresh_queued(display)) { PORT->Group[1].DIRSET.reg = 1 << 22; // We compute the pixels @@ -50,7 +23,7 @@ void displayio_refresh_display(void) { //size_t row_size = (x1 - x0); uint16_t buffer_size = 256; uint32_t buffer[buffer_size / 2]; - start_region_update(display, x0, y0, x1, y1); + displayio_display_start_region_update(display, x0, y0, x1, y1); for (uint16_t y = y0; y < y1; ++y) { for (uint16_t x = x0; x < x1; ++x) { uint16_t* pixel = &(((uint16_t*)buffer)[index]); @@ -72,8 +45,8 @@ void displayio_refresh_display(void) { index += 1; // The buffer is full, send it. if (index >= buffer_size) { - if (!send_pixels(display, buffer, buffer_size / 2)) { - finish_region_update(display); + if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) { + displayio_display_finish_region_update(display); return; } index = 0; @@ -81,11 +54,15 @@ void displayio_refresh_display(void) { } } // Send the remaining data. - if (index && !send_pixels(display, buffer, index * 2)) { - finish_region_update(display); + if (index && !displayio_display_send_pixels(display, buffer, index * 2)) { + displayio_display_finish_region_update(display); return; } - finish_region_update(display); + displayio_display_finish_region_update(display); } - finish_refresh(display); + displayio_display_finish_refresh(display); +} + +void reset_primary_display(void) { + common_hal_displayio_display_show(&primary_display.display, NULL); } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 556af430d54d3..84db98fcce30f 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -27,6 +27,22 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H +#include "shared-bindings/displayio/Display.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/ParallelBus.h" + +typedef struct { + union { + displayio_fourwire_obj_t fourwire_bus; + displayio_parallelbus_obj_t parallel_bus; + }; + mp_const_obj_t bus_type; + displayio_display_obj_t display; +} primary_display_t; + +extern primary_display_t primary_display; + void displayio_refresh_display(void); +void reset_primary_display(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H diff --git a/ports/atmel-samd/board_busses.c b/supervisor/shared/board_busses.c similarity index 97% rename from ports/atmel-samd/board_busses.c rename to supervisor/shared/board_busses.c index 424c9cc08f7b2..84919ebff158f 100644 --- a/ports/atmel-samd/board_busses.c +++ b/supervisor/shared/board_busses.c @@ -63,11 +63,12 @@ STATIC mp_obj_t board_i2c(void) { MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); #if BOARD_SPI +STATIC busio_spi_obj_t spi_obj; STATIC mp_obj_t spi_singleton = NULL; -STATIC mp_obj_t board_spi(void) { +mp_obj_t board_spi(void) { if (spi_singleton == NULL) { - busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); + busio_spi_obj_t *self = &spi_obj; self->base.type = &busio_spi_type; assert_pin_free(DEFAULT_SPI_BUS_SCK); assert_pin_free(DEFAULT_SPI_BUS_MOSI); @@ -81,7 +82,7 @@ STATIC mp_obj_t board_spi(void) { return spi_singleton; } #else -STATIC mp_obj_t board_spi(void) { +mp_obj_t board_spi(void) { mp_raise_NotImplementedError(translate("No default SPI bus")); return NULL; } diff --git a/ports/atmel-samd/board_busses.h b/supervisor/shared/board_busses.h similarity index 83% rename from ports/atmel-samd/board_busses.h rename to supervisor/shared/board_busses.h index 08dd1aae12d85..f6a8a429665df 100644 --- a/ports/atmel-samd/board_busses.h +++ b/supervisor/shared/board_busses.h @@ -24,18 +24,20 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BOARD_BUSSES_H -#define MICROPY_INCLUDED_ATMEL_SAMD_BOARD_BUSSES_H +#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_BOARD_BUSSES_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_BOARD_BUSSES_H -void board_i2c(void); +#include "py/obj.h" + +mp_obj_t board_i2c(void); extern mp_obj_fun_builtin_fixed_t board_i2c_obj; -void board_spi(void); +mp_obj_t board_spi(void); extern mp_obj_fun_builtin_fixed_t board_spi_obj; -void board_uart(void); +mp_obj_t board_uart(void); extern mp_obj_fun_builtin_fixed_t board_uart_obj; void reset_board_busses(void); -#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARD_BUSSES_H +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_BOARD_BUSSES_H diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 191af7b255c99..0bbfd9141d7d2 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -2,6 +2,7 @@ SRC_SUPERVISOR = \ main.c \ supervisor/port.c \ supervisor/shared/autoreload.c \ + supervisor/shared/board_busses.c \ supervisor/shared/filesystem.c \ supervisor/shared/flash.c \ supervisor/shared/micropython.c \ From 7a33e588d40e01862b60d6f0b9d2880ad19be030 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 16 Jan 2019 20:41:01 -0500 Subject: [PATCH 116/153] Put back native C UUID string parsing and printing (complete rewrite) --- shared-bindings/bleio/UUID.c | 70 +++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index f2df9d0952a81..8b868a1aeb96e 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -70,20 +70,51 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, co common_hal_bleio_uuid_construct(self, uuid16, NULL); } else { - mp_buffer_info_t bufinfo; - if (!mp_get_buffer(value, &bufinfo, MP_BUFFER_READ)) { - mp_raise_ValueError(translate("UUID value is not int or byte buffer")); - } + if (MP_OBJ_IS_STR(value)) { + // 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + GET_STR_DATA_LEN(value, chars, len); + char hex[32]; + // Validate length, hyphens, and hex digits. + bool good_uuid = + len == 36 && chars[8] == '-' && chars[13] == '-' && chars[18] == '-' && chars[23] == '-'; + if (good_uuid) { + size_t hex_idx = 0; + for (int i = 0; i < len; i++) { + if (unichar_isxdigit(chars[i])) { + hex[hex_idx] = chars[i]; + hex_idx++; + } + } + good_uuid = hex_idx == 32; + } + if (!good_uuid) { + mp_raise_ValueError(translate("UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'")); + } + + size_t hex_idx = 0; + for (int i = 15; i >= 0; i--) { + uuid128[i] = (unichar_xdigit_value(hex[hex_idx]) << 4) | unichar_xdigit_value(hex[hex_idx + 1]); + hex_idx += 2; + } + } else { + // Last possibility is that it's a buf. + mp_buffer_info_t bufinfo; + if (!mp_get_buffer(value, &bufinfo, MP_BUFFER_READ)) { + mp_raise_ValueError(translate("UUID value is not str, int or byte buffer")); + } - if (bufinfo.len != 16) { - mp_raise_ValueError(translate("Byte buffer must be 16 bytes.")); + if (bufinfo.len != 16) { + mp_raise_ValueError(translate("Byte buffer must be 16 bytes.")); + } + + memcpy(uuid128, bufinfo.buf, 16); } - memcpy(uuid128, bufinfo.buf, 16); + // Str and bytes both get constructed the same way here. uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12]; uuid128[12] = 0; uuid128[13] = 0; - common_hal_bleio_uuid_construct(self, uuid16, bufinfo.buf); + common_hal_bleio_uuid_construct(self, uuid16, uuid128); } return MP_OBJ_FROM_PTR(self); @@ -200,9 +231,32 @@ STATIC mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_ } } +void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint32_t size = common_hal_bleio_uuid_get_size(self); + if (size == 16) { + 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); + mp_printf(print, "UUID('" + "%02x%02x%02x%02x-" + "%02x%02x-" + "%02x%02x-" + "%02x%02x-" + "%02x%02x%02x%02x%02x%02x')", + uuid128[15], uuid128[14], uuid128[13], uuid128[12], + uuid128[11], uuid128[10], + uuid128[9], uuid128[8], + uuid128[7], uuid128[6], + uuid128[5], uuid128[4], uuid128[3], uuid128[2], uuid128[1], uuid128[0]); + } +} + const mp_obj_type_t bleio_uuid_type = { { &mp_type_type }, .name = MP_QSTR_UUID, + .print = bleio_uuid_print, .make_new = bleio_uuid_make_new, .unary_op = bleio_uuid_unary_op, .binary_op = bleio_uuid_binary_op, From 84292ad89070f1994ed09b59c8a693216a40cd89 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 00:20:16 -0800 Subject: [PATCH 117/153] External fourwire works and blinka splash after --- main.c | 2 +- ports/atmel-samd/background.c | 2 +- .../grandcentral_m4_express/mpconfigboard.h | 2 + .../boards/grandcentral_m4_express/pins.c | 2 +- .../boards/pyportal/mpconfigboard.h | 2 +- ports/atmel-samd/boards/pyportal/pins.c | 4 +- ports/atmel-samd/common-hal/busio/SPI.c | 13 ++ .../common-hal/displayio/FourWire.c | 10 + .../common-hal/displayio/FourWire.h | 1 + .../common-hal/microcontroller/Pin.c | 2 + shared-bindings/displayio/Display.c | 23 +- shared-bindings/displayio/FourWire.c | 23 +- shared-bindings/displayio/FourWire.h | 2 + shared-bindings/displayio/ParallelBus.h | 2 + shared-bindings/displayio/__init__.c | 16 ++ shared-bindings/displayio/__init__.h | 4 +- shared-module/displayio/__init__.c | 220 ++++++++++++++---- shared-module/displayio/__init__.h | 7 +- 18 files changed, 255 insertions(+), 82 deletions(-) diff --git a/main.c b/main.c index d328fcaa4e9f3..02c832e67512c 100755 --- a/main.c +++ b/main.c @@ -201,7 +201,7 @@ bool run_code_py(safe_mode_t safe_mode) { } } // Turn off the display before the heap disappears. - reset_primary_display(); + reset_displays(); stop_mp(); free_memory(heap); diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 439877d2e7cba..59e03008a9151 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -44,7 +44,7 @@ void run_background_tasks(void) { audio_dma_background(); #endif #ifdef CIRCUITPY_DISPLAYIO - displayio_refresh_display(); + displayio_refresh_displays(); #endif #if MICROPY_PY_NETWORK diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h index e1bef00194a75..465c51b4abaa7 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h @@ -46,3 +46,5 @@ #define IGNORE_PIN_PA25 1 #define CIRCUITPY_I2CSLAVE +#define CIRCUITPY_DISPLAYIO (1) +#define CIRCUITPY_DISPLAY_LIMIT (3) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c index 081bb701e7968..0d19a63efdd16 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.h b/ports/atmel-samd/boards/pyportal/mpconfigboard.h index 847e2ba7641c1..f02d4a372bbcc 100644 --- a/ports/atmel-samd/boards/pyportal/mpconfigboard.h +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.h @@ -13,7 +13,7 @@ // QSPI Data pins #define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 ) // QSPI CS, and QSPI SCK -#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 ) +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 ) #define MICROPY_PORT_C ( 0 ) #define MICROPY_PORT_D (0) diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index ddb8fa08a2b69..4ddc10e52a3e7 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -1,7 +1,7 @@ #include "shared-bindings/board/__init__.h" #include "boards/board.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from @@ -72,7 +72,5 @@ STATIC const mp_map_elem_t board_global_dict_table[] = { { 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_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&board_display_obj)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 68382d405d58d..8fb831a69a09d 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -54,6 +54,17 @@ void never_reset_sercom(Sercom* sercom) { } } +void allow_reset_sercom(Sercom* sercom) { + // Reset all SERCOMs except the ones being used by on-board devices. + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (sercom_instances[i] == sercom) { + never_reset_sercoms[i] = false; + break; + } + } +} + void reset_sercoms(void) { // Reset all SERCOMs except the ones being used by on-board devices. Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; @@ -235,6 +246,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } + allow_reset_sercom(self->spi_desc.dev.prvt); + spi_m_sync_disable(&self->spi_desc); spi_m_sync_deinit(&self->spi_desc); reset_pin_number(self->clock_pin); diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.c b/ports/atmel-samd/common-hal/displayio/FourWire.c index 7a0bdd0c163f8..ab01e26091c8d 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.c +++ b/ports/atmel-samd/common-hal/displayio/FourWire.c @@ -53,6 +53,16 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, never_reset_pin_number(reset->number); } +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { + if (self->bus == &self->inline_bus) { + common_hal_busio_spi_deinit(self->bus); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->reset.pin->number); +} + bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); if (!common_hal_busio_spi_try_lock(self->bus)) { diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.h b/ports/atmel-samd/common-hal/displayio/FourWire.h index e3ae5781b52d3..234bcf794f3de 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.h +++ b/ports/atmel-samd/common-hal/displayio/FourWire.h @@ -34,6 +34,7 @@ typedef struct { mp_obj_base_t base; busio_spi_obj_t* bus; + busio_spi_obj_t inline_bus; digitalio_digitalinout_obj_t command; digitalio_digitalinout_obj_t chip_select; digitalio_digitalinout_obj_t reset; diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 7d0d97758c068..b7d527d042ab5 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -100,6 +100,8 @@ void never_reset_pin_number(uint8_t pin_number) { } void reset_pin_number(uint8_t pin_number) { + never_reset_pins[GPIO_PORT(pin_number)] &= ~(1 << GPIO_PIN(pin_number)); + if (pin_number >= PORT_BITS) { return; } diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 5db4704179c7c..21f44965ea351 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -40,18 +40,19 @@ //| .. currentmodule:: displayio //| -//| :class:`FourWire` -- Manage updating a display over SPI four wire protocol +//| :class:`Display` -- Manage updating a display over a display bus //| ========================================================================== //| -//| Manage updating a display over SPI four wire protocol in the background while Python code runs. -//| It doesn't handle display initialization. +//| This initializes a display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, Display objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself. //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| //| .. class:: Display(display_bus, *, width, height, colstart=0, rowstart=0, color_depth=16, //| set_column_command=0x2a set_row_command=0x2b, write_ram_command=0x2c) //| -//| Create a FourWire object associated with the given pins. +//| Create a Display object. //| STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command }; @@ -80,11 +81,15 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); - displayio_display_obj_t *self; - if (display_bus == &primary_display.fourwire_bus) { - self = &primary_display.display; - } else { - self = m_new_obj(displayio_display_obj_t); + displayio_display_obj_t *self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + self = &displays[i].display; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Display limit reached")); } self->base.type = &displayio_display_type; common_hal_displayio_display_construct(self, diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 674d1c9008838..9833fbc640330 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -69,18 +69,21 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ if (command == mp_const_none || chip_select == mp_const_none) { mp_raise_ValueError(translate("Command and chip_select required")); } + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(reset); - displayio_fourwire_obj_t* self; + displayio_fourwire_obj_t* self = NULL; mp_obj_t spi = args[ARG_spi_bus].u_obj; - if (board_spi() == spi && primary_display.bus_type == NULL) { - self = &primary_display.fourwire_bus; - primary_display.bus_type = &displayio_fourwire_type; - } else { - // TODO(tannewt): Always check pin free. For now we ignore the primary display. - assert_pin_free(command); - assert_pin_free(chip_select); - assert_pin_free(reset); - self = m_new_obj(displayio_fourwire_obj_t); + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type== NULL) { + self = &displays[i].fourwire_bus; + self->base.type = &displayio_fourwire_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Display bus limit reached")); } common_hal_displayio_fourwire_construct(self, diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index a9e1bf566a95d..3a9f66d4c57c4 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -39,6 +39,8 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, busio_spi_obj_t* spi, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset); +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self); + bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self); void common_hal_displayio_fourwire_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h index f1d1656b111aa..c739348389993 100644 --- a/shared-bindings/displayio/ParallelBus.h +++ b/shared-bindings/displayio/ParallelBus.h @@ -38,6 +38,8 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write); +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self); + bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self); void common_hal_displayio_parallelbus_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index d485d8095e0c8..66cf4d63d6e0d 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -32,6 +32,7 @@ #include "shared-bindings/displayio/__init__.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/OnDiskBitmap.h" @@ -61,6 +62,7 @@ //| //| Bitmap //| ColorConverter +//| Display //| FourWire //| Group //| OnDiskBitmap @@ -71,10 +73,22 @@ //| All libraries change hardware state but are never deinit //| + +//| .. method:: release_displays() +//| +//| Releases any actively used displays so theis pins can be used again. +//| +STATIC mp_obj_t displayio_release_displays(void) { + common_hal_displayio_release_displays(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(displayio_release_displays_obj, displayio_release_displays); + STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) }, { MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) }, { MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) }, + { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) }, { MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) }, { MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) }, { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, @@ -82,6 +96,8 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) }, { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, + + { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table); diff --git a/shared-bindings/displayio/__init__.h b/shared-bindings/displayio/__init__.h index a6663bf57215e..427ddb47ddb4b 100644 --- a/shared-bindings/displayio/__init__.h +++ b/shared-bindings/displayio/__init__.h @@ -27,8 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H -#include "py/obj.h" - -// Nothing now. +void common_hal_displayio_release_displays(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index b528c328964b3..48194f63f060e 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -1,68 +1,190 @@ +#include #include "shared-module/displayio/__init__.h" +#include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Display.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Sprite.h" -primary_display_t primary_display; +primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -void displayio_refresh_display(void) { - displayio_display_obj_t* display = &primary_display.display; +void displayio_refresh_displays(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + continue; + } + displayio_display_obj_t* display = &displays[i].display; - if (!displayio_display_frame_queued(display)) { - return; - } - if (displayio_display_refresh_queued(display)) { - PORT->Group[1].DIRSET.reg = 1 << 22; - - // We compute the pixels - uint16_t x0 = 0; - uint16_t y0 = 0; - uint16_t x1 = display->width; - uint16_t y1 = display->height; - size_t index = 0; - //size_t row_size = (x1 - x0); - uint16_t buffer_size = 256; - uint32_t buffer[buffer_size / 2]; - displayio_display_start_region_update(display, x0, y0, x1, y1); - for (uint16_t y = y0; y < y1; ++y) { - for (uint16_t x = x0; x < x1; ++x) { - uint16_t* pixel = &(((uint16_t*)buffer)[index]); - *pixel = 0; - - PORT->Group[1].OUTTGL.reg = 1 << 22; - - //if (index == 0) { - if (display->current_group != NULL) { - displayio_group_get_pixel(display->current_group, x, y, pixel); - } - // } else { - // *pixel = (((uint16_t*)buffer)[0]); - // } + if (!displayio_display_frame_queued(display)) { + return; + } + if (displayio_display_refresh_queued(display)) { + PORT->Group[1].DIRSET.reg = 1 << 22; + + // We compute the pixels + uint16_t x0 = 0; + uint16_t y0 = 0; + uint16_t x1 = display->width; + uint16_t y1 = display->height; + size_t index = 0; + //size_t row_size = (x1 - x0); + uint16_t buffer_size = 256; + uint32_t buffer[buffer_size / 2]; + displayio_display_start_region_update(display, x0, y0, x1, y1); + for (uint16_t y = y0; y < y1; ++y) { + for (uint16_t x = x0; x < x1; ++x) { + uint16_t* pixel = &(((uint16_t*)buffer)[index]); + *pixel = 0; + + PORT->Group[1].OUTTGL.reg = 1 << 22; + + //if (index == 0) { + if (display->current_group != NULL) { + displayio_group_get_pixel(display->current_group, x, y, pixel); + } + // } else { + // *pixel = (((uint16_t*)buffer)[0]); + // } - PORT->Group[1].OUTTGL.reg = 1 << 22; + PORT->Group[1].OUTTGL.reg = 1 << 22; - index += 1; - // The buffer is full, send it. - if (index >= buffer_size) { - if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) { - displayio_display_finish_region_update(display); - return; + index += 1; + // The buffer is full, send it. + if (index >= buffer_size) { + if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) { + displayio_display_finish_region_update(display); + return; + } + index = 0; } - index = 0; } } - } - // Send the remaining data. - if (index && !displayio_display_send_pixels(display, buffer, index * 2)) { + // Send the remaining data. + if (index && !displayio_display_send_pixels(display, buffer, index * 2)) { + displayio_display_finish_region_update(display); + return; + } displayio_display_finish_region_update(display); - return; } - displayio_display_finish_region_update(display); + displayio_display_finish_refresh(display); } - displayio_display_finish_refresh(display); } -void reset_primary_display(void) { - common_hal_displayio_display_show(&primary_display.display, NULL); +uint32_t blinka_bitmap_data[32] = { + 0x00000011, 0x11000000, + 0x00000111, 0x53100000, + 0x00000111, 0x56110000, + 0x00000111, 0x11140000, + 0x00000111, 0x20002000, + 0x00000011, 0x13000000, + 0x00000001, 0x11200000, + 0x00000000, 0x11330000, + 0x00000000, 0x01122000, + 0x00001111, 0x44133000, + 0x00032323, 0x24112200, + 0x00111114, 0x44113300, + 0x00323232, 0x34112200, + 0x11111144, 0x44443300, + 0x11111111, 0x11144401, + 0x23232323, 0x21111110 +}; + +displayio_bitmap_t blinka_bitmap = { + .base = {.type = &displayio_bitmap_type }, + .width = 16, + .height = 16, + .data = blinka_bitmap_data, + .stride = 2, + .bits_per_value = 4, + .x_shift = 3, + .x_mask = 0x7, + .bitmask = 0xf +}; + +uint32_t blinka_transparency[1] = {0x80000000}; +uint32_t blinka_colors[8] = {0x1e910000, 0x72dc722b, 0xffffb05a, 0x00000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000}; + +displayio_palette_t blinka_palette = { + .base = {.type = &displayio_palette_type }, + .opaque = blinka_transparency, + .colors = blinka_colors, + .color_count = 16, + .needs_refresh = false +}; + +displayio_sprite_t blinka_sprite = { + .base = {.type = &displayio_sprite_type }, + .bitmap = &blinka_bitmap, + .pixel_shader = &blinka_palette, + .x = 0, + .y = 0, + .width = 16, + .height = 16, + .needs_refresh = false +}; + +mp_obj_t splash_children[1] = { + &blinka_sprite, +}; + +displayio_group_t splash = { + .base = {.type = &displayio_group_type }, + .x = 0, + .y = 0, + .size = 1, + .max_size = 1, + .children = splash_children, + .needs_refresh = true +}; + +void reset_displays(void) { + // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type != &displayio_fourwire_type) { + continue; + } + displayio_fourwire_obj_t* fourwire = &displays[i].fourwire_bus; + if (((uint32_t) fourwire->bus) < ((uint32_t) &displays) || + ((uint32_t) fourwire->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) { + busio_spi_obj_t* original_spi = fourwire->bus; + memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); + fourwire->bus = &fourwire->inline_bus; + // Check for other displays that use the same spi bus and swap them too. + for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { + if (displays[i].fourwire_bus.bus == original_spi) { + displays[i].fourwire_bus.bus = &fourwire->inline_bus; + } + } + } + } + + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + continue; + } + displayio_display_obj_t* display = &displays[i].display; + common_hal_displayio_display_show(display, &splash); + } +} + +void common_hal_displayio_release_displays(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; + if (bus_type == NULL) { + continue; + } else if (bus_type == &displayio_fourwire_type) { + common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); + } else if (bus_type == &displayio_parallelbus_type) { + //common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); + } + displays[i].fourwire_bus.base.type = NULL; + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + displays[i].display.base.type = NULL; + } + // TODO(tannewt): Clear the display datastructures and release everything used. } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 84db98fcce30f..fdabd4ec4e685 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -36,13 +36,12 @@ typedef struct { displayio_fourwire_obj_t fourwire_bus; displayio_parallelbus_obj_t parallel_bus; }; - mp_const_obj_t bus_type; displayio_display_obj_t display; } primary_display_t; -extern primary_display_t primary_display; +extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -void displayio_refresh_display(void); -void reset_primary_display(void); +void displayio_refresh_displays(void); +void reset_displays(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H From 5277138c992b860cfbdb767f18e034c42e31b6a1 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 10:57:05 -0800 Subject: [PATCH 118/153] pyportal compiles and tweak blinka colors --- ports/atmel-samd/boards/pyportal/board.c | 57 ++++++++++++++++++++++-- ports/atmel-samd/mpconfigport.h | 1 + shared-module/displayio/Group.c | 3 ++ shared-module/displayio/Group.h | 1 + shared-module/displayio/__init__.c | 7 ++- 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index 8ec498e8cdbe8..cf03bb28a2ffe 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * 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 @@ -25,15 +25,67 @@ */ #include "boards/board.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" #include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" #include "tick.h" +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0xEF, 3, 0x03, 0x80, 0x02, + 0xCF, 3, 0x00, 0xC1, 0x30, + 0xED, 4, 0x64, 0x03, 0x12, 0x81, + 0xE8, 3, 0x85, 0x00, 0x78, + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, + 0xF7, 1, 0x20, + 0xEA, 2, 0x00, 0x00, + 0xc0, 1, 0x23, // Power control VRH[5:0] + 0xc1, 1, 0x10, // Power control SAP[2:0];BT[3:0] + 0xc5, 2, 0x3e, 0x28, // VCM control + 0xc7, 1, 0x86, // VCM control2 + 0x36, 1, 0x38, // Memory Access Control + 0x37, 1, 0x00, // Vertical scroll zero + 0x3a, 1, 0x55, // COLMOD: Pixel Format Set + 0xb1, 2, 0x00, 0x18, // Frame Rate Control (In Normal Mode/Full Colors) + 0xb6, 3, 0x08, 0x82, 0x27, // Display Function Control + 0xF2, 1, 0x00, // 3Gamma Function Disable + 0x26, 1, 0x01, // Gamma curve selected + 0xe0, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma + 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, + 0xe1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma + 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, + 0x11, DELAY, 120, // Exit Sleep + 0x29, DELAY, 120, // Display on +}; + void board_init(void) { + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + board_spi(), + &pin_PB09, // Command or data + &pin_PB06, // Chip select + &pin_PA00); // Reset + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 320, // Width + 240, // Height + 0, // column start + 0, // row start + 16, // Color depth + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence)); } bool board_requests_safe_mode(void) { @@ -41,5 +93,4 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { - common_hal_displayio_display_show(&primary_display_obj, NULL); } diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 65b8c94c5bb1a..77881fefd3bad 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -192,6 +192,7 @@ typedef long mp_off_t; #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_SYS_EXC_INFO (1) // MICROPY_PY_UERRNO_LIST - Use the default +#define CIRCUITPY_DISPLAY_LIMIT (3) #endif #ifdef LONGINT_IMPL_NONE diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index b9923128a0a59..255349d7cde83 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -67,11 +67,14 @@ void displayio_group_construct(displayio_group_t* self, mp_obj_t* child_array, u self->children = child_array; self->max_size = max_size; self->needs_refresh = false; + self->scale = 1; } bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, uint16_t* pixel) { x -= self->x; y -= self->y; + x /= self->scale; + y /= self->scale; for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i]; if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { diff --git a/shared-module/displayio/Group.h b/shared-module/displayio/Group.h index 272f3114ce64d..60f573ff6f360 100644 --- a/shared-module/displayio/Group.h +++ b/shared-module/displayio/Group.h @@ -36,6 +36,7 @@ typedef struct { mp_obj_base_t base; int16_t x; int16_t y; + uint16_t scale; uint16_t size; uint16_t max_size; mp_obj_t* children; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 48194f63f060e..dc5957c23227a 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -105,8 +105,10 @@ displayio_bitmap_t blinka_bitmap = { }; uint32_t blinka_transparency[1] = {0x80000000}; -uint32_t blinka_colors[8] = {0x1e910000, 0x72dc722b, 0xffffb05a, 0x00000000, - 0x80000000, 0x00000000, 0x00000000, 0x00000000}; + +// TODO(tannewt): Fix these colors +uint32_t blinka_colors[8] = {0x91780000, 0x879FFC98, 0xffff0000, 0x0000f501, + 0x00000000, 0x00000000, 0x00000000, 0x00000000}; displayio_palette_t blinka_palette = { .base = {.type = &displayio_palette_type }, @@ -135,6 +137,7 @@ displayio_group_t splash = { .base = {.type = &displayio_group_type }, .x = 0, .y = 0, + .scale = 2, .size = 1, .max_size = 1, .children = splash_children, From 2d136d58bf288f0be945ed5cd3efe9113d0acce3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 14:45:29 -0800 Subject: [PATCH 119/153] Fix other builds and hallowing --- .../atmel-samd/boards/arduino_mkr1300/pins.c | 2 +- .../atmel-samd/boards/arduino_mkrzero/pins.c | 4 +- ports/atmel-samd/boards/arduino_zero/pins.c | 2 +- .../atmel-samd/boards/catwan_usbstick/pins.c | 2 +- .../boards/circuitplayground_express/pins.c | 2 +- .../circuitplayground_express_crickit/pins.c | 2 +- ports/atmel-samd/boards/cp32-m4/pins.c | 2 +- ports/atmel-samd/boards/datalore_ip_m4/pins.c | 2 +- .../boards/feather_m0_adalogger/pins.c | 2 +- .../atmel-samd/boards/feather_m0_basic/pins.c | 2 +- .../boards/feather_m0_express/pins.c | 2 +- .../boards/feather_m0_express_crickit/pins.c | 2 +- .../atmel-samd/boards/feather_m0_rfm69/pins.c | 2 +- .../atmel-samd/boards/feather_m0_rfm9x/pins.c | 2 +- .../boards/feather_m0_supersized/pins.c | 2 +- .../boards/feather_radiofruit_zigbee/pins.c | 2 +- ports/atmel-samd/boards/gemma_m0/pins.c | 2 +- .../boards/hallowing_m0_express/board.c | 47 ++++++----------- .../boards/hallowing_m0_express/pins.c | 5 +- .../boards/itsybitsy_m0_express/pins.c | 2 +- .../boards/itsybitsy_m4_express/pins.c | 2 +- ports/atmel-samd/boards/meowmeow/pins.c | 2 +- .../atmel-samd/boards/metro_m0_express/pins.c | 2 +- .../atmel-samd/boards/metro_m4_express/pins.c | 2 +- ports/atmel-samd/boards/mini_sam_m4/pins.c | 2 +- ports/atmel-samd/boards/pirkey_m0/pins.c | 2 +- ports/atmel-samd/boards/pyportal/board.c | 12 +++-- ports/atmel-samd/boards/pyportal/pins.c | 3 ++ .../boards/sparkfun_samd21_mini/pins.c | 16 +++--- .../boards/trellis_m4_express/pins.c | 2 +- ports/atmel-samd/boards/trinket_m0/pins.c | 2 +- .../boards/trinket_m0_haxpress/pins.c | 2 +- ports/atmel-samd/boards/ugame10/pins.c | 2 +- .../common-hal/displayio/ParallelBus.c | 38 +++++++++++--- .../common-hal/displayio/ParallelBus.h | 4 ++ ports/atmel-samd/mpconfigport.h | 1 + shared-bindings/displayio/ParallelBus.c | 50 +++++++++++++++++-- shared-bindings/displayio/ParallelBus.h | 4 +- shared-bindings/displayio/__init__.c | 3 ++ shared-module/displayio/Display.c | 4 +- shared-module/displayio/__init__.c | 17 +++---- 41 files changed, 160 insertions(+), 102 deletions(-) diff --git a/ports/atmel-samd/boards/arduino_mkr1300/pins.c b/ports/atmel-samd/boards/arduino_mkr1300/pins.c index de9f9769c8ed7..a5a058acec8e4 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/pins.c +++ b/ports/atmel-samd/boards/arduino_mkr1300/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/arduino_mkrzero/pins.c b/ports/atmel-samd/boards/arduino_mkrzero/pins.c index 3ffd37fa6e415..654c0d6dae187 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/pins.c +++ b/ports/atmel-samd/boards/arduino_mkrzero/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, @@ -31,7 +31,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB23) }, { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB22) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) }, { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA13) }, { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA12) }, { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA15) }, diff --git a/ports/atmel-samd/boards/arduino_zero/pins.c b/ports/atmel-samd/boards/arduino_zero/pins.c index 8a7ff70e6dbd7..f9403bb9ad126 100644 --- a/ports/atmel-samd/boards/arduino_zero/pins.c +++ b/ports/atmel-samd/boards/arduino_zero/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/catwan_usbstick/pins.c b/ports/atmel-samd/boards/catwan_usbstick/pins.c index 8997b653ffc63..87ee84c0be860 100644 --- a/ports/atmel-samd/boards/catwan_usbstick/pins.c +++ b/ports/atmel-samd/boards/catwan_usbstick/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA30) }, diff --git a/ports/atmel-samd/boards/circuitplayground_express/pins.c b/ports/atmel-samd/boards/circuitplayground_express/pins.c index 14ae89c55e838..70743366ed723 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/pins.c +++ b/ports/atmel-samd/boards/circuitplayground_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c b/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c index 14ae89c55e838..70743366ed723 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/cp32-m4/pins.c b/ports/atmel-samd/boards/cp32-m4/pins.c index 93c169c8b591e..9da67dfb448d1 100644 --- a/ports/atmel-samd/boards/cp32-m4/pins.c +++ b/ports/atmel-samd/boards/cp32-m4/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/datalore_ip_m4/pins.c b/ports/atmel-samd/boards/datalore_ip_m4/pins.c index 460fd6fefa5e5..468a09a47613d 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/pins.c +++ b/ports/atmel-samd/boards/datalore_ip_m4/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c index 0029bba1a3205..d99e62c9554e3 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c +++ b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_basic/pins.c b/ports/atmel-samd/boards/feather_m0_basic/pins.c index 4400a253dae7b..f9b6db63be152 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/pins.c +++ b/ports/atmel-samd/boards/feather_m0_basic/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_express/pins.c b/ports/atmel-samd/boards/feather_m0_express/pins.c index cd6c351d496a7..1eaa98a586e61 100644 --- a/ports/atmel-samd/boards/feather_m0_express/pins.c +++ b/ports/atmel-samd/boards/feather_m0_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c index cd6c351d496a7..1eaa98a586e61 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c index 7e14b3f2514cd..ba59cb69b6b45 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c +++ b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c index 4e77b7fb97015..29a01d4056c4d 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_supersized/pins.c b/ports/atmel-samd/boards/feather_m0_supersized/pins.c index cd6c351d496a7..1eaa98a586e61 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/pins.c +++ b/ports/atmel-samd/boards/feather_m0_supersized/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c b/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c index cd111e17454af..211596f786664 100755 --- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB02) }, diff --git a/ports/atmel-samd/boards/gemma_m0/pins.c b/ports/atmel-samd/boards/gemma_m0/pins.c index c9c7ea555b8bf..b24b4583887d4 100644 --- a/ports/atmel-samd/boards/gemma_m0/pins.c +++ b/ports/atmel-samd/boards/gemma_m0/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, // pad 1 diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index b47c5fbb22fcc..2b12ae464f3dd 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -27,6 +27,7 @@ #include "boards/board.h" #include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/mipi_constants.h" #include "tick.h" @@ -68,13 +69,18 @@ uint8_t display_init_sequence[] = { }; void board_init(void) { - board_display_obj.base.type = &displayio_fourwire_type; - common_hal_displayio_fourwire_construct(&board_display_obj, - &pin_PB23, // Clock - &pin_PB22, // Data + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + board_spi(), &pin_PA28, // Command or data &pin_PA01, // Chip select - &pin_PA27, // Reset + &pin_PA27); // Reset + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, 128, // Width 128, // Height 2, // column start @@ -82,33 +88,9 @@ void board_init(void) { 16, // Color depth MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command - MIPI_COMMAND_WRITE_MEMORY_START); // Write memory command - - uint32_t i = 0; - common_hal_displayio_fourwire_begin_transaction(&board_display_obj); - while (i < sizeof(display_init_sequence)) { - uint8_t *cmd = display_init_sequence + i; - uint8_t data_size = *(cmd + 1); - bool delay = (data_size & DELAY) != 0; - data_size &= ~DELAY; - uint8_t *data = cmd + 2; - common_hal_displayio_fourwire_send(&board_display_obj, true, cmd, 1); - common_hal_displayio_fourwire_send(&board_display_obj, false, data, data_size); - if (delay) { - data_size++; - uint16_t delay_length_ms = *(cmd + 1 + data_size); - if (delay_length_ms == 255) { - delay_length_ms = 500; - } - uint64_t start = ticks_ms; - while (ticks_ms - start < delay_length_ms) {} - } else { - uint64_t start = ticks_ms; - while (ticks_ms - start < 10) {} - } - i += 2 + data_size; - } - common_hal_displayio_fourwire_end_transaction(&board_display_obj); + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence)); } bool board_requests_safe_mode(void) { @@ -116,5 +98,4 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { - common_hal_displayio_fourwire_show(&board_display_obj, NULL); } diff --git a/ports/atmel-samd/boards/hallowing_m0_express/pins.c b/ports/atmel-samd/boards/hallowing_m0_express/pins.c index d1f8609ffa92a..3db1b17524f55 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/pins.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/pins.c @@ -1,7 +1,8 @@ #include "shared-bindings/board/__init__.h" #include "boards/board.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" +#include "shared-module/displayio/__init__.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, @@ -62,6 +63,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { 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_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&board_display_obj)} + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c index 25407bc147c77..912fba4edc2cf 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c index 2a89c3037ed60..ed91c88ee74ff 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/meowmeow/pins.c b/ports/atmel-samd/boards/meowmeow/pins.c index 59c51f4ebf956..089baad32e20c 100644 --- a/ports/atmel-samd/boards/meowmeow/pins.c +++ b/ports/atmel-samd/boards/meowmeow/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/metro_m0_express/pins.c b/ports/atmel-samd/boards/metro_m0_express/pins.c index 13f0eb0ba2797..0707a3581985c 100644 --- a/ports/atmel-samd/boards/metro_m0_express/pins.c +++ b/ports/atmel-samd/boards/metro_m0_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/metro_m4_express/pins.c b/ports/atmel-samd/boards/metro_m4_express/pins.c index 0e66817f7cfcc..dd419aec67001 100644 --- a/ports/atmel-samd/boards/metro_m4_express/pins.c +++ b/ports/atmel-samd/boards/metro_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/mini_sam_m4/pins.c b/ports/atmel-samd/boards/mini_sam_m4/pins.c index 87e2103814457..f78fe1bc83bf3 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/pins.c +++ b/ports/atmel-samd/boards/mini_sam_m4/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/pirkey_m0/pins.c b/ports/atmel-samd/boards/pirkey_m0/pins.c index e08302f140ba3..a6dbcefe3e742 100644 --- a/ports/atmel-samd/boards/pirkey_m0/pins.c +++ b/ports/atmel-samd/boards/pirkey_m0/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_REMOTEIN), MP_ROM_PTR(&pin_PA28) }, diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index cf03bb28a2ffe..6e5b37dd2cb7e 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -64,12 +64,14 @@ uint8_t display_init_sequence[] = { }; void board_init(void) { - displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; - bus->base.type = &displayio_fourwire_type; - common_hal_displayio_fourwire_construct(bus, - board_spi(), - &pin_PB09, // Command or data + displayio_parallelbus_obj_t* bus = &displays[0].parallel_bus; + bus->base.type = &displayio_parallelbus_type; + common_hal_displayio_parallelbus_construct(bus, + &pin_PA16, // Data0 + &pin_PB05, // Command or data &pin_PB06, // Chip select + &pin_PB09, // Write + &pin_PB04, // Read &pin_PA00); // Reset displayio_display_obj_t* display = &displays[0].display; diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index 4ddc10e52a3e7..6b1254dfcd991 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -1,6 +1,7 @@ #include "shared-bindings/board/__init__.h" #include "boards/board.h" +#include "shared-module/displayio/__init__.h" #include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken @@ -72,5 +73,7 @@ STATIC const mp_map_elem_t board_global_dict_table[] = { { 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_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c index abe63d0644d80..42cd3736b8578 100644 --- a/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c @@ -1,15 +1,15 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { - + // Analog pins { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, - + // Digital pins { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, @@ -25,16 +25,16 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, - + // UART pins - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, - + // SPI pins { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, - + // I2C pins { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, @@ -44,7 +44,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_PA17) }, { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA27) }, { MP_ROM_QSTR(MP_QSTR_YELLOW_LED), MP_ROM_PTR(&pin_PB03) }, - + // Comm objects { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/atmel-samd/boards/trellis_m4_express/pins.c b/ports/atmel-samd/boards/trellis_m4_express/pins.c index 9626f525f3330..a9f20431854bb 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/pins.c +++ b/ports/atmel-samd/boards/trellis_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/trinket_m0/pins.c b/ports/atmel-samd/boards/trinket_m0/pins.c index 6330170249073..b3637bd5bbe2a 100644 --- a/ports/atmel-samd/boards/trinket_m0/pins.c +++ b/ports/atmel-samd/boards/trinket_m0/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) }, diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c index 6330170249073..b3637bd5bbe2a 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) }, diff --git a/ports/atmel-samd/boards/ugame10/pins.c b/ports/atmel-samd/boards/ugame10/pins.c index 87ace5e96f5bb..71db52752f31d 100644 --- a/ports/atmel-samd/boards/ugame10/pins.c +++ b/ports/atmel-samd/boards/ugame10/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_X), MP_ROM_PTR(&pin_PA00) }, diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.c b/ports/atmel-samd/common-hal/displayio/ParallelBus.c index f852647a4b675..3c287eccd622f 100644 --- a/ports/atmel-samd/common-hal/displayio/ParallelBus.c +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.c @@ -35,8 +35,8 @@ #include "tick.h" void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, - const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write) { + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { uint8_t data_pin = data0->number; if (data_pin % 8 != 0 || data_pin % 32 >= 24) { @@ -47,8 +47,8 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i); } } - PortGroup *const g = &PORT->Group[data0->number % 32]; - g->DIRSET.reg = 0xff << data_pin; + PortGroup *const g = &PORT->Group[data0->number / 32]; + g->DIRSET.reg = 0xff << (data_pin % 32); self->bus = ((uint8_t*) &g->OUT.reg) + (data0->number % 32 / 8); self->command.base.type = &digitalio_digitalinout_type; @@ -67,15 +67,36 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel common_hal_digitalio_digitalinout_construct(&self->write, write); common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); + self->read.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->read, read); + common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL); + + self->data0_pin = data_pin; + self->write_group = &PORT->Group[write->number / 32]; + self->write_mask = 1 << (write->number % 32); + never_reset_pin_number(command->number); never_reset_pin_number(chip_select->number); - never_reset_pin_number(reset->number); never_reset_pin_number(write->number); + never_reset_pin_number(read->number); + never_reset_pin_number(reset->number); for (uint8_t i = 0; i < 8; i++) { never_reset_pin_number(data_pin + i); } } +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) { + for (uint8_t i = 0; i < 8; i++) { + reset_pin_number(self->data0_pin + i); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->write.pin->number); + reset_pin_number(self->read.pin->number); + reset_pin_number(self->reset.pin->number); +} + bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); @@ -85,10 +106,13 @@ bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { void common_hal_displayio_parallelbus_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); common_hal_digitalio_digitalinout_set_value(&self->command, !command); + uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR.reg; + uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET.reg; + uint32_t mask = self->write_mask; for (uint32_t i = 0; i < data_length; i++) { - common_hal_digitalio_digitalinout_set_value(&self->write, false); + *clear_write = mask; *self->bus = data[i]; - common_hal_digitalio_digitalinout_set_value(&self->write, true); + *set_write = mask; } } diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.h b/ports/atmel-samd/common-hal/displayio/ParallelBus.h index cc45598c5b01a..630bec351b686 100644 --- a/ports/atmel-samd/common-hal/displayio/ParallelBus.h +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.h @@ -36,6 +36,10 @@ typedef struct { digitalio_digitalinout_obj_t chip_select; digitalio_digitalinout_obj_t reset; digitalio_digitalinout_obj_t write; + digitalio_digitalinout_obj_t read; + uint8_t data0_pin; + PortGroup* write_group; + uint32_t write_mask; } displayio_parallelbus_obj_t; #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_PARALLELBUS_H diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 77881fefd3bad..a2e4075c4582a 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -282,6 +282,7 @@ extern const struct _mp_obj_module_t wiznet_module; #endif #ifdef CIRCUITPY_DISPLAYIO + #define CIRCUITPY_DISPLAY_LIMIT (3) #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, #else #define DISPLAYIO_MODULE diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index dddb4ce8ac2f8..aa861bb81a707 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -34,6 +34,7 @@ #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" #include "supervisor/shared/translate.h" //| .. currentmodule:: displayio @@ -46,13 +47,54 @@ //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| -//| .. class:: ParallelBus(*, data0, command, chip_select, reset, write, bus_width=8) +//| .. class:: ParallelBus(*, data0, command, chip_select, write, read, reset) //| -//| Create a ParallelBus object associated with the given pins. +//| Create a ParallelBus object associated with the given pins. The bus is inferred from data0 +//| by implying the next 7 additional pins on a given GPIO port. //| STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_raise_NotImplementedError(translate("displayio is a work in progress")); - return mp_const_none; + enum { ARG_data0, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_write, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_read, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + }; + 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); + + mp_obj_t data0 = args[ARG_data0].u_obj; + mp_obj_t command = args[ARG_command].u_obj; + mp_obj_t chip_select = args[ARG_chip_select].u_obj; + mp_obj_t write = args[ARG_write].u_obj; + mp_obj_t read = args[ARG_read].u_obj; + mp_obj_t reset = args[ARG_reset].u_obj; + if (data0 == mp_const_none || command == mp_const_none || chip_select == mp_const_none || write == mp_const_none || read == mp_const_none) { + mp_raise_ValueError(translate("Data0, command, chip_select, write and read required")); + } + assert_pin_free(data0); + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(write); + assert_pin_free(read); + assert_pin_free(reset); + + displayio_parallelbus_obj_t* self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].parallel_bus.base.type== NULL) { + self = &displays[i].parallel_bus; + self->base.type = &displayio_parallelbus_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Display bus limit reached")); + } + + common_hal_displayio_parallelbus_construct(self, data0, command, chip_select, write, read, reset); + return self; } diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h index c739348389993..c4cde5ff532c7 100644 --- a/shared-bindings/displayio/ParallelBus.h +++ b/shared-bindings/displayio/ParallelBus.h @@ -35,8 +35,8 @@ extern const mp_obj_type_t displayio_parallelbus_type; void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, - const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write); + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset); void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self); diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 66cf4d63d6e0d..306f8c08bf7f7 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -37,6 +37,7 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/OnDiskBitmap.h" #include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/ParallelBus.h" #include "shared-bindings/displayio/Shape.h" #include "shared-bindings/displayio/Sprite.h" @@ -67,6 +68,7 @@ //| Group //| OnDiskBitmap //| Palette +//| ParallelBus //| Shape //| Sprite //| @@ -96,6 +98,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) }, { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, + { MP_ROM_QSTR(MP_QSTR_ParallelBus), MP_ROM_PTR(&displayio_parallelbus_type) }, { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, }; diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 0a14e74bb3c4a..f75f0392f7c9f 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -113,10 +113,10 @@ void displayio_display_start_region_update(displayio_display_obj_t* self, uint16 uint16_t data[2]; self->send(self->bus, true, &self->set_column_command, 1); data[0] = __builtin_bswap16(x0 + self->colstart); - data[1] = __builtin_bswap16(x1 + self->colstart); + data[1] = __builtin_bswap16(x1 - 1 + self->colstart); self->send(self->bus, false, (uint8_t*) data, 4); self->send(self->bus, true, &self->set_row_command, 1); - data[0] = __builtin_bswap16(y0 + self->rowstart); + data[0] = __builtin_bswap16(y0 + 1 + self->rowstart); data[1] = __builtin_bswap16(y1 + self->rowstart); self->send(self->bus, false, (uint8_t*) data, 4); self->send(self->bus, true, &self->write_ram_command, 1); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index dc5957c23227a..92d97a6efe650 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -7,6 +7,7 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/Sprite.h" +#include "supervisor/usb.h" primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; @@ -21,8 +22,6 @@ void displayio_refresh_displays(void) { return; } if (displayio_display_refresh_queued(display)) { - PORT->Group[1].DIRSET.reg = 1 << 22; - // We compute the pixels uint16_t x0 = 0; uint16_t y0 = 0; @@ -38,8 +37,6 @@ void displayio_refresh_displays(void) { uint16_t* pixel = &(((uint16_t*)buffer)[index]); *pixel = 0; - PORT->Group[1].OUTTGL.reg = 1 << 22; - //if (index == 0) { if (display->current_group != NULL) { displayio_group_get_pixel(display->current_group, x, y, pixel); @@ -48,9 +45,6 @@ void displayio_refresh_displays(void) { // *pixel = (((uint16_t*)buffer)[0]); // } - - PORT->Group[1].OUTTGL.reg = 1 << 22; - index += 1; // The buffer is full, send it. if (index >= buffer_size) { @@ -58,6 +52,9 @@ void displayio_refresh_displays(void) { displayio_display_finish_region_update(display); return; } + // TODO(tannewt): Make refresh displays faster so we don't starve other + // background tasks. + usb_background(); index = 0; } } @@ -182,12 +179,12 @@ void common_hal_displayio_release_displays(void) { } else if (bus_type == &displayio_fourwire_type) { common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); } else if (bus_type == &displayio_parallelbus_type) { - //common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); + common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); } - displays[i].fourwire_bus.base.type = NULL; + displays[i].fourwire_bus.base.type = &mp_type_NoneType; } for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - displays[i].display.base.type = NULL; + displays[i].display.base.type = &mp_type_NoneType; } // TODO(tannewt): Clear the display datastructures and release everything used. } From 760bd8d8a4f0aa0ed8651e89596fb2e6effbc14f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 15:15:59 -0800 Subject: [PATCH 120/153] share fourwire and make nrf compile --- ports/atmel-samd/Makefile | 2 +- ports/nrf/Makefile | 12 +- ports/nrf/board_busses.c | 114 --------------- .../boards/feather_nrf52840_express/pins.c | 4 +- .../nrf/boards/makerdiary_nrf52840_mdk/pins.c | 2 +- .../makerdiary_nrf52840_mdk_usb_dongle/pins.c | 2 +- ports/nrf/boards/particle_argon/pins.c | 2 +- ports/nrf/boards/particle_boron/pins.c | 2 +- ports/nrf/boards/particle_xenon/pins.c | 2 +- ports/nrf/boards/pca10056/pins.c | 2 +- ports/nrf/boards/pca10059/pins.c | 2 +- .../nrf/boards/sparkfun_nrf52840_mini/pins.c | 2 +- ports/nrf/common-hal/displayio/ParallelBus.c | 137 ++++++++++++++++++ .../displayio/ParallelBus.h} | 28 ++-- ports/nrf/common-hal/microcontroller/Pin.h | 1 + ports/nrf/mpconfigport.h | 2 + shared-bindings/displayio/FourWire.h | 2 +- .../displayio/FourWire.c | 0 .../displayio/FourWire.h | 0 supervisor/shared/board_busses.c | 1 - 20 files changed, 180 insertions(+), 139 deletions(-) delete mode 100644 ports/nrf/board_busses.c create mode 100644 ports/nrf/common-hal/displayio/ParallelBus.c rename ports/nrf/{board_busses.h => common-hal/displayio/ParallelBus.h} (63%) rename {ports/atmel-samd/common-hal => shared-module}/displayio/FourWire.c (100%) rename {ports/atmel-samd/common-hal => shared-module}/displayio/FourWire.h (100%) diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 088288fbdcea5..c8d197b3ef798 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -305,7 +305,6 @@ SRC_COMMON_HAL = \ busio/UART.c \ digitalio/__init__.c \ digitalio/DigitalInOut.c \ - displayio/FourWire.c \ displayio/ParallelBus.c \ i2cslave/__init__.c \ i2cslave/I2CSlave.c \ @@ -380,6 +379,7 @@ SRC_SHARED_MODULE = \ displayio/Bitmap.c \ displayio/ColorConverter.c \ displayio/Display.c \ + displayio/FourWire.c \ displayio/Group.c \ displayio/OnDiskBitmap.c \ displayio/Palette.c \ diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 2bc5084754617..85e6346a111df 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -118,7 +118,6 @@ SRC_C += \ fatfs_port.c \ mphalport.c \ tick.c \ - board_busses.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ @@ -156,6 +155,7 @@ SRC_COMMON_HAL += \ busio/__init__.c\ digitalio/DigitalInOut.c \ digitalio/__init__.c \ + displayio/ParallelBus.c \ microcontroller/Pin.c \ microcontroller/Processor.c \ microcontroller/__init__.c \ @@ -214,6 +214,16 @@ SRC_SHARED_MODULE = \ bitbangio/OneWire.c \ bitbangio/SPI.c \ busio/OneWire.c \ + displayio/__init__.c \ + displayio/Bitmap.c \ + displayio/ColorConverter.c \ + displayio/Display.c \ + displayio/FourWire.c \ + displayio/Group.c \ + displayio/OnDiskBitmap.c \ + displayio/Palette.c \ + displayio/Shape.c \ + displayio/Sprite.c \ storage/__init__.c # uheap/__init__.c \ diff --git a/ports/nrf/board_busses.c b/ports/nrf/board_busses.c deleted file mode 100644 index 6d5cbd041ef73..0000000000000 --- a/ports/nrf/board_busses.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 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 "shared-bindings/busio/I2C.h" -#include "shared-bindings/busio/SPI.h" -#include "shared-bindings/busio/UART.h" - -#include "shared-bindings/microcontroller/Pin.h" -#include "supervisor/shared/translate.h" -#include "nrf/pins.h" -#include "py/mpconfig.h" -#include "py/runtime.h" - -#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL) - STATIC mp_obj_t board_i2c(void) { - mp_raise_NotImplementedError(translate("No default I2C bus")); - return NULL; - } -#else - STATIC mp_obj_t i2c_singleton = NULL; - - STATIC mp_obj_t board_i2c(void) { - - if (i2c_singleton == NULL) { - busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); - self->base.type = &busio_i2c_type; - - assert_pin_free(DEFAULT_I2C_BUS_SDA); - assert_pin_free(DEFAULT_I2C_BUS_SCL); - common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0); - i2c_singleton = (mp_obj_t)self; - } - return i2c_singleton; - - } -#endif -MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); - -#if !defined(DEFAULT_SPI_BUS_SCK) || !defined(DEFAULT_SPI_BUS_MISO) || !defined(DEFAULT_SPI_BUS_MOSI) - STATIC mp_obj_t board_spi(void) { - mp_raise_NotImplementedError(translate("No default SPI bus")); - return NULL; - } -#else - STATIC mp_obj_t spi_singleton = NULL; - - STATIC mp_obj_t board_spi(void) { - - if (spi_singleton == NULL) { - busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); - self->base.type = &busio_spi_type; - assert_pin_free(DEFAULT_SPI_BUS_SCK); - assert_pin_free(DEFAULT_SPI_BUS_MOSI); - assert_pin_free(DEFAULT_SPI_BUS_MISO); - const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK); - const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); - const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); - common_hal_busio_spi_construct(self, clock, mosi, miso); - spi_singleton = (mp_obj_t)self; - } - return spi_singleton; - } -#endif -MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); - -#if !defined(DEFAULT_UART_BUS_RX) || !defined(DEFAULT_UART_BUS_TX) - STATIC mp_obj_t board_uart(void) { - mp_raise_NotImplementedError(translate("No default UART bus")); - return NULL; - } -#else - STATIC mp_obj_t uart_singleton = NULL; - - STATIC mp_obj_t board_uart(void) { - if (uart_singleton == NULL) { - busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t); - self->base.type = &busio_uart_type; - - assert_pin_free(DEFAULT_UART_BUS_RX); - assert_pin_free(DEFAULT_UART_BUS_TX); - - const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX); - const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX); - - common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64); - uart_singleton = (mp_obj_t)self; - } - return uart_singleton; - } -#endif -MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart); diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c index 2f8ac02599fff..dfb0be6df7575 100644 --- a/ports/nrf/boards/feather_nrf52840_express/pins.c +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, @@ -44,7 +44,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, - + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, }; diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c index 27f0c67974ddf..2d24e85979f83 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c index 6049ac0538af5..10490c8cb1275 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, diff --git a/ports/nrf/boards/particle_argon/pins.c b/ports/nrf/boards/particle_argon/pins.c index 0457f0aa86454..8c2fb38e63335 100644 --- a/ports/nrf/boards/particle_argon/pins.c +++ b/ports/nrf/boards/particle_argon/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, diff --git a/ports/nrf/boards/particle_boron/pins.c b/ports/nrf/boards/particle_boron/pins.c index 2bff0a2ce4f15..5981212bf634f 100644 --- a/ports/nrf/boards/particle_boron/pins.c +++ b/ports/nrf/boards/particle_boron/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, diff --git a/ports/nrf/boards/particle_xenon/pins.c b/ports/nrf/boards/particle_xenon/pins.c index 11a29e9273c5e..cdd5b5306c562 100644 --- a/ports/nrf/boards/particle_xenon/pins.c +++ b/ports/nrf/boards/particle_xenon/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, diff --git a/ports/nrf/boards/pca10056/pins.c b/ports/nrf/boards/pca10056/pins.c index a57c9d1c9578d..510b6100e3ec0 100644 --- a/ports/nrf/boards/pca10056/pins.c +++ b/ports/nrf/boards/pca10056/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, diff --git a/ports/nrf/boards/pca10059/pins.c b/ports/nrf/boards/pca10059/pins.c index a1916bd046917..c43d3a9eb60cc 100644 --- a/ports/nrf/boards/pca10059/pins.c +++ b/ports/nrf/boards/pca10059/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c index 5c50f55c7c656..f826ac771deeb 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P1_15) }, // D1/TX diff --git a/ports/nrf/common-hal/displayio/ParallelBus.c b/ports/nrf/common-hal/displayio/ParallelBus.c new file mode 100644 index 0000000000000..3afedf73633bc --- /dev/null +++ b/ports/nrf/common-hal/displayio/ParallelBus.c @@ -0,0 +1,137 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 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 "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "common-hal/microcontroller/Pin.h" +#include "py/runtime.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "tick.h" + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { + + uint8_t data_pin = data0->number; + if (data_pin % 8 != 0 || data_pin % 32 >= 24) { + mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); + } + for (uint8_t i = 0; i < 8; i++) { + if (!pin_number_is_free(data_pin + i)) { + mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i); + } + } + NRF_GPIO_Type *g; + uint8_t num_pins_in_port; + if (data0->number < P0_PIN_NUM) { + g = NRF_P0; + num_pins_in_port = P0_PIN_NUM; + } else { + g = NRF_P1; + num_pins_in_port = P1_PIN_NUM; + } + g->DIRSET = 0xff << (data_pin % num_pins_in_port); + self->bus = ((uint8_t*) &g->OUT) + (data0->number % num_pins_in_port / 8); + + self->command.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->command, command); + common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + + self->chip_select.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + + self->reset.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + + self->write.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->write, write); + common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); + + self->read.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->read, read); + common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL); + + self->data0_pin = data_pin; + uint8_t num_pins_in_write_port; + if (data0->number < P0_PIN_NUM) { + self->write_group = NRF_P0; + num_pins_in_write_port = P0_PIN_NUM; + } else { + self->write_group = NRF_P1; + num_pins_in_write_port = P1_PIN_NUM; + } + self->write_mask = 1 << (write->number % num_pins_in_write_port); + + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); + never_reset_pin_number(write->number); + never_reset_pin_number(read->number); + never_reset_pin_number(reset->number); + for (uint8_t i = 0; i < 8; i++) { + never_reset_pin_number(data_pin + i); + } +} + +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) { + for (uint8_t i = 0; i < 8; i++) { + reset_pin_number(self->data0_pin + i); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->write.pin->number); + reset_pin_number(self->read.pin->number); + reset_pin_number(self->reset.pin->number); +} + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + return true; +} + +void common_hal_displayio_parallelbus_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->command, !command); + uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR; + uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET; + uint32_t mask = self->write_mask; + for (uint32_t i = 0; i < data_length; i++) { + *clear_write = mask; + *self->bus = data[i]; + *set_write = mask; + } +} + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); +} diff --git a/ports/nrf/board_busses.h b/ports/nrf/common-hal/displayio/ParallelBus.h similarity index 63% rename from ports/nrf/board_busses.h rename to ports/nrf/common-hal/displayio/ParallelBus.h index 2a4bfc3d4b64c..5c10d3d42a961 100644 --- a/ports/nrf/board_busses.h +++ b/ports/nrf/common-hal/displayio/ParallelBus.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * 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 @@ -24,16 +24,22 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_NRF_BOARD_BUSSES_H -#define MICROPY_INCLUDED_NRF_BOARD_BUSSES_H +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H -void board_i2c(void); -extern mp_obj_fun_builtin_fixed_t board_i2c_obj; +#include "common-hal/digitalio/DigitalInOut.h" -void board_spi(void); -extern mp_obj_fun_builtin_fixed_t board_spi_obj; +typedef struct { + mp_obj_base_t base; + uint8_t* bus; + digitalio_digitalinout_obj_t command; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t reset; + digitalio_digitalinout_obj_t write; + digitalio_digitalinout_obj_t read; + uint8_t data0_pin; + NRF_GPIO_Type* write_group; + uint32_t write_mask; +} displayio_parallelbus_obj_t; -void board_uart(void); -extern mp_obj_fun_builtin_fixed_t board_uart_obj; - -#endif // MICROPY_INCLUDED_NRF_BOARD_BUSSES_H +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H diff --git a/ports/nrf/common-hal/microcontroller/Pin.h b/ports/nrf/common-hal/microcontroller/Pin.h index 61be8bc358649..735ed90ccaf7d 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.h +++ b/ports/nrf/common-hal/microcontroller/Pin.h @@ -44,6 +44,7 @@ void reset_all_pins(void); // need to store a full pointer. void reset_pin_number(uint8_t pin); void claim_pin(const mcu_pin_obj_t* pin); +bool pin_number_is_free(uint8_t pin_number); void never_reset_pin_number(uint8_t pin_number); // Lower 5 bits of a pin number are the pin number in a port. diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index d38b145783031..b6e5f9fdf42ec 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -235,5 +235,7 @@ void run_background_tasks(void); //#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt" #define CIRCUITPY_DEFAULT_STACK_SIZE 4096 +#define CIRCUITPY_DISPLAYIO (1) +#define CIRCUITPY_DISPLAY_LIMIT (3) #endif diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index 3a9f66d4c57c4..b8b00372ce3ec 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -27,7 +27,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H -#include "common-hal/displayio/FourWire.h" +#include "shared-module/displayio/FourWire.h" #include "common-hal/microcontroller/Pin.h" #include "shared-module/displayio/Group.h" diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.c b/shared-module/displayio/FourWire.c similarity index 100% rename from ports/atmel-samd/common-hal/displayio/FourWire.c rename to shared-module/displayio/FourWire.c diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.h b/shared-module/displayio/FourWire.h similarity index 100% rename from ports/atmel-samd/common-hal/displayio/FourWire.h rename to shared-module/displayio/FourWire.h diff --git a/supervisor/shared/board_busses.c b/supervisor/shared/board_busses.c index 84919ebff158f..38308ccee3d9f 100644 --- a/supervisor/shared/board_busses.c +++ b/supervisor/shared/board_busses.c @@ -31,7 +31,6 @@ #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/translate.h" #include "mpconfigboard.h" -#include "samd/pins.h" #include "py/runtime.h" #define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL)) From 6404aaf411d7fe5fd96f3a8cbf7a1cb7580a09e7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 18:19:07 -0800 Subject: [PATCH 121/153] Fix up nrf and using board.SPI in FourWire --- main.c | 7 +- ports/atmel-samd/background.c | 5 +- ports/atmel-samd/mpconfigport.h | 2 + ports/nrf/background.c | 15 ++-- .../boards/feather_nrf52840_express/pins.c | 68 ++++++++++--------- ports/nrf/common-hal/microcontroller/Pin.c | 7 +- ports/nrf/mpconfigport.h | 2 + shared-bindings/displayio/Display.c | 3 +- shared-bindings/displayio/FourWire.c | 11 ++- shared-bindings/displayio/ParallelBus.c | 3 +- shared-module/displayio/FourWire.c | 8 ++- shared-module/displayio/__init__.c | 3 + supervisor/shared/board_busses.c | 25 +++++-- supervisor/shared/board_busses.h | 6 +- 14 files changed, 109 insertions(+), 56 deletions(-) diff --git a/main.c b/main.c index 02c832e67512c..e137f7d47d63e 100755 --- a/main.c +++ b/main.c @@ -27,7 +27,6 @@ #include #include -#include "shared-module/displayio/__init__.h" #include "extmod/vfs.h" #include "extmod/vfs_fat.h" @@ -62,6 +61,10 @@ #include "shared-module/network/__init__.h" #endif +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -200,8 +203,10 @@ bool run_code_py(safe_mode_t safe_mode) { serial_write_compressed(translate("WARNING: Your code filename has two extensions\n")); } } + #ifdef CIRCUITPY_DISPLAYIO // Turn off the display before the heap disappears. reset_displays(); + #endif stop_mp(); free_memory(heap); diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 59e03008a9151..4f3257f3fdaa6 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -30,10 +30,13 @@ #include "supervisor/usb.h" #include "py/runtime.h" -#include "shared-module/displayio/__init__.h" #include "shared-module/network/__init__.h" #include "supervisor/shared/stack.h" +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + volatile uint64_t last_finished_tick = 0; bool stack_ok_so_far = true; diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index a2e4075c4582a..12410b0beff3e 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -285,6 +285,7 @@ extern const struct _mp_obj_module_t wiznet_module; #define CIRCUITPY_DISPLAY_LIMIT (3) #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, #else + #define CIRCUITPY_DISPLAY_LIMIT (0) #define DISPLAYIO_MODULE #endif @@ -338,6 +339,7 @@ extern const struct _mp_obj_module_t wiznet_module; #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) + #define CIRCUITPY_DISPLAY_LIMIT (0) #endif // Disabled for now. diff --git a/ports/nrf/background.c b/ports/nrf/background.c index f022b5bc914d3..69c76fd066ecd 100644 --- a/ports/nrf/background.c +++ b/ports/nrf/background.c @@ -24,15 +24,20 @@ * THE SOFTWARE. */ -#ifdef NRF52840 +#include "py/runtime.h" #include "supervisor/usb.h" -#endif - #include "supervisor/shared/stack.h" +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + void run_background_tasks(void) { - #ifdef NRF52840 - usb_background(); + usb_background(); + + #ifdef CIRCUITPY_DISPLAYIO + displayio_refresh_displays(); #endif + assert_heap_ok(); } diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c index dfb0be6df7575..c6f643761dd23 100644 --- a/ports/nrf/boards/feather_nrf52840_express/pins.c +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -3,49 +3,53 @@ #include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_28) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_29) }, - { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_29) }, - { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) }, - { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, - { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, - { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, - { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_27) }, - { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_06) }, - { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_08) }, - { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_09) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_16) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_14) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, - { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, - { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, - { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c index 02847e1505fc1..268e2f75dab11 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.c +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -142,6 +142,11 @@ void claim_pin(const mcu_pin_obj_t* pin) { #endif } + +bool pin_number_is_free(uint8_t pin_number) { + return !(claimed_pins[nrf_pin_port(pin_number)] & (1 << nrf_relative_pin_number(pin_number))); +} + bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { #ifdef MICROPY_HW_NEOPIXEL if (pin == MICROPY_HW_NEOPIXEL) { @@ -163,5 +168,5 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { } #endif - return !(claimed_pins[nrf_pin_port(pin->number)] & (1 << nrf_relative_pin_number(pin->number))); + return pin_number_is_free(pin->number); } diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index b6e5f9fdf42ec..3ec37960b9611 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -163,6 +163,7 @@ extern const struct _mp_obj_module_t microcontroller_module; extern const struct _mp_obj_module_t bitbangio_module; extern const struct _mp_obj_module_t analogio_module; extern const struct _mp_obj_module_t digitalio_module; +extern const struct _mp_obj_module_t displayio_module; extern const struct _mp_obj_module_t pulseio_module; extern const struct _mp_obj_module_t busio_module; extern const struct _mp_obj_module_t board_module; @@ -195,6 +196,7 @@ extern const struct _mp_obj_module_t bleio_module; { MP_OBJ_NEW_QSTR (MP_QSTR_busio ), (mp_obj_t)&busio_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_analogio ), (mp_obj_t)&analogio_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_digitalio ), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR (MP_QSTR_displayio ), (mp_obj_t)&displayio_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_pulseio ), (mp_obj_t)&pulseio_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_microcontroller ), (mp_obj_t)µcontroller_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_neopixel_write ), (mp_obj_t)&neopixel_write_module }, \ diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 21f44965ea351..9028c28654f29 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -83,7 +83,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a displayio_display_obj_t *self = NULL; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].display.base.type == NULL) { + if (displays[i].display.base.type == NULL || + displays[i].display.base.type == &mp_type_NoneType) { self = &displays[i].display; break; } diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 9833fbc640330..530eafb51fd0b 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -65,18 +65,23 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ mp_obj_t command = args[ARG_command].u_obj; mp_obj_t chip_select = args[ARG_chip_select].u_obj; - mp_obj_t reset = args[ARG_reset].u_obj; if (command == mp_const_none || chip_select == mp_const_none) { mp_raise_ValueError(translate("Command and chip_select required")); } assert_pin_free(command); assert_pin_free(chip_select); - assert_pin_free(reset); + mp_obj_t reset = args[ARG_reset].u_obj; + if (reset != mp_const_none) { + assert_pin_free(reset); + } else { + reset = NULL; + } displayio_fourwire_obj_t* self = NULL; mp_obj_t spi = args[ARG_spi_bus].u_obj; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].fourwire_bus.base.type== NULL) { + if (displays[i].fourwire_bus.base.type == NULL || + displays[i].fourwire_bus.base.type == &mp_type_NoneType) { self = &displays[i].fourwire_bus; self->base.type = &displayio_fourwire_type; break; diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index aa861bb81a707..e1079acb58a6c 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -83,7 +83,8 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t displayio_parallelbus_obj_t* self = NULL; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].parallel_bus.base.type== NULL) { + if (displays[i].parallel_bus.base.type== NULL || + displays[i].parallel_bus.base.type == &mp_type_NoneType) { self = &displays[i].parallel_bus; self->base.type = &displayio_parallelbus_type; break; diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c index ab01e26091c8d..9da5c07012385 100644 --- a/shared-module/displayio/FourWire.c +++ b/shared-module/displayio/FourWire.c @@ -45,12 +45,14 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); - common_hal_digitalio_digitalinout_construct(&self->reset, reset); - common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + if (reset != NULL) { + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + never_reset_pin_number(reset->number); + } never_reset_pin_number(command->number); never_reset_pin_number(chip_select->number); - never_reset_pin_number(reset->number); } void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 92d97a6efe650..ccabe9c9d5f18 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -151,6 +151,9 @@ void reset_displays(void) { if (((uint32_t) fourwire->bus) < ((uint32_t) &displays) || ((uint32_t) fourwire->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) { busio_spi_obj_t* original_spi = fourwire->bus; + if (original_spi == board_spi()) { + continue; + } memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); fourwire->bus = &fourwire->inline_bus; // Check for other displays that use the same spi bus and swap them too. diff --git a/supervisor/shared/board_busses.c b/supervisor/shared/board_busses.c index 38308ccee3d9f..ed1f98a58b170 100644 --- a/supervisor/shared/board_busses.c +++ b/supervisor/shared/board_busses.c @@ -33,6 +33,10 @@ #include "mpconfigboard.h" #include "py/runtime.h" +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + #define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL)) #define BOARD_SPI (defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MISO) && defined(DEFAULT_SPI_BUS_MOSI)) #define BOARD_UART (defined(DEFAULT_UART_BUS_RX) && defined(DEFAULT_UART_BUS_TX)) @@ -40,7 +44,7 @@ #if BOARD_I2C STATIC mp_obj_t i2c_singleton = NULL; -STATIC mp_obj_t board_i2c(void) { +mp_obj_t board_i2c(void) { if (i2c_singleton == NULL) { busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); @@ -54,7 +58,7 @@ STATIC mp_obj_t board_i2c(void) { return i2c_singleton; } #else -STATIC mp_obj_t board_i2c(void) { +mp_obj_t board_i2c(void) { mp_raise_NotImplementedError(translate("No default I2C bus")); return NULL; } @@ -91,7 +95,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); #if BOARD_UART STATIC mp_obj_t uart_singleton = NULL; -STATIC mp_obj_t board_uart(void) { +mp_obj_t board_uart(void) { if (uart_singleton == NULL) { busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t); self->base.type = &busio_uart_type; @@ -108,7 +112,7 @@ STATIC mp_obj_t board_uart(void) { return uart_singleton; } #else -STATIC mp_obj_t board_uart(void) { +mp_obj_t board_uart(void) { mp_raise_NotImplementedError(translate("No default UART bus")); return NULL; } @@ -121,7 +125,18 @@ void reset_board_busses(void) { i2c_singleton = NULL; #endif #if BOARD_SPI - spi_singleton = NULL; + bool display_using_spi = false; + #ifdef CIRCUITPY_DISPLAYIO + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.bus == spi_singleton) { + display_using_spi = true; + break; + } + } + #endif + if (!display_using_spi) { + spi_singleton = NULL; + } #endif #if BOARD_UART uart_singleton = NULL; diff --git a/supervisor/shared/board_busses.h b/supervisor/shared/board_busses.h index f6a8a429665df..0ccb3ba6a6672 100644 --- a/supervisor/shared/board_busses.h +++ b/supervisor/shared/board_busses.h @@ -30,13 +30,13 @@ #include "py/obj.h" mp_obj_t board_i2c(void); -extern mp_obj_fun_builtin_fixed_t board_i2c_obj; +MP_DECLARE_CONST_FUN_OBJ_0(board_i2c_obj); mp_obj_t board_spi(void); -extern mp_obj_fun_builtin_fixed_t board_spi_obj; +MP_DECLARE_CONST_FUN_OBJ_0(board_spi_obj); mp_obj_t board_uart(void); -extern mp_obj_fun_builtin_fixed_t board_uart_obj; +MP_DECLARE_CONST_FUN_OBJ_0(board_uart_obj); void reset_board_busses(void); From fddc98858afb19b87a2ed65b4d2b301b3e1ce667 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 18:51:40 -0800 Subject: [PATCH 122/153] fix nonetype handling and nrf never reset --- ports/nrf/common-hal/microcontroller/Pin.c | 2 +- shared-module/displayio/__init__.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c index 268e2f75dab11..112654c7e0b78 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.c +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -53,7 +53,7 @@ void reset_all_pins(void) { } for (uint32_t pin = 0; pin < NUMBER_OF_PINS; ++pin) { - if (!(never_reset_pins[nrf_pin_port(pin)] & (1 << nrf_relative_pin_number(pin)))) { + if ((never_reset_pins[nrf_pin_port(pin)] & (1 << nrf_relative_pin_number(pin))) != 0) { continue; } nrf_gpio_cfg_default(pin); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index ccabe9c9d5f18..c8132e2f94307 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -13,7 +13,7 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; void displayio_refresh_displays(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].display.base.type == NULL) { + if (displays[i].display.base.type == NULL || displays[i].display.base.type == &mp_type_NoneType) { continue; } displayio_display_obj_t* display = &displays[i].display; From 96e2c717fc9fa94ad6fd3784d1a9dd693efdb780 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 22:10:11 -0800 Subject: [PATCH 123/153] Fix build --- ports/atmel-samd/mpconfigport.h | 1 - 1 file changed, 1 deletion(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 12410b0beff3e..86edc9039fbec 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -192,7 +192,6 @@ typedef long mp_off_t; #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_SYS_EXC_INFO (1) // MICROPY_PY_UERRNO_LIST - Use the default -#define CIRCUITPY_DISPLAY_LIMIT (3) #endif #ifdef LONGINT_IMPL_NONE From 41dad1ea1eb5126ec7e80173a0fb74d9707b1e56 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 11:43:35 -0800 Subject: [PATCH 124/153] Fix pin defs --- .../boards/grandcentral_m4_express/pins.c | 228 +++++++++--------- .../atmel-samd/boards/metro_m4_express/pins.c | 62 ++--- ports/atmel-samd/boards/pyportal/pins.c | 88 +++---- 3 files changed, 189 insertions(+), 189 deletions(-) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c index 0d19a63efdd16..26d0e71a0e850 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -5,129 +5,129 @@ // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from // microcontroller.pin. -STATIC const mp_map_elem_t board_global_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_AREF), (mp_obj_t)&pin_PA03 }, +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_PA03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PA05 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PB03 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PC00 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PC01 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PC02 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A6), (mp_obj_t)&pin_PC03 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A7), (mp_obj_t)&pin_PB04 }, + { 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_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PC00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PC01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PC02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PC03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A8), (mp_obj_t)&pin_PB05 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A9), (mp_obj_t)&pin_PB06 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A10), (mp_obj_t)&pin_PB07 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A11), (mp_obj_t)&pin_PB08 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A12), (mp_obj_t)&pin_PB09 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A13), (mp_obj_t)&pin_PA04 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A14), (mp_obj_t)&pin_PA06 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A15), (mp_obj_t)&pin_PA07 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_PA07) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D0), (mp_obj_t)&pin_PB25 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PB25 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D1), (mp_obj_t)&pin_PB24 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PB24 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PC18 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PC19 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PC20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D5), (mp_obj_t)&pin_PC21 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D6), (mp_obj_t)&pin_PD20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PD21 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PB18 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PB02 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D10), (mp_obj_t)&pin_PB22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D11), (mp_obj_t)&pin_PB23 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PB00 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PB01 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB25) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB25) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB24) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB24) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PC18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PC19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PC20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PC21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PD20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PD21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB01) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX3), (mp_obj_t)&pin_PB16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D14), (mp_obj_t)&pin_PB16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX3), (mp_obj_t)&pin_PB17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D15), (mp_obj_t)&pin_PB17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX2), (mp_obj_t)&pin_PC22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D16), (mp_obj_t)&pin_PC22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX2), (mp_obj_t)&pin_PC23 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D17), (mp_obj_t)&pin_PC23 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX1), (mp_obj_t)&pin_PB12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D18), (mp_obj_t)&pin_PB12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX1), (mp_obj_t)&pin_PB13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D19), (mp_obj_t)&pin_PB13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D20), (mp_obj_t)&pin_PB20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D21), (mp_obj_t)&pin_PB21 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB21 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX3), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX3), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PC22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PC22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_PC23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PC23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_PB20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_PB21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB21) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D22), (mp_obj_t)&pin_PD12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D23), (mp_obj_t)&pin_PA15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D24), (mp_obj_t)&pin_PC17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL1), (mp_obj_t)&pin_PC17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D25), (mp_obj_t)&pin_PC16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA1), (mp_obj_t)&pin_PC16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D26), (mp_obj_t)&pin_PA12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_DEN1), (mp_obj_t)&pin_PA12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D27), (mp_obj_t)&pin_PA13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_DEN2), (mp_obj_t)&pin_PA13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D28), (mp_obj_t)&pin_PA14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_CLK), (mp_obj_t)&pin_PA14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D29), (mp_obj_t)&pin_PB19 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_XCLK), (mp_obj_t)&pin_PB19 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D30), (mp_obj_t)&pin_PA23 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D7), (mp_obj_t)&pin_PA23 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D31), (mp_obj_t)&pin_PA22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D6), (mp_obj_t)&pin_PA22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D32), (mp_obj_t)&pin_PA21 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D5), (mp_obj_t)&pin_PA21 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D33), (mp_obj_t)&pin_PA20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D4), (mp_obj_t)&pin_PA20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D34), (mp_obj_t)&pin_PA19 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D3), (mp_obj_t)&pin_PA19 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D35), (mp_obj_t)&pin_PA18 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D2), (mp_obj_t)&pin_PA18 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D36), (mp_obj_t)&pin_PA17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D1), (mp_obj_t)&pin_PA17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D37), (mp_obj_t)&pin_PA16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D0), (mp_obj_t)&pin_PA16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D38), (mp_obj_t)&pin_PB15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D9), (mp_obj_t)&pin_PB15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D39), (mp_obj_t)&pin_PB14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D8), (mp_obj_t)&pin_PB14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D40), (mp_obj_t)&pin_PC13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D11), (mp_obj_t)&pin_PC13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D41), (mp_obj_t)&pin_PC12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D10), (mp_obj_t)&pin_PC12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D42), (mp_obj_t)&pin_PC15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D13), (mp_obj_t)&pin_PC15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D43), (mp_obj_t)&pin_PC14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D12), (mp_obj_t)&pin_PC14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D44), (mp_obj_t)&pin_PC11 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D45), (mp_obj_t)&pin_PC10 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D46), (mp_obj_t)&pin_PC06 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D47), (mp_obj_t)&pin_PC07 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D48), (mp_obj_t)&pin_PC04 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D49), (mp_obj_t)&pin_PC05 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D50), (mp_obj_t)&pin_PD11 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PD11 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D51), (mp_obj_t)&pin_PD08 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PD08 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D52), (mp_obj_t)&pin_PD09 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PD09 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D53), (mp_obj_t)&pin_PD10 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SS), (mp_obj_t)&pin_PD10 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_PD12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_PC17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PC17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_PC16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PC16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_DEN1), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_DEN2), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_CLK), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_PB19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_XCLK), MP_ROM_PTR(&pin_PB19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D7), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D6), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D5), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D3), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D2), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D1), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D9), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D8), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_PC13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D11), MP_ROM_PTR(&pin_PC13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_PC12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D10), MP_ROM_PTR(&pin_PC12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_PC15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D13), MP_ROM_PTR(&pin_PC15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_PC14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D12), MP_ROM_PTR(&pin_PC14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_PC11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D45), MP_ROM_PTR(&pin_PC10) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D46), MP_ROM_PTR(&pin_PC06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D47), MP_ROM_PTR(&pin_PC07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_PC04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D49), MP_ROM_PTR(&pin_PC05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D50), MP_ROM_PTR(&pin_PD11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PD11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D51), MP_ROM_PTR(&pin_PD08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PD08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D52), MP_ROM_PTR(&pin_PD09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PD09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D53), MP_ROM_PTR(&pin_PD10) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PD10) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MOSI), (mp_obj_t)&pin_PB26 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SCK), (mp_obj_t)&pin_PB27 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), (mp_obj_t)&pin_PB28 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MISO), (mp_obj_t)&pin_PB29 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PB26) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PB27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PB28) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PB29) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), (mp_obj_t)&pin_PB31 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_PB31) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PC24 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PC24) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), (mp_obj_t)&pin_PC31 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), (mp_obj_t)&pin_PC30 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PC31) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PC30) }, { 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) }, diff --git a/ports/atmel-samd/boards/metro_m4_express/pins.c b/ports/atmel-samd/boards/metro_m4_express/pins.c index dd419aec67001..63ae319a2be88 100644 --- a/ports/atmel-samd/boards/metro_m4_express/pins.c +++ b/ports/atmel-samd/boards/metro_m4_express/pins.c @@ -5,42 +5,42 @@ // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from // microcontroller.pin. -STATIC const mp_map_elem_t board_global_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PA05 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PA06 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PA04 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PB08 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PB09 }, +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_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D0), (mp_obj_t)&pin_PA23 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PA23 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D1), (mp_obj_t)&pin_PA22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PA22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PB17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PB16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PB13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D5), (mp_obj_t)&pin_PB14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D6), (mp_obj_t)&pin_PB15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PB12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PA21 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PA20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D10), (mp_obj_t)&pin_PA18 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D11), (mp_obj_t)&pin_PA19 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PA17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA16 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB02 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB03 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB22 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PA13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA14 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), (mp_obj_t)&pin_PB06 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), (mp_obj_t)&pin_PA27 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX),MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX),MP_ROM_PTR(&pin_PA27) }, { 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) }, diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index 6b1254dfcd991..9a5c5b1a5c770 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -7,68 +7,68 @@ // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from // microcontroller.pin. -STATIC const mp_map_elem_t board_global_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_AUDIO_OUT), (mp_obj_t)&pin_PA02 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 }, // analog out/in +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_AUDIO_OUT), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, // analog out/in // STEMMA connectors - { MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PB02 }, // SDA - { MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PB03 }, // SCL - { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PB00 }, // D3 - { MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PB00 }, // D3 - { MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PB01 }, // D4 - { MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PB01 }, // D4 + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB02) }, // SDA + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB03) }, // SCL + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB00) }, // D3 + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB00) }, // D3 + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB01) }, // D4 + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB01) }, // D4 // Indicator LED - { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA27 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_L), (mp_obj_t)&pin_PA27 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB22 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, // LCD pins - { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), (mp_obj_t)&pin_PA00 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RD), (mp_obj_t)&pin_PB04 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RS), (mp_obj_t)&pin_PB05 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_CS), (mp_obj_t)&pin_PB06 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_TE), (mp_obj_t)&pin_PB07 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_WR), (mp_obj_t)&pin_PB09 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_BACKLIGHT), (mp_obj_t)&pin_PB31 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA0), (mp_obj_t)&pin_PA16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA1), (mp_obj_t)&pin_PA17 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA2), (mp_obj_t)&pin_PA18 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA3), (mp_obj_t)&pin_PA19 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA4), (mp_obj_t)&pin_PA20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA5), (mp_obj_t)&pin_PA21 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA6), (mp_obj_t)&pin_PA22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA7), (mp_obj_t)&pin_PA23 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RD), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RS), MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_TE), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_WR), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_PB31) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA1), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA2), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA3), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA5), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA6), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA7), MP_ROM_PTR(&pin_PA23) }, // Touch pins - { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YD), (mp_obj_t)&pin_PA04 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XL), (mp_obj_t)&pin_PA05 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YU), (mp_obj_t)&pin_PA06 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XR), (mp_obj_t)&pin_PB08 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YD), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XL), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YU), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XR), MP_ROM_PTR(&pin_PB08) }, // ESP control - { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), (mp_obj_t)&pin_PA15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), (mp_obj_t)&pin_PB14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), (mp_obj_t)&pin_PB15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), (mp_obj_t)&pin_PB16 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_PB16) }, // UART - { MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PB12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PB13 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB13) }, // SPI - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PA13 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA14 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, // I2C - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB02 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB03 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, // SD Card - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), (mp_obj_t)&pin_PB30 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), (mp_obj_t)&pin_PA01 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT),MP_ROM_PTR(&pin_PA01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, From 427766ac6913ae3b838e29f5cd1dc9b782c7d56a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 11:44:53 -0800 Subject: [PATCH 125/153] Update translations --- locale/ID.po | 288 +++++++++++++++++++------------ locale/circuitpython.pot | 273 ++++++++++++++++++------------ locale/de_DE.po | 308 ++++++++++++++++++++------------- locale/en_US.po | 273 ++++++++++++++++++------------ locale/es.po | 355 ++++++++++++++++++++++++--------------- locale/fil.po | 335 +++++++++++++++++++++--------------- locale/fr.po | 327 ++++++++++++++++++++++-------------- locale/it_IT.po | 325 +++++++++++++++++++++-------------- locale/pt_BR.po | 308 ++++++++++++++++++++------------- 9 files changed, 1705 insertions(+), 1087 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 952e12d4d3ede..ae18a14d0d4dd 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -151,11 +151,11 @@ msgstr "argumen-argumen tidak valid" msgid "script compilation not supported" msgstr "kompilasi script tidak didukung" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr "output:\n" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,30 +163,30 @@ msgstr "" "Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk " "menjalankannya atau masuk ke REPL untukmenonaktifkan.\n" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Berjalan di mode aman(safe mode)! Auto-reload tidak aktif.\n" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "Auto-reload tidak aktif.\n" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "" "Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset " "(Reload)" -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "memulai ulang software(soft reboot)\n" @@ -203,18 +203,6 @@ msgstr "kalibrasi adalah read only" msgid "calibration is out of range" msgstr "kalibrasi keluar dari jangkauan" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "Tidak ada standar bus I2C" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "Tidak ada standar bus SPI" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "Tidak ada standar bus UART" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -333,7 +321,7 @@ msgid "Not enough pins available" msgstr "Pin yang tersedia tidak cukup" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -381,6 +369,17 @@ msgstr "Tidak ada pin TX" msgid "Cannot get pull while in output mode" msgstr "Tidak bisa mendapatkan pull pada saat mode output" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC sudah digunakan" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -901,46 +900,46 @@ msgstr "Tidak tahu cara meloloskan objek ke fungsi native" msgid "[addrinfo error %d]" msgstr "[addrinfo error %d]" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "fungsi tidak dapat mengambil argumen keyword" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "fungsi mengambil posisi argumen %d tapi %d yang diberikan" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "fungsi kehilangan %d argumen posisi yang dibutuhkan" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "fungsi diharapkan setidaknya %d argumen, hanya mendapatkan %d" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "'%q' argumen dibutuhkan" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "argumen posisi ekstra telah diberikan" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "argumen keyword ekstra telah diberikan" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "argumen num/types tidak cocok" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "argumen keyword belum diimplementasi - gunakan args normal" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" @@ -952,11 +951,11 @@ msgstr "argumen keyword tidak diharapkan" msgid "keywords must be strings" msgstr "keyword harus berupa string" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "keyword argumen '%q' tidak diharapkan" @@ -1544,11 +1543,11 @@ msgstr "" msgid "empty" msgstr "" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "" @@ -1809,69 +1808,69 @@ msgstr "" msgid "string index out of range" msgstr "" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "" @@ -2067,8 +2066,8 @@ msgstr "" msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "" @@ -2105,29 +2104,29 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 msgid "Invalid voice count" msgstr "" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 msgid "Invalid channel count" msgstr "" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 msgid "Sample rate must be positive" msgstr "" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 msgid "bits_per_sample must be 8 or 16" msgstr "" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" msgstr "" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "" @@ -2136,52 +2135,52 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "buffers harus mempunyai panjang yang sama" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 #, fuzzy msgid "buffer_size must be >= 1" msgstr "buffers harus mempunyai panjang yang sama" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 msgid "Expected a Characteristic" msgstr "" @@ -2201,20 +2200,20 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 #, fuzzy msgid "name must be a string" msgstr "keyword harus berupa string" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2235,19 +2234,19 @@ msgstr "buffers harus mempunyai panjang yang sama" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "" -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" @@ -2273,7 +2272,7 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 msgid "y should be an int" msgstr "" @@ -2289,45 +2288,78 @@ msgstr "" msgid "color should be an int" msgstr "" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 msgid "Group must have size at least 1" msgstr "" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 msgid "color buffer must be a buffer or int" msgstr "" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/displayio/Shape.c:96 +msgid "end_x should be an int" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:49 msgid "position must be 2-tuple" msgstr "" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 msgid "unsupported bitmap type" msgstr "" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -2339,15 +2371,15 @@ msgstr "" msgid "expected a DigitalInOut" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 msgid "can't convert address to int" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "" @@ -2389,29 +2421,29 @@ msgstr "" msgid "No hardware random available" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 msgid "" "PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:195 +#: shared-bindings/pulseio/PWMOut.c:193 msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "" @@ -2577,11 +2609,20 @@ msgstr "" msgid "row must be packed and word aligned" msgstr "" +#: shared-module/displayio/Display.c:62 +#, fuzzy +msgid "Unsupported display bus type" +msgstr "Baudrate tidak didukung" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 msgid "Group empty" msgstr "" @@ -2599,6 +2640,19 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/displayio/Shape.c:60 +msgid "y value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:63 +msgid "x value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "" @@ -2624,6 +2678,18 @@ msgstr "" msgid "USB Error" msgstr "" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "Tidak ada standar bus I2C" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "Tidak ada standar bus SPI" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "Tidak ada standar bus UART" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " @@ -2688,13 +2754,6 @@ msgstr "" #~ msgid "Invalid UUID string length" #~ msgstr "Panjang string UUID tidak valid" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parameter UUID tidak valid" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" - #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " #~ "CIRCUITPY).\n" @@ -2702,6 +2761,13 @@ msgstr "" #~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " #~ "CIRCUITPY).\n" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parameter UUID tidak valid" + #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 5c85d09a8035a..e52ee4df47333 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: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -151,37 +151,37 @@ msgstr "" msgid "script compilation not supported" msgstr "" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr "" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "" @@ -198,18 +198,6 @@ msgstr "" msgid "calibration is out of range" msgstr "" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -326,7 +314,7 @@ msgid "Not enough pins available" msgstr "" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -374,6 +362,17 @@ msgstr "" msgid "Cannot get pull while in output mode" msgstr "" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, c-format +msgid "Bus pin %d is already in use" +msgstr "" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -874,46 +873,46 @@ msgstr "" msgid "[addrinfo error %d]" msgstr "" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "" @@ -925,11 +924,11 @@ msgstr "" msgid "keywords must be strings" msgstr "" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "" @@ -1511,11 +1510,11 @@ msgstr "" msgid "empty" msgstr "" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "" @@ -1776,69 +1775,69 @@ msgstr "" msgid "string index out of range" msgstr "" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "" @@ -2034,8 +2033,8 @@ msgstr "" msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "" @@ -2072,29 +2071,29 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 msgid "Invalid voice count" msgstr "" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 msgid "Invalid channel count" msgstr "" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 msgid "Sample rate must be positive" msgstr "" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 msgid "bits_per_sample must be 8 or 16" msgstr "" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" msgstr "" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "" @@ -2103,51 +2102,51 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, c-format msgid "Address must be %d bytes long" msgstr "" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 msgid "buffer_size must be >= 1" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 msgid "Expected a Characteristic" msgstr "" @@ -2167,19 +2166,19 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 msgid "name must be a string" msgstr "" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2199,19 +2198,19 @@ msgstr "" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "" -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" @@ -2237,7 +2236,7 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 msgid "y should be an int" msgstr "" @@ -2253,45 +2252,78 @@ msgstr "" msgid "color should be an int" msgstr "" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 msgid "Group must have size at least 1" msgstr "" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 msgid "color buffer must be a buffer or int" msgstr "" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/displayio/Shape.c:96 +msgid "end_x should be an int" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:49 msgid "position must be 2-tuple" msgstr "" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 msgid "unsupported bitmap type" msgstr "" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -2303,15 +2335,15 @@ msgstr "" msgid "expected a DigitalInOut" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 msgid "can't convert address to int" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "" @@ -2353,29 +2385,29 @@ msgstr "" msgid "No hardware random available" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 msgid "" "PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:195 +#: shared-bindings/pulseio/PWMOut.c:193 msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "" @@ -2541,11 +2573,19 @@ msgstr "" msgid "row must be packed and word aligned" msgstr "" +#: shared-module/displayio/Display.c:62 +msgid "Unsupported display bus type" +msgstr "" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 msgid "Group empty" msgstr "" @@ -2563,6 +2603,19 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/displayio/Shape.c:60 +msgid "y value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:63 +msgid "x value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "" @@ -2588,6 +2641,18 @@ msgstr "" msgid "USB Error" msgstr "" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 47098b66acb35..a6d7b6103c546 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -151,11 +151,11 @@ msgstr "ungültige argumente" msgid "script compilation not supported" msgstr "kompilieren von Skripten ist nicht unterstützt" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr " Ausgabe:\n" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,29 +163,29 @@ msgstr "" "Automatisches Neuladen ist aktiv. Speichere Dateien über USB um sie " "auszuführen oder verbinde dich mit der REPL um zu deaktivieren.\n" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Sicherheitsmodus aktiv! Automatisches Neuladen ist deaktiviert.\n" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "Automatisches Neuladen ist deaktiviert.\n" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "Sicherheitsmodus aktiv! Gespeicherter Code wird nicht ausgeführt\n" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "WARNUNG: Der Dateiname deines codes hat zwei Dateityperweiterungen\n" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Drücke eine Taste um dich mit der REPL zu verbinden. Drücke Strg-D zum neu " "laden" -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "soft reboot\n" @@ -202,18 +202,6 @@ msgstr "Kalibrierung ist Schreibgeschützt" msgid "calibration is out of range" msgstr "Kalibrierung ist außerhalb der Reichweite" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "Kein Standard I2C Bus" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "Kein Standard SPI Bus" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "Kein Standard UART Bus" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -330,7 +318,7 @@ msgid "Not enough pins available" msgstr "Nicht genug Pins vorhanden" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -378,6 +366,17 @@ msgstr "Kein TX Pin" msgid "Cannot get pull while in output mode" msgstr "Pull up im Ausgabemodus nicht möglich" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC wird schon benutzt" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -901,46 +900,46 @@ msgstr "" msgid "[addrinfo error %d]" msgstr "" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "" @@ -952,11 +951,11 @@ msgstr "" msgid "keywords must be strings" msgstr "" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "" @@ -1540,11 +1539,11 @@ msgstr "" msgid "empty" msgstr "" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "" @@ -1805,69 +1804,69 @@ msgstr "" msgid "string index out of range" msgstr "" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "" @@ -2063,8 +2062,8 @@ msgstr "" msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "" @@ -2101,32 +2100,32 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 #, fuzzy msgid "Invalid voice count" msgstr "Ungültiger clock pin" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 #, fuzzy msgid "Invalid channel count" msgstr "Ungültiger clock pin" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 msgid "Sample rate must be positive" msgstr "" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "bits müssen 8 sein" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" msgstr "" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "" @@ -2135,52 +2134,52 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "Buffer müssen gleich lang sein" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 #, fuzzy msgid "buffer_size must be >= 1" msgstr "Buffer müssen gleich lang sein" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 #, fuzzy msgid "Expected a Characteristic" msgstr "Kann das Merkmal nicht hinzufügen." @@ -2201,20 +2200,20 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 #, fuzzy msgid "name must be a string" msgstr "heap muss eine Liste sein" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2235,19 +2234,19 @@ msgstr "Buffer müssen gleich lang sein" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "" -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" @@ -2273,7 +2272,7 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 msgid "y should be an int" msgstr "" @@ -2289,46 +2288,79 @@ msgstr "" msgid "color should be an int" msgstr "" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 msgid "Group must have size at least 1" msgstr "" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 msgid "color buffer must be a buffer or int" msgstr "" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/displayio/Shape.c:96 +msgid "end_x should be an int" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:49 msgid "position must be 2-tuple" msgstr "" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 #, fuzzy msgid "unsupported bitmap type" msgstr "Baudrate wird nicht unterstütz" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -2340,15 +2372,15 @@ msgstr "" msgid "expected a DigitalInOut" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 msgid "can't convert address to int" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "" @@ -2390,29 +2422,29 @@ msgstr "" msgid "No hardware random available" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 msgid "" "PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:195 +#: shared-bindings/pulseio/PWMOut.c:193 msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "" @@ -2578,11 +2610,20 @@ msgstr "" msgid "row must be packed and word aligned" msgstr "" +#: shared-module/displayio/Display.c:62 +#, fuzzy +msgid "Unsupported display bus type" +msgstr "Baudrate wird nicht unterstütz" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 msgid "Group empty" msgstr "" @@ -2601,6 +2642,19 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/displayio/Shape.c:60 +msgid "y value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:63 +msgid "x value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "Kann '/' nicht remounten when USB aktiv ist" @@ -2626,6 +2680,18 @@ msgstr "USB beschäftigt" msgid "USB Error" msgstr "USB Fehler" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "Kein Standard I2C Bus" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "Kein Standard SPI Bus" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "Kein Standard UART Bus" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "Du hast das Starten im Sicherheitsmodus ausgelöst durch " @@ -2691,12 +2757,24 @@ msgstr "" #~ msgid "Invalid UUID parameter" #~ msgstr "Ungültiger UUID-Parameter" -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." + +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" + #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" @@ -2705,15 +2783,6 @@ msgstr "" #~ msgid "Can not encode UUID, to check length." #~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." - #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " #~ "CIRCUITPY).\n" @@ -2721,14 +2790,11 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." + #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Kann UUID in das advertisement packet kodieren." #~ msgid "Can not query for the device address." #~ msgstr "Kann nicht nach der Geräteadresse suchen." - -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." - -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." diff --git a/locale/en_US.po b/locale/en_US.po index ee47b08eab9bb..1fd9cd3779de3 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:31-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -151,37 +151,37 @@ msgstr "" msgid "script compilation not supported" msgstr "" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr "" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "" @@ -198,18 +198,6 @@ msgstr "" msgid "calibration is out of range" msgstr "" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -326,7 +314,7 @@ msgid "Not enough pins available" msgstr "" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -374,6 +362,17 @@ msgstr "" msgid "Cannot get pull while in output mode" msgstr "" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, c-format +msgid "Bus pin %d is already in use" +msgstr "" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -874,46 +873,46 @@ msgstr "" msgid "[addrinfo error %d]" msgstr "" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "" @@ -925,11 +924,11 @@ msgstr "" msgid "keywords must be strings" msgstr "" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "" @@ -1511,11 +1510,11 @@ msgstr "" msgid "empty" msgstr "" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "" @@ -1776,69 +1775,69 @@ msgstr "" msgid "string index out of range" msgstr "" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "" @@ -2034,8 +2033,8 @@ msgstr "" msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "" @@ -2072,29 +2071,29 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 msgid "Invalid voice count" msgstr "" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 msgid "Invalid channel count" msgstr "" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 msgid "Sample rate must be positive" msgstr "" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 msgid "bits_per_sample must be 8 or 16" msgstr "" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" msgstr "" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "" @@ -2103,51 +2102,51 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, c-format msgid "Address must be %d bytes long" msgstr "" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 msgid "buffer_size must be >= 1" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 msgid "Expected a Characteristic" msgstr "" @@ -2167,19 +2166,19 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 msgid "name must be a string" msgstr "" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2199,19 +2198,19 @@ msgstr "" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "" -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" @@ -2237,7 +2236,7 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 msgid "y should be an int" msgstr "" @@ -2253,45 +2252,78 @@ msgstr "" msgid "color should be an int" msgstr "" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 msgid "Group must have size at least 1" msgstr "" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 msgid "color buffer must be a buffer or int" msgstr "" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/displayio/Shape.c:96 +msgid "end_x should be an int" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:49 msgid "position must be 2-tuple" msgstr "" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 msgid "unsupported bitmap type" msgstr "" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -2303,15 +2335,15 @@ msgstr "" msgid "expected a DigitalInOut" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 msgid "can't convert address to int" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "" @@ -2353,29 +2385,29 @@ msgstr "" msgid "No hardware random available" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 msgid "" "PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:195 +#: shared-bindings/pulseio/PWMOut.c:193 msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "" @@ -2541,11 +2573,19 @@ msgstr "" msgid "row must be packed and word aligned" msgstr "" +#: shared-module/displayio/Display.c:62 +msgid "Unsupported display bus type" +msgstr "" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 msgid "Group empty" msgstr "" @@ -2563,6 +2603,19 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/displayio/Shape.c:60 +msgid "y value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:63 +msgid "x value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "" @@ -2588,6 +2641,18 @@ msgstr "" msgid "USB Error" msgstr "" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "" diff --git a/locale/es.po b/locale/es.po index 1278e92cbdce9..8dd8ef920091c 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -152,11 +152,11 @@ msgstr "argumentos inválidos" msgid "script compilation not supported" msgstr "script de compilación no soportado" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr " salida:\n" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -164,28 +164,28 @@ msgstr "" "Auto-reload habilitado. Simplemente guarda los archivos via USB para " "ejecutarlos o entra al REPL para desabilitarlos.\n" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Ejecutando en modo seguro! La auto-recarga esta deshabilitada.\n" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "Auto-recarga deshabilitada.\n" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "ADVERTENCIA: El nombre de archivo de tu código tiene dos extensiones\n" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Presiona cualquier tecla para entrar al REPL. Usa CTRL-D para recargar." -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "reinicio suave\n" @@ -204,18 +204,6 @@ msgstr "calibration es de solo lectura" msgid "calibration is out of range" msgstr "calibration esta fuera de rango" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "Sin bus I2C por defecto" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "Sin bus SPI por defecto" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "Sin bus UART por defecto" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -332,7 +320,7 @@ msgid "Not enough pins available" msgstr "No hay suficientes pines disponibles" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -380,6 +368,18 @@ msgstr "Sin pin TX" msgid "Cannot get pull while in output mode" msgstr "No puede ser pull mientras este en modo de salida" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +#, fuzzy +msgid "Data 0 pin must be byte aligned" +msgstr "graphic debe ser 2048 bytes de largo" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC ya está siendo utilizado" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -897,48 +897,48 @@ msgstr "No se sabe cómo pasar objeto a función nativa" msgid "[addrinfo error %d]" msgstr "[addrinfo error %d]" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "la función no tiene argumentos por palabra clave" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "la función toma %d argumentos posicionales pero le fueron dados %d" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "a la función le hacen falta %d argumentos posicionales requeridos" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "la función esperaba minimo %d argumentos, tiene %d" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "argumento '%q' requerido" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "argumento posicional adicional dado" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "argumento(s) por palabra clave adicionales fueron dados" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "argumento número/tipos no coinciden" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" "argumento(s) por palabra clave aún no implementados - usa argumentos " "normales en su lugar" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() toma %d argumentos posicionales pero %d fueron dados" @@ -950,11 +950,11 @@ msgstr "argumento por palabra clave inesperado" msgid "keywords must be strings" msgstr "palabras clave deben ser strings" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "la función tiene múltiples valores para el argumento '%q'" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "argumento por palabra clave inesperado '%q'" @@ -1546,11 +1546,11 @@ msgstr "lleno" msgid "empty" msgstr "vacío" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "popitem(): diccionario vacío" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "la secuencia de actualizacion del dict tiene una longitud incorrecta" @@ -1731,7 +1731,9 @@ msgstr "atributos aún no soportados" #: py/objstr.c:1079 msgid "" "can't switch from manual field specification to automatic field numbering" -msgstr "no se puede cambiar de especificación de campo manual a numeración automática de campos" +msgstr "" +"no se puede cambiar de especificación de campo manual a numeración " +"automática de campos" #: py/objstr.c:1171 msgid "invalid format specifier" @@ -1796,7 +1798,8 @@ msgstr "carácter no soportado '%c' (0x%x) en índice %d" #: py/objstr.c:1577 msgid "not all arguments converted during string formatting" -msgstr "no todos los argumentos fueron convertidos durante el formato de string" +msgstr "" +"no todos los argumentos fueron convertidos durante el formato de string" #: py/objstr.c:2102 msgid "can't convert to str implicitly" @@ -1815,69 +1818,69 @@ msgstr "índices de string deben ser enteros, no %s" msgid "string index out of range" msgstr "string index fuera de rango" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "__init__() deberia devolver None" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "__init__() deberia devolver None, no '%s'" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "atributo no legible" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "objeto no puede ser llamado" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "objeto '%s' no puede ser llamado" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "type acepta 1 o 3 argumentos" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "no se puede crear instancia" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "no se pueden crear '%q' instancias" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "no se puede agregar un método a una clase ya subclasificada" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "type no es un tipo de base aceptable" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "type '%q' no es un tipo de base aceptable" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "herencia multiple no soportada" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "primer argumento para super() debe ser de tipo" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "issubclass() arg 2 debe ser una clase o tuple de clases" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 debe ser una clase" @@ -2075,8 +2078,8 @@ msgstr "chars buffer muy pequeño" msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "AnalogOut es solo de 16 bits. Value debe ser menos a 65536." -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "" @@ -2115,23 +2118,23 @@ msgstr "" "el buffer de destino debe ser un bytearray o array de tipo 'B' para " "bit_depth = 8" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 msgid "Invalid voice count" msgstr "Cuenta de voces inválida" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 msgid "Invalid channel count" msgstr "Cuenta de canales inválida" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 msgid "Sample rate must be positive" msgstr "Sample rate debe ser positivo" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample debe ser 8 o 16" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2139,7 +2142,7 @@ msgstr "" "sample_source buffer debe ser un bytearray o un array de tipo 'h', 'H', 'b' " "o'B'" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "buffer debe de ser un objeto bytes-like" @@ -2148,53 +2151,53 @@ msgstr "buffer debe de ser un objeto bytes-like" msgid "file must be a file opened in byte mode" msgstr "el archivo deberia ser una archivo abierto en modo byte" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "La función requiere lock" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "Buffer debe ser de longitud 1 como minimo" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "Polaridad inválida" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "Fase inválida" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "Numero inválido de bits" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "palette debe ser 32 bytes de largo" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 #, fuzzy msgid "Expected a UUID" msgstr "Se espera un %q" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 #, fuzzy msgid "buffer_size must be >= 1" msgstr "los buffers deben de tener la misma longitud" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 #, fuzzy msgid "Expected a Characteristic" msgstr "No se puede agregar la Característica." @@ -2215,20 +2218,20 @@ msgstr "No se puede cambiar el nombre en modo Central" msgid "Can't advertise in Central mode" msgstr "" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 #, fuzzy msgid "name must be a string" msgstr "palabras clave deben ser strings" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2249,19 +2252,19 @@ msgstr "buffer debe de ser un objeto bytes-like" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "La función requiere lock" -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "bits deben ser 7, 8 o 9" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "stop debe ser 1 o 2" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" @@ -2287,7 +2290,7 @@ msgstr "Pull no se usa cuando la dirección es output." msgid "Unsupported pull value." msgstr "valor pull no soportado." -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 msgid "y should be an int" msgstr "y deberia ser un int" @@ -2303,45 +2306,80 @@ msgstr "row data debe ser un buffer" msgid "color should be an int" msgstr "color deberia ser un int" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "displayio todavia esta en desarrollo" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 msgid "Group must have size at least 1" msgstr "Group debe tener size de minimo 1" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "color buffer deberia ser un bytearray o array de tipo 'b' o 'B'" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 msgid "color must be between 0x000000 and 0xffffff" msgstr "color debe estar entre 0x000000 y 0xffffff" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 msgid "color buffer must be a buffer or int" msgstr "color buffer deber ser un buffer o un int" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 msgid "palette_index should be an int" msgstr "palette_index deberia ser un int" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +#, fuzzy +msgid "start_x should be an int" +msgstr "y deberia ser un int" + +#: shared-bindings/displayio/Shape.c:96 +#, fuzzy +msgid "end_x should be an int" +msgstr "y deberia ser un int" + +#: shared-bindings/displayio/Sprite.c:49 msgid "position must be 2-tuple" msgstr "posición debe ser 2-tuple" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 msgid "unsupported bitmap type" msgstr "tipo de bitmap no soportado" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader debe ser displayio.Palette o displayio.ColorConverter" @@ -2353,15 +2391,15 @@ msgstr "muchos argumentos" msgid "expected a DigitalInOut" msgstr "se espera un DigitalInOut" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 msgid "can't convert address to int" msgstr "no se puede convertir address a int" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "address fuera de límites" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "addresses esta vacío" @@ -2403,29 +2441,29 @@ msgstr "Bytes debe estar entre 0 y 255." msgid "No hardware random available" msgstr "No hay hardware random disponible" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 msgid "" "PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:195 +#: shared-bindings/pulseio/PWMOut.c:193 msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "No se puede eliminar valores" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "indice debe ser int" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "Solo-lectura" @@ -2593,11 +2631,20 @@ msgstr "Solo se admiten bit maps de color de 8 bits o menos" msgid "row must be packed and word aligned" msgstr "la fila debe estar empacada y la palabra alineada" +#: shared-module/displayio/Display.c:62 +#, fuzzy +msgid "Unsupported display bus type" +msgstr "tipo de bitmap no soportado" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "Group lleno" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 msgid "Group empty" msgstr "Group vacío" @@ -2615,6 +2662,21 @@ msgstr "Solo formato Windows, BMP sin comprimir soportado %d" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "Solo color verdadero (24 bpp o superior) BMP admitido %x" +#: shared-module/displayio/Shape.c:60 +#, fuzzy +msgid "y value out of bounds" +msgstr "address fuera de límites" + +#: shared-module/displayio/Shape.c:63 +#, fuzzy +msgid "x value out of bounds" +msgstr "address fuera de límites" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "No se puede volver a montar '/' cuando el USB esta activo." @@ -2640,6 +2702,18 @@ msgstr "USB ocupado" msgid "USB Error" msgstr "Error USB" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "Sin bus I2C por defecto" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "Sin bus SPI por defecto" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "Sin bus UART por defecto" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "Solicitaste iniciar en modo seguro por " @@ -2663,7 +2737,8 @@ msgid "" " with the contents of your CIRCUITPY drive and this message:\n" msgstr "" "Parece que nuestro código de CircuitPython ha fallado con fuerza. Whoops!\n" -"Por favor, crea un issue en https://github.com/adafruit/circuitpython/issues\n" +"Por favor, crea un issue en https://github.com/adafruit/circuitpython/" +"issues\n" " con el contenido de su unidad CIRCUITPY y este mensaje:\n" #: supervisor/shared/safe_mode.c:111 @@ -2688,8 +2763,8 @@ msgid "" msgstr "" "La alimentación del microcontrolador cayó. Por favor asegurate de que tu " "fuente de alimentación provee\n" -"suficiente energia para todo el circuito y presiona el botón de reset (despues" -"de expulsar CIRCUITPY).\n" +"suficiente energia para todo el circuito y presiona el botón de reset " +"(despuesde expulsar CIRCUITPY).\n" #: supervisor/shared/safe_mode.c:120 msgid "" @@ -2705,8 +2780,11 @@ msgid "" "The reset button was pressed while booting CircuitPython. Press again to " "exit safe mode.\n" msgstr "" -"El botón reset fue presionado mientras arrancaba CircuitPython. Presiona otra" -" vez para salir del modo seguro.\n" +"El botón reset fue presionado mientras arrancaba CircuitPython. Presiona " +"otra vez para salir del modo seguro.\n" + +#~ msgid "Wrong address length" +#~ msgstr "Longitud de address erronea" #~ msgid "Invalid UUID string length" #~ msgstr "Longitud de string UUID inválida" @@ -2714,17 +2792,34 @@ msgstr "" #~ msgid "Invalid UUID parameter" #~ msgstr "Parámetro UUID inválido" -#~ msgid "Wrong address length" -#~ msgstr "Longitud de address erronea" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." #~ msgid "Wrong number of bytes provided" #~ msgstr "Numero erroneo de bytes dados" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#, fuzzy +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " +#~ "unidad de almacenamiento CIRCUITPY:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "suficiente poder para todo el circuito y presiona reset (después de " +#~ "expulsar CIRCUITPY).\n" #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" @@ -2736,34 +2831,14 @@ msgstr "" #~ msgid "Can not encode UUID, to check length." #~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." + #~ msgid "Can not query for the device address." #~ msgstr "No se puede consultar la dirección del dispositivo." -#, fuzzy -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " -#~ "unidad de almacenamiento CIRCUITPY:\n" - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." - -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de Servicio inválido" - #~ msgid "Can not add Service." #~ msgstr "No se puede agregar el Servicio." #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "No se pueden establecer los parámetros PPCP." - -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "suficiente poder para todo el circuito y presiona reset (después de " -#~ "expulsar CIRCUITPY).\n" diff --git a/locale/fil.po b/locale/fil.po index 5daa673f70058..59c4150665b0a 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -151,11 +151,11 @@ msgstr "mali ang mga argumento" msgid "script compilation not supported" msgstr "script kompilasyon hindi supportado" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr " output:\n" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,29 +163,29 @@ msgstr "" "Ang awtomatikong pag re-reload ay ON. i-save lamang ang mga files sa USB " "para patakbuhin sila o pasukin ang REPL para i-disable ito.\n" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Tumatakbo sa safe mode! Awtomatikong pag re-reload ay OFF.\n" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "Awtomatikong pag re-reload ay OFF.\n" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "BABALA: Ang pangalan ng file ay may dalawang extension\n" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Pindutin ang anumang key upang pumasok sa REPL. Gamitin ang CTRL-D upang i-" "reload." -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "malambot na reboot\n" @@ -202,18 +202,6 @@ msgstr "pagkakalibrate ay basahin lamang" msgid "calibration is out of range" msgstr "kalibrasion ay wala sa sakop" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "Walang default na I2C bus" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "Walang default SPI bus" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "Walang default UART bus" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -330,7 +318,7 @@ msgid "Not enough pins available" msgstr "Hindi sapat ang magagamit na pins" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -378,6 +366,18 @@ msgstr "Walang TX pin" msgid "Cannot get pull while in output mode" msgstr "Hindi makakakuha ng pull habang nasa output mode" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +#, fuzzy +msgid "Data 0 pin must be byte aligned" +msgstr "graphic ay dapat 2048 bytes ang haba" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "Ginagamit na ang DAC" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -898,49 +898,49 @@ msgstr "Hindi alam ipasa ang object sa native function" msgid "[addrinfo error %d]" msgstr "[addrinfo error %d]" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "ang function ay hindi kumukuha ng mga argumento ng keyword" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" "ang function ay kumuhuha ng %d positional arguments ngunit %d ang ibinigay" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "function kulang ng %d required na positional arguments" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "function na inaasahang %d ang argumento, ngunit %d ang nakuha" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "'%q' argument kailangan" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "dagdag na positional argument na ibinigay" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "dagdag na keyword argument na ibinigay" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "hindi tugma ang argument num/types" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" "kindi pa ipinapatupad ang (mga) argument(s) ng keyword - gumamit ng normal " "args" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "" "Ang %q() ay kumukuha ng %d positional arguments pero %d lang ang binigay" @@ -953,11 +953,11 @@ msgstr "hindi inaasahang argumento ng keyword" msgid "keywords must be strings" msgstr "ang keywords dapat strings" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "ang function ay nakakuha ng maraming values para sa argument '%q'" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "hindi inaasahang argumento ng keyword na '%q'" @@ -1548,11 +1548,11 @@ msgstr "puno" msgid "empty" msgstr "walang laman" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "popitem(): dictionary ay walang laman" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "may mali sa haba ng dict update sequence" @@ -1819,70 +1819,70 @@ msgstr "ang indeks ng string ay dapat na integer, hindi %s" msgid "string index out of range" msgstr "indeks ng string wala sa sakop" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "__init __ () dapat magbalik na None" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "__init__() dapat magbalink na None, hindi '%s'" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "hindi mabasa ang attribute" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "hindi matatawag ang object" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "'%s' object hindi matatawag" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "type kumuhuha ng 1 o 3 arguments" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "hindi magawa ang instance" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "hindi magawa '%q' instances" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "" "hindi madagdag ang isang espesyal na method sa isang na i-subclass na class" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "hindi puede ang type para sa base type" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "hindi maari ang type na '%q' para sa base type" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "maraming inhertance hindi sinusuportahan" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "maraming bases ay may instance lay-out conflict" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "unang argument ng super() ay dapat type" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "issubclass() arg 2 ay dapat na class o tuple ng classes" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 ay dapat na class" @@ -2080,8 +2080,8 @@ msgstr "masyadong maliit ang buffer" msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "AnalogOut ay 16 bits. Value ay dapat hindi hihigit pa sa 65536." -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "Hindi playing" @@ -2123,23 +2123,23 @@ msgstr "" "ang destination buffer ay dapat na isang bytearray o array ng uri na 'B' " "para sa bit_depth = 8" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 msgid "Invalid voice count" msgstr "Maling bilang ng voice" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 msgid "Invalid channel count" msgstr "Maling bilang ng channel" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 msgid "Sample rate must be positive" msgstr "Sample rate ay dapat positibo" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample ay dapat 8 o 16" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2147,7 +2147,7 @@ msgstr "" "ang sample_source buffer ay dapat na isang bytearray o array ng uri na 'h', " "'H', 'b' o'B'" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "buffer ay dapat bytes-like object" @@ -2156,53 +2156,53 @@ msgstr "buffer ay dapat bytes-like object" msgid "file must be a file opened in byte mode" msgstr "file ay dapat buksan sa byte mode" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "Function nangangailangan ng lock" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "Buffer dapat ay hindi baba sa 1 na haba" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "Mali ang polarity" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "Mali ang phase" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "Mali ang bilang ng bits" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "aarehas na haba dapat ang buffer slices" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "ang palette ay dapat 32 bytes ang haba" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 #, fuzzy msgid "Expected a UUID" msgstr "Umasa ng %q" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 #, fuzzy msgid "buffer_size must be >= 1" msgstr "aarehas na haba dapat ang buffer slices" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 #, fuzzy msgid "Expected a Characteristic" msgstr "Hindi mabasa and Characteristic." @@ -2223,20 +2223,20 @@ msgstr "Hindi mapalitan ang pangalan sa Central mode" msgid "Can't advertise in Central mode" msgstr "Hindi ma advertise habang nasa Central mode" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 #, fuzzy msgid "name must be a string" msgstr "ang keywords dapat strings" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2257,19 +2257,19 @@ msgstr "buffer ay dapat bytes-like object" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "Kailangan ng lock ang function." -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "bits ay dapat 7, 8 o 9" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "stop dapat 1 o 2" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "timeout >100 (units ay seconds, hindi na msecs)" @@ -2295,7 +2295,7 @@ msgstr "Pull hindi ginagamit kapag ang direksyon ay output." msgid "Unsupported pull value." msgstr "Hindi suportado ang pull value." -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 msgid "y should be an int" msgstr "y ay dapat int" @@ -2311,45 +2311,80 @@ msgstr "row data ay dapat na buffer" msgid "color should be an int" msgstr "color ay dapat na int" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "displayio ay nasa gitna ng konstruksiyon" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 msgid "Group must have size at least 1" msgstr "Group dapat ay hindi baba sa 1 na haba" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "ang color buffer ay dapat bytearray o array na type ‘b’ or ‘B’" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "color buffer ay dapat na 3 bytes (RGB) o 4 bytes (RGB + pad byte)" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 msgid "color must be between 0x000000 and 0xffffff" msgstr "color ay dapat mula sa 0x000000 hangang 0xffffff" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 msgid "color buffer must be a buffer or int" msgstr "color buffer ay dapat buffer or int" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 msgid "palette_index should be an int" msgstr "palette_index ay dapat na int" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +#, fuzzy +msgid "start_x should be an int" +msgstr "y ay dapat int" + +#: shared-bindings/displayio/Shape.c:96 +#, fuzzy +msgid "end_x should be an int" +msgstr "y ay dapat int" + +#: shared-bindings/displayio/Sprite.c:49 msgid "position must be 2-tuple" msgstr "position ay dapat 2-tuple" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 msgid "unsupported bitmap type" msgstr "Hindi supportadong tipo ng bitmap" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader ay dapat displayio.Palette o displayio.ColorConverter" @@ -2361,15 +2396,15 @@ msgstr "masyadong maraming argumento" msgid "expected a DigitalInOut" msgstr "umasa ng DigitalInOut" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 msgid "can't convert address to int" msgstr "hindi ma i-convert ang address sa INT" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "wala sa sakop ang address" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "walang laman ang address" @@ -2411,30 +2446,30 @@ msgstr "Sa gitna ng 0 o 255 dapat ang bytes." msgid "No hardware random available" msgstr "Walang magagamit na hardware random" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 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:195 +#: shared-bindings/pulseio/PWMOut.c:193 msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" "PWM frequency hindi writable kapag variable_frequency ay False sa pag buo." -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "Hindi mabura ang values" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "Hindi suportado ang Slices" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "index ay dapat int" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "Basahin-lamang" @@ -2602,11 +2637,20 @@ msgstr "Tanging bit maps na may 8 bit color o mas mababa ang supportado" msgid "row must be packed and word aligned" msgstr "row ay dapat packed at ang word nakahanay" +#: shared-module/displayio/Display.c:62 +#, fuzzy +msgid "Unsupported display bus type" +msgstr "Hindi supportadong tipo ng bitmap" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "Puno ang group" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 msgid "Group empty" msgstr "Walang laman ang group" @@ -2624,6 +2668,21 @@ msgstr "Tanging Windows format, uncompressed BMP lamang ang supportado %d" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "Dapat true color (24 bpp o mas mataas) BMP lamang ang supportado %x" +#: shared-module/displayio/Shape.c:60 +#, fuzzy +msgid "y value out of bounds" +msgstr "wala sa sakop ang address" + +#: shared-module/displayio/Shape.c:63 +#, fuzzy +msgid "x value out of bounds" +msgstr "wala sa sakop ang address" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "Hindi ma-remount '/' kapag aktibo ang USB." @@ -2649,6 +2708,18 @@ msgstr "Busy ang USB" msgid "USB Error" msgstr "May pagkakamali ang USB" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "Walang default na I2C bus" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "Walang default SPI bus" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "Walang default UART bus" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "Ikaw ang humiling sa safe mode sa pamamagitan ng " @@ -2718,23 +2789,42 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" +#~ msgid "Wrong address length" +#~ msgstr "Mali ang address length" + #~ msgid "Invalid UUID string length" #~ msgstr "Mali ang UUID string length" #~ msgid "Invalid UUID parameter" #~ msgstr "Mali ang UUID parameter" -#~ msgid "Wrong address length" -#~ msgstr "Mali ang address length" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." + +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." #~ msgid "Wrong number of bytes provided" #~ msgstr "Mali ang bilang ng bytes" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " +#~ "drive:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " +#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" @@ -2747,33 +2837,14 @@ msgstr "" #~ msgid "Can not encode UUID, to check length." #~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." + #~ msgid "Can not query for the device address." #~ msgstr "Hindi maaaring mag-query para sa address ng device." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " -#~ "drive:\n" - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." - -#~ msgid "Invalid Service type" -#~ msgstr "Mali ang tipo ng serbisyo" - #~ msgid "Can not add Service." #~ msgstr "Hindi maidaragdag ang serbisyo." #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Hindi ma-set ang PPCP parameters." - -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " -#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" diff --git a/locale/fr.po b/locale/fr.po index b27cfeb7996ce..4ef9d9f872b62 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: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -150,11 +150,11 @@ msgstr "arguments invalides" msgid "script compilation not supported" msgstr "compilation de script non supporté" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr " sortie:\n" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -162,27 +162,27 @@ msgstr "" "Auto-chargement activé. Copiez simplement les fichiers en USB pour les " "lancer ou entrez sur REPL pour le désactiver.\n" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Mode sans-échec. Auto-rechargement désactivé.\n" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "Auto-rechargement désactivé.\n" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "Mode sans-échec! Le code sauvegardé ne s'éxecute pas.\n" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "ATTENTION: le nom de fichier de votre code a deux extensions\n" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger." -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "redémarrage logiciel\n" @@ -199,18 +199,6 @@ msgstr "calibration en lecture seule" msgid "calibration is out of range" msgstr "calibration hors gamme" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "Pas de bus I2C par défaut" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "Pas de bus SPI par défaut" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "Pas de bus UART par défaut" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -327,7 +315,7 @@ msgid "Not enough pins available" msgstr "Pas assez de broches disponibles" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -375,6 +363,18 @@ msgstr "Pas de broche TX" msgid "Cannot get pull while in output mode" msgstr "Ne peux être tiré ('pull') en mode 'output'" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +#, fuzzy +msgid "Data 0 pin must be byte aligned" +msgstr "le graphic doit être long de 2048 octets" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC déjà utilisé" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -900,47 +900,47 @@ msgstr "Ne sais pas comment passer l'objet à une fonction native" msgid "[addrinfo error %d]" msgstr "" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "la fonction ne prend pas d'arguments nommés" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "la fonction prend %d argument(s) mais %d ont été donné(s)" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "il manque %d arguments obligatoires à la fonction" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "la fonction attendait au plus %d arguments, reçu %d" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "'%q' argument requis" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "argument positionnel donné en plus" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "argument nommé donné en plus" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "argument num/types ne correspond pas" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" "argument(s) nommé(s) pas encore implémenté - utilisez les arguments normaux" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() prend %d arguments mais %d ont été donnés" @@ -952,11 +952,11 @@ msgstr "argument nommé imprévu" msgid "keywords must be strings" msgstr "les noms doivent être des chaînes de caractère" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "la fonction a reçu plusieurs valeurs pour l'argument '%q'" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "argument nommé '%q' imprévu" @@ -1546,11 +1546,11 @@ msgstr "plein" msgid "empty" msgstr "vide" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "popitem(): dictionnaire vide" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "la séquence de mise à jour de dict a une mauvaise longueur" @@ -1818,71 +1818,71 @@ msgstr "les indices de chaîne de caractère doivent être des entiers, pas %s" msgid "string index out of range" msgstr "index de chaîne hors gamme" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "__init__() doit retourner None" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "__init__() doit retourner None, pas '%s'" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "attribut illisible" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "objet non appelable" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "objet '%s' non appelable" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "le type prend 1 ou 3 arguments" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "ne peut pas créer une instance" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "ne peut pas créer une instance de '%q'" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "" "impossible d'ajouter une méthode spécial à une classe déjà sous-classée" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "le type n'est pas un type de base accepté" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "le type '%q' n'est pas un type de base accepté" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "héritage multiple non supporté" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "de multiple bases ont un conflit de lay-out d'instance" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "le premier argument de super() doit être un type" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" "l'argument 2 de issubclass() doit être une classe ou un tuple de classes" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "l'argument 1 de issubclass() doit être une classe" @@ -2082,8 +2082,8 @@ msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" "AnalogOut est seulement 16 bits. Les valeurs doivent être inf. à 65536." -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "Ne joue pas" @@ -2122,26 +2122,26 @@ msgid "" msgstr "" "le tampon de destination doit être un tableau de type 'B' pour bit_depth = 8" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 #, fuzzy msgid "Invalid voice count" msgstr "Type de service invalide" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 msgid "Invalid channel count" msgstr "" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 #, fuzzy msgid "Sample rate must be positive" msgstr "le taux d'échantillonage doit être positif" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "bits doivent être 8 ou 16" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2149,7 +2149,7 @@ msgstr "" "le tampon de sample_source doit être un bytearray ou un tableau de type " "'h','H', 'b' ou 'B'" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "le tampon doit être un objet bytes-like" @@ -2158,53 +2158,53 @@ msgstr "le tampon doit être un objet bytes-like" msgid "file must be a file opened in byte mode" msgstr "le fichier doit être un fichier ouvert en mode 'byte'" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "La fonction nécessite un verrou" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "Le tampon doit être de longueur au moins 1" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "Polarité invalide" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "Phase invalide" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "Nombre de bits invalide" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "les slices de tampon doivent être de longueurs égales" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "la palette doit être longue de 32 octets" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 #, fuzzy msgid "Expected a UUID" msgstr "Attendu : %q" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 #, fuzzy msgid "buffer_size must be >= 1" msgstr "les slices de tampon doivent être de longueurs égales" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 #, fuzzy msgid "Expected a Characteristic" msgstr "Impossible d'ajouter la Characteristic." @@ -2225,20 +2225,20 @@ msgstr "Modification du nom impossible en mode Central" msgid "Can't advertise in Central mode" msgstr "" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 #, fuzzy msgid "name must be a string" msgstr "les noms doivent être des chaînes de caractère" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2259,19 +2259,19 @@ msgstr "le tampon doit être un objet bytes-like" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "La fonction nécessite un verrou." -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "bits doivent être 7, 8 ou 9" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "stop doit être 1 ou 2" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "timeout >100 (exprimé en secondes, pas en ms)" @@ -2297,7 +2297,7 @@ msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'." msgid "Unsupported pull value." msgstr "Valeur de tirage 'pull' non supportée." -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 #, fuzzy msgid "y should be an int" msgstr "y doit être un entier (int)" @@ -2318,53 +2318,88 @@ msgstr "les données de ligne doivent être un tampon" msgid "color should be an int" msgstr "la couleur doit être un entier (int)" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "displayio est en cours de développement" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 #, fuzzy msgid "Group must have size at least 1" msgstr "Le tampon doit être de longueur au moins 1" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 #, fuzzy msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" "le tampon de couleur doit être un bytearray ou un tableau de type 'b' ou 'B'" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "le tampon de couleur doit faire 3 octets (RVB) ou 4 (RVB + pad byte)" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 #, fuzzy msgid "color must be between 0x000000 and 0xffffff" msgstr "la couleur doit être entre 0x000000 et 0xffffff" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 #, fuzzy msgid "color buffer must be a buffer or int" msgstr "le tampon de couleur doit être un tampon ou un entier" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 #, fuzzy msgid "palette_index should be an int" msgstr "palette_index devrait être un entier (int)'" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +#, fuzzy +msgid "start_x should be an int" +msgstr "y doit être un entier (int)" + +#: shared-bindings/displayio/Shape.c:96 +#, fuzzy +msgid "end_x should be an int" +msgstr "y doit être un entier (int)" + +#: shared-bindings/displayio/Sprite.c:49 #, fuzzy msgid "position must be 2-tuple" msgstr "position doit être un 2-tuple" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 #, fuzzy msgid "unsupported bitmap type" msgstr "type de bitmap non supporté" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" "pixel_shader doit être un objet displayio.Palette ou displayio.ColorConverter" @@ -2377,16 +2412,16 @@ msgstr "trop d'arguments" msgid "expected a DigitalInOut" msgstr "objet DigitalInOut attendu" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 #, fuzzy msgid "can't convert address to int" msgstr "ne peut convertir %s en entier int" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "adresse hors limites" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "adresses vides" @@ -2428,14 +2463,14 @@ msgstr "Les octets 'bytes' doivent être entre 0 et 255" msgid "No hardware random available" msgstr "Pas de source matérielle d'aléa disponible" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 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:195 +#: shared-bindings/pulseio/PWMOut.c:193 #, fuzzy msgid "" "PWM frequency not writable when variable_frequency is False on construction." @@ -2443,19 +2478,19 @@ msgstr "" "La fréquence de PWM n'est pas modifiable quand variable_frequency est False " "à la construction." -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "Impossible de supprimer les valeurs" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "Slices non supportées" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "l'index doit être un entier" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "Lecture seule" @@ -2624,11 +2659,20 @@ msgstr "Seules les bitmaps de 8bits par couleur ou moins sont supportées" msgid "row must be packed and word aligned" msgstr "" +#: shared-module/displayio/Display.c:62 +#, fuzzy +msgid "Unsupported display bus type" +msgstr "type de bitmap non supporté" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "Groupe plein" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 #, fuzzy msgid "Group empty" msgstr "Groupe vide" @@ -2648,6 +2692,21 @@ msgstr "Seul les BMP non-compressé au format Windows sont supportés %d" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "Seul les BMP 24bits ou plus sont supportés %x" +#: shared-module/displayio/Shape.c:60 +#, fuzzy +msgid "y value out of bounds" +msgstr "adresse hors limites" + +#: shared-module/displayio/Shape.c:63 +#, fuzzy +msgid "x value out of bounds" +msgstr "adresse hors limites" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "'/' ne peut être remonté quand l'USB est actif." @@ -2673,6 +2732,18 @@ msgstr "USB occupé" msgid "USB Error" msgstr "Erreur USB" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "Pas de bus I2C par défaut" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "Pas de bus SPI par défaut" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "Pas de bus UART par défaut" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "Vous avez demandé à démarrer en mode sans-échec par " @@ -2747,27 +2818,37 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer denouveau pour quitter de le mode sans-échec.\n" +#~ msgid "Wrong address length" +#~ msgstr "Mauvaise longueur d'adresse" + #~ msgid "Invalid UUID string length" #~ msgstr "Longeur de chaîne UUID invalide" #~ msgid "Invalid UUID parameter" #~ msgstr "Paramètre UUID invalide" -#~ msgid "Wrong address length" -#~ msgstr "Mauvaise longueur d'adresse" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" + +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." + +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" #, fuzzy #~ msgid "Wrong number of bytes provided" #~ msgstr "mauvais nombre d'octets fourni'" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" #, fuzzy #~ msgid "value_size must be power of two" @@ -2783,27 +2864,17 @@ msgstr "" #~ "assez de puissance pour l'ensemble du circuit et appuyez sur " #~ "'reset' (après avoir éjecter CIRCUITPY).\n" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" + #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "la palette doit être une displayio.Palette" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." - -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" - -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." - #~ msgid "Can not apply device name in the stack." #~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" #~ msgid "Can not query for the device address." #~ msgstr "Impossible d'obtenir l'adresse du périphérique" - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" - -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" diff --git a/locale/it_IT.po b/locale/it_IT.po index 9b54d5dc9ae3c..47aff51660043 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -151,11 +151,11 @@ msgstr "argomenti non validi" msgid "script compilation not supported" msgstr "compilazione dello scrip non suportata" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr " output:\n" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,28 +163,28 @@ msgstr "" "L'auto-reload è attivo. Salva i file su USB per eseguirli o entra nel REPL " "per disabilitarlo.\n" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Modalità sicura in esecuzione! Auto-reload disattivato.\n" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "Auto-reload disattivato.\n" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "Modalità sicura in esecuzione! Codice salvato non in esecuzione.\n" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "ATTENZIONE: Il nome del sorgente ha due estensioni\n" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Premi un qualunque tasto per entrare nel REPL. Usa CTRL-D per ricaricare." -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "soft reboot\n" @@ -201,18 +201,6 @@ msgstr "la calibrazione è in sola lettura" msgid "calibration is out of range" msgstr "la calibrazione è fuori intervallo" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "Nessun bus I2C predefinito" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "Nessun bus SPI predefinito" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "Nessun bus UART predefinito" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -331,7 +319,7 @@ msgid "Not enough pins available" msgstr "Non sono presenti abbastanza pin" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -379,6 +367,18 @@ msgstr "Nessun pin TX" msgid "Cannot get pull while in output mode" msgstr "" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +#, fuzzy +msgid "Data 0 pin must be byte aligned" +msgstr "graphic deve essere lunga 2048 byte" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC già in uso" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -901,49 +901,49 @@ msgstr "Non so come passare l'oggetto alla funzione nativa" msgid "[addrinfo error %d]" msgstr "[errore addrinfo %d]" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "la funzione non prende argomenti nominati" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" "la funzione prende %d argomenti posizionali ma ne sono stati forniti %d" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "mancano %d argomenti posizionali obbligatori alla funzione" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "la funzione prevede al massimo %d argmoneti, ma ne ha ricevuti %d" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "'%q' argomento richiesto" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "argomenti posizonali extra dati" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "argomento nominato aggiuntivo fornito" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "discrepanza di numero/tipo di argomenti" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" "argomento(i) nominati non ancora implementati - usare invece argomenti " "normali" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() prende %d argomenti posizionali ma ne sono stati forniti %d" @@ -955,11 +955,11 @@ msgstr "argomento nominato inaspettato" msgid "keywords must be strings" msgstr "argomenti nominati devono essere stringhe" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "la funzione ha ricevuto valori multipli per l'argomento '%q'" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "argomento nominato '%q' inaspettato" @@ -1546,11 +1546,11 @@ msgstr "pieno" msgid "empty" msgstr "vuoto" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "popitem(): il dizionario è vuoto" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "sequanza di aggiornamento del dizionario ha la lunghezza errata" @@ -1814,71 +1814,71 @@ msgstr "indici della stringa devono essere interi, non %s" msgid "string index out of range" msgstr "indice della stringa fuori intervallo" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "__init__() deve ritornare None" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "__init__() deve ritornare None, non '%s'" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "attributo non leggibile" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "tipo prende 1 o 3 argomenti" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "impossibile creare un istanza" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "creare '%q' istanze" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "il tipo non è un tipo di base accettabile" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "il tipo '%q' non è un tipo di base accettabile" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "ereditarietà multipla non supportata" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" "il secondo argomento di issubclass() deve essere una classe o una tupla di " "classi" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "il primo argomento di issubclass() deve essere una classe" @@ -2076,8 +2076,8 @@ msgstr "buffer dei caratteri troppo piccolo" msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "AnalogOut ha solo 16 bit. Il valore deve essere meno di 65536." -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "In pausa" @@ -2118,27 +2118,27 @@ msgstr "" "il buffer di destinazione deve essere un bytearray o un array di tipo 'B' " "con bit_depth = 8" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 #, fuzzy msgid "Invalid voice count" msgstr "Tipo di servizio non valido" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 #, fuzzy msgid "Invalid channel count" msgstr "Argomento non valido" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 #, fuzzy msgid "Sample rate must be positive" msgstr "STA deve essere attiva" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "i bit devono essere 7, 8 o 9" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2146,7 +2146,7 @@ msgstr "" "il buffer sample_source deve essere un bytearray o un array di tipo 'h', " "'H', 'b' o 'B'" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "" @@ -2155,53 +2155,53 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "Il buffer deve essere lungo almeno 1" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "Polarità non valida" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "Fase non valida" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "Numero di bit non valido" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "slice del buffer devono essere della stessa lunghezza" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "la palette deve essere lunga 32 byte" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 #, fuzzy msgid "Expected a UUID" msgstr "Atteso un %q" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 #, fuzzy msgid "buffer_size must be >= 1" msgstr "slice del buffer devono essere della stessa lunghezza" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 #, fuzzy msgid "Expected a Characteristic" msgstr "Non è possibile aggiungere Characteristic." @@ -2222,20 +2222,20 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 #, fuzzy msgid "name must be a string" msgstr "argomenti nominati devono essere stringhe" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2256,19 +2256,19 @@ msgstr "i buffer devono essere della stessa lunghezza" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "" -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "i bit devono essere 7, 8 o 9" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" @@ -2294,7 +2294,7 @@ msgstr "" msgid "Unsupported pull value." msgstr "Valore di pull non supportato." -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 msgid "y should be an int" msgstr "y dovrebbe essere un int" @@ -2310,47 +2310,82 @@ msgstr "valori della riga devono essere un buffer" msgid "color should be an int" msgstr "il colore deve essere un int" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 msgid "Group must have size at least 1" msgstr "Il gruppo deve avere dimensione almeno 1" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" "buffer del colore deve essere un bytearray o un array di tipo 'b' o 'B'" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" "il buffer del colore deve esseer di 3 byte (RGB) o 4 byte (RGB + pad byte)" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 msgid "color must be between 0x000000 and 0xffffff" msgstr "il colore deve essere compreso tra 0x000000 e 0xffffff" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 msgid "color buffer must be a buffer or int" msgstr "il buffer del colore deve essere un buffer o un int" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 msgid "palette_index should be an int" msgstr "palette_index deve essere un int" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +#, fuzzy +msgid "start_x should be an int" +msgstr "y dovrebbe essere un int" + +#: shared-bindings/displayio/Shape.c:96 +#, fuzzy +msgid "end_x should be an int" +msgstr "y dovrebbe essere un int" + +#: shared-bindings/displayio/Sprite.c:49 msgid "position must be 2-tuple" msgstr "position deve essere una 2-tuple" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 msgid "unsupported bitmap type" msgstr "tipo di bitmap non supportato" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader deve essere displayio.Palette o displayio.ColorConverter" @@ -2362,15 +2397,15 @@ msgstr "troppi argomenti" msgid "expected a DigitalInOut" msgstr "DigitalInOut atteso" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 msgid "can't convert address to int" msgstr "impossible convertire indirizzo in int" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "indirizzo fuori limite" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "gli indirizzi sono vuoti" @@ -2412,14 +2447,14 @@ msgstr "I byte devono essere compresi tra 0 e 255" msgid "No hardware random available" msgstr "Nessun generatore hardware di numeri casuali disponibile" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 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:195 +#: shared-bindings/pulseio/PWMOut.c:193 #, fuzzy msgid "" "PWM frequency not writable when variable_frequency is False on construction." @@ -2427,19 +2462,19 @@ msgstr "" "frequenza PWM frequency non è scrivibile quando variable_frequency è " "impostato nel costruttore a False." -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "Impossibile cancellare valori" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "Slice non supportate" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "l'indice deve essere int" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "Sola lettura" @@ -2608,11 +2643,20 @@ msgstr "Sono supportate solo bitmap con colori a 8 bit o meno" msgid "row must be packed and word aligned" msgstr "la riga deve essere compattata e allineata alla parola" +#: shared-module/displayio/Display.c:62 +#, fuzzy +msgid "Unsupported display bus type" +msgstr "tipo di bitmap non supportato" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "Gruppo pieno" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 msgid "Group empty" msgstr "Gruppo vuoto" @@ -2630,6 +2674,21 @@ msgstr "Formato solo di Windows, BMP non compresso supportato %d" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "Solo BMP true color (24 bpp o superiore) sono supportati %x" +#: shared-module/displayio/Shape.c:60 +#, fuzzy +msgid "y value out of bounds" +msgstr "indirizzo fuori limite" + +#: shared-module/displayio/Shape.c:63 +#, fuzzy +msgid "x value out of bounds" +msgstr "indirizzo fuori limite" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "Non è possibile rimontare '/' mentre l'USB è attiva." @@ -2655,6 +2714,18 @@ msgstr "USB occupata" msgid "USB Error" msgstr "Errore USB" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "Nessun bus I2C predefinito" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "Nessun bus SPI predefinito" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "Nessun bus UART predefinito" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "È stato richiesto l'avvio in modalità sicura da " @@ -2716,28 +2787,44 @@ msgid "" "exit safe mode.\n" msgstr "" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parametro UUID non valido" + #~ msgid "Invalid UUID string length" #~ msgstr "Lunghezza della stringa UUID non valida" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parametro UUID non valido" +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" #, fuzzy #~ msgid "Wrong number of bytes provided" #~ msgstr "numero di argomenti errato" -#~ msgid "Invalid Service type" -#~ msgstr "Tipo di servizio non valido" - #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." + +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " +#~ "espulso CIRCUITPY).\n" + #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" #~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " #~ "CIRCUITPY:\n" +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." + #~ msgid "Can not encode UUID, to check length." #~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." @@ -2749,27 +2836,11 @@ msgstr "" #~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " #~ "Whoops!\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." - #~ msgid "Cannot apply GAP parameters." #~ msgstr "Impossibile applicare i parametri GAP." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " -#~ "espulso CIRCUITPY).\n" - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." - -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." - -#~ msgid "Can not add Service." -#~ msgstr "Non è possibile aggiungere Service." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." #~ msgid "Can not apply device name in the stack." #~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 85fe90909cd07..e610577a1c5f9 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-10 21:32-0500\n" +"POT-Creation-Date: 2019-01-18 11:43-0800\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -151,37 +151,37 @@ msgstr "argumentos inválidos" msgid "script compilation not supported" msgstr "compilação de script não suportada" -#: main.c:150 +#: main.c:155 msgid " output:\n" msgstr " saída:\n" -#: main.c:164 main.c:237 +#: main.c:169 main.c:247 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:166 +#: main.c:171 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Rodando em modo seguro! Atualização automática está desligada.\n" -#: main.c:168 main.c:239 +#: main.c:173 main.c:249 msgid "Auto-reload is off.\n" msgstr "A atualização automática está desligada.\n" -#: main.c:182 +#: main.c:187 msgid "Running in safe mode! Not running saved code.\n" msgstr "Rodando em modo seguro! Não está executando o código salvo.\n" -#: main.c:198 +#: main.c:203 msgid "WARNING: Your code filename has two extensions\n" msgstr "AVISO: Seu arquivo de código tem duas extensões\n" -#: main.c:244 +#: main.c:254 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:407 +#: main.c:417 msgid "soft reboot\n" msgstr "" @@ -198,18 +198,6 @@ msgstr "Calibração é somente leitura" msgid "calibration is out of range" msgstr "Calibração está fora do intervalo" -#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 -msgid "No default I2C bus" -msgstr "Nenhum barramento I2C padrão" - -#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 -msgid "No default SPI bus" -msgstr "Nenhum barramento SPI padrão" - -#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 -msgid "No default UART bus" -msgstr "Nenhum barramento UART padrão" - #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" @@ -326,7 +314,7 @@ msgid "Not enough pins available" msgstr "Não há pinos suficientes disponíveis" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/SPI.c:176 #: ports/atmel-samd/common-hal/busio/UART.c:120 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:84 @@ -374,6 +362,17 @@ msgstr "Nenhum pino TX" msgid "Cannot get pull while in output mode" msgstr "" +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 +#: ports/nrf/common-hal/displayio/ParallelBus.c:43 +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 +#: ports/nrf/common-hal/displayio/ParallelBus.c:47 +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC em uso" + #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." @@ -890,46 +889,46 @@ msgstr "Não sabe como passar o objeto para a função nativa" msgid "[addrinfo error %d]" msgstr "" -#: py/argcheck.c:44 +#: py/argcheck.c:53 msgid "function does not take keyword arguments" msgstr "função não aceita argumentos de palavras-chave" -#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "função leva %d argumentos posicionais, mas apenas %d foram passadas" -#: py/argcheck.c:64 +#: py/argcheck.c:73 #, c-format msgid "function missing %d required positional arguments" msgstr "função ausente %d requer argumentos posicionais" -#: py/argcheck.c:72 +#: py/argcheck.c:81 #, c-format msgid "function expected at most %d arguments, got %d" msgstr "função esperada na maioria dos %d argumentos, obteve %d" -#: py/argcheck.c:97 +#: py/argcheck.c:106 msgid "'%q' argument required" msgstr "'%q' argumento(s) requerido(s)" -#: py/argcheck.c:122 +#: py/argcheck.c:131 msgid "extra positional arguments given" msgstr "argumentos extra posicionais passados" -#: py/argcheck.c:130 +#: py/argcheck.c:139 msgid "extra keyword arguments given" msgstr "argumentos extras de palavras-chave passados" -#: py/argcheck.c:142 +#: py/argcheck.c:151 msgid "argument num/types mismatch" msgstr "" -#: py/argcheck.c:147 +#: py/argcheck.c:156 msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c:88 py/objnamedtuple.c:108 +#: py/bc.c:88 py/objnamedtuple.c:109 msgid "%q() takes %d positional arguments but %d were given" msgstr "" @@ -941,11 +940,11 @@ msgstr "" msgid "keywords must be strings" msgstr "" -#: py/bc.c:206 py/objnamedtuple.c:138 +#: py/bc.c:206 py/objnamedtuple.c:139 msgid "function got multiple values for argument '%q'" msgstr "" -#: py/bc.c:218 py/objnamedtuple.c:130 +#: py/bc.c:218 py/objnamedtuple.c:131 msgid "unexpected keyword argument '%q'" msgstr "" @@ -1529,11 +1528,11 @@ msgstr "cheio" msgid "empty" msgstr "vazio" -#: py/objdict.c:314 +#: py/objdict.c:312 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:357 +#: py/objdict.c:355 msgid "dict update sequence has wrong length" msgstr "" @@ -1794,69 +1793,69 @@ msgstr "" msgid "string index out of range" msgstr "" -#: py/objtype.c:358 +#: py/objtype.c:368 msgid "__init__() should return None" msgstr "" -#: py/objtype.c:360 +#: py/objtype.c:370 #, c-format msgid "__init__() should return None, not '%s'" msgstr "" -#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +#: py/objtype.c:633 py/objtype.c:1287 py/runtime.c:1065 msgid "unreadable attribute" msgstr "atributo ilegível" -#: py/objtype.c:868 py/runtime.c:653 +#: py/objtype.c:878 py/runtime.c:653 msgid "object not callable" msgstr "" -#: py/objtype.c:870 py/runtime.c:655 +#: py/objtype.c:880 py/runtime.c:655 #, c-format msgid "'%s' object is not callable" msgstr "" -#: py/objtype.c:978 +#: py/objtype.c:988 msgid "type takes 1 or 3 arguments" msgstr "" -#: py/objtype.c:989 +#: py/objtype.c:999 msgid "cannot create instance" msgstr "não é possível criar instância" -#: py/objtype.c:991 +#: py/objtype.c:1001 msgid "cannot create '%q' instances" msgstr "" -#: py/objtype.c:1047 +#: py/objtype.c:1059 msgid "can't add special method to already-subclassed class" msgstr "" -#: py/objtype.c:1091 py/objtype.c:1097 +#: py/objtype.c:1103 py/objtype.c:1109 msgid "type is not an acceptable base type" msgstr "" -#: py/objtype.c:1100 +#: py/objtype.c:1112 msgid "type '%q' is not an acceptable base type" msgstr "" -#: py/objtype.c:1137 +#: py/objtype.c:1149 msgid "multiple inheritance not supported" msgstr "" -#: py/objtype.c:1164 +#: py/objtype.c:1176 msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/objtype.c:1205 +#: py/objtype.c:1217 msgid "first argument to super() must be type" msgstr "" -#: py/objtype.c:1370 +#: py/objtype.c:1382 msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: py/objtype.c:1384 +#: py/objtype.c:1396 msgid "issubclass() arg 1 must be a class" msgstr "" @@ -2052,8 +2051,8 @@ msgstr "" msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" -#: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:226 +#: shared-bindings/audiobusio/I2SOut.c:222 +#: shared-bindings/audioio/AudioOut.c:223 msgid "Not playing" msgstr "" @@ -2090,32 +2089,32 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: shared-bindings/audioio/Mixer.c:94 +#: shared-bindings/audioio/Mixer.c:91 #, fuzzy msgid "Invalid voice count" msgstr "certificado inválido" -#: shared-bindings/audioio/Mixer.c:99 +#: shared-bindings/audioio/Mixer.c:96 #, fuzzy msgid "Invalid channel count" msgstr "certificado inválido" -#: shared-bindings/audioio/Mixer.c:103 +#: shared-bindings/audioio/Mixer.c:100 msgid "Sample rate must be positive" msgstr "" -#: shared-bindings/audioio/Mixer.c:107 +#: shared-bindings/audioio/Mixer.c:104 #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "bits devem ser 8" -#: shared-bindings/audioio/RawSample.c:98 +#: shared-bindings/audioio/RawSample.c:95 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" msgstr "" -#: shared-bindings/audioio/RawSample.c:104 +#: shared-bindings/audioio/RawSample.c:101 msgid "buffer must be a bytes-like object" msgstr "" @@ -2124,53 +2123,53 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" -#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 -#: shared-bindings/busio/SPI.c:133 +#: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 +#: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" msgstr "" -#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +#: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +#: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +#: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" msgstr "Fase Inválida" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +#: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" msgstr "Número inválido de bits" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +#: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" msgstr "" -#: shared-bindings/bleio/Address.c:119 +#: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" msgstr "" -#: shared-bindings/bleio/Address.c:126 +#: shared-bindings/bleio/Address.c:122 #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "buffers devem ser o mesmo tamanho" -#: shared-bindings/bleio/Characteristic.c:81 -#: shared-bindings/bleio/Descriptor.c:93 shared-bindings/bleio/Service.c:78 +#: shared-bindings/bleio/Characteristic.c:74 +#: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 #, fuzzy msgid "Expected a UUID" msgstr "Esperado um" -#: shared-bindings/bleio/CharacteristicBuffer.c:68 +#: shared-bindings/bleio/CharacteristicBuffer.c:61 #, fuzzy msgid "buffer_size must be >= 1" msgstr "buffers devem ser o mesmo tamanho" -#: shared-bindings/bleio/CharacteristicBuffer.c:72 +#: shared-bindings/bleio/CharacteristicBuffer.c:65 #, fuzzy msgid "Expected a Characteristic" msgstr "Não é possível adicionar Característica." @@ -2191,20 +2190,20 @@ msgstr "" msgid "Can't advertise in Central mode" msgstr "" -#: shared-bindings/bleio/Peripheral.c:111 +#: shared-bindings/bleio/Peripheral.c:106 msgid "services includes an object that is not a Service" msgstr "" -#: shared-bindings/bleio/Peripheral.c:124 +#: shared-bindings/bleio/Peripheral.c:119 #, fuzzy msgid "name must be a string" msgstr "heap deve ser uma lista" -#: shared-bindings/bleio/Service.c:90 +#: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" msgstr "" -#: shared-bindings/bleio/Service.c:96 +#: shared-bindings/bleio/Service.c:90 msgid "Characteristic UUID doesn't match Service UUID" msgstr "" @@ -2225,19 +2224,19 @@ msgstr "buffers devem ser o mesmo tamanho" msgid "not a 128-bit UUID" msgstr "" -#: shared-bindings/busio/I2C.c:120 +#: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." msgstr "" -#: shared-bindings/busio/UART.c:106 +#: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" msgstr "" -#: shared-bindings/busio/UART.c:118 +#: shared-bindings/busio/UART.c:115 msgid "stop must be 1 or 2" msgstr "" -#: shared-bindings/busio/UART.c:123 +#: shared-bindings/busio/UART.c:120 msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" @@ -2263,7 +2262,7 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: shared-bindings/displayio/Bitmap.c:84 +#: shared-bindings/displayio/Bitmap.c:84 shared-bindings/displayio/Shape.c:88 msgid "y should be an int" msgstr "y deve ser um int" @@ -2279,45 +2278,80 @@ msgstr "" msgid "color should be an int" msgstr "cor deve ser um int" -#: shared-bindings/displayio/FourWire.c:55 -#: shared-bindings/displayio/FourWire.c:64 +#: shared-bindings/displayio/Display.c:79 +msgid "Width and height kwargs required" +msgstr "" + +#: shared-bindings/displayio/Display.c:93 +msgid "Display limit reached" +msgstr "" + +#: shared-bindings/displayio/Display.c:112 +msgid "Must be a Group subclass." +msgstr "" + +#: shared-bindings/displayio/FourWire.c:69 +msgid "Command and chip_select required" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:91 +#: shared-bindings/displayio/ParallelBus.c:94 +msgid "Display bus limit reached" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:104 +#: shared-bindings/displayio/ParallelBus.c:106 msgid "displayio is a work in progress" msgstr "" -#: shared-bindings/displayio/Group.c:65 +#: shared-bindings/displayio/Group.c:62 msgid "Group must have size at least 1" msgstr "Grupo deve ter tamanho pelo menos 1" -#: shared-bindings/displayio/Palette.c:96 +#: shared-bindings/displayio/Palette.c:93 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: shared-bindings/displayio/Palette.c:102 +#: shared-bindings/displayio/Palette.c:99 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: shared-bindings/displayio/Palette.c:106 +#: shared-bindings/displayio/Palette.c:103 msgid "color must be between 0x000000 and 0xffffff" msgstr "cor deve estar entre 0x000000 e 0xffffff" -#: shared-bindings/displayio/Palette.c:110 +#: shared-bindings/displayio/Palette.c:107 msgid "color buffer must be a buffer or int" msgstr "" -#: shared-bindings/displayio/Palette.c:123 -#: shared-bindings/displayio/Palette.c:137 +#: shared-bindings/displayio/Palette.c:120 +#: shared-bindings/displayio/Palette.c:134 msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/Sprite.c:48 +#: shared-bindings/displayio/ParallelBus.c:75 +msgid "Data0, command, chip_select, write and read required" +msgstr "" + +#: shared-bindings/displayio/Shape.c:92 +#, fuzzy +msgid "start_x should be an int" +msgstr "y deve ser um int" + +#: shared-bindings/displayio/Shape.c:96 +#, fuzzy +msgid "end_x should be an int" +msgstr "y deve ser um int" + +#: shared-bindings/displayio/Sprite.c:49 msgid "position must be 2-tuple" msgstr "" -#: shared-bindings/displayio/Sprite.c:97 +#: shared-bindings/displayio/Sprite.c:102 msgid "unsupported bitmap type" msgstr "" -#: shared-bindings/displayio/Sprite.c:162 +#: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -2329,15 +2363,15 @@ msgstr "muitos argumentos" msgid "expected a DigitalInOut" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:98 +#: shared-bindings/i2cslave/I2CSlave.c:95 msgid "can't convert address to int" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:101 +#: shared-bindings/i2cslave/I2CSlave.c:98 msgid "address out of bounds" msgstr "" -#: shared-bindings/i2cslave/I2CSlave.c:107 +#: shared-bindings/i2cslave/I2CSlave.c:104 msgid "addresses is empty" msgstr "" @@ -2379,29 +2413,29 @@ msgstr "Os bytes devem estar entre 0 e 255." msgid "No hardware random available" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:164 +#: shared-bindings/pulseio/PWMOut.c:162 msgid "" "PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" msgstr "" -#: shared-bindings/pulseio/PWMOut.c:195 +#: shared-bindings/pulseio/PWMOut.c:193 msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" -#: shared-bindings/pulseio/PulseIn.c:275 +#: shared-bindings/pulseio/PulseIn.c:272 msgid "Cannot delete values" msgstr "Não é possível excluir valores" -#: shared-bindings/pulseio/PulseIn.c:281 +#: shared-bindings/pulseio/PulseIn.c:278 msgid "Slices not supported" msgstr "" -#: shared-bindings/pulseio/PulseIn.c:287 +#: shared-bindings/pulseio/PulseIn.c:284 msgid "index must be int" msgstr "index deve ser int" -#: shared-bindings/pulseio/PulseIn.c:293 +#: shared-bindings/pulseio/PulseIn.c:290 msgid "Read-only" msgstr "Somente leitura" @@ -2568,11 +2602,20 @@ msgstr "Apenas bit maps de cores de 8 bit ou menos são suportados" msgid "row must be packed and word aligned" msgstr "Linha deve ser comprimida e com as palavras alinhadas" +#: shared-module/displayio/Display.c:62 +#, fuzzy +msgid "Unsupported display bus type" +msgstr "Taxa de transmissão não suportada" + #: shared-module/displayio/Group.c:39 msgid "Group full" msgstr "Grupo cheio" -#: shared-module/displayio/Group.c:48 +#: shared-module/displayio/Group.c:46 +msgid "Layer must be a Group or Sprite subclass." +msgstr "" + +#: shared-module/displayio/Group.c:55 msgid "Group empty" msgstr "Grupo vazio" @@ -2590,6 +2633,19 @@ msgstr "Apenas formato Windows, BMP descomprimido suportado" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "Apenas cores verdadeiras (24 bpp ou maior) BMP suportadas" +#: shared-module/displayio/Shape.c:60 +msgid "y value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:63 +msgid "x value out of bounds" +msgstr "" + +#: shared-module/displayio/Shape.c:67 +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + #: shared-module/storage/__init__.c:155 msgid "Cannot remount '/' when USB is active." msgstr "Não é possível remontar '/' enquanto o USB estiver ativo." @@ -2615,6 +2671,18 @@ msgstr "USB ocupada" msgid "USB Error" msgstr "Erro na USB" +#: supervisor/shared/board_busses.c:62 +msgid "No default I2C bus" +msgstr "Nenhum barramento I2C padrão" + +#: supervisor/shared/board_busses.c:89 +msgid "No default SPI bus" +msgstr "Nenhum barramento SPI padrão" + +#: supervisor/shared/board_busses.c:116 +msgid "No default UART bus" +msgstr "Nenhum barramento UART padrão" + #: supervisor/shared/safe_mode.c:97 msgid "You requested starting safe mode by " msgstr "Você solicitou o início do modo de segurança" @@ -2670,32 +2738,32 @@ msgid "" "exit safe mode.\n" msgstr "" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parâmetro UUID inválido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" + #~ msgid "Can not add Characteristic." #~ msgstr "Não é possível adicionar Característica." -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Pode codificar o UUID no pacote de anúncios." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Não é possível aplicar parâmetros GAP." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." #~ msgid "Baud rate too high for this SPI peripheral" #~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parâmetro UUID inválido" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possível aplicar parâmetros GAP." From 0318a9a9bcbceab308323788cb9e579da166710e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 11:53:09 -0800 Subject: [PATCH 126/153] More make_new fixes for unix build --- extmod/moductypes.c | 4 ++-- extmod/modutimeq.c | 4 ++-- extmod/moduzlib.c | 4 ++-- extmod/modwebsocket.c | 4 ++-- ports/unix/file.c | 4 ++-- ports/unix/modffi.c | 6 +++--- ports/unix/modusocket.c | 4 ++-- py/modio.c | 4 ++-- py/objdeque.c | 4 ++-- py/objfun.c | 2 +- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/extmod/moductypes.c b/extmod/moductypes.c index e627cd1462072..9eea30bf3ea6f 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -122,8 +122,8 @@ STATIC NORETURN void syntax_error(void) { mp_raise_TypeError(translate("syntax error in uctypes descriptor")); } -STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, 3, false); +STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, 3, false); mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); o->base.type = type; o->addr = (void*)(uintptr_t)mp_obj_int_get_truncated(args[0]); diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c index 614820443be97..99b51016d82d9 100644 --- a/extmod/modutimeq.c +++ b/extmod/modutimeq.c @@ -76,8 +76,8 @@ STATIC bool time_less_than(struct qentry *item, struct qentry *parent) { return res && res < (MODULO / 2); } -STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); +STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); mp_uint_t alloc = mp_obj_get_int(args[0]); mp_obj_utimeq_t *o = m_new_obj_var(mp_obj_utimeq_t, struct qentry, alloc); o->base.type = type; diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index 253deac1e6f0f..7f15d02a8e340 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -69,8 +69,8 @@ STATIC int read_src_stream(TINF_DATA *data) { return c; } -STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 2, false); +STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 2, false); mp_get_stream_raise(args[0], MP_STREAM_OP_READ); mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t); o->base.type = type; diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c index c556f2b7706cb..997c7e2625965 100644 --- a/extmod/modwebsocket.c +++ b/extmod/modwebsocket.c @@ -57,8 +57,8 @@ typedef struct _mp_obj_websocket_t { STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode); -STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 2, false); +STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 2, false); mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); mp_obj_websocket_t *o = m_new_obj(mp_obj_websocket_t); o->base.type = type; diff --git a/ports/unix/file.c b/ports/unix/file.c index 98ac1b3cc2e1c..c0cf6dcc433e0 100644 --- a/ports/unix/file.c +++ b/ports/unix/file.c @@ -205,9 +205,9 @@ STATIC mp_obj_t fdfile_open(const mp_obj_type_t *type, mp_arg_val_t *args) { return MP_OBJ_FROM_PTR(o); } -STATIC mp_obj_t fdfile_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t fdfile_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); + mp_arg_parse_all(n_args, args, kw_args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); return fdfile_open(type, arg_vals); } diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index fcbcebc39074e..03dc9e4ec6977 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -304,9 +304,9 @@ STATIC mp_obj_t ffimod_addr(mp_obj_t self_in, mp_obj_t symname_in) { } MP_DEFINE_CONST_FUN_OBJ_2(ffimod_addr_obj, ffimod_addr); -STATIC mp_obj_t ffimod_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t ffimod_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)n_args; - (void)n_kw; + (void)kw_args; const char *fname = NULL; if (args[0] != mp_const_none) { @@ -481,7 +481,7 @@ STATIC const mp_obj_type_t opaque_type = { */ STATIC mp_obj_t mod_ffi_open(size_t n_args, const mp_obj_t *args) { - return ffimod_make_new(&ffimod_type, n_args, 0, args); + return ffimod_make_new(&ffimod_type, n_args, args, NULL); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_ffi_open_obj, 1, 2, mod_ffi_open); diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 9b9869f5b1396..84e9298fd3d34 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -325,9 +325,9 @@ STATIC mp_obj_t socket_makefile(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_makefile_obj, 1, 3, socket_makefile); -STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - (void)n_kw; + (void)kw_args; int family = AF_INET; int type = SOCK_STREAM; diff --git a/py/modio.c b/py/modio.c index 9b09de96e4c12..9918159cb5e74 100644 --- a/py/modio.c +++ b/py/modio.c @@ -46,11 +46,11 @@ STATIC const mp_obj_type_t mp_type_iobase; STATIC mp_obj_base_t iobase_singleton = {&mp_type_iobase}; -STATIC mp_obj_t iobase_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t iobase_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type; (void)n_args; - (void)n_kw; (void)args; + (void)kw_args; return MP_OBJ_FROM_PTR(&iobase_singleton); } diff --git a/py/objdeque.c b/py/objdeque.c index dd0141831d026..b2785b5b60f98 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -44,8 +44,8 @@ typedef struct _mp_obj_deque_t { #define FLAG_CHECK_OVERFLOW 1 } mp_obj_deque_t; -STATIC mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, 3, false); +STATIC mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, 3, false); /* Initialization from existing sequence is not supported, so an empty tuple must be passed as such. */ diff --git a/py/objfun.c b/py/objfun.c index 2ada0b3f1678b..b8364815be900 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -436,7 +436,7 @@ typedef mp_uint_t (*viper_fun_4_t)(mp_uint_t, mp_uint_t, mp_uint_t, mp_uint_t); STATIC mp_obj_t fun_viper_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_obj_fun_viper_t *self = self_in; - mp_arg_check_num(n_args, n_kw, self->n_args, self->n_args, false); + mp_arg_check_num_kw_array(n_args, n_kw, self->n_args, self->n_args, false); void *fun = MICROPY_MAKE_POINTER_CALLABLE(self->fun_data); From 58a2009cc11ac6b080d182854d0f669a6f65647a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 12:52:27 -0800 Subject: [PATCH 127/153] Fix unix build --- extmod/machine_i2c.c | 10 ++++------ extmod/machine_pinbase.c | 4 ++-- extmod/machine_signal.c | 10 +++++----- extmod/machine_spi.c | 14 +++++++------- ports/unix/Makefile | 8 ++++++++ 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index b91f1a1ebd7d8..85b46a9f6bda1 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -287,14 +287,14 @@ STATIC void machine_i2c_obj_init_helper(machine_i2c_obj_t *self, size_t n_args, mp_hal_i2c_init(self, args[ARG_freq].u_int); } -STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check the id argument, if given if (n_args > 0) { if (args[0] != MP_OBJ_NEW_SMALL_INT(-1)) { #if defined(MICROPY_PY_MACHINE_I2C_MAKE_NEW) // dispatch to port-specific constructor - extern mp_obj_t MICROPY_PY_MACHINE_I2C_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); - return MICROPY_PY_MACHINE_I2C_MAKE_NEW(type, n_args, n_kw, args); + extern mp_obj_t MICROPY_PY_MACHINE_I2C_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args); + return MICROPY_PY_MACHINE_I2C_MAKE_NEW(type, n_args, args, kw_args); #else mp_raise_ValueError(translate("invalid I2C peripheral")); #endif @@ -306,9 +306,7 @@ STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, s // create new soft I2C object machine_i2c_obj_t *self = m_new_obj(machine_i2c_obj_t); self->base.type = &machine_i2c_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - machine_i2c_obj_init_helper(self, n_args, args, &kw_args); + machine_i2c_obj_init_helper(self, n_args, args, kw_args); return (mp_obj_t)self; } diff --git a/extmod/machine_pinbase.c b/extmod/machine_pinbase.c index 070c5cde9d3ac..997a6fd991d3c 100644 --- a/extmod/machine_pinbase.c +++ b/extmod/machine_pinbase.c @@ -45,11 +45,11 @@ STATIC const mp_pinbase_t pinbase_singleton = { .base = { &machine_pinbase_type }, }; -STATIC mp_obj_t pinbase_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t pinbase_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type; (void)n_args; - (void)n_kw; (void)args; + (void)kw_args; return MP_OBJ_FROM_PTR(&pinbase_singleton); } diff --git a/extmod/machine_signal.c b/extmod/machine_signal.c index 3f9f5af947707..62658cbb172d5 100644 --- a/extmod/machine_signal.c +++ b/extmod/machine_signal.c @@ -42,7 +42,7 @@ typedef struct _machine_signal_t { bool invert; } machine_signal_t; -STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_obj_t pin = args[0]; bool invert = false; @@ -96,9 +96,9 @@ STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t // Otherwise there should be 1 or 2 args { if (n_args == 1) { - if (n_kw == 0) { - } else if (n_kw == 1 && args[1] == MP_OBJ_NEW_QSTR(MP_QSTR_invert)) { - invert = mp_obj_is_true(args[2]); + if (kw_args == NULL || kw_args->used == 0) { + } else if (kw_args->used == 1 && kw_args->table[0].key == MP_OBJ_NEW_QSTR(MP_QSTR_invert)) { + invert = mp_obj_is_true(kw_args->table[0].value); } else { goto error; } @@ -133,7 +133,7 @@ STATIC mp_uint_t signal_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg // fast method for getting/setting signal value STATIC mp_obj_t signal_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num_kw_array(n_args, n_kw, 0, 1, false); if (n_args == 0) { // get pin return MP_OBJ_NEW_SMALL_INT(mp_virtual_pin_read(self_in)); diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index 3bbab2824209c..c5707a3d0b028 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -43,16 +43,16 @@ /******************************************************************************/ // MicroPython bindings for generic machine.SPI -STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); +STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); -mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check the id argument, if given if (n_args > 0) { if (args[0] != MP_OBJ_NEW_SMALL_INT(-1)) { #if defined(MICROPY_PY_MACHINE_SPI_MAKE_NEW) // dispatch to port-specific constructor - extern mp_obj_t MICROPY_PY_MACHINE_SPI_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); - return MICROPY_PY_MACHINE_SPI_MAKE_NEW(type, n_args, n_kw, args); + extern mp_obj_t MICROPY_PY_MACHINE_SPI_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); + return MICROPY_PY_MACHINE_SPI_MAKE_NEW(type, n_args, args, kw_args); #else mp_raise_ValueError(translate("invalid SPI peripheral")); #endif @@ -62,7 +62,7 @@ mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_ } // software SPI - return mp_machine_soft_spi_make_new(type, n_args, n_kw, args); + return mp_machine_soft_spi_make_new(type, n_args, args, kw_args); } STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { @@ -180,7 +180,7 @@ STATIC void mp_machine_soft_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_hal_pin_name(self->spi.sck), mp_hal_pin_name(self->spi.mosi), mp_hal_pin_name(self->spi.miso)); } -STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { +STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; static const mp_arg_t allowed_args[] = { { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} }, @@ -193,7 +193,7 @@ STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all(n_args, all_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // create new object mp_machine_soft_spi_obj_t *self = m_new_obj(mp_machine_soft_spi_obj_t); diff --git a/ports/unix/Makefile b/ports/unix/Makefile index 8775ec11ac11e..99b65ec1bc22f 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -154,6 +154,14 @@ SRC_C = \ supervisor/shared/translate.c \ $(SRC_MOD) +PY_EXTMOD_O_BASENAME += \ + extmod/machine_mem.o \ + extmod/machine_pinbase.o \ + extmod/machine_signal.o \ + extmod/machine_pulse.o \ + extmod/machine_i2c.o \ + extmod/machine_spi.o + LIB_SRC_C = $(addprefix lib/,\ $(LIB_SRC_C_EXTRA) \ timeutils/timeutils.c \ From dc024cf411e5a77bffc3662aa581c667284e67e6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 12:59:23 -0800 Subject: [PATCH 128/153] Add a bit more to the docs --- shared-bindings/displayio/Display.c | 37 +++++++++++++++++++++++-- shared-bindings/displayio/FourWire.c | 5 ++++ shared-bindings/displayio/ParallelBus.c | 9 +++++- shared-bindings/displayio/__init__.c | 11 ++++---- 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 9028c28654f29..501b96549094e 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -49,10 +49,41 @@ //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| -//| .. class:: Display(display_bus, *, width, height, colstart=0, rowstart=0, color_depth=16, -//| set_column_command=0x2a set_row_command=0x2b, write_ram_command=0x2c) +//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, color_depth=16, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c) //| -//| Create a Display object. +//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`). +//| +//| The ``init_sequence`` is bitbacked to minimize the ram impact. Every command begins with a +//| command byte followed by a byte to determine the parameter count and if a delay is need after. +//| When the top bit of the second byte is 1, the next byte will be the delay time in milliseconds. +//| The remaining 7 bits are the parameter count excluding any delay byte. The third through final +//| bytes are the remaining command parameters. The next byte will begin a new command definition. +//| Here is a portion of ILI9341 init code: +//| +//| .. code-block:: python +//| +//| init_sequence = (b"\xe1\x0f\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F" # Set Gamma +//| b"\x11\x80\x78"# Exit Sleep then delay 0x78 (120ms) +//| b"\x29\x80\x78"# Display on then delay 0x78 (120ms) +//| ) +//| display = displayio.Display(display_bus, init_sequence, width=320, height=240) +//| +//| The first command is 0xe1 with 15 (0xf) parameters following. The second and third are 0x11 and +//| 0x29 respectively with delays (0x80) of 120ms (0x78) and no parameters. Multiple byte literals +//| (b"") are merged together on load. The parens are needed to allow byte literals on subsequent +//| lines. +//| +//| :param displayio.FourWire or displayio.ParallelBus display_bus: The bus that the display is connected to +//| :param buffer init_sequence: Byte-packed initialization sequence. +//| :param int width: Width in pixels +//| :param int height: Height in pixels +//| :param int colstart: The index if the first visible column +//| :param int rowstart: The index if the first visible row +//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays +//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) +//| :param int set_column_command: Command used to set the start and end columns to update +//| :param int set_row_command: Command used so set the start and end rows to update +//| :param int write_ram_command: Command used to write pixels values into the update region //| STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command }; diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 530eafb51fd0b..561e2871ef928 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -52,6 +52,11 @@ //| //| Create a FourWire object associated with the given pins. //| +//| :param busio.SPI spi_bus: The SPI bus that make up the clock and data lines +//| :param microcontroller.Pin command: Data or command pin +//| :param microcontroller.Pin chip_select: Chip select pin +//| :param microcontroller.Pin reset: Reset pin +//| STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index e1079acb58a6c..2f99678662a0c 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -40,7 +40,7 @@ //| .. currentmodule:: displayio //| //| :class:`ParallelBus` -- Manage updating a display over SPI four wire protocol -//| ========================================================================== +//| ============================================================================== //| //| Manage updating a display over SPI four wire protocol in the background while Python code runs. //| It doesn't handle display initialization. @@ -52,6 +52,13 @@ //| Create a ParallelBus object associated with the given pins. The bus is inferred from data0 //| by implying the next 7 additional pins on a given GPIO port. //| +//| :param microcontroller.Pin: The first data pin. The rest are implied +//| :param microcontroller.Pin command: Data or command pin +//| :param microcontroller.Pin chip_select: Chip select pin +//| :param microcontroller.Pin write: Write pin +//| :param microcontroller.Pin read: Read pin +//| :param microcontroller.Pin reset: Reset pin +//| STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_data0, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 306f8c08bf7f7..6ed1218b2bf1b 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -46,13 +46,10 @@ //| //| .. module:: displayio //| :synopsis: Native helpers for driving displays -//| :platform: SAMD21, SAMD51 +//| :platform: SAMD21, SAMD51, nRF52 //| //| The `displayio` module contains classes to manage display output -//| including synchronizing with refresh rates and partial updating. It does -//| not include display initialization commands. It should live in a Python -//| driver for use when a display is connected to a board. It should also be -//| built into the board init when the board has the display on it. +//| including synchronizing with refresh rates and partial updating. //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| @@ -78,7 +75,9 @@ //| .. method:: release_displays() //| -//| Releases any actively used displays so theis pins can be used again. +//| Releases any actively used displays so their busses and pins can be used again. This will also +//| release the builtin display on boards that have one. You will need to reinitialize it yourself +//| afterwards. //| STATIC mp_obj_t displayio_release_displays(void) { common_hal_displayio_release_displays(); From ae52c964c2cdb91643b05f180353d95895260245 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 13:47:40 -0800 Subject: [PATCH 129/153] Cleanup display rework for PR. Fixes #1465. Fixes #1337. Fixes #1168 --- ports/atmel-samd/boards/feather_m4_express/board.c | 9 +-------- ports/atmel-samd/boards/feather_m4_express/pins.c | 1 - shared-module/displayio/__init__.c | 11 +++-------- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/ports/atmel-samd/boards/feather_m4_express/board.c b/ports/atmel-samd/boards/feather_m4_express/board.c index 85e9959c9cc73..8096b9b8ea6d8 100644 --- a/ports/atmel-samd/boards/feather_m4_express/board.c +++ b/ports/atmel-samd/boards/feather_m4_express/board.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2017 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 @@ -26,13 +26,6 @@ #include "boards/board.h" #include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" - -#include "shared-bindings/displayio/Display.h" -#include "shared-bindings/displayio/FourWire.h" -#include "shared-module/displayio/mipi_constants.h" - -#include "tick.h" void board_init(void) { } diff --git a/ports/atmel-samd/boards/feather_m4_express/pins.c b/ports/atmel-samd/boards/feather_m4_express/pins.c index 23b55e9577c92..cec9fe37f190f 100644 --- a/ports/atmel-samd/boards/feather_m4_express/pins.c +++ b/ports/atmel-samd/boards/feather_m4_express/pins.c @@ -1,6 +1,5 @@ #include "shared-bindings/board/__init__.h" -#include "boards/board.h" #include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index c8132e2f94307..59a5cf398e752 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -37,13 +37,9 @@ void displayio_refresh_displays(void) { uint16_t* pixel = &(((uint16_t*)buffer)[index]); *pixel = 0; - //if (index == 0) { - if (display->current_group != NULL) { - displayio_group_get_pixel(display->current_group, x, y, pixel); - } - // } else { - // *pixel = (((uint16_t*)buffer)[0]); - // } + if (display->current_group != NULL) { + displayio_group_get_pixel(display->current_group, x, y, pixel); + } index += 1; // The buffer is full, send it. @@ -189,5 +185,4 @@ void common_hal_displayio_release_displays(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { displays[i].display.base.type = &mp_type_NoneType; } - // TODO(tannewt): Clear the display datastructures and release everything used. } From 4768d4ff93aeeeb5c7db7f58fbb1bcc87ff9d81d Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 18 Jan 2019 14:52:12 -0500 Subject: [PATCH 130/153] report status in .travis.yml correctly --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index e8e1494e7a7f0..91c6728b8c08a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -86,7 +86,7 @@ before_script: script: # Build mpy-cross first because other builds depend on it. - echo 'Building mpy-cross' && echo 'travis_fold:start:mpy-cross' - - make -C mpy-cross -j2 ; echo $? > status + - make -C mpy-cross -j2 ; S=$? ; echo $S > status ; (exit $S) - echo 'travis_fold:end:mpy-cross' && tools/print_status.py status # Use unbuffered output because building all the releases can take a long time. @@ -95,7 +95,7 @@ script: - cd .. - echo 'Building unix' && echo 'travis_fold:start:unix' - - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; echo $? > status + - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; S=$? ; echo $S > status ; (exit $S) - echo 'travis_fold:end:unix' && tools/print_status.py status # run tests without coverage info @@ -104,27 +104,27 @@ script: # run tests with coverage info - echo 'Test all' && echo 'travis_fold:start:test_all' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; echo $? > status + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; S=$? ; echo $S > status ; (exit $S) - echo 'travis_fold:end:test_all' && tools/print_status.py status - echo 'Test threads' && echo 'travis_fold:start:test_threads' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; echo $? >status + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; S=$? ; echo $S > status ; (exit $S) - echo 'travis_fold:end:test_threads' && tools/print_status.py status - echo 'Testing with native' && echo 'travis_fold:start:test_native' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; echo $? >status + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; S=$? ; echo $S > status ; (exit $S) - echo 'travis_fold:end:test_native' && tools/print_status.py status - (echo 'Testing with mpy' && echo 'travis_fold:start:test_mpy') - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; echo $? >status + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; S=$? ; echo $S > status ; (exit $S) - echo 'travis_fold:end:test_mpy' && tools/print_status.py status - (echo 'Building docs' && echo 'travis_fold:start:build_docs') - - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; echo $? >status + - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; S=$? ; echo $S > status ; (exit $S) - echo 'travis_fold:end:build_docs' && tools/print_status.py status - (echo 'Building translations' && echo 'travis_fold:start:build_translations') - - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; echo $? >status + - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; S=$? ; echo $S > status ; (exit $S) - echo 'travis_fold:end:build_translations' && tools/print_status.py status # run coveralls coverage analysis (try to, even if some builds/tests failed) From edc8383e2297156134a58067899eefacd5764802 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 16:37:06 -0800 Subject: [PATCH 131/153] Improvements thanks to danh's review --- .../atmel-samd/common-hal/displayio/ParallelBus.c | 9 ++++++++- ports/nrf/common-hal/displayio/ParallelBus.c | 5 ++++- shared-bindings/displayio/Display.c | 6 +++--- shared-bindings/displayio/FourWire.c | 9 +++------ shared-bindings/displayio/ParallelBus.c | 15 ++++++--------- supervisor/shared/board_busses.c | 2 ++ 6 files changed, 26 insertions(+), 20 deletions(-) diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.c b/ports/atmel-samd/common-hal/displayio/ParallelBus.c index 3c287eccd622f..7a5f61448a4e2 100644 --- a/ports/atmel-samd/common-hal/displayio/ParallelBus.c +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.c @@ -39,7 +39,7 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { uint8_t data_pin = data0->number; - if (data_pin % 8 != 0 || data_pin % 32 >= 24) { + if (data_pin % 8 != 0) { mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); } for (uint8_t i = 0; i < 8; i++) { @@ -49,6 +49,13 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel } PortGroup *const g = &PORT->Group[data0->number / 32]; g->DIRSET.reg = 0xff << (data_pin % 32); + uint32_t wrconfig = PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_DRVSTR; + if (data_pin % 32 > 15) { + wrconfig |= PORT_WRCONFIG_HWSEL | (0xff << ((data_pin % 32) - 16)); + } else { + wrconfig |= 0xff << (data_pin % 32); + } + g->WRCONFIG.reg = wrconfig; self->bus = ((uint8_t*) &g->OUT.reg) + (data0->number % 32 / 8); self->command.base.type = &digitalio_digitalinout_type; diff --git a/ports/nrf/common-hal/displayio/ParallelBus.c b/ports/nrf/common-hal/displayio/ParallelBus.c index 3afedf73633bc..42231be5275dc 100644 --- a/ports/nrf/common-hal/displayio/ParallelBus.c +++ b/ports/nrf/common-hal/displayio/ParallelBus.c @@ -39,7 +39,7 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { uint8_t data_pin = data0->number; - if (data_pin % 8 != 0 || data_pin % 32 >= 24) { + if (data_pin % 8 != 0) { mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); } for (uint8_t i = 0; i < 8; i++) { @@ -57,6 +57,9 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel num_pins_in_port = P1_PIN_NUM; } g->DIRSET = 0xff << (data_pin % num_pins_in_port); + for (uint8_t i = 0; i < 8; i++) { + g->PIN_CNF[data_pin + i] |= NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos; + } self->bus = ((uint8_t*) &g->OUT) + (data0->number % num_pins_in_port / 8); self->command.base.type = &digitalio_digitalinout_type; diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 501b96549094e..4de6c2b248575 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -90,8 +90,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a static const mp_arg_t allowed_args[] = { { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, - { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, @@ -121,7 +121,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a } } if (self == NULL) { - mp_raise_RuntimeError(translate("Display limit reached")); + mp_raise_RuntimeError(translate("Too many displays")); } self->base.type = &displayio_display_type; common_hal_displayio_display_construct(self, diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 561e2871ef928..dceb4fe69209a 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -61,8 +61,8 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset }; static const mp_arg_t allowed_args[] = { { MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -70,9 +70,6 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ mp_obj_t command = args[ARG_command].u_obj; mp_obj_t chip_select = args[ARG_chip_select].u_obj; - if (command == mp_const_none || chip_select == mp_const_none) { - mp_raise_ValueError(translate("Command and chip_select required")); - } assert_pin_free(command); assert_pin_free(chip_select); mp_obj_t reset = args[ARG_reset].u_obj; @@ -93,7 +90,7 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ } } if (self == NULL) { - mp_raise_RuntimeError(translate("Display bus limit reached")); + mp_raise_RuntimeError(translate("Too many display busses")); } common_hal_displayio_fourwire_construct(self, diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index 2f99678662a0c..916c5f8523781 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -62,11 +62,11 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_data0, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_write, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_read, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_write, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_read, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -78,9 +78,6 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t mp_obj_t write = args[ARG_write].u_obj; mp_obj_t read = args[ARG_read].u_obj; mp_obj_t reset = args[ARG_reset].u_obj; - if (data0 == mp_const_none || command == mp_const_none || chip_select == mp_const_none || write == mp_const_none || read == mp_const_none) { - mp_raise_ValueError(translate("Data0, command, chip_select, write and read required")); - } assert_pin_free(data0); assert_pin_free(command); assert_pin_free(chip_select); @@ -98,7 +95,7 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t } } if (self == NULL) { - mp_raise_RuntimeError(translate("Display bus limit reached")); + mp_raise_RuntimeError(translate("Too many display busses")); } common_hal_displayio_parallelbus_construct(self, data0, command, chip_select, write, read, reset); diff --git a/supervisor/shared/board_busses.c b/supervisor/shared/board_busses.c index ed1f98a58b170..8a1c7bf86d2f7 100644 --- a/supervisor/shared/board_busses.c +++ b/supervisor/shared/board_busses.c @@ -66,6 +66,8 @@ mp_obj_t board_i2c(void) { MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); #if BOARD_SPI +// Statically allocate the SPI object so it can live past the end of the heap and into the next VM. +// That way it can be used by built-in FourWire displays and be accessible through board.SPI(). STATIC busio_spi_obj_t spi_obj; STATIC mp_obj_t spi_singleton = NULL; From b41d386d02f26e81dc1f234826fde7d24b020531 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 17:04:18 -0800 Subject: [PATCH 132/153] simplify arg checking for display --- shared-bindings/displayio/Display.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 4de6c2b248575..d61732f6f9880 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -104,11 +104,6 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_obj_t display_bus = args[ARG_display_bus].u_obj; - mp_int_t width = args[ARG_width].u_int; - mp_int_t height = args[ARG_height].u_int; - if (width == -1 || height == -1) { - mp_raise_ValueError(translate("Width and height kwargs required")); - } mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); @@ -125,7 +120,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a } self->base.type = &displayio_display_type; common_hal_displayio_display_construct(self, - display_bus, width, height, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, + display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len); From b569e8bab044bb54210e12254a5c22342edb1296 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 17:09:56 -0800 Subject: [PATCH 133/153] More make_new updates --- extmod/modframebuf.c | 4 ++-- extmod/vfs_posix.c | 4 ++-- extmod/vfs_posix_file.c | 4 ++-- py/modio.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 4135405409a6a..f92312a231b7c 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -259,8 +259,8 @@ STATIC void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, u formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col); } -STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 4, 5, false); +STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 4, 5, false); mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t); o->base.type = type; diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 39e197f2936bf..d28dfe4516586 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -90,8 +90,8 @@ STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path return MP_IMPORT_STAT_NO_EXIST; } -STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_vfs_posix_t *vfs = m_new_obj(mp_obj_vfs_posix_t); vfs->base.type = type; diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 3eca47eb45465..b760b384741b3 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -109,14 +109,14 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_ return MP_OBJ_FROM_PTR(o); } -STATIC mp_obj_t vfs_posix_file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t vfs_posix_file_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { static const mp_arg_t allowed_args[] = { { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, { MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_r)} }, }; mp_arg_val_t arg_vals[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, arg_vals); + mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, arg_vals); return mp_vfs_posix_file_open(type, arg_vals[0].u_obj, arg_vals[1].u_obj); } diff --git a/py/modio.c b/py/modio.c index 9918159cb5e74..d7c1a58a8c23f 100644 --- a/py/modio.c +++ b/py/modio.c @@ -113,8 +113,8 @@ typedef struct _mp_obj_bufwriter_t { byte buf[0]; } mp_obj_bufwriter_t; -STATIC mp_obj_t bufwriter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, 2, false); +STATIC mp_obj_t bufwriter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, 2, false); size_t alloc = mp_obj_get_int(args[1]); mp_obj_bufwriter_t *o = m_new_obj_var(mp_obj_bufwriter_t, byte, alloc); o->base.type = type; From b82e1d7fcbbb4b637ad960ecb3c4f75d2388123d Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 19 Jan 2019 16:54:11 -0500 Subject: [PATCH 134/153] Fix build to work with constructor calling convention. --- shared-bindings/_pixelbuf/PixelBuf.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c index 545166724f318..37933fdfff280 100644 --- a/shared-bindings/_pixelbuf/PixelBuf.c +++ b/shared-bindings/_pixelbuf/PixelBuf.c @@ -76,10 +76,8 @@ extern const int32_t colorwheel(float pos); //| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The //| PixelBuf instance is appended after these args. //| -STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 2, MP_OBJ_FUN_ARGS_MAX, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); +STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, MP_OBJ_FUN_ARGS_MAX, true); enum { ARG_size, ARG_buf, ARG_byteorder, ARG_brightness, ARG_rawbuf, ARG_offset, ARG_dotstar, ARG_auto_write, ARG_write_function, ARG_write_args }; static const mp_arg_t allowed_args[] = { @@ -95,7 +93,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a { MP_QSTR_write_args, MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; 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); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); if (mp_obj_is_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type)) mp_raise_TypeError_varg(translate("byteorder is not an instance of ByteOrder (got a %s)"), mp_obj_get_type_str(args[ARG_byteorder].u_obj)); From 79d9c9cd56f718f89e99b449215756e28faf794d Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 19 Jan 2019 17:01:31 -0500 Subject: [PATCH 135/153] remove fill_wheel --- shared-bindings/_pixelbuf/PixelBuf.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c index 37933fdfff280..7c2766aa3fe5d 100644 --- a/shared-bindings/_pixelbuf/PixelBuf.c +++ b/shared-bindings/_pixelbuf/PixelBuf.c @@ -454,32 +454,6 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp } } -//| .. method:: fill_wheel(start=0, step=1) -//| -//| fill the buffer with a colorwheel starting at offset n, and stepping by step -//| - -STATIC mp_obj_t pixelbuf_pixelbuf_fill_wheel(mp_obj_t self_in, mp_obj_t start, mp_obj_t step) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); - pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); - float i = MP_OBJ_IS_SMALL_INT(start) ? MP_OBJ_SMALL_INT_VALUE(start) : mp_obj_float_get(start); - float incr = MP_OBJ_IS_SMALL_INT(step) ? MP_OBJ_SMALL_INT_VALUE(step) : mp_obj_float_get(step); - - bool auto_write = self->auto_write; - self->auto_write = false; - for (size_t n = 0; n < self->pixels; n++) { - mp_obj_t value = MP_OBJ_NEW_SMALL_INT(colorwheel(i)); - pixelbuf_pixelbuf_subscr(self_in, MP_OBJ_NEW_SMALL_INT(n), value); - i += incr; - } - self->auto_write = auto_write; - if (auto_write) - call_write_function(self); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(pixelbuf_pixelbuf_fill_wheel_obj, pixelbuf_pixelbuf_fill_wheel); - STATIC const mp_rom_map_elem_t pixelbuf_pixelbuf_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_auto_write), MP_ROM_PTR(&pixelbuf_pixelbuf_auto_write_obj)}, { MP_ROM_QSTR(MP_QSTR_bpp), MP_ROM_PTR(&pixelbuf_pixelbuf_bpp_obj)}, @@ -487,7 +461,6 @@ STATIC const mp_rom_map_elem_t pixelbuf_pixelbuf_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_buf), MP_ROM_PTR(&pixelbuf_pixelbuf_buf_obj)}, { MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_PTR(&pixelbuf_pixelbuf_byteorder_obj)}, { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&pixelbuf_pixelbuf_show_obj)}, - { MP_ROM_QSTR(MP_QSTR_fill_wheel), MP_ROM_PTR(&pixelbuf_pixelbuf_fill_wheel_obj)}, }; STATIC MP_DEFINE_CONST_DICT(pixelbuf_pixelbuf_locals_dict, pixelbuf_pixelbuf_locals_dict_table); From 8fa81fe00317ec6cda286476b8cea5f0e3dba43a Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 19 Jan 2019 17:03:16 -0500 Subject: [PATCH 136/153] move headers to __init__.h --- shared-bindings/_pixelbuf/PixelBuf.h | 4 ---- shared-bindings/_pixelbuf/__init__.h | 4 +++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/shared-bindings/_pixelbuf/PixelBuf.h b/shared-bindings/_pixelbuf/PixelBuf.h index b35e3ff9083c2..0b1e36278343e 100644 --- a/shared-bindings/_pixelbuf/PixelBuf.h +++ b/shared-bindings/_pixelbuf/PixelBuf.h @@ -53,8 +53,4 @@ typedef struct { void pixelbuf_recalculate_brightness(pixelbuf_pixelbuf_obj_t *self); void call_write_function(pixelbuf_pixelbuf_obj_t *self); - -#include "common-hal/digitalio/DigitalInOut.h" -extern void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* gpio, uint8_t *pixels, uint32_t numBytes); - #endif // CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H diff --git a/shared-bindings/_pixelbuf/__init__.h b/shared-bindings/_pixelbuf/__init__.h index 5049ea38d2bf8..a62d67c4a4450 100644 --- a/shared-bindings/_pixelbuf/__init__.h +++ b/shared-bindings/_pixelbuf/__init__.h @@ -27,9 +27,11 @@ #ifndef CP_SHARED_BINDINGS_PIXELBUF_INIT_H #define CP_SHARED_BINDINGS_PIXELBUF_INIT_H +#include "common-hal/digitalio/DigitalInOut.h" + STATIC void pixelbuf_byteorder_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); const int32_t colorwheel(float pos); - const mp_obj_type_t pixelbuf_byteorder_type; +extern void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* gpio, uint8_t *pixels, uint32_t numBytes); #endif //CP_SHARED_BINDINGS_PIXELBUF_INIT_H From 02266eafd87c410593c4f94c820490023e78eb55 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 19 Jan 2019 17:04:24 -0500 Subject: [PATCH 137/153] adjust comment --- shared-bindings/_pixelbuf/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c index 58fccfd91c251..31defc7fbc6d3 100644 --- a/shared-bindings/_pixelbuf/__init__.c +++ b/shared-bindings/_pixelbuf/__init__.c @@ -43,7 +43,7 @@ //| :synopsis: A fast RGB(W) pixel buffer library for like NeoPixel and DotStar. //| //| The `_pixelbuf` module provides :py:class:`PixelBuf` and :py:class:`ByteOrder` classes to accelerate -//| Dotstar and Neopixel manipulation. +//| RGB(W) strip/matrix manipulation, such as DotStar and Neopixel. //| //| Libraries From 28cfd8a5135a1e420b56d693cef20fc1a4721081 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 19 Jan 2019 19:45:35 -0500 Subject: [PATCH 138/153] CharacteristicBuffer: make it be a stream class; add locking --- ports/nrf/Makefile | 1 + ports/nrf/common-hal/bleio/Characteristic.c | 2 +- .../common-hal/bleio/CharacteristicBuffer.c | 80 +++++++-- .../common-hal/bleio/CharacteristicBuffer.h | 5 +- ports/nrf/common-hal/bleio/Device.c | 2 + ports/nrf/common-hal/busio/UART.c | 39 +---- ports/nrf/sd_mutex.c | 56 ++++++ ports/nrf/sd_mutex.h | 46 +++++ py/ringbuf.h | 32 +++- py/stream.c | 2 +- shared-bindings/bleio/CharacteristicBuffer.c | 159 ++++++++++++++++-- shared-bindings/bleio/CharacteristicBuffer.h | 9 +- shared-bindings/busio/UART.c | 4 +- 13 files changed, 371 insertions(+), 66 deletions(-) create mode 100644 ports/nrf/sd_mutex.c create mode 100644 ports/nrf/sd_mutex.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 2bc5084754617..1b4aef0504e30 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -142,6 +142,7 @@ SRC_C += \ peripherals/nrf/$(MCU_CHIP)/pins.c \ peripherals/nrf/$(MCU_CHIP)/power.c \ peripherals/nrf/timers.c \ + sd_mutex.c \ supervisor/shared/memory.c diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 0bade8d015577..1db564549cf1e 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -36,9 +36,9 @@ #include "common-hal/bleio/Characteristic.h" #include "shared-module/bleio/Characteristic.h" -// TODO - should these be per object?? ***** STATIC volatile bleio_characteristic_obj_t *m_read_characteristic; STATIC volatile uint8_t m_tx_in_progress; +// Serialize gattc writes that send a response. This might be done per object? STATIC nrf_mutex_t *m_write_mutex; STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) { diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c index 4bd3e147ff813..42e45abdfb244 100644 --- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c +++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Artur Pacholec + * 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 @@ -29,9 +29,13 @@ #include "ble_drv.h" #include "ble_gatts.h" -#include "nrf_soc.h" +#include "sd_mutex.h" +#include "lib/utils/interrupt_char.h" #include "py/runtime.h" +#include "py/stream.h" + +#include "tick.h" #include "common-hal/bleio/__init__.h" #include "common-hal/bleio/CharacteristicBuffer.h" @@ -43,10 +47,13 @@ STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) { 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 == self->characteristic->handle) { - // Push all the data onto the ring buffer. + // Push all the data onto the ring buffer, but wait for any reads to finish. + sd_mutex_acquire_wait_no_vm(&self->ringbuf_mutex); for (size_t i = 0; i < evt_write->len; i++) { ringbuf_put(&self->ringbuf, evt_write->data[i]); } + // Don't check for errors: we're in an event handler. + sd_mutex_release(&self->ringbuf_mutex); break; } } @@ -54,22 +61,75 @@ STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) { } -// Assumes that buffer_size has been validated before call. -void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, size_t buffer_size) { +// 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. - ringbuf_alloc(&self->ringbuf, buffer_size); + // true means long-lived, so it won't be moved. + ringbuf_alloc(&self->ringbuf, buffer_size, true); + sd_mutex_new(&self->ringbuf_mutex); ble_drv_add_event_handler(characteristic_buffer_on_ble_evt, self); } -// Returns a uint8_t byte value, or -1 if no data is available. -int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self) { - return ringbuf_get(&self->ringbuf); +int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) { + uint64_t start_ticks = ticks_ms; + + // Wait for all bytes received or timeout + while ( (ringbuf_count(&self->ringbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP ; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if ( mp_hal_is_interrupted() ) { + return 0; + } +#endif + } + + // Copy received data. Lock out writes while copying. + sd_mutex_acquire_wait(&self->ringbuf_mutex); + + size_t rx_bytes = MIN(ringbuf_count(&self->ringbuf), len); + for ( size_t i = 0; i < rx_bytes; i++ ) { + data[i] = ringbuf_get(&self->ringbuf); + } + + // Writes now OK. + sd_mutex_release_check(&self->ringbuf_mutex); + + return rx_bytes; +} + +uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) { + return ringbuf_count(&self->ringbuf); +} + +void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self) { + // prevent conflict with uart irq + sd_mutex_acquire_wait(&self->ringbuf_mutex); + ringbuf_clear(&self->ringbuf); + sd_mutex_release_check(&self->ringbuf_mutex); +} + +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) { - ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self); + if (!common_hal_bleio_characteristic_buffer_deinited(self)) { + ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self); + } +} + +bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self) { + return self->characteristic != NULL && + self->characteristic->service != NULL && + self->characteristic->service->device != NULL && + common_hal_bleio_device_get_conn_handle(self->characteristic->service->device) != BLE_CONN_HANDLE_INVALID; } diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h b/ports/nrf/common-hal/bleio/CharacteristicBuffer.h index f9ff7dd66da0b..f5c7151547504 100644 --- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h +++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.h @@ -27,15 +27,18 @@ #ifndef MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H #define MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H -#include "py/ringbuf.h" +#include "nrf_soc.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; + nrf_mutex_t ringbuf_mutex; } bleio_characteristic_buffer_obj_t; #endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 50c738abeea04..5f625829e480a 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -262,11 +262,13 @@ STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) mp_raise_OSError_msg(translate("Failed to discover services")); } + // Serialize discovery. err_code = sd_mutex_acquire(m_discovery_mutex); if (err_code != NRF_SUCCESS) { mp_raise_OSError_msg(translate("Failed to acquire mutex")); } + // Wait for someone else to release m_discovery_mutex. while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 912956369c8d9..43868f5065ad0 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -52,33 +52,6 @@ static uint32_t get_nrf_baud (uint32_t baudrate); -static uint16_t ringbuf_count(ringbuf_t *r) -{ - volatile int count = r->iput - r->iget; - if ( count < 0 ) { - count += r->size; - } - - return (uint16_t) count; -} - -static void ringbuf_clear(ringbuf_t *r) -{ - r->iput = r->iget = 0; -} - -// will overwrite old data -static void ringbuf_put_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize) -{ - for(uint8_t i=0; i < bufsize; i++) { - if ( ringbuf_put(r, buf[i]) < 0 ) { - // if full overwrite old data - (void) ringbuf_get(r); - ringbuf_put(r, buf[i]); - } - } -} - static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) { busio_uart_obj_t* self = (busio_uart_obj_t*) context; @@ -145,16 +118,20 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, // Init buffer for rx if ( rx != mp_const_none ) { - self->rbuf.buf = (uint8_t *) gc_alloc(receiver_buffer_size, false, false); + // Initially allocate the UART's buffer in the long-lived part of the + // heap. UARTs are generally long-lived objects, but the "make long- + // lived" machinery is incapable of moving internal pointers like + // self->buffer, so do it manually. (However, as long as internal + // pointers like this are NOT moved, allocating the buffer + // in the long-lived pool is not strictly necessary) + // (This is a macro.) + ringbuf_alloc(&self->rbuf, receiver_buffer_size, true); if ( !self->rbuf.buf ) { nrfx_uarte_uninit(&self->uarte); mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); } - self->rbuf.size = receiver_buffer_size; - self->rbuf.iget = self->rbuf.iput = 0; - self->rx_pin_number = rx->number; claim_pin(rx); } diff --git a/ports/nrf/sd_mutex.c b/ports/nrf/sd_mutex.c new file mode 100644 index 0000000000000..7682ffa6233f7 --- /dev/null +++ b/ports/nrf/sd_mutex.c @@ -0,0 +1,56 @@ +/* + * 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/mpconfig.h" +#include "py/runtime.h" +#include "nrf_soc.h" + +void sd_mutex_acquire_check(nrf_mutex_t* p_mutex) { + uint32_t err_code = sd_mutex_acquire(p_mutex); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to acquire mutex, err 0x%04x"), err_code); + } +} + +void sd_mutex_acquire_wait(nrf_mutex_t* p_mutex) { + while (sd_mutex_acquire(p_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } +} + +void sd_mutex_acquire_wait_no_vm(nrf_mutex_t* p_mutex) { + while (sd_mutex_acquire(p_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { + } +} + +void sd_mutex_release_check(nrf_mutex_t* p_mutex) { + uint32_t err_code = sd_mutex_release(p_mutex); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to release mutex, err 0x%04x"), err_code); + } +} diff --git a/ports/nrf/sd_mutex.h b/ports/nrf/sd_mutex.h new file mode 100644 index 0000000000000..ca46917205bb7 --- /dev/null +++ b/ports/nrf/sd_mutex.h @@ -0,0 +1,46 @@ +/* + * 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_NRF_SD_MUTEX_H +#define MICROPY_INCLUDED_NRF_SD_MUTEX_H + +#include "nrf_soc.h" + +// Helpers for common usage of nrf_mutex. + +// Try to acquire a mutex right now. Raise exception if we can't get it. +void sd_mutex_acquire_check(nrf_mutex_t* p_mutex); + +// Wait for a mutex to become available. Run VM background tasks while waiting. +void sd_mutex_acquire_wait(nrf_mutex_t* p_mutex); + +// Wait for a mutex to become available.. Block VM while waiting. +void sd_mutex_acquire_wait_no_vm(nrf_mutex_t* p_mutex); + +// Release a mutex, and raise exception on error. +void sd_mutex_release_check(nrf_mutex_t* p_mutex); + +#endif // MICROPY_INCLUDED_NRF_SD_MUTEX_H diff --git a/py/ringbuf.h b/py/ringbuf.h index c62e20e1dbde4..5f82cc0968f79 100644 --- a/py/ringbuf.h +++ b/py/ringbuf.h @@ -26,6 +26,8 @@ #ifndef MICROPY_INCLUDED_PY_RINGBUF_H #define MICROPY_INCLUDED_PY_RINGBUF_H +#include "py/gc.h" + #include typedef struct _ringbuf_t { @@ -40,9 +42,9 @@ typedef struct _ringbuf_t { // ringbuf_t buf = {buf_array, sizeof(buf_array)}; // Dynamic initialization. This creates root pointer! -#define ringbuf_alloc(r, sz) \ +#define ringbuf_alloc(r, sz, long_lived) \ { \ - (r)->buf = m_new(uint8_t, sz); \ + (r)->buf = gc_alloc(sz, false, long_lived); \ (r)->size = sz; \ (r)->iget = (r)->iput = 0; \ } @@ -71,4 +73,30 @@ static inline int ringbuf_put(ringbuf_t *r, uint8_t v) { return 0; } +static inline uint16_t ringbuf_count(ringbuf_t *r) +{ + volatile int count = r->iput - r->iget; + if ( count < 0 ) { + count += r->size; + } + + return (uint16_t) count; +} + +static inline void ringbuf_clear(ringbuf_t *r) +{ + r->iput = r->iget = 0; +} + +// will overwrite old data +static inline void ringbuf_put_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize) +{ + for(uint8_t i=0; i < bufsize; i++) { + if ( ringbuf_put(r, buf[i]) < 0 ) { + // if full overwrite old data + (void) ringbuf_get(r); + ringbuf_put(r, buf[i]); + } + } +} #endif // MICROPY_INCLUDED_PY_RINGBUF_H diff --git a/py/stream.c b/py/stream.c index aca9b84607bbc..9d8be445c558c 100644 --- a/py/stream.c +++ b/py/stream.c @@ -103,7 +103,7 @@ STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte fl // CPython does a readall, but here we silently let negatives through, // and they will cause a MemoryError. mp_int_t sz; - if (n_args == 1 || ((sz = mp_obj_get_int(args[1])) == -1)) { + if (n_args == 1 || args[1] == mp_const_none || ((sz = mp_obj_get_int(args[1])) == -1)) { return stream_readall(args[0]); } diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c index 2bb4448c4a84e..32629ca19336b 100644 --- a/shared-bindings/bleio/CharacteristicBuffer.c +++ b/shared-bindings/bleio/CharacteristicBuffer.c @@ -24,10 +24,21 @@ * THE SOFTWARE. */ +#include "py/mperrno.h" +#include "py/ioctl.h" #include "py/objproperty.h" #include "py/runtime.h" +#include "py/stream.h" + #include "shared-bindings/bleio/CharacteristicBuffer.h" #include "shared-bindings/bleio/UUID.h" +#include "shared-bindings/util.h" + +STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self) { + if (!common_hal_bleio_characteristic_buffer_connected(self)) { + mp_raise_ValueError(translate("Not connected")); + } +} //| .. currentmodule:: bleio //| @@ -36,27 +47,34 @@ //| //| Accumulates a Characteristic's incoming values in a FIFO buffer. //| -//| .. class:: CharacteristicBuffer(Characteristic, buffer_size=0) +//| .. class:: CharacteristicBuffer(Characteristic, *, timeout=1, buffer_size=64) //| //| Create a new Characteristic object identified by the specified UUID. //| //| :param bleio.Characteristic characteristic: The characteristic to monitor +//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters.//| //| :param int buffer_size: Size of ring buffer that stores incoming data coming from client. //| Must be >= 1. //| STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_characteristic, ARG_buffer_size, }; + enum { ARG_characteristic, ARG_timeout, ARG_buffer_size, }; static const mp_arg_t allowed_args[] = { { MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_buffer_size, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + { MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, }; 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); const mp_obj_t characteristic = args[ARG_characteristic].u_obj; - const int buffer_size = args[ARG_buffer_size].u_int; + mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + if (timeout < 0.0f) { + mp_raise_ValueError(translate("timeout must be >= 0.0")); + } + + const int buffer_size = args[ARG_buffer_size].u_int; if (buffer_size < 1) { mp_raise_ValueError(translate("buffer_size must be >= 1")); } @@ -69,30 +87,117 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, self->base.type = &bleio_characteristic_buffer_type; self->characteristic = MP_OBJ_TO_PTR(characteristic); - common_hal_bleio_characteristic_buffer_construct(self, self->characteristic, buffer_size); + common_hal_bleio_characteristic_buffer_construct(self, self->characteristic, timeout, buffer_size); return MP_OBJ_FROM_PTR(self); } - -//| .. method:: read() +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: read(nbytes=None) +//| +//| Read characters. If ``nbytes`` is specified then read at most that many +//| bytes. Otherwise, read everything that arrives until the connection +//| times out. Providing the number of bytes expected is highly recommended +//| because it will be faster. +//| +//| :return: Data read +//| :rtype: bytes or None +//| +//| .. method:: readinto(buf) //| -//| Read a single byte from the buffer. If no character is available, return None. -STATIC mp_obj_t bleio_characteristic_buffer_read(mp_obj_t self_in) { +//| Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: int or None (on a non-blocking error) +//| +//| .. method:: readline() +//| +//| Read a line, ending in a newline character. +//| +//| :return: the line read +//| :rtype: int or None +//| + +// These three methods are used by the shared stream methods. +STATIC mp_uint_t bleio_characteristic_buffer_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self)); + raise_error_if_not_connected(self); + byte *buf = buf_in; - int byte = common_hal_bleio_characteristic_buffer_read(self); - if (byte == -1) { - return mp_const_none; + // make sure we want at least 1 char + if (size == 0) { + return 0; } - return MP_OBJ_NEW_SMALL_INT(byte); + return common_hal_bleio_characteristic_buffer_read(self, buf, size, errcode); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_read_obj, bleio_characteristic_buffer_read); + +STATIC mp_uint_t bleio_characteristic_buffer_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + mp_raise_NotImplementedError(translate("CharacteristicBuffer writing not provided")); + return 0; +} + +STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self)); + raise_error_if_not_connected(self); + if (!common_hal_bleio_characteristic_buffer_connected(self)) { + mp_raise_ValueError(translate("Not connected.")); + } + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_RD) && common_hal_bleio_characteristic_buffer_rx_characters_available(self) > 0) { + ret |= MP_IOCTL_POLL_RD; + } +// No writing provided. +// if ((flags & MP_IOCTL_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) { +// ret |= MP_IOCTL_POLL_WR; +// } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +//| .. attribute:: in_waiting +//| +//| The number of bytes in the input buffer, available to be read +//| +STATIC mp_obj_t bleio_characteristic_buffer_obj_get_in_waiting(mp_obj_t self_in) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_buffer_rx_characters_available(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_get_in_waiting_obj, bleio_characteristic_buffer_obj_get_in_waiting); + +const mp_obj_property_t bleio_characteristic_buffer_in_waiting_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_characteristic_buffer_get_in_waiting_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: reset_input_buffer() +//| +//| Discard any unread characters in the input buffer. +//| +STATIC mp_obj_t bleio_characteristic_buffer_obj_reset_input_buffer(mp_obj_t self_in) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self)); + common_hal_bleio_characteristic_buffer_clear_rx_buffer(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_reset_input_buffer_obj, bleio_characteristic_buffer_obj_reset_input_buffer); //| .. method:: deinit() //| //| Disable permanently. +//| STATIC mp_obj_t bleio_characteristic_buffer_deinit(mp_obj_t self_in) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_bleio_characteristic_buffer_deinit(self); @@ -101,15 +206,39 @@ STATIC mp_obj_t bleio_characteristic_buffer_deinit(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_deinit_obj, bleio_characteristic_buffer_deinit); STATIC const mp_rom_map_elem_t bleio_characteristic_buffer_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_buffer_read_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_characteristic_buffer_deinit_obj) }, + + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + // CharacteristicBuffer is currently read-only. + // { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&bleio_characteristic_buffer_reset_input_buffer_obj) }, + // Properties + { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&bleio_characteristic_buffer_in_waiting_obj) }, + }; STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_buffer_locals_dict, bleio_characteristic_buffer_locals_dict_table); +STATIC const mp_stream_p_t characteristic_buffer_stream_p = { + .read = bleio_characteristic_buffer_read, + .write = bleio_characteristic_buffer_write, + .ioctl = bleio_characteristic_buffer_ioctl, + .is_text = false, + // Match PySerial when possible, such as disallowing optional length argument for .readinto() + .pyserial_compatibility = true, +}; + + const mp_obj_type_t bleio_characteristic_buffer_type = { { &mp_type_type }, .name = MP_QSTR_CharacteristicBuffer, .make_new = bleio_characteristic_buffer_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &characteristic_buffer_stream_p, .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_buffer_locals_dict }; diff --git a/shared-bindings/bleio/CharacteristicBuffer.h b/shared-bindings/bleio/CharacteristicBuffer.h index c5d7580da348d..f25017c19e741 100644 --- a/shared-bindings/bleio/CharacteristicBuffer.h +++ b/shared-bindings/bleio/CharacteristicBuffer.h @@ -31,9 +31,12 @@ extern const mp_obj_type_t bleio_characteristic_buffer_type; -extern void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, size_t buffer_size); -// Returns a uint8_t byte value, or -1 if no data is available. -int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self); +extern 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); +int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode); +uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self); +void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self); +bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self); int common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self); +bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index cd0ca3f360d38..85bf498a48a95 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -62,7 +62,7 @@ //| //| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds. //| The new upper limit on ``timeout`` is meant to catch mistaken use of milliseconds. - +//| typedef struct { mp_obj_base_t base; } busio_uart_parity_obj_t; @@ -172,7 +172,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ //| Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. //| //| :return: number of bytes read and stored into ``buf`` -//| :rtype: bytes or None +//| :rtype: int or None (on a non-blocking error) //| //| *New in CircuitPython 4.0:* No length parameter is permitted. From e44ba8b9c41041580b3cdd533878ad055c2824eb Mon Sep 17 00:00:00 2001 From: Pascal Deneaux Date: Sun, 20 Jan 2019 02:17:53 +0100 Subject: [PATCH 139/153] Update de_DE.po changed and inserted some translations and fixed typos. --- locale/de_DE.po | 95 ++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/locale/de_DE.po b/locale/de_DE.po index 47098b66acb35..beeb9ea7a7e87 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -509,8 +509,7 @@ msgstr "Dateisystem kann nicht wieder gemounted werden." #: ports/esp8266/common-hal/storage/__init__.c:38 msgid "Use esptool to erase flash and re-upload Python instead" -msgstr "" -"Benutze esptool um den flash zu löschen und stattdessen Python hochzuladen" +msgstr "Benutze esptool um den flash zu löschen und stattdessen Python hochzuladen" #: ports/esp8266/esp_mphal.c:154 msgid "C-level assert" @@ -651,110 +650,110 @@ msgstr "" #: ports/nrf/common-hal/analogio/AnalogOut.c:37 msgid "AnalogOut functionality not supported" -msgstr "" +msgstr "AnalogOut-Funktion wird nicht unterstützt" #: ports/nrf/common-hal/bleio/Adapter.c:41 #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" -msgstr "" +msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX" #: ports/nrf/common-hal/bleio/Adapter.c:110 #, fuzzy msgid "Failed to change softdevice state" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" +msgstr "Fehler beim Ändern des Softdevice-Status" #: ports/nrf/common-hal/bleio/Adapter.c:119 #, fuzzy msgid "Failed to get softdevice state" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" +msgstr "Fehler beim Abrufen des Softdevice-Status" #: ports/nrf/common-hal/bleio/Adapter.c:138 msgid "Failed to get local address" -msgstr "" +msgstr "Lokale Adresse konnte nicht abgerufen werden" #: ports/nrf/common-hal/bleio/Broadcaster.c:48 msgid "interval not in range 0.0020 to 10.24" -msgstr "" +msgstr "Das Interval ist nicht im Bereich 0.0020 bis 10.24" #: ports/nrf/common-hal/bleio/Broadcaster.c:58 #: ports/nrf/common-hal/bleio/Peripheral.c:56 #, fuzzy msgid "Data too large for advertisement packet" -msgstr "Daten können nicht in das advertisement packet eingefügt werden." +msgstr "Zu vielen Daten für das advertisement packet" #: ports/nrf/common-hal/bleio/Broadcaster.c:83 #: ports/nrf/common-hal/bleio/Peripheral.c:324 #, fuzzy, c-format msgid "Failed to start advertising, err 0x%04x" -msgstr "Kann advertisement nicht starten. Status: 0x%02x" +msgstr "Kann advertisement nicht starten. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 #: ports/nrf/common-hal/bleio/Peripheral.c:336 #, fuzzy, c-format msgid "Failed to stop advertising, err 0x%04x" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" +msgstr "Kann advertisement nicht stoppen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:59 #, fuzzy, c-format msgid "Failed to read CCCD value, err 0x%04x" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:89 #, fuzzy, c-format msgid "Failed to read gatts value, err 0x%04x" -msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" +msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:106 #, fuzzy, c-format msgid "Failed to write gatts value, err 0x%04x" -msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" +msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:132 #, fuzzy, c-format msgid "Failed to notify or indicate attribute value, err %0x04x" -msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%02x" +msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:144 #, fuzzy, c-format msgid "Failed to read attribute value, err %0x04x" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:172 #, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:178 #, fuzzy, c-format msgid "Failed to write attribute value, err 0x%04x" -msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" +msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:189 #, fuzzy, c-format msgid "Failed to release mutex, err 0x%04x" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" +msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:251 #: ports/nrf/common-hal/bleio/Characteristic.c:284 msgid "bad GATT role" -msgstr "" +msgstr "bad GATT role" #: ports/nrf/common-hal/bleio/Device.c:80 #: ports/nrf/common-hal/bleio/Device.c:112 #, fuzzy msgid "Data too large for the advertisement packet" -msgstr "Daten können nicht in das advertisement packet eingefügt werden." +msgstr "Daten sind zu groß für das advertisement packet" #: ports/nrf/common-hal/bleio/Device.c:262 #, fuzzy msgid "Failed to discover services" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" +msgstr "Es konnten keine Dienste gefunden werden" #: ports/nrf/common-hal/bleio/Device.c:267 #: ports/nrf/common-hal/bleio/Device.c:300 #, fuzzy msgid "Failed to acquire mutex" -msgstr "Konnte keinen RX Buffer allozieren" +msgstr "Akquirieren des Mutex gescheitert" #: ports/nrf/common-hal/bleio/Device.c:278 #: ports/nrf/common-hal/bleio/Device.c:311 @@ -762,105 +761,105 @@ msgstr "Konnte keinen RX Buffer allozieren" #: ports/nrf/common-hal/bleio/Device.c:376 #, fuzzy msgid "Failed to release mutex" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" +msgstr "Loslassen des Mutex gescheitert" #: ports/nrf/common-hal/bleio/Device.c:387 #, fuzzy msgid "Failed to continue scanning" -msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" +msgstr "Der Scanvorgang kann nicht fortgesetzt werden" #: ports/nrf/common-hal/bleio/Device.c:419 #, fuzzy msgid "Failed to connect:" -msgstr "Kann nicht verbinden. Status: 0x%02x" +msgstr "Das Verbinden ist fehlgeschlagen:" #: ports/nrf/common-hal/bleio/Device.c:489 #, fuzzy msgid "Failed to add service" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" +msgstr "Dienst konnte nicht hinzugefügt werden" #: ports/nrf/common-hal/bleio/Device.c:506 #, fuzzy msgid "Failed to start advertising" -msgstr "Kann advertisement nicht starten. Status: 0x%02x" +msgstr "Kann advertisement nicht starten" #: ports/nrf/common-hal/bleio/Device.c:523 #, fuzzy msgid "Failed to stop advertising" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" +msgstr "Kann advertisement nicht stoppen" #: ports/nrf/common-hal/bleio/Device.c:548 #, fuzzy msgid "Failed to start scanning" -msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" +msgstr "Der Scanvorgang kann nicht gestartet werden" #: ports/nrf/common-hal/bleio/Device.c:564 #, fuzzy msgid "Failed to create mutex" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" +msgstr "Erstellen des Mutex ist fehlgeschlagen" #: ports/nrf/common-hal/bleio/Peripheral.c:304 #, fuzzy, c-format msgid "Failed to add service, err 0x%04x" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" +msgstr "Dienst konnte nicht hinzugefügt werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Scanner.c:75 #, fuzzy, c-format msgid "Failed to continue scanning, err 0x%04x" -msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" +msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Scanner.c:101 #, fuzzy, c-format msgid "Failed to start scanning, err 0x%04x" -msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" +msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Service.c:88 #, fuzzy, c-format msgid "Failed to add characteristic, err 0x%04x" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" +msgstr "Fehler beim Hinzufügen des Merkmals. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Service.c:92 msgid "Characteristic already in use by another Service." -msgstr "" +msgstr "Merkmal wird bereits von einem anderen Dienst verwendet." #: ports/nrf/common-hal/bleio/UUID.c:54 #, fuzzy, c-format msgid "Failed to register Vendor-Specific UUID, err 0x%04x" -msgstr "Kann keine herstellerspezifische 128-Bit-UUID hinzufügen." +msgstr "Kann keine herstellerspezifische UUID hinzufügen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/UUID.c:73 #, c-format msgid "Could not decode ble_uuid, err 0x%04x" -msgstr "" +msgstr "Konnte ble_uuid nicht decodieren. Status: 0x%04x" #: ports/nrf/common-hal/bleio/UUID.c:88 msgid "Unexpected nrfx uuid type" -msgstr "" +msgstr "Unerwarteter nrfx uuid-Typ" #: ports/nrf/common-hal/busio/I2C.c:98 #, fuzzy msgid "All I2C peripherals are in use" -msgstr "Alle timer werden benutzt" +msgstr "Alle I2C-Peripheriegeräte sind in Benutzung" #: ports/nrf/common-hal/busio/SPI.c:133 #, fuzzy msgid "All SPI peripherals are in use" -msgstr "Alle timer werden benutzt" +msgstr "Alle SPI-Peripheriegeräte sind in Benutzung" #: ports/nrf/common-hal/busio/UART.c:49 #, c-format msgid "error = 0x%08lX" -msgstr "" +msgstr "error = 0x%08lX" #: ports/nrf/common-hal/busio/UART.c:122 #, fuzzy msgid "Invalid buffer size" -msgstr "ungültiger dupterm index" +msgstr "Ungültige Puffergröße" #: ports/nrf/common-hal/busio/UART.c:126 #, fuzzy msgid "Odd parity is not supported" -msgstr "bytes mit merh als 8 bits werden nicht unterstützt" +msgstr "bytes mit mehr als 8 bits werden nicht unterstützt" #: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 #: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 @@ -868,17 +867,17 @@ msgstr "bytes mit merh als 8 bits werden nicht unterstützt" #: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 #: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" -msgstr "" +msgstr "Kann busio.UART nicht finden" #: ports/nrf/common-hal/microcontroller/Processor.c:48 #, fuzzy msgid "Cannot get temperature" -msgstr "Kann PPCP Parameter nicht setzen." +msgstr "Kann Temperatur nicht holen" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 #, fuzzy msgid "All PWM peripherals are in use" -msgstr "Alle timer werden benutzt" +msgstr "Alle PWM-Peripheriegeräte werden verwendet" #: ports/unix/modffi.c:138 msgid "Unknown type" @@ -890,7 +889,7 @@ msgstr "Fehler in ffi_prep_cif" #: ports/unix/modffi.c:270 msgid "ffi_prep_closure_loc" -msgstr "" +msgstr "ffi_prep_closure_loc" #: ports/unix/modffi.c:413 msgid "Don't know how to pass object to native function" From 62df7ab73053fcf7b7eac54adbc90be9328df347 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 20 Jan 2019 15:10:09 -0500 Subject: [PATCH 140/153] Improve struct compatibility with CPython --- py/binary.c | 7 +- py/modstruct.c | 16 ++++- shared-bindings/struct/__init__.c | 63 +++++++++++------ shared-bindings/struct/__init__.h | 2 +- shared-module/struct/__init__.c | 113 ++++++++++++++++++------------ 5 files changed, 126 insertions(+), 75 deletions(-) diff --git a/py/binary.c b/py/binary.c index ca851c9369ecb..9c3a49e8f998e 100644 --- a/py/binary.c +++ b/py/binary.c @@ -49,7 +49,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { switch (struct_type) { case '<': case '>': switch (val_type) { - case 'b': case 'B': + case 'b': case 'B': case 'x': size = 1; break; case 'h': case 'H': size = 2; break; @@ -79,7 +79,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { // particular (or any) ABI. switch (val_type) { case BYTEARRAY_TYPECODE: - case 'b': case 'B': + case 'b': case 'B': case 'x': align = size = 1; break; case 'h': case 'H': align = alignof(short); @@ -126,6 +126,7 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) { break; case BYTEARRAY_TYPECODE: case 'B': + case 'x': // value will be discarded val = ((unsigned char*)p)[index]; break; case 'h': @@ -364,6 +365,8 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, m case 'B': ((unsigned char*)p)[index] = val; break; + case 'x': + ((unsigned char*)p)[index] = 0; case 'h': ((short*)p)[index] = val; break; diff --git a/py/modstruct.c b/py/modstruct.c index 3f1b2f8b8cdd0..a238d3935a2d2 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -97,7 +97,10 @@ STATIC size_t calc_size_items(const char *fmt, size_t *total_sz) { total_cnt += 1; size += cnt; } else { - total_cnt += cnt; + // Pad bytes are skipped and don't get included in the item count. + if (*fmt != 'x') { + total_cnt += cnt; + } mp_uint_t align; size_t sz = mp_binary_get_size(fmt_type, *fmt, &align); while (cnt--) { @@ -166,7 +169,10 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) { } else { while (cnt--) { item = mp_binary_get_val(fmt_type, *fmt, &p); - res->items[i++] = item; + // Pad bytes ('x') are just skipped. + if (*fmt != 'x') { + res->items[i++] = item; + } } } fmt++; @@ -204,7 +210,11 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c } else { // If we run out of args then we just finish; CPython would raise struct.error while (cnt-- && i < n_args) { - mp_binary_set_val(fmt_type, *fmt, args[i++], &p); + mp_binary_set_val(fmt_type, *fmt, args[i], &p); + // Pad bytes don't have a corresponding argument. + if (*fmt != 'x') { + i++; + } } } fmt++; diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c index 0935977859c5c..9240a15bb1cfc 100644 --- a/shared-bindings/struct/__init__.c +++ b/shared-bindings/struct/__init__.c @@ -51,7 +51,7 @@ //| //| Supported size/byte order prefixes: *@*, *<*, *>*, *!*. //| -//| Supported format codes: *b*, *B*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*, +//| Supported format codes: *b*, *B*, *x*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*, //| *s*, *P*, *f*, *d* (the latter 2 depending on the floating-point support). //| @@ -74,7 +74,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize); //| STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) { - // TODO: "The arguments must match the values required by the format exactly." mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); vstr_t vstr; vstr_init_len(&vstr, size); @@ -115,49 +114,67 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_into_obj, 3, MP_OBJ_FUN_ARGS_MAX //| .. function:: unpack(fmt, data) //| //| Unpack from the data according to the format string fmt. The return value -//| is a tuple of the unpacked values. +//| is a tuple of the unpacked values. The buffer size must match the size +//| required by the format. //| -//| .. function:: unpack_from(fmt, data, offset) +STATIC mp_obj_t struct_unpack(size_t n_args, const mp_obj_t *args) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); + byte *p = bufinfo.buf; + byte *end_p = &p[bufinfo.len]; + + // true means check the size must be exactly right. + return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[0] , p, end_p, true)); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_obj, 2, 3, struct_unpack); + +//| .. function:: unpack_from(fmt, data, offset=0) //| //| Unpack from the data starting at offset according to the format string fmt. //| offset may be negative to count from the end of buffer. The return value is -//| a tuple of the unpacked values. +//| a tuple of the unpacked values. The buffer size must be at least as big +//| as the size required by the form. //| -STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) { - // unpack requires that the buffer be exactly the right size. - // unpack_from requires that the buffer be "big enough". - // Since we implement unpack and unpack_from using the same function - // we relax the "exact" requirement, and only implement "big enough". +STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_format, ARG_buffer, ARG_offset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_format, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_offset, MP_ARG_INT, {.u_int = 0} }, + }; + + 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); + mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); byte *p = bufinfo.buf; byte *end_p = &p[bufinfo.len]; - if (n_args > 2) { - mp_int_t offset = mp_obj_get_int(args[2]); - // offset arg provided + mp_int_t offset = args[ARG_offset].u_int; + if (offset < 0) { + // negative offsets are relative to the end of the buffer + offset = bufinfo.len + offset; if (offset < 0) { - // negative offsets are relative to the end of the buffer - offset = bufinfo.len + offset; - if (offset < 0) { - mp_raise_RuntimeError(translate("buffer too small")); - } + mp_raise_RuntimeError(translate("buffer too small")); } - p += offset; } + p += offset; - return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[0] , p, end_p)); + // false means the size doesn't have to be exact. struct.unpack_from() only requires + // that be buffer be big enough. + return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[ARG_format].u_obj, p, end_p, false)); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_from_obj, 2, 3, struct_unpack_from); +MP_DEFINE_CONST_FUN_OBJ_KW(struct_unpack_from_obj, 0, struct_unpack_from); STATIC const mp_rom_map_elem_t mp_module_struct_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_struct) }, { MP_ROM_QSTR(MP_QSTR_calcsize), MP_ROM_PTR(&struct_calcsize_obj) }, { MP_ROM_QSTR(MP_QSTR_pack), MP_ROM_PTR(&struct_pack_obj) }, { MP_ROM_QSTR(MP_QSTR_pack_into), MP_ROM_PTR(&struct_pack_into_obj) }, - { MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&struct_unpack_from_obj) }, + { MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&struct_unpack_obj) }, { MP_ROM_QSTR(MP_QSTR_unpack_from), MP_ROM_PTR(&struct_unpack_from_obj) }, }; diff --git a/shared-bindings/struct/__init__.h b/shared-bindings/struct/__init__.h index c4e867aaaf3a6..a7e72b11c7577 100644 --- a/shared-bindings/struct/__init__.h +++ b/shared-bindings/struct/__init__.h @@ -29,6 +29,6 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args); mp_uint_t shared_modules_struct_calcsize(mp_obj_t fmt_in); -mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p); +mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p, bool exact_size); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_RANDOM___INIT___H diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c index 78c04f07bab4d..28e7c0c3f93e6 100644 --- a/shared-module/struct/__init__.c +++ b/shared-module/struct/__init__.c @@ -71,45 +71,6 @@ mp_uint_t get_fmt_num(const char **p) { return val; } -void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args) { - const char *fmt = mp_obj_str_get_str(fmt_in); - char fmt_type = get_fmt_type(&fmt); - - size_t i; - for (i = 0; i < n_args;) { - mp_uint_t sz = 1; - if (*fmt == '\0') { - // more arguments given than used by format string; CPython raises struct.error here - mp_raise_RuntimeError(translate("too many arguments provided with the given format")); - } - struct_validate_format(*fmt); - - if (unichar_isdigit(*fmt)) { - sz = get_fmt_num(&fmt); - } - if (p + sz > end_p) { - mp_raise_RuntimeError(translate("buffer too small")); - } - - if (*fmt == 's') { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ); - mp_uint_t to_copy = sz; - if (bufinfo.len < to_copy) { - to_copy = bufinfo.len; - } - memcpy(p, bufinfo.buf, to_copy); - memset(p + to_copy, 0, sz - to_copy); - p += sz; - } else { - while (sz--) { - mp_binary_set_val(fmt_type, *fmt, args[i++], &p); - } - } - fmt++; - } -} - mp_uint_t calcsize_items(const char *fmt) { mp_uint_t cnt = 0; while (*fmt) { @@ -120,7 +81,10 @@ mp_uint_t calcsize_items(const char *fmt) { num = 1; } } - cnt += num; + // Pad bytes are skipped and don't get included in the item count. + if (*fmt != 'x') { + cnt += num; + } fmt++; } return cnt; @@ -155,14 +119,71 @@ mp_uint_t shared_modules_struct_calcsize(mp_obj_t fmt_in) { return size; } +void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args) { + const char *fmt = mp_obj_str_get_str(fmt_in); + char fmt_type = get_fmt_type(&fmt); + const mp_uint_t total_sz = shared_modules_struct_calcsize(fmt_in); + + if (p + total_sz != end_p) { + mp_raise_msg_varg(&mp_type_RuntimeError, translate("unpack requires a buffer of %d bytes"), total_sz); + } + + size_t i; + for (i = 0; i < n_args;) { + mp_uint_t sz = 1; + if (*fmt == '\0') { + // more arguments given than used by format string; CPython raises struct.error here + mp_raise_RuntimeError(translate("too many arguments provided with the given format")); + } + struct_validate_format(*fmt); + + if (unichar_isdigit(*fmt)) { + sz = get_fmt_num(&fmt); + } + + if (*fmt == 's') { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ); + mp_uint_t to_copy = sz; + if (bufinfo.len < to_copy) { + to_copy = bufinfo.len; + } + memcpy(p, bufinfo.buf, to_copy); + memset(p + to_copy, 0, sz - to_copy); + p += sz; + } else { + while (sz--) { + mp_binary_set_val(fmt_type, *fmt, args[i], &p); + // Pad bytes don't have a corresponding argument. + if (*fmt != 'x') { + i++; + } + } + } + fmt++; + } +} -mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p) { +mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p, bool exact_size) { const char *fmt = mp_obj_str_get_str(fmt_in); char fmt_type = get_fmt_type(&fmt); - mp_uint_t num_items = calcsize_items(fmt); + const mp_uint_t num_items = calcsize_items(fmt); + const mp_uint_t total_sz = shared_modules_struct_calcsize(fmt_in); mp_obj_tuple_t *res = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_items, NULL)); + // If exact_size, make sure the buffer is exactly the right size. + // Otherwise just make sure it's big enough. + if (exact_size) { + if (p + total_sz != end_p) { + mp_raise_RuntimeError(translate("buffer size must match format")); + } + } else { + if (p + total_sz > end_p) { + mp_raise_RuntimeError(translate("buffer too small")); + } + } + for (uint i = 0; i < num_items;) { mp_uint_t sz = 1; @@ -171,9 +192,6 @@ mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byt if (unichar_isdigit(*fmt)) { sz = get_fmt_num(&fmt); } - if (p + sz > end_p) { - mp_raise_RuntimeError(translate("buffer too small")); - } mp_obj_t item; if (*fmt == 's') { item = mp_obj_new_bytes(p, sz); @@ -182,7 +200,10 @@ mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byt } else { while (sz--) { item = mp_binary_get_val(fmt_type, *fmt, &p); - res->items[i++] = item; + // Pad bytes are not stored. + if (*fmt != 'x') { + res->items[i++] = item; + } } } fmt++; From 7a09af73ec7f4a11a1404dff6276e09072d06983 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 20 Jan 2019 15:10:09 -0500 Subject: [PATCH 141/153] Improve struct compatibility with CPython --- py/binary.c | 7 +- py/modstruct.c | 16 ++++- shared-bindings/struct/__init__.c | 63 +++++++++++------ shared-bindings/struct/__init__.h | 2 +- shared-module/struct/__init__.c | 113 ++++++++++++++++++------------ 5 files changed, 126 insertions(+), 75 deletions(-) diff --git a/py/binary.c b/py/binary.c index ca851c9369ecb..9c3a49e8f998e 100644 --- a/py/binary.c +++ b/py/binary.c @@ -49,7 +49,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { switch (struct_type) { case '<': case '>': switch (val_type) { - case 'b': case 'B': + case 'b': case 'B': case 'x': size = 1; break; case 'h': case 'H': size = 2; break; @@ -79,7 +79,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { // particular (or any) ABI. switch (val_type) { case BYTEARRAY_TYPECODE: - case 'b': case 'B': + case 'b': case 'B': case 'x': align = size = 1; break; case 'h': case 'H': align = alignof(short); @@ -126,6 +126,7 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) { break; case BYTEARRAY_TYPECODE: case 'B': + case 'x': // value will be discarded val = ((unsigned char*)p)[index]; break; case 'h': @@ -364,6 +365,8 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, m case 'B': ((unsigned char*)p)[index] = val; break; + case 'x': + ((unsigned char*)p)[index] = 0; case 'h': ((short*)p)[index] = val; break; diff --git a/py/modstruct.c b/py/modstruct.c index 3f1b2f8b8cdd0..a238d3935a2d2 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -97,7 +97,10 @@ STATIC size_t calc_size_items(const char *fmt, size_t *total_sz) { total_cnt += 1; size += cnt; } else { - total_cnt += cnt; + // Pad bytes are skipped and don't get included in the item count. + if (*fmt != 'x') { + total_cnt += cnt; + } mp_uint_t align; size_t sz = mp_binary_get_size(fmt_type, *fmt, &align); while (cnt--) { @@ -166,7 +169,10 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) { } else { while (cnt--) { item = mp_binary_get_val(fmt_type, *fmt, &p); - res->items[i++] = item; + // Pad bytes ('x') are just skipped. + if (*fmt != 'x') { + res->items[i++] = item; + } } } fmt++; @@ -204,7 +210,11 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c } else { // If we run out of args then we just finish; CPython would raise struct.error while (cnt-- && i < n_args) { - mp_binary_set_val(fmt_type, *fmt, args[i++], &p); + mp_binary_set_val(fmt_type, *fmt, args[i], &p); + // Pad bytes don't have a corresponding argument. + if (*fmt != 'x') { + i++; + } } } fmt++; diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c index 0935977859c5c..9240a15bb1cfc 100644 --- a/shared-bindings/struct/__init__.c +++ b/shared-bindings/struct/__init__.c @@ -51,7 +51,7 @@ //| //| Supported size/byte order prefixes: *@*, *<*, *>*, *!*. //| -//| Supported format codes: *b*, *B*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*, +//| Supported format codes: *b*, *B*, *x*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*, //| *s*, *P*, *f*, *d* (the latter 2 depending on the floating-point support). //| @@ -74,7 +74,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize); //| STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) { - // TODO: "The arguments must match the values required by the format exactly." mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); vstr_t vstr; vstr_init_len(&vstr, size); @@ -115,49 +114,67 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_into_obj, 3, MP_OBJ_FUN_ARGS_MAX //| .. function:: unpack(fmt, data) //| //| Unpack from the data according to the format string fmt. The return value -//| is a tuple of the unpacked values. +//| is a tuple of the unpacked values. The buffer size must match the size +//| required by the format. //| -//| .. function:: unpack_from(fmt, data, offset) +STATIC mp_obj_t struct_unpack(size_t n_args, const mp_obj_t *args) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); + byte *p = bufinfo.buf; + byte *end_p = &p[bufinfo.len]; + + // true means check the size must be exactly right. + return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[0] , p, end_p, true)); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_obj, 2, 3, struct_unpack); + +//| .. function:: unpack_from(fmt, data, offset=0) //| //| Unpack from the data starting at offset according to the format string fmt. //| offset may be negative to count from the end of buffer. The return value is -//| a tuple of the unpacked values. +//| a tuple of the unpacked values. The buffer size must be at least as big +//| as the size required by the form. //| -STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) { - // unpack requires that the buffer be exactly the right size. - // unpack_from requires that the buffer be "big enough". - // Since we implement unpack and unpack_from using the same function - // we relax the "exact" requirement, and only implement "big enough". +STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_format, ARG_buffer, ARG_offset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_format, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_offset, MP_ARG_INT, {.u_int = 0} }, + }; + + 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); + mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); byte *p = bufinfo.buf; byte *end_p = &p[bufinfo.len]; - if (n_args > 2) { - mp_int_t offset = mp_obj_get_int(args[2]); - // offset arg provided + mp_int_t offset = args[ARG_offset].u_int; + if (offset < 0) { + // negative offsets are relative to the end of the buffer + offset = bufinfo.len + offset; if (offset < 0) { - // negative offsets are relative to the end of the buffer - offset = bufinfo.len + offset; - if (offset < 0) { - mp_raise_RuntimeError(translate("buffer too small")); - } + mp_raise_RuntimeError(translate("buffer too small")); } - p += offset; } + p += offset; - return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[0] , p, end_p)); + // false means the size doesn't have to be exact. struct.unpack_from() only requires + // that be buffer be big enough. + return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[ARG_format].u_obj, p, end_p, false)); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_from_obj, 2, 3, struct_unpack_from); +MP_DEFINE_CONST_FUN_OBJ_KW(struct_unpack_from_obj, 0, struct_unpack_from); STATIC const mp_rom_map_elem_t mp_module_struct_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_struct) }, { MP_ROM_QSTR(MP_QSTR_calcsize), MP_ROM_PTR(&struct_calcsize_obj) }, { MP_ROM_QSTR(MP_QSTR_pack), MP_ROM_PTR(&struct_pack_obj) }, { MP_ROM_QSTR(MP_QSTR_pack_into), MP_ROM_PTR(&struct_pack_into_obj) }, - { MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&struct_unpack_from_obj) }, + { MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&struct_unpack_obj) }, { MP_ROM_QSTR(MP_QSTR_unpack_from), MP_ROM_PTR(&struct_unpack_from_obj) }, }; diff --git a/shared-bindings/struct/__init__.h b/shared-bindings/struct/__init__.h index c4e867aaaf3a6..a7e72b11c7577 100644 --- a/shared-bindings/struct/__init__.h +++ b/shared-bindings/struct/__init__.h @@ -29,6 +29,6 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args); mp_uint_t shared_modules_struct_calcsize(mp_obj_t fmt_in); -mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p); +mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p, bool exact_size); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_RANDOM___INIT___H diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c index 78c04f07bab4d..28e7c0c3f93e6 100644 --- a/shared-module/struct/__init__.c +++ b/shared-module/struct/__init__.c @@ -71,45 +71,6 @@ mp_uint_t get_fmt_num(const char **p) { return val; } -void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args) { - const char *fmt = mp_obj_str_get_str(fmt_in); - char fmt_type = get_fmt_type(&fmt); - - size_t i; - for (i = 0; i < n_args;) { - mp_uint_t sz = 1; - if (*fmt == '\0') { - // more arguments given than used by format string; CPython raises struct.error here - mp_raise_RuntimeError(translate("too many arguments provided with the given format")); - } - struct_validate_format(*fmt); - - if (unichar_isdigit(*fmt)) { - sz = get_fmt_num(&fmt); - } - if (p + sz > end_p) { - mp_raise_RuntimeError(translate("buffer too small")); - } - - if (*fmt == 's') { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ); - mp_uint_t to_copy = sz; - if (bufinfo.len < to_copy) { - to_copy = bufinfo.len; - } - memcpy(p, bufinfo.buf, to_copy); - memset(p + to_copy, 0, sz - to_copy); - p += sz; - } else { - while (sz--) { - mp_binary_set_val(fmt_type, *fmt, args[i++], &p); - } - } - fmt++; - } -} - mp_uint_t calcsize_items(const char *fmt) { mp_uint_t cnt = 0; while (*fmt) { @@ -120,7 +81,10 @@ mp_uint_t calcsize_items(const char *fmt) { num = 1; } } - cnt += num; + // Pad bytes are skipped and don't get included in the item count. + if (*fmt != 'x') { + cnt += num; + } fmt++; } return cnt; @@ -155,14 +119,71 @@ mp_uint_t shared_modules_struct_calcsize(mp_obj_t fmt_in) { return size; } +void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args) { + const char *fmt = mp_obj_str_get_str(fmt_in); + char fmt_type = get_fmt_type(&fmt); + const mp_uint_t total_sz = shared_modules_struct_calcsize(fmt_in); + + if (p + total_sz != end_p) { + mp_raise_msg_varg(&mp_type_RuntimeError, translate("unpack requires a buffer of %d bytes"), total_sz); + } + + size_t i; + for (i = 0; i < n_args;) { + mp_uint_t sz = 1; + if (*fmt == '\0') { + // more arguments given than used by format string; CPython raises struct.error here + mp_raise_RuntimeError(translate("too many arguments provided with the given format")); + } + struct_validate_format(*fmt); + + if (unichar_isdigit(*fmt)) { + sz = get_fmt_num(&fmt); + } + + if (*fmt == 's') { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ); + mp_uint_t to_copy = sz; + if (bufinfo.len < to_copy) { + to_copy = bufinfo.len; + } + memcpy(p, bufinfo.buf, to_copy); + memset(p + to_copy, 0, sz - to_copy); + p += sz; + } else { + while (sz--) { + mp_binary_set_val(fmt_type, *fmt, args[i], &p); + // Pad bytes don't have a corresponding argument. + if (*fmt != 'x') { + i++; + } + } + } + fmt++; + } +} -mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p) { +mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p, bool exact_size) { const char *fmt = mp_obj_str_get_str(fmt_in); char fmt_type = get_fmt_type(&fmt); - mp_uint_t num_items = calcsize_items(fmt); + const mp_uint_t num_items = calcsize_items(fmt); + const mp_uint_t total_sz = shared_modules_struct_calcsize(fmt_in); mp_obj_tuple_t *res = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_items, NULL)); + // If exact_size, make sure the buffer is exactly the right size. + // Otherwise just make sure it's big enough. + if (exact_size) { + if (p + total_sz != end_p) { + mp_raise_RuntimeError(translate("buffer size must match format")); + } + } else { + if (p + total_sz > end_p) { + mp_raise_RuntimeError(translate("buffer too small")); + } + } + for (uint i = 0; i < num_items;) { mp_uint_t sz = 1; @@ -171,9 +192,6 @@ mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byt if (unichar_isdigit(*fmt)) { sz = get_fmt_num(&fmt); } - if (p + sz > end_p) { - mp_raise_RuntimeError(translate("buffer too small")); - } mp_obj_t item; if (*fmt == 's') { item = mp_obj_new_bytes(p, sz); @@ -182,7 +200,10 @@ mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byt } else { while (sz--) { item = mp_binary_get_val(fmt_type, *fmt, &p); - res->items[i++] = item; + // Pad bytes are not stored. + if (*fmt != 'x') { + res->items[i++] = item; + } } } fmt++; From 5ddc50473a37959fcac5a768013c825b1b1d8d23 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Sun, 20 Jan 2019 16:18:34 -0800 Subject: [PATCH 142/153] Check for null kw_args --- py/objnamedtuple.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 781a1871bfe54..a044fe3ff81c4 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -96,7 +96,10 @@ void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { const mp_obj_namedtuple_type_t *type = (const mp_obj_namedtuple_type_t*)type_in; size_t num_fields = type->n_fields; - size_t n_kw = kw_args->used; + size_t n_kw = 0; + if (kw_args != NULL) { + n_kw = kw_args->used; + } if (n_args + n_kw != num_fields) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); From 479b28660006a0e4f2febb67a0bd8e517290cd78 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Sun, 20 Jan 2019 17:32:43 -0800 Subject: [PATCH 143/153] Fix dict_make_new --- py/objdict.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/py/objdict.c b/py/objdict.c index f672ac039e51c..683fcb748ec46 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -91,7 +91,10 @@ STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, const mp } #endif if (n_args > 0 || kw_args != NULL) { - mp_obj_t args2[2] = {dict_out, args[0]}; // args[0] is always valid, even if it's not a positional arg + mp_obj_t args2[2] = {dict_out, NULL}; // args[0] is always valid, even if it's not a positional arg + if (n_args > 0) { + args2[1] = args[0]; + } dict_update(n_args + 1, args2, kw_args); // dict_update will check that n_args + 1 == 1 or 2 } return dict_out; From 3d11dd077c225e6b1c01ff9befd2d6fcc910c553 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Sun, 20 Jan 2019 17:33:18 -0800 Subject: [PATCH 144/153] Update translations --- locale/ID.po | 74 +++++++++++-------------- locale/circuitpython.pot | 50 +++++++---------- locale/de_DE.po | 104 ++++++++++++++++------------------- locale/en_US.po | 50 +++++++---------- locale/es.po | 112 +++++++++++++++++--------------------- locale/fil.po | 114 ++++++++++++++++++--------------------- locale/fr.po | 112 +++++++++++++++++--------------------- locale/it_IT.po | 102 ++++++++++++++++------------------- locale/pt_BR.po | 84 +++++++++++++---------------- 9 files changed, 347 insertions(+), 455 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index ae18a14d0d4dd..8547493e96254 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,8 +21,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "perangkat I2C tidak valid" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "operasi I2C tidak didukung" @@ -904,7 +904,7 @@ msgstr "[addrinfo error %d]" msgid "function does not take keyword arguments" msgstr "fungsi tidak dapat mengambil argumen keyword" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "fungsi mengambil posisi argumen %d tapi %d yang diberikan" @@ -939,7 +939,7 @@ msgstr "argumen num/types tidak cocok" msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "argumen keyword belum diimplementasi - gunakan args normal" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" @@ -951,11 +951,11 @@ msgstr "argumen keyword tidak diharapkan" msgid "keywords must be strings" msgstr "keyword harus berupa string" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "keyword argumen '%q' tidak diharapkan" @@ -1543,11 +1543,11 @@ msgstr "" msgid "empty" msgstr "" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "" @@ -2288,29 +2288,21 @@ msgstr "" msgid "color should be an int" msgstr "" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "" @@ -2339,10 +2331,6 @@ msgstr "" msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 msgid "start_x should be an int" msgstr "" @@ -2682,11 +2670,11 @@ msgstr "" msgid "No default I2C bus" msgstr "Tidak ada standar bus I2C" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "Tidak ada standar bus SPI" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "Tidak ada standar bus UART" @@ -2751,24 +2739,24 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid UUID string length" -#~ msgstr "Panjang string UUID tidak valid" - #~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" -#~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " -#~ "CIRCUITPY).\n" +#~ "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parameter UUID tidak valid" #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" #~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parameter UUID tidak valid" - #~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" #~ msgstr "" -#~ "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" +#~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " +#~ "CIRCUITPY).\n" + +#~ msgid "Invalid UUID string length" +#~ msgstr "Panjang string UUID tidak valid" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index e52ee4df47333..0a9e67685f0b0 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: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,8 +21,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "" @@ -877,7 +877,7 @@ msgstr "" msgid "function does not take keyword arguments" msgstr "" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" @@ -912,7 +912,7 @@ msgstr "" msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "" @@ -924,11 +924,11 @@ msgstr "" msgid "keywords must be strings" msgstr "" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "" @@ -1510,11 +1510,11 @@ msgstr "" msgid "empty" msgstr "" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "" @@ -2252,29 +2252,21 @@ msgstr "" msgid "color should be an int" msgstr "" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "" @@ -2303,10 +2295,6 @@ msgstr "" msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 msgid "start_x should be an int" msgstr "" @@ -2645,11 +2633,11 @@ msgstr "" msgid "No default I2C bus" msgstr "" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index a6d7b6103c546..170104e9fe855 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -21,8 +21,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "ungültige I2C Schnittstelle" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "I2C-operation nicht unterstützt" @@ -904,7 +904,7 @@ msgstr "" msgid "function does not take keyword arguments" msgstr "" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" @@ -939,7 +939,7 @@ msgstr "" msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "" @@ -951,11 +951,11 @@ msgstr "" msgid "keywords must be strings" msgstr "" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "" @@ -1539,11 +1539,11 @@ msgstr "" msgid "empty" msgstr "" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "" @@ -2288,29 +2288,21 @@ msgstr "" msgid "color should be an int" msgstr "" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "" @@ -2339,10 +2331,6 @@ msgstr "" msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 msgid "start_x should be an int" msgstr "" @@ -2684,11 +2672,11 @@ msgstr "USB Fehler" msgid "No default I2C bus" msgstr "Kein Standard I2C Bus" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "Kein Standard SPI Bus" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "Kein Standard UART Bus" @@ -2754,34 +2742,19 @@ msgstr "" #~ msgid "Invalid UUID string length" #~ msgstr "Ungültige UUID-Stringlänge" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Ungültiger UUID-Parameter" - -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" - -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." - -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" #~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." +#~ msgid "Invalid UUID parameter" +#~ msgstr "Ungültiger UUID-Parameter" + +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2790,11 +2763,26 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." #~ msgid "Can not query for the device address." #~ msgstr "Kann nicht nach der Geräteadresse suchen." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" + +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." diff --git a/locale/en_US.po b/locale/en_US.po index 1fd9cd3779de3..acd5f54cb4600 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -21,8 +21,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "" @@ -877,7 +877,7 @@ msgstr "" msgid "function does not take keyword arguments" msgstr "" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" @@ -912,7 +912,7 @@ msgstr "" msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "" @@ -924,11 +924,11 @@ msgstr "" msgid "keywords must be strings" msgstr "" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "" @@ -1510,11 +1510,11 @@ msgstr "" msgid "empty" msgstr "" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "" @@ -2252,29 +2252,21 @@ msgstr "" msgid "color should be an int" msgstr "" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "" @@ -2303,10 +2295,6 @@ msgstr "" msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 msgid "start_x should be an int" msgstr "" @@ -2645,11 +2633,11 @@ msgstr "" msgid "No default I2C bus" msgstr "" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "" diff --git a/locale/es.po b/locale/es.po index 8dd8ef920091c..799fc68bf6b7e 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -22,8 +22,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "periférico I2C inválido" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "operación I2C no soportada" @@ -901,7 +901,7 @@ msgstr "[addrinfo error %d]" msgid "function does not take keyword arguments" msgstr "la función no tiene argumentos por palabra clave" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "la función toma %d argumentos posicionales pero le fueron dados %d" @@ -938,7 +938,7 @@ msgstr "" "argumento(s) por palabra clave aún no implementados - usa argumentos " "normales en su lugar" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() toma %d argumentos posicionales pero %d fueron dados" @@ -950,11 +950,11 @@ msgstr "argumento por palabra clave inesperado" msgid "keywords must be strings" msgstr "palabras clave deben ser strings" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "la función tiene múltiples valores para el argumento '%q'" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "argumento por palabra clave inesperado '%q'" @@ -1546,11 +1546,11 @@ msgstr "lleno" msgid "empty" msgstr "vacío" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "popitem(): diccionario vacío" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "la secuencia de actualizacion del dict tiene una longitud incorrecta" @@ -2306,29 +2306,21 @@ msgstr "row data debe ser un buffer" msgid "color should be an int" msgstr "color deberia ser un int" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "displayio todavia esta en desarrollo" @@ -2357,10 +2349,6 @@ msgstr "color buffer deber ser un buffer o un int" msgid "palette_index should be an int" msgstr "palette_index deberia ser un int" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 #, fuzzy msgid "start_x should be an int" @@ -2706,11 +2694,11 @@ msgstr "Error USB" msgid "No default I2C bus" msgstr "Sin bus I2C por defecto" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "Sin bus SPI por defecto" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "Sin bus UART por defecto" @@ -2783,29 +2771,31 @@ msgstr "" "El botón reset fue presionado mientras arrancaba CircuitPython. Presiona " "otra vez para salir del modo seguro.\n" -#~ msgid "Wrong address length" -#~ msgstr "Longitud de address erronea" - #~ msgid "Invalid UUID string length" #~ msgstr "Longitud de string UUID inválida" #~ msgid "Invalid UUID parameter" #~ msgstr "Parámetro UUID inválido" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" #~ msgid "Cannot set PPCP parameters." #~ msgstr "No se pueden establecer los parámetros PPCP." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de Servicio inválido" - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "suficiente poder para todo el circuito y presiona reset (después de " +#~ "expulsar CIRCUITPY).\n" -#~ msgid "Wrong number of bytes provided" -#~ msgstr "Numero erroneo de bytes dados" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." #, fuzzy #~ msgid "" @@ -2814,31 +2804,29 @@ msgstr "" #~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " #~ "unidad de almacenamiento CIRCUITPY:\n" -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "suficiente poder para todo el circuito y presiona reset (después de " -#~ "expulsar CIRCUITPY).\n" +#~ msgid "Wrong address length" +#~ msgstr "Longitud de address erronea" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Numero erroneo de bytes dados" -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Baud rate demasiado alto para este periférico SPI" +#~ msgid "Can not add Service." +#~ msgstr "No se puede agregar el Servicio." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." #~ msgid "Can not encode UUID, to check length." #~ msgstr "No se puede codificar el UUID, para revisar la longitud." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." - -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." - -#~ msgid "Can not add Service." -#~ msgstr "No se puede agregar el Servicio." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" + +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" diff --git a/locale/fil.po b/locale/fil.po index 59c4150665b0a..6b3e408c7d2e6 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -21,8 +21,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "maling I2C peripheral" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "Hindi supportado ang operasyong I2C" @@ -902,7 +902,7 @@ msgstr "[addrinfo error %d]" msgid "function does not take keyword arguments" msgstr "ang function ay hindi kumukuha ng mga argumento ng keyword" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" @@ -940,7 +940,7 @@ msgstr "" "kindi pa ipinapatupad ang (mga) argument(s) ng keyword - gumamit ng normal " "args" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "" "Ang %q() ay kumukuha ng %d positional arguments pero %d lang ang binigay" @@ -953,11 +953,11 @@ msgstr "hindi inaasahang argumento ng keyword" msgid "keywords must be strings" msgstr "ang keywords dapat strings" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "ang function ay nakakuha ng maraming values para sa argument '%q'" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "hindi inaasahang argumento ng keyword na '%q'" @@ -1548,11 +1548,11 @@ msgstr "puno" msgid "empty" msgstr "walang laman" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "popitem(): dictionary ay walang laman" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "may mali sa haba ng dict update sequence" @@ -2311,29 +2311,21 @@ msgstr "row data ay dapat na buffer" msgid "color should be an int" msgstr "color ay dapat na int" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "displayio ay nasa gitna ng konstruksiyon" @@ -2362,10 +2354,6 @@ msgstr "color buffer ay dapat buffer or int" msgid "palette_index should be an int" msgstr "palette_index ay dapat na int" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 #, fuzzy msgid "start_x should be an int" @@ -2712,11 +2700,11 @@ msgstr "May pagkakamali ang USB" msgid "No default I2C bus" msgstr "Walang default na I2C bus" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "Walang default SPI bus" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "Walang default UART bus" @@ -2789,29 +2777,31 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#~ msgid "Wrong address length" -#~ msgstr "Mali ang address length" - #~ msgid "Invalid UUID string length" #~ msgstr "Mali ang UUID string length" #~ msgid "Invalid UUID parameter" #~ msgstr "Mali ang UUID parameter" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" #~ msgid "Cannot set PPCP parameters." #~ msgstr "Hindi ma-set ang PPCP parameters." -#~ msgid "Invalid Service type" -#~ msgstr "Mali ang tipo ng serbisyo" - -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " +#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" -#~ msgid "Wrong number of bytes provided" -#~ msgstr "Mali ang bilang ng bytes" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" @@ -2819,32 +2809,30 @@ msgstr "" #~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " #~ "drive:\n" -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " -#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" +#~ msgid "Wrong address length" +#~ msgstr "Mali ang address length" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Mali ang bilang ng bytes" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "ang palette ay dapat 32 bytes ang haba" +#~ msgid "Can not add Service." +#~ msgstr "Hindi maidaragdag ang serbisyo." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." #~ msgid "Can not encode UUID, to check length." #~ msgstr "Hindi ma-encode UUID, para suriin ang haba." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." - -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." - -#~ msgid "Can not add Service." -#~ msgstr "Hindi maidaragdag ang serbisyo." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" + +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "ang palette ay dapat 32 bytes ang haba" diff --git a/locale/fr.po b/locale/fr.po index 4ef9d9f872b62..236ce43456bb9 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: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -20,8 +20,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "périphérique I2C invalide" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "opération sur I2C non supportée" @@ -904,7 +904,7 @@ msgstr "" msgid "function does not take keyword arguments" msgstr "la fonction ne prend pas d'arguments nommés" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "la fonction prend %d argument(s) mais %d ont été donné(s)" @@ -940,7 +940,7 @@ msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" "argument(s) nommé(s) pas encore implémenté - utilisez les arguments normaux" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() prend %d arguments mais %d ont été donnés" @@ -952,11 +952,11 @@ msgstr "argument nommé imprévu" msgid "keywords must be strings" msgstr "les noms doivent être des chaînes de caractère" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "la fonction a reçu plusieurs valeurs pour l'argument '%q'" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "argument nommé '%q' imprévu" @@ -1546,11 +1546,11 @@ msgstr "plein" msgid "empty" msgstr "vide" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "popitem(): dictionnaire vide" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "la séquence de mise à jour de dict a une mauvaise longueur" @@ -2318,29 +2318,21 @@ msgstr "les données de ligne doivent être un tampon" msgid "color should be an int" msgstr "la couleur doit être un entier (int)" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "displayio est en cours de développement" @@ -2375,10 +2367,6 @@ msgstr "le tampon de couleur doit être un tampon ou un entier" msgid "palette_index should be an int" msgstr "palette_index devrait être un entier (int)'" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 #, fuzzy msgid "start_x should be an int" @@ -2736,11 +2724,11 @@ msgstr "Erreur USB" msgid "No default I2C bus" msgstr "Pas de bus I2C par défaut" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "Pas de bus SPI par défaut" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "Pas de bus UART par défaut" @@ -2818,44 +2806,47 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer denouveau pour quitter de le mode sans-échec.\n" -#~ msgid "Wrong address length" -#~ msgstr "Mauvaise longueur d'adresse" - #~ msgid "Invalid UUID string length" #~ msgstr "Longeur de chaîne UUID invalide" #~ msgid "Invalid UUID parameter" #~ msgstr "Paramètre UUID invalide" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" + +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" #~ msgid "Cannot apply GAP parameters." #~ msgstr "Impossible d'appliquer les paramètres GAP" -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." - -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" -#, fuzzy -#~ msgid "Wrong number of bytes provided" -#~ msgstr "mauvais nombre d'octets fourni'" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" #~ msgid "Can not encode UUID, to check length." #~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" +#~ msgid "Wrong address length" +#~ msgstr "Mauvaise longueur d'adresse" #, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size doit être une puissance de 2" +#~ msgid "Wrong number of bytes provided" +#~ msgstr "mauvais nombre d'octets fourni'" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2864,17 +2855,14 @@ msgstr "" #~ "assez de puissance pour l'ensemble du circuit et appuyez sur " #~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" - -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être une displayio.Palette" - -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" #~ msgid "Can not query for the device address." #~ msgstr "Impossible d'obtenir l'adresse du périphérique" + +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" diff --git a/locale/it_IT.po b/locale/it_IT.po index 47aff51660043..225e51cf5727a 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -21,8 +21,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "periferica I2C invalida" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "operazione I2C non supportata" @@ -905,7 +905,7 @@ msgstr "[errore addrinfo %d]" msgid "function does not take keyword arguments" msgstr "la funzione non prende argomenti nominati" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "" @@ -943,7 +943,7 @@ msgstr "" "argomento(i) nominati non ancora implementati - usare invece argomenti " "normali" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() prende %d argomenti posizionali ma ne sono stati forniti %d" @@ -955,11 +955,11 @@ msgstr "argomento nominato inaspettato" msgid "keywords must be strings" msgstr "argomenti nominati devono essere stringhe" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "la funzione ha ricevuto valori multipli per l'argomento '%q'" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "argomento nominato '%q' inaspettato" @@ -1546,11 +1546,11 @@ msgstr "pieno" msgid "empty" msgstr "vuoto" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "popitem(): il dizionario è vuoto" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "sequanza di aggiornamento del dizionario ha la lunghezza errata" @@ -2310,29 +2310,21 @@ msgstr "valori della riga devono essere un buffer" msgid "color should be an int" msgstr "il colore deve essere un int" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "" @@ -2363,10 +2355,6 @@ msgstr "il buffer del colore deve essere un buffer o un int" msgid "palette_index should be an int" msgstr "palette_index deve essere un int" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 #, fuzzy msgid "start_x should be an int" @@ -2718,11 +2706,11 @@ msgstr "Errore USB" msgid "No default I2C bus" msgstr "Nessun bus I2C predefinito" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "Nessun bus SPI predefinito" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "Nessun bus UART predefinito" @@ -2787,12 +2775,12 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parametro UUID non valido" - #~ msgid "Invalid UUID string length" #~ msgstr "Lunghezza della stringa UUID non valida" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parametro UUID non valido" + #~ msgid "Invalid Service type" #~ msgstr "Tipo di servizio non valido" @@ -2800,18 +2788,14 @@ msgstr "" #~ msgid "Wrong number of bytes provided" #~ msgstr "numero di argomenti errato" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." -#~ msgid "Can not add Service." -#~ msgstr "Non è possibile aggiungere Service." +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " -#~ "espulso CIRCUITPY).\n" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" @@ -2819,28 +2803,32 @@ msgstr "" #~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " #~ "CIRCUITPY:\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." - #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." -#~ msgid "Can not add Characteristic." -#~ msgstr "Non è possibile aggiungere Characteristic." +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" + +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" #~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " #~ "Whoops!\n" +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " +#~ "espulso CIRCUITPY).\n" + #~ msgid "Cannot apply GAP parameters." #~ msgstr "Impossibile applicare i parametri GAP." - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." - -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index e610577a1c5f9..a0d81d182bfd1 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-18 11:43-0800\n" +"POT-Creation-Date: 2019-01-20 17:33-0800\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -21,8 +21,8 @@ msgstr "" msgid "invalid I2C peripheral" msgstr "periférico I2C inválido" -#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 -#: extmod/machine_i2c.c:392 +#: extmod/machine_i2c.c:338 extmod/machine_i2c.c:352 extmod/machine_i2c.c:366 +#: extmod/machine_i2c.c:390 msgid "I2C operation not supported" msgstr "I2C operação não suportada" @@ -893,7 +893,7 @@ msgstr "" msgid "function does not take keyword arguments" msgstr "função não aceita argumentos de palavras-chave" -#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:105 +#: py/argcheck.c:63 py/bc.c:85 py/objnamedtuple.c:108 #, c-format msgid "function takes %d positional arguments but %d were given" msgstr "função leva %d argumentos posicionais, mas apenas %d foram passadas" @@ -928,7 +928,7 @@ msgstr "" msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c:88 py/objnamedtuple.c:109 +#: py/bc.c:88 py/objnamedtuple.c:112 msgid "%q() takes %d positional arguments but %d were given" msgstr "" @@ -940,11 +940,11 @@ msgstr "" msgid "keywords must be strings" msgstr "" -#: py/bc.c:206 py/objnamedtuple.c:139 +#: py/bc.c:206 py/objnamedtuple.c:142 msgid "function got multiple values for argument '%q'" msgstr "" -#: py/bc.c:218 py/objnamedtuple.c:131 +#: py/bc.c:218 py/objnamedtuple.c:134 msgid "unexpected keyword argument '%q'" msgstr "" @@ -1528,11 +1528,11 @@ msgstr "cheio" msgid "empty" msgstr "vazio" -#: py/objdict.c:312 +#: py/objdict.c:315 msgid "popitem(): dictionary is empty" msgstr "" -#: py/objdict.c:355 +#: py/objdict.c:358 msgid "dict update sequence has wrong length" msgstr "" @@ -2278,29 +2278,21 @@ msgstr "" msgid "color should be an int" msgstr "cor deve ser um int" -#: shared-bindings/displayio/Display.c:79 -msgid "Width and height kwargs required" +#: shared-bindings/displayio/Display.c:119 +msgid "Too many displays" msgstr "" -#: shared-bindings/displayio/Display.c:93 -msgid "Display limit reached" -msgstr "" - -#: shared-bindings/displayio/Display.c:112 +#: shared-bindings/displayio/Display.c:138 msgid "Must be a Group subclass." msgstr "" -#: shared-bindings/displayio/FourWire.c:69 -msgid "Command and chip_select required" +#: shared-bindings/displayio/FourWire.c:93 +#: shared-bindings/displayio/ParallelBus.c:98 +msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/FourWire.c:91 -#: shared-bindings/displayio/ParallelBus.c:94 -msgid "Display bus limit reached" -msgstr "" - -#: shared-bindings/displayio/FourWire.c:104 -#: shared-bindings/displayio/ParallelBus.c:106 +#: shared-bindings/displayio/FourWire.c:106 +#: shared-bindings/displayio/ParallelBus.c:110 msgid "displayio is a work in progress" msgstr "" @@ -2329,10 +2321,6 @@ msgstr "" msgid "palette_index should be an int" msgstr "" -#: shared-bindings/displayio/ParallelBus.c:75 -msgid "Data0, command, chip_select, write and read required" -msgstr "" - #: shared-bindings/displayio/Shape.c:92 #, fuzzy msgid "start_x should be an int" @@ -2675,11 +2663,11 @@ msgstr "Erro na USB" msgid "No default I2C bus" msgstr "Nenhum barramento I2C padrão" -#: supervisor/shared/board_busses.c:89 +#: supervisor/shared/board_busses.c:91 msgid "No default SPI bus" msgstr "Nenhum barramento SPI padrão" -#: supervisor/shared/board_busses.c:116 +#: supervisor/shared/board_busses.c:118 msgid "No default UART bus" msgstr "Nenhum barramento UART padrão" @@ -2738,32 +2726,32 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parâmetro UUID inválido" +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." + +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" #~ msgid "Can not add Characteristic." #~ msgstr "Não é possível adicionar Característica." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possível aplicar parâmetros GAP." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parâmetro UUID inválido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Pode codificar o UUID no pacote de anúncios." #~ msgid "Cannot set PPCP parameters." #~ msgstr "Não é possível definir parâmetros PPCP." - -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" - -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Não é possível aplicar parâmetros GAP." From 9558b3afa7d90e1f84070088b0f7c4c21def4683 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 20 Jan 2019 22:46:32 -0500 Subject: [PATCH 145/153] make translate --- locale/ID.po | 44 ++++++++++------- locale/circuitpython.pot | 19 ++++++-- locale/de_DE.po | 82 ++++++++++++++++++-------------- locale/en_US.po | 19 ++++++-- locale/es.po | 98 +++++++++++++++++++++----------------- locale/fil.po | 100 +++++++++++++++++++++------------------ locale/fr.po | 98 +++++++++++++++++++++----------------- locale/it_IT.po | 96 ++++++++++++++++++++----------------- locale/pt_BR.po | 58 +++++++++++++---------- 9 files changed, 351 insertions(+), 263 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 8547493e96254..cf317b42dc336 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1363,9 +1363,9 @@ msgstr "" msgid "schedule stack full" msgstr "" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2649,10 +2649,20 @@ msgstr "" msgid "'S' and 'O' are not supported format types" msgstr "" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, fuzzy, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" +#: shared-module/struct/__init__.c:179 +#, fuzzy +msgid "buffer size must match format" +msgstr "buffers harus mempunyai panjang yang sama" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." @@ -2739,24 +2749,24 @@ msgid "" "exit safe mode.\n" msgstr "" +#~ msgid "Invalid UUID string length" +#~ msgstr "Panjang string UUID tidak valid" + #~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" #~ msgstr "" -#~ "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" - -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parameter UUID tidak valid" +#~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " +#~ "CIRCUITPY).\n" #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" #~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parameter UUID tidak valid" + #~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" -#~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " -#~ "CIRCUITPY).\n" - -#~ msgid "Invalid UUID string length" -#~ msgstr "Panjang string UUID tidak valid" +#~ "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 0a9e67685f0b0..4962a67ab17c3 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: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1330,9 +1330,9 @@ msgstr "" msgid "schedule stack full" msgstr "" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2612,10 +2612,19 @@ msgstr "" msgid "'S' and 'O' are not supported format types" msgstr "" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" +#: shared-module/struct/__init__.c:179 +msgid "buffer size must match format" +msgstr "" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." diff --git a/locale/de_DE.po b/locale/de_DE.po index 170104e9fe855..fe16a724bc368 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -1359,9 +1359,9 @@ msgstr "" msgid "schedule stack full" msgstr "" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2651,10 +2651,20 @@ msgstr "Kann '/' nicht remounten when USB aktiv ist" msgid "'S' and 'O' are not supported format types" msgstr "" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, fuzzy, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "Konnte keine RX Buffer mit %d allozieren" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" +#: shared-module/struct/__init__.c:179 +#, fuzzy +msgid "buffer size must match format" +msgstr "Buffer müssen gleich lang sein" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." @@ -2739,22 +2749,29 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid UUID string length" -#~ msgstr "Ungültige UUID-Stringlänge" +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Ungültiger UUID-Parameter" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." + +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2763,26 +2780,19 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." - -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Ungültiger UUID-Parameter" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." +#~ msgid "Invalid UUID string length" +#~ msgstr "Ungültige UUID-Stringlänge" diff --git a/locale/en_US.po b/locale/en_US.po index acd5f54cb4600..33b1e614b23bf 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -1330,9 +1330,9 @@ msgstr "" msgid "schedule stack full" msgstr "" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2612,10 +2612,19 @@ msgstr "" msgid "'S' and 'O' are not supported format types" msgstr "" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" +#: shared-module/struct/__init__.c:179 +msgid "buffer size must match format" +msgstr "" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." diff --git a/locale/es.po b/locale/es.po index 799fc68bf6b7e..6daa4170b1ad8 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -1366,9 +1366,9 @@ msgstr "división por cero" msgid "schedule stack full" msgstr "" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "buffer demasiado pequeño" @@ -2673,10 +2673,20 @@ msgstr "No se puede volver a montar '/' cuando el USB esta activo." msgid "'S' and 'O' are not supported format types" msgstr "'S' y 'O' no son compatibles con los tipos de formato" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, fuzzy, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "Falló la asignación del buffer RX de %d bytes" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "demasiados argumentos provistos con el formato dado" +#: shared-module/struct/__init__.c:179 +#, fuzzy +msgid "buffer size must match format" +msgstr "los buffers deben de tener la misma longitud" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." @@ -2771,31 +2781,32 @@ msgstr "" "El botón reset fue presionado mientras arrancaba CircuitPython. Presiona " "otra vez para salir del modo seguro.\n" -#~ msgid "Invalid UUID string length" -#~ msgstr "Longitud de string UUID inválida" +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parámetro UUID inválido" +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "No se pueden establecer los parámetros PPCP." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "No se puede codificar el UUID, para revisar la longitud." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "suficiente poder para todo el circuito y presiona reset (después de " -#~ "expulsar CIRCUITPY).\n" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "Can not add Service." +#~ msgstr "No se puede agregar el Servicio." + +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Numero erroneo de bytes dados" + +#~ msgid "Wrong address length" +#~ msgstr "Longitud de address erronea" #, fuzzy #~ msgid "" @@ -2804,29 +2815,28 @@ msgstr "" #~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " #~ "unidad de almacenamiento CIRCUITPY:\n" -#~ msgid "Wrong address length" -#~ msgstr "Longitud de address erronea" - -#~ msgid "Wrong number of bytes provided" -#~ msgstr "Numero erroneo de bytes dados" - -#~ msgid "Can not add Service." -#~ msgstr "No se puede agregar el Servicio." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "suficiente poder para todo el circuito y presiona reset (después de " +#~ "expulsar CIRCUITPY).\n" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de Servicio inválido" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parámetro UUID inválido" -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Baud rate demasiado alto para este periférico SPI" +#~ msgid "Invalid UUID string length" +#~ msgstr "Longitud de string UUID inválida" diff --git a/locale/fil.po b/locale/fil.po index 6b3e408c7d2e6..8d112726e4324 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -1367,9 +1367,9 @@ msgstr "dibisyon ng zero" msgid "schedule stack full" msgstr "puno na ang schedule stack" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "masyadong maliit ang buffer" @@ -2679,10 +2679,20 @@ msgstr "Hindi ma-remount '/' kapag aktibo ang USB." msgid "'S' and 'O' are not supported format types" msgstr "Ang 'S' at 'O' ay hindi suportadong uri ng format" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, fuzzy, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "Nabigong ilaan ang RX buffer ng %d bytes" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" +#: shared-module/struct/__init__.c:179 +#, fuzzy +msgid "buffer size must match format" +msgstr "aarehas na haba dapat ang buffer slices" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." @@ -2777,31 +2787,33 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#~ msgid "Invalid UUID string length" -#~ msgstr "Mali ang UUID string length" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "ang palette ay dapat 32 bytes ang haba" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Mali ang UUID parameter" +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Hindi ma-set ang PPCP parameters." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " -#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#~ msgid "Can not add Service." +#~ msgstr "Hindi maidaragdag ang serbisyo." + +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Mali ang bilang ng bytes" + +#~ msgid "Wrong address length" +#~ msgstr "Mali ang address length" #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" @@ -2809,30 +2821,28 @@ msgstr "" #~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " #~ "drive:\n" -#~ msgid "Wrong address length" -#~ msgstr "Mali ang address length" - -#~ msgid "Wrong number of bytes provided" -#~ msgstr "Mali ang bilang ng bytes" - -#~ msgid "Can not add Service." -#~ msgstr "Hindi maidaragdag ang serbisyo." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " +#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." -#~ msgid "Invalid Service type" -#~ msgstr "Mali ang tipo ng serbisyo" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Mali ang UUID parameter" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "ang palette ay dapat 32 bytes ang haba" +#~ msgid "Invalid UUID string length" +#~ msgstr "Mali ang UUID string length" diff --git a/locale/fr.po b/locale/fr.po index 236ce43456bb9..2110a4c6e7bfb 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: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -1366,9 +1366,9 @@ msgstr "division par zéro" msgid "schedule stack full" msgstr "pile de plannification pleine" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "tampon trop petit" @@ -2703,10 +2703,20 @@ msgstr "'/' ne peut être remonté quand l'USB est actif." msgid "'S' and 'O' are not supported format types" msgstr "'S' et 'O' ne sont pas des types de format supportés" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, fuzzy, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "Echec de l'allocation de %d octets du tampon RX" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" +#: shared-module/struct/__init__.c:179 +#, fuzzy +msgid "buffer size must match format" +msgstr "les slices de tampon doivent être de longueurs égales" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." @@ -2806,63 +2816,63 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer denouveau pour quitter de le mode sans-échec.\n" -#~ msgid "Invalid UUID string length" -#~ msgstr "Longeur de chaîne UUID invalide" - -#~ msgid "Invalid UUID parameter" -#~ msgstr "Paramètre UUID invalide" - -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être une displayio.Palette" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size doit être une puissance de 2" +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" #~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" #~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" +#~ "assez de puissance pour l'ensemble du circuit et appuyez sur " +#~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" -#~ msgid "Wrong address length" -#~ msgstr "Mauvaise longueur d'adresse" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" #, fuzzy #~ msgid "Wrong number of bytes provided" #~ msgstr "mauvais nombre d'octets fourni'" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#~ msgid "Wrong address length" +#~ msgstr "Mauvaise longueur d'adresse" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." #~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" -#~ "assez de puissance pour l'ensemble du circuit et appuyez sur " -#~ "'reset' (après avoir éjecter CIRCUITPY).\n" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Paramètre UUID invalide" + +#~ msgid "Invalid UUID string length" +#~ msgstr "Longeur de chaîne UUID invalide" diff --git a/locale/it_IT.po b/locale/it_IT.po index 225e51cf5727a..cb413f073ad73 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -1366,9 +1366,9 @@ msgstr "divisione per zero" msgid "schedule stack full" msgstr "" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "buffer troppo piccolo" @@ -2685,10 +2685,20 @@ msgstr "Non è possibile rimontare '/' mentre l'USB è attiva." msgid "'S' and 'O' are not supported format types" msgstr "'S' e 'O' non sono formati supportati" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, fuzzy, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "Fallita allocazione del buffer RX di %d byte" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "troppi argomenti forniti con il formato specificato" +#: shared-module/struct/__init__.c:179 +#, fuzzy +msgid "buffer size must match format" +msgstr "slice del buffer devono essere della stessa lunghezza" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." @@ -2775,27 +2785,35 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid UUID string length" -#~ msgstr "Lunghezza della stringa UUID non valida" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parametro UUID non valido" +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " +#~ "espulso CIRCUITPY).\n" -#~ msgid "Invalid Service type" -#~ msgstr "Tipo di servizio non valido" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " +#~ "Whoops!\n" -#, fuzzy -#~ msgid "Wrong number of bytes provided" -#~ msgstr "numero di argomenti errato" +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" -#~ msgid "Can not add Characteristic." -#~ msgstr "Non è possibile aggiungere Characteristic." +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" @@ -2803,32 +2821,24 @@ msgstr "" #~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " #~ "CIRCUITPY:\n" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." - -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." -#~ msgid "Can not add Service." -#~ msgstr "Non è possibile aggiungere Service." +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." +#, fuzzy +#~ msgid "Wrong number of bytes provided" +#~ msgstr "numero di argomenti errato" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " -#~ "Whoops!\n" +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " -#~ "espulso CIRCUITPY).\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parametro UUID non valido" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossibile applicare i parametri GAP." +#~ msgid "Invalid UUID string length" +#~ msgstr "Lunghezza della stringa UUID non valida" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index a0d81d182bfd1..457850a556e51 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 17:33-0800\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -1348,9 +1348,9 @@ msgstr "divisão por zero" msgid "schedule stack full" msgstr "" -#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 -#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 -#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +#: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 +#: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2642,10 +2642,20 @@ msgstr "Não é possível remontar '/' enquanto o USB estiver ativo." msgid "'S' and 'O' are not supported format types" msgstr "'S' e 'O' não são tipos de formato suportados" -#: shared-module/struct/__init__.c:83 +#: shared-module/struct/__init__.c:128 +#, fuzzy, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "Falha ao alocar buffer RX de %d bytes" + +#: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "Muitos argumentos fornecidos com o formato dado" +#: shared-module/struct/__init__.c:179 +#, fuzzy +msgid "buffer size must match format" +msgstr "buffers devem ser o mesmo tamanho" + #: shared-module/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." @@ -2726,32 +2736,32 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." - -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" -#~ msgid "Can not add Characteristic." -#~ msgstr "Não é possível adicionar Característica." +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parâmetro UUID inválido" #~ msgid "Cannot apply GAP parameters." #~ msgstr "Não é possível aplicar parâmetros GAP." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parâmetro UUID inválido" +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possível adicionar Característica." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" + +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." From ab2ad7ba4542c2e133ced64ccb8e9d0b4065e86f Mon Sep 17 00:00:00 2001 From: Bryan Siepert Date: Sun, 20 Jan 2019 22:33:22 -0800 Subject: [PATCH 146/153] adding height and width to OnDiskBitmap for #1460 --- shared-bindings/displayio/OnDiskBitmap.c | 44 ++++++++++++++++++++++++ shared-bindings/displayio/OnDiskBitmap.h | 3 ++ shared-module/displayio/OnDiskBitmap.c | 8 +++++ 3 files changed, 55 insertions(+) diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c index 46cb5913c1642..d6d3b98625fc2 100644 --- a/shared-bindings/displayio/OnDiskBitmap.c +++ b/shared-bindings/displayio/OnDiskBitmap.c @@ -29,7 +29,9 @@ #include #include "py/runtime.h" +#include "py/objproperty.h" #include "supervisor/shared/translate.h" +#include "shared-bindings/displayio/OnDiskBitmap.h" //| .. currentmodule:: displayio //| @@ -92,7 +94,49 @@ STATIC mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_ return MP_OBJ_FROM_PTR(self); } +//| .. attribute:: width +//| +//| Width of the bitmap. (read only) +//| +STATIC mp_obj_t displayio_ondiskbitmap_obj_get_width(mp_obj_t self_in) { + displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_ondiskbitmap_get_width(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(displayio_ondiskbitmap_get_width_obj, displayio_ondiskbitmap_obj_get_width); + +const mp_obj_property_t displayio_ondiskbitmap_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_ondiskbitmap_get_width_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, + +}; + +//| .. attribute:: height +//| +//| Height of the bitmap. (read only) +//| +STATIC mp_obj_t displayio_ondiskbitmap_obj_get_height(mp_obj_t self_in) { + displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_ondiskbitmap_get_height(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(displayio_ondiskbitmap_get_height_obj, displayio_ondiskbitmap_obj_get_height); + +const mp_obj_property_t displayio_ondiskbitmap_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_ondiskbitmap_get_height_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, + +}; + STATIC const mp_rom_map_elem_t displayio_ondiskbitmap_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_ondiskbitmap_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_ondiskbitmap_width_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_ondiskbitmap_locals_dict, displayio_ondiskbitmap_locals_dict_table); diff --git a/shared-bindings/displayio/OnDiskBitmap.h b/shared-bindings/displayio/OnDiskBitmap.h index ab8b8dcd8051c..9a6c81f8f1fd4 100644 --- a/shared-bindings/displayio/OnDiskBitmap.h +++ b/shared-bindings/displayio/OnDiskBitmap.h @@ -37,4 +37,7 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *bitmap, int16_t x, int16_t y); +uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t *self); + +uint16_t common_hal_displayio_ondiskbitmap_get_width(displayio_ondiskbitmap_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKBITMAP_H diff --git a/shared-module/displayio/OnDiskBitmap.c b/shared-module/displayio/OnDiskBitmap.c index 6e4a4c6f07645..aa2ca3e103f1c 100644 --- a/shared-module/displayio/OnDiskBitmap.c +++ b/shared-module/displayio/OnDiskBitmap.c @@ -91,3 +91,11 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s } return 0; } + +uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t *self) { + return self->height; +} + +uint16_t common_hal_displayio_ondiskbitmap_get_width(displayio_ondiskbitmap_t *self) { + return self->width; +} From 777408ff8d45b9a73dbf0bcf8c083ade0b5152e5 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 21 Jan 2019 11:45:38 -0500 Subject: [PATCH 147/153] struct.pack_into incorrect buffer size check --- shared-module/struct/__init__.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c index 28e7c0c3f93e6..245dbbda97ca8 100644 --- a/shared-module/struct/__init__.c +++ b/shared-module/struct/__init__.c @@ -124,8 +124,8 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size char fmt_type = get_fmt_type(&fmt); const mp_uint_t total_sz = shared_modules_struct_calcsize(fmt_in); - if (p + total_sz != end_p) { - mp_raise_msg_varg(&mp_type_RuntimeError, translate("unpack requires a buffer of %d bytes"), total_sz); + if (p + total_sz > end_p) { + mp_raise_RuntimeError(translate("buffer too small")); } size_t i; From 6aa9f69b19898a1fdb7a233dafb06b10d119a2a8 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 21 Jan 2019 21:51:22 -0500 Subject: [PATCH 148/153] make translateimgrofybeepboopbop --- locale/ID.po | 125 ++++++++++++++++----------- locale/circuitpython.pot | 95 +++++++++++--------- locale/de_DE.po | 167 ++++++++++++++++++++---------------- locale/en_US.po | 95 +++++++++++--------- locale/es.po | 179 +++++++++++++++++++++----------------- locale/fil.po | 181 ++++++++++++++++++++++----------------- locale/fr.po | 177 +++++++++++++++++++++----------------- locale/it_IT.po | 177 +++++++++++++++++++++----------------- locale/pt_BR.po | 137 ++++++++++++++++------------- 9 files changed, 756 insertions(+), 577 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index cf317b42dc336..e06e0706318dd 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -341,12 +341,12 @@ msgid "bytes > 8 bits not supported" msgstr "byte > 8 bit tidak didukung" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "tx dan rx keduanya tidak boleh kosong" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "Gagal untuk mengalokasikan buffer RX" @@ -355,12 +355,12 @@ msgid "Could not initialize UART" msgstr "Tidak dapat menginisialisasi UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "Tidak pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "Tidak ada pin TX" @@ -723,7 +723,7 @@ msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX" msgid "Failed to read attribute value, err %0x04x" msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" @@ -733,7 +733,7 @@ msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" msgid "Failed to write attribute value, err 0x%04x" msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, fuzzy, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" @@ -754,51 +754,51 @@ msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" msgid "Failed to discover services" msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 #, fuzzy msgid "Failed to acquire mutex" msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 #, fuzzy msgid "Failed to release mutex" msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 #, fuzzy msgid "Failed to continue scanning" msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 #, fuzzy msgid "Failed to connect:" msgstr "Gagal untuk menyambungkan, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 #, fuzzy msgid "Failed to add service" msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 #, fuzzy msgid "Failed to start advertising" msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 #, fuzzy msgid "Failed to stop advertising" msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 #, fuzzy msgid "Failed to start scanning" msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 #, fuzzy msgid "Failed to create mutex" msgstr "Gagal untuk membuat mutex, status: 0x%08lX" @@ -854,19 +854,19 @@ msgstr "Semua perangkat SPI sedang digunakan" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 msgid "Invalid buffer size" msgstr "Ukuran buffer tidak valid" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 msgid "Odd parity is not supported" msgstr "Parity ganjil tidak didukung" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 msgid "busio.UART not available" msgstr "busio.UART tidak tersedia" @@ -1365,7 +1365,7 @@ msgstr "" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2131,7 +2131,7 @@ msgid "buffer must be a bytes-like object" msgstr "" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "" @@ -2175,15 +2175,33 @@ msgstr "buffers harus mempunyai panjang yang sama" msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +#, fuzzy +msgid "Not connected" +msgstr "Tidak dapat menyambungkan ke AP" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "bits harus memilki nilai 8" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 #, fuzzy msgid "buffer_size must be >= 1" msgstr "buffers harus mempunyai panjang yang sama" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 msgid "Expected a Characteristic" msgstr "" +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "" @@ -2221,16 +2239,20 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:107 #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "buffers harus mempunyai panjang yang sama" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2649,11 +2671,6 @@ msgstr "" msgid "'S' and 'O' are not supported format types" msgstr "" -#: shared-module/struct/__init__.c:128 -#, fuzzy, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" @@ -2749,24 +2766,28 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid UUID string length" -#~ msgstr "Panjang string UUID tidak valid" - #~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" -#~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " -#~ "CIRCUITPY).\n" +#~ "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" + +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parameter UUID tidak valid" #~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" #~ msgstr "" #~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parameter UUID tidak valid" - #~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" #~ msgstr "" -#~ "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" +#~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " +#~ "CIRCUITPY).\n" + +#~ msgid "Invalid UUID string length" +#~ msgstr "Panjang string UUID tidak valid" + +#, fuzzy +#~ msgid "unpack requires a buffer of %d bytes" +#~ msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 4962a67ab17c3..c041ec86c0aca 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: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -334,12 +334,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "" @@ -348,12 +348,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "" @@ -708,7 +708,7 @@ msgstr "" msgid "Failed to read attribute value, err %0x04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "" @@ -718,7 +718,7 @@ msgstr "" msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "" @@ -737,43 +737,43 @@ msgstr "" msgid "Failed to discover services" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 msgid "Failed to acquire mutex" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 msgid "Failed to release mutex" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 msgid "Failed to continue scanning" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 msgid "Failed to connect:" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 msgid "Failed to add service" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 msgid "Failed to start advertising" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 msgid "Failed to stop advertising" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 msgid "Failed to start scanning" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 msgid "Failed to create mutex" msgstr "" @@ -828,19 +828,19 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 msgid "Invalid buffer size" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 msgid "busio.UART not available" msgstr "" @@ -1332,7 +1332,7 @@ msgstr "" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2098,7 +2098,7 @@ msgid "buffer must be a bytes-like object" msgstr "" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "" @@ -2142,14 +2142,30 @@ msgstr "" msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +msgid "Not connected" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +msgid "timeout must be >= 0.0" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 msgid "buffer_size must be >= 1" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 msgid "Expected a Characteristic" msgstr "" +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "" @@ -2186,15 +2202,19 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:107 msgid "Byte buffer must be 16 bytes." msgstr "" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2612,11 +2632,6 @@ msgstr "" msgid "'S' and 'O' are not supported format types" msgstr "" -#: shared-module/struct/__init__.c:128 -#, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index dfa492ed0be17..3a3b4da51bc48 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -338,12 +338,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "Konnte keinen RX Buffer allozieren" @@ -352,12 +352,12 @@ msgid "Could not initialize UART" msgstr "Konnte UART nicht initialisieren" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "Kein RX Pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "Kein TX Pin" @@ -508,7 +508,8 @@ msgstr "Dateisystem kann nicht wieder gemounted werden." #: ports/esp8266/common-hal/storage/__init__.c:38 msgid "Use esptool to erase flash and re-upload Python instead" -msgstr "Benutze esptool um den flash zu löschen und stattdessen Python hochzuladen" +msgstr "" +"Benutze esptool um den flash zu löschen und stattdessen Python hochzuladen" #: ports/esp8266/esp_mphal.c:154 msgid "C-level assert" @@ -717,7 +718,7 @@ msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%04x" msgid "Failed to read attribute value, err %0x04x" msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" @@ -727,7 +728,7 @@ msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" msgid "Failed to write attribute value, err 0x%04x" msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, fuzzy, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x" @@ -748,51 +749,51 @@ msgstr "Daten sind zu groß für das advertisement packet" msgid "Failed to discover services" msgstr "Es konnten keine Dienste gefunden werden" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 #, fuzzy msgid "Failed to acquire mutex" msgstr "Akquirieren des Mutex gescheitert" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 #, fuzzy msgid "Failed to release mutex" msgstr "Loslassen des Mutex gescheitert" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 #, fuzzy msgid "Failed to continue scanning" msgstr "Der Scanvorgang kann nicht fortgesetzt werden" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 #, fuzzy msgid "Failed to connect:" msgstr "Das Verbinden ist fehlgeschlagen:" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 #, fuzzy msgid "Failed to add service" msgstr "Dienst konnte nicht hinzugefügt werden" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 #, fuzzy msgid "Failed to start advertising" msgstr "Kann advertisement nicht starten" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 #, fuzzy msgid "Failed to stop advertising" msgstr "Kann advertisement nicht stoppen" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 #, fuzzy msgid "Failed to start scanning" msgstr "Der Scanvorgang kann nicht gestartet werden" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 #, fuzzy msgid "Failed to create mutex" msgstr "Erstellen des Mutex ist fehlgeschlagen" @@ -850,21 +851,21 @@ msgstr "Alle SPI-Peripheriegeräte sind in Benutzung" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 #, fuzzy msgid "Invalid buffer size" msgstr "Ungültige Puffergröße" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 #, fuzzy msgid "Odd parity is not supported" msgstr "bytes mit mehr als 8 bits werden nicht unterstützt" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 msgid "busio.UART not available" msgstr "Kann busio.UART nicht finden" @@ -1360,7 +1361,7 @@ msgstr "" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2129,7 +2130,7 @@ msgid "buffer must be a bytes-like object" msgstr "" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "" @@ -2173,16 +2174,35 @@ msgstr "Buffer müssen gleich lang sein" msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +#, fuzzy +msgid "Not connected" +msgstr "Kann nicht zu AP verbinden" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "bits müssen 8 sein" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 #, fuzzy msgid "buffer_size must be >= 1" msgstr "Buffer müssen gleich lang sein" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 #, fuzzy msgid "Expected a Characteristic" msgstr "Kann das Merkmal nicht hinzufügen." +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +#, fuzzy +msgid "CharacteristicBuffer writing not provided" +msgstr "Merkmal wird bereits von einem anderen Dienst verwendet." + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "" @@ -2220,16 +2240,20 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:107 #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "Buffer müssen gleich lang sein" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2650,11 +2674,6 @@ msgstr "Kann '/' nicht remounten when USB aktiv ist" msgid "'S' and 'O' are not supported format types" msgstr "" -#: shared-module/struct/__init__.c:128 -#, fuzzy, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "Konnte keine RX Buffer mit %d allozieren" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" @@ -2748,29 +2767,22 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." - -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "Invalid UUID string length" +#~ msgstr "Ungültige UUID-Stringlänge" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." +#~ msgid "Invalid UUID parameter" +#~ msgstr "Ungültiger UUID-Parameter" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2779,19 +2791,30 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Ungültiger UUID-Parameter" +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." -#~ msgid "Invalid UUID string length" -#~ msgstr "Ungültige UUID-Stringlänge" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" + +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." + +#, fuzzy +#~ msgid "unpack requires a buffer of %d bytes" +#~ msgstr "Konnte keine RX Buffer mit %d allozieren" diff --git a/locale/en_US.po b/locale/en_US.po index 33b1e614b23bf..d62e9fd206238 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -334,12 +334,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "" @@ -348,12 +348,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "" @@ -708,7 +708,7 @@ msgstr "" msgid "Failed to read attribute value, err %0x04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "" @@ -718,7 +718,7 @@ msgstr "" msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "" @@ -737,43 +737,43 @@ msgstr "" msgid "Failed to discover services" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 msgid "Failed to acquire mutex" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 msgid "Failed to release mutex" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 msgid "Failed to continue scanning" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 msgid "Failed to connect:" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 msgid "Failed to add service" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 msgid "Failed to start advertising" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 msgid "Failed to stop advertising" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 msgid "Failed to start scanning" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 msgid "Failed to create mutex" msgstr "" @@ -828,19 +828,19 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 msgid "Invalid buffer size" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 msgid "busio.UART not available" msgstr "" @@ -1332,7 +1332,7 @@ msgstr "" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2098,7 +2098,7 @@ msgid "buffer must be a bytes-like object" msgstr "" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "" @@ -2142,14 +2142,30 @@ msgstr "" msgid "Expected a UUID" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +msgid "Not connected" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +msgid "timeout must be >= 0.0" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 msgid "buffer_size must be >= 1" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 msgid "Expected a Characteristic" msgstr "" +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "" @@ -2186,15 +2202,19 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:107 msgid "Byte buffer must be 16 bytes." msgstr "" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2612,11 +2632,6 @@ msgstr "" msgid "'S' and 'O' are not supported format types" msgstr "" -#: shared-module/struct/__init__.c:128 -#, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" diff --git a/locale/es.po b/locale/es.po index 6daa4170b1ad8..446fe7bc5d892 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -340,12 +340,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits no soportados" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "Ambos tx y rx no pueden ser None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "Ha fallado la asignación del buffer RX" @@ -354,12 +354,12 @@ msgid "Could not initialize UART" msgstr "No se puede inicializar la UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "Sin pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "Sin pin TX" @@ -720,7 +720,7 @@ msgstr "No se puede notificar el valor del anuncio. status: 0x%02x" msgid "Failed to read attribute value, err %0x04x" msgstr "No se puede leer el valor del atributo. status 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "No se puede adquirir el mutex, status: 0x%08lX" @@ -730,7 +730,7 @@ msgstr "No se puede adquirir el mutex, status: 0x%08lX" msgid "Failed to write attribute value, err 0x%04x" msgstr "No se puede escribir el valor del atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, fuzzy, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "No se puede liberar el mutex, status: 0x%08lX" @@ -751,51 +751,51 @@ msgstr "Los datos no caben en el paquete de anuncio." msgid "Failed to discover services" msgstr "No se puede descubrir servicios, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 #, fuzzy msgid "Failed to acquire mutex" msgstr "No se puede adquirir el mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 #, fuzzy msgid "Failed to release mutex" msgstr "No se puede liberar el mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 #, fuzzy msgid "Failed to continue scanning" msgstr "No se puede iniciar el escaneo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 #, fuzzy msgid "Failed to connect:" msgstr "No se puede conectar. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 #, fuzzy msgid "Failed to add service" msgstr "No se puede detener el anuncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 #, fuzzy msgid "Failed to start advertising" msgstr "No se puede inicar el anuncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 #, fuzzy msgid "Failed to stop advertising" msgstr "No se puede detener el anuncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 #, fuzzy msgid "Failed to start scanning" msgstr "No se puede iniciar el escaneo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 #, fuzzy msgid "Failed to create mutex" msgstr "No se puede leer el valor del atributo. status 0x%02x" @@ -851,19 +851,19 @@ msgstr "Todos los timers están siendo usados" msgid "error = 0x%08lX" msgstr "error = 0x%08lx" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 msgid "Invalid buffer size" msgstr "Tamaño de buffer inválido" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 msgid "Odd parity is not supported" msgstr "Paridad impar no soportada" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 msgid "busio.UART not available" msgstr "busio.UART no disponible" @@ -1368,7 +1368,7 @@ msgstr "" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "buffer demasiado pequeño" @@ -2147,7 +2147,7 @@ msgid "buffer must be a bytes-like object" msgstr "buffer debe de ser un objeto bytes-like" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "el archivo deberia ser una archivo abierto en modo byte" @@ -2192,16 +2192,34 @@ msgstr "palette debe ser 32 bytes de largo" msgid "Expected a UUID" msgstr "Se espera un %q" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +#, fuzzy +msgid "Not connected" +msgstr "No se puede conectar a AP" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "bits debe ser 8" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 #, fuzzy msgid "buffer_size must be >= 1" msgstr "los buffers deben de tener la misma longitud" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 #, fuzzy msgid "Expected a Characteristic" msgstr "No se puede agregar la Característica." +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "No se pueden agregar servicio en modo Central" @@ -2239,16 +2257,20 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:107 #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "buffer debe de ser un objeto bytes-like" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2673,11 +2695,6 @@ msgstr "No se puede volver a montar '/' cuando el USB esta activo." msgid "'S' and 'O' are not supported format types" msgstr "'S' y 'O' no son compatibles con los tipos de formato" -#: shared-module/struct/__init__.c:128 -#, fuzzy, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "Falló la asignación del buffer RX de %d bytes" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "demasiados argumentos provistos con el formato dado" @@ -2781,32 +2798,31 @@ msgstr "" "El botón reset fue presionado mientras arrancaba CircuitPython. Presiona " "otra vez para salir del modo seguro.\n" -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Baud rate demasiado alto para este periférico SPI" - -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de Servicio inválido" - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" +#~ msgid "Invalid UUID string length" +#~ msgstr "Longitud de string UUID inválida" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parámetro UUID inválido" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" -#~ msgid "Can not add Service." -#~ msgstr "No se puede agregar el Servicio." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." -#~ msgid "Wrong number of bytes provided" -#~ msgstr "Numero erroneo de bytes dados" +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "suficiente poder para todo el circuito y presiona reset (después de " +#~ "expulsar CIRCUITPY).\n" -#~ msgid "Wrong address length" -#~ msgstr "Longitud de address erronea" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." #, fuzzy #~ msgid "" @@ -2815,28 +2831,33 @@ msgstr "" #~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " #~ "unidad de almacenamiento CIRCUITPY:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "Wrong address length" +#~ msgstr "Longitud de address erronea" -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "suficiente poder para todo el circuito y presiona reset (después de " -#~ "expulsar CIRCUITPY).\n" +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Numero erroneo de bytes dados" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "No se pueden establecer los parámetros PPCP." +#~ msgid "Can not add Service." +#~ msgstr "No se puede agregar el Servicio." -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "No se puede codificar el UUID, para revisar la longitud." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parámetro UUID inválido" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." -#~ msgid "Invalid UUID string length" -#~ msgstr "Longitud de string UUID inválida" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" + +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" + +#, fuzzy +#~ msgid "unpack requires a buffer of %d bytes" +#~ msgstr "Falló la asignación del buffer RX de %d bytes" diff --git a/locale/fil.po b/locale/fil.po index 8d112726e4324..ad9134f8e8c24 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -338,12 +338,12 @@ msgid "bytes > 8 bits not supported" msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "tx at rx hindi pwedeng parehas na None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "Nabigong ilaan ang RX buffer" @@ -352,12 +352,12 @@ msgid "Could not initialize UART" msgstr "Hindi ma-initialize ang UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "Walang RX pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "Walang TX pin" @@ -720,7 +720,7 @@ msgstr "Hindi mabalitaan ang attribute value, status: 0x%08lX" msgid "Failed to read attribute value, err %0x04x" msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" @@ -730,7 +730,7 @@ msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" msgid "Failed to write attribute value, err 0x%04x" msgstr "Hindi maisulat ang attribute value, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, fuzzy, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" @@ -751,51 +751,51 @@ msgstr "Hindi makasya ang data sa loob ng advertisement packet" msgid "Failed to discover services" msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 #, fuzzy msgid "Failed to acquire mutex" msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 #, fuzzy msgid "Failed to release mutex" msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 #, fuzzy msgid "Failed to continue scanning" msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 #, fuzzy msgid "Failed to connect:" msgstr "Hindi makaconnect, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 #, fuzzy msgid "Failed to add service" msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 #, fuzzy msgid "Failed to start advertising" msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 #, fuzzy msgid "Failed to stop advertising" msgstr "Hindi mahinto ang advertisement, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 #, fuzzy msgid "Failed to start scanning" msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 #, fuzzy msgid "Failed to create mutex" msgstr "Hindi matagumpay ang pagbuo ng mutex, status: 0x%0xlX" @@ -852,19 +852,19 @@ msgstr "Lahat ng SPI peripherals ay ginagamit" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 msgid "Invalid buffer size" msgstr "Mali ang buffer size" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 msgid "Odd parity is not supported" msgstr "Odd na parity ay hindi supportado" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 msgid "busio.UART not available" msgstr "busio.UART hindi available" @@ -1369,7 +1369,7 @@ msgstr "puno na ang schedule stack" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "masyadong maliit ang buffer" @@ -2152,7 +2152,7 @@ msgid "buffer must be a bytes-like object" msgstr "buffer ay dapat bytes-like object" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "file ay dapat buksan sa byte mode" @@ -2197,16 +2197,34 @@ msgstr "ang palette ay dapat 32 bytes ang haba" msgid "Expected a UUID" msgstr "Umasa ng %q" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +#, fuzzy +msgid "Not connected" +msgstr "Hindi maka connect sa AP" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "bits ay dapat walo (8)" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 #, fuzzy msgid "buffer_size must be >= 1" msgstr "aarehas na haba dapat ang buffer slices" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 #, fuzzy msgid "Expected a Characteristic" msgstr "Hindi mabasa and Characteristic." +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "Hindi maarang maglagay ng service sa Central mode" @@ -2244,16 +2262,20 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:107 #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "buffer ay dapat bytes-like object" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2679,11 +2701,6 @@ msgstr "Hindi ma-remount '/' kapag aktibo ang USB." msgid "'S' and 'O' are not supported format types" msgstr "Ang 'S' at 'O' ay hindi suportadong uri ng format" -#: shared-module/struct/__init__.c:128 -#, fuzzy, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "Nabigong ilaan ang RX buffer ng %d bytes" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" @@ -2787,33 +2804,31 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "ang palette ay dapat 32 bytes ang haba" - -#~ msgid "Invalid Service type" -#~ msgstr "Mali ang tipo ng serbisyo" - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" +#~ msgid "Invalid UUID string length" +#~ msgstr "Mali ang UUID string length" -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." +#~ msgid "Invalid UUID parameter" +#~ msgstr "Mali ang UUID parameter" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" -#~ msgid "Can not add Service." -#~ msgstr "Hindi maidaragdag ang serbisyo." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." -#~ msgid "Wrong number of bytes provided" -#~ msgstr "Mali ang bilang ng bytes" +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " +#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" -#~ msgid "Wrong address length" -#~ msgstr "Mali ang address length" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" @@ -2821,28 +2836,34 @@ msgstr "" #~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " #~ "drive:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#~ msgid "Wrong address length" +#~ msgstr "Mali ang address length" -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " -#~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" +#~ msgid "Wrong number of bytes provided" +#~ msgstr "Mali ang bilang ng bytes" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Hindi ma-set ang PPCP parameters." +#~ msgid "Can not add Service." +#~ msgstr "Hindi maidaragdag ang serbisyo." -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Mali ang UUID parameter" +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." -#~ msgid "Invalid UUID string length" -#~ msgstr "Mali ang UUID string length" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" + +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "ang palette ay dapat 32 bytes ang haba" + +#, fuzzy +#~ msgid "unpack requires a buffer of %d bytes" +#~ msgstr "Nabigong ilaan ang RX buffer ng %d bytes" diff --git a/locale/fr.po b/locale/fr.po index 2110a4c6e7bfb..4c7fb050209fc 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: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: 2018-12-23 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -335,12 +335,12 @@ msgid "bytes > 8 bits not supported" msgstr "octets > 8 bits non supporté" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "tx et rx ne peuvent être None tous les deux" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "Echec de l'allocation du tampon RX" @@ -349,12 +349,12 @@ msgid "Could not initialize UART" msgstr "L'UART n'a pu être initialisé" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "Pas de broche RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "Pas de broche TX" @@ -717,7 +717,7 @@ msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%08lX" msgid "Failed to read attribute value, err %0x04x" msgstr "Impossible de lire la valeur de l'attribut. status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "Echec de l'obtention de mutex, status: 0x%08lX" @@ -727,7 +727,7 @@ msgstr "Echec de l'obtention de mutex, status: 0x%08lX" msgid "Failed to write attribute value, err 0x%04x" msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, fuzzy, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Impossible de libérer mutex, status: 0x%08lX" @@ -747,51 +747,51 @@ msgstr "" msgid "Failed to discover services" msgstr "Echec de la découverte de services, statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 #, fuzzy msgid "Failed to acquire mutex" msgstr "Echec de l'obtention de mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 #, fuzzy msgid "Failed to release mutex" msgstr "Impossible de libérer mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 #, fuzzy msgid "Failed to continue scanning" msgstr "Impossible de commencer à scanner. statut: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 #, fuzzy msgid "Failed to connect:" msgstr "Connection impossible. statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 #, fuzzy msgid "Failed to add service" msgstr "Echec de l'ajout de service, statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 #, fuzzy msgid "Failed to start advertising" msgstr "Echec de l'ajout de service, statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 #, fuzzy msgid "Failed to stop advertising" msgstr "Echec de l'ajout de service, statut: 0x%08lX" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 #, fuzzy msgid "Failed to start scanning" msgstr "Impossible de commencer à scanner, statut: 0x%0xlX" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 #, fuzzy msgid "Failed to create mutex" msgstr "Echec de la création de mutex, statut: 0x%0xlX" @@ -850,21 +850,21 @@ msgstr "Tous les périphériques SPI sont utilisés" msgid "error = 0x%08lX" msgstr "erreur = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 #, fuzzy msgid "Invalid buffer size" msgstr "longueur de tampon invalide" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 #, fuzzy msgid "Odd parity is not supported" msgstr "parité impaire non supportée" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART n'est pas disponible" @@ -1368,7 +1368,7 @@ msgstr "pile de plannification pleine" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "tampon trop petit" @@ -2154,7 +2154,7 @@ msgid "buffer must be a bytes-like object" msgstr "le tampon doit être un objet bytes-like" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "le fichier doit être un fichier ouvert en mode 'byte'" @@ -2199,16 +2199,34 @@ msgstr "la palette doit être longue de 32 octets" msgid "Expected a UUID" msgstr "Attendu : %q" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +#, fuzzy +msgid "Not connected" +msgstr "Impossible de se connecter à 'AP'" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "les bits doivent être 8" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 #, fuzzy msgid "buffer_size must be >= 1" msgstr "les slices de tampon doivent être de longueurs égales" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 #, fuzzy msgid "Expected a Characteristic" msgstr "Impossible d'ajouter la Characteristic." +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "Impossible d'ajouter des service en mode Central" @@ -2246,16 +2264,20 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:107 #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "le tampon doit être un objet bytes-like" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2703,11 +2725,6 @@ msgstr "'/' ne peut être remonté quand l'USB est actif." msgid "'S' and 'O' are not supported format types" msgstr "'S' et 'O' ne sont pas des types de format supportés" -#: shared-module/struct/__init__.c:128 -#, fuzzy, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "Echec de l'allocation de %d octets du tampon RX" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" @@ -2816,63 +2833,67 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer denouveau pour quitter de le mode sans-échec.\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#~ msgid "Invalid UUID string length" +#~ msgstr "Longeur de chaîne UUID invalide" -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." +#~ msgid "Invalid UUID parameter" +#~ msgstr "Paramètre UUID invalide" -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" + +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" #~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" #~ msgstr "" -#~ "assez de puissance pour l'ensemble du circuit et appuyez sur " -#~ "'reset' (après avoir éjecter CIRCUITPY).\n" +#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#~ msgid "Wrong address length" +#~ msgstr "Mauvaise longueur d'adresse" #, fuzzy #~ msgid "Wrong number of bytes provided" #~ msgstr "mauvais nombre d'octets fourni'" -#~ msgid "Wrong address length" -#~ msgstr "Mauvaise longueur d'adresse" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" #~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" #~ msgstr "" -#~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" - -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" +#~ "assez de puissance pour l'ensemble du circuit et appuyez sur " +#~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size doit être une puissance de 2" +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être une displayio.Palette" +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Paramètre UUID invalide" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" -#~ msgid "Invalid UUID string length" -#~ msgstr "Longeur de chaîne UUID invalide" +#, fuzzy +#~ msgid "unpack requires a buffer of %d bytes" +#~ msgstr "Echec de l'allocation de %d octets du tampon RX" diff --git a/locale/it_IT.po b/locale/it_IT.po index cb413f073ad73..8f5fb56848d2a 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -339,12 +339,12 @@ msgid "bytes > 8 bits not supported" msgstr "byte > 8 bit non supportati" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "tx e rx non possono essere entrambi None" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "Impossibile allocare buffer RX" @@ -353,12 +353,12 @@ msgid "Could not initialize UART" msgstr "Impossibile inizializzare l'UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "Nessun pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "Nessun pin TX" @@ -719,7 +719,7 @@ msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x" msgid "Failed to read attribute value, err %0x04x" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" @@ -729,7 +729,7 @@ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" msgid "Failed to write attribute value, err 0x%04x" msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, fuzzy, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" @@ -750,51 +750,51 @@ msgstr "Impossibile inserire dati nel pacchetto di advertisement." msgid "Failed to discover services" msgstr "Impossibile fermare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 #, fuzzy msgid "Failed to acquire mutex" msgstr "Impossibile allocare buffer RX" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 #, fuzzy msgid "Failed to release mutex" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 #, fuzzy msgid "Failed to continue scanning" msgstr "Impossible iniziare la scansione. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 #, fuzzy msgid "Failed to connect:" msgstr "Impossibile connettersi. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 #, fuzzy msgid "Failed to add service" msgstr "Impossibile fermare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 #, fuzzy msgid "Failed to start advertising" msgstr "Impossibile avviare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 #, fuzzy msgid "Failed to stop advertising" msgstr "Impossibile fermare advertisement. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 #, fuzzy msgid "Failed to start scanning" msgstr "Impossible iniziare la scansione. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 #, fuzzy msgid "Failed to create mutex" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" @@ -851,21 +851,21 @@ msgstr "Tutte le periferiche SPI sono in uso" msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 #, fuzzy msgid "Invalid buffer size" msgstr "lunghezza del buffer non valida" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 #, fuzzy msgid "Odd parity is not supported" msgstr "operazione I2C non supportata" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART non ancora implementato" @@ -1368,7 +1368,7 @@ msgstr "" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "buffer troppo piccolo" @@ -2151,7 +2151,7 @@ msgid "buffer must be a bytes-like object" msgstr "" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "" @@ -2196,16 +2196,34 @@ msgstr "la palette deve essere lunga 32 byte" msgid "Expected a UUID" msgstr "Atteso un %q" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +#, fuzzy +msgid "Not connected" +msgstr "Impossible connettersi all'AP" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "i bit devono essere 8" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 #, fuzzy msgid "buffer_size must be >= 1" msgstr "slice del buffer devono essere della stessa lunghezza" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 #, fuzzy msgid "Expected a Characteristic" msgstr "Non è possibile aggiungere Characteristic." +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "" @@ -2243,16 +2261,20 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:107 #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "i buffer devono essere della stessa lunghezza" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2685,11 +2707,6 @@ msgstr "Non è possibile rimontare '/' mentre l'USB è attiva." msgid "'S' and 'O' are not supported format types" msgstr "'S' e 'O' non sono formati supportati" -#: shared-module/struct/__init__.c:128 -#, fuzzy, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "Fallita allocazione del buffer RX di %d byte" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "troppi argomenti forniti con il formato specificato" @@ -2785,35 +2802,27 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossibile applicare i parametri GAP." - -#~ msgid "" -#~ "enough power for the whole circuit and press reset (after ejecting " -#~ "CIRCUITPY).\n" -#~ msgstr "" -#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " -#~ "espulso CIRCUITPY).\n" +#~ msgid "Invalid UUID string length" +#~ msgstr "Lunghezza della stringa UUID non valida" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " -#~ "Whoops!\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parametro UUID non valido" -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#, fuzzy +#~ msgid "Wrong number of bytes provided" +#~ msgstr "numero di argomenti errato" -#~ msgid "Can not add Service." -#~ msgstr "Non è possibile aggiungere Service." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." #~ msgid "" #~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" @@ -2821,24 +2830,36 @@ msgstr "" #~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " #~ "CIRCUITPY:\n" -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." -#~ msgid "Can not add Characteristic." -#~ msgstr "Non è possibile aggiungere Characteristic." +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." -#, fuzzy -#~ msgid "Wrong number of bytes provided" -#~ msgstr "numero di argomenti errato" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" -#~ msgid "Invalid Service type" -#~ msgstr "Tipo di servizio non valido" +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parametro UUID non valido" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " +#~ "Whoops!\n" -#~ msgid "Invalid UUID string length" -#~ msgstr "Lunghezza della stringa UUID non valida" +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " +#~ "espulso CIRCUITPY).\n" + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." + +#, fuzzy +#~ msgid "unpack requires a buffer of %d bytes" +#~ msgstr "Fallita allocazione del buffer RX di %d byte" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 457850a556e51..c0583d8bc9468 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-20 22:46-0500\n" +"POT-Creation-Date: 2019-01-21 21:50-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -334,12 +334,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits não suportado" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:118 +#: ports/nrf/common-hal/busio/UART.c:91 msgid "tx and rx cannot both be None" msgstr "TX e RX não podem ser ambos" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:152 +#: ports/nrf/common-hal/busio/UART.c:132 msgid "Failed to allocate RX buffer" msgstr "Falha ao alocar buffer RX" @@ -348,12 +348,12 @@ msgid "Could not initialize UART" msgstr "Não foi possível inicializar o UART" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:197 +#: ports/nrf/common-hal/busio/UART.c:174 msgid "No RX pin" msgstr "Nenhum pino RX" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:232 +#: ports/nrf/common-hal/busio/UART.c:209 msgid "No TX pin" msgstr "Nenhum pino TX" @@ -711,7 +711,7 @@ msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" msgid "Failed to read attribute value, err %0x04x" msgstr "Não é possível ler o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 #, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "Não é possível ler o valor do atributo. status: 0x%02x" @@ -721,7 +721,7 @@ msgstr "Não é possível ler o valor do atributo. status: 0x%02x" msgid "Failed to write attribute value, err 0x%04x" msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 #, fuzzy, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Não é possível ler o valor do atributo. status: 0x%02x" @@ -742,49 +742,49 @@ msgstr "Não é possível ajustar dados no pacote de anúncios." msgid "Failed to discover services" msgstr "Não pode parar propaganda. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:267 -#: ports/nrf/common-hal/bleio/Device.c:300 +#: ports/nrf/common-hal/bleio/Device.c:268 +#: ports/nrf/common-hal/bleio/Device.c:302 #, fuzzy msgid "Failed to acquire mutex" msgstr "Falha ao alocar buffer RX" -#: ports/nrf/common-hal/bleio/Device.c:278 -#: ports/nrf/common-hal/bleio/Device.c:311 -#: ports/nrf/common-hal/bleio/Device.c:342 -#: ports/nrf/common-hal/bleio/Device.c:376 +#: ports/nrf/common-hal/bleio/Device.c:280 +#: ports/nrf/common-hal/bleio/Device.c:313 +#: ports/nrf/common-hal/bleio/Device.c:344 +#: ports/nrf/common-hal/bleio/Device.c:378 #, fuzzy msgid "Failed to release mutex" msgstr "Não é possível ler o valor do atributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:387 +#: ports/nrf/common-hal/bleio/Device.c:389 msgid "Failed to continue scanning" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:419 +#: ports/nrf/common-hal/bleio/Device.c:421 msgid "Failed to connect:" msgstr "" -#: ports/nrf/common-hal/bleio/Device.c:489 +#: ports/nrf/common-hal/bleio/Device.c:491 #, fuzzy msgid "Failed to add service" msgstr "Não pode parar propaganda. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:506 +#: ports/nrf/common-hal/bleio/Device.c:508 #, fuzzy msgid "Failed to start advertising" msgstr "Não é possível iniciar o anúncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:523 +#: ports/nrf/common-hal/bleio/Device.c:525 #, fuzzy msgid "Failed to stop advertising" msgstr "Não pode parar propaganda. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:548 +#: ports/nrf/common-hal/bleio/Device.c:550 #, fuzzy msgid "Failed to start scanning" msgstr "Não é possível iniciar o anúncio. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Device.c:564 +#: ports/nrf/common-hal/bleio/Device.c:566 #, fuzzy msgid "Failed to create mutex" msgstr "Não é possível ler o valor do atributo. status: 0x%02x" @@ -840,21 +840,21 @@ msgstr "Todos os periféricos SPI estão em uso" msgid "error = 0x%08lX" msgstr "erro = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:122 +#: ports/nrf/common-hal/busio/UART.c:95 #, fuzzy msgid "Invalid buffer size" msgstr "Arquivo inválido" -#: ports/nrf/common-hal/busio/UART.c:126 +#: ports/nrf/common-hal/busio/UART.c:99 #, fuzzy msgid "Odd parity is not supported" msgstr "I2C operação não suportada" -#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 -#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 -#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 -#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 -#: ports/nrf/common-hal/busio/UART.c:400 +#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 +#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 +#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 +#: ports/nrf/common-hal/busio/UART.c:377 msgid "busio.UART not available" msgstr "busio.UART não disponível" @@ -1350,7 +1350,7 @@ msgstr "" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2119,7 +2119,7 @@ msgid "buffer must be a bytes-like object" msgstr "" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:85 +#: shared-bindings/displayio/OnDiskBitmap.c:87 msgid "file must be a file opened in byte mode" msgstr "" @@ -2164,16 +2164,34 @@ msgstr "buffers devem ser o mesmo tamanho" msgid "Expected a UUID" msgstr "Esperado um" -#: shared-bindings/bleio/CharacteristicBuffer.c:61 +#: shared-bindings/bleio/CharacteristicBuffer.c:39 +#, fuzzy +msgid "Not connected" +msgstr "Não é possível conectar-se ao AP" + +#: shared-bindings/bleio/CharacteristicBuffer.c:74 +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "bits devem ser 8" + +#: shared-bindings/bleio/CharacteristicBuffer.c:79 #, fuzzy msgid "buffer_size must be >= 1" msgstr "buffers devem ser o mesmo tamanho" -#: shared-bindings/bleio/CharacteristicBuffer.c:65 +#: shared-bindings/bleio/CharacteristicBuffer.c:83 #, fuzzy msgid "Expected a Characteristic" msgstr "Não é possível adicionar Característica." +#: shared-bindings/bleio/CharacteristicBuffer.c:138 +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-bindings/bleio/CharacteristicBuffer.c:147 +msgid "Not connected." +msgstr "" + #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" msgstr "" @@ -2211,16 +2229,20 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:75 -msgid "UUID value is not int or byte buffer" +#: shared-bindings/bleio/UUID.c:91 +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c:79 +#: shared-bindings/bleio/UUID.c:103 +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: shared-bindings/bleio/UUID.c:107 #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "buffers devem ser o mesmo tamanho" -#: shared-bindings/bleio/UUID.c:120 +#: shared-bindings/bleio/UUID.c:151 msgid "not a 128-bit UUID" msgstr "" @@ -2642,11 +2664,6 @@ msgstr "Não é possível remontar '/' enquanto o USB estiver ativo." msgid "'S' and 'O' are not supported format types" msgstr "'S' e 'O' não são tipos de formato suportados" -#: shared-module/struct/__init__.c:128 -#, fuzzy, c-format -msgid "unpack requires a buffer of %d bytes" -msgstr "Falha ao alocar buffer RX de %d bytes" - #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "Muitos argumentos fornecidos com o formato dado" @@ -2736,32 +2753,36 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Invalid UUID parameter" -#~ msgstr "Parâmetro UUID inválido" +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" + +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possível adicionar Característica." #~ msgid "Cannot apply GAP parameters." #~ msgstr "Não é possível aplicar parâmetros GAP." -#~ msgid "Can not add Characteristic." -#~ msgstr "Não é possível adicionar Característica." +#~ msgid "Invalid UUID parameter" +#~ msgstr "Parâmetro UUID inválido" -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." +#, fuzzy +#~ msgid "unpack requires a buffer of %d bytes" +#~ msgstr "Falha ao alocar buffer RX de %d bytes" From 3d3c50f9273858fcaa5686760daf49db39b1e36c Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Tue, 22 Jan 2019 15:39:54 -0500 Subject: [PATCH 149/153] tell people that esp8266 is no longer supported Closes #1483 --- ports/esp8266/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index d38285c914401..4f23dfff1ef78 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -216,7 +216,8 @@ SRC_QSTR += $(SRC_C) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $( # Append any auto-generated sources that are needed by sources listed in SRC_QSTR SRC_QSTR_AUTO_DEPS += -all: $(BUILD)/libaxtls.a $(FWBIN) +all: + @echo "CircuitPython 4.0.0 and later do not support esp8266 boards." CONFVARS_FILE = $(BUILD)/confvars From 603f64d731e051a7b0d08b7d36cefbd56845ce31 Mon Sep 17 00:00:00 2001 From: Pascal Deneaux Date: Tue, 22 Jan 2019 23:05:38 +0100 Subject: [PATCH 150/153] Corrected incorrect translations and added some Should the error messages from files in the py folder also be translated? --- locale/de_DE.po | 326 +++++++++++++++++++++--------------------------- 1 file changed, 139 insertions(+), 187 deletions(-) diff --git a/locale/de_DE.po b/locale/de_DE.po index 3a3b4da51bc48..92bf619563c1a 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-21 21:50-0500\n" +"POT-Creation-Date: 2019-01-20 22:46-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -311,7 +311,7 @@ msgstr "Alle event Kanäle werden benutzt" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" -msgstr "" +msgstr "Abtastrate zu hoch. Wert muss unter %d liegen" #: ports/atmel-samd/common-hal/busio/I2C.c:71 msgid "Not enough pins available" @@ -335,15 +335,15 @@ msgstr "Baudrate wird nicht unterstützt" #: ports/atmel-samd/common-hal/busio/UART.c:67 msgid "bytes > 8 bits not supported" -msgstr "bytes mit merh als 8 bits werden nicht unterstützt" +msgstr "bytes mit mehr als 8 bits werden nicht unterstützt" #: ports/atmel-samd/common-hal/busio/UART.c:73 -#: ports/nrf/common-hal/busio/UART.c:91 +#: ports/nrf/common-hal/busio/UART.c:118 msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" #: ports/atmel-samd/common-hal/busio/UART.c:146 -#: ports/nrf/common-hal/busio/UART.c:132 +#: ports/nrf/common-hal/busio/UART.c:152 msgid "Failed to allocate RX buffer" msgstr "Konnte keinen RX Buffer allozieren" @@ -352,12 +352,12 @@ msgid "Could not initialize UART" msgstr "Konnte UART nicht initialisieren" #: ports/atmel-samd/common-hal/busio/UART.c:241 -#: ports/nrf/common-hal/busio/UART.c:174 +#: ports/nrf/common-hal/busio/UART.c:197 msgid "No RX pin" msgstr "Kein RX Pin" #: ports/atmel-samd/common-hal/busio/UART.c:300 -#: ports/nrf/common-hal/busio/UART.c:209 +#: ports/nrf/common-hal/busio/UART.c:232 msgid "No TX pin" msgstr "Kein TX Pin" @@ -369,13 +369,13 @@ msgstr "Pull up im Ausgabemodus nicht möglich" #: ports/atmel-samd/common-hal/displayio/ParallelBus.c:43 #: ports/nrf/common-hal/displayio/ParallelBus.c:43 msgid "Data 0 pin must be byte aligned" -msgstr "" +msgstr "Data 0 pin muss am Byte ausgerichtet sein" #: ports/atmel-samd/common-hal/displayio/ParallelBus.c:47 #: ports/nrf/common-hal/displayio/ParallelBus.c:47 -#, fuzzy, c-format +#, c-format msgid "Bus pin %d is already in use" -msgstr "DAC wird schon benutzt" +msgstr "Bus pin %d wird schon benutzt" #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 @@ -399,7 +399,7 @@ msgstr "Keine Hardwareunterstützung an diesem Pin" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 msgid "EXTINT channel already in use" -msgstr "EXTINT Kanal wird benutzt" +msgstr "EXTINT Kanal ist schon in Benutzung" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 @@ -490,8 +490,7 @@ msgstr "Minimale PWM Frequenz ist %dHz" #: ports/esp8266/common-hal/pulseio/PWMOut.c:68 #, c-format msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." -msgstr "" -"Mehrere PWM Frequenzen nicht unterstützt. PWM bereits auf %dHz gesetzt." +msgstr "Mehrere PWM Frequenzen werden nicht unterstützt. PWM wurde bereits auf %dHz gesetzt." #: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 #, c-format @@ -508,12 +507,11 @@ msgstr "Dateisystem kann nicht wieder gemounted werden." #: ports/esp8266/common-hal/storage/__init__.c:38 msgid "Use esptool to erase flash and re-upload Python instead" -msgstr "" -"Benutze esptool um den flash zu löschen und stattdessen Python hochzuladen" +msgstr "Benutze esptool um den flash zu löschen und stattdessen Python hochzuladen" #: ports/esp8266/esp_mphal.c:154 msgid "C-level assert" -msgstr "" +msgstr "C-Level Assert" #: ports/esp8266/machine_adc.c:57 #, c-format @@ -565,8 +563,7 @@ msgstr "len muss ein vielfaches von 4 sein" #: ports/esp8266/modesp.c:274 #, c-format msgid "memory allocation failed, allocating %u bytes for native code" -msgstr "" -"Speicherallozierung fehlgeschlagen, alloziere %u Bytes für nativen Code" +msgstr "Speicherallozierung fehlgeschlagen, alloziere %u Bytes für nativen Code" #: ports/esp8266/modesp.c:317 msgid "flash location must be below 1MByte" @@ -658,12 +655,10 @@ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX" #: ports/nrf/common-hal/bleio/Adapter.c:110 -#, fuzzy msgid "Failed to change softdevice state" msgstr "Fehler beim Ändern des Softdevice-Status" #: ports/nrf/common-hal/bleio/Adapter.c:119 -#, fuzzy msgid "Failed to get softdevice state" msgstr "Fehler beim Abrufen des Softdevice-Status" @@ -677,144 +672,132 @@ msgstr "Das Interval ist nicht im Bereich 0.0020 bis 10.24" #: ports/nrf/common-hal/bleio/Broadcaster.c:58 #: ports/nrf/common-hal/bleio/Peripheral.c:56 -#, fuzzy msgid "Data too large for advertisement packet" msgstr "Zu vielen Daten für das advertisement packet" #: ports/nrf/common-hal/bleio/Broadcaster.c:83 #: ports/nrf/common-hal/bleio/Peripheral.c:324 -#, fuzzy, c-format +#, c-format msgid "Failed to start advertising, err 0x%04x" msgstr "Kann advertisement nicht starten. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Broadcaster.c:96 #: ports/nrf/common-hal/bleio/Peripheral.c:336 -#, fuzzy, c-format +#, c-format msgid "Failed to stop advertising, err 0x%04x" msgstr "Kann advertisement nicht stoppen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:59 -#, fuzzy, c-format +#, c-format msgid "Failed to read CCCD value, err 0x%04x" msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:89 -#, fuzzy, c-format +#, c-format msgid "Failed to read gatts value, err 0x%04x" msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:106 -#, fuzzy, c-format +#, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:132 -#, fuzzy, c-format +#, c-format msgid "Failed to notify or indicate attribute value, err %0x04x" msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:144 -#, fuzzy, c-format +#, c-format msgid "Failed to read attribute value, err %0x04x" msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c:172 ports/nrf/sd_mutex.c:34 -#, fuzzy, c-format +#: ports/nrf/common-hal/bleio/Characteristic.c:172 +#, c-format msgid "Failed to acquire mutex, err 0x%04x" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" +msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:178 -#, fuzzy, c-format +#, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c:189 ports/nrf/sd_mutex.c:54 -#, fuzzy, c-format +#: ports/nrf/common-hal/bleio/Characteristic.c:189 +#, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Characteristic.c:251 #: ports/nrf/common-hal/bleio/Characteristic.c:284 msgid "bad GATT role" -msgstr "bad GATT role" +msgstr "" #: ports/nrf/common-hal/bleio/Device.c:80 #: ports/nrf/common-hal/bleio/Device.c:112 -#, fuzzy msgid "Data too large for the advertisement packet" msgstr "Daten sind zu groß für das advertisement packet" #: ports/nrf/common-hal/bleio/Device.c:262 -#, fuzzy msgid "Failed to discover services" msgstr "Es konnten keine Dienste gefunden werden" -#: ports/nrf/common-hal/bleio/Device.c:268 -#: ports/nrf/common-hal/bleio/Device.c:302 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:267 +#: ports/nrf/common-hal/bleio/Device.c:300 msgid "Failed to acquire mutex" msgstr "Akquirieren des Mutex gescheitert" -#: ports/nrf/common-hal/bleio/Device.c:280 -#: ports/nrf/common-hal/bleio/Device.c:313 -#: ports/nrf/common-hal/bleio/Device.c:344 -#: ports/nrf/common-hal/bleio/Device.c:378 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:278 +#: ports/nrf/common-hal/bleio/Device.c:311 +#: ports/nrf/common-hal/bleio/Device.c:342 +#: ports/nrf/common-hal/bleio/Device.c:376 msgid "Failed to release mutex" msgstr "Loslassen des Mutex gescheitert" -#: ports/nrf/common-hal/bleio/Device.c:389 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:387 msgid "Failed to continue scanning" msgstr "Der Scanvorgang kann nicht fortgesetzt werden" -#: ports/nrf/common-hal/bleio/Device.c:421 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:419 msgid "Failed to connect:" -msgstr "Das Verbinden ist fehlgeschlagen:" +msgstr "Verbindung fehlgeschlagen:" -#: ports/nrf/common-hal/bleio/Device.c:491 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:489 msgid "Failed to add service" msgstr "Dienst konnte nicht hinzugefügt werden" -#: ports/nrf/common-hal/bleio/Device.c:508 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:506 msgid "Failed to start advertising" msgstr "Kann advertisement nicht starten" -#: ports/nrf/common-hal/bleio/Device.c:525 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:523 msgid "Failed to stop advertising" msgstr "Kann advertisement nicht stoppen" -#: ports/nrf/common-hal/bleio/Device.c:550 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:548 msgid "Failed to start scanning" msgstr "Der Scanvorgang kann nicht gestartet werden" -#: ports/nrf/common-hal/bleio/Device.c:566 -#, fuzzy +#: ports/nrf/common-hal/bleio/Device.c:564 msgid "Failed to create mutex" msgstr "Erstellen des Mutex ist fehlgeschlagen" #: ports/nrf/common-hal/bleio/Peripheral.c:304 -#, fuzzy, c-format +#, c-format msgid "Failed to add service, err 0x%04x" msgstr "Dienst konnte nicht hinzugefügt werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Scanner.c:75 -#, fuzzy, c-format +#, c-format msgid "Failed to continue scanning, err 0x%04x" msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Scanner.c:101 -#, fuzzy, c-format +#, c-format msgid "Failed to start scanning, err 0x%04x" msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%04x" #: ports/nrf/common-hal/bleio/Service.c:88 -#, fuzzy, c-format +#, c-format msgid "Failed to add characteristic, err 0x%04x" msgstr "Fehler beim Hinzufügen des Merkmals. Status: 0x%04x" @@ -823,7 +806,7 @@ msgid "Characteristic already in use by another Service." msgstr "Merkmal wird bereits von einem anderen Dienst verwendet." #: ports/nrf/common-hal/bleio/UUID.c:54 -#, fuzzy, c-format +#, c-format msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "Kann keine herstellerspezifische UUID hinzufügen. Status: 0x%04x" @@ -837,12 +820,10 @@ msgid "Unexpected nrfx uuid type" msgstr "Unerwarteter nrfx uuid-Typ" #: ports/nrf/common-hal/busio/I2C.c:98 -#, fuzzy msgid "All I2C peripherals are in use" msgstr "Alle I2C-Peripheriegeräte sind in Benutzung" #: ports/nrf/common-hal/busio/SPI.c:133 -#, fuzzy msgid "All SPI peripherals are in use" msgstr "Alle SPI-Peripheriegeräte sind in Benutzung" @@ -851,31 +832,27 @@ msgstr "Alle SPI-Peripheriegeräte sind in Benutzung" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/nrf/common-hal/busio/UART.c:95 -#, fuzzy +#: ports/nrf/common-hal/busio/UART.c:122 msgid "Invalid buffer size" msgstr "Ungültige Puffergröße" -#: ports/nrf/common-hal/busio/UART.c:99 -#, fuzzy +#: ports/nrf/common-hal/busio/UART.c:126 msgid "Odd parity is not supported" -msgstr "bytes mit mehr als 8 bits werden nicht unterstützt" +msgstr "Ungerade Parität wird nicht unterstützt" -#: ports/nrf/common-hal/busio/UART.c:335 ports/nrf/common-hal/busio/UART.c:339 -#: ports/nrf/common-hal/busio/UART.c:344 ports/nrf/common-hal/busio/UART.c:349 -#: ports/nrf/common-hal/busio/UART.c:355 ports/nrf/common-hal/busio/UART.c:360 -#: ports/nrf/common-hal/busio/UART.c:365 ports/nrf/common-hal/busio/UART.c:369 -#: ports/nrf/common-hal/busio/UART.c:377 +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 msgid "busio.UART not available" msgstr "Kann busio.UART nicht finden" #: ports/nrf/common-hal/microcontroller/Processor.c:48 -#, fuzzy msgid "Cannot get temperature" msgstr "Kann Temperatur nicht holen" #: ports/nrf/common-hal/pulseio/PWMOut.c:161 -#, fuzzy msgid "All PWM peripherals are in use" msgstr "Alle PWM-Peripheriegeräte werden verwendet" @@ -981,9 +958,8 @@ msgid "bad compile mode" msgstr "" #: py/builtinhelp.c:137 -#, fuzzy msgid "Plus any modules on the filesystem\n" -msgstr "Dateisystem kann nicht wieder gemounted werden." +msgstr "" #: py/builtinhelp.c:183 #, c-format @@ -994,6 +970,11 @@ msgid "" "\n" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +"Willkommen bei Adafruit CircuitPython %s!\n" +"\n" +"Projektleitfäden findest du auf learn.adafruit.com/category/circuitpython \n" +"\n" +"Um die integrierten Module aufzulisten, führe bitte `help(\"modules\")` aus.\n" #: py/builtinimport.c:336 msgid "cannot perform relative import" @@ -1219,7 +1200,7 @@ msgid "unsupported Thumb instruction '%s' with %d arguments" msgstr "" #: py/emitinlinethumb.c:810 -#, fuzzy +#, still fuzzy, what branch? msgid "branch not in range" msgstr "Kalibrierung ist außerhalb der Reichweite" @@ -1361,7 +1342,7 @@ msgstr "" #: py/modstruct.c:148 py/modstruct.c:156 py/modstruct.c:244 py/modstruct.c:254 #: shared-bindings/struct/__init__.c:102 shared-bindings/struct/__init__.c:161 -#: shared-module/struct/__init__.c:128 shared-module/struct/__init__.c:183 +#: shared-module/struct/__init__.c:183 msgid "buffer too small" msgstr "" @@ -2101,23 +2082,20 @@ msgid "" msgstr "" #: shared-bindings/audioio/Mixer.c:91 -#, fuzzy msgid "Invalid voice count" -msgstr "Ungültiger clock pin" +msgstr "Ungültige Anzahl von Stimmen" #: shared-bindings/audioio/Mixer.c:96 -#, fuzzy msgid "Invalid channel count" -msgstr "Ungültiger clock pin" +msgstr "Ungültige Anzahl von Kanälen" #: shared-bindings/audioio/Mixer.c:100 msgid "Sample rate must be positive" -msgstr "" +msgstr "Abtastrate muss positiv sein" #: shared-bindings/audioio/Mixer.c:104 -#, fuzzy msgid "bits_per_sample must be 8 or 16" -msgstr "bits müssen 8 sein" +msgstr "Es müssen 8 oder 16 bits_per_sample sein" #: shared-bindings/audioio/RawSample.c:95 msgid "" @@ -2130,78 +2108,57 @@ msgid "buffer must be a bytes-like object" msgstr "" #: shared-bindings/audioio/WaveFile.c:78 -#: shared-bindings/displayio/OnDiskBitmap.c:87 +#: shared-bindings/displayio/OnDiskBitmap.c:85 msgid "file must be a file opened in byte mode" msgstr "" #: shared-bindings/bitbangio/I2C.c:109 shared-bindings/bitbangio/SPI.c:119 #: shared-bindings/busio/SPI.c:130 msgid "Function requires lock" -msgstr "" +msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde" #: shared-bindings/bitbangio/I2C.c:193 shared-bindings/busio/I2C.c:207 msgid "Buffer must be at least length 1" -msgstr "" +msgstr "Der Puffer muss eine Mindestenslänge von 1 haben" #: shared-bindings/bitbangio/SPI.c:149 shared-bindings/busio/SPI.c:172 msgid "Invalid polarity" -msgstr "" +msgstr "Ungültige Polarität" #: shared-bindings/bitbangio/SPI.c:153 shared-bindings/busio/SPI.c:176 msgid "Invalid phase" -msgstr "" +msgstr "Ungültige Phase" #: shared-bindings/bitbangio/SPI.c:157 shared-bindings/busio/SPI.c:180 msgid "Invalid number of bits" -msgstr "" +msgstr "Ungültige Anzahl von Bits" #: shared-bindings/bitbangio/SPI.c:282 shared-bindings/busio/SPI.c:345 msgid "buffer slices must be of equal length" -msgstr "" +msgstr "Puffersegmente müssen gleich lang sein" #: shared-bindings/bleio/Address.c:115 #, c-format msgid "Address is not %d bytes long or is in wrong format" -msgstr "" +msgstr "Die Adresse ist nicht %d Bytes lang oder das Format ist falsch" #: shared-bindings/bleio/Address.c:122 -#, fuzzy, c-format +#, c-format msgid "Address must be %d bytes long" -msgstr "Buffer müssen gleich lang sein" +msgstr "Die Adresse muss %d Bytes lang sein" #: shared-bindings/bleio/Characteristic.c:74 #: shared-bindings/bleio/Descriptor.c:86 shared-bindings/bleio/Service.c:66 msgid "Expected a UUID" -msgstr "" - -#: shared-bindings/bleio/CharacteristicBuffer.c:39 -#, fuzzy -msgid "Not connected" -msgstr "Kann nicht zu AP verbinden" - -#: shared-bindings/bleio/CharacteristicBuffer.c:74 -#, fuzzy -msgid "timeout must be >= 0.0" -msgstr "bits müssen 8 sein" +msgstr "Eine UUID wird erwartet" -#: shared-bindings/bleio/CharacteristicBuffer.c:79 -#, fuzzy +#: shared-bindings/bleio/CharacteristicBuffer.c:61 msgid "buffer_size must be >= 1" -msgstr "Buffer müssen gleich lang sein" +msgstr "Puffergröße muss >= 1 sein" -#: shared-bindings/bleio/CharacteristicBuffer.c:83 -#, fuzzy +#: shared-bindings/bleio/CharacteristicBuffer.c:65 msgid "Expected a Characteristic" -msgstr "Kann das Merkmal nicht hinzufügen." - -#: shared-bindings/bleio/CharacteristicBuffer.c:138 -#, fuzzy -msgid "CharacteristicBuffer writing not provided" -msgstr "Merkmal wird bereits von einem anderen Dienst verwendet." - -#: shared-bindings/bleio/CharacteristicBuffer.c:147 -msgid "Not connected." -msgstr "" +msgstr "Erwartet ein Merkmal" #: shared-bindings/bleio/Device.c:210 msgid "Can't add services in Central mode" @@ -2224,9 +2181,8 @@ msgid "services includes an object that is not a Service" msgstr "" #: shared-bindings/bleio/Peripheral.c:119 -#, fuzzy msgid "name must be a string" -msgstr "heap muss eine Liste sein" +msgstr "name muss ein String sein" #: shared-bindings/bleio/Service.c:84 msgid "characteristics includes an object that is not a Characteristic" @@ -2240,26 +2196,21 @@ msgstr "" msgid "UUID integer value not in range 0 to 0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c:91 -msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" -msgstr "" - -#: shared-bindings/bleio/UUID.c:103 -msgid "UUID value is not str, int or byte buffer" +#: shared-bindings/bleio/UUID.c:75 +msgid "UUID value is not int or byte buffer" msgstr "" -#: shared-bindings/bleio/UUID.c:107 -#, fuzzy +#: shared-bindings/bleio/UUID.c:79 msgid "Byte buffer must be 16 bytes." -msgstr "Buffer müssen gleich lang sein" +msgstr "Der Puffer muss 16 Bytes lang sein" -#: shared-bindings/bleio/UUID.c:151 +#: shared-bindings/bleio/UUID.c:120 msgid "not a 128-bit UUID" msgstr "" #: shared-bindings/busio/I2C.c:117 msgid "Function requires lock." -msgstr "" +msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde" #: shared-bindings/busio/UART.c:103 msgid "bits must be 7, 8 or 9" @@ -2367,9 +2318,8 @@ msgid "position must be 2-tuple" msgstr "" #: shared-bindings/displayio/Sprite.c:102 -#, fuzzy msgid "unsupported bitmap type" -msgstr "Baudrate wird nicht unterstütz" +msgstr "Nicht unterstützter Bitmap-Typ" #: shared-bindings/displayio/Sprite.c:167 msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" @@ -2622,9 +2572,8 @@ msgid "row must be packed and word aligned" msgstr "" #: shared-module/displayio/Display.c:62 -#, fuzzy msgid "Unsupported display bus type" -msgstr "Baudrate wird nicht unterstütz" +msgstr "Nicht unterstützter display bus type" #: shared-module/displayio/Group.c:39 msgid "Group full" @@ -2639,9 +2588,8 @@ msgid "Group empty" msgstr "" #: shared-module/displayio/OnDiskBitmap.c:49 -#, fuzzy msgid "Invalid BMP file" -msgstr "Ungültiger Pin" +msgstr "Ungültige BMP-Datei" #: shared-module/displayio/OnDiskBitmap.c:59 #, c-format @@ -2674,14 +2622,18 @@ msgstr "Kann '/' nicht remounten when USB aktiv ist" msgid "'S' and 'O' are not supported format types" msgstr "" +#: shared-module/struct/__init__.c:128 +#, c-format +msgid "unpack requires a buffer of %d bytes" +msgstr "unpack erfordert einen Puffer von %d Bytes" + #: shared-module/struct/__init__.c:136 msgid "too many arguments provided with the given format" msgstr "" #: shared-module/struct/__init__.c:179 -#, fuzzy msgid "buffer size must match format" -msgstr "Buffer müssen gleich lang sein" +msgstr "Buffergröße muss zum Format passen" #: shared-module/usb_hid/Device.c:45 #, c-format @@ -2717,10 +2669,10 @@ msgid "To exit, please reset the board without " msgstr "Zum beenden bitte resette das board ohne " #: supervisor/shared/safe_mode.c:107 -#, fuzzy msgid "" "You are running in safe mode which means something unanticipated happened.\n" -msgstr "Sicherheitsmodus aktiv, etwas wirklich schlechtes ist passiert.\n" +msgstr "" +"Sie laufen im abgesicherten Modus, was bedeutet, dass etwas Unerwartetes passiert ist.\n" #: supervisor/shared/safe_mode.c:109 msgid "" @@ -2728,6 +2680,9 @@ msgid "" "Please file an issue at https://github.com/adafruit/circuitpython/issues\n" " with the contents of your CIRCUITPY drive and this message:\n" msgstr "" +"Sieht aus, als wäre der CircuitPython-Kernel-Code abgestürzt. Uups!\n" +"Bitte melde das Problem unter https://github.com/adafruit/circuitpython/issues\n" +"mit dem Inhalt deines CIRCUITPY-Laufwerks und dieser Nachricht:\n" #: supervisor/shared/safe_mode.c:111 msgid "Crash into the HardFault_Handler.\n" @@ -2742,15 +2697,16 @@ msgid "MicroPython fatal error.\n" msgstr "" #: supervisor/shared/safe_mode.c:118 -#, fuzzy msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" msgstr "" -"Die Stromversorgung des Mikrocontrollers ist eingebrochen. Stelle sicher," -"dass deine Stromversorgung\n" +"Die Stromversorgung des Mikrocontrollers ist eingebrochen. Stelle sicher,\n" +"dass deine Stromversorgung genug Leistung für die gesamte Schaltung zur\n" +"Verfügung stellt und drücke die Reset-Taste (nachdem du das CIRCUITPY-Laufwerk\n" +"ausgeworfen hast)\n" #: supervisor/shared/safe_mode.c:120 msgid "" @@ -2767,22 +2723,29 @@ msgid "" "exit safe mode.\n" msgstr "" -#~ msgid "Invalid UUID string length" -#~ msgstr "Ungültige UUID-Stringlänge" +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" -#~ msgid "Invalid UUID parameter" -#~ msgstr "Ungültiger UUID-Parameter" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" -#~ msgid "Invalid Service type" -#~ msgstr "Ungültiger Diensttyp" +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." + +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2791,30 +2754,19 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." - -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" +#~ msgid "Invalid UUID parameter" +#~ msgstr "Ungültiger UUID-Parameter" -#~ msgid "Can not add Service." -#~ msgstr "Kann den Dienst nicht hinzufügen." +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." -#, fuzzy -#~ msgid "unpack requires a buffer of %d bytes" -#~ msgstr "Konnte keine RX Buffer mit %d allozieren" +#~ msgid "Invalid UUID string length" +#~ msgstr "Ungültige UUID-Stringlänge" From f43379c771fd9e8d95f7c43951b5869ad37224bf Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 22 Jan 2019 14:38:34 -0800 Subject: [PATCH 151/153] No pixelbuf on Hallowing --- ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 37f1bdef0bd52..fea4bc222c52a 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -9,6 +9,9 @@ EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ +# Disable pixelbuf to save room +EXCLUDE_PIXELBUF = 1 + CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 From 0cdbc004e6b8c29c06b53b648599ca190b881d2a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 22 Jan 2019 17:59:31 -0800 Subject: [PATCH 152/153] Enable displayio on all Express boards. --- ports/atmel-samd/mpconfigport.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index e9507e3cc97c0..c5b64b026072d 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -283,13 +283,9 @@ extern const struct _mp_obj_module_t pixelbuf_module; #define I2CSLAVE_MODULE #endif - #ifdef CIRCUITPY_DISPLAYIO + #define CIRCUITPY_DISPLAYIO (1) #define CIRCUITPY_DISPLAY_LIMIT (3) #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, - #else - #define CIRCUITPY_DISPLAY_LIMIT (0) - #define DISPLAYIO_MODULE - #endif #if MICROPY_PY_NETWORK #define NETWORK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&network_module }, From aaa644b223bcf86db6af14416916ea74311f7903 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 22 Jan 2019 18:49:37 -0800 Subject: [PATCH 153/153] Skip displayio on crickit builds and cpx build due to lack of space. --- .../boards/circuitplayground_express/mpconfigboard.h | 2 ++ .../circuitplayground_express_crickit/mpconfigboard.h | 2 ++ .../boards/feather_m0_express_crickit/mpconfigboard.h | 2 ++ ports/atmel-samd/mpconfigport.h | 6 ++++++ 4 files changed, 12 insertions(+) diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index e6a7e06769a20..6d926778e9362 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -46,3 +46,5 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 + +#define CIRCUITPY_DISPLAYIO (0) diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h index e66d9c40e8fa0..5c3be69dd6f00 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h @@ -49,3 +49,5 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 + +#define CIRCUITPY_DISPLAYIO (0) diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h index abbf0b08c9070..4a5004b3a92fd 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h @@ -32,3 +32,5 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +#define CIRCUITPY_DISPLAYIO (0) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index c5b64b026072d..da3383f8e9806 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -283,9 +283,15 @@ extern const struct _mp_obj_module_t pixelbuf_module; #define I2CSLAVE_MODULE #endif + #if !defined(CIRCUITPY_DISPLAYIO) || CIRCUITPY_DISPLAYIO #define CIRCUITPY_DISPLAYIO (1) #define CIRCUITPY_DISPLAY_LIMIT (3) #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, + #else + #define CIRCUITPY_DISPLAYIO (0) + #define CIRCUITPY_DISPLAY_LIMIT (0) + #define DISPLAYIO_MODULE + #endif #if MICROPY_PY_NETWORK #define NETWORK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&network_module },

&WnVKYts1@*rA_IRV8!*PAEhOZ|}QKb%&n5%x{G~ z*C(HwH!PLtl%0>L1^X;ZX8DSxNQA!KKXVPqn`IIDcjMYrR)QKNxt)wb_1pHlr+MHN z%@@i`B&HeWnlI>Six~AV8&ppk+ce{#WK{P!j>gm_=#D2 zhn}%7O&ZpUTbEo*i=Se!Va!PS>Ak#w{^<9YjelH7)fpqYq0!AAVq(wB>KMc?r-o3Y z5O@ox+YOSp8Q@l+&=L<@@@3%F>Zs}tkEw1k)cHiU$Y=DkJ%9yxTsQQ)xqm>Vl@ZCn zrBV85^ft%ZYMQgLqo&oDW3&%LlrjbK$*>sk(sd{>y4|VG?_YU{erL)?lcql!)K|q4 zswTYn$hj*+evi6>`7rfUwu)Rz>xzKUS}2l=`k8`U$_>1?9CyI=R^jsZ8tmy>VSC3E zL=ks(uz5Kx7RHeWzY*kecsobtHcK5M!+sZG!4y=45sUXJqFuSuIx7w>u82dDjj*j7aXVP42aq%PL zz)ukAU%!8`Rh5@>9`Q%dHp%_{n=HgwhLv(mtc>GPqXdpSMJx+5{{<}YqM|E6GM3FW&#y*h`j(!))BXuEzeZ46~TJI=?b9V=IH9C6cMvpF{DUpR4Pz%0e2S+he@I~93 z8|n{@8V2qxkbH+co%?|oz(4g8?9!97v8sv)KD@6{ua4xbNbjCF(6%8qo{kt0vbz`c zHoku#qo_1mhUI0m41LkI!D1*mAMw$vnU<5*%I0g7N=2%MVZSN|`v*dLjAux3@q0`9 ztCMLrN`drd*xJTM%dhrm33=IAU?uk`^N*LYq^i^)bW!JvIlXc1Z43Nq-b>>;pF6a_ zGg}Kj+z~0m0>D;5n?E>9E$6RuGDZ7Iyd$8%Eg>6i8gSYjRipugF2Z^%cKM*Wr;f1GaCVj=#l znXOrcMS{LS5tugBgF$vr!q3m2(N5-m9`?pJ7Twa#gE>VA z_BMXoq$NRy#Busv+cZ;KKvPb~uo(mPM%>c8xgj7R6d%!r|C}G7SPTsO^xbDrFJ2an zFUCO;!l_#Adkd8G8Z3!P@K%3kA=El7W?rM%jX!?jWrZJ2ztBr!Q0%U)Yh90O`T3gS zhLRF$rEV-{0Ie~G31E7vhE;ePWvE~=W#(`AlSB^Di(kL9)>PS zd`al$i@v;L&kUM+IkAjCPtQH&zuDrfz)cO<4P)PB`7qVNLu>~UK_vIukOrQ{q1{oH zB&KGU<^51B)h1Elk3_k#XHxDl5=$$>eRGt!rAWbb=ruD4=qgL1fj4jIzV2A?^ZwY& z-`y2-bW9$)!PVR23bYPL8NM}23O+>2G4lVi358PmwArN%PreL&#nT!Tvkkmpl)RN; zZB9ITLbqAI!~1?Bik9#eEiC@r;KsugknaBwj}`Yq4UjQ)w)a=9Q#=5aN!8S#?o#)*!VuS;&nu^DF(;>F^~4MX1`uzq2Qm-?12Bei1&0OZdYVbzM)d*9^e3L1H7`2BIq^y-{&btvXc720k7ruRKbg${~nK~u?ynH2vO19HZ+FXr?`%5wb%m4=3zaB8;J3W3H^^=hvh!?cW z)wtKpu)p`0Ei^|PfSjPda6YptQK8ZiMIF)S#M0Wtk>an7(_=YRyR5#wpw8c3O|BPC zgwyd*69GtYb$IlZGYfgnIrNvH7hRIF7|Xhn7IdRVR9`SfNiMr{Z`bwg=Vc@MFYFtw zmECGo3y32UyFUZCyNNa~hcfah1rY+OF9dxF)31>JW_cOk#Oio*gD<6bf%zgcDw_D; z{X0|87gqAL!LSd@c!BK?-lj3Bzoh;mWLh04L`TBT5c}wUP6}uDOZFP$K#{5e)zF@b z&5C}$?0ycwm`~VHn;}Igg7~jD&XNuv9I^Yy4UYU^$G_ltYa>>-`KO~8QP)S|lWeKJ zS~U#;gG=dEpl(k?w=4*^EV$^HRjCt;YbrfTN76^H`o3+26NZ*=;$G?9P1Pt^k?p|A zfD`bhf(<~{L;*>;JK%Om@Y5;z())5Dm8RUFmCFVO*e(N-E^wZARZP;~D4bSr<_Pr-MKsU(-vO8*R=HCqi7WtFM=p2XvFxc&{CNyo}~of?-v^denQRh4l3H`uz_-E*fKI9PMMs3SQAQ z4L#hdBG7(G&6%jmM9h4n<#+R{CA`24O~~D!XI09>uS)r<=p&L4TISB16v`8|w!Xf1 z_Tph*s7WJF38Roe^Y2xhuMYDD<3vgd>(#PoE@^&_WgaHVs}#_0tOE^gPE|!QhG$|M z$cH~hT6l+@Tc@X)0GQo+=`&V}hK6PrbvYBBotc?wQcc4Jz=E*}R-yN!*!}$d?-1UU zv4@MKmP!+~r2(IO=m)@J0+s57e445Bz4jue{4^ib@)%{Fd)ujB)fpHaSE8-Wqr`4b05}B0ScR;6_^Ga9N3zY( z@1AomPJ98`kB1cLOKQfkY%5!Mo^pd?4xVa4S}vkWBlsImaj0c95AhUBV!w>lB5_dp zmK%^Pr$63k|%_M;$!BKc6V8H)Y*I-3TYY ze#9iVsY*x{`P8sfRJvrzAuwAYHGd&2nq0Gn{eG_qW#mn*r!<;79yTXE(v0aa*oso% z>mQDpC+gbWI=o30j$38k%!_-q*teS0&l*sTFy68W*LjVRriNerB&^1zI!;v82_M9; z9TIGD`rOPp>jOj9WVvDuousK6_|6ZVlP;QdAM?A4eP5SFRhb>1br&4fO5IEE17#u) zPfy>W7LGR@adN@zZr2AwuzBseD#cS!@o1&>2 z! zog(T2g2LV&VzM5-Os%}a!cM(}qk_Gagd)b8PrCL)V!VQBhIf8E#KQ>8rl29e^b)Mo z^h+X3OBvnIY;OkJUO!vjfRW4hv(tIcNo7xn+AykbK|?MJnCD-O%H9bGQDNI?YBy%} z9D4#Vu0L=MCHlu2Tsk7i;T+q)xivY4tanxR3ih}TdrwX7Gp>8oSwLsn_KOi(iG@8o z-$wx;qQNF7{ZDrqQ`*U&kp=%wL(D=be16i|Ip0<+))~#wl9rmf)0yNf4Y~j2~`<2Qnyh-c=#;wrjA6w71 z^k$pJ{hx`}@gKQctzQKEL0n$<=+?upPWCl%T`J~@+S*M9qL7QL@|Ti85Rfoy6-aVv zIXLec#nM>u(nRZBcc#Oi4LWsf02G+ofMb!H3P1D=Oc3=uP4$}#aI*MycZnMPgfBz8 z(!-xfm~K>ir9{Ws>c%-kfZibezuVjW(>woi_@mf^Mou}j(LvLf=1g5IE@v-(FS|vz zh6$`#NJz(E$eYOKpXgwf1yfqV8KgZIDD;oTscUZjUyegHkpb6DfXSx>_p~(%_Pr!R#dnz^^3WquRWcalu-n`>CrG_vD24Ja$?h4pe+l5=@j?LnaB&t}_6(D-5f!;S5`Uz1Ezf2+Uusc>08iIC4cA6% zJ=F@)#-S?9-Tq~wus(pNxyuTk5cVlMTZMi|tz}KYQud!-$%R?lQCZ-iEj2f7> z{|qAl;-Z72qXWbtbJv|e8>TeOH6(pC-rWdz%nob2PCinqP57m6(w>j6`tdaf8+M&=c2Pt>)w@?Bg zb2(L^BQfN`bbx4V=~@4RhmD%(`%sG-@R8v0YT1iG7xD%5t@KBZEdW;+3Ut+rapVZa z?aJ~{!0>JWarY_Z(qnV-sq>Go>R^V1BoUhog@U zfqI<_#>5-$<5OE)dP~8@;)R&zH}NIpkYatqE@-9uEGHTC?6&|bWCSR#UN8vJZQzL* z@r-g1-ZP#ChR#l+l`k-!4JR8VK0t3Zy%;g!;H7DIFZDOg`#ns+`3Kqy;-&+%yu&{# zO;Hr=$fb&^FvT>8ULL?cd!aJq%u*u*wSJKYd93Gzmxs=m`ub?o;B!wVX)h9Oxnqk| zww^0I29s<9IMoXL3m#HsJfKhXBVjTUN|1ML!U4(?m`IV94*BNdAtxc5`3pJ3IhF${+@o;$pM^f`piuI3ELc z=DXD_e=@)$YYiipgLpN9&?wJB^X11^@sl6M?>sgBm|`o!HJliiAa0nfE^8P3S0z|i z1c@=Ro{PGYOiTEA-Z*zEt6|P?T5-xm%ALqrRH|UE%hZ01TirXu^{2=VT+KggAFP8r z`1p6hW4C}K0-=xhrvdk=z4tqbQ*Dr`jya$UT?;-ixHLYT1PZP$i*2`M4#&;M>pblZ zXA(eIrwxKgf^oN{>}S>6-pcKRLkDuaOzlDKhGq70*+S`Io1Dp24)HhRB%DURj(`|= z7s$nuJ2xKa8}1)X+LtZ-+gtM4@8<4Jpwr3Duz_2eA+b_T2T126q)oO4*WP}w&=R07 z{ad7MhIq}@jkQGipO#&0lOS3bhu1N?U+o3s+Qb-YqpXD8#i{ z_H^^xr_|I3jb6w5mS?*W@@?zGg?n8b@w)3e+;(uw_{p;~nTxaj%ZAO#ENO4D;LD@n zctF%yob}&9^4=(fLMHOO0G8sc-Sq5P>IVt;6%wGk9_GK(NDE|-?e+M%p*CbfC^2vF z5SU;SFA{F;thOsp07y=-lw;it+>?HW9uHfQz-;E);a<3cxF>6qPH1X|Y^EXwh~X z*$SMkJZ_$#6aa_TLFJV)tIye9XG!INYM^r=jTdFJ*wLMNXM-a1>ceW-Lu9&2Z`mcm zu=)|g7KS~jL;ag2O+sn|rrE!4?Vwi&-%XF(g_1QYI`1O*%z>DCokj*P>lmQS8Mn@T z^>j~Nv5=b&@MkG`lS-y39hGkj?aru;v|R2ym-nJpPhPHI8F=YRO+e1VPet1(%)+~QE>JTHvgD$8GSnv%pC^wSU|ZVZPt+_ znJS{uAIsrTiTilpPCucW^GYVsZ^#7fK-4+5tQqFcSPg`r77FFhZAbT{Mq7GL&jB>` zf%-^khNL_G70kCJ4%1zE7u1I~4&#H*mUw5X#`+)6`s8hj>*-0qBIfhm{=RA_DEzmF zuWTMr4fW6&z}zG+TjkG``YM7J5VXS5(nfk@TG=K^%V(K80i9kv#c;ZRK;-zvs1o+C z9O^8CQ}y4rceA~}Ch(o!&8IWP?uQI~NoosM=Yvr(B6eR9SKEZk+|kYaHjFFgF9S@g zkv?L+*g6pEB@19pu5^2&4Pd_c8$OxSrXX#!s=)T0rW{}%#B6Q2o!9t^#q{ODNgOHE zE>U0ht5jg8Gj*MV)j2I*k7H0+y}N5$HFI9FUNg5>V6XJ;ZiiPr6HD()uDU6iN`Rg| z*RT#1rAr8BI*-fcu~a(8XG){87s?touU4goWE)oW^!2p{SodzzWC& zUj+0?!e)NreaQ_BT#|GyNl=zN&1!}SY8}&2Jee7_mV@z%l3K!wkxxK5GLx zC$U^Aak{Y%d&SzZX3SC^gjbvb!}CLil0n=bAUxf|e3x%YdXS`k0SJ7bd$me8Ang7h z764ZVq|*%$G|<=q;A0p&CMzt}Q|Up21MX~KSqe@9{_EoVDYMYLTQQF{DUb zsGW_fk3tt01Icc}!=1Susfe#JK!_b($5s4-XC8RQT5yz^w2P4B@s0uKyTK5$Yy)53 zVUY`{b%Ob<58XEgsBr+HN155C>08z@%yfch8x;2tXSVIqB=bBQb7 zfMCPs$?3|?faYTJ@No9G>z{EF2EL^31upU=slb#XY0bhN2sXezIAlkYbM^p z5bb~Xa`U}69zVtV>!hq?Z=QUvggkjq%-)6=02!mr^E@K}&Q#19NMb3>zc;ls1^ag1 z;7N{2c@)54zOm?fq8Hq%ucScH13mG{0-UkPaw}&ge03{vp>FcGZvJ*a8 zDg%&)ZMg}|ZjM>UeuXyFur#-9LFqmd83#4ty{=n~vqp>@@GtJKbYl2~{yxE2{KZP0 z@e_YvJaLW*|Il|gog(@g>&6?dRblF~=JTJsyDo+^SNrjmlhY&T#u}hm6Y~8;MO;km zt+C6?Y$antIM=ib;$_@YvDv}l;UkC7fWFbTJiq*^ltK}hfLr~$H*emgwRV->&N|5Y zXgTqLM*nvYh5IaTd!@Bq=lP=uZ= z;tp8^maEb0M3;wJN{bjNo6o@!OKbTpI;nq^**2#tqFuF=l<|>nd(X04T;)I=+phx6 zbeVR$ku|e1Q+s}_Oh43Nva-l-p<7up3r?qpLuY=P>pAN#y0VYQ&a=kiQokervlVm6 zZergoZzKSHn*nJGz!|d;nYaT86_`~uV(g)xoKk^%`i<~D3~HkJ8^reqziQii&@)K8zjLVxzD5`P5Ql1^ts6{pN8k8x8>EQ9-iob9O2TadV9JGP@6#06Le1?f)3r_A+rOPtAu1ss!vwbrc237?l(alB9O zxsBTyhQfEhijV!=ApN`r6E&B#y^WN~VwUzAnXcKHB)#$cOFM(rkckivw?`PU*Bd}a zlzh=h+S&9oh~J{klF^`}GnBUO=Skl9IIW_oclpW(9>5D#y}&}uDJl{MYjJk zd*1$51%l7QfaBKg=Ej=7Y`YO_&}Z|d{_%{5&glDxAjVT&z7F_;26E0&PZ&%*Z(md{ zo4jV)P2I?>N{JYGq_zBhNqO0pF1!!|R9B1aVS#e2KqER{w;hyD{ExPg(1Yrsf$0ET z9|~J<0&@pB+?a_E7wCttM`0kRM>}QGPyHpK5PEE~kyBCn6;s>{D3@ndmM16^#{vlp zzu&|&|1sRALA~({J*;YA+h_APmbRb&<3-cufdBZvZ_+&%)#s;;%#xkMy$xDe)@%Rr zJE9K^BW~aLDycF4!PQYbN#I9bUf#dIh4Lmi9E{fLzZ0Xa?IwUU%T4tI-sqCL>B+0s zCFEUzt9R}e(`ESBBQGr~Sr8{l!y~%jN!8n?Di0R z*7o(XYsFTkg4g=dA@<%Kj#LA4XMJ;}YAYFB;YpYQ)t$&xn@@9qH(iWaIr7>ZAKdi^ z3{7r<(guQ~ojFrcI3w7y=JB#CJdzc|g+2beAdj=r)PZ3Qm&C`o<&RZ2O9wwo%gM#v zARyB3W3s)(-0kbp64DJJYXx%>iGVs2S$amP~*$Rf?vVdhi zJ=xb|SR-49nKh?WFL$OU@O*tHx@{g&O409eL}tNc-IR@^s)u$FRcL zdiI5_A+go{vAcNLzALF|k0F-PLqM?`4LFa0yaX6vOCgqs8Ub+@F>8TVZLiUHKpuFs zygTsp5N=~b82R)%;CX?J^qWkq>G7-Tv7`ESyYsvgtvdBK^~QNzPw!D=$<;p| zdXmhT)#SAe2$PVUhO47b$p0?w3X$FLG?P8)$)g(zrw}y*u8e}pJkFn9dHl|=if`|* zu7F8Mhh=F669(Y4@B6HNR`9dbt=Ro7#!nFUGgf)zQ7`hbVcqgVgobx_h3EYc$#C&wZX0sl(q2_QD&|fw|q!F zalMIcj-EGt_|MqKv+qDD9gyF^GYHveq8H+%w|^KkpNtka-njeBH6Jl%F|mq+UtXM3 z+`I;)PQ~J}U?1=_oh=I)+~4z>Di|47v~MNpt*AX1GXnPr3ORsh17t8<=K_xwuH3}v zHLr|-)& ze{jB_y9`Jv4l{Lkvrng2cO$g}a(gnKC;Wkc^GN742t0l7iW~7i;-N4}7|>%00Gs27 ziT8}&0i%|As${JA*!(=3Q^TGzfWU#53sVHptGS}NR?AL0iRJA#0O6x@K<5O_k}t!y z0BxwDrM1XsdQ1c!izSOqoDm1l6p#jrEI=})r*gN%^n9bDs{AF4jtH@vLmo(IdOC?I zJ}ev+>r0{$d@STq_b8fC;0!r;f-K%jnYPK9urVt{^v|A%{0@H3d)`=Mk3UztTl3G^ z`f{$K+1dC^`mAW#`F@{ugV6kXybX&Ex5#s@DAdJ}DE^S!weN4=WW0I`O$afI9dt6# zD4CeDtGP>tCk!&u+3}j4hQh@0Dtm+VIj>f}QY8cyDK}-qGCK!dc{Q@(T19sE;%O!% zlucsNxtEOF-Imu#KA7V88s0qVCF6_ie_SE^$0)0K#-mNp?if_w{rr#Z=}QM&{^3eF z9=Ue`ayvfvt;69IWD$FyoAXNO*X8lD0BLLqXjp@@+@M3PP`+x!ec^Q+mf*ZO9#C;9 zo(&%O`qCF{TL@}engQx_6YGiGZ}h5g>+cbMp>G5;{AC0c^CD%$;gi2wY-z+ z!$e{lyuineBjT$XFgEdtN>|(q9?@>P9#5c#@dm_K-efkyd}QTxTiSbWnf1hBJtjV? zMz0RH5=736u4?aIRkK;aKs#&x8YmDk0PRbeb~ll-@>j(62j!18AGio#{hhgKFc|}p z>6e~-i~;ja*DJHIO9UV!4ppF2f;@hpu5!Xb=8)dH3(g(Rw!oL43Dk5=_JK zMkjyEz{vvW=;948^uMjd0(~0={YD53`ERLtiSZVt=j*bCIK&e@FA?$@_+%|AS5MZm zyRrE4{j$47@izN@_G^ytO0&(r&5M;>>JoWTIKwjmQ?%=kwgT7nN=p}EUR0D((uiLR zu4Zp%ZPTk!`|J8OzYq7CO8Gi?*hCfA1d)phuL(KjT)dx+H)V+8{4o2ALsX0z|8d5) z#+Kvop*x=C>Pz33J4QPaktJrLL8s5+QqbPI4pink9yi}Q-|WXoW+oa;^UMhe%~#NH zk`rXrkG$a8f4MnQZ$qmd+n)hX!`ufvTbg9OSNH*EoR&nbAk1eB69q&_214e^3RYIefgO`^Z1P5 z(oDiz7ggR< zx`iH>X;{-Gu;&~gb&ki?*H};KUG67i=VkLpXh>^J8IarETbO)HGkdyJm^|`SU?S6^ zHD~2ARgoJEx$)Q)*ywQC(c@Hxbxw}Y8PGaX%VFkiLn*=kv-Bi1@oI~WWl~uP(sH_s zf7q_EM%fSS?{xNwD{2Pz4M?7Hms6B|HL%XotyteET&XnTie9qKN>0vt@BpSP8_3J1 z+<)_n<<|}j>OuBwxfJ^~f4wlSJHlq>kAJ|N-r!ifk9Th4sz#lQkigW=r+HcY1ic&G zb^6FU8oj6z8`I2`NhGx{jETu*SdS1IoTzJ%7uN3pt0beUfgR#Z3e8Ws#-}oFuN#Gk zW=dOWXsu>=@HO)}HL||NU-iY7WTWL+ZSdTy%#Vdwnxf1i-BSRe5IY6gmL?bF=URKr zXM0Je^ah<68l`v^th$5CLbB4~Tx248UnQoCkH}yD)B_MNgs7YP2dRAlAyBK*T{a?DMDK-*=~B z2|v3^`){;U7If&O52Vvq;?WgO8RDI3cUCj6!~7|d?cREvhhfK4md#Acve@)4d!AQI zD?HQw!ar7WYL{h}+kUC!6Zjyj0gIdOZum`-I_Z17kkOOA&^3c({iFudp@{7Oqm zSW4~9#R!gV{jCVxky&nSns4eKt|SrOo@hnMXJ`!M78?a7jFZ|qcc>KF7=}Yfr>Y>N zVg2O;cTetagKGw;q`gRwZvHBhB3cdp9COLL_nrSf_{5owv)vtv=x5iQuTfA$mTs1R3944?>wRy=xA{bP`2p)Qa@pdeza`__Y=-_oS)X_2o(Tp5#=V^ZGvxWbS;m9RKa-^#9XLY6t zR%SchOHR^bu%0n13_#CxBQ&RJzT&efWj7zp}L$$omf zO-`FKbM36YmCgK{vT&IwCnX~ormb{YoqVpKYN@XdhmjJ$9;IqfbHZ=xpmr9sGSU|} z@^-io854{oZ!44damj>JJBaDaoA|4+GX8qUw4_Md>C@hSJE2K4u#$Yn#n<+pQpn@~ z4kmAXED$1rFQ}#*ox21#a7Wo_H>8*q2~;zca;hE>Jsb|Q@Y~t9S0Z6erF3@Y3C`lV zAl^*fe@J;><=fUP7`MAI$N`@z2e$?pxem4X`P$%oijb?O+$Ad1{?V5@CVuekQ=j(fmfYqo&twvw z#};tdrTqEkkI~WC4-)IVNjjjiHY;1B_qr6Qd}5eJS`q~;Zp?ChP@LEGosS_}sRm{` zZ1Q(3bJu-r#vSa+pYvVmc1Mq$J{}i@DRq@`Kty100g8Ixw;fM~1kFi$BJ#a`neNVq^F34^4u)UiwOg@2>;1%jn9OHiFUsn~5Cr`({6= zS5~gWJ>lM}{as~{Z@7%2X22@hg!%j7_Bl8St62; z*DeeZ9~Svb3pY*~r*W?OBc5ct6S+Cacz{sL9!7uDmY^oeD=Q+6p z7&CbG6puRUa{+%imQ(v5nFcxbZ1;>%9bpg?aAiCXdL7W+M-IaQjnajsocyUoEDE)L z-&gi;K^2ppg!e&G9tU*oy}|-|Oe1hsaU$Auddo-wQ6mXU=Kc+-@4Ma~@;~IeWS>O} zedLP@r4)5DxdxOR}@k@7B zg&-CM5K+1U8f1>;=KSHnMlsbMoVr=l;_z`s14c#vi^L55jmOQ?Q-&0G_}V$V#w^!N zrw01dU3(}~%c`_yEEoY|Cs{ZDz&k8)9zZV`RKmsCr}H>KjAoXgvY|3f0Sx1-R>HuE zi_t_|nXXD|}U%Ppk==ty;Ml2BLUkur7OIHgXuDZZf&B(n+mw&VU&in8IT{luR zZbQGvP)cLRL*4!DeHR)Ob`A~>60VQFZA3G1UOlTF#gTYVg)*HW>UhMN*uL9T9)=-T?7Pv^2^HlwSu5! z{{Mq~eig^Gm3NK8tOeKfv$0<_+Gz#6FFoBZf^y0(L6EqaML}h>-6zT})Z`I)mu5MH ze3k3Obe9M8jOc`c7355`r3Q{rD!xFcC?sm@E#OTN%TEb)o2(KBR@eA*AI=`HxPNEo zMm&UTbzy179y*kN{`A2u-X*;`1V5ShY{bLCW<>cI*^A`62D^2eQ&B#3(yu0 zr&GQcGf2PMIfJ(4Te%*#q{DytiyYBmF=ps?9ymWJ$`Xj1;d%}Ku~@07_0blMD7&tk z3nD-6*MUj|6tZkD6Zn{bfKTfzod3fenFyXNA3|EPp}HX_&gjWdW^S;+H5J!JwxO^g z1tybrONokwJHlu0m-M!Gwx8d={|W?xbV0tNt-W1ZU(LNj4|y*j-H+}a;j-LU8?Fyg zwwC=Ko}M4rxy3o@-T!0;i@vcFK*Ji)|Bf>4bmGlX{`Ms?Cz*5nVS`m|&%r$qZ>Xc3 zQnKElB}mE-3GE1J5>%1lPkju>GN;9(5MS0Uy`NTv&plwyU)hhIkmfHie@r)8%&t8y z2xXiPLcA>82nGZBSm%mVy$?Rt)xB_7DxV=}rtkU6)_`%FITTOV<~;mYcl7JCMy6-e z&iEN}>SHjA@GF+rMBOP}(_Gz;=;?dB;%g;_sD?YE{W2BUN+$l?^DK2xnJazpT~|a% z;AqH{-Pw{~$-(6YdpB4258?p_zOvZYv7~QwE-K7bY)Sf^mVduFc>h4ZY4~N+GwC+( zQf<7sl>^uLqn7Rc^DNKFl&3bY6PH9q=}D$HJ%~;(Q+$7Nn+!GQut>lb9yL=>>wMvn z5~@qP`c{;9p`63|^6-kJxbDMg31=(8U6HEfN93}m<899LE~#W5JWeDp%w80imhyKc zmh>1KxK1brDn4*aF5Jjx&m>9|Iyf)ZC={Q=DOUIf=kQG%Sc=!{t8>3 ztd-@%RNG1(M=DA=$~1l>a@k&_&I{T?G4{kdw@Ot{cE;#50V7bf76x$vjND1wF*64z zCx4+@>J!WR)Aqu1r!pGk-yA-aJU0VJap4Ld216ePV-@Wis?(~^X<7%gt3hU})}z#7 zQH+hggTOMxhI?Y%u*Bhhrs^EoIif+GSG~WRHEMn(FU03nT4&*hrf#5W3;g+P_CxTGXC-oSd{0)HiR8dyJqHPPT7Hw|)U@aiV_NxzYX z1Pn|F0q{j9AYss7(vm>!|60J7!#H)G>_md=oMb;`r_%aaL5`D;n^-jC!w67~1JF}6 zQ*|KY{*Aj&%OCMkCseI-uZ38Bld)Ilh#13dK8*9B7xy6r?nvf#TwwolJ75phrdYwg5mrH#5CGg3UdwEc>Ajaisu)S8^_avV9^aHP~|`gJO(w?UaZuc+uU zea|gwBGZ$-WvtE{dC(9a5mX#&q-bv5)K$)Zk(b6NEF5}`Bp?tZ*8x+1&i4islTAMd z;h{9$WL42LXc{gx9`-CFfOT;`#jk@R{IrkPUGPZfj3EF*ikh378%2-ea?NzfXgAw1 zdpvIUSVOt+ZcbY1%fDhIHzgx;b8o>AWkdu4mwqj->#qTg6!g2_@4O;kMxx>(yG$R& z#oIYKksAB%;yKK>TumPgh1mcu!zOYt;w7lG7F7IGDH;t^>)yWxXaME74BhtXul6bT z%v{C5>Nf7V$Js5q0MV4R) zmWi}2o>i&ZW79x3GqKM}(tw&I3`=~jq;Kd2tPp|B&VQ&#fm$! zXNeYmCuO$pUhiw`+!>~Kwz-``6b&Qom&_4^k9ax0fm9y}y=dUWroaEBGZ#vKU6&>M z^zZMsGhk&QZ(zG#0!RnTL8?D{Rz|8dHVAj*MRCud_E5b`9{#8s$vlRd+IgVHjcE0u z!18Xm$GLnQG5aw$4!yuaIj5AHKL!c z`^&Ea$s*53x7CA~zWMX)Z|f^k$!a{l*yWsolrginCjvMvDQ`f2(QCPnqUFzCf5e|W zj)*Tr_lWXWN38SGoYtqfTL9^bz~`ooGKD%jH4V*Yuz05kS`~t4?@<(|~uUF@HRSU~TYH@~DB;RSvK?2uZxF zYr4=L!k=8<9a_JeEW+442=;i{ch@J8li743I3|dEuEYc5=p)2aL>N@i)*Tl(jFF-?~%4zG{{SZlD!e~LW6iZZ6e5QfPWA7|^ z!bt>u&w}y!vau7eb+Qa_mU!>+@dbhmw-#A->Zr7kE`Mt0u>WrXA`o!T`a6;WIqR9w zBx<0%_z2u;8YwN`5RR|Q8XMol(vjQXq!pnmQ$l~kF1OU-)7e(DsP`TVI50Lj&&^G> z8~<6P($XZn6CuqsxS&1x9$pTg zQ=gX4#_u+f=_Tnz1`2Da0Nz>; z-+Fl&=+S~7YuszB2A_Ir%iA-4PBbfi>Eeqt9lxzvP*gUHRuRNA+|G2Eeb2q5S_a@g z_9uUND@?_$MjdZ|tz%!3Gl8$7T$Up+{3-s1P51vCjH?Mqu7D*y_Ll3CV6ou)D~6Fw zvZ(Rgo{wBNBw-ZiPw)_SG4WF5kGDO14=Yvma-TgHUu5YjA9#ME)es1{5kCLqeeO}*3(=7S-f69WS|{5_S^r)w|I?1P_@{?F zzFR<9y40?m$sGVNp5WmA%1Xgv+4*i(8Xu^rZ|>Sl^FDVZ%t3c!OE*co(I{DMwU>;_Ps%;VMgs_XRV64i$BP zOsey2Lrgin8`NJ+ulG4;)R*uEPG|^xjdqQbyVJkcr<}|iy%bn)|IusLbm}F@Jwo@Z zW!XpzF?PD+2D2a*bH2A3W0t`CAmxE)pyu zfweFXJuG?P;b7XwS3+4j{#-l8HHz>sYsG)09f3lYQd(Y;)wmKS?Q}h|{E76f1YK=C zl6?mn-I8R?>0}um`-iXgY0qu)hVb1*>1lbco9v(XMx4pZO^P#KD^)7f`keJ3VlB_M zWB#EAj3nd!eALiXOv@U6J#VG#_npQ_pP!(PA}fox_)0WyS!2M`lKBzd7t|k5)IeU7 zn0wVj6LB35Y9izqg~0Hw{1R%Eg=n=5BCgpB(DfE_F+!fjtcMVPqfT>dPQ`yRr4BhP5O>;r02%%sKSb+l&iJC6Xa{l9Be* zb5>yJdwOeGLctphD~D!Q+SFNSiTWQkf44w4P;DUl7tHNUcn&)^J<>m_@$#^Ywj-9>n@d9E z5RJAbOr#_9J(O=Pu6;ADnJ%z3;X(MI6!-}H+Cgd3A?ETVzJyETBe52723u#A&mz3W z!sQ7hVKN;$#>S4*&&DSv3Q#diqPKZ41Kcs=m$Ey;N=r*4$2~8!VchbXnrQE-mA0SJ zOM2nPRB*I^C_8u7!x+K}w@sbFyZPVi}YCyUP-PK6+fY`h; z#hc{LO`Nt~F=D#g;E1z|Ntg5!%NW`?0{0UPey^PL_My+R6>eaf!IF=TzJ7^9GBbvc z+_(x&n0-W|Ytg!EunSQgaWc1wJpz>OeX|}QFm{2pH0x!b%XXN$CO>;T|L{VDCiwyP zwX5}aTBUy9_ucs#HQaeaR>Mpc+{KBv?dYwV-SO$93B6Ysf*Gdo ztDPvUuh(`J*W^!S8IwMgf9&oqRB8MvtAVIgC>UvT8!jmu9BZ`ick2^XljI|D>(B#- z^wD*@-{vnmSjj0U?({i;Dbj+(c##^~zSC?1!~fMFMF}Bl)*YE)D%6S^v1ZX`0O^$n zw+vR@#0Zfg;4ZHp6WgmpXvmW+M`&kj>$Ex35P38)HASgR82tJ9R8w9L#7Qn`QhHj? z2&q1QBuV<5sYhMu>@J$g!F@OQA!+PCmU5$3FM5UQYwW zF6Bq!AhVn{C?M~XGci2Ave5x?XYKs{PRF%=jKiXD(C6m*34^1<#GRzn}*Mvv`(4InOkS=kw@`oLa^`iaaiFXb{S$DJ?7O0HTmQ)Z{{4pqGSv zQ)BE!qr+3Bt3Zx-f{&HU;-Yuf^cQo&6a^JsA14+1jACUfg?zZARV{mp-Hgjs0e{!^ zP)@lJv!EtUzQM(XWQ;;9aeNozl>XMicoQbWe`UYcJP((;sEj9+*W+jdLCC+~Qfu)x z1n)TiswCZNy{U|un{Sh!X^}r|uC^~~e{E!3 zclnHVel+q_J~QMY;QR22$|)6hd|Ho3WBd!ACC@pCV22BAJ!V*6sIh4gPNHGKT4+EU zjnBEiZ)pMXkClMRlW4b_m)x7u($nj@LmXRnLl^c94CIj^7({_{ZrXbK_djfKqKjU( z8l~Y$F>RG=xOFOLlaOZp<0SsApF%zDe>RJP%hGsQrg^JZa53$pnVzGgqsL0Q05>j< zzhCna*SLl#hPiT>+KJj3g1+luJJtzt#>H1SlyG+764@c$W0fW1ez=K^>V7NY({i1@ zzq+x}i5>TWz!M;w`VSw>CQEhpEJZb$z9v~SgUvHykEG=~+TKz)`sTxEvz}-ZNSt8D z@&etanAm#kmb=8IyFUX0436?LDjP=|JELmR>yv`N1y#(}rz&8ajF8Y_pS4LWlF6}=5dwNJCgq3`UbVDj2;2}N9WlAo+ zK&)SqYgRT#1Y~WGi3=f&2pJ=c@cB0I-)pg{9$2w0xHR%P&Wpq9hYwCuag`?rzKhHu z{LTO`FaG!(jB;MWhkgt!fY`L(tJMfEnZ|D{{Wg2VZER5_M)LFuy2|*8h6Wi--Gy3Z z`#rs(mp*FPYGVi5Z`<>&d#cG678YI`H9b3%RsK5TU#0koc?}6Chx_)$X@6Iw?}VO7 zr8K=1DO!hz;E9&epl$9<{alOp4N%Ny1ed{ES1!U0UE{rPIrw$hQn16a?iT44Yvoxu z$-6LK)%#%TeM5r@fUs#A3U#NC^FlT^H@#p`NT~lB!RN{G@nFcD7h#Fs@e+qM=a#VJ zd^zR^b85V=$fC4>!7*TTD)|;Cwz;5O-R#MWmD^VsZJ%rQ1c7}&Y6b>b3k%k#6$Y#y z$}mi+@fq{NWg^atq9kCg*ak*bfCNE(;VpZ%?{!#k$0ms5@APUB2L~^Et(7S1rQj~j zC|PqH5-dKZ)@5qI=TByc9~4Aj5OW_LRGf-!a&*3@-XlsSilE^c>wY|FF@<70`A2zO zgiSMlz_}`gzcRV(JRQR%`3&dL%md|_lmd|iaQ>ycaA z7EAo&xp5_Rp$STBBcg7rvANFf&2vqeLIsGyr9n`4Z}!|42Ej;L3(eT_mrwT=`WzrYnGVYu1k35^O zizrL9O>C6!m*}sxE;N8jyA?KO0-E;2P?4$z4p)FDYL0m6`D}vzxXZecGjd) zcoz&~Z|9D%U#~XGV3?uTCT@|F@Ub^9+%&ldhcOY3im_V5(8046Xv{>kOX?7oj{$zU-`Qt>>BZbWb?n(Dy8Jz2@pi z3jZXd${C-tIsQ0v{RMK+OH6m)OQ6MwmrVEWWSRg~2VV+R`epF3O5d}$4*w9SI^Wx2 z|DbJ6=;uBzei{jP`9GFv7SAC%cs@ob`<+pZsByw zi%h~*mQUO#EkPvVHjf7RXTC_AVBZh*v4TA0viBUhGX_vjoYuKU_Q`K))M5x*jd(Sh z_7)UlCgsOiiTRY}h-?=w+^fV~OnyuHQ!|y7=fiBpv);!V2`?Y+-`R+F5)>G8YM$Gh zk!uJCWqoJ1ED>FC#vX(v4}wQmjt8_htroqPO>#Z{atrQd;Sh(GzL_7H8ox-oK*ecb7Fx`l+e`~y^ntxd{1y8b4*7Zz> zK(8z{JX_x}H?grxY@j!|FFy0_g%dWFA$gCLPFK|QPX21nUot}E{^RZo%g=nu^9Vte z{M7z(nz2yZUGwuasdiQyxm)!k7&praLn+dq;sarJTQyc(W@56$Hb^qf^g%Y>OCth_ z@s>a7nB@&pqLes;PqOavN>p_g>arKOQ3Qd^32JUDGCyHVey0@~@{XcR#RFko5Tco( z@dl+HVN>h8Jd>I$Tm``t_-=~$bFw6BLoWKkL4p$Z0#U~|S33i4@f{?Yf)L#qY;UI~g_`%8WUZz&$R zJR->Ls_BO!Zo~XwfkCopn4^z=+?Of8p$J5RJm~h-(S1~#DhhHA@U|y};tu#fm&LG9;6Pu7sQ9>)eD&H|_!Sj#>zc&zM{A29@ISZ3!N(gR^+l1SahYPpjUG z+iNu;XVa+pGC2!=IUn|PrR#5`34a8?4kw*aUJi0oI+n&`c!vioM^u5>HTHLQ{6fJi zCkozHS_*{RW3}xVIWwnp# z7#A=~-ljc>v9gh}@^IgxI)L?w9eI=$+hN3^=wA9(0>wmRFy_H_h$k&Nn^{4q`;;qm6@B{^8<`2vlFJs3Xy*ISWjgDihMBV9pg1 z61q=^MxeNqqorEW0~m8^t^Ndq|9%B)ZeBx=ZpvjX<%1>*ADKO_dK`0T^9Rv)7;gTM(e*1`G1EE(s(ml2MZXe zY)CTE5e!#dzs$eC>-KTnNhm!ooHzaIrQ~$p=T43a_JR-!EioM1M4*=Y4szo;(J~aQJ z168O%bN;JI78D4^n4%xd;xNsastm$op#9c7M-tX?p$eUj#uvGET{QaLzB;)q^gUsr z@M@h8+7|1tEg!&pF5OtL$HPzzK0H5M8h`A15%jS}ztUp4 zE|q-bab9T0b$Ng;E$k5!bnsFHAE$lW1@S#UquZ977?|)tps_dAuE!PXB_0ip$G+NI z7js^r)&9--IjXbwWo(uFyMxoVen|P45NuvRB$8*3NF?p{0A@lr1=ks%vY%e#8{}!BXCUgXVz*k3#mI z3VLn?QgBFVAf5Aeor^;8(dp(cNlQGw9rsd`FzTQr7CN(xLY4b$PD?DnunP-Yddn#R|MER&6^HC2pn!@A{GH5t&!YcS&>g0^A^eT=ML`|-agV>`T zBG!Wyb9!2@kN&cNYo>GN=ax8cjyrc=eb3HbHnaN8Y|vr(hXe;fwGxQLw9qB;I1(jr z?|b6#W%Ee$rw%k~gm;-z-@GYe{|)vth@`{fKW`6( zQ`sSj>Nt5^_D%LW7X^Hq^Dn*$$;m4d#n2^%M%DPxc%WLZEJG1NDGfkOd zDIAqBt-(iRR?H1;EZEZO>jka+z<#=fBy?7D$H(!U&ApU%BAl+Eb7}JW86IV)bxWakwacjcHd9MN&(JI@DbB#-d zOK6T+alF1gMRS?zVB9$1($G5bbGS_81bHo>KjQ@KM$Ag|z0KYcM#Cc(zPlKiWRcL) zezW4@Vm^k)ak#c?wSvM)i~O@n_hBCG#`_yhY?|AChsQ5R_{W0!`V_}6JQJnwzSDEZ z6bm`b$jz$j>)UX?fo>_BeaI#R#S7%(-Eg(ZWh0}a7RpyP3Y?-MBdPHPF|j_QgZN?K zBz9ghc$6uXdBru&My!flFMjAp98u_?WxoQUf*4}bodryq!a9(|-K{wxAcN#amsLhd zoBC8DIIfIR@dc|59glPBD3JnTRAhlsBR4Ov$e>Uvw(_4Kr|23^IOwuWN0pXpLJeJc zrWMr4So=3<@^+?9DreKA>ai;<@SE+qNU>bM_rjpCechuu{AE}{L|!tZ6e+N6@Kn3q zwHKrfncZZoe6DGhCmav$QkeMVq6|i_hx9Cc&IwT8{d;_jDrq3sbSz_}f+x9W3F=@@ zjR@LGP?}Eem!-#%mjF|f<+UoD;@|-L_d}B+ZIi~Y_I)l%mY!dsb9nJcM~A|ByFrk3 z>!}%MG0hH(`n4RLC&5+U&;6f{g~gOUZ10YXDz2<#bKsx}?WHb;JR>5{t?0e{a<_6d za1|EgY3DpFJfSAAIN(C)^NH8yalOR1Xdnqpc_Q-6$4jxx*$+|GERy7*Ni3m)`j1cv z;^@bb{67`|zrh9&2d0SILkoz{kpd z+Ojo_;Ja_vXXn<|j@47H;n{+cENxU?ak0FJ7nE%UFbZ6h2l%y<&>8E70_Dc>dz}Ec)b4-7z}!n^eJhHaZVLk3S24A z)7$;E$Ok|3M~f?M5>fWT>6MZS-j3Z~Dg~7B-6250T@P;qJMnX)O6OcgDg^{b#V6q# zRBM=bf_qy>XYK*KXcS*MC1jm*DIWX{PEh-S!WQ&eCv5~FRW#aZSU-Aav-#@0w&rR5 zqG+_0P*rFlzp!L99lA2Sly~(>J?DPfeLM&Q2JduD4T!pFxms*{Ty?v*^uy`KOZ)!?I#U)G~DZFy`D_}e$*_Ht)i|ZT;-aR+e#9>u%Icb{DGeY&u!E?prz*2bV zH|972aW>|a+UV@;UEbqt;543ABEsY2uj3_)tjX%@(~#+MQFd&V&f%0gq(3$1s|bW! z26cM(L)E^i=cI$L#BcY6gap!0v)DT%Zx%^TqkI=A{Mv$&I`~xL$T_GrAD#GOD<6#h$0i68L{j4r zYUnv$T~KkDW|~3RZB{g3GH;$-)JtNuO}HPegx4%J$rUtfky%f6+lHgivup?r0w>r? zj!U31IDBEpSFK;Xn4Dy9p36#B$W+8{82RP)^&zs}3KThxXV4#!BYGu7>7&x_fzU+4 zs_Xm!C+$6aegJHy>uuh(N6NqY2yNr!4}gS1=nCMW()=HDh%b-VbU&5yfx;#XBc_f? zyW@xf(Sv=(hYz~*8&;!vvR;6+P@F=tw7BbKWFQJ>0~`C=fIbToKXEN(sS|(}pn7pB znb#OU*5KL)-xC+{lb`P*#O`*HAnVoPlk)rk1*A66;KC`8tH)kYowBEQObPCI@D+w| zVzH5qYY!9LMF2E{mWE!FTS<_Tt&*}$E&*1P=gCb!mh^Ba8H*oIXzA5k$03Q%{+=tK z+YyUk_^^Ajl5GYQ$DZp18oh)m%I*ftXWIZFDk-UIkGK;tMja4pQvLGC0c4<*v#v|L z{B1A3KOg|{>Kzm%R2FZ*TeRFYn4X`HhC=h5dUb<~d=w3Q3{<>`z~}8PQf{%ww4zZ*euA5V8n87B{jO^ zYqO_gA1RqC1xbi>gb-5?x?JI}zeVBsc2R}1VT;u@oSc@H40%!5!N@N{0R_x&{@qv^ zvUy^ip~`Oba#Ki9SeR3?s=S=Vwgp`5LwFpM>GjlNRIv&~ydtp}SWb_-MLxb-Jt(Gs zeW`8fyoZ>M9Pl!zULG93B*#Ai`_swH_pn~?3_AMXFcUK4N4HFigF_azFh?GTsh1aZ zbD76d(My}J8N%-cF-8F=h&69`nDkEUAI>mu>IJw;*xK2_FO?##=KXjLBAZW zspCVdZ~GcZe!Ty@sUjI|(3Ipg0cat3duf>&dP zXvcs_-ui0{&#fhJLwK;RHpvuyfmybWY1EAmww{cTz z_5R8*w!Qz;?!xn1pJI!Tvhz6Tmt#0l^1`O^FTWZ*tC81xJmJ-A7d(zq%@CCmZzySK zpop1fyk*-0;-R4PxL9Y{?6I&v{1DxG4&`_xJ$+^4dAGz1O+p*>!ok>r9}85Uj`4U5 zn+h6-mUe%DTkV7!DHw^7+AQqsROd0?BMJt=C_*s&O*^ei2(1e{yFmcBK32%YKU`J<0Td~U+&QF?@hBozl_aRH}A0b>a&IK|M%!E!X# zMf4<3j0}#)v(L3X|C&o0eBq0qT##FVKe*N4e$s|+S8H?0ssCU z?f%^kFxE(o?=8rEv@0H9wK6qpnP1neg|1hWNCgpw9-vst^va%$*Dr7|_BeZbXtfTy zAN(ARv?GSZh=f7xHAru8$QkxiFUjsfsK@wXkO4wH4y#DCAgG3Xd8@CmcSy;cMK&?k z0J%y|#$Az(#wo%t;ANcUT(AR$YAmwH=y#ye^?-$@OY0xv*=qa71@F+mnt71h&rA_9UBWw5^W#y z{=P*1=7}W;rv7N`pm^Km^z#c@dE*>LwmngqEj+SJ>@VC{O|NF+wu@+2nUD2t=T9Zf zvA5>rx~g{;8dnk8WaGpW1)j}*XCBx`YP99@b#85RK5R+r__msjUmNVGuqMAM4@?R| z#>lQ=j-jFFeo2T)==RQ6t85dv=mbzuBc8p{Dux1V&=6$bMI64h0dq=m_-e)5i9WfG z(sJg2{U*2ee;*vgkGk)8178nXwNlTXrP}~)1cT(j%<<+^GD`T6Uwin6FD)%ixrcLY z9R#@EznD!Daxj3ExqSnO!8AKxU;1WGD~J4te|BWt+}t=KOYh9Fj!0hxr|gbDC;Jr3 z>ChlwDpf^yy`^$jDbseC5BTSYm1zrUH;?NMS%X`{-D1OSS(F4iE1;^ib7|ZeW+l^9 zkS?PjhGJul5U?>(QHe4o*EJL-2oDX#7Zem+_5T1u3H`nLNFAy|nZo1cPv@E@Mk;jZ z@YilxsjruCUs)j))B1%#Awhq;5&A3b3)QAgxV_?@t#rcC%;FkNi}k48wirS0Xs#G%?W0o)~WzjEs)9+%T74 zQ531XPNl$9<=`0Qac^sFO_N#|KqiZjpMDC<_tS@9|HgI~Y4$?}4FNjtr_J9HkAX$o zY33b5wo$nN5Ngd+`2V?m%3cJ%S)zErkEIgk)|ErhDn3J>fgTFzoM;#g=SmCrpE)zffVN+ zR9cI1lP)Q)OdK>e33xD)%n$=|Y%O`utNThYUR$H8&drFXZ_T-aB5uuzj&B3BSy zA>*C*Ew&$=A}Td|WouRZ0N}WO{(3-1I+6MpwzI~mq@{%l&Uzs6K6#kfGJ}WfmLB=z z!n^K{8U&(GOt$@Iplj~Oo3(}xlLKIpw4JfXiC5lzIEy=Iqn{Bp|6}S ztYQ|gP_N#4-oHBi4l3X2R4fK5SyW?4+pleWk)cYC3C9k0CQXg3LUy)1@nkZG2|c5u z8socHZJO5B*2od5auejQQpQXAW%EKX=nP4}nOG%5_QJS;x)aq}=a}!?B7=uVpv-um zrUl?ja%Gt)6oG{Sx40MEmQw< zS5SD$sjCxMmjE~*;;g_%T@Ini+tiNW;|Ay#r0MfbfyDSxaG9B zC%wHO&MiNJ_^!_a{lc|_yQvOe-BLueDOqK$^6(!W*2xp_&=j3AJ3Bk)Nq3zg8LE}r z5S&Y-O8WUsJ)d7cw4HLkMQ_If^qfRR z)oE8aiZ|TiQz_K%dlF^gFFhltdl@ zt*`B{k=AJ0xGNGgFVvsJEn{qK-2F0%*H|^-p%3D}&Sc5=r0Ax5z7Icm-b@;k6Eoz< zR1#a0yEfLXJmwCh#kLYd3$&bhmhh=?1k-I&?!frs;r%lhnTN9XMHql!%Qx`?qJG&I zCzjvKbU;uS$_tjmS=`%1rBvS}_P#I^RQ@)9u=pl@r~`%qp2I<;JPi1_b%<5`!*bG# z1eGa$4_o=akBtSrn0;?ypP-f@`U?9gFHwK_;?7Gw>8oOUdO8jR5CW9~tFFI6t^^X9 zI}n>BjN*tNjL7W$(zQHLNc){!xx0?88Wt0)b(j+yv{tP&K>7bYjdUl(5w@R>)s=Ya z+6u0~cq^Jk{g!nmz!)5FItHZgWGefW=t3ANZX$>T;2GPJMH#}*px?7C}E>~HH!yz3s^F*WrRz%v88*P{H) z6Iu38;F}G;+`@h@uQZ>3PjF83Af4(!I>zKARke1oQoB0ShmpLO`PFBxJ-Nzh$YcC4 zJL{Ta&KuOk@zTR{GX%;>%F}bh(Qo}(TE)3Sf6i%>q}5G83?iR>aIlg434uBALnjkg z#JVjyVy~eId0PUrK@B;r#Dyg65^u}SMW`mCGke*y;5V4;QggtcKK@SKN+H$zH%^sLc#XkJ^XMYuN=iQ|l zJYg6q;7a1s&pRQ$4l)S8u~NvO#@9qgvu1M(;~hrdVa zAWy!O2CH6`Z}++`wI$#Lo@7TH(DB4Cq zgQBTP40{vbD85j_Oe%j#ID42qd-rZ@71a5kMAJ*Dsa=CO7uNC`n4EnwZ+XyN#u#j| z0){C9nXXt{TemI6JdB3j3lE@>S6kk%Q=wW}kTMD=Eljr2V>2HJLzfRru)h)R+EG|H zk37%E69h_6(k23YPltcHj3!wN6oybK@>&Zn!P5p53TbFq*ut*Y$kbG*MSs#l{I;gi zX@RG<26$Uz2UK993hG}bUu!M&nmsBk>k}=$wlrcfFsO|@hnfIv6?!$Mcv!q{Q0@Uy zM+(pzjU8y0-|+HII?1?U<| z`5iD03HZ z!GD@Y`%R|_@%hmHK!1@*GV|?ECpV!1+^KjQC{+_IC2krn&-BL5>$`TlcMD<*CyQ;g z@=-ItlMikre?HhAaN{>$D<55&IUddaE+XfSKK++j!{}MfaNlO3v8_>Ils$X+Nqwr) zEjRS`5#5$`*<~qGmoWhBy|RWC2wg|n<4JV;l?_5ip$Do(=ObXhMNx1w{N1J~J&xDb zC&}bPdh{I=L}A-6Pn+>T`N*UZkbW)D#k$ zi=l(Q9F`(2oyBzpx}DO(Rl?(z{JL>IX9rOm1e~!V-;5vsoapFZ8R%XQ%}!1tOXc>? zX4=dPvaG)<&XuQ{ScneKf$sSCyTqsWB>WRuKZuTMQ`ulUIa26ieaifMajoZg_s<{H zl~lLr$Yz{ZSg9!2%~%hW?+2$8Mhh@u+>hb9BVxfjkOB zfWpPS;tmR>Xvw>A>>EDnoFSK!S}Z?|rsenNo08-GIiBCY9*Z9P%BC*wiJKKfFO#x$ z){Gu|UbhBjgrTG(uAjRgb13rZh?d@nz_m>c~bb$(^-Jg&cD(*nsz zl_Fr7dgG8aVg%0HqqnhHHM%LXZh<%)ojHpsRi(u#$S2wWXF(DqehD0OMpvB568;-fF4lmEm`xB zBC?ve+N5q_V~rl(@`D8^jp^h1<1cACZ^V@~S?IWO7v(bW8}tVAWj|REGvEk;DmX_M zqY~~zj%`YuQdJ;PX7ZIReu!sq*rh1oCQ_n}#Y6A@`_-E|I)r9Cg@yLu{(FJFTIOlq z3YlPc1?t(RKtGumL)VUi1fG!1wmjqbF4M@s>JYTT!&4F@P;41t+sfe1lF%8t()d0i z--3f(uV<{I#r)@YStZNg=2=eH1jv;r*HT+sr(ske3&*pg8{X04Ez-n4jXOYxqp%0r z5O7?vaZefEM(m0V>cOPF%8@oLL8ZfMdHjN_=(OnUzo!Wyg2yoLphT(5+h_3~z@iuI zet&r9kGa)xoFmPFWaYMM;0n7Wx3Vn(Y;_sndnVTKPqkHR1UdOze7=n8AsR z?Z3wd(PW=0RQRifN%0CT#Mm`$C}sagb5PDUy|gMR>;sA=csf@<<3^5;pi-fQ1p8|n zO1b~{6bulfSC5P0C+`%dv~;fu2gNFToDHSI{~iYhMjuj_VUDE;jv3{2Yd``U2LHh| zfxYoxn~vbsy^ogF?b~i0YX=}NA?Gs$TnlAWfk7@TI6x_qG^nixRW7*INr4f=H7X}p zu`+o_(a8l7w3`46xHRJQg8_kFA~r?>X|x$TvEd|yGXRE2@TqVCVx>SSp#6CrIo~at z)N7qwE{&l7NH3Fc3C+gX831SkMeuJOb&TB=w3)|_%+9XD&}dmX_QBshkfPKYj7C_x zX5;1M1)Y|WDIj6Tg<(>V+uN~dH3eNdGb&)kgkEoXV~{EsuS96QL^5w~z?bl7T0QnD zt^aW;5=5EAc|l~~dDj|2Ab8V%tmVOjpKZ)xua@^m4cM~BnLyp`FhsA82Uy6NpSP>@ z{oCoz8S?%s^?w-YZlZ%0Kp~r6hvf=NI{H^Cp80>NQGq9Nk1^;3nKYOSM#vmDNMYUl zAUYQr8ynj!9b-Zvb^o@TcM}h0AcR)rh(Q4y3vgd-uPXU|3XA~|Kmbs9Uv~g~BESd$ z(0;sjPc-f7N13@Fgr|hyjJyQ%4IT72dza(BD2y`DCJTyS%)#1?xyqj^z*J-hJ-LtA zzlT@;T^g9=pgK(DDV4E2KHPqy>U`-_rL^7s4x-w~d?#BH|ve$XHT z-wmTXWw~e5XYAHq*d?X003cYjJSMX@==3x&ca5Ej_DF zeaN7aZZ)CXJ-8u(;ZmGU1lX16iQp@=F+$ILDsZo^ zE#e(6xeU3C^(lVDOz0NlY4*3i^^@44m=Ci0~@3E`Xu5h-{<${UpqeD(&*mHc_p6 zR-N-L*0|sbBgS;`^sjy2i*MB?SHrjh;diMn**R%V;=|O+1MU?*y*oOM&;H z!XzKKnb_0I*SC_ib;bT70tvvRcR>6ToU7tp?qUS-O-2950(jA`1m=YTal*WIP~QQ5 z85y|goy}t+@d*hjWX!yQsU%l{5!xiFC{$*ZZ$!u#{Ezw2NYfFe<=3q%r)Gb^jWqO^Oll$O3uyWvHa( z2IU4K8l4BEadXDM=GxK~+JKBgSU9zsEH+h#Spb~l`}J|P5pwkRRZU=U58DU5 zVIpHv=h^|G?!eLb=+Sa4idla0HQWnf`wwDnfTYwJ3oPvw(!uK|ewQ;^KW!cClz zPM99LF1_U2kcv`F71lx`@nFy9%CD~cm3>EAu^tUA72Tzkj$wPH*ZHuDoS`G-f5B2+iO7r%91k*|IAgM^*U}!@nFOzJ!pPg)jGQD>*o)R@ zkH5UpKZapMC`~{+qph9i{cpk-BM?Ao6JCXn!3CV8u@Pa`oOd!^Lbj8lBTnc9tzw`k zK@F*_ABT!cgiAT>{gD#u=wZG0Ap_P2c)I3HZl0KBxGp`>cxf-&;1}StfT3@+P_}(G z9KH_U=kq5BtAy4sK$+AD2?`Fk}?hw;fYU#rxfu7NUzg(>d~9iTs&Qq8I7pAW z4!vDETwM@`w4T(IXEikFcS<)lh>OswmKrGW;_;jDfBJLw{OI&_&{P9VXeH$ z2+W(6PrFUIy;-WvMPOL;`1Uyvgh&0e(=#)s!>Rm$o`epRh=o(e+>vq3T%GJTMMGR))7&5=H^%1F1~rXyvD=ADDZ&%u&8FE z!g41Qn!4EaqN{c}<@J|>tor1C{Mx!&Xb|7*Kv`N$(fMecs@K7S2elwWFxdyH2 zr0(VCbve+uX4Nh0I*#3SX>4pZ?0PUeAxwWY9#zxUcK12~O>{(K=ju~g+3Oh54`^R` zbn~0y>aPTColWhZY396N;J6cqUu=(Xl%#S^+a?0%|^y*F7wRSnA)gdH`6|_JW>?Nh8 z-L9jeAw4}Z5#Pa}#2t$&RO$zG@Yfa_9uM+^!s=krbu_ECR!37%zJ`k`!uC}M3;<9M z!-jg#Pb+9O^wFMk15V*VMF$a<}QkDz$^;f6+DL;?mI z!6*yC2z(<(xNac=SQ8UC(P2Jt6+(GMijNdA;OLIH1wJMiQx1V0Smr=J7`;x3Ue-!1 z9&M;N2u?z!Bs!15(|zS*;FX_z8`;_SG4&zdcMr+lweO!2r(A2Pk6sh{w$wrm72-sE z2VkEC9OmCZ{b!4myeQ(IR8NqnCT?$UFI)tPH^ES2_Roi)?RtI@yv!}`(yUdLly&b# z8mftwrL9wPKUa2KW}()Dh_>_H`S~Hq?+1E#;|I>aH~;;8c2k~k#?af4RIuMc$=4I7o=qQDq|55gkU^J5);X~{J1BP zY=gEh4#DlgYb(Q(@BOV?w{ptMZ$bB6XPtcXP)f9!PnlK50ET5CBuwG_hK*y{#M?r- zO3{j4y6aBNq_#>DaVc(=4OM*N!Q< zhl58PdbKtwS3tUvr2fs)5BGc9W63%}znoNls1VF@&~wXl2fooX(`$S7FZ=mgKv#g& z=Fhuoo6?GkwhHbR^N6$ijW?h%$&~$$@IY2gL0QG|>%m$tNRT5+z$^o^MT8n!(5530 zMot{=ul&=40#fcC&Tp;ut=vA6@^MOND`Jv_yg^w92lmw8g(Ed^@avFuT*CrDj7+|! zg2V*~M56(BnX#{vkV?h{hf~@Z_DBbjRXewX0jkC1146BJ9E}Y*L^8gz>RcJKYTE<=u#n-duJlr?~)l7=J z0lzCd?!f}@a7&Z7%5pe0uij`LJGm>p0DlRSum;^irY|hPCS%~816X=6`rZ?NMvIAh zu0Ko9{+-VPuTh`<0!k?`_`);>b$2;0b$H&aFHy1Oc>~wOWJOU&!peU5(`}_N|ZY9xW*W>DsWDKfJ zzRFx?vg8ZqUpOl!nw^WSPUSD%!E(x0E*yWB<(&M8?H|UFt7D%{YU38G`dOy}+u!e| zm|(_V2T=iR|12hI!D}dN6b5OYRBLsTO2_5abaeEVxAGkkmvuQAj>xqNvtEL1;i7!i z9pPW_?d*i7Ck9Wz<0!c@l4{z_{RJ2WFj758q&*6NKT`c3j!U#`%{91M^@vbXQ%_F0 ziW8#J$%-0aJcAVnuk8X{#7^Mh)p`1~quZIL)?u)O8>Rp%UU6YwCI34xS+)3j_Us<- zNR}aCC8e+Gh2eAf0-rD^HPRS0dEm=N(GGk40jDOuJ=wBt=;{KD3NNU0SkS4c{{gII zSYWb5chId^vKNrXhpLH=x5H@t{X|Bsz9}g@Vd;mu!>ZFd+A}KXG9~a2#)5OabVO9T z+u!)A)vnLdV@s8aEIDf(oorr>1YX0XRh2Jk>6G4^ z$uRD(AJCGSY8*EYypWTug)-+_X?_DTLNo%4<|`0bni?65T$%-omaN;_uE%6h)6628 zeJeZnD9#2=ip6oumb%vUUEQV@fxPmr+O}HzkPY2E%Avaeaq0d3+>QCa>So07JLd2r zK7U<_`!Qoj)^QYc?sGQTsXQJlc}begD+xR19PX@|pVfEc8q-xsbipGDg+GumSRgun zk@-gP4+cJRvm{k`kCPYF5HHzsGQ)H$@8yJjV;Qo+w4N?r*znc87WsvY=iOFN*+mU=`!0Bi9h>f4~ z2?-TYQq+?}q1F6$ixnMnNL*o1SYyD&+*Hme^y}JT@!KxSd&P@vsNKorb>}wUpICWW z>pKM3Vay2fOdE1Y)X>pEC4awv(ci{ceKYQgV7a5;l4}hpjxVhi2yqtf^uHHC>{9CZhwa?1JLbCff*BvRNmXv?g zIl!9*W74Fb=fp;2W9Uw(uwhxjAeSLvO*hUYc*q}{FGfRS9zV%{u|5;fr4L|`)1CPx z{ms_^_OsiY6|TnAg5T-E;Ul)e^ew5>4MtP9BTQ)K+hcj3-fj1H=AZSU0sL*+qk(pI z@>mKXREq4E=5Z)Oqe(JtqlUDlwZVtxKj6dNy~eaiFcc#&9!3esq(Y!N6%`f9B)R;~ ze+C`Zv_$Mf(!8MUP%|`S|MwnclkHa65Zk|=YeRQ4$*1#P>__b|${`onO)=L`P2wD{ zcr@`N>3P*K?{aM8Mf`nc78VVs&}?g=FwAvu1|ykVuBxRO ze~YIQ&xYb`_uQ#TUOiD zLkHXG{AjyG{P)rJB>ySp0jAje)lG=TDNJPwJRD#Q)t4>>3kN#cB60UHmF(?nK1leH z`gISJJl??bFwltAj%WB)xaqAi6bES<&vs}T03_u}nR9Y@56j3ZvHeHH&ircaw~Go3 z$2WKsk|wvcn%Cy%L9f45BCY@{Y7{bB$vtM`VJHGx#P$LPI=80>C9?*mOmK^*F(wn#M=Fv zc*p3m(|^^TU|hOrwe;`gXfemk?fz4VdxSTlpKfxkyo`{yH#MUs4iVZ2Gh=KDjkEto zlQuZ_t@S{ss=Rt`-oH9cOTZ%%!FVtqx+c_49%)9vcx}ieyq)H97u}fX#G?P{MaZJ$ zsN1O0sWtsoA2DsMIbP8}1>jZU_+)u``)~u?@6cS&ObfQ-T8%2$(heQ%?d|!xs(9RZ zz`I`fj!xNNnDaDxOr-=+VpO+=_Ou4=hMVxDTSc^9SoS(QgmQo{#^hg=gsJ|t1n+P~ z8aWT1S>fz7+YIn4u1m}Iqq>zfU@AdTYs#X9Yc-T?@|BsEmEGRjy00(@A0NN=aOYsA zW9WSU^x`&th-?==1`uYThy*-Yw(-J<3#$?7S4*2GK#tLqTne4gH>-{Rvg ze%k&m8TPL0za!>OgSt#9dNfK1ta=N~9%ZO3x(u>E3Ob)LaAg15h`z}CYzA#l*j;QW zDZ$nS{O?Qsiu2&B>S=3h1HAHLq$ds@r8LzSf2YkjySla~m_jvW|9-mPy%zoSF6(5p zC2tXCqXY+zt9jvE%=Nzj-GJY{0bO-%fA*%@Fpe=_cXkGB5e5hZUTKp~x#F{#J0k>a z&ss&c2Ft;griLiz&aj#`se^<8q6GF?8+q;3`hlbh*T9p48!Qw{dUbVlOg9D+q(i5H+lSHFLbSEDmG&JOJB!?Vo+yJF zTkR2TE7_c&l-|!^NBM{x5-v=G=s3|t5O5*+r{Qcf&2=*f6V{76g1cwC3fb2#+P16U z(=N7JGq&>B)(#9X8aa_%4!Q8_0F&`=X@TO*kNL&4#0r%q?V!LIi;RGyoVy$LHmq*i zCLx`Hp8uBrHMxCf`;z-iyPn-_{C4r@zXTxl%DsqG2$+yoNVXR?==dW7Hhc!`ytdj%0-{uQVgaf5vj&fX%vk#F6@S@r&A#WzJ!#O zRen~|;;Pe1;B{IqdeLkqge^CulS{V77`g8?mSwo_y)7L0s%)uGcDm?#3#Q`)55ok% zJd4*n>&j6zE+-14qKWqJu~&GH^M5u}kFoT$m#YOgx!DP1IG zD}C%;aP082=~5b%AF5o!*||(FBVq51=Wlhs5)qMH1lx$tCs>6o$QEwSqEVf+)TyBa z&*T0kG4D)4M_Q1;m=*K_=iCW85_{{K+8os@-vi?wrT9Yy=8F4vvE=;&pZc?X^8e;D>D59PDZ4 z1Pu&Yv_}Ez4~0auQtL{%h{tDVt%S?}nccleZg-Q9S)Yb}sN(B$xI)g9H zAv}6~?1yE|R@b*iGIqop*zYZTXo9{LX8VJ05F;0BuK%9L_b$xt_V-{7@$!db=8OctN&CI_6x4rU}uLv#aFVVbP48l{!|3{ysj zZtG9d&VfFfUQ$s`V65mMe3tHYWsQ$vk^!!MBL5u~u}lQ`(#T*E>xqqUhX>-^g>TbR zb^I73tUuMcwG}Hb_24$%(Xok_^$qC29rId#GMW+~M;AE-i;4VkLpnI_5BPp)?Z()a z1@9lT&TXV6XE0L*jP1QkaL``eYs|tr{c7|fmR>&VF5z|fq50q$onVncP>qy zzTA1nprfmAp-;v*D2tai^Lm<%Kc}gQ8k0;71oz6}83uWonVE@in8cG*Z0=5c>K^Y- zVVVKD39u`WWFnCO0U73aHMnk3nGU}juBNA&AKa1JzA0IPi6DnsPhkWqiB10%3WY+O zVHrPnE3+7fLUW;Zc+KI^?X49kL}CCNC@O+AUWNS}53JrOO!;L~*+)lDyhKpcqafM( z?+Zbx5#vg9%WvgM@SAHC`i~}Tv!T=HJQcvV*Jz1beE{S5>eulcNO{vlDYXN+10`Fy zfgB{LL9()OMhWTbH61k`nGCHr!D3Y!gc!C2KZ~@B)pT?Oiu9n#Hku%E9qZHX(mO_i zzswgq9s4OW8yzlKA47=lR*|w2-dH&eT+TOj7o83=jyfX~OtqPA{Wp5?7o3P+baUmjTC!j;zyKE8tVs+JdQo0IvTi~G5sLqOW{ZN3H<=<-5y=k19+<_Cq2 z1(n4?DV3P&CTOa_LLd6E#(#gG0e7g%Uqnju&O(23DHh5^U#4}RNds{N){PiLsS>@) z4z-zA_dZQXRI@8$Y>^!n1mNY_+1Z!(eU~rBmX@Bs?LKT~XXo3!{R9XxkME12;3*9_ z^ja|W^N-Mn#se|5l_Dn!tEc_uE*-Wen_Oc0i3jJq z%TWFvhxrLc-_)g9)2$$=J9lG@N-Z21XQqpS=1dK@5!S&Uf#}u`cIEiy z%UbP-7r*ine_LEEmYMWf2A6ap`q^UzT>{CD+1Z~LG%k0lXa-fH+Vo9xQf3doc^_5uuv;I=Oq5ZM@)`LY zriNNZ*64W*du8>5)%c1~***UWK?(haXYabCb0#DnpHDHMBNTA=zLsS(VcTWZ{#w*y z_z;xZd=UO{@F!_bkca6Ue;-J(uRm@<=J0!a4F9rL$~5GC(SRN+J80DSDKXK}acm=E zrhK)p-e|SwIP)DjI2+|zR2<%fPU*-+6`K|pPms~B_i(qwbMsc~tV)XDz}a18MXBn_ zdkr5x(C0+!9TFcpa6ZXQk@9XaqB)?gB!Q#=nY+L@=o3ka6S9qZ(+<1W+;kw6uKchr z|GvVzWeMGLjTcs^I4agW#N$?fMmI&iONQPG+&WY5b`j113xz~e(o~UcV)dxrI9*?ug-$b|^AhJcb=cSmE|&fpo?mDW>CG?RNE)=@sz^1t zqby;acvUE4ggYwF;fV!Vae|}rbcAX5L>cR3vfZc-T?@sTsRcu8SaxpanyFDzN+Gh3 zovp~ye3H?>q;jld$V%~9aQ94yQp84I9qBFmgp{vMN`t8UU z9k~%5UR;A$m%>gL=+vc?QiaBKrx6&5<`Du8LJ`j?N5To3c^7Kp#iP&{t0c z&(~EVlDL*|?}n*q+B)knMbyR*8=h|6dgqM%1uOXHSNA#<7>;-3v2OBkUgg$t-&L6E zG)*(*=~%NzG7=RPp#=CjuEo;Rr6@^|bWhQ$fu9U*)ODlsx`Ik6^{c(kg?bR6WT6l3 zYhZM;dx);mkt(wC{<)09=KOywfII2o3u{P%ROp6P9(c6C5<$8JYGBZ*W=ZT^1)a$o za6$mfmmPO!8sI)BOdBx9Ge-5uvg~dR5^Ryt{4!jMIk|;B4`_Xph$ea%RJF?4HG z7Fu1uU;Hb;w}bV=?fu&?FRcjlAPDteR#jE0Q|o1J-42zKF@2tvL(pHU+bpIkSg>-4mujh(rze6&9t2xi_!>dOILAX~r$jKx)S~ zT3J*C><(B?Y*vyO8!d}~117ZjBUm7=2}lK?ico12jB)Z{`i6NVF)@+_4l6w3wQyG3 zVA=On(NR&o=124{;mG+YO6=BOXIw6`^){>bxJtj)d?w5KS$OU1;M~ptiBoKKSpnmN@g6v704k<>uyo&;y9;dh(UT zGMnda9Dr-J<70u?RF0l#hL$#19B?3Ue5|4(Q%H{vL58pyVh|!|;bZe-F@-@^)tk=D z&O}p~8)f0m#ZgFg66n1}@>%MI!)`)bO|_hDkb;JW#%8F3(2lN-@PDra8yYnx^VE-N zu=r629~-qRK)OS-=>a|-Sy{2NHFXVHtHy;ws>xoF;$^HIU%$f9C+@%R@Z^#eF8&Uv zegQjs0Ty;h_DGCs1Nye)_8j<}1VW_{ZpK$fAcMOhGHM{4X)y=$4pUg7nf`c3XvHbF zcyLPn`LbEJKzmB?F;isZdSJ5S;76m%9&O%o__DQe9k7@jL}|mVl9iops)d>!TD0IT zhn-!m>BBhrZ!st9e6ig;@t8n^gqB(}c2Bmt&%SpeWF}dfruA42SsfVFSDh#hycRwF zlol0LWk>}{WX0PIyDOjXrjnJj8e!|E12C_Q<=7C*La%=84v=M9AtG|C= z&>TmhnZ6a$a3{DU@0gBLWLH`j=?0rn9C`U-VX;cE+Ea7tC&HdLWbI+E^Gtw%ds(CT zosJkT&~5|2Q8ZiMyYO1Lj3eR5XscnQiV}iq!Pj3%-RC}Oab)ooEn^{(aNsYY+GXrb zXdF#uXJk(c8&w{u0!<*(|1G&2$xpo*P%ybP&O`&s2;2sEH%MG4Vrf?aWWb zlr038lET=SxW+EYCLd2og(I#Wucaz)St9-A zzLt&-VkQFa+9@uCKbtxUw~$b>LN*w8)9ExVMjCSo?Q{wMFBkxZS_owkRQ{x>puiSo z3*{z2CJL8qhtUEIRDd%=iyR9ovdo$&;IvWxj&-*cCOeXfj1+iF&uM2ie#@Elh88Bh z5UgwBS`((_oS)(Rt*U^_OU(ewBgol+;0HAgjaN`2OA#xF0(WiASc$!_j}Q3xs2dqY zg6^f0w~H&>ft_Zo<@#|Y2eSSpKu6F%(R8RNR$VI%g7E@X2|Msxz%5t|kW6k(L!i}6 zhaA1>FJM2@fe8R7iFvdQ%oqGLYaUGwHYT;1&Y4@|)6+ojV61*8dvMEV?F?|^@rM|JJM2>otXE@G6K2c+m+u)baa2k;H}}EPaHp=NA&X5p2SRKRGtZL$s^6Lh+lsZG${dU$v*wtoO&o@;@>5 zIjFo6fNm|_!$?{kc2dg3wAJJ;^hB2~CxzdfZC?#fe_<%kk)q%hVR?or7Vl$?!Rfk&_YrH!(vf9G{N$dF zVljKlHHX#8pZUyb+uiw}MK#2T(i zG^oQ@zz9U;;X$f+%Whc{7j$!86X-$7p4jc+i!^vkw26Z)_D(fiv3~0h?zTh6cG3+( z8s{fF@J7-fy|&8qW|&sHf`w5l0&ApRYIjwK1iMntei6+TBd2HkRNltqnq%7^fm-{y z*qOB^ke)5N&l=k7Ka-D*mZSd$j{++K1rYb>Kco5Cqh`0=pWf_;b& z#(fNV;>#LQ#TjAfgtqm$PG0RfI+TFM62YKOG$LMH!|TgX&##9{#3dw^IGEUR!QG_@7G1XY4UD`l_UbV5 zd7IuUws(K?TV)u6l@4+pOZv0}ex~T`HMRUZys^1_sx=}6gY^8J$fM0PN0gKT@iuI5 z`_(LQn%M?_&5gbY{{H=W=kgKILTxb2KrvAHF<>}~l36eYuC&F!9Qe|Q`zA0ny6EM7 zmV&h%4f(IIo@-Y1d$yFNHh=kvkL!J0o|Tb1ii(jin0od8A(-j2`$-U_L1JO9Mub2V${S?PDzE_G@N^b{iR)vNj&#}C=Hs%s)f4tvpRv^jQ_L~P{+~FpC(Rpa|Fea*Z?d64rzvEl} zm4qZC@wLSs^cspYlK@M|W&H*j2QpdsFWkTbu@;G#YYA&9=2{jK#UDqk86#lth3+3Y zy_Ng#NhjB@w6-(qp-j=o$0Zi)ReMyRIVVILCN0_@=jSj0?mZJk3Fj2EB@ z|Md^18xE!8S3WcmywqnjZ@2_UCm->jabc{qNvHrZTmvzz7k4a^4L z;w%s~_lQDQh~NK`ns2Fu-Ux>0z+B9Dl^9tdAVrwkcktF^6`5rPpo;*vEky6yFSp)# zb#LWl!BH^XOv2Vg=KDbxvFZx6RiQ==N01f^X9SmbkW1I-*OaDepoPAq(Wl=jy=)sn zEiElJqikT5GWzeg>f~(#ON7_MQ>Lf{W(G--O64EzDNi5XipT9)6gMl+XCH2+?N%S^ z_50TQV$x`~xrblpV>(rFK~b1sS<}djBj{!yB3+01ZRDXz?~SdXPSWWY2L>qAUGk$C zeJ`j~a$A~9D0JmxHCjp$M9bvcR|a0rtCg<)Y8?=pTpbh{-BO;BQs+yK`|I^&WrS9d z5PRs0C8d#orDP~i6u8;%)(g|DMYZEP&gg-QAcNqc#uo#h%i5-Yz131qiz16VZysD- z41a7_qQ@q{6aPyz5<4N42!0ycYbdMq&dabp zOyS`0W-c7{Fmaisgvt!Mj`Bo3_B|<~Q=hDcVk(SA zJnSj8(BYcC-T7fq`!O`*QT)Tr&8~F(5t0FhI%u`sxjR4bp1zma+E$rt$Pp?<=6E?aA8_vPc+#fs{)unNTo9F492%PT?{+B>&ZU!_W1YVs8u;c z)~-NPumjZpc>DB6Ph2l>m(|P{4 zEfLk5qRjrO$^sWE#t|iLHqW2;WaQm3f7?$;e&>%HR6!5-b5mw9V`?<_)^wt?wgZQp z>1_Rc(3%jY5907PDM9+?kkL=DSn4}VgQEBwi7dXDx~igrIqrTbBBnt@viTqP*l)7) z>9i(g-e)aLY9T8gkv1wPKc8{S zQ6*EvCV8KI&}GS7IW`wvs@xIt8@EZyOdSj-67;Ir@)LAx$#XM73o^HuN45k@Xm070 z*g9RNYP^f<=Z8Hw_`zIO^XZEHq5qg{r{|mH3z))Qa>#zA{`$HzcIV zcRYWt_c!-?dU#MF)=RCkS{Ylp$KPgbd1hNGoX}O_zoVAf)Jrs(LRbg2WD2-7#NF_9 z5p>!XL~Owb%~YJg(+uHs;Pr`^&@UkKa9daDQh6_iFRebYQ;6I53LRpvX)?LVOzkeW9shVvDq>T9&Ady zW%INPiRiJO>byH_a6_&NA7no5vK`s(n&9XMX(Pg3S?F|39|%Pqju+{NCC} zP47=kOf)~}9|}eUfHxBNQEGsD|GGez`J26zStN2Mt0U;UqQ0SF#3R?uT+!S!BZ=pA zkM{(z*h=MuV8R_r<@n_A3nF#5 z3>DhI@&!L{yRvaCK~P6o89%**mz0$Pf0MKe1l)Y_xxK=R&O(kQjm++aLRe~4?8DT> zRaHdzfx%id;v`OArfx1&ULJqCqz9{Tn@;RuGGu=j>?n7Ld!4ichl9%vUMiZ0Re1COO zzF=^Vr^__>a8w?4HxeCjSo`aA!qNpsq|NacXQw_bAU%=D&dP)zkO*@2w0h=TPEZYgaMRv=9QDnOHJ`sc;bk!%Pmv z)U>^zY{5dHGOF=PhaRVaA;~;a)1lr;jD0BmeQNpAKvlSYwI!vG?N5FzDF2|lrWJAm z*#?8F#)28PidCW8B|k~Y8qpfm1qEM3D8KuT*21Hgy=&ZE1GVKYmi`mHaM;kZyX;Ju z-#8H)@Mm$y9&|a9Y^;+7(6OAz%!h8R-UOaMTQ%KD_e2M#NP_0#)oC3!4%!UjNGkr& zTmiv4U=LG!*dc*-g58M?K7NpG7HPG?Te8HYBsjj8|3K%AhS0ciR~PHNk*E!S|;AXVm?}hjUX?@dD$^-{=a<%T+Hjrf1~$ zy1RvvHu=74NqVD7h)=NDb zMzrf$?R=VYWJe~E*_H8-162XrYA&`o!9r$ws36KU^+Md!jjNX*5r;q{iFzk)S`TP~ zV^1Az-Bqov!e-8_q1`G3=TRk~Nrxwy@kxm}gVRCR8ce1te^SmC4HTjEpp$6&b}kGQ zjF{yd3H!ks~8ibHsc^){~8hnltOS@l{S;>n} z-#K%=#18G}E4}i*2^(5LiPGOI&=K;M`k3{NRg{Uoeu_yNL9v0qc@K2761Q!esla_C z*!!K%F*EPXPztYWhz5%cBrp0e*hc64exho`y!O>;5N+ou)Z=u=jy& z?Pl|=<*Y?b>ux~)d%@(vUs1XxLp6sfV<>|WXIQ)x);cG0IpZA=5SVS3rH`S3HWy8D)%Mt*8jvZHr?cCbgtp4v*23vMn;2DQlr`p|ZB)CPddGRX?~`YqtG}F^CLJzR0ZV-of)U)1LWy=Ldf;+WtMZbMb^7R&r|^?s&)J@AYOwXtibEFQ*rk z;9l7LqXQS!d*LUx=yy0Atfzygu<7&#ifmvbLltl~_-x3Xi=qoQqK-l#(|SI`)?hrF zE&a~v>sVIFJleE7>=oaG!^Zjfc`mydHa8CsOa3(=TG*I$=n$X4rrU|F<=P@F2D~;? ztf~ke3J&6y+L~BC2-LY=y%7W~&^thde%c#8XK!AMd|Ux)T<6ISupxDmuwI1|g*(wP zG%m%cn*OvR`!Z>xPtU`+dZ)htR#LByB(Ih1e@*F=@e)z0c;O#zZ!QpRm9~t7^=)(b z-;ce<#&4nzE|0EN_TE*sljmN8`{co`FYI+6CVB{ih@bpk&2zO%kqeNi+ga$%^y)AU z_s*<4k}%O1Q1*f>Iq)lrXz@Lz3N|W1)Zkz&ZSb>A+;iOie~L)OiZOjFgQAD)vi#bQ zwt7y2Yk2EsJPN8w9lHmnDV`}CdXp*JLU%=PIhVi9ToYA$Nb3Ad#Fs50&`nEXdrkwY z;cU+Am1v4LMMVXkQ)}OT=;O6Mdh2>;i|{m@qQJiL1J;E4O$%}vG7@V~w1LrwtU!m4 zDS^B<_Hb4gw_WADh##3@C*0%0)nkYp3Pb=+B>zE68-%k8zTP!xw6U@A$7n1V=KQu5 zpLJjw`V!XsI-&+qVzsyEWN&QE9lp(cx7p0$*oT{^DZcjfL9;k#QG)Ft=SKA7H$S$y zI?6-Fr$6(%sJe8yoHk@-s*h9HzA2vwVJRGNsp4Lt!t#C9{bR%g`K>KkF!3;(_@_Rl zatwnPYjXh!3ws^%R>hT%O;2Z6!4#UlYUWfcqulDFP>R;)0y!PM$h=ub9M0ciz9Fa~x_yf!BClJx_~n{YF-7c~=UqmCN#4V$7iq^Mh1srK{|{!mFZz z+dtjXjk+X+W<#q!y$!AZnjU+inp4aXYCPx?U%XMz>Yc>SKDBEN5;Ms8jKqA*&dhbO zAD8^TncY?NB^%cHG3;Ir!?~?3h;{>E2pCl3NE2}Afa`72lsU{)AD5S3azT^FwVev; z;lBGVB6$1uz}3;gj&PbuV1kDhU zM<7THZx;`82EQ0ApC_7dYFCpcmG&U2%x^CF?6P;BJORey7woQW^n&yW-(=gZg5TB; zhG{XTLhgFvv77+8b35$bd!vXNwH#U+yD3B8o&Oj zvqk0$;j-E~&kepZhsHljyyPZhW5LefmTFi_rSIQ0STZ0b#+upbImpj25S-eDCOm!u z*Ya0y zWqBb+y7r*9I*AEP=|r_Ug4Rz&Vbro#Y7A6=FFT|yVb5g-=(tOWNqc>J34%M11 zrO-mLw_Dx!YwPqr5%Kv%do|!fW+b9r*2f?z3cX}N!;r4%dHve83b0It2*=w{sMKq4 z$!ouABcC;$pqinQzwK8K#W9R)HIykp1NsqafmXs(F@TmI_8#@8&YdtpplnnG+H;tl@j)sBZEAqDdNCXC*(bL#oC)hQ++(~TiCUCkVthP>j|uL^ zw>gDHH_hYZ~A=QVl16pCDaIwE4$@SK0uzK4H5*{BKIu@@alrmf9hcVpWi znupaN^11Ic8lM>OLK>edM^l*s3yFMxDp#610uctfFc2edkwk$9oZ?0H#(gmP?vH)= ztMl&P=)-z=R1ueaJsVd17_YRmjU?ArbXmhD)xwsJId)Ml>SQRvge2cyGUBQ@Tp@hT z_MnKfra)Mn@Ng?mLB{|(B(C3k^A%1uy&uyMfCcz#6AC!woLizG$)ucanHVb1X3`I7 zuxYt==!UNr)RPJ>SA8cck2ZVY$p)zg76sH_`iiEin9^o&wY959RM&+@V3ukz!hp3H zqrO5_9pY5uDeoSb%HQ0yaplnF>2&WpW~hEUI3hIDj_xt%Gy?6=U8+~4kkL3cu8(tbpjyU z@U}OdO%^{pdf`f{^7|eMT+XCAN>#C=97D6`ub|z%G8HZa4cf0oiYPpL1|6m1hik$y z@(gjcMzM%)$bPQHORi0E2NC6TL|LF>OZ3{M?pGFTMFGqU`tfogHQ*$UTw`;fhxDAE zJ@7L9{WyC0#FK5-U@`DiN%X?Sl+fg#zZzrB^-16zC+dT~8GUT%E40%KQ?VbJZv1`t zpPJ^pkQvCNRKZr}*8YisB1=^Js?#ULzo+UXgQ9#XqsUD)N!H453`)3YhGhHa2J&g!_4 z&(%s0=(8+n3jY3^ZjCuG$BhPWEyI(@h`M>(FaAHK{sW%s{{J7xPmwZ{z1m22_LjY6 zJ7lknl#v-JI%IEUZ?d59`iukn06o{w=KW#W6Y za*jM3!e>e22042{yv6#Kx_IBrbxw-Nw`1w=KJ6>6Ci7%}MUH*$3Gc~4P$8)4Q^&0g z-3c1D=Gj;z#cv0Pp|tmkgFD>8vEjgvXIwA4Phb}RPE(}cOi$qn*Iz!CvYkL6R0@U< z8xcWxi2C%9x;h#t%Q`x7AHo)c!1elOpOb$4kLQ63Q5O3CPHKbk-{?thLpbS zz0J^UEhdjXM(()S=kLYEDBip>eOF($b0t((CE(WTLT~xwyDMWP36gt(%O3sOOJVC9 zLFVr_i}>G79M5=iYErZQptv>IA(xHWjq$K{{xGNaw<6DIOc}~qWESeHL{>>t-{_cz zu1nmk15vB&EL}30zTLTgf|oheI#DxTG!`B1dWhsC9#@n(V7tr~m85ywEGH^gXXRW0 z#Gw1htEL})M1!hK`6y{_BV}IH$=rTpZ7nu~DK5n6UZq;!*iHwtj?p{804LVpft6dm z!;%^9tR0_YJO-){HN-|dWoUGT&F6NtEe1FNNyAg7t4&_c`juudwxBELhdZv&Fz&M@ z@drJQ&)Z(idhM#TJu36Kr{oy6P*a3PMlxLtfE>+Hntd1=+n0nUm$v_+wDgHfMqPuD zT&LZTTckEBOLHid*^?STqtv~ed>lB2e!9bEP}fpZ2v8TGA@p#vej`bw#M%%2HCfK( zqY`Hcy@b-;n0+Ybh&guxl_^Al)@_@~hNPVae*tZZfPncEzhmn@mGupN}$RNQaWX4Xafl#NxVm@fsMyt%P#OnZB?f()mp=_4w}F)6c0su8j` zn{KWLKjeyMwRX&tT*Hjx*;jYJ9`m$(#7?13rT?Hl`H1Vd&XKqAM%P+GXT^HwiI_UI zkziS8g`8ErnPJ$ms!K|-O?k{siO#(s*{5pV*2>D2>F5OypGv}E-VtT^+jC8IbqNgM z(GZ}U#9c+*)JZRCUj$J0@9Q0B=Rb7We}DfEiiW&Yg4n{~j?jne;;L>iocQ01Ls}Ut{Sg?_?jlBXWsXAX znwrtBY$8LMO--p!c>Z?~oh}*NPzaxXzbO84B>u#;ey5iOq1~8#v8aVqGhB3^3V3>N z#PI8@$__A902DR!M$Wo-B1onZSk`a@$~HMj;(2ABGrs_Ib=^o=-_WbK`FErU{V9ZBl1FmXi-hbHy;5-kZ&h9H5n^j1<7pvyvKcdxktjytocXkhCI+J<1}#`$QFuFVZ3k>0_W9XxA9 zm%+>Z`@spqAR4ZEDUkfnu|X5m@PTlF)28y{4jJAe@5!tCsMNFdNBCigYT%l&vokl9 ze+$T@%efE&zvv%JLURO2UW1X?y1aqx-{)EG7m~^waGp9lOuxsyr1$s2v}4;-s$xna zQ`DQ3^L0kp0;>az$nnmvzVtM>g912x4QT0CBq*T{Oa2~nAc-=9%osdFTsnY`-zjxj z^fgew!zOvZJsVL$4j<+(6OH@4Af}(?&C$m-{qsCx%Ch}+_79)k^go{&@Gbyj546y1 zm-rt?KXol_mwwMyYX6p8vAw&Xh6J;+g<-kt7eJzb$*?9^{!>HL-09}NbVIylvjq4|V2SE-w3R_)v)}(*DR+^naX8xQuHMoBL zdkA!|48{|75r>mKeQzW}LR}&5$~q)U!?^oR1uAA_@QFf2R;aM|AG5kwR3bwt0P249&I2w$cpGMHli}Z_T(7ps-A&qv_SL#U)&# zkr2SnUpRtWGW+0yWA-6YT&!CET`O}z<4~QfWOpFX(Lv1sw2vY1p&{Sq57!k)}dI?jrw1NV=`M)g-BC|SIbGf6RAc)u3f<*cPzk9igwXjM3Kw``sxK3M-Z1&>H(ABj^jsGwLPW;|DWird`AU9DLw4PYMnq+=gjAYkTKkW^3o2`!4=xLHzSl&5lSo z;?8{8=TOSg7#lpRIgAKU$Q<~mEb>|K1@R0I_+g;g^&hrXP#1Sx)7Uutsn-IngMiZm zK{3~LDk3_8h`r|kr73?rzS(&`b?72Wx1D&d4^zDu41R}Q3q2o=OH#tU*Udc+96@ax zBv!JrcWr`QRy=@E<^Z4$sC_Ps z;z9BcsM?`r@E04fqgn2c$ATURK+%wx!7Iv06FT1=c{_ss?wSWP3kxEQrFMr-3EVDy?!7dgy#KE%ev0CAS=tiGh_j}VBZi1oj_hc#jJoDIr!De{|_ z!MKZ#2yjs?fYe_lgpsI4i;EOlM`4p8*xfI|X)ucJARZdv>l6C%R~gd_|}*fTkrxUT&CrSxo{S70yQF0T}j)No-J6o2p&0-B2nROxu7M~OBY zPuRuIRvsk2IGEmiK?#rZ;e^kbE}i&``k!Th5Zi*lOwB+2j8yE;cDOmvnkuQ3!*B@C z9>Jbd&YGE(Wzp~NWUTs6_!`8(VO)XmY_>s}Lc{V?y8HR9H*|DnaahJZfydQ)L9%xok|*KBNwODI{%zgVy0ur(Tfm_qbRe>-m80w9e z7(XDFkgNYgb2v%YS#@c{VEEYXecHcE_;0(B;VA+b6b#eIWJZp>%2{uNS!c4HzMftn z^2q6#gS$t_q=5vW{kdHMITp;(2*_g7<1@_%q8OL8@pNdJgp2H4g3)R6{uzjhm-_tu zqo9YJ57@_B==nnrNh%LOZD4~uKKBC|edj30NAY%oa)kr5D=LSOGBSD7>mmZ#!tl>} zjeJ@I-Xb^wsHo^a4H+*a?FK!IvS%xwD>t8h z+~9i*YV;aIK0xAQ?UN+N*31M*pt`=T*d0gc3ZTm^6vmxP^s9O~hdiJghD3MhZ-gHo zdqTCI_(umCCQ#h3)dC?I_*YSTC!mTyU;Ob`uMpWEP-|+h_t-_4WOY^GJTX+4us;^E z>Trwi<5k{iT8C zHMaw-!2awiBE5|~>OVi-9NC2OF#Agxnsqa%1&&RciL4c-UjVR-+MfnGxy^9S0Z;)@ zAq`2sH(&>>Y;Z?ZrhfhU^$kZ}TSb>Jjvg0rZh8S)R&&tF=>iZNAt57Zv;aL(z;XWd z+=0&86f6p-!C4BKf9nL+V>k=|bN86-M2n+i|Jd=R?|)CMxk0tu?ToUxh$Z)Grov}M z?x*SPf3Y)!CGt8j-koX*@NaL6q*@uwdLI}fupsjtegt*)=(0UL5sg6gqhy* z4+%0t3vPP-D)>3$Lt?e|@v6vM zvf80H+*m1QZZY!V(cW)P9jH;fkos?|LudgiJh^QdTldBzBklL*68zTC;d^+|M55~hklN%i_%x+gCsh1K{wn}fPKZI~1fvjqsMkjd2!>A4)f z>wq9^2004ghN?7Or=e*@2GS#ANh~ZZ+lw4N)IP@}sfd=&SD#sEQ3k-S-KMvu147P_ zD%;gvy=+P-`~7>6?04nPkf|%qt>k4*-6Wd}sLQcz|91+s?~1M!To+n(5O7!skU5$w8dQz-F^gGB}+@(&5MJ?#Xrpy%fTt`FK3H*JSL{qCH4LN}N!EXQAk^1b7l zxgOrssn-5uCJt4BhkmrupG;2m*gm86zp4msAR*v`Rk(|x{Tyt3dJ8zx6)DRI z@e>%YoG?G|b36k*tdN$LmL$<)&=F;RHhBJP&r# z_e3Y&Hl13+ObhaBh>;1khnhLaWP%aN3@-Va95w>KleN#x!GRba@tPIEUrm2sAOq6c z+W7xhy>;#>zP8jm^lGeM!bU;6ad>(0NGDA7Ot+~n^;3}oyxHaM|3V14r4Aqn#`mmKlq(^i+5P_1e4zsetGMM~b&OJ;1 zFOk583Kg$)(dj1frFS$kQw7dWq?fRvo>5j|u@8{?x5Y^i%LdJ;lt1nWQZP&-Xajv& z%jqTQD0;3t(PWU$LItNel25Js??HmqsqAFK>^rXxjU?v_rrO&0zw8Nd{7|Tr<-D{K z&Tmin&%e4qC=*7nkg*Z@-&%&pYV8Yj8fNUDN~`xjPl1{bkz25l3hC?ZEp^?{M|Ibg zY5=t!Z0-&$HwH%b@v=>O-v$^U2-rG~XsRA#oU%G1-?sOcy=qAfYQ5v*>KU|3|D7Lf zE&T&>?CvQac%%>UjStVmrBG=K?pknPjMY_ESwr&D5qr1a@ZWbRyPj1rs!gkrbv%3Eq5 z>yRN6L7PQ#>ic|VY>85ll0C?41a(S`lE)YH0ReAUT#ExGpWS$23;39Qeo$ueODHnsa6O z3uyiHWpOmlr`{t*DgJi{ZV6ZZ>L-sYICu0xP7sXdU;~xQwoKo#^VihY?k<1)Jp0S^ zM>q3>U(^0WNbH^Oqtv=&~PQtn7XU1qVv&?B@ z8TA`|uDx79qDvG-4{TAbRI3mUt|3<{DW*8+x?`=)A4Wgk7d z1L{C3O&}(C(#%PKOf+bi|F@VU9FtkCMT>O?lo6SKSs<|8?Bm)iHe&d)!3*M_Iruy*xb0NRK9M3*H#I30u8$|CVc#5PH?)9$ih1sn4peV0N z|BZL1S|y@wTzk8)MeqMOwIajft_VY@7AQu;HHJkj`$+ZoE?kKYkV&zF()-8R27pe= zUwij_u-<3+zgrC%3mJ-9E^xCHktEsLh*UV+l`F}A}T_7HxAGEJmz6F*SPnxki9$#1m-3ZjK<4p8wFk0om8JbWUg|1UZK zF?j$grKg|)m@^ACO_sl})j#Lef5o{+?06`me~2i>CG89Lm4kLL^;j+JTi2IFtzg$c zkeJi|i!<}(^J%wg2ry5~wb4_?wmT-vMql%!{#$Vn2V+Y?(5w7e(#Q(EA6NV}*?_hk z+ZLTQ;(uEkau?XnL*Gs8Zm6A@Un?hpeE>J^@R0d{w$K0T&PC&XbvF0_!&)HWYxIPY zG|h$sl}MdTMWtYNGk0cO;Zk2Yz^rnfpPs+nur-?I=%TK{O*o>zBtfH0)0jx{JA?ga zSqVpM)&HWG@{$*O>8Ncbuge_b(`6q-#ig#pawDwM!EDdPnZ zz45!HTb;ZPt`M>8@=K%_D)CP4Bnu_}my}%MDwf`ceF46-h^1+Gw37ZSfp4%&n5#q0 z!OoqZk?=zGHphRLi!se{T8#6)+v^)|dN8f8Na;sP42sV)=r6rT*s}1Ne>__<+`Bkp z!H#=1N&lZD39gtr-Jz+p*^+416H2=y9)h;ktMAV(IGmS!*ZZ%n2?>&ZQr;zKXrr0| zg{xVBMM{cquWckj+{tG3^eG4GM!a%HNlEyVR%vpHTvCt%hPAwK-C!w#!0mRAl3qxG zOQ36wh=Zq6x;$N0`-S`3DE}$O{~ed-So%hyjT@+1L(t)BHCQdZ$7d%g>@ zp2Gn6g|F$CxQ`9|T5d%3ShUosZ{1Sd-ld}ADxoF7s!7^kD`;D}aL5#~j&nNFrHxc=dwBUc{lY;!OP zc^?X34$`sU=sP`acZX4smhtN~X8IIzG^Anw~d2)8kE z2l73f^YU&ah3XA9`tBNiD|;6g+m1O9-GMnM!r;}Gg&r$WfF{S4h6up5d+Gr&3sGnf zjg_Z&VjKqzW4X2gLP6s%gG6^go+sD)PoME0t}#$^gsl!pbDDp}KMA1V+56FNG5GfV zNz7N`we7C!Lmr{f2z@#gY@Oza@*+*$T?D@rkz7%mGPrv$pmcn6MhLWuuT5uPD~E7s zF5Vct;@p^oV|2Y)b-mwK4UBXWZ$Kb|MAlOrOtNoWg033)6ac9c#F{*4^?B|MbQT#m zk{cQCb3IFbCh>(nD|QZ2Rm8~4@@xRw!H7kb6t&rlU*iUk0!Zf>@3D;o+GPv&UyHK= z$Ue%zqfLs{N(}2qclbMVf*2J={X*bTnEd^-{=^kbGu&rSX5L;4FnxJcn|i?Zx9-Bc z#yz{~Qm)qq#Mq!sk~s5VLnaw)BDUStjEqvman-Q9hw(4T$%!}do*g;9bn(2|HKa$w zo}_|bmDOBKu{6>H#JVZ9v~bWO0e+rXKDIDL@J$#c!fLr5+yNvpgyN{LFO-jl6NN%F z);+;SR^*x-@VEgifftsY&wMLV-qur5-$f%v3&;xokPN~UL7ic&W3)9X+&2R(p1%Ax z%w@uJPq{d>3q)z~8p!05E@w4|f*ZKCL5th&vawnqz?--l%-R=WNln+4Z5G<;1w&iF zzQ4(^_C&ll76c$mLe@rnOopB5HSZwlTOQ`2mdI*S8{zoe+E;>U*S0l))_*X#g@^ZD zA8@2QJ~>ebGH%3;DeAg-*yS&shh|1aHL(rHM+1lk?xK^%)kfizRiRby55{x7Q%bZ! zSq~RFQ+ag$xLW(I>eR8da z3$WYWiKP}nHcQ@6$n$t_CkE#1&$F|z^y&HRs6)A4acx4i=)%iNu70-}=mHw~&wR5) z3lC7)-5BE2hA58du;uI&g3k5K^TKe;>_$5mX3C?KS?C;sdzR7=?hwQ!s{3#*zs4o{ zaT@*)3$W9Ep`C=TT)Rgylm*3ENK4#?nz(ql8kBU`yKw2Lb~gTCak%lzUyWnd-o%{zm~PBqGwcwHQ{;WeU2$&|sd9 zsqHre%ha#Uxo3vp9|8Pq*k$i_e?wkJV+!dL2=u^nhtIVLjy7a?dI-q`!Onwmm)a(@ zFsW#0dXHX={56Ep$NR!U*6x__Knkmy*TNsB`0~ymGq@k0BJ@Sq$yz45XQGzxm?wcEz;z+Cd+nWHt^xUlN^39${B~PE|&h7LI%mnuYl+#Q|R;oc5 zc9~Q_RZ@6=WRw~){D}L0`luILB!IO6hIuuq8cU$Ql`kk2j>z_+0fE!KKko!_k0_w6 zI-L%{H?iwe9s%d?1C6q;yjnTM%5#G~4Ls|UXrgQ=KgJ}+Bgad95(=ugX z!2lF200Os5?^|CL2A8o4mEz}G;&pp~F?=vaopo{wQCYDS={T4%S zjHMC}+i(aV0=a!vdN zI93pllaqs$c4R{VJm(*$RayNheDQY$#}&_efXN?lU!<91C1Icd<(9?Jb)o>%ipe)J zQuHM1%I6TmIy}mes=33TKD~sGj&H`pNWL#FW+WPC%68~`CAFf>5wL8ydwd6a0= z%WN4=3v*D70OT4%&_*FvlK|>gEX96un_LRN7xNky$Zb>*3&U?vQza^PuTw$eEl_nti6!P~V%hy_SfL*$xOApiQ<*6#l z&164mx8Tp@7v}K#vr#&_x}-8Ya77Dmhlhk9tlqfDo~j8WWFJuKo-pA|%gOP#P6Onb zfSJ&F)M3^X-O$5ox?xX z+dIwPRX)f!8)LM+qEFk(`^pZ5Du^G;UukQ-A;`g5Cb-hW z*?89$+aI}8>Tj-vW*V#S31%`0igisI8 z{4~ny8j%lS;56bZJ|-%_8hd#KZHhi;7fn7_Rg7{c=-IFsHSf2-9Exj?q$EVLvLKvfH;|M_? zo)CJ*J9jMUJfO+j^Xs9ZVbOYb_^;-z$#Y4xgiK~7)>|eXSRSKaEnHf4xcEOR-jPhp zL#cfx7=1Ap zq0s(r*t#8x#4?XvD;xTW$BY!y1v9{xh^OeSh<+>XCrxLrg%9ssjVaP8U}W!4 ziTzgb=rU61D{M_zRm{P>OIBC+ZB}91+&fCjM(9Z+{tZFB7>MmoP8vI>AiM^vqz$yw z=`EpjN1Q*?%hc=YJ2qTNozope;?d7ef4Mb*IdJL^HyCk(m^gZz2&8J?)H+yM$ueT6 zc<<|hLW$ywl7fOZ{-z_9$&*_u)T)fpP~dT;u7ap38{nUB98E9p&ZP%jiyDJepCTFm zD>V0^soD4IAxI{WebZ9Bl9G_n`qby-p`JH5uZKd*;^90NyJeHwa%;z&WWiX_^Ix^O zChP`^d?E&~IDBeJ-WCL2Si?dGGSd8@SY<}XUhjLQnu&!S#Nsi|6vQY3cC3tKb!A6Q=e-OP=|TNlktpSt zRXssH)e2vH`EH!Q@gT~tZ1l}mK4;FCynbQ&jfXhF=c*U^l&c=J(3GCPN1m>2BU#Gu zM!}QIPiDT5fdrST5J%bd!7basj2%gaw5W8g>=-6b>E${MhmmzxqbPzl=;wCFMm3ki_6+mGa2jk{z0=S;C^%0k1# z7mk)wb(11J0SJTmu1-(0UE$_YA$2sZ&UA$d@hQwz-_ElR_i;24gm?J?6G_oZ4IRfY z-}+c?0~96UE8x~!Q4kM3+!g=p+_V14tCsU&C50d2Mh514kO6QFGrtL*1P2NWZ4dkgU`^kV-yAgk^$y&+x!AhC zKL{EGFOF^Et&^Q!1R%aGb7fuEqP-F^-&;p=AFw!?-io|IQamXVqnf*o_!c`_{RV9f zzyiQP{`v5!WRZb<`SwC=FNUD4yJib&B*EIP?6*exWbDehBfImG)UHB=nLSy@AtFOV z_SLprE$FP|XpY#kk<{X(1JO=z=aYc`QNzaz+N6|UNB{U7C)PH3ulZzRT@`ramp`wq zUDIiPPdOx@k&q~0&ElWgKH<7zps+PPaN;Pg|L zS>GWP>t81Cxygr(MwRw%GHwc28n$OVj>&f*bdqSse#yA`keaotqgnpT`$i&WD!lUy zpGL!DSAFK&ab@IG=!W-C&Z2%g7P|@1(zYF~C?wJ8{3;=ppzXbrW&go0mU6G^vx*HJ zJ4JSiz++YZq|`a5@!dCBcZg|RdS2VHv-eXQ zj&?F{_VZse4Z@p3Z6K4Xn8Z6LreCY({>#gJ8Vqz81`}RpFI~E8y7*N+$x_d2tK}jB zUE&SDqiFE%=}3o%v*~zKtS@HX@h@nnA~MaE8^LezWhjC>$S#zl)#wDBuwlNXw$Wv~ z>EP)}1J#CL-vd~aKYF5nuCFKYixXbH{OGe^>^iKY8pw6L#Ac)BC3%~+Aj$KX_=s3B z)U4zr2F+8xKx`svBieKCzQ%V0SCt>NYPc-dDe-)aR}Gl(Pm{#M@k%Jkjh-%j$P2`M z*Keg|mFN^cJROW>jO?`yCA=J~jc{ zLP6uL!mT@WT|GkIzkGRT`&*ETAfvI-h&xV=qoOCN_N{GOm4-}YMac$;t+YlTQ z94+O|#|mmOi7>fa^dRa2O@{ijPgki6TRux@?XKFWwNl$#MN>0I4QVL#b z)V@Tis;q3iB+1a^U}h${cZ9c%kH6RoS;r))X?l&?7XyVP#TSAObKTwDmO~i&92YF% zvWCN^YFlQX?=l9ij4Afy!Q)dq!GHEFx{H{Mc8{yxmTOp5P$T|XT{I9=-h}{XcH4<&o@UyE zd^{s?j`G*IJI?8^y{2twm`p8A^A5+|?An;MH4G4FzG<)~(Z4Cz(zSFzrLpSd1T8}4 z_uaPpJ7DdiAF1XG5lo^PhDo%YdW_tp%Iz}x7Ne@}%r)1|{-DB(69SLCc!Vd!&wr^4La}me~Zs7H_|jv*^hG5#{7e6T7CXtx)>f zTy6AN;idsvS68kbqxizKdb5o9MY={Ry`WXk@-7<zt;&m!TG=9a# z)|&Vytv^icKD*lfOD>|igJ$(X7|Q$hwNA|?)gp|fC0A#sBHhOKqVOgpGq2g(+n3Ah z+(ZLn(_;i9axL7#UqVSs-o_#PR>Fh=g|r>Zh!6+s$7v#(TH)*-i(Z1l^AtV8TFmD6 z9%^00i8}egJkncf_DMv5azlI4a_m>>5WdoS%=p;YV(8BP@84vvW6v7OFLE(xl8|F6 zLqR5P>{3Z?tKXH8O9@|UO;k9hgPE?6g=iZamoOXH<=fGtMOUu1kM0DM&p3mh#2`U( z&*uHHiJN!zFDVHLr-&wweEk}%YvjSO`JF@cs4u|s-q*QuVYRs1$pa7deOH}YwQi3S ziJ9I{AUuzAyXF~<)!>D9>yYFix2w1hv!e-Jegv1an*c^{@tOKeI$)7A^Wxj^@Xf^O zn=Km0IWVR2m^IyJyy@#)MBZmsme$a4_0EGOq92yIr-noZK&^d)$T4JStX!q|%m-68 z(<=R4p^1*xRUmi`Tlb%+mN!x6J&hT7pg7w=g%%m2Y{y)^dR1n344iAke-PD7Jq})? z1RFv&W=gA)IU`$x_gb={_`w|yj%v2XubDEs;ypP1Eo895XB_EqSB2H+RV`uC&On{f z&VmD;-a;tYtmMfcY8-Ft(CRc)*9@pHzpVQMP&dVH*{w0y>@?;?ZE^oaNM@EnJ zAU8uS_O+gmrg{_&&p5*L!YoUnnjn^W!kRe1c!eM5hX$)e1Z`+%Enm;F*we}! zS>~-e&FMG0jss}EM0@rD`3o$sBXXW*zhtpohCthWW(&@T$E8x02E+$Dbeg7$pgH*Ph?0$hXJ0eioXLj-P4 z6SP|Mv_7qUV;Nt1qkZugnN6ZlH4I`xXUq|##)$2e3=-?n23}IQUqUvxl7mV z-?Q01D@B_G#%uKn$|~>pRBoFPn6&fwegTvk&BAJwZC1mIa)XG%Wx=>wT+N(30v!wb zC^ubGO$=_Q#)3@Y>i_|#tCd59jnswsM7Sf*U}76@)B6fEMuD*V8|I(Dj$;#mx7Un>=wXhfoAe z(&)#>%X^;N{64$<(AJ6-T+TAE=1XKiL{|`($gr!zj2`@ezdr1F@Zy#*pTFrl4@XlM zmpxyHbjTA-c=`F;7M;?Ynv9*oftz^xx9f-vIWv z1!dhtInUrTAr*M;(7+>w`JjOFQpjt3#0nAs?*~$ zN|S5*m!JNiled(YENhEk@jr(TRP5PiCXHwM|+Qp z5hPsX=C%^ycXKu5BzxWV3mipnv+Cf>Dmw>HHoZ#-X8ItjA9y<*t{@CKyI8v{(3$3$ zfQ^O9(iu%5sH0Sa5g@VUig(C)%+9760w!;=a&kakgK>>7>_=3go&B?z_~IqCiX4>? z9Hr$j;x9IdUj>T;?azZF_*Lo)v1v=6U00!(MMIBXw{PE0v!MZ74Ok&myy1$C+7IgFNaF^q`qmxTIy1nR zH`6?gng)IgbCQ^<;9pw&OhLCg!BJjdPUL1=kZdMA0T;U*-xn2Ox)vf$T^K&{Tn$Ae zRlZY2m}1)Il!deaC5&(H$P47y~{L5I%_0N?Bf55ngYIHLBV zCJo;6uyBH#=E{l<^lHErvs?>u?4XD(UuwHewv43y+ z1ZHWYLqCjG@2HZ_9J>9@@XRU5cOXwJHUFw{rC1+VEVTk;a&e6uP^xbY44OEtuk}AP zB6iciy7u^9)&)ClFY=P(wm!0@VmHSL?5imhT zaJK(K1$4s?ZbZsktBQiJY(iNjo==&%^EX!m=LV*r&#x_cXn=By*ZO&W9S=>ve9qR@ zRa2sra;E)yc#6cWZ2O+qUu`<320KsZ$9|v^s<9|0qP|O3-KGn|#3~Ww#Zx@eRUycu z?#a2+(aLObJE~(|@>Qxb&5$seRV@XUQo)uksfX6=rnH^%Q+I4gBu7c0QL#k3~FP6xTL0MZQ^LUS`=@g&}75YCr}3>jHFr6rOIJCHZAe<4aLyRI-{v zp*rw7@U+)q^DRfC%_J0jwcp&QkWPW6-Tx!fg#18%rb>ZKqT zpnie#YNXc9rKtD-AT(F=<843juyt@vq7Lvn2I7|%qzB&OSD6h2;8(qwI5M#zkHK8B zxJPMw1^KhZY2XJN8Kv#q^pVreyzT{$7c&MmRA~L9JmTTH?*?e>!lOeBehWrFTx9q{ z?h~aR|Fgy2M!DkKjyr)ms1C~F+V(Xw+=-8asT|hdhpuU@y9y7#>RNf`X|yZ`NB?ER zHIO^iUUVgeVBD+!F<+ZiMV?uVP-|gWB1jy_S?wR;QK^q(xlVyXEJph>nKIv$ zJQ#n&^|{d?6GdDz=BV^_mBZWHl=-;PW=^J!p7#hedDyk^`TFG?ES=M7#0TyiKFh07 z3rz*=g9-f0l2JWX!^f+)oXa2?J|~Y|xJ8?1eIc&7xK;5y?^}2B$BjSe3D(JES}eF) z;M6U+EOG9IEpR33ku9W|#aRM-emKE);Bk3mD0!y2jE4`Rd_PGLcYj}G$Zy#Lx@!WY z9EuIE-9{5^F&$=+0&iIR2FHT$sy0A#tBuoIsmhX1=1P-PLXJe4milU}YOcfx4=Y8m z1r~+r2j$P9s+A^H52sA|61iPST!k(4D9EJ9FDSk9wt4WOZ+yD#-k`N?m5h3$kU}mXxGRsre8*Z_4M9aw&g|Xt81UX#`aPRQBufhts1=F9g#FQ zw8_wxTBhX>Z@a7=Ys41J_`A~xx8Rx zHA-so8`hY?q%f+&z~#RKL4LcPhyTFPVbx5Ne>yJa|9g~}Ty_zc7PzGFS(vr+@eXNq z(CVVQ)v z7|*aI<8$c#`e6&fbcfgHtIB5mAS%B#{ z*L8pCKzmyojO{@uSEkL3iqX%d)kD&M(W%y?3?1YvGs43Z6lLn7b`>@%0PArk29NZA zUV$GN)04=JD@fdk(An^U5Y9Q| z8nzyoEe8cLj4E;ZwV)CQ;#!#FoF!I?4T=rkg;qrvFk$nwqwzbS(-z%RnFh<4D{Q8e2W zE1SRlpjb<+MBa;Tu=>?255ZkBnVWP(1wsLksRO*~f;r4X;M!U9Fgwn~7QX$3I6Bn7 zhMBd5$Ti&#{kCEWXuGtiat!T)9xaS{GxYbFe=&pC0tJ%Twa#&dC4?`rO;FfN{RdoH zT5JxGya{OD)2m%3_u*&Xo*dNUM1cpvLiNJYiDBVYfVe=WxZ8?{|6(LU|%xIPt zv009DbG=xMQQwLz{YvmnXKnmZy0 z)k^7T|DqE)2AR#+P98bUEi&GBnajf;GMjWc5KnhbAH*o-J~cF5t{I$Q|H|3k-%kLr zWQjpj0XoK2w6D1cH@6?is}HEt0;vrTvxGhI=-BFuV4=uQ4Kcb3I;q?yQlk=G?wc^$ zH{pC^9%t@R<`r`p<?q=&kdO|Cbd<9qua11c>uW`ob0Z_yhUV4%8@FqAs)Awdq3{bs3uS<+ zC?Uy3e96MfdDk@gSu!@2iT7h~i42igMPMOVoWFBasw(gRWn+T%G5v;miab3r0S@=9 z==E_J8ruKiL#!F3J>Y`DITDc|5DG9gq3_KcW+Ixu;Z9k?q>q`6%Z*#8*$~hfC}e(z z4{GmbWnVHJZw5x+#Kr|Tk@^}nwnKU<8TB+9Pa^}S6mMNSx$`>d2J)>BB!x3;PLPnO_Zics+*ILQsCzQO4&V>a=eJok z(Wg@jY~@b`XjLArlEeLqWLt?(i^mNtlNh)MDpy&_@GPywt4v&S>v&1!ZV49XEN!>mbNz;nm5Wucbik;z{`U&v}>NSpN5WyCP*6zCHv2A>XH>5l}?#&0CGOT z%1ASh4DL=lUm;nt4BTx84BTt`U#`w;Ql?X$H;AF?G+TLA+oPoLpD zXW5L=zfk@K>NdtEho0Y0y*st1HY>@*Tz@lp>XxvtVmZ+15}RI9^$?%~_U=vglGhN- z5D6pY2M^kwe8_|X8&LI8s(qXUfbZH4p;Q^+8eYxx0!tPF_thJ|EjJ+Zf*Jv|!vai~ zIsO05j(>kWDPyk=Llb0=z{qh=UF>z6sh86ZDHy&0bQ(Y@0E<)fb%8OpuI3Ljrg-IE z>4NYbQ&(4tlLwn}z#o7r2V|j`nVIR)P&7K&@90B9XVxY3u=1GcI)E~^hU3E#=+Qr^ zp;|5dd*fF|t~^$JdW(Xo46UqQ30fYeCMGB{nRGC6w43OCBx+tp1qbRF!%q^}ExlHL z$Q2S2Vls3j3S}SwbwDvjTbr%-@JACRtnl2ic)v!n~b{^vlb@K5%jIMfTL<> zUiOZWUCU_{RvJS11E?k74bnb*paf}?pb6VKNd`H4TU$K2Fggi{;4t18FVyn`8b$xC zxaa=EI@B2C5y>b{n-g1AcI>6kcD&B%lBvRApvTC_2>auwsVPL}2{%rsDZ-RW=0#nM z!584BF7~}03dYBrvF<~kcG`2!c1iAq|80!wNn-Xw5(?qzOs|DEYd>g|xV{!uc?mK#sbrY2BiPdl~g zyoEr=(fNQe$&tLUt}ek^N9wMOJ8-&yT~DBq7xUu)nx{ZppN+T#VAYqlKi`FtGc5_g#~eO)3g1kpx^(q_e27aIlzNDs}|B(rJBr2I!o?YFDM$`v#^#G_NC`@A}%J1G}5}X-qO_xw*NB6nr;b0l+!E zb`xh~2=@UIEA6M}>MuK@OsZnP>}JsPqXt^7y`Se1ND*+veg8cEPWc%6 zhc(cqXE3nfqyk-MCFr9K`Fw9ahg3`DRXq=@AGaXw*4mODi(5;Q-Z)wxSY*7S*7XZ8 z__VaN+ugUryK73z%cJCZmk0oV+%4l&z0c6Kb+ytX7Jz29aS*Sv$)2$m=Erhkst zqEteHS}+io%a>~?Gv;7=%W?1m-U%0PRMk5LfmTt zt`|AK>&oV)9OO{4Kh8Bn-WZeHtDS5Ywm_djj)D8s z|DFh#Zt{HJw$;U8jS!t2Z0dSlM2t`20gK}>W{+2y0kBW+vTi5CeY0ZUl>398%l#|zcM_jf$P{cD42d4lfg$<#g@ z2PHky1vfq+%8}oIycA`k1b7pQVorre1wJ1Z+yLkzfG6y_-fZYLjk$6lj}y$(ns`P8 zkh$mwVtE3zoLpSKl*V2NH~P)`HTqV#Kj-&@_iia*cGSfb6n|^{Xnnl=6oMJJmiYF2 zkkGM|Ot3gUe*HYc!IW?O(_9uP5kfC z&^u98A!(AUrKueW2TN-XHW4yJ`OWXTiYr~f~$ z&I2CnzWw`>y+Za@_LiAM3E3gLlkA;MNGdBkBYTAGy;nvyS=k|bWn?5o#dG}n-}nFZ zJdf9PUw1jr>m0xF9mnT$yg$IIU4NnsmtoJ8RKFClSu}B(o*S$Kz}39Q`vNMGNTNf` zoqMd06j{zq8iL8gx&$C6X-Z$*eT(cCeU!?x*cQk##+XK-{^p<}9<9rsDstZ1f()Q=U zf7k;zhNj|=cjv-DV7s$kWTQ%%o|cB$UkUm}gDKODWmTrh^bLY5geI1@N^JJ-k7SpU z)$-aZc)0LV4Roty-pmm{z8^!>4(1dnyK2_NLIDKwy3BpA8$RN&7dERgFfn_wA2yom z8iJK6q^ieWE?GgxCQq*{F0F~LBR~}}Z4WaU)xEoVrx^ZB#;{M$l|-WwcPT!MJS=a= zGaJos)bJ;z2!Ya?;%s7Cn)cj*BRDuF)5mL*DQ5}?ZTq7vc_<#D`j^v#8L! zF?ES)CYYUyVA=NAHuY(0f^h*!IU=`k4*GHtVu+QCnU@FI-^*XJ6E;)D&eKMi_Dz#F ziK;3@zlhV4SeZLgK@&)hcN*+(FzoQw!eM9hsqxRHCdhKK^A~x@AJ$fBi~?nIfUnx^J%s$g|IYi)E?Bua-nyerRmS!-5-L#Y$Cdk&_ADYa#m2lY5%4C z?&Jf-di5RIqKF=JY4C9?%l?pYUK$usxr<61q*hA0H9bs8fW>+(iKSmI1b<=+nCjP} zaezfn5eQ|ZYV&43-1s)*&*37sZxe=fT|3BAoRMeN14|6%>G`x?J6pu5y^BjFhgDG? zDQ>;8vi7XDg*JJ&ynK{ej`4L=UC}H$jxJg`#U}BpeH&AH`;_VOHdT-YIgL({c92}m z%;w=K3;vX1IV@Xk``5E_G+fDQRCqNc)Br26um7<;z95i&H##TYJOv=CPYTHT9qKmb zYKF{jWC8~NZQN*pHmr^f>d5+SYu2AL!WJH2ElEEhqkvmG;)k~+!+7I*>E)N+Pj3@o z-7{)icM><(E6rCHp)t_VU}nA^Bm5O`W%|#uIJg{tk|jRc)7!4s;}^?G|D>g{>|bi0e12w)&Kp<}g)$BB-c_|wOnk5OJOemFH+b&dxt$MZC^$nTvCXu( zcuT~nOsuLjC%!=LUgO=PZ?HU{nm_m3l^5nDhpAGS`>$LD81p1PA1h7HSAiT$=UZ+*VT z{kZMjpT2hrzF}Rah|T2Jp+$PI7wd-yF*}m8U%qgV)Ui}m!xtdsN#CFh$KT%G#s_OA zPfSESvcQ_E;3@hP2t{HKM@>F5>;t?d8IvaMD#XS42?n!ktpd;J^I#D`t1g-X>@gow zlT@V~t>-l{F{JvBprYhe<|8RqjcA$_@El2=gGjWO%Qgv?>gNrkDDbB0KjfTN* z-1TnpsBj7Xlrk&obeMu}cw>JBmAmd~H5>m)sSiulbeT1z*kTq|(Ff2uw-K4DrSl03 zJ;q9>9X1*rpFgV``B8R00YgfeH=NzIh$c}nF{_rmmvWl?IX6Iz5%>OSJ!A)#4E(cQ znIxTDa{u+V0f#`Vp;UbVo;L73KzuqhN~azsPvCv9qx91TJt!t7rb#VSvsqzAUKEl@ z{Xsdn^{u9^&g`>~U|K!u$O(zfL3oClv6ZT<}&1gk&b zCGKK~oUH8VzX5L53V?PD=i8*8t?-R{j3}R2dh9R=U&+d;!89{7yIDrPN81CH!hl2Z zRu072!~S7d^J|6zW#+pFmy#X*Gj|LZVEScvwo}n`cWNi+7CK|pPm7Ay@#$&Ys_E2| z{F+H^r&V1Y7zw`Fy>8tQ*c}pwVv0=J4psa0dl1`{NjXA&1GOxGq7x~aZTA0bZY4EEI^+L zaEcVSCgOI`yB>Bz?Y&rs8~G0wA<c!q3kDV6k~SMJv`Wos}(u(+8f z^KSU{T>@JM6{?_1_LLRS-B;nf(w#cgovWIHGzT&HCEX$X=jsq|f?kz&_;tDCf>hU! zr*rNJ_T5JK6temXAW(|eUohDwa1Lj=IqVKdrl|ABxCXmAFMVmbNZKgm{Ikv|x-Fwc znSpQnUF?GU{QJVW>VYF-{FA;olve(O8KWAHy3KxxK$8d*r`9a%4y|v!S+*3v(dWq~WVhBO6`NU}YDbuNu((oZ-v~j#Rb|f!5 z@szBG_<_)Cs8b9*`uzhfu<{K!v_un=%fZm0`4SaHUz*{j{VR9lqICb z@D)x)l35H!@uULx$jhvNiBt!KthImsd(SFeSDeiT0Wn$KVsEp>ts^FU3zk}|PebN2 zfiG(S!2=#8G1n`xeF3x%^_P&#M1NZ!SI0F!$$B3O?UhG@!m2B98R%$a+nQfy6-*|pp8w+7wV>msb`KI{JM^_*SQ;VZ{!Dfs(vr8lcG z8_}A{ju#ick9G!5H+`@gX85zE+Ztn@2}_kr&~bcXE)y)g_Fyq@r{(l`)^TOp>fPXe zX`3+;e0X5>;ut6t{5$tFa3~<13!o}U3y;MpGu-A54QmvVXW!meF5d2|y!vXTGJ&~* zCk&z!u^d}YE!VvUErk%UJs?0HAGau;+Eg?M%<8`9z`HnocfmOw-m~Vi)P~L2$y@jJ z2LEH;XMcBP&cKoY>{999)59!PK~O*YXKk6~31OLlh)2t?(~1f~gog2<6C0T1T}U6o zbWj>g|8nQ6jGdZy2xA=y#e8a&C6czfqu<+*M*PDx|Ul}lg zA-qzi6nb{WZJkP?ya)c*37XLE7(RbKqGmesrelNybu%(Hsz#hVhpJs$(v$oeO7X|? z1eTJq!`<`VUK~(-0OCbv^{QsID~#T&;`$6YGoeZbr2x=#pndRVpLxt5!!YAsRvNU7 zK!>)~RTijdLQnPQ&!5p?WzuntoS@x!8%%(v!7Jh_YHHWOWZl$+upFVV5px3^CkG$n zlrwO^P5nN}KiAII)~VYiIyf%%mkgH0EA`>@+hNwip+GXD#>IOc0HLWotgl8t4Lsk2 zU=jqaP+Lm@hp*BxhczRU><-B;h^fv??U>nPHo~H!KyA_rf)V*z@?bAH@}L5XfP@4d zWLCg%4dXp^eEiEG0d>3{))1hMXsy@31IrB5dywDDm%buRoPB8vn`%4Xm z@LNBTc2@xL5}fzH7z@njyF=O4a&(0ejI&(dqm;&kq3sYLd~lPp-SjRdW|vB^Chk50 z!%DU$Cp1>d9E9H=O`7w`x=ZW;ClRwl00HbTdn@s(`S6XP4U|ORe&)evJT*F+{0-y^(P5+mVlpIe9_<(;eixa^I zlY?$$DCfaaoou_bi~sGqfMT%yx3}Hbi!ibaEFsk<O1w zHFh*Am0eL3Jfr%Gq}X=`tBIS8r-i0izGo%uP9Pppbq}8oy)3%Ab?o3Ha6af z0L%NT^`%$SsGJChpBJUOT_IKcuGhZw&7dM5L;JG?acI`(uBVv`^A7@Gp@fbQQx<`&gjh%pSwzFS z&?j#u0$7v@O;Pr)R?$TA6fT&e`phdA<<3pPUmUN-Q^_jcO zr{Lod)kZzZFsIkT{`XkGt5JK=jbhygjo8Af*VEJ}!)wSa<=vUREpSGBJ}f}-Uc|Q% z)gbWB$(SlPAC(`Zt-{Ab!q&Cij)Ia0SZTn_kP^qQg<;c0>LZezyJ1+?b&P+ADH_UJ zuTU-?$zAw3@r_VuU`-;*Q?W-FM4_`e${*_hluhp1HccYFDV(GNDgEzK+-NTSu zL~VyeoXN076U2S3Op*n^l&@E?H1 z;9&{8O3YJ^QeDCDT$|6rgs@_FMz5?0mGcu;h0um-wnr9r*Yx5sRmT*ZLb9r#nixAO z*C@_2_c&8l{F2q!VwKgL9e6@|KXgUhiB2rRw2M7VvkX{1Fg6z??2Ba@a@=feq?(Yk zuE5L}i05!NsSv+cpCI7D>1-l+Y9rX79-h+~h$4whBzDc*FL_&Eu6N5H55?j8dK#ri zz#~W*IvbRTuOH7lb4!ISHpx3lC0C^xgD1!&)PP?w9=z+-cQap*<16puSN%SaISoXQ zk9l1GS#Q}J_rqn%e*UJ>diA>D5T|Cka0`9F+CT^tMR8a0R9t|z{S9{JuC9*;1KzkK zCtV6j`YJpXS3L_b3;5*u`I#jasMW!>@OZv?w82TRoTB5Yfj!Th?pT9*9k)V#x`exu z$GTp{PVK`ymd*Bm&JRCBrMrb;Bg1*b|LgSNGh1rZtDW5&ZWz)=d>`=I3a|(MuS;aJ z{oilDSCVDJ5em%zUk3@kZpe3N{@NJ&_sV=q?sp6EHU8J}QK!s@;tzaMQ2drI6elr;Ev)`^|KYpR&>je|kO;N|1HddhNGR);zC-kXwwNPrliW zZ@gh&(<#$IH^XTTKvYmPeXbuo0W-4}7wb)qX=8zprWGH70<`2rh8dP?12`n8&!@Vj z4g8sBuzNjW8#uNZFz3LpbYD4d3~`m@Xx@O^87rY5Gi6Zctv6Hzpxy?PHg)`*!|Sn4 z9vZ~o1k$)fS~urO7umsoY$gq;ay=e7=8tdzhh{}7<*>XEqKQEKCm-hIuA78r?N44b zJfzIg4W??|F7qJEfn7@&2)STZxjJ+;rWFKh#0}ym5fl!68sl$*z)v)f`zn*gR#7;=FnBXo&bFdo3l{cBvI#vpIQZ5$#i z6J!B?t-tkpdSLzpum(W~hiL<>J>DuqguHgY0S^V@z#xo=bj;TgueJN(%K{6>NC1|z;1~YqCaHzu!;c?7 z{IHe(p&gvZeY9$JY%N8gj)BL(qaTk<`|oNV)a=lB5F)>0^9HjU0Tztt+Wn1l4q!wf zoqH;1sZ!>q;mwJ;IVbIl{mo;W)kSEBS8VZz+&X?sT0WUMSqH5M_!Obj9Cn;5n05+?Kb4mzI|lN#u>SS zVDcBKdc)S<`=GsizyAJP@^`I1Sy`t3n7~DgOpMHUR!fV#gQ6gT|MaxJ zHv2uetg(Vjz>!k1*#1+AA}7HhDn?J3hSkNo^T{OGLRNz<(G4Are0|!z(7&I1AWn-& zV^G}GIb>JO$-?jzQwfauO!rQHZ*&E+_$d=pR#jC&SFs2QOQOIn5k@|iHTKY~8+u`V zfd;&3YS)Qz^6~hbADipfGTj&c=T^xNWvVCxC^@)Sl2jmVh|~n62x9@9c#9=C1*A`x zoD%B?vCuDpO`1~Jwf+lA;o5Gep6)fup@D&KD9;dN9M5!m;^?TG<{r_rf*Gb0Zz19i zUrV0Hpo`uG6gu#NCrjwDkoE=ZR2*^!^BnBKas9=?sMe^KWmbFne;yW~8VJ_WEWXr( z)`)Hh9UG%60e;qluUY>L-aiG|`2K@(Y*_9i<(0Rxc2dYW(7S2`*R;#v(WmiQzzzv_qhQ%f%w3v9bZ$?6p;`~6CGV{9Tw78 z@BxHrxqMb+egPNKhSV!;Ffcny|$+EN(>DT_*g<=*%-uz&WQ-YQfM(lZSd^7}F3y{Sx_O&Y1CIV$Za$#V(ml)?pOZD|M4003?%M7U||m?A6Z>pN}z7C>a}|d@uKoqUq(hoE-$wE0}q1(_?Xb{ z2kc`OJy=&#gxM_1uwuKx9uaYYz~~73$fIZmRPei|Crip-| z!W1z5ki7X87wvUNW)gnY>^cOX0}2SznLz7wf?)9eGY#$Atuo(gJ_33QV6>gVnekaTA}9#!pENTMc0o`+D(>J0%G@Y+ zlZb$tDH$*kF84SinQ1|UwB`l9a94X8n(_Gp+z#kMXhE+xJk3vktknZx$-)n=7XBxE zTEBu2-RIXYaUKeMgy=n?t*a9~hS7FZCen2t%#+eDYPK3N`6L zVIx9-PDMJ&2??D-adh-H3TwN`ds~OJIls&DpyDPQLILYCTZ0exy{vzN=8WRw$Bagv zOPJG((_g=aBa{+Rp@(2@5cb6MZyPup4p-RO>w)Hai_0^g;<%mrdFza;&4pKrYkOui z;A!I;Kq{0~0hbUG$pV=U{j>`Au^pNYsE<&6V93QFU0mep=PQ$+~BLu(7iVC4;L;YM=$K&tW5mE?c zaTlP8fQA;Heb4lsS;y9hE7E_|b&e58G@xl%-JydX9{pnoj{<2U99%h{>YbqEi^TJ> zv_2})xi<3AnGP|%2xS1h5*X3Z2c^)sO#k%jEARm*`#u$?gNeTo+~KCSwo2=r=Ma(D z1}MxN5)bIcnt#R*fF_pK4=BDYYNH?%#J96O`#|ylqr0bvwRP5BR1ylqNIQ%(ZXZEe zlta?of-fMw+WCJN25h`ojlOSABx*zB2wq?Ts<$=$kN?hj|7<8zfXyq4aJ;)WxEromCBLb8EJ5GuHO&q-gY}WzFE_Ed^7!o z|H^85;;+3E3yk7qPwgY8WrV;MXu%M+J&`42%FSXS9<4wO;2A*7|0eIlMH_;06f}zB zKmF?bddF)5i_ApV;9#H+Ah221m@fe;wFEHNE|DozEawZDR?^?z7qJMo(4Qvww!dGF zJmo68S_X6z73r1@y_MdS2nlryv^`@{9gA@<0sBX6o*GxE4jMv5LtGD&lksh!<$vri zEPJPrHx`qo_5AIX`;iRMHy^bBo(DW@>eVlzCk&|<3$9;s!p4-jl%)4-jX}LWaD-+t z2nj{&?(Y^1zZo5`z!ID$qQ_VJG~VI>N}t^Fm9YQ&ubG7Ot^&={;Cdb`sPfXim7E*e zzmZv5+qPrx#x5$No}BD0p;` z+)XI;LD#OqwOo*L358)xF#Yrt5F+MKfY1ep%N^(nLx$gzMRB!>hM{>(GBhY0-nY>mf{`E7bws;*9dM@O6YTp>)dCZC@;9F~5=2>sGAN!7B~?y{ibEYppA zPc7iFvu!wO|KPhZ$7w2TA!j-s&2Tq>(hXi5KPtprcJQ9@ufpiMu(OE{qbIO!%(KW7 zQ!stuPy4@C-YCzs$v9;$?7gFe((RZYPdrJfLIcblsr<&x03I2_$8R zaVAt$s=1icY6d={nZ`)!rGZO3qHY#*_o)Q{P6lfg*qW<@vC^LVOaS9%V>Zy_IdI5; z>*?fdzW>Ag8h~h!5uJ5NM0Koi$e{Lc^}Ubh-*4MqWj8@B>wHDJ1(YDpIqr8b>JUK9 z_{N69lZ*k6J6`DtCeJ%!$X7kLZ5B(0%ft;;G?JSOq6N13gE@Xj(Z}+)Bp#l@{tAh7 z^^G%pxbW%i)sd0j-e6O_6yr8yVpxxSO}kBH_yuRBN-`;Lc0+lC3J+?^`y z@35Oz+_+}Aa;=!qX(r8ycCOMb9Yy3%Y~fBjSDwuydo&tK9wK|g%4Sg9s{C35`g*mu zcV?ft-z;+%9tOHs87>AoY=yz3V60NqdJoEJbrTWHzll>Xe$xFxtGz_p_QUIHUKp#2 z?w^T^FnBl@{4wbX- z;CBZ?0gs7qpgS2HM~{pWr%4{)uN(n^e7qd})k}L-HpRjkSfHD%ec~gwhbhE^P_Y@h zp;jf9zQp>73JG2BxOQp;o(>lh=2+1T*8x+hN4z4eMNX(NyAL4UxL7Jc0b zk{Q#AfgIx;P4JO?G_LTEO1rmrjx1l_h9@8HEw^5yzfDv^&Jvo@3ZUb8XYTEAr~C<3hJCqZ%XK zlBtP3_cEi2zh})8+BIAv=AMR%q2kV_w7QZk9^u%Mf>f6&a0C^Y0-{QHCDWe;o!?9C zNZM`wO=pPv>ZC3{ez19CesA~r@#*p2?C-i0qIEx!%Vez!WlJs}=Cq%lyZ#e#qDryR zUUZk;GSe8YftC2pH13CIG7V?tpAj+ssPMOi@)z6P$m#L%0IaE>8)zS=)t}jb<$0u< zP`RnL&(6lCEx=V~*))qFT0XeV-M{S8;Q4y;EuF2B17>~pdWhKV+7OQ{YKU!^bGUy` z_S8N)`wrMF-qUd@ui0`8Nb_nr#*pF#I>G2)`0i1qdB`=@Diq&Un@n#VQDPh|dV47F z=+!%AwvP)E+{+HMi&K7WRdDMhxZOtk8TUJi$cv zo*AaM7TUz3MWLUczq)uWe`DNdL@5J)@?X9eHxMzb&vmYuvA5PQM>Bi>o=VCcZzKro z;cFdTeEZb`eT4aDvZ7QusYHx1XpjhIajmbO?Y1?`A?)d&soXXFryg!ai>lI8UO|=v z$OdHSopf2lJYWwYoJbSnAR8q)Y==Jo$e{uA-HY>vT@`<$W2L0df^$yKPI#BBBB#x~Qf2-_((k<3|^~kZA9PGXEyGO9a$nSQeF1gq6>Jj9Z zwESAepWEJR*kDi`hG!2)IfA1dv7N(*SFth486Q^4mk1NndhCCHOt`@LJ#v`qCGNPP zB})^3^s5zBQBzs;i#!e;_A8Tre@qz+YCS7zZHHXG>pSz! zk7z0!fl&$$;1Iz0+oDTdM>!edmELc<{_D7|H6p>t8y6{+3_A5(8OPf-D#%tGR5TtrzI0&a~lzTE=_b z@ei_qc#LU>7&Lt|tnFWaJ9SXEnoVsXw@--FfWn|2;2aQb-=^dGfp4?}PiJMZrMlT% zqdVwCUux_U-cDLqO_u}J1ljYj)3K{K$MstbW^{v?3ME^hq&X^FriK0tFh>g^2Yzrd zBy%unRjNlS;MQ*aWq=VNX$jdswShqeE|eu`_Z)Si_KKWH89;Ui@{lVAe&K65Z$VO( z{Ly>;7q|l?u0QwN7_D+|cSc9@#f+YP7x4iaM~nu+>kb6tGBP#w`egU~Hrk?O&?U6J zrIXy*$K2PfON@U={aRS)#`a7(P8?s5JP+ z1YT?*_DH?Xtse43qu$w7wKc{d*_$HN;B6R}2!S6yx*g`SN=q>x}*!7-2hlDvStQ%HTH9@;9Q4H9ku zAjq1lbe=p*G9tsnH03Lrz=NBf@uFG8s&#`TeSOzlJGK#~&ua<&)XSB6JkVJd>gIzc-fEV3 zOfgQZiJVfDrH{wDs{!s~m++@XOcF%cXbz_bQ}B6j3YBKBPplj$2&L5w6zQ+nb~hyp zme}$+i)zt-?pI|&b6ab)-L+Pu7u%w^od~?aw~&Zo5D-B zx#Uc!6$#2kFNRYe21r9#Z(9?Blv22WoElKt4W8-u3$$)nsH~#k;i7u&7-w}_1!Hej zz?E=Ru#Ta4`r%uf#1)C^7HFY&2WJob^h(bFT8IF=?V`slUH}sQ#2UBu?1elZ#^eP*b5HxNSQr{#J<<3Qo`+ z0{`qw@;_-e_wZ02Mx(^T9JXao z&Sp$1ZU2kMYqzX|QfP;1g+foszT}m73)Mk+on`PfaEEfU@Kw-5i>ONj%6Wz7{jCN~ zAw@X8s1a+>m(^|%ES9X59u3XPSUrB#w-1 zd{sl8N>GYSS9JZxd|HWKM3yhHstxO9Wm|)7OVrc7c|+$k?yj%PN&lq$K)o++0)rp~AoK0N)~kaJ=4V z&CUmhO?^TPmttA$QZt~bGP|xF7hl6&V0`QJS(HShOge$iMVX?v_7q1)B7nGEoN#1h1Bm0tuzZbbL3s6k`?a~lWjCi+lzvI z2Da#p7epFDogIT+mp@zKues=t5*!$xOn+RPY@c2x#kjQQLhZ+-uts{N=v{ZK2~@Czu6h{owKl(PWFg zTcMZg&KG17HE0Pp6C}-4n(lZ&FERw9H46Ji1J``nb5UHr>AJ%C`iqPwog#KY6Zslx z1&TSjKl|;(CxT)&yv(b>eu7DN#Gu_Y6}RozvjTHLk@Dv@XF8V#x*w;Kk*ATHE~kIb z8!^y%`jv(&sPaQ#;3d_)En(F_L39@9?=pAlp!ja9O)e|YsI0COlJ9jSNs`4aBI(xM5T3sW!@!C-XQB3%uI z0mQZ*?tCAq$8+_a8+vd0|AnPM{L46NFL{HkEBglNQGpREi=warB)_>D^;OO7*j{aj zV_9=)L{$|8Zf$(AteViq?_axdBWa-NGk9QiDW4}R^O7}GP8XL_gr2Q>d?@4K%}$gq z2b8)R)LzGbQubQGf_1LY>v7A?hc#LzcZuQ9M)#R#PaQ9~^yloAMse{B)uS_|JCkEv zf(CaOWY=q8g%4&R0sZ&jv&4hd#;p{;6|Z%K4PPny~m8H|Gup_XSC zR@epEtfq}-6g5uBNKwl@75MM(Ep!HY9Avge+fL$u3{s`VhR+QZIjlQiVuk5?(>Q&@ z3l#G?Ce`7OK^-RlhG&53_zB;Jun-U>$1aKXSAu{-bF}~)45VNhN(Mp)bmB);j6w4{ z1dR*-rAts^1rR_o3ibrPt*v|p`Jx`)sH0IC(o$|!{55A2Rv6j}19cNApiWJ_Ifk-X zTI=prAe*f<{M*l}D9CS#ijeF)S_GyfN1T%Elq=n95Jf=Op`zftON_JwEy(+FH+!(S zVU&tVp;Mq5OE;S?mn`x8a-tBoLJ24gZsmnFj)>F6ozI=I3gzo&U5cX}Y;j@C8p$tM zh2D?JSo+xPi7l^8X4KM4UYLmZTPf?QUTCk-{JerLSpZrcZ{lcT3UR?ZiDQ9kmi!VHy!SIvQN- zt(-uXON0Wqw*}z?TMOGJ!Yl#Cf@>YD$+>-filAmu6Mca;Ssse(H&9tNq}!i4DEliD zlasHlb5VrB|I3(}yzFN zC}Xia8k3ttd)d9jVXC}>#`L$&Sv>S$2;Z9CzTukcR-Ca6cS+BxI8khD>?lvBwaU!l z_fOAu=-Y7knxFPM_m=lvz0W$4tDT^HJb!ogZt*a+kQYIR3byT~oaw?Y_m3`UQ)^{H zWM9a_Xz=ViwOE8MrO!Etk=er{s;@fcZPD$8NLU_zQ*q0xs2KU2 z?<0{W+QeeUW}rZm-{)T{d+il;w%)VkfYLd(?N&w|Jc(FWl7XEleSFyb{VPK3E^o0< z+I$J%rXWa?tl(2nE&6l%Aa4xkbzhaQc;t1_n5_-zG_{mbnfJ)@#pAyAgI>K}GD1lzgcCTe=OXN%A?! zwD3W2$UsSk$VQMNochflFE7Ca5qQ~BbQe#_tCzlC7w!1zV8!OE#V4mpEJwK!ehdLv&v4cSx45!OT zJS_zGicEndN}R{h_wbRNYo$OlG4>m}PRNb}9uG7hK{M~?@$qZ{PHZ0R@`k3Q`iE*c zns{R~>5kYP0$*NuN<%yRWiY8i!KI~Ta~gG1mo4@cum!f>c2WDok;kjj<{;be%Y5Jj zws6270w1JUzY43(SiKGI60l5!NGL_)SAHpl6NTb?eH;4(!Q+7zk3?3?)YvT@o|3T% zq^ZF$PZH7eL$WM|loEU;V3-b%jD+RWQnFoX8`M9^FXjEZrFh?qmG>t%HWfk*7|MJK zW(lZBlzSeS{yaWz-*i(t68pv&AoN}K-o1{dahYZ`HwZ*RIws-y5a9HAY|Q`s+*j_| zia1e{3Rb3iaBz`2$2TGsBEUmloc{&B45Us$OM3^f0m;5cSm>`FdYSrX)s;fg00Ch` z!CO`$4dQd!kuVJCq2QcB>kxp2Zf8N}w7t&Nd|bbmNGmyXSN2*~fz#znxyfY-2?^ou zTy+lOva$(fu{H5X1;7wV0*aQISIZT4l|F#Q7Kb!;r5sY|?QsS$dIq%NJY+{m0Z**C z;zkoEH46d|i4anSkS!4G|Do#wb~?rNL*W!#H3`ULz%+!rUa!ehP}Fh0*eg=SCR43> zce)B2^1_j$?dXVvK8wh|n77NsgT2(3Dl3B(@Q}i%gPMXE$4pB81NmwY;52ztGbsuO ze@$cr%46R^`%FD|6K#Y>_bxHB|h5x<6&eAf`Qr z4XwhUNXC&4Iqn(A&PLmkqhr&`ZNASNWEp%xqv(5dk*i@@W9p;;8yQ7eKB z|K09P=X+fBZt08Q_nBRU!Vr0DSG{T7O(MinWL*>gX5<)w`i9HRKfnj>{Pn9|9)Ay- zWe{J$LF3dm>ts7jhJ!-;{1-p?VOIt&nvWK1B0zbZehcfLJSRtkEgC10wOmaRmx>bin4h-s${L z_=}fk%rJ@~T}!x;EBnjc5sg?AJJ!L;c0N9+scLj2oUy`gif@iYh?MU@!ba7OaEwc= z3~fJp*gsmYKFj9$euLQlqO0S}6>*=Xb96Lf*RGe0l{6iNq9rbe1`o^(zL%wYy07iI zUDWSQ=S>Bie-1ouH4H)icmKst*}+5cBabUS5EboqSp>}!CK*9VNz~yjF6X|HbjKd3 zH5Lh$nBJOcepW|@5wadDoTErzU%fGl$g$gz$zbJLxHvx<S$t7$|cIX~z=zK55@DV4bO73Su>4 z1!&yN1SJZIgt0q*p@kn|$E>JSl}-UZk-97j263m4)f8LbgHfvZ3okC7j~V2PDF}NU z^Jw<5gmzu)?&*$FVskd}p@ZFCn>vosyDOVog?#hDrdWu1#axJ5mX@YGtLiGZ#I2>H zQvv65Nk0>_o|61wAM)Y87&GXA4|4fYM;e*BFIi?&{On}6WM=a@1isT8Tqm?$<&4eF z)lPjv|KO}Bc>??0vwLl<5B%TeVd&l{M$4WCmEV1EKYY;U_CBNUkL;gMFBWdIBt7`^ zIgs_j5&PWfJ3~|BkEi6)FMvEV_w24q>v&cfg^ma!pQ}C+ZD$ozM+AtOX+k*E1fK*K z1hbClZA-!EIx;d+IDA%N)pV2jaM5I&&(?Hh$Cg4Jj^j7 zFdqJ{$uN4Y&WlzOsC(;HQ7(Q_gYA=aCWd9zMje@eLCX%UL$W`KQbmOalGEOu2ic4d z({CiZ5!iLna?A>68Eu$`u+0AWE=XE)jd=-2kp)rpMvH+&>v)WHy3cwzGCPKQGHr- zNp{iyGP8LL^eX0IR=$|%86T;#CG<81oPTRR%TZaBn7G47&MD3SI_B`#-6NlBCRJ2{ z`G(`g?;JtdW9LF1CMWzm?}%#^hk2Fd5qq|p7t1t|DY&R73D7hPQ}j+)gs^~uGW?>K z#IN<6Sk4C)1L)J_s;qn z_!_81M9P=PSSj@*VQ*ZR7Tlj*7Lu5zPJhHTtu%!S7nFoD!EybleU`W!oA_8| zs#R>Igqq;=uW!I#6O5fP3p*DPC`anj%K?c4sD5~SPiG8WSG9R3SuUeRE69#{91&Gb z39*|D=ePu>*je!cW=geTNAcNU67a|T%72q4yl*&0Qxd0}bkbk0xdkS%(DH54gsKt6 zV`^$RaOEtvt|FqM*LIpZyJYR&*u%y{VOa6YRr&F&tav}hPZG`P)$HtwmSIYnT7}-# z7^#q>yOp^2U0sEgUd3pYItdo1q?Zs04_GfjGO?;nCc_jEed!{VPiMGXoA$!7`~nD`Xqe^emm z#7|kW_3f(IrwI6q^58I!UirszDSd!r7+44O+e6Rek_;j!3&CE0yK1mIP`*Zee9qg( zMC5s49>v+;^TI~>sPILS!(_q28^y^xekil$K0x%r(8QqY*sem4DN*5mF4NCQjC)UD znU3d7)+0N?oLi3@8?7OEgtIL_-8kv(w<6wwQcmET2o_Q_AcZVNWB%`!q751Lz11Es zPNcJbf4GR|;8h%CWqA6qKc6U)v1fmrnjn&qy|lyeeEZ>-AD=|+y)0-c{&;ZKHdPWn zym(k^d*b!Som&pb5pP@r_>5m`QL^vs26{a+&Oh&Bpx(= z54t4i!!r$jJ1fZEbaVbF<-? zRjdp3M0iU}OQVemZ>hKK5~0{v0mo|fJ>O*g6)r8$h}~(XJ z5Mk4H&|15YZpa`QW?W#VrX3ZbG5uHs;zi+n>l#*_ySiQK>b7c^bo$1K?(Rd3DNvIi zb)jWsW?llLUr~2zBFQNjWjuDiXgEJRhHG^3pR5>-^VaCLG&J6lM@$uJ7wyND`Q%t) zD_r{lrvsMjkL6ZsU|$nq!hX9|rAbY=4~meWoZgYkY~F3$7VdeJxb_43)PYIQW%L59 ztP1i9f5P=k0o(}=&F1AJFuFyJo^%dJMb;LUfh7VLfhC1by?`Wz(Q4XJmx2ZmMRh73 z!a6-Pje2l$Nu@eU7)M*$A3S;YKdhS&8s5o!N z{iR*_CEul=4+d|<88tOdXwxu`JjgZFTUS@N^5*>88x`s%B?CR1sp%x^%w*`nUW6Wa z54jchIrk}>0a6>Z!j{J#ALt+4KGN#?*$Jym?J@a5sYh`$)xnTaI6RK_cHSMbmXRop zu5HF=JA#AZ%W)ZjaH&pK3vmY57#yVS`P?6SJrqwNbu|7kw_5$dyHXwAKW9^|MjH5! z3=B$fc*pOF#%g$G-ss4P8s;`iDPYgaC!F=a0(lyBwK_v2R#aFG_7pj$8fO5FqzJQ+ zu*lTwZ2h}TIeO%6h5GcA-sgDQ%DwB(?H^`!v#=TuC(lzeJln;4AKy{w7NwT9mmsEh zGoj104X!;j2>k>9H0K=BBkKukI1#Hm&U9ARZAVd7ILyoeAtFZE@>om#Mx>MWBO&%9 z1%f5CiJNzha=)quQA9C5WxTI|!|eNz^xzezXKVs`M8OVOZe_wGU2v}U*WS(FFD_a$ zHr`Acf4}{A^l?`-Q4zV|eF8$C%gdAE2H#8csw@eip%hXnA=?=?JqYX#AZ;J_POdvd zD8F*AreY=Xoc$c6*puB^(_4cB7Jn#J#!RY%lmS;h12}pGhR%k${5-FtV3$bJ2{lsW z_u%%9^{90FF!yf<4gKo!RUWTQsFsK9qTNZ@cCK14(h8U}wugSkb8~YuhJBKO-M0hJ za*KWngfS+*DOtdwn@!A|Zb94t9~Ay+q-jJl(2VWvRg~loPkri-CLdJ*1~1hqRXw@g zC)kt4E&2%wn|(sPH|5W)k`h7~#xy?x9jOyIc!*_N0Y&)7jYf~dD!u51qBKO;1C=d1 zjTXSB2+RQ}fEqNP;ZuFq-Mv0PrwOi+=3Rgt!ha9k$DBR=dMD;|uXSo9N7t4YL9tI7Db2n>1z;!#BL(=|4|Skifzz z4Ba)CB=M*^gOX6==`|M<0F#4;j>z^f7lV-joaE`xc5kXW<(`a=yUz6-&^v{4kd?Mg)9^+If^lPi=c8$+rtlPJ z&C94`VsbKQch@0R>bb$_9B`bl8GVQmm|J&h)UI)Hk2`W!Hb-;BpPyB~b)buoM<9QT zV2mx{hS7i$svbxOg5uMZloSL$xL7;uFy?c=xuzV>5dv$2ESYsUE)sl5mip}6-R=brPPujh(fMph$nB}#~j zp&h^8>96KTbb}`Kq<&>Ot$SXFCmx_1aFZ6>EE7PZt6fwkFTapR7B}$5b-qIi82FkEWguH|_gbtaKgR?sr;fl5&+67*rq*bUVWfGrfCB!T z@%52OO=w|&FF+#$F41JNQ>>Ugil4@ZKH<~_SR|TUGoDhpC1<^=jckpWnATDp`G?<5 zTAR|r#urvzvpaUmq>fF?ibt^OfQw=^{VgFOsHP^E^B+vbfjAl-Xv1W<=2SCd<+ zEq}?aa`B?j_>J1CJYlA2qd=~O3OXYcY@x^m5{qXwncDrgl`-Xd;uG;Dp*!bx zSw{Wrk^FR|;O5*`nHCHyQIthAgE7!j%0?X}1t$v{yQ_bOUBDx0@I8)|wA3W0vqMOa zQ2@1r{9!IXA#=n2Uqn;<-?GFNuD{6aux|VEVsVRYJOrh+&ZO~%2!`Flr7p^qab2_M z95Y54FZww;ed`Lpv34QRVc=Bx5>QqFJ59R?oI&0+US#y5yBnj}N!D!~p+uURiQIc0 z;oIu?VF|V17QOIJZQPct^mVM*~+O`K8{$)Bvky(!5q)C@g zqB|sbcFu|3F=jpd2`8r~&BuAIYG3EKd^xg_FS?^7JA2{vO_w_^n=5co7PZkRXU}rb zUk4>t%h#5QuQnW37YXn~<(n$0ih3PO-ILFgwAppfyI=2d6ceaW{t&C1;L+))c-54f zM$;`K<#Ng>0$EH_{9ON+Et6vM`Qf7Y;=%eeQGM)|F8mzxDG_wv*S!H?oc&SGhEOeH z6v4_5K6cJSdX$C&wWUNZ!SQmTpO_;@FN4j?Ioq62mru1T?V6~dn%K(M!`yv}83lBD z{5kFMOvVcBhEt{x|JE8h8hCQm`7hwEUh7o(WL~Cde%!7^K5F_)95F3Sa1SX&mD{!x&wYN(7mu<1#in< z{Vx|F_8x-}nZASo<}fy~7%4Cs3eIgf$hyK01;k0)Va8%<+WaBYnBv4`=oV150y^YW zV^~VD0Z;Nq)cm?RpK&hx<3+zW>bW(Zud{9&@{F#`qJ+pq?hEMgm(UyY&j~TtnDG~& z!|9+hTLny=cDcZptGS`^RjtulXi@%3P#jC8(N+`471YuhiBRl~G^@j=b=aJgcR8-= z>#jPs`P)L)KMi73Fv2bV?PxNSv0sOE#W(Q%{Z+ibU&CyCc$VKq8R!Z*rDLWEXZhcOk@8h6a@Hk$Zvlu*ky39G9mO{i#|Y==FI2CPSJQpvqQ}De-hi~sf}bYi zKJI^obb53CoGlicf)n)tK1w?%0?4T7to$q)DNRomx{2Z&MY?U>dMIVnPDU@Q60X{3 zQ*FyzP?d_@zT+<-lz3g`pF{BH;65bkGPb$9jFBesk`dzEzx1yEd>^j*hem~?QvLHl z_O@fcq!|8}8}iS;DCFHtwp9!Kc`nV!&4)RpiP!(7s{DtqQhM=c$6^nmMcVvk{y!X* z|9q?Jisn7{e;;kB%%gHO6!B00&%>I|DkEC3w8Iqrl>PBN2H+L3zPV*a)%W;9^_q9> z?5_=f92ykS4V0l7*BL0|TYXi2{xPpzzrc6sJ`9HIqKv{ z`0ot>EZCSoRipPE?z+utJV4q#1)#}E{Doej=qeJRjcTM;BJOnNwqW@;ntPF#h6J!K z$yuqa6|pB9z7kLx0^|26C0#0lh*i=9dL}eph@R1IwiUoflw6R`D`?3*%)O8}v|OTb?TS13A0kflexNkq z@Xx?@oSmvbV-c*~V}SI+M<<3%(@z`pK)(74l=!PKR|2pwRRLr>-&;^z@mdyA;=i?a ztHfc`T;E);dZo$hChP$leQ}%~1UHj_(xTm`zDT+ce8t^j%!q<~ZHn;wTA2RLgO+vg zQA1Lti#ZD^A@E720#@&q#+0i*^AOIOI@YH&O;@0F@cXrKclP0woJ1pPxy zk^N&gENoX{`rt-#3UXY)36{{HZIzhZvb(|fpyJ#2Eck>pB+25}v*;e#9&6q++53g* zEQ73yx8f9u3Z!a;oX+BA=9M~v?8BrvE19AG_?Z^$pghs^h(M@jX=~;0L=MTzv=oJn zu9m)_TS-RK&wdq-s?#NS4sickM;s#)fbG&E3&4G29=Wv#;g%NY89kxigr(f8jtHqo)xV)u#<0LcLjre7l1_$n`_-lKGJHyz+s5E1=Oh7U( z>4<+<=4lI{lg0{V>Ze@SN4-9-k`aZ&b=_0`QS8>MNUC;*$&X#?BEM*t*hPL0VV~_g zyXph-S7A=c!+_rl)1RpEb@9^BWzX;Zc6AnI4!GC2|2{qeT8U#@C(UMDjja!Gu=z10`Q(zKZAu2nz_4r^7TN%;>UgVF?ARFY9ObqrIk55d(b zYCxZamo6z9XORLR+)A1B`)D{1LpKUoLWz3Gja?zqr|*)EX+lt^mTU4m0~(`uJyOJ_;HS_A&9(`@z^c%NK=Bm|)8}fh~YZnofNz}b$ z-C_+p!~AlNj0lzW7_dWyC*<89RJr1qhMh4 zyT(Nde|vNBA1l06SnAsa+X4m>Z>1qbO!3idu%P>0mAJ;R2||TJg;0698>PzCXhGyd z?p|pi^im8fmbyVA!_#O_DgI<5rRw1WbwhMKy-_n1Ye~dyvqIrBhuz=?@1@K;cYAFB zIwH`{8UaofuFA-ZD_+ZAeUefjw&fcL=)EpvI(bSttCL1&0UIo?lVL8g`WLbCaR_cyZy;7avUsA3$ysr`J?B~tumf}@X(*$1x2^lmg`UZVn?fqOaruB~1Kqx7BRkrt7(EkeGh#|OgT9sTcC0%zq9 zvX{Y$RlP#RiR<}#*UA16N_juxO*G_LK$Z91q4d>{NF^(C$(-L#Whv9jzpq1&4XF=!X-N zN`g)k0t7*ykBddXf${@Wt&jSi(-not1I7!Ur!yc{RS|!y1YDt!GRs$Djw9SvaLIs9 z`Uz2h8?b!g1A*!HbC?#u^#E7N;591gA8r6PA_%0=np`1Jz@fjUm3pTdi3hoz z;b+rqO2~!#S_wl_R&H*n3F+Q!b4(0%-Ra3u2KP`qXMee=M z9jW-Iql+QajaKyMZaPuk{+$>+`8`E^@1C1NWT6S!MMx9ThM0%7ziomXnZqq0tKL0@ z%v`=3$x#b4e?Y6UwUcqm0vPk4{cN&`T{&u3Pkm>Qq>#Pk2L4LmzG<{-@!9CfTA#T# zdP_w}(a6-f11LFAvp^9F_2}D5L_Ht)+`?luxrFa!==3D51D)qm;IAj5HHm$T!ctO^ zGc)&`Olt5=wdt;_kj%Iry75Po zoTt+&p4|+GK&+PD_^^K@7{Ty???q7a?Kbuh znR^{C1V2BA(}eK^NcFH-fh68$FbAo9Z&qWBN5!uk0gb5%zZ*Y?rEsO)GOQ^r#N_Xi zwP<3BTURhiw?}t`UM8?FD85rL0T26m+b3<0wB0mCmCO)(R_)sviME{KK`oeSfsZe~ zTvF;sqT0`Io-g4;bCCFYRHt(F z-u>Hax-KGJzx01T<)`UK%wV66-O58wnz&Cjg{FxvlNMoy878 zN*a3R1f=k4BqXaqTsG~5+3C{XA4E8-;mS-{q zkDr}!gPOCgtpxj<)8N(f46IUm4_>1(zY|A;rwDko;wyt=V&9@JH;pUUG_H+*q6Bme z{5kZHf*X>WS)r&PDZg!w6EG5G1Ti&Gy5I}vzVbQfsQf|ah0snYG2Sb_@&%^?Dhu*7aLJH*nSKQNU*e_=psR}c!94Tk9(xuMEBuvpjR zaGm+<$B~x@IXzD^saU+mCY);~eai!@>1pWq28MfV3ZIR&5@=;eKJl>o`tEi2Wd@Ra zonoWhY=MK+++KD-@F-)@(!bFn23-V~UUBgKzw|7rPHX@4MKNZMXh<4?llrq|#}_6O zu+Och^or=^MUe7c%f0%7@DR{`$wz;yHuk{!xdW&Iv`E;6Jg@4S|48ohIyb+2PRKpXTFpx-06127{HKKy^qCJgWZsllp@xoW*zV zCc8rjtk&vqvD`ylpyyNoBT}9yG_^q6_ix$pt2!^ugWqeY<6oPctTo_KbEs`as^nJ# z`jQtKF&bUlA(n@kLatO+!8Q%rhOR_Qjt;jK6xUM%?pGos-}pXtS7VxE748wEM-+T^ zffOAWFyxei{DA~?7d~G8Kmv}S2z~;^lF$Ey%l?(y2~g7`obO0^4vawUww<0=Y%-Bh z#4lgi2o}>&_hq3?0*7p&kQeqg2y=B9?;DW{)}1%v%*;v zlL8#)I}=LpX-9QVt`ST;N)B0-D|IIGz`mr=46<^5bz7e3iPWn8VJWVLp8qvX+DoDX z%1XF5iEj3W(b2tVtFgbVhD_4R-@@5uyC5-@zj6~TicBRex%l5)suhK0>bL&Rg8xuz zVki25eKjCr=lZAheCvH-uuSDMsiNwZlKN3vaWhZo9=OUXTw&|@0+G9*3GGyrXSxd# z+v_Q2X5@l;i+&bEkHMwIUTVE+q$Sto7mhjeCplZ?6-tUGHe7?B0d5w|x4l^#bU~L}VCU$B(3wW_>BLuwCjF=u!y@!r)w_Kr_ zGr_#112%lRp7ZNEGW~b9qn(7f_LzIBW(S5?TSdF!Qad9RsZ_t43j%K9BUx}?$VIE#5$Y=~f|uzkU$b{g8Gy|>Ib zkYL4=bbu)EiT-mljXx;mE`P~0r1*;+Fdq521@5o^0U?N0u9#H$3ZD@f+e&>(Cgvfo z-gd=0F7AtEpia;uStcgtnVlouFN?zd3sIMGF+S=Q@9ADBRV-wtEPbwWyUO<4S1R7c zhtJ5(?w$-_ObWPT={pZmw zGj~Ma{p@;hLrg^rj0xpWsA4lYfD6;4Uy|m+c^dSn`sQU5kC{DR>gHX$w9fC#7s06n zOtltS7Ry)re6XS>@l{Tp-wWku4{f&J<&8W?a>Wf)UW?sLyTkst;96wP>TDQC9A?}F z=50}?_zgik6Lm~ASPnz>g_fTdBOT#;itG(;K22w|tK_YqwI>~pDUQuDPw4V;ZDnAu z)RV;96<4aJSEkL$XliF_G$5|})ZA_KOAfC?5%SQLEmNLY?y_pDSR$;miZF5%-5-Eo z0zSt=21FF$3N40?a~V$Jjw>dl5W_rEgb_hcG0DbC0mK&RX(D{=AzrnBAf0zyQhjOM zxww;8rN~bMn3T99a>muf%{+JQ+Rezetc~L<1M+)Jw=ZPhQ_jGV*#x}Ihf$l>WHtu4 zAEy>ot9GsX5eV+~P{1OLp>)q&K#duUf}(Z$%^_H!2_o+-SR<;t*Ol+q*oJnSsmguf?^t!f(r<%^X^Mf74vcmwzZ@@69bSm2E&=pky^6 zeh^hPq2$v$AODQT;A*H4 z4IZDvV|FaQ{`turJd3i?;lqd4tc0ofCKpFikWE&u?Z~&~=fAlp6x_D$qLq8btz$Gj zH!||wtQ9O7uHWw13GB7{g2JdDjA>RUj3sJjJnSTL^#18zn-Ke7whKZ8(kk3=)&pMe zfmotMNZBH!h$yhwgj|$jCUub8fS5rk!-yyTIV|#jgtpx4EqTR)BkrUFh!jKDHLeJ? zmGN~n;=uop0XNNpCNRwd@3s^#K=jeQUU7RPpR-RMTRU@}H}>$T2;+U*3j~?K(s%wl zoHD@q<%SW1edJoT8|Mtl*;%ZIllbX%exSHy0`;l`#lbwmkEm2_YI94y4mE%X6hAoj z<;D0wouJYc$T@)G$gsWQ8ozNNLRBMm7yQ_O_EIyQahHFX;fLaxGml+4o<5J5d&<2M zob(fQqX3`T(lxU_??h`W`!r08?t);fx2Z zI-9UZ8!ci$Uc7|m{}<3C;9oGqh95#VO^LcGp9A>zQ-DD z+#sUH7|LdkdaI@r#b}gt0As1`MRB4VkUP?!-Z#N{;FwBm3&Z*OnZ8L0~7TZxD0Kgl2~ zxXUhThV(xe;v0>Yn6ft!>2ZY;E$l$wuh{K&IUA9VmYPXin@2e~46Lze>UAjZsHdG-);nh`cF^(=cbc zGQ1ccfA7>r0#s5R9y(!hsYnlcl}PorEDll3NI^j++uqXBQe&FWl&PDi6PL~l4RD-r z`Fyw#c~u(6t?1n>;HZ;BaxFwZ&w0*G5q^Ae=5w8lx)bM@*0&GAgF77n;7?|Vs z8?@~$Y3ZCOM6~_nDmK83l)oek#1CbR!!5IVRb0+F_--r}+CtId4xXNJQ%gS z|6HTG6P!^+s)}?5=C!B*j!h!A7a(Ro1F40#H!(V!eiB8YIrBG)Lc#N6>~l~pFwMyR z_};R2ac%<^Dv(YIYJ0;vN$FizW_1xZVaf5we%zjfM^P-{_aTgI%b)tC@(d{f41~B9 zxK{3KwcN%Jd@SD5xZpTEcIgX?V74~EFbL)iSD2!$Jw0ilI1fakprD}NCkG9$1}>eN z)O=lvk(~8j+kUxSvx*J@^sw4v5jGS+h8UQhezlkpY$0;7-7Pg!p(r1z57Y{(Pwg?~ zoUR&u{NTutl#~Rj4X{^PT3>Iw|4IhOIII#A=xqh5|CK3Ge7wBW#H!eRj?do@3_)iU z5pf=NoUqs{G5bV;Bb|VK&r@DR_XJ@pp6K0E%+2q+)n79bpZ=CjaEtNghNPf@Eoj&<3c>1@1w;;@ zZ3o>Z&OnYW_^(^9_z_vAJ!pNDMwF7uwckB?*a+=jBS>Qa1V&KdRJ?)@a+wH4*Ky}h zGeC9kP+RO={(3ZfOhVt>dZxO+hN>gA10oyumsv^P;Nm<$31^?p)>Nm@O50@PU+>e)< zE>UkvUMGIa^?L?;I27^%C!%24NChT~;?Ca*z{&$mwK7fkpkDa{=hX)lp)xhn z2c{#i{jCO26z6Q{$`TGQ0!9y@xKJiM7ksi9j8?l0lm;kBq0i#1GC*SiTY0cm0nIxZ zOlCN95?mC9sKZm`suH8(r`>Z~KfqZ-kt?nVEFMAd_%B(n#wIjIm zuDk&HDsG$yvg3ChzJ0KP z?6#XYhR|?77;652pq-JlAi#V6R>&TSl$h6gDKBq%N!id&C zgq7M^46r+SDqVpSR|5dIwld~d?esC)fxpDaD8D=O4)-%xQCMXNrzNC!U#5PQ?fE`h zI!!A}Y>VSv$4tRS6RF_OXBbD7yTMP`iN7qmL&5Ni?TvDi(y`0Tj6=-Tv6tdSBqdGu ztTwIR6W2}()So{5z>XeV(5$stjoL8i#S5sPinI%e$kJU7iuID-ZeQQ?&%N)~%J`My zo%Nv*8IXs>N3DK&_~n%`we%@S6Z5LV zf@Pe(c!HuF%D(y44?^_Cs`s@ww;ee8f#yzIAp?>-2*)!#zHz}GTtVtC_$uiJ!w{Y# zp7F4ccV!di@jEItE&VlV)g$utjMs#dysDA3b~!!v_c(z{jQ45Wd@GmOs{g-SfFKco z1<&8=%QoRN`Z?=2RZiz$KUIWedzC+Xv|~!j>lUH%z(A_>@dNWrpuF@hfWdx(4X=Al z$)b_tJ$1OAcA3ld`9>Si0tc5*J{c@UmCQ{(O zoEh_(59BkpPya!)90}T#_%q(`U`&4O9Kn_f@`FBzc~{c*mQ2*qk%UH4CL#V_Vq(@$ zGR~%A7CWDacoQ8p_`JE_ak&kMN}lDc3?C@XZ}9M}Czi4D)4d4Or|5Cr1Lr5fpX8;6 zbZuS(kE|+BXLTh;&2JQ=o~z7ESXNy+%n}wTq}V^Zlp$VnxL@}`nS&*CmLV0U_{)}G zn2Tf~?9>f=u}dBQmB}ULE=Y}+sz_tlrBpwVcWX%fb5NW=91=KS0;~chV>Icn&XpqO z?@}~G1g-uPlnPC83>?5!!rxrOVK9JOGLVp&|6#iz(5Ul{>-MV^T?=aLNE{<8D}D6_ zW{R{f)M1C@2lvYr0gtYQCPNHxf8|Ax){}j9{Cx51HGO~;7u(ad{t+q)C2Lu7d1TZ}u$Ks(+pm=8dK-koxIgzbMFWNr7ildCC3|#nAt4 zJvjKrdEw6aL-R$lX!R9&TMIFrw~AE`ONFN*UgPZ zov*vWmHHBiLK3YQn{*?Xi9t zKO=cbn^fQ8PL)cP-AFee<>h*=CfDC3N6;BDd6m)hCkMMbD3#9ECdbHTNyOyWoXmW0hrV9FZbELWxH6zo7m%sX4?f7Zi3Qg?8H@+IA zxvM0LBtZEy|FU=7b0?yFLJ1#l^yRc%fu+kOh=wWz6QAC()Ws|Dg(0M=UUJ|2Q1i~Kda6F}W z!P`dI?t)4urhneua5xIs>c}O)_KHGjEUo`_D*384lopxv2M9hn?O)tdmnR#G+#;^a zfVxDgOe^sDDz<-~b%SJ_iO(12lKn?AtBgib7@ntx->NJ@17IA0 zRK>WSI9_fubV1IK0ePscw9PRhNJi-+q9vodJqVMq>MmD5U@UXl`?-hitJyE?ZSha4 z{a-F#0RGV}boC(Fd!+GOy05wIqvKZC*_7p;-N0daCVC)~ZCwnFH^M)6E|mC?J?>k{ z`TyYwMHaVLr6h;aUY>SRd$db_?wpd%7rUH!5p3d%7by?^`?5&ChsgP)=y!&n$A1-z za-*4lda1d;6gbxwDD-ofL;t@dq&amtU22~cqz}U3J{NcueJQ;BUuIFem(f!JlE`n3 zPA)x)I4hceA6uM4=y)>1|I0Qy*H$Nj{{Og6G{!k@X`O%gV$(vG3Ge>jr+@_&7;)!A zwyVq?3EP^wcg!dMJry0DIdwNfh1*9#i+nCgiW0Uri2M`&m)0bPP83$n1Hw~S>i>R9 z6!IT}RKfq8^zUs(VpCAc}(@fz2+8dvuQ)ekR#WCj#=Zx{*rx}PrksfpaO5Ujg>2}_1M z;RT|lcFmoOpacKA#9c~Ea&EAYri&~jERQSHfmJ#H*D>9kIhd66HAqV<1% z56NVBjVKH_5~w}7-nWw!iE|$4|LD7Q+BcQf*6ucan04yyvp3b7Tm2CA4Z*FR!xtXQ z*&VyivESOMcIKv5s?8NUS2nHm1)GH_=_(2#Nd_c=WL46RJEiN7aOo6hyd z>NKrkwb^#Td7Vb7^8!W>net#WU^3h`zUZK6YOMRKs?hgR(C)AS3A?`uB9?mwgmKYO;Nh3q=NJdF|`KcAJ2%{eM1KwWTOyZ#)b0bzE2 zjQ%0`XG22DrCCxP$j~cKLp=`{0p0rTA4izGU?_?4&l19(e*HNT&74a8hLeTlG7U-Y zxls((5ESa3d%N%Iv(G{ZnzI*edM>AlvpCfGzE;t>ZhmEbrf_+eoU9T2N!f`_o5X3z ztljS6`?yTCE`(nSdn7Zaw-c#+Eqdm#hy#EplkqF$fJYzvs>_U z8{_Dioc{0FNpd?gW=$^r5fcs;l6wwr)IJZV!;Uh;t!DAd!i?!D?W~hHiv;H<0@z3h zsUd+{^hPtIn$o$z+aSaA^zu=lB7g##=fQ5{hAUhscR~!_^7fCMvK6| zlRwmis<_v>9yVq5qo(Nxf;CW5dv*3hSv0C4k0(YI_q_d$t-`7to=TIFk&@s~CVbD8 zvQy>w?`U%2<2@ZP*{yiWey42oYK*FDJI1x|ix*`b*7km%eRAGqu=#0Dx>~-l%Dl!% zhW3*4Q!Com!&W|dKRY<`>86kiF^a9H^~h{B?wj=!?nslb6*4Xl*zHu&ukclF(S>kF z7N+Su>6VFG&B$D^6-|COv|PTj^<`D*cKW;xSo5S3Nf)S@wfmdgMPK>>dbs}8J-_dy z0m>Tv%T_nuLJQIpeNFiHkz(_`{U|QoxNwo{n;x853${0s`>{hI^KD8NDf%-f$(uLv z!O6dpWkf|qW%bWHEpX~JHZJQrtD{TfkuGySyyd3gX_hTZ$V$Jg4BgwXeISp;XnQRfMNdpS&RMV(&LKKXp!h9L+RV^A_@+@ynI@m#9L}VwkONo z0L4M7vonyYR9oi?PqjIId|}YxxDZj2PpR+W@ew0OMc_L+0$C{)6#mQPgs=m;b;N#S1LY0ZHM*2ZYADG!U@aKQhpiJaUE4h*#WsDhd-%`#b3NVZ=}OzW&vF z?-2vClElzbGsJs;AWWk@+uvae{IY~}xx$A!uQluaq3EzT@VblWajmVQoXO zwhGh!RB9X-3P+JNRibZF-Zoi1mTTiomrA3!>LOuh@ z4fN>@$O!kYJsuWa8pBI7dKT(mMYa_cOYi0n(blc$cb|kJ&W=VTJY*_7%NlssNZ&EC zg*xz#e$W=WbmkAnF{wU~an#mMIQT%|!j|vhOcJH-l`AO3dwZHjC(5E0ZGO!^Rs#- zB6P*HS6x2UDMTn=soKIC17FqN@!=v_(OFcwfmxB_t(Pz!9d2H`eF%0htb>*7A{-J9 zl3PdArm{Tfuui9iICe9R)QOCY@HUhZ3=t4Z+MG$1Ku_K)kNe&nvu?lZEPN9ZsYwWhC2x_P&ES}bh1cH`e~bH3j;efi%gWE;e5c}>kd_vA zSMqZqRbmq1R_yGj%)(Vhp>}@NKSm+eGsKYWsdy9ODl6z_+8^BLMH#zibDvgfj? zw{9Ke{%X?fZF?Y|on3Jezv0r=w-P(`{$xKtp!c4HR+RGZ(WqXzbGwSumgVQ*vggw3 zX1Fd@xsWWSaB`2o*9EboqRR`nemlTroAsXiT548xQzCrk?pw(Ugme9uCTk27CT)*v zA?GdNp{Q6w%I#FOo3Hh5+vi`XgkhnwTjKQ1PQY5}C%rPEFF?BNCJ_o0(!amFyc!}$ z<+?b+f1BpX146mR#(pXzW1~TVYxyHw4AHRKz;BRU95tVug!Ac`Z9W5c?q&<(ITob^ z@j;AI1aghf$H^h_#mvJ42BXw_{PHmDLrNFFha8prZ9_@6S37%>WN1SYl}M5Efl2yv zYFu%qlp3mB7l_Y=lo$BYGmG_U*;v^VKV_$>XL*BgVnx0MOqSx^&?=DnNi3!iZpKkp&5(d+AEA7KlS1+IY zR`%SENTz5-t67Dqlrv>B*^%F+q*7RsacaAiWQ||L9V=M@TAFi|kdDm9tm;C-zF>G_CNan3$)lp<4MZKYj@%(9!$7s|@w5LMlxkkm1ej z9p$W35ZN(>@aone6RnAruciiaU!=K5Ardk4m&x2tq@{+3u0D~mm~RH}d<*>A&SF7YQYSk9R&in5 zdiryCtlX~B3(`rCG1^hQcSY=S^%OMw8@Ts{@M5Sw(Ov0 zD_`Tdx)GE(dPjEYyyk>HDU1GZR z;3bQ$Oce{Te#U`|7e77Evsqobde|{PB-LF*i!y9hKG1}N4k~xaMAOKNg^#RL$`?C- z&6BEQlkum?x0EsewIeV3nKdM&n7pE~HXy(-NNbhKbKwj1Ew@>MPX!kiGrrI3tvj) zt?~+1QYmCrS$m?VC#voTcIrjD@v>-N*jFME+}+hJerE78s6wH5Tc#{@YM#gSqb`?N zS@ZS9h-MV`rJmNaw7B~-One!G4OxceGv1}g*J*-Tzt$LA2GQQ9E07xFh0bxmx1FqznN?jR#IBl4_{BwJ>C^G!_? z1ep~7#+HpeTfLi`=*K%!q*!JUFj7OE_X5t@041U*Lx4pP4ylLtyEi*>65D-cuoC^w z?9I8p`hxav&(>##lY^u7;mEA*+oN+G>-@Dd8awJFyEi2y+b)I{%QPVTOouBF0*SVz z*phDCA?Y@F+e`N7jEY&cRykjfr2LXSwIdGLpFqc1s*KAx;QiX_u%taMeCSw5Y1Z54 zWQ1769@yIck}1fr%tq3A6()4&{kqsBo-$n888<9Vt55&Rne2*H3_c;RxwC?z%0OY#?q!dD%aBd@?h2sCKw{8>ip5VE0{jw|rMF}Bh# zJ9i9vs_m2yV#Y|j>0h(~G6t5TczCeHg>-h?is~$kqArgAD$1k;QDa*9Ar@uf5G2z1 zpvborb_ehUXM_iP6xibTo@0wZ2-l9ZETO^h_SCj?cFoP__fWo z{ZmsG-WA$haiCy=MQ|aaW({$1;Cv+p6F*54*U16w5uo>=CChS9hHgSTR!{IhuYayA zlP;5FcAtFFW^H0-)^ctqbXb-<(U^rH?NTVL65#Ld`Uja}uEY?7)F%Ydb?K7@P9q57 zLQmJY>XIL4h4!rS&9R7%qEBli*rHueton$kp)XrxmPv&LcVyN?hIkG=kK;LBW8N55 zC~wS`xQf@>ap+;#B4p2iv~a7*zG4@^F%Yqu#aTek99Sy44!8@~8j+2?uQ>}eDT?sy zH3Sfwz?FXJQU!HcY?L7}5APM2p{U)DD#mFfL}wqmRsj zCny`HPv6O^4RM|!K3i+#)3ofFASPgdB^`AXa};!f1iD(;>j5)@!G{`FdcvBisRl9v z4@_VsXa-#+KBTg-2M?Y7XRK}f zXO8MO=io}GeeO<4)f_ioBrOj;!~4$w00Twp!(WV^M5Cv3O{2l!voSZHs6Rt1XVr%) zQj6b4uq-d-yPy3!x|S~#TISaf2ISzoVgQ(eO=aChJ|hhprPOwZwLQm&dIR<};5#%` zy;x)jPPzneg)Z#|z5WyaKFTJ~>TN|X;Wz!gh5_hWsdUcOL@=ty5=Pu`}K zv4iY29vkWHJikV+y=LC8yhV=7vr=o6n`NuNRt}ED_L{r*yT{%m5x%81f^QUxyAbsJ z^cqF+bO_S5SMeBuBtfgiK`ro-vEK;o?(W`BUXdT-z)C%odga#VJ9*HYo6C9kKE`$} z6wejmlxmT5Q-I(xtjh>!L;S{5$#KKNudYUQuV8h#>MLy0-kKDpay~k21>Y8&k}B`! z5!w$?Hm}y%utA$o6;6e;MxH|-9hdT}C)A$&o|(b9mM(O-?jT~h^!W~?+tkf$wT@CMzppKDE!G;Hp)=A&wz89f5OxneCP1Mrd*-7Ebqz^s}#rT4a9VA5dyXVg4JTgW_2j zdepi$W+PP3J|0ya;sPVeuHT;@HJix>e6rg&b`boR%lVJTz_#K& z7{L$xr!-`<#G_La$;KC)3g3w){ORdVvuwjvwF^*93S}}$BnvePRZashO|X6G{iY@ z&V1bY2!8s9XZFJnT2Ppx@3=UO9BK5m-qNq;1Tl=dnKY0 zf$+zv^w_EJSe7wpWcAayYua5z_ra1Kd{-ZXi(+N}6mh*y3Yz+q__O5BxzB&MH4fR$ zeS9P+SfvOK%B7uaU}*y8_ILd=M^_Dxg~}i+dO8@nZn1Q5WVj~}AvDmC60xK}|GXt& z5H^Bz@(@2H!0s{+ozq6?IyyXmTlJIH^TKw0i60S)0Rgxn$O% zP9#pv0h{&V`uSS9teq(t86B%-4KE=`u1jSnCp#1M%2!S0@0+^^>z}6E!Ln^AeK+7} z-??u8yQ7JPh1Stuzac-YO5K?!cZ{z71#8c6a5FRX^oz*i)*cPrCq4I8AC3RfbJ(m~ zcN+m~OjBurR~;cZp~3bYa#eFJPvA1ufxpjoveWVo>eVmh?14(wMCqmWzkhGxLKR_B z$q~4gl9JL4_EImXPgN284t~Wq-(HrbdZ0PqV{%&MX&CZ-83;Dth(w2n^-{$Q%s|XO zb3ApRf!>pwCbBUv)a8G2hy7R&eP%r2M$T!s>d6q@Ss}{dU%pMkQ zgwprWcfof-i#M0Ju0>u!TQ@IxwAlhBW56y-~}KwY8FoIYr&p zwKYB*6Sc%|O11tMNQ#Qp1r6BxxpV1@N^{pj^-8O&Z{o~)-RA8K7kN4Jnls z-WDjPhkSGaR9ZCBXwLW<^Hp7)d94pLn|pQn%kGJYFUVk6x4*n3o9<)h2?GzZ#`C(f zpLr!xGq}tB3BG~tkSwSarZ#&qFD-;Db;N!|D_%*e=^J)YB2B*_^;i#D$5oGpeHbZM(exKW9H+<+pb8ZLeL21>N}0 zY%uR{(^nl=rypiboG)}>N=BR48vP2`n5d4!mS9;-yT#Ux%PdN}w$(W<6!j6$Ga>0y zWSQ0e1m!ruvbqY)vYIwKG57T=*lahDLANd8(v70cyT4}^B!>^$y-6H#6q`%Z^%^!z zLA#^wj^`PY%Xb%Y25HxqhCp8UI^W&Gpf)q2z242`)e{waxwHgql?xd+dT+GK;{D% z7xa(KB+xrbNEnZ~lN>uqz3*PY9*S>t2T7W#r0A{4(5h3?eTsqliC z#(kd^i?}Cacr_uDN9=5iY z`Lc>C8cS!-Ds=*teUGzZWsFtS_&qxOi6Fxn3wn_02G8ZEdaNchY#w zg`M+v$8!ucoCSAHZn^U}U@Ze1xrm`3>^B?k6d@g_M9Yd2Dh1h|lUs4f0CKl>!+$H_GSA*E&AY9Jc`88avrPkWP5x=B8=C(9{)4DOKS}T{GsVCUMINGxR6nQt*lB{r9=qTC zyxXNg`T0}NL5NX``w3&TGVI;5x~t2|1fA0%F5Yk`7x_^+oBH_pSn1MA|M>V@Lyg{- z6MzBQi(0EnQO`v1LiC2t}4evbG4>8M|Z|MD{I|EG1;mo}FRF zE@bRm_I=Hs?AiD2+@pMdzjMy@`}17a;d6EInKARs^Sqz?ec$)%b-!LVd~!rLyv1ib z=F(6Ywf@&o%Qfu9CsGFUsYC8rhlJrpbonbi)?D0ei^7hMFo-_6IV-}LT#lN%tMFng zpVZo`G?c$<^n4l<)-h`|;^$yXFRdy!`h7~!pUThoJjjlo+xFU@cN}b%eD&t!~31@N1pF%(N<05 zReduo%=u0cKlCV!+qKLE{KhGFqQHh%OYzH_46NvlyR7Uf!JR1l) z8IQ!1((_DI%gQ!jSTqY|IOXO)GBWZ`=w7#_(VUwv;TSm4D!MUDj7JoKzW-x{bFI#0V4iTVZPaef?T>YByPCkW6(RS>%EWu#rN?GWV zbn%4;L*o>vXts#dCm=~Z45O_=eLgJRKEiW|;TRA4@^2-(a}m*2phehZQyg$Xs-puu z=X)*;26d5u^X~_|@pR{W%D4hAw6O+bew`w<3kexr9`jo)?3bwqjsRU9kcT}y=~IJdz?(uq082;qD}G0ht`kXyH1TgNHYMHf=dGthlzoh^L=?5_T$%P zz5cMI1fTz!bFeYxT_Z9l6%auyNQYE+#!^yTtX*GSg<(hygF=mbm_;wbnbr8v;b#(5 z%rOmRtN3YK8`D3WFJU0TK(W-wU1LMZc~yyP&P^5(h%!_k3d(ib8Dp4m9FG8W$k%!2 z1&n0}{i69adXv5oI%)ZB z$=Hh)j=s8Yn#2_v854;PcjO3tUo(0HVY@;P|IJ#>SAnMkjHhegrfPu!1h}rJ;KG!V z&Uoh_v7QoEoae>J>9dK{e_-WVU5R{6-_R28ukW|rWf0$AGgWYNlp!PUu4=W2Pg=;5 zy_KG6i+Yc{mXW}AF%V9y|LZ4F9!Aw%{NE>3pg+h6tvO@v7qAfUf}N1p-{jfA>Y|3* z>5Y}Rl+THg6O2AYvPSoMn7)})1!+byF>)Bm>HlVm_egbFTwI(*9$C#LyyHo|OyYi4 z1RdNhVH)4`G|y{pLui2rlzq_693)fjX1$gw>X=L-{f7xiRCGLEO5gJj`Ll~jT%G>* z?!id!pTu5kpFZv7IGFK(Osrqm!4wL54Q$b61~ihT@udLk`anz!;{jJ5uTksxa*r9K zsGl#l>gNnN-^=zaHKVGGcNH%@@IxC=k^w{r1N{8!KP_y3hw7U(T4H`7S6hht`}^DN zM_^_&0}SJ`>_;vUW*Vrasj$m;(cC4)53oaz7*tiD!`PGg0<3Ts#ff3kx_$sjNQ_y{L ztD$!w!6(MR%H_BB$nBbk*|c=2F*ncTdkS5=#}yg z8LCTIuQBWh_V??NuHmj={;|S5y{ceV?v||wt2`wqJpp!j<*C`F%b{I;#}#h;ZzSJt zn|`S&*;~?-(`>LklWhKVO?dJ+m|><}x+?JXB$MNZv?b%QjnVHak931BE{a+n1=)1D zNf>!ry7D9FQC3^iyYXZ$dTKDz>R9m+OzmVYVUXXl^J^+$Fu~ zc1Mzc6q@@WDB6uludh#S$%AlT^H}Ft|7id1X@<@fPkYxgM0lg3EM~5FF3e|#_?=5{ zo=T^Hh>B6Tjq1RIvWzxd23dCREkT@|gfpsABiXtTW^bmEvh0Bxul>>$vCcym2CFpk zg0H9>9ffrBK685PKfglKpvDyG7qq6{Ocd44uimKhs>w}1 zdXA7w%S_=_LmS~$%tmM+L9Q8ZM0OdAYieJMp2ntgRx#H2Jt$4aUlHaGXPp~R4-NUE z+ZE<11rkz**dQY^1@B?z&a7VJjmTXa#HBMCoKLimJdPZ1YdgX74yZMqs79KMaaF}} zl848I4u0!7k4~_9{zXONRN!WCNREk#mnlm@Ftj-?OkC*fU(DO!ZX{??W0W?*(7mOz z+8iu5chF`!-^P#VoU()^zEmpSXy22JyB%##__a>Mw#-pTj&-fvd(JI4`P!;*?u^4t zZGNR%In`7@`Vm|LeOntTR<(ZRg&3Nh-wj zeDfP6Dn(%mpH<&`v=fBOpjs#GxQVo`u3oLAS!6p8C~osx0eUV}7p- z6k(dwWe6j9I}TZ

&WnVKYts1@*rA_IRV8!*PAEhOZ|}QKb%&n5%x{G~ z*C(HwH!PLtl%0>L1^X;ZX8DSxNQA!KKXVPqn`IIDcjMYrR)QKNxt)wb_1pHlr+MHN z%@@i`B&HeWnlI>Six~AV8&ppk+ce{#WK{P!j>gm_=#D2 zhn}%7O&ZpUTbEo*i=Se!Va!PS>Ak#w{^<9YjelH7)fpqYq0!AAVq(wB>KMc?r-o3Y z5O@ox+YOSp8Q@l+&=L<@@@3%F>Zs}tkEw1k)cHiU$Y=DkJ%9yxTsQQ)xqm>Vl@ZCn zrBV85^ft%ZYMQgLqo&oDW3&%LlrjbK$*>sk(sd{>y4|VG?_YU{erL)?lcql!)K|q4 zswTYn$hj*+evi6>`7rfUwu)Rz>xzKUS}2l=`k8`U$_>1?9CyI=R^jsZ8tmy>VSC3E zL=ks(uz5Kx7RHeWzY*kecsobtHcK5M!+sZG!4y=45sUXJqFuSuIx7w>u82dDjj*j7aXVP42aq%PL zz)ukAU%!8`Rh5@>9`Q%dHp%_{n=HgwhLv(mtc>GPqXdpSMJx+5{{<}YqM|E6GM3FW&#y*h`j(!))BXuEzeZ46~TJI=?b9V=IH9C6cMvpF{DUpR4Pz%0e2S+he@I~93 z8|n{@8V2qxkbH+co%?|oz(4g8?9!97v8sv)KD@6{ua4xbNbjCF(6%8qo{kt0vbz`c zHoku#qo_1mhUI0m41LkI!D1*mAMw$vnU<5*%I0g7N=2%MVZSN|`v*dLjAux3@q0`9 ztCMLrN`drd*xJTM%dhrm33=IAU?uk`^N*LYq^i^)bW!JvIlXc1Z43Nq-b>>;pF6a_ zGg}Kj+z~0m0>D;5n?E>9E$6RuGDZ7Iyd$8%Eg>6i8gSYjRipugF2Z^%cKM*Wr;f1GaCVj=#l znXOrcMS{LS5tugBgF$vr!q3m2(N5-m9`?pJ7Twa#gE>VA z_BMXoq$NRy#Busv+cZ;KKvPb~uo(mPM%>c8xgj7R6d%!r|C}G7SPTsO^xbDrFJ2an zFUCO;!l_#Adkd8G8Z3!P@K%3kA=El7W?rM%jX!?jWrZJ2ztBr!Q0%U)Yh90O`T3gS zhLRF$rEV-{0Ie~G31E7vhE;ePWvE~=W#(`AlSB^Di(kL9)>PS zd`al$i@v;L&kUM+IkAjCPtQH&zuDrfz)cO<4P)PB`7qVNLu>~UK_vIukOrQ{q1{oH zB&KGU<^51B)h1Elk3_k#XHxDl5=$$>eRGt!rAWbb=ruD4=qgL1fj4jIzV2A?^ZwY& z-`y2-bW9$)!PVR23bYPL8NM}23O+>2G4lVi358PmwArN%PreL&#nT!Tvkkmpl)RN; zZB9ITLbqAI!~1?Bik9#eEiC@r;KsugknaBwj}`Yq4UjQ)w)a=9Q#=5aN!8S#?o#)*!VuS;&nu^DF(;>F^~4MX1`uzq2Qm-?12Bei1&0OZdYVbzM)d*9^e3L1H7`2BIq^y-{&btvXc720k7ruRKbg${~nK~u?ynH2vO19HZ+FXr?`%5wb%m4=3zaB8;J3W3H^^=hvh!?cW z)wtKpu)p`0Ei^|PfSjPda6YptQK8ZiMIF)S#M0Wtk>an7(_=YRyR5#wpw8c3O|BPC zgwyd*69GtYb$IlZGYfgnIrNvH7hRIF7|Xhn7IdRVR9`SfNiMr{Z`bwg=Vc@MFYFtw zmECGo3y32UyFUZCyNNa~hcfah1rY+OF9dxF)31>JW_cOk#Oio*gD<6bf%zgcDw_D; z{X0|87gqAL!LSd@c!BK?-lj3Bzoh;mWLh04L`TBT5c}wUP6}uDOZFP$K#{5e)zF@b z&5C}$?0ycwm`~VHn;}Igg7~jD&XNuv9I^Yy4UYU^$G_ltYa>>-`KO~8QP)S|lWeKJ zS~U#;gG=dEpl(k?w=4*^EV$^HRjCt;YbrfTN76^H`o3+26NZ*=;$G?9P1Pt^k?p|A zfD`bhf(<~{L;*>;JK%Om@Y5;z())5Dm8RUFmCFVO*e(N-E^wZARZP;~D4bSr<_Pr-MKsU(-vO8*R=HCqi7WtFM=p2XvFxc&{CNyo}~of?-v^denQRh4l3H`uz_-E*fKI9PMMs3SQAQ z4L#hdBG7(G&6%jmM9h4n<#+R{CA`24O~~D!XI09>uS)r<=p&L4TISB16v`8|w!Xf1 z_Tph*s7WJF38Roe^Y2xhuMYDD<3vgd>(#PoE@^&_WgaHVs}#_0tOE^gPE|!QhG$|M z$cH~hT6l+@Tc@X)0GQo+=`&V}hK6PrbvYBBotc?wQcc4Jz=E*}R-yN!*!}$d?-1UU zv4@MKmP!+~r2(IO=m)@J0+s57e445Bz4jue{4^ib@)%{Fd)ujB)fpHaSE8-Wqr`4b05}B0ScR;6_^Ga9N3zY( z@1AomPJ98`kB1cLOKQfkY%5!Mo^pd?4xVa4S}vkWBlsImaj0c95AhUBV!w>lB5_dp zmK%^Pr$63k|%_M;$!BKc6V8H)Y*I-3TYY ze#9iVsY*x{`P8sfRJvrzAuwAYHGd&2nq0Gn{eG_qW#mn*r!<;79yTXE(v0aa*oso% z>mQDpC+gbWI=o30j$38k%!_-q*teS0&l*sTFy68W*LjVRriNerB&^1zI!;v82_M9; z9TIGD`rOPp>jOj9WVvDuousK6_|6ZVlP;QdAM?A4eP5SFRhb>1br&4fO5IEE17#u) zPfy>W7LGR@adN@zZr2AwuzBseD#cS!@o1&>2 z! zog(T2g2LV&VzM5-Os%}a!cM(}qk_Gagd)b8PrCL)V!VQBhIf8E#KQ>8rl29e^b)Mo z^h+X3OBvnIY;OkJUO!vjfRW4hv(tIcNo7xn+AykbK|?MJnCD-O%H9bGQDNI?YBy%} z9D4#Vu0L=MCHlu2Tsk7i;T+q)xivY4tanxR3ih}TdrwX7Gp>8oSwLsn_KOi(iG@8o z-$wx;qQNF7{ZDrqQ`*U&kp=%wL(D=be16i|Ip0<+))~#wl9rmf)0yNf4Y~j2~`<2Qnyh-c=#;wrjA6w71 z^k$pJ{hx`}@gKQctzQKEL0n$<=+?upPWCl%T`J~@+S*M9qL7QL@|Ti85Rfoy6-aVv zIXLec#nM>u(nRZBcc#Oi4LWsf02G+ofMb!H3P1D=Oc3=uP4$}#aI*MycZnMPgfBz8 z(!-xfm~K>ir9{Ws>c%-kfZibezuVjW(>woi_@mf^Mou}j(LvLf=1g5IE@v-(FS|vz zh6$`#NJz(E$eYOKpXgwf1yfqV8KgZIDD;oTscUZjUyegHkpb6DfXSx>_p~(%_Pr!R#dnz^^3WquRWcalu-n`>CrG_vD24Ja$?h4pe+l5=@j?LnaB&t}_6(D-5f!;S5`Uz1Ezf2+Uusc>08iIC4cA6% zJ=F@)#-S?9-Tq~wus(pNxyuTk5cVlMTZMi|tz}KYQud!-$%R?lQCZ-iEj2f7> z{|qAl;-Z72qXWbtbJv|e8>TeOH6(pC-rWdz%nob2PCinqP57m6(w>j6`tdaf8+M&=c2Pt>)w@?Bg zb2(L^BQfN`bbx4V=~@4RhmD%(`%sG-@R8v0YT1iG7xD%5t@KBZEdW;+3Ut+rapVZa z?aJ~{!0>JWarY_Z(qnV-sq>Go>R^V1BoUhog@U zfqI<_#>5-$<5OE)dP~8@;)R&zH}NIpkYatqE@-9uEGHTC?6&|bWCSR#UN8vJZQzL* z@r-g1-ZP#ChR#l+l`k-!4JR8VK0t3Zy%;g!;H7DIFZDOg`#ns+`3Kqy;-&+%yu&{# zO;Hr=$fb&^FvT>8ULL?cd!aJq%u*u*wSJKYd93Gzmxs=m`ub?o;B!wVX)h9Oxnqk| zww^0I29s<9IMoXL3m#HsJfKhXBVjTUN|1ML!U4(?m`IV94*BNdAtxc5`3pJ3IhF${+@o;$pM^f`piuI3ELc z=DXD_e=@)$YYiipgLpN9&?wJB^X11^@sl6M?>sgBm|`o!HJliiAa0nfE^8P3S0z|i z1c@=Ro{PGYOiTEA-Z*zEt6|P?T5-xm%ALqrRH|UE%hZ01TirXu^{2=VT+KggAFP8r z`1p6hW4C}K0-=xhrvdk=z4tqbQ*Dr`jya$UT?;-ixHLYT1PZP$i*2`M4#&;M>pblZ zXA(eIrwxKgf^oN{>}S>6-pcKRLkDuaOzlDKhGq70*+S`Io1Dp24)HhRB%DURj(`|= z7s$nuJ2xKa8}1)X+LtZ-+gtM4@8<4Jpwr3Duz_2eA+b_T2T126q)oO4*WP}w&=R07 z{ad7MhIq}@jkQGipO#&0lOS3bhu1N?U+o3s+Qb-YqpXD8#i{ z_H^^xr_|I3jb6w5mS?*W@@?zGg?n8b@w)3e+;(uw_{p;~nTxaj%ZAO#ENO4D;LD@n zctF%yob}&9^4=(fLMHOO0G8sc-Sq5P>IVt;6%wGk9_GK(NDE|-?e+M%p*CbfC^2vF z5SU;SFA{F;thOsp07y=-lw;it+>?HW9uHfQz-;E);a<3cxF>6qPH1X|Y^EXwh~X z*$SMkJZ_$#6aa_TLFJV)tIye9XG!INYM^r=jTdFJ*wLMNXM-a1>ceW-Lu9&2Z`mcm zu=)|g7KS~jL;ag2O+sn|rrE!4?Vwi&-%XF(g_1QYI`1O*%z>DCokj*P>lmQS8Mn@T z^>j~Nv5=b&@MkG`lS-y39hGkj?aru;v|R2ym-nJpPhPHI8F=YRO+e1VPet1(%)+~QE>JTHvgD$8GSnv%pC^wSU|ZVZPt+_ znJS{uAIsrTiTilpPCucW^GYVsZ^#7fK-4+5tQqFcSPg`r77FFhZAbT{Mq7GL&jB>` zf%-^khNL_G70kCJ4%1zE7u1I~4&#H*mUw5X#`+)6`s8hj>*-0qBIfhm{=RA_DEzmF zuWTMr4fW6&z}zG+TjkG``YM7J5VXS5(nfk@TG=K^%V(K80i9kv#c;ZRK;-zvs1o+C z9O^8CQ}y4rceA~}Ch(o!&8IWP?uQI~NoosM=Yvr(B6eR9SKEZk+|kYaHjFFgF9S@g zkv?L+*g6pEB@19pu5^2&4Pd_c8$OxSrXX#!s=)T0rW{}%#B6Q2o!9t^#q{ODNgOHE zE>U0ht5jg8Gj*MV)j2I*k7H0+y}N5$HFI9FUNg5>V6XJ;ZiiPr6HD()uDU6iN`Rg| z*RT#1rAr8BI*-fcu~a(8XG){87s?touU4goWE)oW^!2p{SodzzWC& zUj+0?!e)NreaQ_BT#|GyNl=zN&1!}SY8}&2Jee7_mV@z%l3K!wkxxK5GLx zC$U^Aak{Y%d&SzZX3SC^gjbvb!}CLil0n=bAUxf|e3x%YdXS`k0SJ7bd$me8Ang7h z764ZVq|*%$G|<=q;A0p&CMzt}Q|Up21MX~KSqe@9{_EoVDYMYLTQQF{DUb zsGW_fk3tt01Icc}!=1Susfe#JK!_b($5s4-XC8RQT5yz^w2P4B@s0uKyTK5$Yy)53 zVUY`{b%Ob<58XEgsBr+HN155C>08z@%yfch8x;2tXSVIqB=bBQb7 zfMCPs$?3|?faYTJ@No9G>z{EF2EL^31upU=slb#XY0bhN2sXezIAlkYbM^p z5bb~Xa`U}69zVtV>!hq?Z=QUvggkjq%-)6=02!mr^E@K}&Q#19NMb3>zc;ls1^ag1 z;7N{2c@)54zOm?fq8Hq%ucScH13mG{0-UkPaw}&ge03{vp>FcGZvJ*a8 zDg%&)ZMg}|ZjM>UeuXyFur#-9LFqmd83#4ty{=n~vqp>@@GtJKbYl2~{yxE2{KZP0 z@e_YvJaLW*|Il|gog(@g>&6?dRblF~=JTJsyDo+^SNrjmlhY&T#u}hm6Y~8;MO;km zt+C6?Y$antIM=ib;$_@YvDv}l;UkC7fWFbTJiq*^ltK}hfLr~$H*emgwRV->&N|5Y zXgTqLM*nvYh5IaTd!@Bq=lP=uZ= z;tp8^maEb0M3;wJN{bjNo6o@!OKbTpI;nq^**2#tqFuF=l<|>nd(X04T;)I=+phx6 zbeVR$ku|e1Q+s}_Oh43Nva-l-p<7up3r?qpLuY=P>pAN#y0VYQ&a=kiQokervlVm6 zZergoZzKSHn*nJGz!|d;nYaT86_`~uV(g)xoKk^%`i<~D3~HkJ8^reqziQii&@)K8zjLVxzD5`P5Ql1^ts6{pN8k8x8>EQ9-iob9O2TadV9JGP@6#06Le1?f)3r_A+rOPtAu1ss!vwbrc237?l(alB9O zxsBTyhQfEhijV!=ApN`r6E&B#y^WN~VwUzAnXcKHB)#$cOFM(rkckivw?`PU*Bd}a zlzh=h+S&9oh~J{klF^`}GnBUO=Skl9IIW_oclpW(9>5D#y}&}uDJl{MYjJk zd*1$51%l7QfaBKg=Ej=7Y`YO_&}Z|d{_%{5&glDxAjVT&z7F_;26E0&PZ&%*Z(md{ zo4jV)P2I?>N{JYGq_zBhNqO0pF1!!|R9B1aVS#e2KqER{w;hyD{ExPg(1Yrsf$0ET z9|~J<0&@pB+?a_E7wCttM`0kRM>}QGPyHpK5PEE~kyBCn6;s>{D3@ndmM16^#{vlp zzu&|&|1sRALA~({J*;YA+h_APmbRb&<3-cufdBZvZ_+&%)#s;;%#xkMy$xDe)@%Rr zJE9K^BW~aLDycF4!PQYbN#I9bUf#dIh4Lmi9E{fLzZ0Xa?IwUU%T4tI-sqCL>B+0s zCFEUzt9R}e(`ESBBQGr~Sr8{l!y~%jN!8n?Di0R z*7o(XYsFTkg4g=dA@<%Kj#LA4XMJ;}YAYFB;YpYQ)t$&xn@@9qH(iWaIr7>ZAKdi^ z3{7r<(guQ~ojFrcI3w7y=JB#CJdzc|g+2beAdj=r)PZ3Qm&C`o<&RZ2O9wwo%gM#v zARyB3W3s)(-0kbp64DJJYXx%>iGVs2S$amP~*$Rf?vVdhi zJ=xb|SR-49nKh?WFL$OU@O*tHx@{g&O409eL}tNc-IR@^s)u$FRcL zdiI5_A+go{vAcNLzALF|k0F-PLqM?`4LFa0yaX6vOCgqs8Ub+@F>8TVZLiUHKpuFs zygTsp5N=~b82R)%;CX?J^qWkq>G7-Tv7`ESyYsvgtvdBK^~QNzPw!D=$<;p| zdXmhT)#SAe2$PVUhO47b$p0?w3X$FLG?P8)$)g(zrw}y*u8e}pJkFn9dHl|=if`|* zu7F8Mhh=F669(Y4@B6HNR`9dbt=Ro7#!nFUGgf)zQ7`hbVcqgVgobx_h3EYc$#C&wZX0sl(q2_QD&|fw|q!F zalMIcj-EGt_|MqKv+qDD9gyF^GYHveq8H+%w|^KkpNtka-njeBH6Jl%F|mq+UtXM3 z+`I;)PQ~J}U?1=_oh=I)+~4z>Di|47v~MNpt*AX1GXnPr3ORsh17t8<=K_xwuH3}v zHLr|-)& ze{jB_y9`Jv4l{Lkvrng2cO$g}a(gnKC;Wkc^GN742t0l7iW~7i;-N4}7|>%00Gs27 ziT8}&0i%|As${JA*!(=3Q^TGzfWU#53sVHptGS}NR?AL0iRJA#0O6x@K<5O_k}t!y z0BxwDrM1XsdQ1c!izSOqoDm1l6p#jrEI=})r*gN%^n9bDs{AF4jtH@vLmo(IdOC?I zJ}ev+>r0{$d@STq_b8fC;0!r;f-K%jnYPK9urVt{^v|A%{0@H3d)`=Mk3UztTl3G^ z`f{$K+1dC^`mAW#`F@{ugV6kXybX&Ex5#s@DAdJ}DE^S!weN4=WW0I`O$afI9dt6# zD4CeDtGP>tCk!&u+3}j4hQh@0Dtm+VIj>f}QY8cyDK}-qGCK!dc{Q@(T19sE;%O!% zlucsNxtEOF-Imu#KA7V88s0qVCF6_ie_SE^$0)0K#-mNp?if_w{rr#Z=}QM&{^3eF z9=Ue`ayvfvt;69IWD$FyoAXNO*X8lD0BLLqXjp@@+@M3PP`+x!ec^Q+mf*ZO9#C;9 zo(&%O`qCF{TL@}engQx_6YGiGZ}h5g>+cbMp>G5;{AC0c^CD%$;gi2wY-z+ z!$e{lyuineBjT$XFgEdtN>|(q9?@>P9#5c#@dm_K-efkyd}QTxTiSbWnf1hBJtjV? zMz0RH5=736u4?aIRkK;aKs#&x8YmDk0PRbeb~ll-@>j(62j!18AGio#{hhgKFc|}p z>6e~-i~;ja*DJHIO9UV!4ppF2f;@hpu5!Xb=8)dH3(g(Rw!oL43Dk5=_JK zMkjyEz{vvW=;948^uMjd0(~0={YD53`ERLtiSZVt=j*bCIK&e@FA?$@_+%|AS5MZm zyRrE4{j$47@izN@_G^ytO0&(r&5M;>>JoWTIKwjmQ?%=kwgT7nN=p}EUR0D((uiLR zu4Zp%ZPTk!`|J8OzYq7CO8Gi?*hCfA1d)phuL(KjT)dx+H)V+8{4o2ALsX0z|8d5) z#+Kvop*x=C>Pz33J4QPaktJrLL8s5+QqbPI4pink9yi}Q-|WXoW+oa;^UMhe%~#NH zk`rXrkG$a8f4MnQZ$qmd+n)hX!`ufvTbg9OSNH*EoR&nbAk1eB69q&_214e^3RYIefgO`^Z1P5 z(oDiz7ggR< zx`iH>X;{-Gu;&~gb&ki?*H};KUG67i=VkLpXh>^J8IarETbO)HGkdyJm^|`SU?S6^ zHD~2ARgoJEx$)Q)*ywQC(c@Hxbxw}Y8PGaX%VFkiLn*=kv-Bi1@oI~WWl~uP(sH_s zf7q_EM%fSS?{xNwD{2Pz4M?7Hms6B|HL%XotyteET&XnTie9qKN>0vt@BpSP8_3J1 z+<)_n<<|}j>OuBwxfJ^~f4wlSJHlq>kAJ|N-r!ifk9Th4sz#lQkigW=r+HcY1ic&G zb^6FU8oj6z8`I2`NhGx{jETu*SdS1IoTzJ%7uN3pt0beUfgR#Z3e8Ws#-}oFuN#Gk zW=dOWXsu>=@HO)}HL||NU-iY7WTWL+ZSdTy%#Vdwnxf1i-BSRe5IY6gmL?bF=URKr zXM0Je^ah<68l`v^th$5CLbB4~Tx248UnQoCkH}yD)B_MNgs7YP2dRAlAyBK*T{a?DMDK-*=~B z2|v3^`){;U7If&O52Vvq;?WgO8RDI3cUCj6!~7|d?cREvhhfK4md#Acve@)4d!AQI zD?HQw!ar7WYL{h}+kUC!6Zjyj0gIdOZum`-I_Z17kkOOA&^3c({iFudp@{7Oqm zSW4~9#R!gV{jCVxky&nSns4eKt|SrOo@hnMXJ`!M78?a7jFZ|qcc>KF7=}Yfr>Y>N zVg2O;cTetagKGw;q`gRwZvHBhB3cdp9COLL_nrSf_{5owv)vtv=x5iQuTfA$mTs1R3944?>wRy=xA{bP`2p)Qa@pdeza`__Y=-_oS)X_2o(Tp5#=V^ZGvxWbS;m9RKa-^#9XLY6t zR%SchOHR^bu%0n13_#CxBQ&RJzT&efWj7zp}L$$omf zO-`FKbM36YmCgK{vT&IwCnX~ormb{YoqVpKYN@XdhmjJ$9;IqfbHZ=xpmr9sGSU|} z@^-io854{oZ!44damj>JJBaDaoA|4+GX8qUw4_Md>C@hSJE2K4u#$Yn#n<+pQpn@~ z4kmAXED$1rFQ}#*ox21#a7Wo_H>8*q2~;zca;hE>Jsb|Q@Y~t9S0Z6erF3@Y3C`lV zAl^*fe@J;><=fUP7`MAI$N`@z2e$?pxem4X`P$%oijb?O+$Ad1{?V5@CVuekQ=j(fmfYqo&twvw z#};tdrTqEkkI~WC4-)IVNjjjiHY;1B_qr6Qd}5eJS`q~;Zp?ChP@LEGosS_}sRm{` zZ1Q(3bJu-r#vSa+pYvVmc1Mq$J{}i@DRq@`Kty100g8Ixw;fM~1kFi$BJ#a`neNVq^F34^4u)UiwOg@2>;1%jn9OHiFUsn~5Cr`({6= zS5~gWJ>lM}{as~{Z@7%2X22@hg!%j7_Bl8St62; z*DeeZ9~Svb3pY*~r*W?OBc5ct6S+Cacz{sL9!7uDmY^oeD=Q+6p z7&CbG6puRUa{+%imQ(v5nFcxbZ1;>%9bpg?aAiCXdL7W+M-IaQjnajsocyUoEDE)L z-&gi;K^2ppg!e&G9tU*oy}|-|Oe1hsaU$Auddo-wQ6mXU=Kc+-@4Ma~@;~IeWS>O} zedLP@r4)5DxdxOR}@k@7B zg&-CM5K+1U8f1>;=KSHnMlsbMoVr=l;_z`s14c#vi^L55jmOQ?Q-&0G_}V$V#w^!N zrw01dU3(}~%c`_yEEoY|Cs{ZDz&k8)9zZV`RKmsCr}H>KjAoXgvY|3f0Sx1-R>HuE zi_t_|nXXD|}U%Ppk==ty;Ml2BLUkur7OIHgXuDZZf&B(n+mw&VU&in8IT{luR zZbQGvP)cLRL*4!DeHR)Ob`A~>60VQFZA3G1UOlTF#gTYVg)*HW>UhMN*uL9T9)=-T?7Pv^2^HlwSu5! z{{Mq~eig^Gm3NK8tOeKfv$0<_+Gz#6FFoBZf^y0(L6EqaML}h>-6zT})Z`I)mu5MH ze3k3Obe9M8jOc`c7355`r3Q{rD!xFcC?sm@E#OTN%TEb)o2(KBR@eA*AI=`HxPNEo zMm&UTbzy179y*kN{`A2u-X*;`1V5ShY{bLCW<>cI*^A`62D^2eQ&B#3(yu0 zr&GQcGf2PMIfJ(4Te%*#q{DytiyYBmF=ps?9ymWJ$`Xj1;d%}Ku~@07_0blMD7&tk z3nD-6*MUj|6tZkD6Zn{bfKTfzod3fenFyXNA3|EPp}HX_&gjWdW^S;+H5J!JwxO^g z1tybrONokwJHlu0m-M!Gwx8d={|W?xbV0tNt-W1ZU(LNj4|y*j-H+}a;j-LU8?Fyg zwwC=Ko}M4rxy3o@-T!0;i@vcFK*Ji)|Bf>4bmGlX{`Ms?Cz*5nVS`m|&%r$qZ>Xc3 zQnKElB}mE-3GE1J5>%1lPkju>GN;9(5MS0Uy`NTv&plwyU)hhIkmfHie@r)8%&t8y z2xXiPLcA>82nGZBSm%mVy$?Rt)xB_7DxV=}rtkU6)_`%FITTOV<~;mYcl7JCMy6-e z&iEN}>SHjA@GF+rMBOP}(_Gz;=;?dB;%g;_sD?YE{W2BUN+$l?^DK2xnJazpT~|a% z;AqH{-Pw{~$-(6YdpB4258?p_zOvZYv7~QwE-K7bY)Sf^mVduFc>h4ZY4~N+GwC+( zQf<7sl>^uLqn7Rc^DNKFl&3bY6PH9q=}D$HJ%~;(Q+$7Nn+!GQut>lb9yL=>>wMvn z5~@qP`c{;9p`63|^6-kJxbDMg31=(8U6HEfN93}m<899LE~#W5JWeDp%w80imhyKc zmh>1KxK1brDn4*aF5Jjx&m>9|Iyf)ZC={Q=DOUIf=kQG%Sc=!{t8>3 ztd-@%RNG1(M=DA=$~1l>a@k&_&I{T?G4{kdw@Ot{cE;#50V7bf76x$vjND1wF*64z zCx4+@>J!WR)Aqu1r!pGk-yA-aJU0VJap4Ld216ePV-@Wis?(~^X<7%gt3hU})}z#7 zQH+hggTOMxhI?Y%u*Bhhrs^EoIif+GSG~WRHEMn(FU03nT4&*hrf#5W3;g+P_CxTGXC-oSd{0)HiR8dyJqHPPT7Hw|)U@aiV_NxzYX z1Pn|F0q{j9AYss7(vm>!|60J7!#H)G>_md=oMb;`r_%aaL5`D;n^-jC!w67~1JF}6 zQ*|KY{*Aj&%OCMkCseI-uZ38Bld)Ilh#13dK8*9B7xy6r?nvf#TwwolJ75phrdYwg5mrH#5CGg3UdwEc>Ajaisu)S8^_avV9^aHP~|`gJO(w?UaZuc+uU zea|gwBGZ$-WvtE{dC(9a5mX#&q-bv5)K$)Zk(b6NEF5}`Bp?tZ*8x+1&i4islTAMd z;h{9$WL42LXc{gx9`-CFfOT;`#jk@R{IrkPUGPZfj3EF*ikh378%2-ea?NzfXgAw1 zdpvIUSVOt+ZcbY1%fDhIHzgx;b8o>AWkdu4mwqj->#qTg6!g2_@4O;kMxx>(yG$R& z#oIYKksAB%;yKK>TumPgh1mcu!zOYt;w7lG7F7IGDH;t^>)yWxXaME74BhtXul6bT z%v{C5>Nf7V$Js5q0MV4R) zmWi}2o>i&ZW79x3GqKM}(tw&I3`=~jq;Kd2tPp|B&VQ&#fm$! zXNeYmCuO$pUhiw`+!>~Kwz-``6b&Qom&_4^k9ax0fm9y}y=dUWroaEBGZ#vKU6&>M z^zZMsGhk&QZ(zG#0!RnTL8?D{Rz|8dHVAj*MRCud_E5b`9{#8s$vlRd+IgVHjcE0u z!18Xm$GLnQG5aw$4!yuaIj5AHKL!c z`^&Ea$s*53x7CA~zWMX)Z|f^k$!a{l*yWsolrginCjvMvDQ`f2(QCPnqUFzCf5e|W zj)*Tr_lWXWN38SGoYtqfTL9^bz~`ooGKD%jH4V*Yuz05kS`~t4?@<(|~uUF@HRSU~TYH@~DB;RSvK?2uZxF zYr4=L!k=8<9a_JeEW+442=;i{ch@J8li743I3|dEuEYc5=p)2aL>N@i)*Tl(jFF-?~%4zG{{SZlD!e~LW6iZZ6e5QfPWA7|^ z!bt>u&w}y!vau7eb+Qa_mU!>+@dbhmw-#A->Zr7kE`Mt0u>WrXA`o!T`a6;WIqR9w zBx<0%_z2u;8YwN`5RR|Q8XMol(vjQXq!pnmQ$l~kF1OU-)7e(DsP`TVI50Lj&&^G> z8~<6P($XZn6CuqsxS&1x9$pTg zQ=gX4#_u+f=_Tnz1`2Da0Nz>; z-+Fl&=+S~7YuszB2A_Ir%iA-4PBbfi>Eeqt9lxzvP*gUHRuRNA+|G2Eeb2q5S_a@g z_9uUND@?_$MjdZ|tz%!3Gl8$7T$Up+{3-s1P51vCjH?Mqu7D*y_Ll3CV6ou)D~6Fw zvZ(Rgo{wBNBw-ZiPw)_SG4WF5kGDO14=Yvma-TgHUu5YjA9#ME)es1{5kCLqeeO}*3(=7S-f69WS|{5_S^r)w|I?1P_@{?F zzFR<9y40?m$sGVNp5WmA%1Xgv+4*i(8Xu^rZ|>Sl^FDVZ%t3c!OE*co(I{DMwU>;_Ps%;VMgs_XRV64i$BP zOsey2Lrgin8`NJ+ulG4;)R*uEPG|^xjdqQbyVJkcr<}|iy%bn)|IusLbm}F@Jwo@Z zW!XpzF?PD+2D2a*bH2A3W0t`CAmxE)pyu zfweFXJuG?P;b7XwS3+4j{#-l8HHz>sYsG)09f3lYQd(Y;)wmKS?Q}h|{E76f1YK=C zl6?mn-I8R?>0}um`-iXgY0qu)hVb1*>1lbco9v(XMx4pZO^P#KD^)7f`keJ3VlB_M zWB#EAj3nd!eALiXOv@U6J#VG#_npQ_pP!(PA}fox_)0WyS!2M`lKBzd7t|k5)IeU7 zn0wVj6LB35Y9izqg~0Hw{1R%Eg=n=5BCgpB(DfE_F+!fjtcMVPqfT>dPQ`yRr4BhP5O>;r02%%sKSb+l&iJC6Xa{l9Be* zb5>yJdwOeGLctphD~D!Q+SFNSiTWQkf44w4P;DUl7tHNUcn&)^J<>m_@$#^Ywj-9>n@d9E z5RJAbOr#_9J(O=Pu6;ADnJ%z3;X(MI6!-}H+Cgd3A?ETVzJyETBe52723u#A&mz3W z!sQ7hVKN;$#>S4*&&DSv3Q#diqPKZ41Kcs=m$Ey;N=r*4$2~8!VchbXnrQE-mA0SJ zOM2nPRB*I^C_8u7!x+K}w@sbFyZPVi}YCyUP-PK6+fY`h; z#hc{LO`Nt~F=D#g;E1z|Ntg5!%NW`?0{0UPey^PL_My+R6>eaf!IF=TzJ7^9GBbvc z+_(x&n0-W|Ytg!EunSQgaWc1wJpz>OeX|}QFm{2pH0x!b%XXN$CO>;T|L{VDCiwyP zwX5}aTBUy9_ucs#HQaeaR>Mpc+{KBv?dYwV-SO$93B6Ysf*Gdo ztDPvUuh(`J*W^!S8IwMgf9&oqRB8MvtAVIgC>UvT8!jmu9BZ`ick2^XljI|D>(B#- z^wD*@-{vnmSjj0U?({i;Dbj+(c##^~zSC?1!~fMFMF}Bl)*YE)D%6S^v1ZX`0O^$n zw+vR@#0Zfg;4ZHp6WgmpXvmW+M`&kj>$Ex35P38)HASgR82tJ9R8w9L#7Qn`QhHj? z2&q1QBuV<5sYhMu>@J$g!F@OQA!+PCmU5$3FM5UQYwW zF6Bq!AhVn{C?M~XGci2Ave5x?XYKs{PRF%=jKiXD(C6m*34^1<#GRzn}*Mvv`(4InOkS=kw@`oLa^`iaaiFXb{S$DJ?7O0HTmQ)Z{{4pqGSv zQ)BE!qr+3Bt3Zx-f{&HU;-Yuf^cQo&6a^JsA14+1jACUfg?zZARV{mp-Hgjs0e{!^ zP)@lJv!EtUzQM(XWQ;;9aeNozl>XMicoQbWe`UYcJP((;sEj9+*W+jdLCC+~Qfu)x z1n)TiswCZNy{U|un{Sh!X^}r|uC^~~e{E!3 zclnHVel+q_J~QMY;QR22$|)6hd|Ho3WBd!ACC@pCV22BAJ!V*6sIh4gPNHGKT4+EU zjnBEiZ)pMXkClMRlW4b_m)x7u($nj@LmXRnLl^c94CIj^7({_{ZrXbK_djfKqKjU( z8l~Y$F>RG=xOFOLlaOZp<0SsApF%zDe>RJP%hGsQrg^JZa53$pnVzGgqsL0Q05>j< zzhCna*SLl#hPiT>+KJj3g1+luJJtzt#>H1SlyG+764@c$W0fW1ez=K^>V7NY({i1@ zzq+x}i5>TWz!M;w`VSw>CQEhpEJZb$z9v~SgUvHykEG=~+TKz)`sTxEvz}-ZNSt8D z@&etanAm#kmb=8IyFUX0436?LDjP=|JELmR>yv`N1y#(}rz&8ajF8Y_pS4LWlF6}=5dwNJCgq3`UbVDj2;2}N9WlAo+ zK&)SqYgRT#1Y~WGi3=f&2pJ=c@cB0I-)pg{9$2w0xHR%P&Wpq9hYwCuag`?rzKhHu z{LTO`FaG!(jB;MWhkgt!fY`L(tJMfEnZ|D{{Wg2VZER5_M)LFuy2|*8h6Wi--Gy3Z z`#rs(mp*FPYGVi5Z`<>&d#cG678YI`H9b3%RsK5TU#0koc?}6Chx_)$X@6Iw?}VO7 zr8K=1DO!hz;E9&epl$9<{alOp4N%Ny1ed{ES1!U0UE{rPIrw$hQn16a?iT44Yvoxu z$-6LK)%#%TeM5r@fUs#A3U#NC^FlT^H@#p`NT~lB!RN{G@nFcD7h#Fs@e+qM=a#VJ zd^zR^b85V=$fC4>!7*TTD)|;Cwz;5O-R#MWmD^VsZJ%rQ1c7}&Y6b>b3k%k#6$Y#y z$}mi+@fq{NWg^atq9kCg*ak*bfCNE(;VpZ%?{!#k$0ms5@APUB2L~^Et(7S1rQj~j zC|PqH5-dKZ)@5qI=TByc9~4Aj5OW_LRGf-!a&*3@-XlsSilE^c>wY|FF@<70`A2zO zgiSMlz_}`gzcRV(JRQR%`3&dL%md|_lmd|iaQ>ycaA z7EAo&xp5_Rp$STBBcg7rvANFf&2vqeLIsGyr9n`4Z}!|42Ej;L3(eT_mrwT=`WzrYnGVYu1k35^O zizrL9O>C6!m*}sxE;N8jyA?KO0-E;2P?4$z4p)FDYL0m6`D}vzxXZecGjd) zcoz&~Z|9D%U#~XGV3?uTCT@|F@Ub^9+%&ldhcOY3im_V5(8046Xv{>kOX?7oj{$zU-`Qt>>BZbWb?n(Dy8Jz2@pi z3jZXd${C-tIsQ0v{RMK+OH6m)OQ6MwmrVEWWSRg~2VV+R`epF3O5d}$4*w9SI^Wx2 z|DbJ6=;uBzei{jP`9GFv7SAC%cs@ob`<+pZsByw zi%h~*mQUO#EkPvVHjf7RXTC_AVBZh*v4TA0viBUhGX_vjoYuKU_Q`K))M5x*jd(Sh z_7)UlCgsOiiTRY}h-?=w+^fV~OnyuHQ!|y7=fiBpv);!V2`?Y+-`R+F5)>G8YM$Gh zk!uJCWqoJ1ED>FC#vX(v4}wQmjt8_htroqPO>#Z{atrQd;Sh(GzL_7H8ox-oK*ecb7Fx`l+e`~y^ntxd{1y8b4*7Zz> zK(8z{JX_x}H?grxY@j!|FFy0_g%dWFA$gCLPFK|QPX21nUot}E{^RZo%g=nu^9Vte z{M7z(nz2yZUGwuasdiQyxm)!k7&praLn+dq;sarJTQyc(W@56$Hb^qf^g%Y>OCth_ z@s>a7nB@&pqLes;PqOavN>p_g>arKOQ3Qd^32JUDGCyHVey0@~@{XcR#RFko5Tco( z@dl+HVN>h8Jd>I$Tm``t_-=~$bFw6BLoWKkL4p$Z0#U~|S33i4@f{?Yf)L#qY;UI~g_`%8WUZz&$R zJR->Ls_BO!Zo~XwfkCopn4^z=+?Of8p$J5RJm~h-(S1~#DhhHA@U|y};tu#fm&LG9;6Pu7sQ9>)eD&H|_!Sj#>zc&zM{A29@ISZ3!N(gR^+l1SahYPpjUG z+iNu;XVa+pGC2!=IUn|PrR#5`34a8?4kw*aUJi0oI+n&`c!vioM^u5>HTHLQ{6fJi zCkozHS_*{RW3}xVIWwnp# z7#A=~-ljc>v9gh}@^IgxI)L?w9eI=$+hN3^=wA9(0>wmRFy_H_h$k&Nn^{4q`;;qm6@B{^8<`2vlFJs3Xy*ISWjgDihMBV9pg1 z61q=^MxeNqqorEW0~m8^t^Ndq|9%B)ZeBx=ZpvjX<%1>*ADKO_dK`0T^9Rv)7;gTM(e*1`G1EE(s(ml2MZXe zY)CTE5e!#dzs$eC>-KTnNhm!ooHzaIrQ~$p=T43a_JR-!EioM1M4*=Y4szo;(J~aQJ z168O%bN;JI78D4^n4%xd;xNsastm$op#9c7M-tX?p$eUj#uvGET{QaLzB;)q^gUsr z@M@h8+7|1tEg!&pF5OtL$HPzzK0H5M8h`A15%jS}ztUp4 zE|q-bab9T0b$Ng;E$k5!bnsFHAE$lW1@S#UquZ977?|)tps_dAuE!PXB_0ip$G+NI z7js^r)&9--IjXbwWo(uFyMxoVen|P45NuvRB$8*3NF?p{0A@lr1=ks%vY%e#8{}!BXCUgXVz*k3#mI z3VLn?QgBFVAf5Aeor^;8(dp(cNlQGw9rsd`FzTQr7CN(xLY4b$PD?DnunP-Yddn#R|MER&6^HC2pn!@A{GH5t&!YcS&>g0^A^eT=ML`|-agV>`T zBG!Wyb9!2@kN&cNYo>GN=ax8cjyrc=eb3HbHnaN8Y|vr(hXe;fwGxQLw9qB;I1(jr z?|b6#W%Ee$rw%k~gm;-z-@GYe{|)vth@`{fKW`6( zQ`sSj>Nt5^_D%LW7X^Hq^Dn*$$;m4d#n2^%M%DPxc%WLZEJG1NDGfkOd zDIAqBt-(iRR?H1;EZEZO>jka+z<#=fBy?7D$H(!U&ApU%BAl+Eb7}JW86IV)bxWakwacjcHd9MN&(JI@DbB#-d zOK6T+alF1gMRS?zVB9$1($G5bbGS_81bHo>KjQ@KM$Ag|z0KYcM#Cc(zPlKiWRcL) zezW4@Vm^k)ak#c?wSvM)i~O@n_hBCG#`_yhY?|AChsQ5R_{W0!`V_}6JQJnwzSDEZ z6bm`b$jz$j>)UX?fo>_BeaI#R#S7%(-Eg(ZWh0}a7RpyP3Y?-MBdPHPF|j_QgZN?K zBz9ghc$6uXdBru&My!flFMjAp98u_?WxoQUf*4}bodryq!a9(|-K{wxAcN#amsLhd zoBC8DIIfIR@dc|59glPBD3JnTRAhlsBR4Ov$e>Uvw(_4Kr|23^IOwuWN0pXpLJeJc zrWMr4So=3<@^+?9DreKA>ai;<@SE+qNU>bM_rjpCechuu{AE}{L|!tZ6e+N6@Kn3q zwHKrfncZZoe6DGhCmav$QkeMVq6|i_hx9Cc&IwT8{d;_jDrq3sbSz_}f+x9W3F=@@ zjR@LGP?}Eem!-#%mjF|f<+UoD;@|-L_d}B+ZIi~Y_I)l%mY!dsb9nJcM~A|ByFrk3 z>!}%MG0hH(`n4RLC&5+U&;6f{g~gOUZ10YXDz2<#bKsx}?WHb;JR>5{t?0e{a<_6d za1|EgY3DpFJfSAAIN(C)^NH8yalOR1Xdnqpc_Q-6$4jxx*$+|GERy7*Ni3m)`j1cv z;^@bb{67`|zrh9&2d0SILkoz{kpd z+Ojo_;Ja_vXXn<|j@47H;n{+cENxU?ak0FJ7nE%UFbZ6h2l%y<&>8E70_Dc>dz}Ec)b4-7z}!n^eJhHaZVLk3S24A z)7$;E$Ok|3M~f?M5>fWT>6MZS-j3Z~Dg~7B-6250T@P;qJMnX)O6OcgDg^{b#V6q# zRBM=bf_qy>XYK*KXcS*MC1jm*DIWX{PEh-S!WQ&eCv5~FRW#aZSU-Aav-#@0w&rR5 zqG+_0P*rFlzp!L99lA2Sly~(>J?DPfeLM&Q2JduD4T!pFxms*{Ty?v*^uy`KOZ)!?I#U)G~DZFy`D_}e$*_Ht)i|ZT;-aR+e#9>u%Icb{DGeY&u!E?prz*2bV zH|972aW>|a+UV@;UEbqt;543ABEsY2uj3_)tjX%@(~#+MQFd&V&f%0gq(3$1s|bW! z26cM(L)E^i=cI$L#BcY6gap!0v)DT%Zx%^TqkI=A{Mv$&I`~xL$T_GrAD#GOD<6#h$0i68L{j4r zYUnv$T~KkDW|~3RZB{g3GH;$-)JtNuO}HPegx4%J$rUtfky%f6+lHgivup?r0w>r? zj!U31IDBEpSFK;Xn4Dy9p36#B$W+8{82RP)^&zs}3KThxXV4#!BYGu7>7&x_fzU+4 zs_Xm!C+$6aegJHy>uuh(N6NqY2yNr!4}gS1=nCMW()=HDh%b-VbU&5yfx;#XBc_f? zyW@xf(Sv=(hYz~*8&;!vvR;6+P@F=tw7BbKWFQJ>0~`C=fIbToKXEN(sS|(}pn7pB znb#OU*5KL)-xC+{lb`P*#O`*HAnVoPlk)rk1*A66;KC`8tH)kYowBEQObPCI@D+w| zVzH5qYY!9LMF2E{mWE!FTS<_Tt&*}$E&*1P=gCb!mh^Ba8H*oIXzA5k$03Q%{+=tK z+YyUk_^^Ajl5GYQ$DZp18oh)m%I*ftXWIZFDk-UIkGK;tMja4pQvLGC0c4<*v#v|L z{B1A3KOg|{>Kzm%R2FZ*TeRFYn4X`HhC=h5dUb<~d=w3Q3{<>`z~}8PQf{%ww4zZ*euA5V8n87B{jO^ zYqO_gA1RqC1xbi>gb-5?x?JI}zeVBsc2R}1VT;u@oSc@H40%!5!N@N{0R_x&{@qv^ zvUy^ip~`Oba#Ki9SeR3?s=S=Vwgp`5LwFpM>GjlNRIv&~ydtp}SWb_-MLxb-Jt(Gs zeW`8fyoZ>M9Pl!zULG93B*#Ai`_swH_pn~?3_AMXFcUK4N4HFigF_azFh?GTsh1aZ zbD76d(My}J8N%-cF-8F=h&69`nDkEUAI>mu>IJw;*xK2_FO?##=KXjLBAZW zspCVdZ~GcZe!Ty@sUjI|(3Ipg0cat3duf>&dP zXvcs_-ui0{&#fhJLwK;RHpvuyfmybWY1EAmww{cTz z_5R8*w!Qz;?!xn1pJI!Tvhz6Tmt#0l^1`O^FTWZ*tC81xJmJ-A7d(zq%@CCmZzySK zpop1fyk*-0;-R4PxL9Y{?6I&v{1DxG4&`_xJ$+^4dAGz1O+p*>!ok>r9}85Uj`4U5 zn+h6-mUe%DTkV7!DHw^7+AQqsROd0?BMJt=C_*s&O*^ei2(1e{yFmcBK32%YKU`J<0Td~U+&QF?@hBozl_aRH}A0b>a&IK|M%!E!X# zMf4<3j0}#)v(L3X|C&o0eBq0qT##FVKe*N4e$s|+S8H?0ssCU z?f%^kFxE(o?=8rEv@0H9wK6qpnP1neg|1hWNCgpw9-vst^va%$*Dr7|_BeZbXtfTy zAN(ARv?GSZh=f7xHAru8$QkxiFUjsfsK@wXkO4wH4y#DCAgG3Xd8@CmcSy;cMK&?k z0J%y|#$Az(#wo%t;ANcUT(AR$YAmwH=y#ye^?-$@OY0xv*=qa71@F+mnt71h&rA_9UBWw5^W#y z{=P*1=7}W;rv7N`pm^Km^z#c@dE*>LwmngqEj+SJ>@VC{O|NF+wu@+2nUD2t=T9Zf zvA5>rx~g{;8dnk8WaGpW1)j}*XCBx`YP99@b#85RK5R+r__msjUmNVGuqMAM4@?R| z#>lQ=j-jFFeo2T)==RQ6t85dv=mbzuBc8p{Dux1V&=6$bMI64h0dq=m_-e)5i9WfG z(sJg2{U*2ee;*vgkGk)8178nXwNlTXrP}~)1cT(j%<<+^GD`T6Uwin6FD)%ixrcLY z9R#@EznD!Daxj3ExqSnO!8AKxU;1WGD~J4te|BWt+}t=KOYh9Fj!0hxr|gbDC;Jr3 z>ChlwDpf^yy`^$jDbseC5BTSYm1zrUH;?NMS%X`{-D1OSS(F4iE1;^ib7|ZeW+l^9 zkS?PjhGJul5U?>(QHe4o*EJL-2oDX#7Zem+_5T1u3H`nLNFAy|nZo1cPv@E@Mk;jZ z@YilxsjruCUs)j))B1%#Awhq;5&A3b3)QAgxV_?@t#rcC%;FkNi}k48wirS0Xs#G%?W0o)~WzjEs)9+%T74 zQ531XPNl$9<=`0Qac^sFO_N#|KqiZjpMDC<_tS@9|HgI~Y4$?}4FNjtr_J9HkAX$o zY33b5wo$nN5Ngd+`2V?m%3cJ%S)zErkEIgk)|ErhDn3J>fgTFzoM;#g=SmCrpE)zffVN+ zR9cI1lP)Q)OdK>e33xD)%n$=|Y%O`utNThYUR$H8&drFXZ_T-aB5uuzj&B3BSy zA>*C*Ew&$=A}Td|WouRZ0N}WO{(3-1I+6MpwzI~mq@{%l&Uzs6K6#kfGJ}WfmLB=z z!n^K{8U&(GOt$@Iplj~Oo3(}xlLKIpw4JfXiC5lzIEy=Iqn{Bp|6}S ztYQ|gP_N#4-oHBi4l3X2R4fK5SyW?4+pleWk)cYC3C9k0CQXg3LUy)1@nkZG2|c5u z8socHZJO5B*2od5auejQQpQXAW%EKX=nP4}nOG%5_QJS;x)aq}=a}!?B7=uVpv-um zrUl?ja%Gt)6oG{Sx40MEmQw< zS5SD$sjCxMmjE~*;;g_%T@Ini+tiNW;|Ay#r0MfbfyDSxaG9B zC%wHO&MiNJ_^!_a{lc|_yQvOe-BLueDOqK$^6(!W*2xp_&=j3AJ3Bk)Nq3zg8LE}r z5S&Y-O8WUsJ)d7cw4HLkMQ_If^qfRR z)oE8aiZ|TiQz_K%dlF^gFFhltdl@ zt*`B{k=AJ0xGNGgFVvsJEn{qK-2F0%*H|^-p%3D}&Sc5=r0Ax5z7Icm-b@;k6Eoz< zR1#a0yEfLXJmwCh#kLYd3$&bhmhh=?1k-I&?!frs;r%lhnTN9XMHql!%Qx`?qJG&I zCzjvKbU;uS$_tjmS=`%1rBvS}_P#I^RQ@)9u=pl@r~`%qp2I<;JPi1_b%<5`!*bG# z1eGa$4_o=akBtSrn0;?ypP-f@`U?9gFHwK_;?7Gw>8oOUdO8jR5CW9~tFFI6t^^X9 zI}n>BjN*tNjL7W$(zQHLNc){!xx0?88Wt0)b(j+yv{tP&K>7bYjdUl(5w@R>)s=Ya z+6u0~cq^Jk{g!nmz!)5FItHZgWGefW=t3ANZX$>T;2GPJMH#}*px?7C}E>~HH!yz3s^F*WrRz%v88*P{H) z6Iu38;F}G;+`@h@uQZ>3PjF83Af4(!I>zKARke1oQoB0ShmpLO`PFBxJ-Nzh$YcC4 zJL{Ta&KuOk@zTR{GX%;>%F}bh(Qo}(TE)3Sf6i%>q}5G83?iR>aIlg434uBALnjkg z#JVjyVy~eId0PUrK@B;r#Dyg65^u}SMW`mCGke*y;5V4;QggtcKK@SKN+H$zH%^sLc#XkJ^XMYuN=iQ|l zJYg6q;7a1s&pRQ$4l)S8u~NvO#@9qgvu1M(;~hrdVa zAWy!O2CH6`Z}++`wI$#Lo@7TH(DB4Cq zgQBTP40{vbD85j_Oe%j#ID42qd-rZ@71a5kMAJ*Dsa=CO7uNC`n4EnwZ+XyN#u#j| z0){C9nXXt{TemI6JdB3j3lE@>S6kk%Q=wW}kTMD=Eljr2V>2HJLzfRru)h)R+EG|H zk37%E69h_6(k23YPltcHj3!wN6oybK@>&Zn!P5p53TbFq*ut*Y$kbG*MSs#l{I;gi zX@RG<26$Uz2UK993hG}bUu!M&nmsBk>k}=$wlrcfFsO|@hnfIv6?!$Mcv!q{Q0@Uy zM+(pzjU8y0-|+HII?1?U<| z`5iD03HZ z!GD@Y`%R|_@%hmHK!1@*GV|?ECpV!1+^KjQC{+_IC2krn&-BL5>$`TlcMD<*CyQ;g z@=-ItlMikre?HhAaN{>$D<55&IUddaE+XfSKK++j!{}MfaNlO3v8_>Ils$X+Nqwr) zEjRS`5#5$`*<~qGmoWhBy|RWC2wg|n<4JV;l?_5ip$Do(=ObXhMNx1w{N1J~J&xDb zC&}bPdh{I=L}A-6Pn+>T`N*UZkbW)D#k$ zi=l(Q9F`(2oyBzpx}DO(Rl?(z{JL>IX9rOm1e~!V-;5vsoapFZ8R%XQ%}!1tOXc>? zX4=dPvaG)<&XuQ{ScneKf$sSCyTqsWB>WRuKZuTMQ`ulUIa26ieaifMajoZg_s<{H zl~lLr$Yz{ZSg9!2%~%hW?+2$8Mhh@u+>hb9BVxfjkOB zfWpPS;tmR>Xvw>A>>EDnoFSK!S}Z?|rsenNo08-GIiBCY9*Z9P%BC*wiJKKfFO#x$ z){Gu|UbhBjgrTG(uAjRgb13rZh?d@nz_m>c~bb$(^-Jg&cD(*nsz zl_Fr7dgG8aVg%0HqqnhHHM%LXZh<%)ojHpsRi(u#$S2wWXF(DqehD0OMpvB568;-fF4lmEm`xB zBC?ve+N5q_V~rl(@`D8^jp^h1<1cACZ^V@~S?IWO7v(bW8}tVAWj|REGvEk;DmX_M zqY~~zj%`YuQdJ;PX7ZIReu!sq*rh1oCQ_n}#Y6A@`_-E|I)r9Cg@yLu{(FJFTIOlq z3YlPc1?t(RKtGumL)VUi1fG!1wmjqbF4M@s>JYTT!&4F@P;41t+sfe1lF%8t()d0i z--3f(uV<{I#r)@YStZNg=2=eH1jv;r*HT+sr(ske3&*pg8{X04Ez-n4jXOYxqp%0r z5O7?vaZefEM(m0V>cOPF%8@oLL8ZfMdHjN_=(OnUzo!Wyg2yoLphT(5+h_3~z@iuI zet&r9kGa)xoFmPFWaYMM;0n7Wx3Vn(Y;_sndnVTKPqkHR1UdOze7=n8AsR z?Z3wd(PW=0RQRifN%0CT#Mm`$C}sagb5PDUy|gMR>;sA=csf@<<3^5;pi-fQ1p8|n zO1b~{6bulfSC5P0C+`%dv~;fu2gNFToDHSI{~iYhMjuj_VUDE;jv3{2Yd``U2LHh| zfxYoxn~vbsy^ogF?b~i0YX=}NA?Gs$TnlAWfk7@TI6x_qG^nixRW7*INr4f=H7X}p zu`+o_(a8l7w3`46xHRJQg8_kFA~r?>X|x$TvEd|yGXRE2@TqVCVx>SSp#6CrIo~at z)N7qwE{&l7NH3Fc3C+gX831SkMeuJOb&TB=w3)|_%+9XD&}dmX_QBshkfPKYj7C_x zX5;1M1)Y|WDIj6Tg<(>V+uN~dH3eNdGb&)kgkEoXV~{EsuS96QL^5w~z?bl7T0QnD zt^aW;5=5EAc|l~~dDj|2Ab8V%tmVOjpKZ)xua@^m4cM~BnLyp`FhsA82Uy6NpSP>@ z{oCoz8S?%s^?w-YZlZ%0Kp~r6hvf=NI{H^Cp80>NQGq9Nk1^;3nKYOSM#vmDNMYUl zAUYQr8ynj!9b-Zvb^o@TcM}h0AcR)rh(Q4y3vgd-uPXU|3XA~|Kmbs9Uv~g~BESd$ z(0;sjPc-f7N13@Fgr|hyjJyQ%4IT72dza(BD2y`DCJTyS%)#1?xyqj^z*J-hJ-LtA zzlT@;T^g9=pgK(DDV4E2KHPqy>U`-_rL^7s4x-w~d?#BH|ve$XHT z-wmTXWw~e5XYAHq*d?X003cYjJSMX@==3x&ca5Ej_DF zeaN7aZZ)CXJ-8u(;ZmGU1lX16iQp@=F+$ILDsZo^ zE#e(6xeU3C^(lVDOz0NlY4*3i^^@44m=Ci0~@3E`Xu5h-{<${UpqeD(&*mHc_p6 zR-N-L*0|sbBgS;`^sjy2i*MB?SHrjh;diMn**R%V;=|O+1MU?*y*oOM&;H z!XzKKnb_0I*SC_ib;bT70tvvRcR>6ToU7tp?qUS-O-2950(jA`1m=YTal*WIP~QQ5 z85y|goy}t+@d*hjWX!yQsU%l{5!xiFC{$*ZZ$!u#{Ezw2NYfFe<=3q%r)Gb^jWqO^Oll$O3uyWvHa( z2IU4K8l4BEadXDM=GxK~+JKBgSU9zsEH+h#Spb~l`}J|P5pwkRRZU=U58DU5 zVIpHv=h^|G?!eLb=+Sa4idla0HQWnf`wwDnfTYwJ3oPvw(!uK|ewQ;^KW!cClz zPM99LF1_U2kcv`F71lx`@nFy9%CD~cm3>EAu^tUA72Tzkj$wPH*ZHuDoS`G-f5B2+iO7r%91k*|IAgM^*U}!@nFOzJ!pPg)jGQD>*o)R@ zkH5UpKZapMC`~{+qph9i{cpk-BM?Ao6JCXn!3CV8u@Pa`oOd!^Lbj8lBTnc9tzw`k zK@F*_ABT!cgiAT>{gD#u=wZG0Ap_P2c)I3HZl0KBxGp`>cxf-&;1}StfT3@+P_}(G z9KH_U=kq5BtAy4sK$+AD2?`Fk}?hw;fYU#rxfu7NUzg(>d~9iTs&Qq8I7pAW z4!vDETwM@`w4T(IXEikFcS<)lh>OswmKrGW;_;jDfBJLw{OI&_&{P9VXeH$ z2+W(6PrFUIy;-WvMPOL;`1Uyvgh&0e(=#)s!>Rm$o`epRh=o(e+>vq3T%GJTMMGR))7&5=H^%1F1~rXyvD=ADDZ&%u&8FE z!g41Qn!4EaqN{c}<@J|>tor1C{Mx!&Xb|7*Kv`N$(fMecs@K7S2elwWFxdyH2 zr0(VCbve+uX4Nh0I*#3SX>4pZ?0PUeAxwWY9#zxUcK12~O>{(K=ju~g+3Oh54`^R` zbn~0y>aPTColWhZY396N;J6cqUu=(Xl%#S^+a?0%|^y*F7wRSnA)gdH`6|_JW>?Nh8 z-L9jeAw4}Z5#Pa}#2t$&RO$zG@Yfa_9uM+^!s=krbu_ECR!37%zJ`k`!uC}M3;<9M z!-jg#Pb+9O^wFMk15V*VMF$a<}QkDz$^;f6+DL;?mI z!6*yC2z(<(xNac=SQ8UC(P2Jt6+(GMijNdA;OLIH1wJMiQx1V0Smr=J7`;x3Ue-!1 z9&M;N2u?z!Bs!15(|zS*;FX_z8`;_SG4&zdcMr+lweO!2r(A2Pk6sh{w$wrm72-sE z2VkEC9OmCZ{b!4myeQ(IR8NqnCT?$UFI)tPH^ES2_Roi)?RtI@yv!}`(yUdLly&b# z8mftwrL9wPKUa2KW}()Dh_>_H`S~Hq?+1E#;|I>aH~;;8c2k~k#?af4RIuMc$=4I7o=qQDq|55gkU^J5);X~{J1BP zY=gEh4#DlgYb(Q(@BOV?w{ptMZ$bB6XPtcXP)f9!PnlK50ET5CBuwG_hK*y{#M?r- zO3{j4y6aBNq_#>DaVc(=4OM*N!Q< zhl58PdbKtwS3tUvr2fs)5BGc9W63%}znoNls1VF@&~wXl2fooX(`$S7FZ=mgKv#g& z=Fhuoo6?GkwhHbR^N6$ijW?h%$&~$$@IY2gL0QG|>%m$tNRT5+z$^o^MT8n!(5530 zMot{=ul&=40#fcC&Tp;ut=vA6@^MOND`Jv_yg^w92lmw8g(Ed^@avFuT*CrDj7+|! zg2V*~M56(BnX#{vkV?h{hf~@Z_DBbjRXewX0jkC1146BJ9E}Y*L^8gz>RcJKYTE<=u#n-duJlr?~)l7=J z0lzCd?!f}@a7&Z7%5pe0uij`LJGm>p0DlRSum;^irY|hPCS%~816X=6`rZ?NMvIAh zu0Ko9{+-VPuTh`<0!k?`_`);>b$2;0b$H&aFHy1Oc>~wOWJOU&!peU5(`}_N|ZY9xW*W>DsWDKfJ zzRFx?vg8ZqUpOl!nw^WSPUSD%!E(x0E*yWB<(&M8?H|UFt7D%{YU38G`dOy}+u!e| zm|(_V2T=iR|12hI!D}dN6b5OYRBLsTO2_5abaeEVxAGkkmvuQAj>xqNvtEL1;i7!i z9pPW_?d*i7Ck9Wz<0!c@l4{z_{RJ2WFj758q&*6NKT`c3j!U#`%{91M^@vbXQ%_F0 ziW8#J$%-0aJcAVnuk8X{#7^Mh)p`1~quZIL)?u)O8>Rp%UU6YwCI34xS+)3j_Us<- zNR}aCC8e+Gh2eAf0-rD^HPRS0dEm=N(GGk40jDOuJ=wBt=;{KD3NNU0SkS4c{{gII zSYWb5chId^vKNrXhpLH=x5H@t{X|Bsz9}g@Vd;mu!>ZFd+A}KXG9~a2#)5OabVO9T z+u!)A)vnLdV@s8aEIDf(oorr>1YX0XRh2Jk>6G4^ z$uRD(AJCGSY8*EYypWTug)-+_X?_DTLNo%4<|`0bni?65T$%-omaN;_uE%6h)6628 zeJeZnD9#2=ip6oumb%vUUEQV@fxPmr+O}HzkPY2E%Avaeaq0d3+>QCa>So07JLd2r zK7U<_`!Qoj)^QYc?sGQTsXQJlc}begD+xR19PX@|pVfEc8q-xsbipGDg+GumSRgun zk@-gP4+cJRvm{k`kCPYF5HHzsGQ)H$@8yJjV;Qo+w4N?r*znc87WsvY=iOFN*+mU=`!0Bi9h>f4~ z2?-TYQq+?}q1F6$ixnMnNL*o1SYyD&+*Hme^y}JT@!KxSd&P@vsNKorb>}wUpICWW z>pKM3Vay2fOdE1Y)X>pEC4awv(ci{ceKYQgV7a5;l4}hpjxVhi2yqtf^uHHC>{9CZhwa?1JLbCff*BvRNmXv?g zIl!9*W74Fb=fp;2W9Uw(uwhxjAeSLvO*hUYc*q}{FGfRS9zV%{u|5;fr4L|`)1CPx z{ms_^_OsiY6|TnAg5T-E;Ul)e^ew5>4MtP9BTQ)K+hcj3-fj1H=AZSU0sL*+qk(pI z@>mKXREq4E=5Z)Oqe(JtqlUDlwZVtxKj6dNy~eaiFcc#&9!3esq(Y!N6%`f9B)R;~ ze+C`Zv_$Mf(!8MUP%|`S|MwnclkHa65Zk|=YeRQ4$*1#P>__b|${`onO)=L`P2wD{ zcr@`N>3P*K?{aM8Mf`nc78VVs&}?g=FwAvu1|ykVuBxRO ze~YIQ&xYb`_uQ#TUOiD zLkHXG{AjyG{P)rJB>ySp0jAje)lG=TDNJPwJRD#Q)t4>>3kN#cB60UHmF(?nK1leH z`gISJJl??bFwltAj%WB)xaqAi6bES<&vs}T03_u}nR9Y@56j3ZvHeHH&ircaw~Go3 z$2WKsk|wvcn%Cy%L9f45BCY@{Y7{bB$vtM`VJHGx#P$LPI=80>C9?*mOmK^*F(wn#M=Fv zc*p3m(|^^TU|hOrwe;`gXfemk?fz4VdxSTlpKfxkyo`{yH#MUs4iVZ2Gh=KDjkEto zlQuZ_t@S{ss=Rt`-oH9cOTZ%%!FVtqx+c_49%)9vcx}ieyq)H97u}fX#G?P{MaZJ$ zsN1O0sWtsoA2DsMIbP8}1>jZU_+)u``)~u?@6cS&ObfQ-T8%2$(heQ%?d|!xs(9RZ zz`I`fj!xNNnDaDxOr-=+VpO+=_Ou4=hMVxDTSc^9SoS(QgmQo{#^hg=gsJ|t1n+P~ z8aWT1S>fz7+YIn4u1m}Iqq>zfU@AdTYs#X9Yc-T?@|BsEmEGRjy00(@A0NN=aOYsA zW9WSU^x`&th-?==1`uYThy*-Yw(-J<3#$?7S4*2GK#tLqTne4gH>-{Rvg ze%k&m8TPL0za!>OgSt#9dNfK1ta=N~9%ZO3x(u>E3Ob)LaAg15h`z}CYzA#l*j;QW zDZ$nS{O?Qsiu2&B>S=3h1HAHLq$ds@r8LzSf2YkjySla~m_jvW|9-mPy%zoSF6(5p zC2tXCqXY+zt9jvE%=Nzj-GJY{0bO-%fA*%@Fpe=_cXkGB5e5hZUTKp~x#F{#J0k>a z&ss&c2Ft;griLiz&aj#`se^<8q6GF?8+q;3`hlbh*T9p48!Qw{dUbVlOg9D+q(i5H+lSHFLbSEDmG&JOJB!?Vo+yJF zTkR2TE7_c&l-|!^NBM{x5-v=G=s3|t5O5*+r{Qcf&2=*f6V{76g1cwC3fb2#+P16U z(=N7JGq&>B)(#9X8aa_%4!Q8_0F&`=X@TO*kNL&4#0r%q?V!LIi;RGyoVy$LHmq*i zCLx`Hp8uBrHMxCf`;z-iyPn-_{C4r@zXTxl%DsqG2$+yoNVXR?==dW7Hhc!`ytdj%0-{uQVgaf5vj&fX%vk#F6@S@r&A#WzJ!#O zRen~|;;Pe1;B{IqdeLkqge^CulS{V77`g8?mSwo_y)7L0s%)uGcDm?#3#Q`)55ok% zJd4*n>&j6zE+-14qKWqJu~&GH^M5u}kFoT$m#YOgx!DP1IG zD}C%;aP082=~5b%AF5o!*||(FBVq51=Wlhs5)qMH1lx$tCs>6o$QEwSqEVf+)TyBa z&*T0kG4D)4M_Q1;m=*K_=iCW85_{{K+8os@-vi?wrT9Yy=8F4vvE=;&pZc?X^8e;D>D59PDZ4 z1Pu&Yv_}Ez4~0auQtL{%h{tDVt%S?}nccleZg-Q9S)Yb}sN(B$xI)g9H zAv}6~?1yE|R@b*iGIqop*zYZTXo9{LX8VJ05F;0BuK%9L_b$xt_V-{7@$!db=8OctN&CI_6x4rU}uLv#aFVVbP48l{!|3{ysj zZtG9d&VfFfUQ$s`V65mMe3tHYWsQ$vk^!!MBL5u~u}lQ`(#T*E>xqqUhX>-^g>TbR zb^I73tUuMcwG}Hb_24$%(Xok_^$qC29rId#GMW+~M;AE-i;4VkLpnI_5BPp)?Z()a z1@9lT&TXV6XE0L*jP1QkaL``eYs|tr{c7|fmR>&VF5z|fq50q$onVncP>qy zzTA1nprfmAp-;v*D2tai^Lm<%Kc}gQ8k0;71oz6}83uWonVE@in8cG*Z0=5c>K^Y- zVVVKD39u`WWFnCO0U73aHMnk3nGU}juBNA&AKa1JzA0IPi6DnsPhkWqiB10%3WY+O zVHrPnE3+7fLUW;Zc+KI^?X49kL}CCNC@O+AUWNS}53JrOO!;L~*+)lDyhKpcqafM( z?+Zbx5#vg9%WvgM@SAHC`i~}Tv!T=HJQcvV*Jz1beE{S5>eulcNO{vlDYXN+10`Fy zfgB{LL9()OMhWTbH61k`nGCHr!D3Y!gc!C2KZ~@B)pT?Oiu9n#Hku%E9qZHX(mO_i zzswgq9s4OW8yzlKA47=lR*|w2-dH&eT+TOj7o83=jyfX~OtqPA{Wp5?7o3P+baUmjTC!j;zyKE8tVs+JdQo0IvTi~G5sLqOW{ZN3H<=<-5y=k19+<_Cq2 z1(n4?DV3P&CTOa_LLd6E#(#gG0e7g%Uqnju&O(23DHh5^U#4}RNds{N){PiLsS>@) z4z-zA_dZQXRI@8$Y>^!n1mNY_+1Z!(eU~rBmX@Bs?LKT~XXo3!{R9XxkME12;3*9_ z^ja|W^N-Mn#se|5l_Dn!tEc_uE*-Wen_Oc0i3jJq z%TWFvhxrLc-_)g9)2$$=J9lG@N-Z21XQqpS=1dK@5!S&Uf#}u`cIEiy z%UbP-7r*ine_LEEmYMWf2A6ap`q^UzT>{CD+1Z~LG%k0lXa-fH+Vo9xQf3doc^_5uuv;I=Oq5ZM@)`LY zriNNZ*64W*du8>5)%c1~***UWK?(haXYabCb0#DnpHDHMBNTA=zLsS(VcTWZ{#w*y z_z;xZd=UO{@F!_bkca6Ue;-J(uRm@<=J0!a4F9rL$~5GC(SRN+J80DSDKXK}acm=E zrhK)p-e|SwIP)DjI2+|zR2<%fPU*-+6`K|pPms~B_i(qwbMsc~tV)XDz}a18MXBn_ zdkr5x(C0+!9TFcpa6ZXQk@9XaqB)?gB!Q#=nY+L@=o3ka6S9qZ(+<1W+;kw6uKchr z|GvVzWeMGLjTcs^I4agW#N$?fMmI&iONQPG+&WY5b`j113xz~e(o~UcV)dxrI9*?ug-$b|^AhJcb=cSmE|&fpo?mDW>CG?RNE)=@sz^1t zqby;acvUE4ggYwF;fV!Vae|}rbcAX5L>cR3vfZc-T?@sTsRcu8SaxpanyFDzN+Gh3 zovp~ye3H?>q;jld$V%~9aQ94yQp84I9qBFmgp{vMN`t8UU z9k~%5UR;A$m%>gL=+vc?QiaBKrx6&5<`Du8LJ`j?N5To3c^7Kp#iP&{t0c z&(~EVlDL*|?}n*q+B)knMbyR*8=h|6dgqM%1uOXHSNA#<7>;-3v2OBkUgg$t-&L6E zG)*(*=~%NzG7=RPp#=CjuEo;Rr6@^|bWhQ$fu9U*)ODlsx`Ik6^{c(kg?bR6WT6l3 zYhZM;dx);mkt(wC{<)09=KOywfII2o3u{P%ROp6P9(c6C5<$8JYGBZ*W=ZT^1)a$o za6$mfmmPO!8sI)BOdBx9Ge-5uvg~dR5^Ryt{4!jMIk|;B4`_Xph$ea%RJF?4HG z7Fu1uU;Hb;w}bV=?fu&?FRcjlAPDteR#jE0Q|o1J-42zKF@2tvL(pHU+bpIkSg>-4mujh(rze6&9t2xi_!>dOILAX~r$jKx)S~ zT3J*C><(B?Y*vyO8!d}~117ZjBUm7=2}lK?ico12jB)Z{`i6NVF)@+_4l6w3wQyG3 zVA=On(NR&o=124{;mG+YO6=BOXIw6`^){>bxJtj)d?w5KS$OU1;M~ptiBoKKSpnmN@g6v704k<>uyo&;y9;dh(UT zGMnda9Dr-J<70u?RF0l#hL$#19B?3Ue5|4(Q%H{vL58pyVh|!|;bZe-F@-@^)tk=D z&O}p~8)f0m#ZgFg66n1}@>%MI!)`)bO|_hDkb;JW#%8F3(2lN-@PDra8yYnx^VE-N zu=r629~-qRK)OS-=>a|-Sy{2NHFXVHtHy;ws>xoF;$^HIU%$f9C+@%R@Z^#eF8&Uv zegQjs0Ty;h_DGCs1Nye)_8j<}1VW_{ZpK$fAcMOhGHM{4X)y=$4pUg7nf`c3XvHbF zcyLPn`LbEJKzmB?F;isZdSJ5S;76m%9&O%o__DQe9k7@jL}|mVl9iops)d>!TD0IT zhn-!m>BBhrZ!st9e6ig;@t8n^gqB(}c2Bmt&%SpeWF}dfruA42SsfVFSDh#hycRwF zlol0LWk>}{WX0PIyDOjXrjnJj8e!|E12C_Q<=7C*La%=84v=M9AtG|C= z&>TmhnZ6a$a3{DU@0gBLWLH`j=?0rn9C`U-VX;cE+Ea7tC&HdLWbI+E^Gtw%ds(CT zosJkT&~5|2Q8ZiMyYO1Lj3eR5XscnQiV}iq!Pj3%-RC}Oab)ooEn^{(aNsYY+GXrb zXdF#uXJk(c8&w{u0!<*(|1G&2$xpo*P%ybP&O`&s2;2sEH%MG4Vrf?aWWb zlr038lET=SxW+EYCLd2og(I#Wucaz)St9-A zzLt&-VkQFa+9@uCKbtxUw~$b>LN*w8)9ExVMjCSo?Q{wMFBkxZS_owkRQ{x>puiSo z3*{z2CJL8qhtUEIRDd%=iyR9ovdo$&;IvWxj&-*cCOeXfj1+iF&uM2ie#@Elh88Bh z5UgwBS`((_oS)(Rt*U^_OU(ewBgol+;0HAgjaN`2OA#xF0(WiASc$!_j}Q3xs2dqY zg6^f0w~H&>ft_Zo<@#|Y2eSSpKu6F%(R8RNR$VI%g7E@X2|Msxz%5t|kW6k(L!i}6 zhaA1>FJM2@fe8R7iFvdQ%oqGLYaUGwHYT;1&Y4@|)6+ojV61*8dvMEV?F?|^@rM|JJM2>otXE@G6K2c+m+u)baa2k;H}}EPaHp=NA&X5p2SRKRGtZL$s^6Lh+lsZG${dU$v*wtoO&o@;@>5 zIjFo6fNm|_!$?{kc2dg3wAJJ;^hB2~CxzdfZC?#fe_<%kk)q%hVR?or7Vl$?!Rfk&_YrH!(vf9G{N$dF zVljKlHHX#8pZUyb+uiw}MK#2T(i zG^oQ@zz9U;;X$f+%Whc{7j$!86X-$7p4jc+i!^vkw26Z)_D(fiv3~0h?zTh6cG3+( z8s{fF@J7-fy|&8qW|&sHf`w5l0&ApRYIjwK1iMntei6+TBd2HkRNltqnq%7^fm-{y z*qOB^ke)5N&l=k7Ka-D*mZSd$j{++K1rYb>Kco5Cqh`0=pWf_;b& z#(fNV;>#LQ#TjAfgtqm$PG0RfI+TFM62YKOG$LMH!|TgX&##9{#3dw^IGEUR!QG_@7G1XY4UD`l_UbV5 zd7IuUws(K?TV)u6l@4+pOZv0}ex~T`HMRUZys^1_sx=}6gY^8J$fM0PN0gKT@iuI5 z`_(LQn%M?_&5gbY{{H=W=kgKILTxb2KrvAHF<>}~l36eYuC&F!9Qe|Q`zA0ny6EM7 zmV&h%4f(IIo@-Y1d$yFNHh=kvkL!J0o|Tb1ii(jin0od8A(-j2`$-U_L1JO9Mub2V${S?PDzE_G@N^b{iR)vNj&#}C=Hs%s)f4tvpRv^jQ_L~P{+~FpC(Rpa|Fea*Z?d64rzvEl} zm4qZC@wLSs^cspYlK@M|W&H*j2QpdsFWkTbu@;G#YYA&9=2{jK#UDqk86#lth3+3Y zy_Ng#NhjB@w6-(qp-j=o$0Zi)ReMyRIVVILCN0_@=jSj0?mZJk3Fj2EB@ z|Md^18xE!8S3WcmywqnjZ@2_UCm->jabc{qNvHrZTmvzz7k4a^4L z;w%s~_lQDQh~NK`ns2Fu-Ux>0z+B9Dl^9tdAVrwkcktF^6`5rPpo;*vEky6yFSp)# zb#LWl!BH^XOv2Vg=KDbxvFZx6RiQ==N01f^X9SmbkW1I-*OaDepoPAq(Wl=jy=)sn zEiElJqikT5GWzeg>f~(#ON7_MQ>Lf{W(G--O64EzDNi5XipT9)6gMl+XCH2+?N%S^ z_50TQV$x`~xrblpV>(rFK~b1sS<}djBj{!yB3+01ZRDXz?~SdXPSWWY2L>qAUGk$C zeJ`j~a$A~9D0JmxHCjp$M9bvcR|a0rtCg<)Y8?=pTpbh{-BO;BQs+yK`|I^&WrS9d z5PRs0C8d#orDP~i6u8;%)(g|DMYZEP&gg-QAcNqc#uo#h%i5-Yz131qiz16VZysD- z41a7_qQ@q{6aPyz5<4N42!0ycYbdMq&dabp zOyS`0W-c7{Fmaisgvt!Mj`Bo3_B|<~Q=hDcVk(SA zJnSj8(BYcC-T7fq`!O`*QT)Tr&8~F(5t0FhI%u`sxjR4bp1zma+E$rt$Pp?<=6E?aA8_vPc+#fs{)unNTo9F492%PT?{+B>&ZU!_W1YVs8u;c z)~-NPumjZpc>DB6Ph2l>m(|P{4 zEfLk5qRjrO$^sWE#t|iLHqW2;WaQm3f7?$;e&>%HR6!5-b5mw9V`?<_)^wt?wgZQp z>1_Rc(3%jY5907PDM9+?kkL=DSn4}VgQEBwi7dXDx~igrIqrTbBBnt@viTqP*l)7) z>9i(g-e)aLY9T8gkv1wPKc8{S zQ6*EvCV8KI&}GS7IW`wvs@xIt8@EZyOdSj-67;Ir@)LAx$#XM73o^HuN45k@Xm070 z*g9RNYP^f<=Z8Hw_`zIO^XZEHq5qg{r{|mH3z))Qa>#zA{`$HzcIV zcRYWt_c!-?dU#MF)=RCkS{Ylp$KPgbd1hNGoX}O_zoVAf)Jrs(LRbg2WD2-7#NF_9 z5p>!XL~Owb%~YJg(+uHs;Pr`^&@UkKa9daDQh6_iFRebYQ;6I53LRpvX)?LVOzkeW9shVvDq>T9&Ady zW%INPiRiJO>byH_a6_&NA7no5vK`s(n&9XMX(Pg3S?F|39|%Pqju+{NCC} zP47=kOf)~}9|}eUfHxBNQEGsD|GGez`J26zStN2Mt0U;UqQ0SF#3R?uT+!S!BZ=pA zkM{(z*h=MuV8R_r<@n_A3nF#5 z3>DhI@&!L{yRvaCK~P6o89%**mz0$Pf0MKe1l)Y_xxK=R&O(kQjm++aLRe~4?8DT> zRaHdzfx%id;v`OArfx1&ULJqCqz9{Tn@;RuGGu=j>?n7Ld!4ichl9%vUMiZ0Re1COO zzF=^Vr^__>a8w?4HxeCjSo`aA!qNpsq|NacXQw_bAU%=D&dP)zkO*@2w0h=TPEZYgaMRv=9QDnOHJ`sc;bk!%Pmv z)U>^zY{5dHGOF=PhaRVaA;~;a)1lr;jD0BmeQNpAKvlSYwI!vG?N5FzDF2|lrWJAm z*#?8F#)28PidCW8B|k~Y8qpfm1qEM3D8KuT*21Hgy=&ZE1GVKYmi`mHaM;kZyX;Ju z-#8H)@Mm$y9&|a9Y^;+7(6OAz%!h8R-UOaMTQ%KD_e2M#NP_0#)oC3!4%!UjNGkr& zTmiv4U=LG!*dc*-g58M?K7NpG7HPG?Te8HYBsjj8|3K%AhS0ciR~PHNk*E!S|;AXVm?}hjUX?@dD$^-{=a<%T+Hjrf1~$ zy1RvvHu=74NqVD7h)=NDb zMzrf$?R=VYWJe~E*_H8-162XrYA&`o!9r$ws36KU^+Md!jjNX*5r;q{iFzk)S`TP~ zV^1Az-Bqov!e-8_q1`G3=TRk~Nrxwy@kxm}gVRCR8ce1te^SmC4HTjEpp$6&b}kGQ zjF{yd3H!ks~8ibHsc^){~8hnltOS@l{S;>n} z-#K%=#18G}E4}i*2^(5LiPGOI&=K;M`k3{NRg{Uoeu_yNL9v0qc@K2761Q!esla_C z*!!K%F*EPXPztYWhz5%cBrp0e*hc64exho`y!O>;5N+ou)Z=u=jy& z?Pl|=<*Y?b>ux~)d%@(vUs1XxLp6sfV<>|WXIQ)x);cG0IpZA=5SVS3rH`S3HWy8D)%Mt*8jvZHr?cCbgtp4v*23vMn;2DQlr`p|ZB)CPddGRX?~`YqtG}F^CLJzR0ZV-of)U)1LWy=Ldf;+WtMZbMb^7R&r|^?s&)J@AYOwXtibEFQ*rk z;9l7LqXQS!d*LUx=yy0Atfzygu<7&#ifmvbLltl~_-x3Xi=qoQqK-l#(|SI`)?hrF zE&a~v>sVIFJleE7>=oaG!^Zjfc`mydHa8CsOa3(=TG*I$=n$X4rrU|F<=P@F2D~;? ztf~ke3J&6y+L~BC2-LY=y%7W~&^thde%c#8XK!AMd|Ux)T<6ISupxDmuwI1|g*(wP zG%m%cn*OvR`!Z>xPtU`+dZ)htR#LByB(Ih1e@*F=@e)z0c;O#zZ!QpRm9~t7^=)(b z-;ce<#&4nzE|0EN_TE*sljmN8`{co`FYI+6CVB{ih@bpk&2zO%kqeNi+ga$%^y)AU z_s*<4k}%O1Q1*f>Iq)lrXz@Lz3N|W1)Zkz&ZSb>A+;iOie~L)OiZOjFgQAD)vi#bQ zwt7y2Yk2EsJPN8w9lHmnDV`}CdXp*JLU%=PIhVi9ToYA$Nb3Ad#Fs50&`nEXdrkwY z;cU+Am1v4LMMVXkQ)}OT=;O6Mdh2>;i|{m@qQJiL1J;E4O$%}vG7@V~w1LrwtU!m4 zDS^B<_Hb4gw_WADh##3@C*0%0)nkYp3Pb=+B>zE68-%k8zTP!xw6U@A$7n1V=KQu5 zpLJjw`V!XsI-&+qVzsyEWN&QE9lp(cx7p0$*oT{^DZcjfL9;k#QG)Ft=SKA7H$S$y zI?6-Fr$6(%sJe8yoHk@-s*h9HzA2vwVJRGNsp4Lt!t#C9{bR%g`K>KkF!3;(_@_Rl zatwnPYjXh!3ws^%R>hT%O;2Z6!4#UlYUWfcqulDFP>R;)0y!PM$h=ub9M0ciz9Fa~x_yf!BClJx_~n{YF-7c~=UqmCN#4V$7iq^Mh1srK{|{!mFZz z+dtjXjk+X+W<#q!y$!AZnjU+inp4aXYCPx?U%XMz>Yc>SKDBEN5;Ms8jKqA*&dhbO zAD8^TncY?NB^%cHG3;Ir!?~?3h;{>E2pCl3NE2}Afa`72lsU{)AD5S3azT^FwVev; z;lBGVB6$1uz}3;gj&PbuV1kDhU zM<7THZx;`82EQ0ApC_7dYFCpcmG&U2%x^CF?6P;BJORey7woQW^n&yW-(=gZg5TB; zhG{XTLhgFvv77+8b35$bd!vXNwH#U+yD3B8o&Oj zvqk0$;j-E~&kepZhsHljyyPZhW5LefmTFi_rSIQ0STZ0b#+upbImpj25S-eDCOm!u z*Ya0y zWqBb+y7r*9I*AEP=|r_Ug4Rz&Vbro#Y7A6=FFT|yVb5g-=(tOWNqc>J34%M11 zrO-mLw_Dx!YwPqr5%Kv%do|!fW+b9r*2f?z3cX}N!;r4%dHve83b0It2*=w{sMKq4 z$!ouABcC;$pqinQzwK8K#W9R)HIykp1NsqafmXs(F@TmI_8#@8&YdtpplnnG+H;tl@j)sBZEAqDdNCXC*(bL#oC)hQ++(~TiCUCkVthP>j|uL^ zw>gDHH_hYZ~A=QVl16pCDaIwE4$@SK0uzK4H5*{BKIu@@alrmf9hcVpWi znupaN^11Ic8lM>OLK>edM^l*s3yFMxDp#610uctfFc2edkwk$9oZ?0H#(gmP?vH)= ztMl&P=)-z=R1ueaJsVd17_YRmjU?ArbXmhD)xwsJId)Ml>SQRvge2cyGUBQ@Tp@hT z_MnKfra)Mn@Ng?mLB{|(B(C3k^A%1uy&uyMfCcz#6AC!woLizG$)ucanHVb1X3`I7 zuxYt==!UNr)RPJ>SA8cck2ZVY$p)zg76sH_`iiEin9^o&wY959RM&+@V3ukz!hp3H zqrO5_9pY5uDeoSb%HQ0yaplnF>2&WpW~hEUI3hIDj_xt%Gy?6=U8+~4kkL3cu8(tbpjyU z@U}OdO%^{pdf`f{^7|eMT+XCAN>#C=97D6`ub|z%G8HZa4cf0oiYPpL1|6m1hik$y z@(gjcMzM%)$bPQHORi0E2NC6TL|LF>OZ3{M?pGFTMFGqU`tfogHQ*$UTw`;fhxDAE zJ@7L9{WyC0#FK5-U@`DiN%X?Sl+fg#zZzrB^-16zC+dT~8GUT%E40%KQ?VbJZv1`t zpPJ^pkQvCNRKZr}*8YisB1=^Js?#ULzo+UXgQ9#XqsUD)N!H453`)3YhGhHa2J&g!_4 z&(%s0=(8+n3jY3^ZjCuG$BhPWEyI(@h`M>(FaAHK{sW%s{{J7xPmwZ{z1m22_LjY6 zJ7lknl#v-JI%IEUZ?d59`iukn06o{w=KW#W6Y za*jM3!e>e22042{yv6#Kx_IBrbxw-Nw`1w=KJ6>6Ci7%}MUH*$3Gc~4P$8)4Q^&0g z-3c1D=Gj;z#cv0Pp|tmkgFD>8vEjgvXIwA4Phb}RPE(}cOi$qn*Iz!CvYkL6R0@U< z8xcWxi2C%9x;h#t%Q`x7AHo)c!1elOpOb$4kLQ63Q5O3CPHKbk-{?thLpbS zz0J^UEhdjXM(()S=kLYEDBip>eOF($b0t((CE(WTLT~xwyDMWP36gt(%O3sOOJVC9 zLFVr_i}>G79M5=iYErZQptv>IA(xHWjq$K{{xGNaw<6DIOc}~qWESeHL{>>t-{_cz zu1nmk15vB&EL}30zTLTgf|oheI#DxTG!`B1dWhsC9#@n(V7tr~m85ywEGH^gXXRW0 z#Gw1htEL})M1!hK`6y{_BV}IH$=rTpZ7nu~DK5n6UZq;!*iHwtj?p{804LVpft6dm z!;%^9tR0_YJO-){HN-|dWoUGT&F6NtEe1FNNyAg7t4&_c`juudwxBELhdZv&Fz&M@ z@drJQ&)Z(idhM#TJu36Kr{oy6P*a3PMlxLtfE>+Hntd1=+n0nUm$v_+wDgHfMqPuD zT&LZTTckEBOLHid*^?STqtv~ed>lB2e!9bEP}fpZ2v8TGA@p#vej`bw#M%%2HCfK( zqY`Hcy@b-;n0+Ybh&guxl_^Al)@_@~hNPVae*tZZfPncEzhmn@mGupN}$RNQaWX4Xafl#NxVm@fsMyt%P#OnZB?f()mp=_4w}F)6c0su8j` zn{KWLKjeyMwRX&tT*Hjx*;jYJ9`m$(#7?13rT?Hl`H1Vd&XKqAM%P+GXT^HwiI_UI zkziS8g`8ErnPJ$ms!K|-O?k{siO#(s*{5pV*2>D2>F5OypGv}E-VtT^+jC8IbqNgM z(GZ}U#9c+*)JZRCUj$J0@9Q0B=Rb7We}DfEiiW&Yg4n{~j?jne;;L>iocQ01Ls}Ut{Sg?_?jlBXWsXAX znwrtBY$8LMO--p!c>Z?~oh}*NPzaxXzbO84B>u#;ey5iOq1~8#v8aVqGhB3^3V3>N z#PI8@$__A902DR!M$Wo-B1onZSk`a@$~HMj;(2ABGrs_Ib=^o=-_WbK`FErU{V9ZBl1FmXi-hbHy;5-kZ&h9H5n^j1<7pvyvKcdxktjytocXkhCI+J<1}#`$QFuFVZ3k>0_W9XxA9 zm%+>Z`@spqAR4ZEDUkfnu|X5m@PTlF)28y{4jJAe@5!tCsMNFdNBCigYT%l&vokl9 ze+$T@%efE&zvv%JLURO2UW1X?y1aqx-{)EG7m~^waGp9lOuxsyr1$s2v}4;-s$xna zQ`DQ3^L0kp0;>az$nnmvzVtM>g912x4QT0CBq*T{Oa2~nAc-=9%osdFTsnY`-zjxj z^fgew!zOvZJsVL$4j<+(6OH@4Af}(?&C$m-{qsCx%Ch}+_79)k^go{&@Gbyj546y1 zm-rt?KXol_mwwMyYX6p8vAw&Xh6J;+g<-kt7eJzb$*?9^{!>HL-09}NbVIylvjq4|V2SE-w3R_)v)}(*DR+^naX8xQuHMoBL zdkA!|48{|75r>mKeQzW}LR}&5$~q)U!?^oR1uAA_@QFf2R;aM|AG5kwR3bwt0P249&I2w$cpGMHli}Z_T(7ps-A&qv_SL#U)&# zkr2SnUpRtWGW+0yWA-6YT&!CET`O}z<4~QfWOpFX(Lv1sw2vY1p&{Sq57!k)}dI?jrw1NV=`M)g-BC|SIbGf6RAc)u3f<*cPzk9igwXjM3Kw``sxK3M-Z1&>H(ABj^jsGwLPW;|DWird`AU9DLw4PYMnq+=gjAYkTKkW^3o2`!4=xLHzSl&5lSo z;?8{8=TOSg7#lpRIgAKU$Q<~mEb>|K1@R0I_+g;g^&hrXP#1Sx)7Uutsn-IngMiZm zK{3~LDk3_8h`r|kr73?rzS(&`b?72Wx1D&d4^zDu41R}Q3q2o=OH#tU*Udc+96@ax zBv!JrcWr`QRy=@E<^Z4$sC_Ps z;z9BcsM?`r@E04fqgn2c$ATURK+%wx!7Iv06FT1=c{_ss?wSWP3kxEQrFMr-3EVDy?!7dgy#KE%ev0CAS=tiGh_j}VBZi1oj_hc#jJoDIr!De{|_ z!MKZ#2yjs?fYe_lgpsI4i;EOlM`4p8*xfI|X)ucJARZdv>l6C%R~gd_|}*fTkrxUT&CrSxo{S70yQF0T}j)No-J6o2p&0-B2nROxu7M~OBY zPuRuIRvsk2IGEmiK?#rZ;e^kbE}i&``k!Th5Zi*lOwB+2j8yE;cDOmvnkuQ3!*B@C z9>Jbd&YGE(Wzp~NWUTs6_!`8(VO)XmY_>s}Lc{V?y8HR9H*|DnaahJZfydQ)L9%xok|*KBNwODI{%zgVy0ur(Tfm_qbRe>-m80w9e z7(XDFkgNYgb2v%YS#@c{VEEYXecHcE_;0(B;VA+b6b#eIWJZp>%2{uNS!c4HzMftn z^2q6#gS$t_q=5vW{kdHMITp;(2*_g7<1@_%q8OL8@pNdJgp2H4g3)R6{uzjhm-_tu zqo9YJ57@_B==nnrNh%LOZD4~uKKBC|edj30NAY%oa)kr5D=LSOGBSD7>mmZ#!tl>} zjeJ@I-Xb^wsHo^a4H+*a?FK!IvS%xwD>t8h z+~9i*YV;aIK0xAQ?UN+N*31M*pt`=T*d0gc3ZTm^6vmxP^s9O~hdiJghD3MhZ-gHo zdqTCI_(umCCQ#h3)dC?I_*YSTC!mTyU;Ob`uMpWEP-|+h_t-_4WOY^GJTX+4us;^E z>Trwi<5k{iT8C zHMaw-!2awiBE5|~>OVi-9NC2OF#Agxnsqa%1&&RciL4c-UjVR-+MfnGxy^9S0Z;)@ zAq`2sH(&>>Y;Z?ZrhfhU^$kZ}TSb>Jjvg0rZh8S)R&&tF=>iZNAt57Zv;aL(z;XWd z+=0&86f6p-!C4BKf9nL+V>k=|bN86-M2n+i|Jd=R?|)CMxk0tu?ToUxh$Z)Grov}M z?x*SPf3Y)!CGt8j-koX*@NaL6q*@uwdLI}fupsjtegt*)=(0UL5sg6gqhy* z4+%0t3vPP-D)>3$Lt?e|@v6vM zvf80H+*m1QZZY!V(cW)P9jH;fkos?|LudgiJh^QdTldBzBklL*68zTC;d^+|M55~hklN%i_%x+gCsh1K{wn}fPKZI~1fvjqsMkjd2!>A4)f z>wq9^2004ghN?7Or=e*@2GS#ANh~ZZ+lw4N)IP@}sfd=&SD#sEQ3k-S-KMvu147P_ zD%;gvy=+P-`~7>6?04nPkf|%qt>k4*-6Wd}sLQcz|91+s?~1M!To+n(5O7!skU5$w8dQz-F^gGB}+@(&5MJ?#Xrpy%fTt`FK3H*JSL{qCH4LN}N!EXQAk^1b7l zxgOrssn-5uCJt4BhkmrupG;2m*gm86zp4msAR*v`Rk(|x{Tyt3dJ8zx6)DRI z@e>%YoG?G|b36k*tdN$LmL$<)&=F;RHhBJP&r# z_e3Y&Hl13+ObhaBh>;1khnhLaWP%aN3@-Va95w>KleN#x!GRba@tPIEUrm2sAOq6c z+W7xhy>;#>zP8jm^lGeM!bU;6ad>(0NGDA7Ot+~n^;3}oyxHaM|3V14r4Aqn#`mmKlq(^i+5P_1e4zsetGMM~b&OJ;1 zFOk583Kg$)(dj1frFS$kQw7dWq?fRvo>5j|u@8{?x5Y^i%LdJ;lt1nWQZP&-Xajv& z%jqTQD0;3t(PWU$LItNel25Js??HmqsqAFK>^rXxjU?v_rrO&0zw8Nd{7|Tr<-D{K z&Tmin&%e4qC=*7nkg*Z@-&%&pYV8Yj8fNUDN~`xjPl1{bkz25l3hC?ZEp^?{M|Ibg zY5=t!Z0-&$HwH%b@v=>O-v$^U2-rG~XsRA#oU%G1-?sOcy=qAfYQ5v*>KU|3|D7Lf zE&T&>?CvQac%%>UjStVmrBG=K?pknPjMY_ESwr&D5qr1a@ZWbRyPj1rs!gkrbv%3Eq5 z>yRN6L7PQ#>ic|VY>85ll0C?41a(S`lE)YH0ReAUT#ExGpWS$23;39Qeo$ueODHnsa6O z3uyiHWpOmlr`{t*DgJi{ZV6ZZ>L-sYICu0xP7sXdU;~xQwoKo#^VihY?k<1)Jp0S^ zM>q3>U(^0WNbH^Oqtv=&~PQtn7XU1qVv&?B@ z8TA`|uDx79qDvG-4{TAbRI3mUt|3<{DW*8+x?`=)A4Wgk7d z1L{C3O&}(C(#%PKOf+bi|F@VU9FtkCMT>O?lo6SKSs<|8?Bm)iHe&d)!3*M_Iruy*xb0NRK9M3*H#I30u8$|CVc#5PH?)9$ih1sn4peV0N z|BZL1S|y@wTzk8)MeqMOwIajft_VY@7AQu;HHJkj`$+ZoE?kKYkV&zF()-8R27pe= zUwij_u-<3+zgrC%3mJ-9E^xCHktEsLh*UV+l`F}A}T_7HxAGEJmz6F*SPnxki9$#1m-3ZjK<4p8wFk0om8JbWUg|1UZK zF?j$grKg|)m@^ACO_sl})j#Lef5o{+?06`me~2i>CG89Lm4kLL^;j+JTi2IFtzg$c zkeJi|i!<}(^J%wg2ry5~wb4_?wmT-vMql%!{#$Vn2V+Y?(5w7e(#Q(EA6NV}*?_hk z+ZLTQ;(uEkau?XnL*Gs8Zm6A@Un?hpeE>J^@R0d{w$K0T&PC&XbvF0_!&)HWYxIPY zG|h$sl}MdTMWtYNGk0cO;Zk2Yz^rnfpPs+nur-?I=%TK{O*o>zBtfH0)0jx{JA?ga zSqVpM)&HWG@{$*O>8Ncbuge_b(`6q-#ig#pawDwM!EDdPnZ zz45!HTb;ZPt`M>8@=K%_D)CP4Bnu_}my}%MDwf`ceF46-h^1+Gw37ZSfp4%&n5#q0 z!OoqZk?=zGHphRLi!se{T8#6)+v^)|dN8f8Na;sP42sV)=r6rT*s}1Ne>__<+`Bkp z!H#=1N&lZD39gtr-Jz+p*^+416H2=y9)h;ktMAV(IGmS!*ZZ%n2?>&ZQr;zKXrr0| zg{xVBMM{cquWckj+{tG3^eG4GM!a%HNlEyVR%vpHTvCt%hPAwK-C!w#!0mRAl3qxG zOQ36wh=Zq6x;$N0`-S`3DE}$O{~ed-So%hyjT@+1L(t)BHCQdZ$7d%g>@ zp2Gn6g|F$CxQ`9|T5d%3ShUosZ{1Sd-ld}ADxoF7s!7^kD`;D}aL5#~j&nNFrHxc=dwBUc{lY;!OP zc^?X34$`sU=sP`acZX4smhtN~X8IIzG^Anw~d2)8kE z2l73f^YU&ah3XA9`tBNiD|;6g+m1O9-GMnM!r;}Gg&r$WfF{S4h6up5d+Gr&3sGnf zjg_Z&VjKqzW4X2gLP6s%gG6^go+sD)PoME0t}#$^gsl!pbDDp}KMA1V+56FNG5GfV zNz7N`we7C!Lmr{f2z@#gY@Oza@*+*$T?D@rkz7%mGPrv$pmcn6MhLWuuT5uPD~E7s zF5Vct;@p^oV|2Y)b-mwK4UBXWZ$Kb|MAlOrOtNoWg033)6ac9c#F{*4^?B|MbQT#m zk{cQCb3IFbCh>(nD|QZ2Rm8~4@@xRw!H7kb6t&rlU*iUk0!Zf>@3D;o+GPv&UyHK= z$Ue%zqfLs{N(}2qclbMVf*2J={X*bTnEd^-{=^kbGu&rSX5L;4FnxJcn|i?Zx9-Bc z#yz{~Qm)qq#Mq!sk~s5VLnaw)BDUStjEqvman-Q9hw(4T$%!}do*g;9bn(2|HKa$w zo}_|bmDOBKu{6>H#JVZ9v~bWO0e+rXKDIDL@J$#c!fLr5+yNvpgyN{LFO-jl6NN%F z);+;SR^*x-@VEgifftsY&wMLV-qur5-$f%v3&;xokPN~UL7ic&W3)9X+&2R(p1%Ax z%w@uJPq{d>3q)z~8p!05E@w4|f*ZKCL5th&vawnqz?--l%-R=WNln+4Z5G<;1w&iF zzQ4(^_C&ll76c$mLe@rnOopB5HSZwlTOQ`2mdI*S8{zoe+E;>U*S0l))_*X#g@^ZD zA8@2QJ~>ebGH%3;DeAg-*yS&shh|1aHL(rHM+1lk?xK^%)kfizRiRby55{x7Q%bZ! zSq~RFQ+ag$xLW(I>eR8da z3$WYWiKP}nHcQ@6$n$t_CkE#1&$F|z^y&HRs6)A4acx4i=)%iNu70-}=mHw~&wR5) z3lC7)-5BE2hA58du;uI&g3k5K^TKe;>_$5mX3C?KS?C;sdzR7=?hwQ!s{3#*zs4o{ zaT@*)3$W9Ep`C=TT)Rgylm*3ENK4#?nz(ql8kBU`yKw2Lb~gTCak%lzUyWnd-o%{zm~PBqGwcwHQ{;WeU2$&|sd9 zsqHre%ha#Uxo3vp9|8Pq*k$i_e?wkJV+!dL2=u^nhtIVLjy7a?dI-q`!Onwmm)a(@ zFsW#0dXHX={56Ep$NR!U*6x__Knkmy*TNsB`0~ymGq@k0BJ@Sq$yz45XQGzxm?wcEz;z+Cd+nWHt^xUlN^39${B~PE|&h7LI%mnuYl+#Q|R;oc5 zc9~Q_RZ@6=WRw~){D}L0`luILB!IO6hIuuq8cU$Ql`kk2j>z_+0fE!KKko!_k0_w6 zI-L%{H?iwe9s%d?1C6q;yjnTM%5#G~4Ls|UXrgQ=KgJ}+Bgad95(=ugX z!2lF200Os5?^|CL2A8o4mEz}G;&pp~F?=vaopo{wQCYDS={T4%S zjHMC}+i(aV0=a!vdN zI93pllaqs$c4R{VJm(*$RayNheDQY$#}&_efXN?lU!<91C1Icd<(9?Jb)o>%ipe)J zQuHM1%I6TmIy}mes=33TKD~sGj&H`pNWL#FW+WPC%68~`CAFf>5wL8ydwd6a0= z%WN4=3v*D70OT4%&_*FvlK|>gEX96un_LRN7xNky$Zb>*3&U?vQza^PuTw$eEl_nti6!P~V%hy_SfL*$xOApiQ<*6#l z&164mx8Tp@7v}K#vr#&_x}-8Ya77Dmhlhk9tlqfDo~j8WWFJuKo-pA|%gOP#P6Onb zfSJ&F)M3^X-O$5ox?xX z+dIwPRX)f!8)LM+qEFk(`^pZ5Du^G;UukQ-A;`g5Cb-hW z*?89$+aI}8>Tj-vW*V#S31%`0igisI8 z{4~ny8j%lS;56bZJ|-%_8hd#KZHhi;7fn7_Rg7{c=-IFsHSf2-9Exj?q$EVLvLKvfH;|M_? zo)CJ*J9jMUJfO+j^Xs9ZVbOYb_^;-z$#Y4xgiK~7)>|eXSRSKaEnHf4xcEOR-jPhp zL#cfx7=1Ap zq0s(r*t#8x#4?XvD;xTW$BY!y1v9{xh^OeSh<+>XCrxLrg%9ssjVaP8U}W!4 ziTzgb=rU61D{M_zRm{P>OIBC+ZB}91+&fCjM(9Z+{tZFB7>MmoP8vI>AiM^vqz$yw z=`EpjN1Q*?%hc=YJ2qTNozope;?d7ef4Mb*IdJL^HyCk(m^gZz2&8J?)H+yM$ueT6 zc<<|hLW$ywl7fOZ{-z_9$&*_u)T)fpP~dT;u7ap38{nUB98E9p&ZP%jiyDJepCTFm zD>V0^soD4IAxI{WebZ9Bl9G_n`qby-p`JH5uZKd*;^90NyJeHwa%;z&WWiX_^Ix^O zChP`^d?E&~IDBeJ-WCL2Si?dGGSd8@SY<}XUhjLQnu&!S#Nsi|6vQY3cC3tKb!A6Q=e-OP=|TNlktpSt zRXssH)e2vH`EH!Q@gT~tZ1l}mK4;FCynbQ&jfXhF=c*U^l&c=J(3GCPN1m>2BU#Gu zM!}QIPiDT5fdrST5J%bd!7basj2%gaw5W8g>=-6b>E${MhmmzxqbPzl=;wCFMm3ki_6+mGa2jk{z0=S;C^%0k1# z7mk)wb(11J0SJTmu1-(0UE$_YA$2sZ&UA$d@hQwz-_ElR_i;24gm?J?6G_oZ4IRfY z-}+c?0~96UE8x~!Q4kM3+!g=p+_V14tCsU&C50d2Mh514kO6QFGrtL*1P2NWZ4dkgU`^kV-yAgk^$y&+x!AhC zKL{EGFOF^Et&^Q!1R%aGb7fuEqP-F^-&;p=AFw!?-io|IQamXVqnf*o_!c`_{RV9f zzyiQP{`v5!WRZb<`SwC=FNUD4yJib&B*EIP?6*exWbDehBfImG)UHB=nLSy@AtFOV z_SLprE$FP|XpY#kk<{X(1JO=z=aYc`QNzaz+N6|UNB{U7C)PH3ulZzRT@`ramp`wq zUDIiPPdOx@k&q~0&ElWgKH<7zps+PPaN;Pg|L zS>GWP>t81Cxygr(MwRw%GHwc28n$OVj>&f*bdqSse#yA`keaotqgnpT`$i&WD!lUy zpGL!DSAFK&ab@IG=!W-C&Z2%g7P|@1(zYF~C?wJ8{3;=ppzXbrW&go0mU6G^vx*HJ zJ4JSiz++YZq|`a5@!dCBcZg|RdS2VHv-eXQ zj&?F{_VZse4Z@p3Z6K4Xn8Z6LreCY({>#gJ8Vqz81`}RpFI~E8y7*N+$x_d2tK}jB zUE&SDqiFE%=}3o%v*~zKtS@HX@h@nnA~MaE8^LezWhjC>$S#zl)#wDBuwlNXw$Wv~ z>EP)}1J#CL-vd~aKYF5nuCFKYixXbH{OGe^>^iKY8pw6L#Ac)BC3%~+Aj$KX_=s3B z)U4zr2F+8xKx`svBieKCzQ%V0SCt>NYPc-dDe-)aR}Gl(Pm{#M@k%Jkjh-%j$P2`M z*Keg|mFN^cJROW>jO?`yCA=J~jc{ zLP6uL!mT@WT|GkIzkGRT`&*ETAfvI-h&xV=qoOCN_N{GOm4-}YMac$;t+YlTQ z94+O|#|mmOi7>fa^dRa2O@{ijPgki6TRux@?XKFWwNl$#MN>0I4QVL#b z)V@Tis;q3iB+1a^U}h${cZ9c%kH6RoS;r))X?l&?7XyVP#TSAObKTwDmO~i&92YF% zvWCN^YFlQX?=l9ij4Afy!Q)dq!GHEFx{H{Mc8{yxmTOp5P$T|XT{I9=-h}{XcH4<&o@UyE zd^{s?j`G*IJI?8^y{2twm`p8A^A5+|?An;MH4G4FzG<)~(Z4Cz(zSFzrLpSd1T8}4 z_uaPpJ7DdiAF1XG5lo^PhDo%YdW_tp%Iz}x7Ne@}%r)1|{-DB(69SLCc!Vd!&wr^4La}me~Zs7H_|jv*^hG5#{7e6T7CXtx)>f zTy6AN;idsvS68kbqxizKdb5o9MY={Ry`WXk@-7<zt;&m!TG=9a# z)|&Vytv^icKD*lfOD>|igJ$(X7|Q$hwNA|?)gp|fC0A#sBHhOKqVOgpGq2g(+n3Ah z+(ZLn(_;i9axL7#UqVSs-o_#PR>Fh=g|r>Zh!6+s$7v#(TH)*-i(Z1l^AtV8TFmD6 z9%^00i8}egJkncf_DMv5azlI4a_m>>5WdoS%=p;YV(8BP@84vvW6v7OFLE(xl8|F6 zLqR5P>{3Z?tKXH8O9@|UO;k9hgPE?6g=iZamoOXH<=fGtMOUu1kM0DM&p3mh#2`U( z&*uHHiJN!zFDVHLr-&wweEk}%YvjSO`JF@cs4u|s-q*QuVYRs1$pa7deOH}YwQi3S ziJ9I{AUuzAyXF~<)!>D9>yYFix2w1hv!e-Jegv1an*c^{@tOKeI$)7A^Wxj^@Xf^O zn=Km0IWVR2m^IyJyy@#)MBZmsme$a4_0EGOq92yIr-noZK&^d)$T4JStX!q|%m-68 z(<=R4p^1*xRUmi`Tlb%+mN!x6J&hT7pg7w=g%%m2Y{y)^dR1n344iAke-PD7Jq})? z1RFv&W=gA)IU`$x_gb={_`w|yj%v2XubDEs;ypP1Eo895XB_EqSB2H+RV`uC&On{f z&VmD;-a;tYtmMfcY8-Ft(CRc)*9@pHzpVQMP&dVH*{w0y>@?;?ZE^oaNM@EnJ zAU8uS_O+gmrg{_&&p5*L!YoUnnjn^W!kRe1c!eM5hX$)e1Z`+%Enm;F*we}! zS>~-e&FMG0jss}EM0@rD`3o$sBXXW*zhtpohCthWW(&@T$E8x02E+$Dbeg7$pgH*Ph?0$hXJ0eioXLj-P4 z6SP|Mv_7qUV;Nt1qkZugnN6ZlH4I`xXUq|##)$2e3=-?n23}IQUqUvxl7mV z-?Q01D@B_G#%uKn$|~>pRBoFPn6&fwegTvk&BAJwZC1mIa)XG%Wx=>wT+N(30v!wb zC^ubGO$=_Q#)3@Y>i_|#tCd59jnswsM7Sf*U}76@)B6fEMuD*V8|I(Dj$;#mx7Un>=wXhfoAe z(&)#>%X^;N{64$<(AJ6-T+TAE=1XKiL{|`($gr!zj2`@ezdr1F@Zy#*pTFrl4@XlM zmpxyHbjTA-c=`F;7M;?Ynv9*oftz^xx9f-vIWv z1!dhtInUrTAr*M;(7+>w`JjOFQpjt3#0nAs?*~$ zN|S5*m!JNiled(YENhEk@jr(TRP5PiCXHwM|+Qp z5hPsX=C%^ycXKu5BzxWV3mipnv+Cf>Dmw>HHoZ#-X8ItjA9y<*t{@CKyI8v{(3$3$ zfQ^O9(iu%5sH0Sa5g@VUig(C)%+9760w!;=a&kakgK>>7>_=3go&B?z_~IqCiX4>? z9Hr$j;x9IdUj>T;?azZF_*Lo)v1v=6U00!(MMIBXw{PE0v!MZ74Ok&myy1$C+7IgFNaF^q`qmxTIy1nR zH`6?gng)IgbCQ^<;9pw&OhLCg!BJjdPUL1=kZdMA0T;U*-xn2Ox)vf$T^K&{Tn$Ae zRlZY2m}1)Il!deaC5&(H$P47y~{L5I%_0N?Bf55ngYIHLBV zCJo;6uyBH#=E{l<^lHErvs?>u?4XD(UuwHewv43y+ z1ZHWYLqCjG@2HZ_9J>9@@XRU5cOXwJHUFw{rC1+VEVTk;a&e6uP^xbY44OEtuk}AP zB6iciy7u^9)&)ClFY=P(wm!0@VmHSL?5imhT zaJK(K1$4s?ZbZsktBQiJY(iNjo==&%^EX!m=LV*r&#x_cXn=By*ZO&W9S=>ve9qR@ zRa2sra;E)yc#6cWZ2O+qUu`<320KsZ$9|v^s<9|0qP|O3-KGn|#3~Ww#Zx@eRUycu z?#a2+(aLObJE~(|@>Qxb&5$seRV@XUQo)uksfX6=rnH^%Q+I4gBu7c0QL#k3~FP6xTL0MZQ^LUS`=@g&}75YCr}3>jHFr6rOIJCHZAe<4aLyRI-{v zp*rw7@U+)q^DRfC%_J0jwcp&QkWPW6-Tx!fg#18%rb>ZKqT zpnie#YNXc9rKtD-AT(F=<843juyt@vq7Lvn2I7|%qzB&OSD6h2;8(qwI5M#zkHK8B zxJPMw1^KhZY2XJN8Kv#q^pVreyzT{$7c&MmRA~L9JmTTH?*?e>!lOeBehWrFTx9q{ z?h~aR|Fgy2M!DkKjyr)ms1C~F+V(Xw+=-8asT|hdhpuU@y9y7#>RNf`X|yZ`NB?ER zHIO^iUUVgeVBD+!F<+ZiMV?uVP-|gWB1jy_S?wR;QK^q(xlVyXEJph>nKIv$ zJQ#n&^|{d?6GdDz=BV^_mBZWHl=-;PW=^J!p7#hedDyk^`TFG?ES=M7#0TyiKFh07 z3rz*=g9-f0l2JWX!^f+)oXa2?J|~Y|xJ8?1eIc&7xK;5y?^}2B$BjSe3D(JES}eF) z;M6U+EOG9IEpR33ku9W|#aRM-emKE);Bk3mD0!y2jE4`Rd_PGLcYj}G$Zy#Lx@!WY z9EuIE-9{5^F&$=+0&iIR2FHT$sy0A#tBuoIsmhX1=1P-PLXJe4milU}YOcfx4=Y8m z1r~+r2j$P9s+A^H52sA|61iPST!k(4D9EJ9FDSk9wt4WOZ+yD#-k`N?m5h3$kU}mXxGRsre8*Z_4M9aw&g|Xt81UX#`aPRQBufhts1=F9g#FQ zw8_wxTBhX>Z@a7=Ys41J_`A~xx8Rx zHA-so8`hY?q%f+&z~#RKL4LcPhyTFPVbx5Ne>yJa|9g~}Ty_zc7PzGFS(vr+@eXNq z(CVVQ)v z7|*aI<8$c#`e6&fbcfgHtIB5mAS%B#{ z*L8pCKzmyojO{@uSEkL3iqX%d)kD&M(W%y?3?1YvGs43Z6lLn7b`>@%0PArk29NZA zUV$GN)04=JD@fdk(An^U5Y9Q| z8nzyoEe8cLj4E;ZwV)CQ;#!#FoF!I?4T=rkg;qrvFk$nwqwzbS(-z%RnFh<4D{Q8e2W zE1SRlpjb<+MBa;Tu=>?255ZkBnVWP(1wsLksRO*~f;r4X;M!U9Fgwn~7QX$3I6Bn7 zhMBd5$Ti&#{kCEWXuGtiat!T)9xaS{GxYbFe=&pC0tJ%Twa#&dC4?`rO;FfN{RdoH zT5JxGya{OD)2m%3_u*&Xo*dNUM1cpvLiNJYiDBVYfVe=WxZ8?{|6(LU|%xIPt zv009DbG=xMQQwLz{YvmnXKnmZy0 z)k^7T|DqE)2AR#+P98bUEi&GBnajf;GMjWc5KnhbAH*o-J~cF5t{I$Q|H|3k-%kLr zWQjpj0XoK2w6D1cH@6?is}HEt0;vrTvxGhI=-BFuV4=uQ4Kcb3I;q?yQlk=G?wc^$ zH{pC^9%t@R<`r`p<?q=&kdO|Cbd<9qua11c>uW`ob0Z_yhUV4%8@FqAs)Awdq3{bs3uS<+ zC?Uy3e96MfdDk@gSu!@2iT7h~i42igMPMOVoWFBasw(gRWn+T%G5v;miab3r0S@=9 z==E_J8ruKiL#!F3J>Y`DITDc|5DG9gq3_KcW+Ixu;Z9k?q>q`6%Z*#8*$~hfC}e(z z4{GmbWnVHJZw5x+#Kr|Tk@^}nwnKU<8TB+9Pa^}S6mMNSx$`>d2J)>BB!x3;PLPnO_Zics+*ILQsCzQO4&V>a=eJok z(Wg@jY~@b`XjLArlEeLqWLt?(i^mNtlNh)MDpy&_@GPywt4v&S>v&1!ZV49XEN!>mbNz;nm5Wucbik;z{`U&v}>NSpN5WyCP*6zCHv2A>XH>5l}?#&0CGOT z%1ASh4DL=lUm;nt4BTx84BTt`U#`w;Ql?X$H;AF?G+TLA+oPoLpD zXW5L=zfk@K>NdtEho0Y0y*st1HY>@*Tz@lp>XxvtVmZ+15}RI9^$?%~_U=vglGhN- z5D6pY2M^kwe8_|X8&LI8s(qXUfbZH4p;Q^+8eYxx0!tPF_thJ|EjJ+Zf*Jv|!vai~ zIsO05j(>kWDPyk=Llb0=z{qh=UF>z6sh86ZDHy&0bQ(Y@0E<)fb%8OpuI3Ljrg-IE z>4NYbQ&(4tlLwn}z#o7r2V|j`nVIR)P&7K&@90B9XVxY3u=1GcI)E~^hU3E#=+Qr^ zp;|5dd*fF|t~^$JdW(Xo46UqQ30fYeCMGB{nRGC6w43OCBx+tp1qbRF!%q^}ExlHL z$Q2S2Vls3j3S}SwbwDvjTbr%-@JACRtnl2ic)v!n~b{^vlb@K5%jIMfTL<> zUiOZWUCU_{RvJS11E?k74bnb*paf}?pb6VKNd`H4TU$K2Fggi{;4t18FVyn`8b$xC zxaa=EI@B2C5y>b{n-g1AcI>6kcD&B%lBvRApvTC_2>auwsVPL}2{%rsDZ-RW=0#nM z!584BF7~}03dYBrvF<~kcG`2!c1iAq|80!wNn-Xw5(?qzOs|DEYd>g|xV{!uc?mK#sbrY2BiPdl~g zyoEr=(fNQe$&tLUt}ek^N9wMOJ8-&yT~DBq7xUu)nx{ZppN+T#VAYqlKi`FtGc5_g#~eO)3g1kpx^(q_e27aIlzNDs}|B(rJBr2I!o?YFDM$`v#^#G_NC`@A}%J1G}5}X-qO_xw*NB6nr;b0l+!E zb`xh~2=@UIEA6M}>MuK@OsZnP>}JsPqXt^7y`Se1ND*+veg8cEPWc%6 zhc(cqXE3nfqyk-MCFr9K`Fw9ahg3`DRXq=@AGaXw*4mODi(5;Q-Z)wxSY*7S*7XZ8 z__VaN+ugUryK73z%cJCZmk0oV+%4l&z0c6Kb+ytX7Jz29aS*Sv$)2$m=Erhkst zqEteHS}+io%a>~?Gv;7=%W?1m-U%0PRMk5LfmTt zt`|AK>&oV)9OO{4Kh8Bn-WZeHtDS5Ywm_djj)D8s z|DFh#Zt{HJw$;U8jS!t2Z0dSlM2t`20gK}>W{+2y0kBW+vTi5CeY0ZUl>398%l#|zcM_jf$P{cD42d4lfg$<#g@ z2PHky1vfq+%8}oIycA`k1b7pQVorre1wJ1Z+yLkzfG6y_-fZYLjk$6lj}y$(ns`P8 zkh$mwVtE3zoLpSKl*V2NH~P)`HTqV#Kj-&@_iia*cGSfb6n|^{Xnnl=6oMJJmiYF2 zkkGM|Ot3gUe*HYc!IW?O(_9uP5kfC z&^u98A!(AUrKueW2TN-XHW4yJ`OWXTiYr~f~$ z&I2CnzWw`>y+Za@_LiAM3E3gLlkA;MNGdBkBYTAGy;nvyS=k|bWn?5o#dG}n-}nFZ zJdf9PUw1jr>m0xF9mnT$yg$IIU4NnsmtoJ8RKFClSu}B(o*S$Kz}39Q`vNMGNTNf` zoqMd06j{zq8iL8gx&$C6X-Z$*eT(cCeU!?x*cQk##+XK-{^p<}9<9rsDstZ1f()Q=U zf7k;zhNj|=cjv-DV7s$kWTQ%%o|cB$UkUm}gDKODWmTrh^bLY5geI1@N^JJ-k7SpU z)$-aZc)0LV4Roty-pmm{z8^!>4(1dnyK2_NLIDKwy3BpA8$RN&7dERgFfn_wA2yom z8iJK6q^ieWE?GgxCQq*{F0F~LBR~}}Z4WaU)xEoVrx^ZB#;{M$l|-WwcPT!MJS=a= zGaJos)bJ;z2!Ya?;%s7Cn)cj*BRDuF)5mL*DQ5}?ZTq7vc_<#D`j^v#8L! zF?ES)CYYUyVA=NAHuY(0f^h*!IU=`k4*GHtVu+QCnU@FI-^*XJ6E;)D&eKMi_Dz#F ziK;3@zlhV4SeZLgK@&)hcN*+(FzoQw!eM9hsqxRHCdhKK^A~x@AJ$fBi~?nIfUnx^J%s$g|IYi)E?Bua-nyerRmS!-5-L#Y$Cdk&_ADYa#m2lY5%4C z?&Jf-di5RIqKF=JY4C9?%l?pYUK$usxr<61q*hA0H9bs8fW>+(iKSmI1b<=+nCjP} zaezfn5eQ|ZYV&43-1s)*&*37sZxe=fT|3BAoRMeN14|6%>G`x?J6pu5y^BjFhgDG? zDQ>;8vi7XDg*JJ&ynK{ej`4L=UC}H$jxJg`#U}BpeH&AH`;_VOHdT-YIgL({c92}m z%;w=K3;vX1IV@Xk``5E_G+fDQRCqNc)Br26um7<;z95i&H##TYJOv=CPYTHT9qKmb zYKF{jWC8~NZQN*pHmr^f>d5+SYu2AL!WJH2ElEEhqkvmG;)k~+!+7I*>E)N+Pj3@o z-7{)icM><(E6rCHp)t_VU}nA^Bm5O`W%|#uIJg{tk|jRc)7!4s;}^?G|D>g{>|bi0e12w)&Kp<}g)$BB-c_|wOnk5OJOemFH+b&dxt$MZC^$nTvCXu( zcuT~nOsuLjC%!=LUgO=PZ?HU{nm_m3l^5nDhpAGS`>$LD81p1PA1h7HSAiT$=UZ+*VT z{kZMjpT2hrzF}Rah|T2Jp+$PI7wd-yF*}m8U%qgV)Ui}m!xtdsN#CFh$KT%G#s_OA zPfSESvcQ_E;3@hP2t{HKM@>F5>;t?d8IvaMD#XS42?n!ktpd;J^I#D`t1g-X>@gow zlT@V~t>-l{F{JvBprYhe<|8RqjcA$_@El2=gGjWO%Qgv?>gNrkDDbB0KjfTN* z-1TnpsBj7Xlrk&obeMu}cw>JBmAmd~H5>m)sSiulbeT1z*kTq|(Ff2uw-K4DrSl03 zJ;q9>9X1*rpFgV``B8R00YgfeH=NzIh$c}nF{_rmmvWl?IX6Iz5%>OSJ!A)#4E(cQ znIxTDa{u+V0f#`Vp;UbVo;L73KzuqhN~azsPvCv9qx91TJt!t7rb#VSvsqzAUKEl@ z{Xsdn^{u9^&g`>~U|K!u$O(zfL3oClv6ZT<}&1gk&b zCGKK~oUH8VzX5L53V?PD=i8*8t?-R{j3}R2dh9R=U&+d;!89{7yIDrPN81CH!hl2Z zRu072!~S7d^J|6zW#+pFmy#X*Gj|LZVEScvwo}n`cWNi+7CK|pPm7Ay@#$&Ys_E2| z{F+H^r&V1Y7zw`Fy>8tQ*c}pwVv0=J4psa0dl1`{NjXA&1GOxGq7x~aZTA0bZY4EEI^+L zaEcVSCgOI`yB>Bz?Y&rs8~G0wA<c!q3kDV6k~SMJv`Wos}(u(+8f z^KSU{T>@JM6{?_1_LLRS-B;nf(w#cgovWIHGzT&HCEX$X=jsq|f?kz&_;tDCf>hU! zr*rNJ_T5JK6temXAW(|eUohDwa1Lj=IqVKdrl|ABxCXmAFMVmbNZKgm{Ikv|x-Fwc znSpQnUF?GU{QJVW>VYF-{FA;olve(O8KWAHy3KxxK$8d*r`9a%4y|v!S+*3v(dWq~WVhBO6`NU}YDbuNu((oZ-v~j#Rb|f!5 z@szBG_<_)Cs8b9*`uzhfu<{K!v_un=%fZm0`4SaHUz*{j{VR9lqICb z@D)x)l35H!@uULx$jhvNiBt!KthImsd(SFeSDeiT0Wn$KVsEp>ts^FU3zk}|PebN2 zfiG(S!2=#8G1n`xeF3x%^_P&#M1NZ!SI0F!$$B3O?UhG@!m2B98R%$a+nQfy6-*|pp8w+7wV>msb`KI{JM^_*SQ;VZ{!Dfs(vr8lcG z8_}A{ju#ick9G!5H+`@gX85zE+Ztn@2}_kr&~bcXE)y)g_Fyq@r{(l`)^TOp>fPXe zX`3+;e0X5>;ut6t{5$tFa3~<13!o}U3y;MpGu-A54QmvVXW!meF5d2|y!vXTGJ&~* zCk&z!u^d}YE!VvUErk%UJs?0HAGau;+Eg?M%<8`9z`HnocfmOw-m~Vi)P~L2$y@jJ z2LEH;XMcBP&cKoY>{999)59!PK~O*YXKk6~31OLlh)2t?(~1f~gog2<6C0T1T}U6o zbWj>g|8nQ6jGdZy2xA=y#e8a&C6czfqu<+*M*PDx|Ul}lg zA-qzi6nb{WZJkP?ya)c*37XLE7(RbKqGmesrelNybu%(Hsz#hVhpJs$(v$oeO7X|? z1eTJq!`<`VUK~(-0OCbv^{QsID~#T&;`$6YGoeZbr2x=#pndRVpLxt5!!YAsRvNU7 zK!>)~RTijdLQnPQ&!5p?WzuntoS@x!8%%(v!7Jh_YHHWOWZl$+upFVV5px3^CkG$n zlrwO^P5nN}KiAII)~VYiIyf%%mkgH0EA`>@+hNwip+GXD#>IOc0HLWotgl8t4Lsk2 zU=jqaP+Lm@hp*BxhczRU><-B;h^fv??U>nPHo~H!KyA_rf)V*z@?bAH@}L5XfP@4d zWLCg%4dXp^eEiEG0d>3{))1hMXsy@31IrB5dywDDm%buRoPB8vn`%4Xm z@LNBTc2@xL5}fzH7z@njyF=O4a&(0ejI&(dqm;&kq3sYLd~lPp-SjRdW|vB^Chk50 z!%DU$Cp1>d9E9H=O`7w`x=ZW;ClRwl00HbTdn@s(`S6XP4U|ORe&)evJT*F+{0-y^(P5+mVlpIe9_<(;eixa^I zlY?$$DCfaaoou_bi~sGqfMT%yx3}Hbi!ibaEFsk<O1w zHFh*Am0eL3Jfr%Gq}X=`tBIS8r-i0izGo%uP9Pppbq}8oy)3%Ab?o3Ha6af z0L%NT^`%$SsGJChpBJUOT_IKcuGhZw&7dM5L;JG?acI`(uBVv`^A7@Gp@fbQQx<`&gjh%pSwzFS z&?j#u0$7v@O;Pr)R?$TA6fT&e`phdA<<3pPUmUN-Q^_jcO zr{Lod)kZzZFsIkT{`XkGt5JK=jbhygjo8Af*VEJ}!)wSa<=vUREpSGBJ}f}-Uc|Q% z)gbWB$(SlPAC(`Zt-{Ab!q&Cij)Ia0SZTn_kP^qQg<;c0>LZezyJ1+?b&P+ADH_UJ zuTU-?$zAw3@r_VuU`-;*Q?W-FM4_`e${*_hluhp1HccYFDV(GNDgEzK+-NTSu zL~VyeoXN076U2S3Op*n^l&@E?H1 z;9&{8O3YJ^QeDCDT$|6rgs@_FMz5?0mGcu;h0um-wnr9r*Yx5sRmT*ZLb9r#nixAO z*C@_2_c&8l{F2q!VwKgL9e6@|KXgUhiB2rRw2M7VvkX{1Fg6z??2Ba@a@=feq?(Yk zuE5L}i05!NsSv+cpCI7D>1-l+Y9rX79-h+~h$4whBzDc*FL_&Eu6N5H55?j8dK#ri zz#~W*IvbRTuOH7lb4!ISHpx3lC0C^xgD1!&)PP?w9=z+-cQap*<16puSN%SaISoXQ zk9l1GS#Q}J_rqn%e*UJ>diA>D5T|Cka0`9F+CT^tMR8a0R9t|z{S9{JuC9*;1KzkK zCtV6j`YJpXS3L_b3;5*u`I#jasMW!>@OZv?w82TRoTB5Yfj!Th?pT9*9k)V#x`exu z$GTp{PVK`ymd*Bm&JRCBrMrb;Bg1*b|LgSNGh1rZtDW5&ZWz)=d>`=I3a|(MuS;aJ z{oilDSCVDJ5em%zUk3@kZpe3N{@NJ&_sV=q?sp6EHU8J}QK!s@;tzaMQ2drI6elr;Ev)`^|KYpR&>je|kO;N|1HddhNGR);zC-kXwwNPrliW zZ@gh&(<#$IH^XTTKvYmPeXbuo0W-4}7wb)qX=8zprWGH70<`2rh8dP?12`n8&!@Vj z4g8sBuzNjW8#uNZFz3LpbYD4d3~`m@Xx@O^87rY5Gi6Zctv6Hzpxy?PHg)`*!|Sn4 z9vZ~o1k$)fS~urO7umsoY$gq;ay=e7=8tdzhh{}7<*>XEqKQEKCm-hIuA78r?N44b zJfzIg4W??|F7qJEfn7@&2)STZxjJ+;rWFKh#0}ym5fl!68sl$*z)v)f`zn*gR#7;=FnBXo&bFdo3l{cBvI#vpIQZ5$#i z6J!B?t-tkpdSLzpum(W~hiL<>J>DuqguHgY0S^V@z#xo=bj;TgueJN(%K{6>NC1|z;1~YqCaHzu!;c?7 z{IHe(p&gvZeY9$JY%N8gj)BL(qaTk<`|oNV)a=lB5F)>0^9HjU0Tztt+Wn1l4q!wf zoqH;1sZ!>q;mwJ;IVbIl{mo;W)kSEBS8VZz+&X?sT0WUMSqH5M_!Obj9Cn;5n05+?Kb4mzI|lN#u>SS zVDcBKdc)S<`=GsizyAJP@^`I1Sy`t3n7~DgOpMHUR!fV#gQ6gT|MaxJ zHv2uetg(Vjz>!k1*#1+AA}7HhDn?J3hSkNo^T{OGLRNz<(G4Are0|!z(7&I1AWn-& zV^G}GIb>JO$-?jzQwfauO!rQHZ*&E+_$d=pR#jC&SFs2QOQOIn5k@|iHTKY~8+u`V zfd;&3YS)Qz^6~hbADipfGTj&c=T^xNWvVCxC^@)Sl2jmVh|~n62x9@9c#9=C1*A`x zoD%B?vCuDpO`1~Jwf+lA;o5Gep6)fup@D&KD9;dN9M5!m;^?TG<{r_rf*Gb0Zz19i zUrV0Hpo`uG6gu#NCrjwDkoE=ZR2*^!^BnBKas9=?sMe^KWmbFne;yW~8VJ_WEWXr( z)`)Hh9UG%60e;qluUY>L-aiG|`2K@(Y*_9i<(0Rxc2dYW(7S2`*R;#v(WmiQzzzv_qhQ%f%w3v9bZ$?6p;`~6CGV{9Tw78 z@BxHrxqMb+egPNKhSV!;Ffcny|$+EN(>DT_*g<=*%-uz&WQ-YQfM(lZSd^7}F3y{Sx_O&Y1CIV$Za$#V(ml)?pOZD|M4003?%M7U||m?A6Z>pN}z7C>a}|d@uKoqUq(hoE-$wE0}q1(_?Xb{ z2kc`OJy=&#gxM_1uwuKx9uaYYz~~73$fIZmRPei|Crip-| z!W1z5ki7X87wvUNW)gnY>^cOX0}2SznLz7wf?)9eGY#$Atuo(gJ_33QV6>gVnekaTA}9#!pENTMc0o`+D(>J0%G@Y+ zlZb$tDH$*kF84SinQ1|UwB`l9a94X8n(_Gp+z#kMXhE+xJk3vktknZx$-)n=7XBxE zTEBu2-RIXYaUKeMgy=n?t*a9~hS7FZCen2t%#+eDYPK3N`6L zVIx9-PDMJ&2??D-adh-H3TwN`ds~OJIls&DpyDPQLILYCTZ0exy{vzN=8WRw$Bagv zOPJG((_g=aBa{+Rp@(2@5cb6MZyPup4p-RO>w)Hai_0^g;<%mrdFza;&4pKrYkOui z;A!I;Kq{0~0hbUG$pV=U{j>`Au^pNYsE<&6V93QFU0mep=PQ$+~BLu(7iVC4;L;YM=$K&tW5mE?c zaTlP8fQA;Heb4lsS;y9hE7E_|b&e58G@xl%-JydX9{pnoj{<2U99%h{>YbqEi^TJ> zv_2})xi<3AnGP|%2xS1h5*X3Z2c^)sO#k%jEARm*`#u$?gNeTo+~KCSwo2=r=Ma(D z1}MxN5)bIcnt#R*fF_pK4=BDYYNH?%#J96O`#|ylqr0bvwRP5BR1ylqNIQ%(ZXZEe zlta?of-fMw+WCJN25h`ojlOSABx*zB2wq?Ts<$=$kN?hj|7<8zfXyq4aJ;)WxEromCBLb8EJ5GuHO&q-gY}WzFE_Ed^7!o z|H^85;;+3E3yk7qPwgY8WrV;MXu%M+J&`42%FSXS9<4wO;2A*7|0eIlMH_;06f}zB zKmF?bddF)5i_ApV;9#H+Ah221m@fe;wFEHNE|DozEawZDR?^?z7qJMo(4Qvww!dGF zJmo68S_X6z73r1@y_MdS2nlryv^`@{9gA@<0sBX6o*GxE4jMv5LtGD&lksh!<$vri zEPJPrHx`qo_5AIX`;iRMHy^bBo(DW@>eVlzCk&|<3$9;s!p4-jl%)4-jX}LWaD-+t z2nj{&?(Y^1zZo5`z!ID$qQ_VJG~VI>N}t^Fm9YQ&ubG7Ot^&={;Cdb`sPfXim7E*e zzmZv5+qPrx#x5$No}BD0p;` z+)XI;LD#OqwOo*L358)xF#Yrt5F+MKfY1ep%N^(nLx$gzMRB!>hM{>(GBhY0-nY>mf{`E7bws;*9dM@O6YTp>)dCZC@;9F~5=2>sGAN!7B~?y{ibEYppA zPc7iFvu!wO|KPhZ$7w2TA!j-s&2Tq>(hXi5KPtprcJQ9@ufpiMu(OE{qbIO!%(KW7 zQ!stuPy4@C-YCzs$v9;$?7gFe((RZYPdrJfLIcblsr<&x03I2_$8R zaVAt$s=1icY6d={nZ`)!rGZO3qHY#*_o)Q{P6lfg*qW<@vC^LVOaS9%V>Zy_IdI5; z>*?fdzW>Ag8h~h!5uJ5NM0Koi$e{Lc^}Ubh-*4MqWj8@B>wHDJ1(YDpIqr8b>JUK9 z_{N69lZ*k6J6`DtCeJ%!$X7kLZ5B(0%ft;;G?JSOq6N13gE@Xj(Z}+)Bp#l@{tAh7 z^^G%pxbW%i)sd0j-e6O_6yr8yVpxxSO}kBH_yuRBN-`;Lc0+lC3J+?^`y z@35Oz+_+}Aa;=!qX(r8ycCOMb9Yy3%Y~fBjSDwuydo&tK9wK|g%4Sg9s{C35`g*mu zcV?ft-z;+%9tOHs87>AoY=yz3V60NqdJoEJbrTWHzll>Xe$xFxtGz_p_QUIHUKp#2 z?w^T^FnBl@{4wbX- z;CBZ?0gs7qpgS2HM~{pWr%4{)uN(n^e7qd})k}L-HpRjkSfHD%ec~gwhbhE^P_Y@h zp;jf9zQp>73JG2BxOQp;o(>lh=2+1T*8x+hN4z4eMNX(NyAL4UxL7Jc0b zk{Q#AfgIx;P4JO?G_LTEO1rmrjx1l_h9@8HEw^5yzfDv^&Jvo@3ZUb8XYTEAr~C<3hJCqZ%XK zlBtP3_cEi2zh})8+BIAv=AMR%q2kV_w7QZk9^u%Mf>f6&a0C^Y0-{QHCDWe;o!?9C zNZM`wO=pPv>ZC3{ez19CesA~r@#*p2?C-i0qIEx!%Vez!WlJs}=Cq%lyZ#e#qDryR zUUZk;GSe8YftC2pH13CIG7V?tpAj+ssPMOi@)z6P$m#L%0IaE>8)zS=)t}jb<$0u< zP`RnL&(6lCEx=V~*))qFT0XeV-M{S8;Q4y;EuF2B17>~pdWhKV+7OQ{YKU!^bGUy` z_S8N)`wrMF-qUd@ui0`8Nb_nr#*pF#I>G2)`0i1qdB`=@Diq&Un@n#VQDPh|dV47F z=+!%AwvP)E+{+HMi&K7WRdDMhxZOtk8TUJi$cv zo*AaM7TUz3MWLUczq)uWe`DNdL@5J)@?X9eHxMzb&vmYuvA5PQM>Bi>o=VCcZzKro z;cFdTeEZb`eT4aDvZ7QusYHx1XpjhIajmbO?Y1?`A?)d&soXXFryg!ai>lI8UO|=v z$OdHSopf2lJYWwYoJbSnAR8q)Y==Jo$e{uA-HY>vT@`<$W2L0df^$yKPI#BBBB#x~Qf2-_((k<3|^~kZA9PGXEyGO9a$nSQeF1gq6>Jj9Z zwESAepWEJR*kDi`hG!2)IfA1dv7N(*SFth486Q^4mk1NndhCCHOt`@LJ#v`qCGNPP zB})^3^s5zBQBzs;i#!e;_A8Tre@qz+YCS7zZHHXG>pSz! zk7z0!fl&$$;1Iz0+oDTdM>!edmELc<{_D7|H6p>t8y6{+3_A5(8OPf-D#%tGR5TtrzI0&a~lzTE=_b z@ei_qc#LU>7&Lt|tnFWaJ9SXEnoVsXw@--FfWn|2;2aQb-=^dGfp4?}PiJMZrMlT% zqdVwCUux_U-cDLqO_u}J1ljYj)3K{K$MstbW^{v?3ME^hq&X^FriK0tFh>g^2Yzrd zBy%unRjNlS;MQ*aWq=VNX$jdswShqeE|eu`_Z)Si_KKWH89;Ui@{lVAe&K65Z$VO( z{Ly>;7q|l?u0QwN7_D+|cSc9@#f+YP7x4iaM~nu+>kb6tGBP#w`egU~Hrk?O&?U6J zrIXy*$K2PfON@U={aRS)#`a7(P8?s5JP+ z1YT?*_DH?Xtse43qu$w7wKc{d*_$HN;B6R}2!S6yx*g`SN=q>x}*!7-2hlDvStQ%HTH9@;9Q4H9ku zAjq1lbe=p*G9tsnH03Lrz=NBf@uFG8s&#`TeSOzlJGK#~&ua<&)XSB6JkVJd>gIzc-fEV3 zOfgQZiJVfDrH{wDs{!s~m++@XOcF%cXbz_bQ}B6j3YBKBPplj$2&L5w6zQ+nb~hyp zme}$+i)zt-?pI|&b6ab)-L+Pu7u%w^od~?aw~&Zo5D-B zx#Uc!6$#2kFNRYe21r9#Z(9?Blv22WoElKt4W8-u3$$)nsH~#k;i7u&7-w}_1!Hej zz?E=Ru#Ta4`r%uf#1)C^7HFY&2WJob^h(bFT8IF=?V`slUH}sQ#2UBu?1elZ#^eP*b5HxNSQr{#J<<3Qo`+ z0{`qw@;_-e_wZ02Mx(^T9JXao z&Sp$1ZU2kMYqzX|QfP;1g+foszT}m73)Mk+on`PfaEEfU@Kw-5i>ONj%6Wz7{jCN~ zAw@X8s1a+>m(^|%ES9X59u3XPSUrB#w-1 zd{sl8N>GYSS9JZxd|HWKM3yhHstxO9Wm|)7OVrc7c|+$k?yj%PN&lq$K)o++0)rp~AoK0N)~kaJ=4V z&CUmhO?^TPmttA$QZt~bGP|xF7hl6&V0`QJS(HShOge$iMVX?v_7q1)B7nGEoN#1h1Bm0tuzZbbL3s6k`?a~lWjCi+lzvI z2Da#p7epFDogIT+mp@zKues=t5*!$xOn+RPY@c2x#kjQQLhZ+-uts{N=v{ZK2~@Czu6h{owKl(PWFg zTcMZg&KG17HE0Pp6C}-4n(lZ&FERw9H46Ji1J``nb5UHr>AJ%C`iqPwog#KY6Zslx z1&TSjKl|;(CxT)&yv(b>eu7DN#Gu_Y6}RozvjTHLk@Dv@XF8V#x*w;Kk*ATHE~kIb z8!^y%`jv(&sPaQ#;3d_)En(F_L39@9?=pAlp!ja9O)e|YsI0COlJ9jSNs`4aBI(xM5T3sW!@!C-XQB3%uI z0mQZ*?tCAq$8+_a8+vd0|AnPM{L46NFL{HkEBglNQGpREi=warB)_>D^;OO7*j{aj zV_9=)L{$|8Zf$(AteViq?_axdBWa-NGk9QiDW4}R^O7}GP8XL_gr2Q>d?@4K%}$gq z2b8)R)LzGbQubQGf_1LY>v7A?hc#LzcZuQ9M)#R#PaQ9~^yloAMse{B)uS_|JCkEv zf(CaOWY=q8g%4&R0sZ&jv&4hd#;p{;6|Z%K4PPny~m8H|Gup_XSC zR@epEtfq}-6g5uBNKwl@75MM(Ep!HY9Avge+fL$u3{s`VhR+QZIjlQiVuk5?(>Q&@ z3l#G?Ce`7OK^-RlhG&53_zB;Jun-U>$1aKXSAu{-bF}~)45VNhN(Mp)bmB);j6w4{ z1dR*-rAts^1rR_o3ibrPt*v|p`Jx`)sH0IC(o$|!{55A2Rv6j}19cNApiWJ_Ifk-X zTI=prAe*f<{M*l}D9CS#ijeF)S_GyfN1T%Elq=n95Jf=Op`zftON_JwEy(+FH+!(S zVU&tVp;Mq5OE;S?mn`x8a-tBoLJ24gZsmnFj)>F6ozI=I3gzo&U5cX}Y;j@C8p$tM zh2D?JSo+xPi7l^8X4KM4UYLmZTPf?QUTCk-{JerLSpZrcZ{lcT3UR?ZiDQ9kmi!VHy!SIvQN- zt(-uXON0Wqw*}z?TMOGJ!Yl#Cf@>YD$+>-filAmu6Mca;Ssse(H&9tNq}!i4DEliD zlasHlb5VrB|I3(}yzFN zC}Xia8k3ttd)d9jVXC}>#`L$&Sv>S$2;Z9CzTukcR-Ca6cS+BxI8khD>?lvBwaU!l z_fOAu=-Y7knxFPM_m=lvz0W$4tDT^HJb!ogZt*a+kQYIR3byT~oaw?Y_m3`UQ)^{H zWM9a_Xz=ViwOE8MrO!Etk=er{s;@fcZPD$8NLU_zQ*q0xs2KU2 z?<0{W+QeeUW}rZm-{)T{d+il;w%)VkfYLd(?N&w|Jc(FWl7XEleSFyb{VPK3E^o0< z+I$J%rXWa?tl(2nE&6l%Aa4xkbzhaQc;t1_n5_-zG_{mbnfJ)@#pAyAgI>K}GD1lzgcCTe=OXN%A?! zwD3W2$UsSk$VQMNochflFE7Ca5qQ~BbQe#_tCzlC7w!1zV8!OE#V4mpEJwK!ehdLv&v4cSx45!OT zJS_zGicEndN}R{h_wbRNYo$OlG4>m}PRNb}9uG7hK{M~?@$qZ{PHZ0R@`k3Q`iE*c zns{R~>5kYP0$*NuN<%yRWiY8i!KI~Ta~gG1mo4@cum!f>c2WDok;kjj<{;be%Y5Jj zws6270w1JUzY43(SiKGI60l5!NGL_)SAHpl6NTb?eH;4(!Q+7zk3?3?)YvT@o|3T% zq^ZF$PZH7eL$WM|loEU;V3-b%jD+RWQnFoX8`M9^FXjEZrFh?qmG>t%HWfk*7|MJK zW(lZBlzSeS{yaWz-*i(t68pv&AoN}K-o1{dahYZ`HwZ*RIws-y5a9HAY|Q`s+*j_| zia1e{3Rb3iaBz`2$2TGsBEUmloc{&B45Us$OM3^f0m;5cSm>`FdYSrX)s;fg00Ch` z!CO`$4dQd!kuVJCq2QcB>kxp2Zf8N}w7t&Nd|bbmNGmyXSN2*~fz#znxyfY-2?^ou zTy+lOva$(fu{H5X1;7wV0*aQISIZT4l|F#Q7Kb!;r5sY|?QsS$dIq%NJY+{m0Z**C z;zkoEH46d|i4anSkS!4G|Do#wb~?rNL*W!#H3`ULz%+!rUa!ehP}Fh0*eg=SCR43> zce)B2^1_j$?dXVvK8wh|n77NsgT2(3Dl3B(@Q}i%gPMXE$4pB81NmwY;52ztGbsuO ze@$cr%46R^`%FD|6K#Y>_bxHB|h5x<6&eAf`Qr z4XwhUNXC&4Iqn(A&PLmkqhr&`ZNASNWEp%xqv(5dk*i@@W9p;;8yQ7eKB z|K09P=X+fBZt08Q_nBRU!Vr0DSG{T7O(MinWL*>gX5<)w`i9HRKfnj>{Pn9|9)Ay- zWe{J$LF3dm>ts7jhJ!-;{1-p?VOIt&nvWK1B0zbZehcfLJSRtkEgC10wOmaRmx>bin4h-s${L z_=}fk%rJ@~T}!x;EBnjc5sg?AJJ!L;c0N9+scLj2oUy`gif@iYh?MU@!ba7OaEwc= z3~fJp*gsmYKFj9$euLQlqO0S}6>*=Xb96Lf*RGe0l{6iNq9rbe1`o^(zL%wYy07iI zUDWSQ=S>Bie-1ouH4H)icmKst*}+5cBabUS5EboqSp>}!CK*9VNz~yjF6X|HbjKd3 zH5Lh$nBJOcepW|@5wadDoTErzU%fGl$g$gz$zbJLxHvx<S$t7$|cIX~z=zK55@DV4bO73Su>4 z1!&yN1SJZIgt0q*p@kn|$E>JSl}-UZk-97j263m4)f8LbgHfvZ3okC7j~V2PDF}NU z^Jw<5gmzu)?&*$FVskd}p@ZFCn>vosyDOVog?#hDrdWu1#axJ5mX@YGtLiGZ#I2>H zQvv65Nk0>_o|61wAM)Y87&GXA4|4fYM;e*BFIi?&{On}6WM=a@1isT8Tqm?$<&4eF z)lPjv|KO}Bc>??0vwLl<5B%TeVd&l{M$4WCmEV1EKYY;U_CBNUkL;gMFBWdIBt7`^ zIgs_j5&PWfJ3~|BkEi6)FMvEV_w24q>v&cfg^ma!pQ}C+ZD$ozM+AtOX+k*E1fK*K z1hbClZA-!EIx;d+IDA%N)pV2jaM5I&&(?Hh$Cg4Jj^j7 zFdqJ{$uN4Y&WlzOsC(;HQ7(Q_gYA=aCWd9zMje@eLCX%UL$W`KQbmOalGEOu2ic4d z({CiZ5!iLna?A>68Eu$`u+0AWE=XE)jd=-2kp)rpMvH+&>v)WHy3cwzGCPKQGHr- zNp{iyGP8LL^eX0IR=$|%86T;#CG<81oPTRR%TZaBn7G47&MD3SI_B`#-6NlBCRJ2{ z`G(`g?;JtdW9LF1CMWzm?}%#^hk2Fd5qq|p7t1t|DY&R73D7hPQ}j+)gs^~uGW?>K z#IN<6Sk4C)1L)J_s;qn z_!_81M9P=PSSj@*VQ*ZR7Tlj*7Lu5zPJhHTtu%!S7nFoD!EybleU`W!oA_8| zs#R>Igqq;=uW!I#6O5fP3p*DPC`anj%K?c4sD5~SPiG8WSG9R3SuUeRE69#{91&Gb z39*|D=ePu>*je!cW=geTNAcNU67a|T%72q4yl*&0Qxd0}bkbk0xdkS%(DH54gsKt6 zV`^$RaOEtvt|FqM*LIpZyJYR&*u%y{VOa6YRr&F&tav}hPZG`P)$HtwmSIYnT7}-# z7^#q>yOp^2U0sEgUd3pYItdo1q?Zs04_GfjGO?;nCc_jEed!{VPiMGXoA$!7`~nD`Xqe^emm z#7|kW_3f(IrwI6q^58I!UirszDSd!r7+44O+e6Rek_;j!3&CE0yK1mIP`*Zee9qg( zMC5s49>v+;^TI~>sPILS!(_q28^y^xekil$K0x%r(8QqY*sem4DN*5mF4NCQjC)UD znU3d7)+0N?oLi3@8?7OEgtIL_-8kv(w<6wwQcmET2o_Q_AcZVNWB%`!q751Lz11Es zPNcJbf4GR|;8h%CWqA6qKc6U)v1fmrnjn&qy|lyeeEZ>-AD=|+y)0-c{&;ZKHdPWn zym(k^d*b!Som&pb5pP@r_>5m`QL^vs26{a+&Oh&Bpx(= z54t4i!!r$jJ1fZEbaVbF<-? zRjdp3M0iU}OQVemZ>hKK5~0{v0mo|fJ>O*g6)r8$h}~(XJ z5Mk4H&|15YZpa`QW?W#VrX3ZbG5uHs;zi+n>l#*_ySiQK>b7c^bo$1K?(Rd3DNvIi zb)jWsW?llLUr~2zBFQNjWjuDiXgEJRhHG^3pR5>-^VaCLG&J6lM@$uJ7wyND`Q%t) zD_r{lrvsMjkL6ZsU|$nq!hX9|rAbY=4~meWoZgYkY~F3$7VdeJxb_43)PYIQW%L59 ztP1i9f5P=k0o(}=&F1AJFuFyJo^%dJMb;LUfh7VLfhC1by?`Wz(Q4XJmx2ZmMRh73 z!a6-Pje2l$Nu@eU7)M*$A3S;YKdhS&8s5o!N z{iR*_CEul=4+d|<88tOdXwxu`JjgZFTUS@N^5*>88x`s%B?CR1sp%x^%w*`nUW6Wa z54jchIrk}>0a6>Z!j{J#ALt+4KGN#?*$Jym?J@a5sYh`$)xnTaI6RK_cHSMbmXRop zu5HF=JA#AZ%W)ZjaH&pK3vmY57#yVS`P?6SJrqwNbu|7kw_5$dyHXwAKW9^|MjH5! z3=B$fc*pOF#%g$G-ss4P8s;`iDPYgaC!F=a0(lyBwK_v2R#aFG_7pj$8fO5FqzJQ+ zu*lTwZ2h}TIeO%6h5GcA-sgDQ%DwB(?H^`!v#=TuC(lzeJln;4AKy{w7NwT9mmsEh zGoj104X!;j2>k>9H0K=BBkKukI1#Hm&U9ARZAVd7ILyoeAtFZE@>om#Mx>MWBO&%9 z1%f5CiJNzha=)quQA9C5WxTI|!|eNz^xzezXKVs`M8OVOZe_wGU2v}U*WS(FFD_a$ zHr`Acf4}{A^l?`-Q4zV|eF8$C%gdAE2H#8csw@eip%hXnA=?=?JqYX#AZ;J_POdvd zD8F*AreY=Xoc$c6*puB^(_4cB7Jn#J#!RY%lmS;h12}pGhR%k${5-FtV3$bJ2{lsW z_u%%9^{90FF!yf<4gKo!RUWTQsFsK9qTNZ@cCK14(h8U}wugSkb8~YuhJBKO-M0hJ za*KWngfS+*DOtdwn@!A|Zb94t9~Ay+q-jJl(2VWvRg~loPkri-CLdJ*1~1hqRXw@g zC)kt4E&2%wn|(sPH|5W)k`h7~#xy?x9jOyIc!*_N0Y&)7jYf~dD!u51qBKO;1C=d1 zjTXSB2+RQ}fEqNP;ZuFq-Mv0PrwOi+=3Rgt!ha9k$DBR=dMD;|uXSo9N7t4YL9tI7Db2n>1z;!#BL(=|4|Skifzz z4Ba)CB=M*^gOX6==`|M<0F#4;j>z^f7lV-joaE`xc5kXW<(`a=yUz6-&^v{4kd?Mg)9^+If^lPi=c8$+rtlPJ z&C94`VsbKQch@0R>bb$_9B`bl8GVQmm|J&h)UI)Hk2`W!Hb-;BpPyB~b)buoM<9QT zV2mx{hS7i$svbxOg5uMZloSL$xL7;uFy?c=xuzV>5dv$2ESYsUE)sl5mip}6-R=brPPujh(fMph$nB}#~j zp&h^8>96KTbb}`Kq<&>Ot$SXFCmx_1aFZ6>EE7PZt6fwkFTapR7B}$5b-qIi82FkEWguH|_gbtaKgR?sr;fl5&+67*rq*bUVWfGrfCB!T z@%52OO=w|&FF+#$F41JNQ>>Ugil4@ZKH<~_SR|TUGoDhpC1<^=jckpWnATDp`G?<5 zTAR|r#urvzvpaUmq>fF?ibt^OfQw=^{VgFOsHP^E^B+vbfjAl-Xv1W<=2SCd<+ zEq}?aa`B?j_>J1CJYlA2qd=~O3OXYcY@x^m5{qXwncDrgl`-Xd;uG;Dp*!bx zSw{Wrk^FR|;O5*`nHCHyQIthAgE7!j%0?X}1t$v{yQ_bOUBDx0@I8)|wA3W0vqMOa zQ2@1r{9!IXA#=n2Uqn;<-?GFNuD{6aux|VEVsVRYJOrh+&ZO~%2!`Flr7p^qab2_M z95Y54FZww;ed`Lpv34QRVc=Bx5>QqFJ59R?oI&0+US#y5yBnj}N!D!~p+uURiQIc0 z;oIu?VF|V17QOIJZQPct^mVM*~+O`K8{$)Bvky(!5q)C@g zqB|sbcFu|3F=jpd2`8r~&BuAIYG3EKd^xg_FS?^7JA2{vO_w_^n=5co7PZkRXU}rb zUk4>t%h#5QuQnW37YXn~<(n$0ih3PO-ILFgwAppfyI=2d6ceaW{t&C1;L+))c-54f zM$;`K<#Ng>0$EH_{9ON+Et6vM`Qf7Y;=%eeQGM)|F8mzxDG_wv*S!H?oc&SGhEOeH z6v4_5K6cJSdX$C&wWUNZ!SQmTpO_;@FN4j?Ioq62mru1T?V6~dn%K(M!`yv}83lBD z{5kFMOvVcBhEt{x|JE8h8hCQm`7hwEUh7o(WL~Cde%!7^K5F_)95F3Sa1SX&mD{!x&wYN(7mu<1#in< z{Vx|F_8x-}nZASo<}fy~7%4Cs3eIgf$hyK01;k0)Va8%<+WaBYnBv4`=oV150y^YW zV^~VD0Z;Nq)cm?RpK&hx<3+zW>bW(Zud{9&@{F#`qJ+pq?hEMgm(UyY&j~TtnDG~& z!|9+hTLny=cDcZptGS`^RjtulXi@%3P#jC8(N+`471YuhiBRl~G^@j=b=aJgcR8-= z>#jPs`P)L)KMi73Fv2bV?PxNSv0sOE#W(Q%{Z+ibU&CyCc$VKq8R!Z*rDLWEXZhcOk@8h6a@Hk$Zvlu*ky39G9mO{i#|Y==FI2CPSJQpvqQ}De-hi~sf}bYi zKJI^obb53CoGlicf)n)tK1w?%0?4T7to$q)DNRomx{2Z&MY?U>dMIVnPDU@Q60X{3 zQ*FyzP?d_@zT+<-lz3g`pF{BH;65bkGPb$9jFBesk`dzEzx1yEd>^j*hem~?QvLHl z_O@fcq!|8}8}iS;DCFHtwp9!Kc`nV!&4)RpiP!(7s{DtqQhM=c$6^nmMcVvk{y!X* z|9q?Jisn7{e;;kB%%gHO6!B00&%>I|DkEC3w8Iqrl>PBN2H+L3zPV*a)%W;9^_q9> z?5_=f92ykS4V0l7*BL0|TYXi2{xPpzzrc6sJ`9HIqKv{ z`0ot>EZCSoRipPE?z+utJV4q#1)#}E{Doej=qeJRjcTM;BJOnNwqW@;ntPF#h6J!K z$yuqa6|pB9z7kLx0^|26C0#0lh*i=9dL}eph@R1IwiUoflw6R`D`?3*%)O8}v|OTb?TS13A0kflexNkq z@Xx?@oSmvbV-c*~V}SI+M<<3%(@z`pK)(74l=!PKR|2pwRRLr>-&;^z@mdyA;=i?a ztHfc`T;E);dZo$hChP$leQ}%~1UHj_(xTm`zDT+ce8t^j%!q<~ZHn;wTA2RLgO+vg zQA1Lti#ZD^A@E720#@&q#+0i*^AOIOI@YH&O;@0F@cXrKclP0woJ1pPxy zk^N&gENoX{`rt-#3UXY)36{{HZIzhZvb(|fpyJ#2Eck>pB+25}v*;e#9&6q++53g* zEQ73yx8f9u3Z!a;oX+BA=9M~v?8BrvE19AG_?Z^$pghs^h(M@jX=~;0L=MTzv=oJn zu9m)_TS-RK&wdq-s?#NS4sickM;s#)fbG&E3&4G29=Wv#;g%NY89kxigr(f8jtHqo)xV)u#<0LcLjre7l1_$n`_-lKGJHyz+s5E1=Oh7U( z>4<+<=4lI{lg0{V>Ze@SN4-9-k`aZ&b=_0`QS8>MNUC;*$&X#?BEM*t*hPL0VV~_g zyXph-S7A=c!+_rl)1RpEb@9^BWzX;Zc6AnI4!GC2|2{qeT8U#@C(UMDjja!Gu=z10`Q(zKZAu2nz_4r^7TN%;>UgVF?ARFY9ObqrIk55d(b zYCxZamo6z9XORLR+)A1B`)D{1LpKUoLWz3Gja?zqr|*)EX+lt^mTU4m0~(`uJyOJ_;HS_A&9(`@z^c%NK=Bm|)8}fh~YZnofNz}b$ z-C_+p!~AlNj0lzW7_dWyC*<89RJr1qhMh4 zyT(Nde|vNBA1l06SnAsa+X4m>Z>1qbO!3idu%P>0mAJ;R2||TJg;0698>PzCXhGyd z?p|pi^im8fmbyVA!_#O_DgI<5rRw1WbwhMKy-_n1Ye~dyvqIrBhuz=?@1@K;cYAFB zIwH`{8UaofuFA-ZD_+ZAeUefjw&fcL=)EpvI(bSttCL1&0UIo?lVL8g`WLbCaR_cyZy;7avUsA3$ysr`J?B~tumf}@X(*$1x2^lmg`UZVn?fqOaruB~1Kqx7BRkrt7(EkeGh#|OgT9sTcC0%zq9 zvX{Y$RlP#RiR<}#*UA16N_juxO*G_LK$Z91q4d>{NF^(C$(-L#Whv9jzpq1&4XF=!X-N zN`g)k0t7*ykBddXf${@Wt&jSi(-not1I7!Ur!yc{RS|!y1YDt!GRs$Djw9SvaLIs9 z`Uz2h8?b!g1A*!HbC?#u^#E7N;591gA8r6PA_%0=np`1Jz@fjUm3pTdi3hoz z;b+rqO2~!#S_wl_R&H*n3F+Q!b4(0%-Ra3u2KP`qXMee=M z9jW-Iql+QajaKyMZaPuk{+$>+`8`E^@1C1NWT6S!MMx9ThM0%7ziomXnZqq0tKL0@ z%v`=3$x#b4e?Y6UwUcqm0vPk4{cN&`T{&u3Pkm>Qq>#Pk2L4LmzG<{-@!9CfTA#T# zdP_w}(a6-f11LFAvp^9F_2}D5L_Ht)+`?luxrFa!==3D51D)qm;IAj5HHm$T!ctO^ zGc)&`Olt5=wdt;_kj%Iry75Po zoTt+&p4|+GK&+PD_^^K@7{Ty???q7a?Kbuh znR^{C1V2BA(}eK^NcFH-fh68$FbAo9Z&qWBN5!uk0gb5%zZ*Y?rEsO)GOQ^r#N_Xi zwP<3BTURhiw?}t`UM8?FD85rL0T26m+b3<0wB0mCmCO)(R_)sviME{KK`oeSfsZe~ zTvF;sqT0`Io-g4;bCCFYRHt(F z-u>Hax-KGJzx01T<)`UK%wV66-O58wnz&Cjg{FxvlNMoy878 zN*a3R1f=k4BqXaqTsG~5+3C{XA4E8-;mS-{q zkDr}!gPOCgtpxj<)8N(f46IUm4_>1(zY|A;rwDko;wyt=V&9@JH;pUUG_H+*q6Bme z{5kZHf*X>WS)r&PDZg!w6EG5G1Ti&Gy5I}vzVbQfsQf|ah0snYG2Sb_@&%^?Dhu*7aLJH*nSKQNU*e_=psR}c!94Tk9(xuMEBuvpjR zaGm+<$B~x@IXzD^saU+mCY);~eai!@>1pWq28MfV3ZIR&5@=;eKJl>o`tEi2Wd@Ra zonoWhY=MK+++KD-@F-)@(!bFn23-V~UUBgKzw|7rPHX@4MKNZMXh<4?llrq|#}_6O zu+Och^or=^MUe7c%f0%7@DR{`$wz;yHuk{!xdW&Iv`E;6Jg@4S|48ohIyb+2PRKpXTFpx-06127{HKKy^qCJgWZsllp@xoW*zV zCc8rjtk&vqvD`ylpyyNoBT}9yG_^q6_ix$pt2!^ugWqeY<6oPctTo_KbEs`as^nJ# z`jQtKF&bUlA(n@kLatO+!8Q%rhOR_Qjt;jK6xUM%?pGos-}pXtS7VxE748wEM-+T^ zffOAWFyxei{DA~?7d~G8Kmv}S2z~;^lF$Ey%l?(y2~g7`obO0^4vawUww<0=Y%-Bh z#4lgi2o}>&_hq3?0*7p&kQeqg2y=B9?;DW{)}1%v%*;v zlL8#)I}=LpX-9QVt`ST;N)B0-D|IIGz`mr=46<^5bz7e3iPWn8VJWVLp8qvX+DoDX z%1XF5iEj3W(b2tVtFgbVhD_4R-@@5uyC5-@zj6~TicBRex%l5)suhK0>bL&Rg8xuz zVki25eKjCr=lZAheCvH-uuSDMsiNwZlKN3vaWhZo9=OUXTw&|@0+G9*3GGyrXSxd# z+v_Q2X5@l;i+&bEkHMwIUTVE+q$Sto7mhjeCplZ?6-tUGHe7?B0d5w|x4l^#bU~L}VCU$B(3wW_>BLuwCjF=u!y@!r)w_Kr_ zGr_#112%lRp7ZNEGW~b9qn(7f_LzIBW(S5?TSdF!Qad9RsZ_t43j%K9BUx}?$VIE#5$Y=~f|uzkU$b{g8Gy|>Ib zkYL4=bbu)EiT-mljXx;mE`P~0r1*;+Fdq521@5o^0U?N0u9#H$3ZD@f+e&>(Cgvfo z-gd=0F7AtEpia;uStcgtnVlouFN?zd3sIMGF+S=Q@9ADBRV-wtEPbwWyUO<4S1R7c zhtJ5(?w$-_ObWPT={pZmw zGj~Ma{p@;hLrg^rj0xpWsA4lYfD6;4Uy|m+c^dSn`sQU5kC{DR>gHX$w9fC#7s06n zOtltS7Ry)re6XS>@l{Tp-wWku4{f&J<&8W?a>Wf)UW?sLyTkst;96wP>TDQC9A?}F z=50}?_zgik6Lm~ASPnz>g_fTdBOT#;itG(;K22w|tK_YqwI>~pDUQuDPw4V;ZDnAu z)RV;96<4aJSEkL$XliF_G$5|})ZA_KOAfC?5%SQLEmNLY?y_pDSR$;miZF5%-5-Eo z0zSt=21FF$3N40?a~V$Jjw>dl5W_rEgb_hcG0DbC0mK&RX(D{=AzrnBAf0zyQhjOM zxww;8rN~bMn3T99a>muf%{+JQ+Rezetc~L<1M+)Jw=ZPhQ_jGV*#x}Ihf$l>WHtu4 zAEy>ot9GsX5eV+~P{1OLp>)q&K#duUf}(Z$%^_H!2_o+-SR<;t*Ol+q*oJnSsmguf?^t!f(r<%^X^Mf74vcmwzZ@@69bSm2E&=pky^6 zeh^hPq2$v$AODQT;A*H4 z4IZDvV|FaQ{`turJd3i?;lqd4tc0ofCKpFikWE&u?Z~&~=fAlp6x_D$qLq8btz$Gj zH!||wtQ9O7uHWw13GB7{g2JdDjA>RUj3sJjJnSTL^#18zn-Ke7whKZ8(kk3=)&pMe zfmotMNZBH!h$yhwgj|$jCUub8fS5rk!-yyTIV|#jgtpx4EqTR)BkrUFh!jKDHLeJ? zmGN~n;=uop0XNNpCNRwd@3s^#K=jeQUU7RPpR-RMTRU@}H}>$T2;+U*3j~?K(s%wl zoHD@q<%SW1edJoT8|Mtl*;%ZIllbX%exSHy0`;l`#lbwmkEm2_YI94y4mE%X6hAoj z<;D0wouJYc$T@)G$gsWQ8ozNNLRBMm7yQ_O_EIyQahHFX;fLaxGml+4o<5J5d&<2M zob(fQqX3`T(lxU_??h`W`!r08?t);fx2Z zI-9UZ8!ci$Uc7|m{}<3C;9oGqh95#VO^LcGp9A>zQ-DD z+#sUH7|LdkdaI@r#b}gt0As1`MRB4VkUP?!-Z#N{;FwBm3&Z*OnZ8L0~7TZxD0Kgl2~ zxXUhThV(xe;v0>Yn6ft!>2ZY;E$l$wuh{K&IUA9VmYPXin@2e~46Lze>UAjZsHdG-);nh`cF^(=cbc zGQ1ccfA7>r0#s5R9y(!hsYnlcl}PorEDll3NI^j++uqXBQe&FWl&PDi6PL~l4RD-r z`Fyw#c~u(6t?1n>;HZ;BaxFwZ&w0*G5q^Ae=5w8lx)bM@*0&GAgF77n;7?|Vs z8?@~$Y3ZCOM6~_nDmK83l)oek#1CbR!!5IVRb0+F_--r}+CtId4xXNJQ%gS z|6HTG6P!^+s)}?5=C!B*j!h!A7a(Ro1F40#H!(V!eiB8YIrBG)Lc#N6>~l~pFwMyR z_};R2ac%<^Dv(YIYJ0;vN$FizW_1xZVaf5we%zjfM^P-{_aTgI%b)tC@(d{f41~B9 zxK{3KwcN%Jd@SD5xZpTEcIgX?V74~EFbL)iSD2!$Jw0ilI1fakprD}NCkG9$1}>eN z)O=lvk(~8j+kUxSvx*J@^sw4v5jGS+h8UQhezlkpY$0;7-7Pg!p(r1z57Y{(Pwg?~ zoUR&u{NTutl#~Rj4X{^PT3>Iw|4IhOIII#A=xqh5|CK3Ge7wBW#H!eRj?do@3_)iU z5pf=NoUqs{G5bV;Bb|VK&r@DR_XJ@pp6K0E%+2q+)n79bpZ=CjaEtNghNPf@Eoj&<3c>1@1w;;@ zZ3o>Z&OnYW_^(^9_z_vAJ!pNDMwF7uwckB?*a+=jBS>Qa1V&KdRJ?)@a+wH4*Ky}h zGeC9kP+RO={(3ZfOhVt>dZxO+hN>gA10oyumsv^P;Nm<$31^?p)>Nm@O50@PU+>e)< zE>UkvUMGIa^?L?;I27^%C!%24NChT~;?Ca*z{&$mwK7fkpkDa{=hX)lp)xhn z2c{#i{jCO26z6Q{$`TGQ0!9y@xKJiM7ksi9j8?l0lm;kBq0i#1GC*SiTY0cm0nIxZ zOlCN95?mC9sKZm`suH8(r`>Z~KfqZ-kt?nVEFMAd_%B(n#wIjIm zuDk&HDsG$yvg3ChzJ0KP z?6#XYhR|?77;652pq-JlAi#V6R>&TSl$h6gDKBq%N!id&C zgq7M^46r+SDqVpSR|5dIwld~d?esC)fxpDaD8D=O4)-%xQCMXNrzNC!U#5PQ?fE`h zI!!A}Y>VSv$4tRS6RF_OXBbD7yTMP`iN7qmL&5Ni?TvDi(y`0Tj6=-Tv6tdSBqdGu ztTwIR6W2}()So{5z>XeV(5$stjoL8i#S5sPinI%e$kJU7iuID-ZeQQ?&%N)~%J`My zo%Nv*8IXs>N3DK&_~n%`we%@S6Z5LV zf@Pe(c!HuF%D(y44?^_Cs`s@ww;ee8f#yzIAp?>-2*)!#zHz}GTtVtC_$uiJ!w{Y# zp7F4ccV!di@jEItE&VlV)g$utjMs#dysDA3b~!!v_c(z{jQ45Wd@GmOs{g-SfFKco z1<&8=%QoRN`Z?=2RZiz$KUIWedzC+Xv|~!j>lUH%z(A_>@dNWrpuF@hfWdx(4X=Al z$)b_tJ$1OAcA3ld`9>Si0tc5*J{c@UmCQ{(O zoEh_(59BkpPya!)90}T#_%q(`U`&4O9Kn_f@`FBzc~{c*mQ2*qk%UH4CL#V_Vq(@$ zGR~%A7CWDacoQ8p_`JE_ak&kMN}lDc3?C@XZ}9M}Czi4D)4d4Or|5Cr1Lr5fpX8;6 zbZuS(kE|+BXLTh;&2JQ=o~z7ESXNy+%n}wTq}V^Zlp$VnxL@}`nS&*CmLV0U_{)}G zn2Tf~?9>f=u}dBQmB}ULE=Y}+sz_tlrBpwVcWX%fb5NW=91=KS0;~chV>Icn&XpqO z?@}~G1g-uPlnPC83>?5!!rxrOVK9JOGLVp&|6#iz(5Ul{>-MV^T?=aLNE{<8D}D6_ zW{R{f)M1C@2lvYr0gtYQCPNHxf8|Ax){}j9{Cx51HGO~;7u(ad{t+q)C2Lu7d1TZ}u$Ks(+pm=8dK-koxIgzbMFWNr7ildCC3|#nAt4 zJvjKrdEw6aL-R$lX!R9&TMIFrw~AE`ONFN*UgPZ zov*vWmHHBiLK3YQn{*?Xi9t zKO=cbn^fQ8PL)cP-AFee<>h*=CfDC3N6;BDd6m)hCkMMbD3#9ECdbHTNyOyWoXmW0hrV9FZbELWxH6zo7m%sX4?f7Zi3Qg?8H@+IA zxvM0LBtZEy|FU=7b0?yFLJ1#l^yRc%fu+kOh=wWz6QAC()Ws|Dg(0M=UUJ|2Q1i~Kda6F}W z!P`dI?t)4urhneua5xIs>c}O)_KHGjEUo`_D*384lopxv2M9hn?O)tdmnR#G+#;^a zfVxDgOe^sDDz<-~b%SJ_iO(12lKn?AtBgib7@ntx->NJ@17IA0 zRK>WSI9_fubV1IK0ePscw9PRhNJi-+q9vodJqVMq>MmD5U@UXl`?-hitJyE?ZSha4 z{a-F#0RGV}boC(Fd!+GOy05wIqvKZC*_7p;-N0daCVC)~ZCwnFH^M)6E|mC?J?>k{ z`TyYwMHaVLr6h;aUY>SRd$db_?wpd%7rUH!5p3d%7by?^`?5&ChsgP)=y!&n$A1-z za-*4lda1d;6gbxwDD-ofL;t@dq&amtU22~cqz}U3J{NcueJQ;BUuIFem(f!JlE`n3 zPA)x)I4hceA6uM4=y)>1|I0Qy*H$Nj{{Og6G{!k@X`O%gV$(vG3Ge>jr+@_&7;)!A zwyVq?3EP^wcg!dMJry0DIdwNfh1*9#i+nCgiW0Uri2M`&m)0bPP83$n1Hw~S>i>R9 z6!IT}RKfq8^zUs(VpCAc}(@fz2+8dvuQ)ekR#WCj#=Zx{*rx}PrksfpaO5Ujg>2}_1M z;RT|lcFmoOpacKA#9c~Ea&EAYri&~jERQSHfmJ#H*D>9kIhd66HAqV<1% z56NVBjVKH_5~w}7-nWw!iE|$4|LD7Q+BcQf*6ucan04yyvp3b7Tm2CA4Z*FR!xtXQ z*&VyivESOMcIKv5s?8NUS2nHm1)GH_=_(2#Nd_c=WL46RJEiN7aOo6hyd z>NKrkwb^#Td7Vb7^8!W>net#WU^3h`zUZK6YOMRKs?hgR(C)AS3A?`uB9?mwgmKYO;Nh3q=NJdF|`KcAJ2%{eM1KwWTOyZ#)b0bzE2 zjQ%0`XG22DrCCxP$j~cKLp=`{0p0rTA4izGU?_?4&l19(e*HNT&74a8hLeTlG7U-Y zxls((5ESa3d%N%Iv(G{ZnzI*edM>AlvpCfGzE;t>ZhmEbrf_+eoU9T2N!f`_o5X3z ztljS6`?yTCE`(nSdn7Zaw-c#+Eqdm#hy#EplkqF$fJYzvs>_U z8{_Dioc{0FNpd?gW=$^r5fcs;l6wwr)IJZV!;Uh;t!DAd!i?!D?W~hHiv;H<0@z3h zsUd+{^hPtIn$o$z+aSaA^zu=lB7g##=fQ5{hAUhscR~!_^7fCMvK6| zlRwmis<_v>9yVq5qo(Nxf;CW5dv*3hSv0C4k0(YI_q_d$t-`7to=TIFk&@s~CVbD8 zvQy>w?`U%2<2@ZP*{yiWey42oYK*FDJI1x|ix*`b*7km%eRAGqu=#0Dx>~-l%Dl!% zhW3*4Q!Com!&W|dKRY<`>86kiF^a9H^~h{B?wj=!?nslb6*4Xl*zHu&ukclF(S>kF z7N+Su>6VFG&B$D^6-|COv|PTj^<`D*cKW;xSo5S3Nf)S@wfmdgMPK>>dbs}8J-_dy z0m>Tv%T_nuLJQIpeNFiHkz(_`{U|QoxNwo{n;x853${0s`>{hI^KD8NDf%-f$(uLv z!O6dpWkf|qW%bWHEpX~JHZJQrtD{TfkuGySyyd3gX_hTZ$V$Jg4BgwXeISp;XnQRfMNdpS&RMV(&LKKXp!h9L+RV^A_@+@ynI@m#9L}VwkONo z0L4M7vonyYR9oi?PqjIId|}YxxDZj2PpR+W@ew0OMc_L+0$C{)6#mQPgs=m;b;N#S1LY0ZHM*2ZYADG!U@aKQhpiJaUE4h*#WsDhd-%`#b3NVZ=}OzW&vF z?-2vClElzbGsJs;AWWk@+uvae{IY~}xx$A!uQluaq3EzT@VblWajmVQoXO zwhGh!RB9X-3P+JNRibZF-Zoi1mTTiomrA3!>LOuh@ z4fN>@$O!kYJsuWa8pBI7dKT(mMYa_cOYi0n(blc$cb|kJ&W=VTJY*_7%NlssNZ&EC zg*xz#e$W=WbmkAnF{wU~an#mMIQT%|!j|vhOcJH-l`AO3dwZHjC(5E0ZGO!^Rs#- zB6P*HS6x2UDMTn=soKIC17FqN@!=v_(OFcwfmxB_t(Pz!9d2H`eF%0htb>*7A{-J9 zl3PdArm{Tfuui9iICe9R)QOCY@HUhZ3=t4Z+MG$1Ku_K)kNe&nvu?lZEPN9ZsYwWhC2x_P&ES}bh1cH`e~bH3j;efi%gWE;e5c}>kd_vA zSMqZqRbmq1R_yGj%)(Vhp>}@NKSm+eGsKYWsdy9ODl6z_+8^BLMH#zibDvgfj? zw{9Ke{%X?fZF?Y|on3Jezv0r=w-P(`{$xKtp!c4HR+RGZ(WqXzbGwSumgVQ*vggw3 zX1Fd@xsWWSaB`2o*9EboqRR`nemlTroAsXiT548xQzCrk?pw(Ugme9uCTk27CT)*v zA?GdNp{Q6w%I#FOo3Hh5+vi`XgkhnwTjKQ1PQY5}C%rPEFF?BNCJ_o0(!amFyc!}$ z<+?b+f1BpX146mR#(pXzW1~TVYxyHw4AHRKz;BRU95tVug!Ac`Z9W5c?q&<(ITob^ z@j;AI1aghf$H^h_#mvJ42BXw_{PHmDLrNFFha8prZ9_@6S37%>WN1SYl}M5Efl2yv zYFu%qlp3mB7l_Y=lo$BYGmG_U*;v^VKV_$>XL*BgVnx0MOqSx^&?=DnNi3!iZpKkp&5(d+AEA7KlS1+IY zR`%SENTz5-t67Dqlrv>B*^%F+q*7RsacaAiWQ||L9V=M@TAFi|kdDm9tm;C-zF>G_CNan3$)lp<4MZKYj@%(9!$7s|@w5LMlxkkm1ej z9p$W35ZN(>@aone6RnAruciiaU!=K5Ardk4m&x2tq@{+3u0D~mm~RH}d<*>A&SF7YQYSk9R&in5 zdiryCtlX~B3(`rCG1^hQcSY=S^%OMw8@Ts{@M5Sw(Ov0 zD_`Tdx)GE(dPjEYyyk>HDU1GZR z;3bQ$Oce{Te#U`|7e77Evsqobde|{PB-LF*i!y9hKG1}N4k~xaMAOKNg^#RL$`?C- z&6BEQlkum?x0EsewIeV3nKdM&n7pE~HXy(-NNbhKbKwj1Ew@>MPX!kiGrrI3tvj) zt?~+1QYmCrS$m?VC#voTcIrjD@v>-N*jFME+}+hJerE78s6wH5Tc#{@YM#gSqb`?N zS@ZS9h-MV`rJmNaw7B~-One!G4OxceGv1}g*J*-Tzt$LA2GQQ9E07xFh0bxmx1FqznN?jR#IBl4_{BwJ>C^G!_? z1ep~7#+HpeTfLi`=*K%!q*!JUFj7OE_X5t@041U*Lx4pP4ylLtyEi*>65D-cuoC^w z?9I8p`hxav&(>##lY^u7;mEA*+oN+G>-@Dd8awJFyEi2y+b)I{%QPVTOouBF0*SVz z*phDCA?Y@F+e`N7jEY&cRykjfr2LXSwIdGLpFqc1s*KAx;QiX_u%taMeCSw5Y1Z54 zWQ1769@yIck}1fr%tq3A6()4&{kqsBo-$n888<9Vt55&Rne2*H3_c;RxwC?z%0OY#?q!dD%aBd@?h2sCKw{8>ip5VE0{jw|rMF}Bh# zJ9i9vs_m2yV#Y|j>0h(~G6t5TczCeHg>-h?is~$kqArgAD$1k;QDa*9Ar@uf5G2z1 zpvborb_ehUXM_iP6xibTo@0wZ2-l9ZETO^h_SCj?cFoP__fWo z{ZmsG-WA$haiCy=MQ|aaW({$1;Cv+p6F*54*U16w5uo>=CChS9hHgSTR!{IhuYayA zlP;5FcAtFFW^H0-)^ctqbXb-<(U^rH?NTVL65#Ld`Uja}uEY?7)F%Ydb?K7@P9q57 zLQmJY>XIL4h4!rS&9R7%qEBli*rHueton$kp)XrxmPv&LcVyN?hIkG=kK;LBW8N55 zC~wS`xQf@>ap+;#B4p2iv~a7*zG4@^F%Yqu#aTek99Sy44!8@~8j+2?uQ>}eDT?sy zH3Sfwz?FXJQU!HcY?L7}5APM2p{U)DD#mFfL}wqmRsj zCny`HPv6O^4RM|!K3i+#)3ofFASPgdB^`AXa};!f1iD(;>j5)@!G{`FdcvBisRl9v z4@_VsXa-#+KBTg-2M?Y7XRK}f zXO8MO=io}GeeO<4)f_ioBrOj;!~4$w00Twp!(WV^M5Cv3O{2l!voSZHs6Rt1XVr%) zQj6b4uq-d-yPy3!x|S~#TISaf2ISzoVgQ(eO=aChJ|hhprPOwZwLQm&dIR<};5#%` zy;x)jPPzneg)Z#|z5WyaKFTJ~>TN|X;Wz!gh5_hWsdUcOL@=ty5=Pu`}K zv4iY29vkWHJikV+y=LC8yhV=7vr=o6n`NuNRt}ED_L{r*yT{%m5x%81f^QUxyAbsJ z^cqF+bO_S5SMeBuBtfgiK`ro-vEK;o?(W`BUXdT-z)C%odga#VJ9*HYo6C9kKE`$} z6wejmlxmT5Q-I(xtjh>!L;S{5$#KKNudYUQuV8h#>MLy0-kKDpay~k21>Y8&k}B`! z5!w$?Hm}y%utA$o6;6e;MxH|-9hdT}C)A$&o|(b9mM(O-?jT~h^!W~?+tkf$wT@CMzppKDE!G;Hp)=A&wz89f5OxneCP1Mrd*-7Ebqz^s}#rT4a9VA5dyXVg4JTgW_2j zdepi$W+PP3J|0ya;sPVeuHT;@HJix>e6rg&b`boR%lVJTz_#K& z7{L$xr!-`<#G_La$;KC)3g3w){ORdVvuwjvwF^*93S}}$BnvePRZashO|X6G{iY@ z&V1bY2!8s9XZFJnT2Ppx@3=UO9BK5m-qNq;1Tl=dnKY0 zf$+zv^w_EJSe7wpWcAayYua5z_ra1Kd{-ZXi(+N}6mh*y3Yz+q__O5BxzB&MH4fR$ zeS9P+SfvOK%B7uaU}*y8_ILd=M^_Dxg~}i+dO8@nZn1Q5WVj~}AvDmC60xK}|GXt& z5H^Bz@(@2H!0s{+ozq6?IyyXmTlJIH^TKw0i60S)0Rgxn$O% zP9#pv0h{&V`uSS9teq(t86B%-4KE=`u1jSnCp#1M%2!S0@0+^^>z}6E!Ln^AeK+7} z-??u8yQ7JPh1Stuzac-YO5K?!cZ{z71#8c6a5FRX^oz*i)*cPrCq4I8AC3RfbJ(m~ zcN+m~OjBurR~;cZp~3bYa#eFJPvA1ufxpjoveWVo>eVmh?14(wMCqmWzkhGxLKR_B z$q~4gl9JL4_EImXPgN284t~Wq-(HrbdZ0PqV{%&MX&CZ-83;Dth(w2n^-{$Q%s|XO zb3ApRf!>pwCbBUv)a8G2hy7R&eP%r2M$T!s>d6q@Ss}{dU%pMkQ zgwprWcfof-i#M0Ju0>u!TQ@IxwAlhBW56y-~}KwY8FoIYr&p zwKYB*6Sc%|O11tMNQ#Qp1r6BxxpV1@N^{pj^-8O&Z{o~)-RA8K7kN4Jnls z-WDjPhkSGaR9ZCBXwLW<^Hp7)d94pLn|pQn%kGJYFUVk6x4*n3o9<)h2?GzZ#`C(f zpLr!xGq}tB3BG~tkSwSarZ#&qFD-;Db;N!|D_%*e=^J)YB2B*_^;i#D$5oGpeHbZM(exKW9H+<+pb8ZLeL21>N}0 zY%uR{(^nl=rypiboG)}>N=BR48vP2`n5d4!mS9;-yT#Ux%PdN}w$(W<6!j6$Ga>0y zWSQ0e1m!ruvbqY)vYIwKG57T=*lahDLANd8(v70cyT4}^B!>^$y-6H#6q`%Z^%^!z zLA#^wj^`PY%Xb%Y25HxqhCp8UI^W&Gpf)q2z242`)e{waxwHgql?xd+dT+GK;{D% z7xa(KB+xrbNEnZ~lN>uqz3*PY9*S>t2T7W#r0A{4(5h3?eTsqliC z#(kd^i?}Cacr_uDN9=5iY z`Lc>C8cS!-Ds=*teUGzZWsFtS_&qxOi6Fxn3wn_02G8ZEdaNchY#w zg`M+v$8!ucoCSAHZn^U}U@Ze1xrm`3>^B?k6d@g_M9Yd2Dh1h|lUs4f0CKl>!+$H_GSA*E&AY9Jc`88avrPkWP5x=B8=C(9{)4DOKS}T{GsVCUMINGxR6nQt*lB{r9=qTC zyxXNg`T0}NL5NX``w3&TGVI;5x~t2|1fA0%F5Yk`7x_^+oBH_pSn1MA|M>V@Lyg{- z6MzBQi(0EnQO`v1LiC2t}4evbG4>8M|Z|MD{I|EG1;mo}FRF zE@bRm_I=Hs?AiD2+@pMdzjMy@`}17a;d6EInKARs^Sqz?ec$)%b-!LVd~!rLyv1ib z=F(6Ywf@&o%Qfu9CsGFUsYC8rhlJrpbonbi)?D0ei^7hMFo-_6IV-}LT#lN%tMFng zpVZo`G?c$<^n4l<)-h`|;^$yXFRdy!`h7~!pUThoJjjlo+xFU@cN}b%eD&t!~31@N1pF%(N<05 zReduo%=u0cKlCV!+qKLE{KhGFqQHh%OYzH_46NvlyR7Uf!JR1l) z8IQ!1((_DI%gQ!jSTqY|IOXO)GBWZ`=w7#_(VUwv;TSm4D!MUDj7JoKzW-x{bFI#0V4iTVZPaef?T>YByPCkW6(RS>%EWu#rN?GWV zbn%4;L*o>vXts#dCm=~Z45O_=eLgJRKEiW|;TRA4@^2-(a}m*2phehZQyg$Xs-puu z=X)*;26d5u^X~_|@pR{W%D4hAw6O+bew`w<3kexr9`jo)?3bwqjsRU9kcT}y=~IJdz?(uq082;qD}G0ht`kXyH1TgNHYMHf=dGthlzoh^L=?5_T$%P zz5cMI1fTz!bFeYxT_Z9l6%auyNQYE+#!^yTtX*GSg<(hygF=mbm_;wbnbr8v;b#(5 z%rOmRtN3YK8`D3WFJU0TK(W-wU1LMZc~yyP&P^5(h%!_k3d(ib8Dp4m9FG8W$k%!2 z1&n0}{i69adXv5oI%)ZB z$=Hh)j=s8Yn#2_v854;PcjO3tUo(0HVY@;P|IJ#>SAnMkjHhegrfPu!1h}rJ;KG!V z&Uoh_v7QoEoae>J>9dK{e_-WVU5R{6-_R28ukW|rWf0$AGgWYNlp!PUu4=W2Pg=;5 zy_KG6i+Yc{mXW}AF%V9y|LZ4F9!Aw%{NE>3pg+h6tvO@v7qAfUf}N1p-{jfA>Y|3* z>5Y}Rl+THg6O2AYvPSoMn7)})1!+byF>)Bm>HlVm_egbFTwI(*9$C#LyyHo|OyYi4 z1RdNhVH)4`G|y{pLui2rlzq_693)fjX1$gw>X=L-{f7xiRCGLEO5gJj`Ll~jT%G>* z?!id!pTu5kpFZv7IGFK(Osrqm!4wL54Q$b61~ihT@udLk`anz!;{jJ5uTksxa*r9K zsGl#l>gNnN-^=zaHKVGGcNH%@@IxC=k^w{r1N{8!KP_y3hw7U(T4H`7S6hht`}^DN zM_^_&0}SJ`>_;vUW*Vrasj$m;(cC4)53oaz7*tiD!`PGg0<3Ts#ff3kx_$sjNQ_y{L ztD$!w!6(MR%H_BB$nBbk*|c=2F*ncTdkS5=#}yg z8LCTIuQBWh_V??NuHmj={;|S5y{ceV?v||wt2`wqJpp!j<*C`F%b{I;#}#h;ZzSJt zn|`S&*;~?-(`>LklWhKVO?dJ+m|><}x+?JXB$MNZv?b%QjnVHak931BE{a+n1=)1D zNf>!ry7D9FQC3^iyYXZ$dTKDz>R9m+OzmVYVUXXl^J^+$Fu~ zc1Mzc6q@@WDB6uludh#S$%AlT^H}Ft|7id1X@<@fPkYxgM0lg3EM~5FF3e|#_?=5{ zo=T^Hh>B6Tjq1RIvWzxd23dCREkT@|gfpsABiXtTW^bmEvh0Bxul>>$vCcym2CFpk zg0H9>9ffrBK685PKfglKpvDyG7qq6{Ocd44uimKhs>w}1 zdXA7w%S_=_LmS~$%tmM+L9Q8ZM0OdAYieJMp2ntgRx#H2Jt$4aUlHaGXPp~R4-NUE z+ZE<11rkz**dQY^1@B?z&a7VJjmTXa#HBMCoKLimJdPZ1YdgX74yZMqs79KMaaF}} zl848I4u0!7k4~_9{zXONRN!WCNREk#mnlm@Ftj-?OkC*fU(DO!ZX{??W0W?*(7mOz z+8iu5chF`!-^P#VoU()^zEmpSXy22JyB%##__a>Mw#-pTj&-fvd(JI4`P!;*?u^4t zZGNR%In`7@`Vm|LeOntTR<(ZRg&3Nh-wj zeDfP6Dn(%mpH<&`v=fBOpjs#GxQVo`u3oLAS!6p8C~osx0eUV}7p- z6k(dwWe6j9I}TZ