summaryrefslogtreecommitdiff
path: root/shared-bindings
diff options
context:
space:
mode:
Diffstat (limited to 'shared-bindings')
-rw-r--r--shared-bindings/_bleio/Adapter.c68
-rw-r--r--shared-bindings/_bleio/Adapter.h4
-rw-r--r--shared-bindings/_bleio/Characteristic.c30
-rw-r--r--shared-bindings/_bleio/Characteristic.h10
-rw-r--r--shared-bindings/_bleio/Connection.c1
-rw-r--r--shared-bindings/_bleio/Descriptor.c11
-rw-r--r--shared-bindings/_bleio/Service.c24
-rw-r--r--shared-bindings/_bleio/Service.h4
-rw-r--r--shared-bindings/_bleio/UUID.c2
-rw-r--r--shared-bindings/_bleio/UUID.h4
-rw-r--r--shared-bindings/_bleio/__init__.c92
-rw-r--r--shared-bindings/_bleio/__init__.h4
-rw-r--r--shared-bindings/displayio/Display.c23
-rw-r--r--shared-bindings/rgbmatrix/RGBMatrix.c2
-rw-r--r--shared-bindings/rgbmatrix/RGBMatrix.h21
-rw-r--r--shared-bindings/usb_midi/__init__.c12
16 files changed, 192 insertions, 120 deletions
diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c
index 3ffe65be3..682177093 100644
--- a/shared-bindings/_bleio/Adapter.c
+++ b/shared-bindings/_bleio/Adapter.c
@@ -48,29 +48,76 @@
#define WINDOW_DEFAULT (0.1f)
//| class Adapter:
-//| """BLE adapter
-//|
-//| The Adapter manages the discovery and connection to other nearby Bluetooth Low Energy devices.
+//| """
+//| The BLE Adapter object manages the discovery and connection to other nearby Bluetooth Low Energy devices.
//| This part of the Bluetooth Low Energy Specification is known as Generic Access Profile (GAP).
//|
//| Discovery of other devices happens during a scanning process that listens for small packets of
//| information, known as advertisements, that are broadcast unencrypted. The advertising packets
//| have two different uses. The first is to broadcast a small piece of data to anyone who cares and
-//| and nothing more. These are known as Beacons. The second class of advertisement is to promote
+//| and nothing more. These are known as beacons. The second class of advertisement is to promote
//| additional functionality available after the devices establish a connection. For example, a
-//| BLE keyboard may advertise that it can provide key information, but not what the key info is.
+//| BLE heart rate monitor would advertise that it provides the standard BLE Heart Rate Service.
//|
-//| The built-in BLE adapter can do both parts of this process: it can scan for other device
+//| The Adapter can do both parts of this process: it can scan for other device
//| advertisements and it can advertise its own data. Furthermore, Adapters can accept incoming
//| connections and also initiate connections."""
//|
-//| def __init__(self) -> None:
-//| """You cannot create an instance of `_bleio.Adapter`.
-//| Use `_bleio.adapter` to access the sole instance available."""
+//| def __init__(self, *, uart: busio.UART, rts: digitalio.DigitalInOut, cts: digitalio.DigitalInOut) -> None:
+//| """On boards that do not have native BLE, you can use an HCI co-processor.
+//| Pass the uart and pins used to communicate with the co-processor, such as an Adafruit AirLift.
+//| The co-processor must have been reset and put into BLE mode beforehand
+//| by the appropriate pin manipulation.
+//| The ``uart``, ``rts``, and ``cts`` objects are used to
+//| communicate with the HCI co-processor in HCI mode.
+//| The `Adapter` object is enabled during this call.
+//|
+//| After instantiating an Adapter, call `_bleio.set_adapter()` to set `_bleio.adapter`
+//|
+//| On boards with native BLE, you cannot create an instance of `_bleio.Adapter`;
+//| this constructor will raise `NotImplementedError`.
+//| Use `_bleio.adapter` to access the sole instance already available.
+//| """
//| ...
//|
+STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+#if CIRCUITPY_BLEIO_HCI
+ bleio_adapter_obj_t *self = common_hal_bleio_allocate_adapter_or_raise();
+ enum { ARG_uart, ARG_rts, ARG_cts };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_uart, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ busio_uart_obj_t *uart = args[ARG_uart].u_obj;
+ if (!MP_OBJ_IS_TYPE(uart, &busio_uart_type)) {
+ mp_raise_ValueError(translate("Expected a UART"));
+ }
+
+ digitalio_digitalinout_obj_t *rts = args[ARG_rts].u_obj;
+ digitalio_digitalinout_obj_t *cts = args[ARG_cts].u_obj;
+ if (!MP_OBJ_IS_TYPE(rts, &digitalio_digitalinout_type) ||
+ !MP_OBJ_IS_TYPE(cts, &digitalio_digitalinout_type)) {
+ mp_raise_ValueError(translate("Expected a DigitalInOut"));
+ }
+
+ // Will enable the adapter.
+ common_hal_bleio_adapter_construct_hci_uart(self, uart, rts, cts);
+
+ return MP_OBJ_FROM_PTR(self);
+#else
+ mp_raise_NotImplementedError(translate("Cannot create a new Adapter; use _bleio.adapter;"));
+ return mp_const_none;
+#endif // CIRCUITPY_BLEIO_HCI
+}
+
+//|
//| enabled: bool
//| """State of the BLE adapter."""
//|
@@ -362,7 +409,7 @@ const mp_obj_property_t bleio_adapter_connections_obj = {
//| """Attempts a connection to the device with the given address.
//|
//| :param Address address: The address of the peripheral to connect to
-//| :param float timeout: Try to connect for timeout seconds."""
+//| :param float/int timeout: Try to connect for timeout seconds."""
//| ...
//|
STATIC mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -426,5 +473,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_adapter_locals_dict, bleio_adapter_locals_dict
const mp_obj_type_t bleio_adapter_type = {
.base = { &mp_type_type },
.name = MP_QSTR_Adapter,
+ .make_new = bleio_adapter_make_new,
.locals_dict = (mp_obj_t)&bleio_adapter_locals_dict,
};
diff --git a/shared-bindings/_bleio/Adapter.h b/shared-bindings/_bleio/Adapter.h
index c56dbb01c..ac7e216d8 100644
--- a/shared-bindings/_bleio/Adapter.h
+++ b/shared-bindings/_bleio/Adapter.h
@@ -37,6 +37,10 @@
extern const mp_obj_type_t bleio_adapter_type;
+#if CIRCUITPY_BLEIO_HCI
+void common_hal_bleio_adapter_construct_hci_uart(bleio_adapter_obj_t *self, busio_uart_obj_t *uart, digitalio_digitalinout_obj_t *rts, digitalio_digitalinout_obj_t *cts);
+#endif // CIRCUITPY_BLEIO_HCI
+
extern bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self);
extern bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self);
extern void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled);
diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c
index dbbacb7d5..5e384a44c 100644
--- a/shared-bindings/_bleio/Characteristic.c
+++ b/shared-bindings/_bleio/Characteristic.c
@@ -109,11 +109,14 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int;
common_hal_bleio_attribute_security_mode_check_valid(write_perm);
- const mp_int_t max_length = args[ARG_max_length].u_int;
+ const mp_int_t max_length_int = args[ARG_max_length].u_int;
+ if (max_length_int <= 0) {
+ mp_raise_ValueError(translate("max_length must be > 0"));
+ }
+ const size_t max_length = (size_t) max_length_int;
const bool fixed_length = args[ARG_fixed_length].u_bool;
mp_obj_t initial_value = args[ARG_initial_value].u_obj;
- // Length will be validated in common_hal.
mp_buffer_info_t initial_value_bufinfo;
if (initial_value == mp_const_none) {
if (fixed_length && max_length > 0) {
@@ -122,7 +125,12 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
initial_value = mp_const_empty_bytes;
}
}
+
mp_get_buffer_raise(initial_value, &initial_value_bufinfo, MP_BUFFER_READ);
+ if (initial_value_bufinfo.len > max_length ||
+ (fixed_length && initial_value_bufinfo.len != max_length)) {
+ mp_raise_ValueError(translate("initial_value length is wrong"));
+ }
bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
characteristic->base.type = &bleio_characteristic_type;
@@ -212,26 +220,14 @@ const mp_obj_property_t bleio_characteristic_value_obj = {
};
//| descriptors: Descriptor
-//| """A tuple of :py:class:`Descriptor` that describe this characteristic. (read-only)"""
+//| """A tuple of :py:class:`Descriptor` objects related to this characteristic. (read-only)"""
//|
STATIC mp_obj_t bleio_characteristic_get_descriptors(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
// Return list as a tuple so user won't be able to change it.
- bleio_descriptor_obj_t *descriptors = common_hal_bleio_characteristic_get_descriptor_list(self);
- bleio_descriptor_obj_t *head = descriptors;
- size_t len = 0;
- while (head != NULL) {
- len++;
- head = head->next;
- }
- mp_obj_tuple_t * t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
- head = descriptors;
- for (size_t i = len - 1; i >= 0; i--) {
- t->items[i] = MP_OBJ_FROM_PTR(head);
- head = head->next;
- }
- return MP_OBJ_FROM_PTR(t);
+ return MP_OBJ_FROM_PTR(common_hal_bleio_characteristic_get_descriptors(self));
}
+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_descriptors_obj, bleio_characteristic_get_descriptors);
const mp_obj_property_t bleio_characteristic_descriptors_obj = {
diff --git a/shared-bindings/_bleio/Characteristic.h b/shared-bindings/_bleio/Characteristic.h
index c4356fd4b..e28d61e1f 100644
--- a/shared-bindings/_bleio/Characteristic.h
+++ b/shared-bindings/_bleio/Characteristic.h
@@ -36,14 +36,14 @@
extern const mp_obj_type_t bleio_characteristic_type;
-extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo);
-extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len);
-extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self);
-extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
-extern bleio_descriptor_obj_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self);
+extern mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self);
extern bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self);
+extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
+extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len);
extern void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor);
+extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo);
extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate);
+extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
diff --git a/shared-bindings/_bleio/Connection.c b/shared-bindings/_bleio/Connection.c
index 5d1b63bdd..b5eeaa906 100644
--- a/shared-bindings/_bleio/Connection.c
+++ b/shared-bindings/_bleio/Connection.c
@@ -31,7 +31,6 @@
#include <string.h>
#include <stdio.h>
-#include "ble_drv.h"
#include "py/objarray.h"
#include "py/objproperty.h"
#include "py/objstr.h"
diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c
index 97422f163..c313007c6 100644
--- a/shared-bindings/_bleio/Descriptor.c
+++ b/shared-bindings/_bleio/Descriptor.c
@@ -100,11 +100,14 @@ STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o
const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int;
common_hal_bleio_attribute_security_mode_check_valid(write_perm);
- const mp_int_t max_length = args[ARG_max_length].u_int;
+ const mp_int_t max_length_int = args[ARG_max_length].u_int;
+ if (max_length_int <= 0) {
+ mp_raise_ValueError(translate("max_length must be > 0"));
+ }
+ const size_t max_length = (size_t) max_length_int;
const bool fixed_length = args[ARG_fixed_length].u_bool;
mp_obj_t initial_value = args[ARG_initial_value].u_obj;
- // Length will be validated in common_hal.
mp_buffer_info_t initial_value_bufinfo;
if (initial_value == mp_const_none) {
if (fixed_length && max_length > 0) {
@@ -114,6 +117,10 @@ STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o
}
}
mp_get_buffer_raise(initial_value, &initial_value_bufinfo, MP_BUFFER_READ);
+ if (initial_value_bufinfo.len > max_length ||
+ (fixed_length && initial_value_bufinfo.len != max_length)) {
+ mp_raise_ValueError(translate("initial_value length is wrong"));
+ }
bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
descriptor->base.type = &bleio_descriptor_type;
diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c
index f410b1798..2ddf1a712 100644
--- a/shared-bindings/_bleio/Service.c
+++ b/shared-bindings/_bleio/Service.c
@@ -79,9 +79,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
//|
STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
- // Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *char_list = common_hal_bleio_service_get_characteristic_list(self);
- return mp_obj_new_tuple(char_list->len, char_list->items);
+ return MP_OBJ_FROM_PTR(common_hal_bleio_service_get_characteristics(self));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics);
@@ -151,7 +149,7 @@ STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) },
{ MP_ROM_QSTR(MP_QSTR_secondary), MP_ROM_PTR(&bleio_service_secondary_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) },
- { MP_ROM_QSTR(MP_QSTR_remote), MP_ROM_PTR(&bleio_service_remote_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remote), MP_ROM_PTR(&bleio_service_remote_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table);
@@ -173,21 +171,3 @@ const mp_obj_type_t bleio_service_type = {
.print = bleio_service_print,
.locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict
};
-
-// Helper for classes that store lists of services.
-mp_obj_tuple_t* service_linked_list_to_tuple(bleio_service_obj_t * services) {
- // Return list as a tuple so user won't be able to change it.
- bleio_service_obj_t *head = services;
- size_t len = 0;
- while (head != NULL) {
- len++;
- head = head->next;
- }
- mp_obj_tuple_t * t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
- head = services;
- for (int32_t i = len - 1; i >= 0; i--) {
- t->items[i] = MP_OBJ_FROM_PTR(head);
- head = head->next;
- }
- return t;
-}
diff --git a/shared-bindings/_bleio/Service.h b/shared-bindings/_bleio/Service.h
index 3af427f95..44d11f60d 100644
--- a/shared-bindings/_bleio/Service.h
+++ b/shared-bindings/_bleio/Service.h
@@ -41,11 +41,9 @@ extern uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, b
extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary);
extern void common_hal_bleio_service_from_remote_service(bleio_service_obj_t *self, bleio_connection_obj_t* connection, bleio_uuid_obj_t *uuid, bool is_secondary);
extern bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self);
-extern mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self);
+extern mp_obj_tuple_t *common_hal_bleio_service_get_characteristics(bleio_service_obj_t *self);
extern bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self);
extern bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self);
extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *initial_value_bufinfo);
-mp_obj_tuple_t* service_linked_list_to_tuple(bleio_service_obj_t * services);
-
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c
index 18eda0b33..fe045f385 100644
--- a/shared-bindings/_bleio/UUID.c
+++ b/shared-bindings/_bleio/UUID.c
@@ -283,7 +283,7 @@ void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
mp_printf(print, "UUID(0x%04x)", common_hal_bleio_uuid_get_uuid16(self));
} else {
uint8_t uuid128[16];
- (void) common_hal_bleio_uuid_get_uuid128(self, uuid128);
+ common_hal_bleio_uuid_get_uuid128(self, uuid128);
mp_printf(print, "UUID('"
"%02x%02x%02x%02x-"
"%02x%02x-"
diff --git a/shared-bindings/_bleio/UUID.h b/shared-bindings/_bleio/UUID.h
index 1490737a7..b10cce67f 100644
--- a/shared-bindings/_bleio/UUID.h
+++ b/shared-bindings/_bleio/UUID.h
@@ -34,9 +34,9 @@ void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
extern const mp_obj_type_t bleio_uuid_type;
-extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[]);
+extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]);
extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self);
-extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
+extern void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self);
void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf);
diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c
index ee9c4bf4a..3d9084dd5 100644
--- a/shared-bindings/_bleio/__init__.c
+++ b/shared-bindings/_bleio/__init__.c
@@ -108,43 +108,95 @@ NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* fmt, ...)
// Called when _bleio is imported.
STATIC mp_obj_t bleio___init__(void) {
+// HCI cannot be enabled on import, because we need to setup the HCI adapter first.
+#if !CIRCUITPY_BLEIO_HCI
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true);
+#endif
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(bleio___init___obj, bleio___init__);
+// Need a forward reference due to mutual references.
+#if CIRCUITPY_BLEIO_HCI
+STATIC mp_obj_dict_t bleio_module_globals;
+#endif
+
+//| def set_adapter(adapter: Optional[_bleio.Adapter]) -> None:
+//| """Set the adapter to use for BLE, such as when using an HCI adapter.
+//| Raises `NotImplementedError` when the adapter is a singleton and cannot be set."""
+//| ...
+//|
+mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj) {
+#if CIRCUITPY_BLEIO_HCI
+ if (adapter_obj != mp_const_none && !MP_OBJ_IS_TYPE(adapter_obj, &bleio_adapter_type)) {
+ mp_raise_TypeError_varg(translate("Expected a %q"), bleio_adapter_type.name);
+ }
+
+ // Equivalent of:
+ // bleio.adapter = adapter_obj
+ mp_map_elem_t *elem = mp_map_lookup(&bleio_module_globals.map, MP_ROM_QSTR(MP_QSTR_adapter), MP_MAP_LOOKUP);
+ if (elem) {
+ elem->value = adapter_obj;
+ }
+#else
+ mp_raise_NotImplementedError(translate("Not settable"));
+#endif
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_set_adapter_obj, bleio_set_adapter);
+
+#if CIRCUITPY_BLEIO_HCI
+// Make the module dictionary be in RAM, so that _bleio.adapter can be set.
+// Use a local macro to define how table entries should be converted.
+#define OBJ_FROM_PTR MP_OBJ_FROM_PTR
+STATIC mp_map_elem_t bleio_module_globals_table[] = {
+#else
+#define OBJ_FROM_PTR MP_ROM_PTR
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
+#endif
// Name must be the first entry so that the exception printing below is correct.
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__bleio) },
- { MP_ROM_QSTR(MP_QSTR_Adapter), MP_ROM_PTR(&bleio_adapter_type) },
- { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) },
- { MP_ROM_QSTR(MP_QSTR_Attribute), MP_ROM_PTR(&bleio_attribute_type) },
- { MP_ROM_QSTR(MP_QSTR_Connection), MP_ROM_PTR(&bleio_connection_type) },
- { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
- { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) },
- { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
- { MP_ROM_QSTR(MP_QSTR_PacketBuffer), MP_ROM_PTR(&bleio_packet_buffer_type) },
- { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
- { MP_ROM_QSTR(MP_QSTR_ScanResults), MP_ROM_PTR(&bleio_scanresults_type) },
- { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) },
- { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) },
-
- // Properties
+ { MP_ROM_QSTR(MP_QSTR_Adapter), OBJ_FROM_PTR(&bleio_adapter_type) },
+ { MP_ROM_QSTR(MP_QSTR_Address), OBJ_FROM_PTR(&bleio_address_type) },
+ { MP_ROM_QSTR(MP_QSTR_Attribute), OBJ_FROM_PTR(&bleio_attribute_type) },
+ { MP_ROM_QSTR(MP_QSTR_Connection), OBJ_FROM_PTR(&bleio_connection_type) },
+ { MP_ROM_QSTR(MP_QSTR_Characteristic), OBJ_FROM_PTR(&bleio_characteristic_type) },
+ { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), OBJ_FROM_PTR(&bleio_characteristic_buffer_type) },
+ { MP_ROM_QSTR(MP_QSTR_Descriptor), OBJ_FROM_PTR(&bleio_descriptor_type) },
+ { MP_ROM_QSTR(MP_QSTR_PacketBuffer), OBJ_FROM_PTR(&bleio_packet_buffer_type) },
+ { MP_ROM_QSTR(MP_QSTR_ScanEntry), OBJ_FROM_PTR(&bleio_scanentry_type) },
+ { MP_ROM_QSTR(MP_QSTR_ScanResults), OBJ_FROM_PTR(&bleio_scanresults_type) },
+ { MP_ROM_QSTR(MP_QSTR_Service), OBJ_FROM_PTR(&bleio_service_type) },
+ { MP_ROM_QSTR(MP_QSTR_UUID), OBJ_FROM_PTR(&bleio_uuid_type) },
+
+#if CIRCUITPY_BLEIO_HCI
+ // For HCI, _bleio.adapter is settable, and starts as None.
+ { MP_ROM_QSTR(MP_QSTR_adapter), mp_const_none },
+ { MP_ROM_QSTR(MP_QSTR_set_adapter), (mp_obj_t) &bleio_set_adapter_obj },
+#else
+ // For non-HCI _bleio.adapter is a fixed singleton, and is not settable.
+ // _bleio.set_adapter will raise NotImplementedError.
{ MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) },
+ { MP_ROM_QSTR(MP_QSTR_set_adapter), MP_ROM_PTR(&bleio_set_adapter_obj) },
+#endif
// Errors
- { MP_ROM_QSTR(MP_QSTR_BluetoothError), MP_ROM_PTR(&mp_type_bleio_BluetoothError) },
- { MP_ROM_QSTR(MP_QSTR_ConnectionError), MP_ROM_PTR(&mp_type_bleio_ConnectionError) },
- { MP_ROM_QSTR(MP_QSTR_RoleError), MP_ROM_PTR(&mp_type_bleio_RoleError) },
- { MP_ROM_QSTR(MP_QSTR_SecurityError), MP_ROM_PTR(&mp_type_bleio_SecurityError) },
+ { MP_ROM_QSTR(MP_QSTR_BluetoothError), OBJ_FROM_PTR(&mp_type_bleio_BluetoothError) },
+ { MP_ROM_QSTR(MP_QSTR_ConnectionError), OBJ_FROM_PTR(&mp_type_bleio_ConnectionError) },
+ { MP_ROM_QSTR(MP_QSTR_RoleError), OBJ_FROM_PTR(&mp_type_bleio_RoleError) },
+ { MP_ROM_QSTR(MP_QSTR_SecurityError), OBJ_FROM_PTR(&mp_type_bleio_SecurityError) },
// Initialization
- { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&bleio___init___obj) },
-
+ { MP_ROM_QSTR(MP_QSTR___init__), OBJ_FROM_PTR(&bleio___init___obj) },
};
+#if CIRCUITPY_BLEIO_HCI
+// Module dict is mutable to allow setting _bleio.adapter.
+STATIC MP_DEFINE_MUTABLE_DICT(bleio_module_globals, bleio_module_globals_table);
+#else
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);
+#endif
void bleio_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS;
diff --git a/shared-bindings/_bleio/__init__.h b/shared-bindings/_bleio/__init__.h
index 5256bdaa0..588b1f197 100644
--- a/shared-bindings/_bleio/__init__.h
+++ b/shared-bindings/_bleio/__init__.h
@@ -55,15 +55,17 @@ extern const mp_obj_type_t mp_type_bleio_ConnectionError;
extern const mp_obj_type_t mp_type_bleio_RoleError;
extern const mp_obj_type_t mp_type_bleio_SecurityError;
+extern mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj);
+
NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t* msg, ...);
NORETURN void mp_raise_bleio_ConnectionError(const compressed_string_t* msg, ...);
NORETURN void mp_raise_bleio_RoleError(const compressed_string_t* msg);
NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* msg, ...);
+bleio_adapter_obj_t *common_hal_bleio_allocate_adapter_or_raise(void);
void common_hal_bleio_check_connected(uint16_t conn_handle);
uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
-mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device);
void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist);
size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len);
diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c
index c4fbdab2e..f36aeed18 100644
--- a/shared-bindings/displayio/Display.c
+++ b/shared-bindings/displayio/Display.c
@@ -215,28 +215,33 @@ STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in)
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show);
-//| def refresh(self, *, target_frames_per_second: int = 60, minimum_frames_per_second: int = 1) -> bool:
+//| def refresh(self, *, target_frames_per_second: Optional[int] = None, minimum_frames_per_second: int = 1) -> bool:
//| """When auto refresh is off, waits for the target frame rate and then refreshes the display,
//| returning True. If the call has taken too long since the last refresh call for the given
//| target frame rate, then the refresh returns False immediately without updating the screen to
//| hopefully help getting caught up.
//|
//| If the time since the last successful refresh is below the minimum frame rate, then an
-//| exception will be raised. Set minimum_frames_per_second to 0 to disable.
+//| exception will be raised. Set ``minimum_frames_per_second`` to 0 to disable.
+//|
+//| When auto refresh is off, ``display.refresh()`` or ``display.refresh(target_frames_per_second=None)``
+//| will update the display immediately.
//|
//| When auto refresh is on, updates the display immediately. (The display will also update
//| without calls to this.)
//|
//| :param int target_frames_per_second: How many times a second `refresh` should be called and the screen updated.
+//| Set to `None` for immediate refresh.
//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second."""
//| ...
//|
STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_target_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 60} },
+ { MP_QSTR_target_frames_per_second, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
{ MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
};
+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -246,8 +251,18 @@ STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos
if (minimum_frames_per_second > 0) {
maximum_ms_per_real_frame = 1000 / minimum_frames_per_second;
}
- return mp_obj_new_bool(common_hal_displayio_display_refresh(self, 1000 / args[ARG_target_frames_per_second].u_int, maximum_ms_per_real_frame));
+
+ uint32_t target_ms_per_frame;
+ if (args[ARG_target_frames_per_second].u_obj == mp_const_none) {
+ target_ms_per_frame = 0xffffffff;
+ }
+ else {
+ target_ms_per_frame = 1000 / mp_obj_get_int(args[ARG_target_frames_per_second].u_obj);
+ }
+
+ return mp_obj_new_bool(common_hal_displayio_display_refresh(self, target_ms_per_frame, maximum_ms_per_real_frame));
}
+
MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_refresh_obj, 1, displayio_display_obj_refresh);
//| auto_refresh: bool
diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c
index 9cfc0d409..e4683af92 100644
--- a/shared-bindings/rgbmatrix/RGBMatrix.c
+++ b/shared-bindings/rgbmatrix/RGBMatrix.c
@@ -252,7 +252,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_deinit(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(rgbmatrix_rgbmatrix_deinit_obj, rgbmatrix_rgbmatrix_deinit);
static void check_for_deinit(rgbmatrix_rgbmatrix_obj_t *self) {
- if (!self->core.rgbPins) {
+ if (!self->protomatter.rgbPins) {
raise_deinited_error();
}
}
diff --git a/shared-bindings/rgbmatrix/RGBMatrix.h b/shared-bindings/rgbmatrix/RGBMatrix.h
index 027f817bb..1dc5a406c 100644
--- a/shared-bindings/rgbmatrix/RGBMatrix.h
+++ b/shared-bindings/rgbmatrix/RGBMatrix.h
@@ -24,29 +24,12 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_RGBMATRIX_RGBMATRIX_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_RGBMATRIX_RGBMATRIX_H
+#pragma once
#include "shared-module/rgbmatrix/RGBMatrix.h"
#include "lib/protomatter/core.h"
extern const mp_obj_type_t rgbmatrix_RGBMatrix_type;
-typedef struct {
- mp_obj_base_t base;
- mp_obj_t framebuffer;
- mp_buffer_info_t bufinfo;
- Protomatter_core core;
- void *timer;
- uint16_t bufsize, width;
- uint8_t rgb_pins[30];
- uint8_t addr_pins[10];
- uint8_t clock_pin, latch_pin, oe_pin;
- uint8_t rgb_count, addr_count;
- uint8_t bit_depth;
- bool core_is_initialized;
- bool paused;
- bool doublebuffer;
-} rgbmatrix_rgbmatrix_obj_t;
void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void* timer);
void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t*);
@@ -57,5 +40,3 @@ bool common_hal_rgbmatrix_rgbmatrix_get_paused(rgbmatrix_rgbmatrix_obj_t* self);
void common_hal_rgbmatrix_rgbmatrix_refresh(rgbmatrix_rgbmatrix_obj_t* self);
int common_hal_rgbmatrix_rgbmatrix_get_width(rgbmatrix_rgbmatrix_obj_t* self);
int common_hal_rgbmatrix_rgbmatrix_get_height(rgbmatrix_rgbmatrix_obj_t* self);
-
-#endif
diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c
index e61086f84..d88a0db48 100644
--- a/shared-bindings/usb_midi/__init__.c
+++ b/shared-bindings/usb_midi/__init__.c
@@ -51,17 +51,7 @@ mp_map_elem_t usb_midi_module_globals_table[] = {
};
// This isn't const so we can set ports dynamically.
-mp_obj_dict_t usb_midi_module_globals = {
- .base = {&mp_type_dict},
- .map = {
- .all_keys_are_qstrs = 1,
- .is_fixed = 1,
- .is_ordered = 1,
- .used = MP_ARRAY_SIZE(usb_midi_module_globals_table),
- .alloc = MP_ARRAY_SIZE(usb_midi_module_globals_table),
- .table = usb_midi_module_globals_table,
- },
-};
+MP_DEFINE_MUTABLE_DICT(usb_midi_module_globals, usb_midi_module_globals_table);
const mp_obj_module_t usb_midi_module = {
.base = { &mp_type_module },