summaryrefslogtreecommitdiff
path: root/shared-bindings
diff options
context:
space:
mode:
Diffstat (limited to 'shared-bindings')
-rw-r--r--shared-bindings/_bleio/Adapter.c28
-rw-r--r--shared-bindings/_bleio/Adapter.h2
-rw-r--r--shared-bindings/_bleio/Characteristic.c6
-rw-r--r--shared-bindings/_bleio/CharacteristicBuffer.c9
-rw-r--r--shared-bindings/_bleio/Connection.c109
-rw-r--r--shared-bindings/_bleio/Connection.h7
-rw-r--r--shared-bindings/_bleio/Descriptor.c4
-rw-r--r--shared-bindings/_bleio/Service.c4
-rw-r--r--shared-bindings/_bleio/__init__.c69
-rw-r--r--shared-bindings/_bleio/__init__.h22
-rw-r--r--shared-bindings/audiobusio/I2SOut.c3
-rw-r--r--shared-bindings/audiocore/RawSample.c11
-rw-r--r--shared-bindings/audiocore/RawSample.h2
-rw-r--r--shared-bindings/audiocore/WaveFile.c12
-rw-r--r--shared-bindings/audiomixer/Mixer.c11
-rw-r--r--shared-bindings/audiomixer/Mixer.h2
-rw-r--r--shared-bindings/audiomp3/MP3File.c226
-rw-r--r--shared-bindings/audiomp3/MP3File.h48
-rw-r--r--shared-bindings/audiomp3/__init__.c60
-rw-r--r--shared-bindings/audiomp3/__init__.h34
-rw-r--r--shared-bindings/board/__init__.c6
-rw-r--r--shared-bindings/busio/UART.c47
-rw-r--r--shared-bindings/busio/UART.h3
-rw-r--r--shared-bindings/displayio/OnDiskBitmap.c2
-rw-r--r--shared-bindings/microcontroller/Pin.h2
-rw-r--r--shared-bindings/socket/__init__.c1
-rw-r--r--shared-bindings/terminalio/Terminal.c1
-rw-r--r--shared-bindings/time/__init__.c4
-rw-r--r--shared-bindings/usb_midi/PortIn.c1
-rw-r--r--shared-bindings/usb_midi/PortOut.c1
30 files changed, 691 insertions, 46 deletions
diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c
index a64167e5a..5d3211b0c 100644
--- a/shared-bindings/_bleio/Adapter.c
+++ b/shared-bindings/_bleio/Adapter.c
@@ -29,6 +29,7 @@
#include "py/objproperty.h"
#include "py/runtime.h"
+#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/Adapter.h"
@@ -144,6 +145,9 @@ const mp_obj_property_t bleio_adapter_name_obj = {
//| Starts advertising until `stop_advertising` is called or if connectable, another device
//| connects to us.
//|
+//| .. warning: If data is longer than 31 bytes, then this will automatically advertise as an
+//| extended advertisement that older BLE 4.x clients won't be able to scan for.
+//|
//| :param buf data: advertising data packet bytes
//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
@@ -182,7 +186,12 @@ STATIC mp_obj_t bleio_adapter_start_advertising(mp_uint_t n_args, const mp_obj_t
ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
}
- common_hal_bleio_adapter_start_advertising(self, args[ARG_connectable].u_bool, interval,
+ bool connectable = args[ARG_connectable].u_bool;
+ if (data_bufinfo.len > 31 && connectable && scan_response_bufinfo.len > 0) {
+ mp_raise_bleio_BluetoothError(translate("Cannot have scan responses for extended, connectable advertisements."));
+ }
+
+ common_hal_bleio_adapter_start_advertising(self, connectable, interval,
&data_bufinfo, &scan_response_bufinfo);
return mp_const_none;
@@ -201,7 +210,7 @@ STATIC mp_obj_t bleio_adapter_stop_advertising(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_advertising_obj, bleio_adapter_stop_advertising);
-//| .. method:: start_scan(prefixes=b"", \*, buffer_size=512, extended=False, timeout=None, interval=0.1, window=0.1, minimum_rssi=-80)
+//| .. method:: start_scan(prefixes=b"", \*, buffer_size=512, extended=False, timeout=None, interval=0.1, window=0.1, minimum_rssi=-80, active=True)
//|
//| Starts a BLE scan and returns an iterator of results. Advertisements and scan responses are
//| filtered and returned separately.
@@ -227,7 +236,7 @@ STATIC mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args
{ MP_QSTR_prefixes, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 512} },
{ MP_QSTR_extended, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
- { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_minimum_rssi, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -80} },
@@ -239,7 +248,7 @@ STATIC mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mp_float_t timeout = 0;
- if (args[ARG_timeout].u_obj != MP_OBJ_NULL) {
+ if (args[ARG_timeout].u_obj != mp_const_none) {
timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
}
@@ -306,7 +315,7 @@ const mp_obj_property_t bleio_adapter_connected_obj = {
//| .. attribute:: connections
//|
-//| Tuple of active connections including those initiated through
+//| Tuple of active connections including those initiated through
//| :py:meth:`_bleio.Adapter.connect`. (read-only)
//|
STATIC mp_obj_t bleio_adapter_get_connections(mp_obj_t self) {
@@ -321,7 +330,7 @@ const mp_obj_property_t bleio_adapter_connections_obj = {
(mp_obj_t)&mp_const_none_obj },
};
-//| .. method:: connect(address, *, timeout, pair=False)
+//| .. method:: connect(address, *, timeout)
//|
//| Attempts a connection to the device with the given address.
//|
@@ -331,24 +340,23 @@ const mp_obj_property_t bleio_adapter_connections_obj = {
STATIC mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- enum { ARG_address, ARG_timeout, ARG_pair };
+ enum { ARG_address, ARG_timeout };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
- { MP_QSTR_pair, 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 - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
if (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) {
- mp_raise_ValueError(translate("Expected an Address"));
+ mp_raise_TypeError(translate("Expected an Address"));
}
bleio_address_obj_t *address = MP_OBJ_TO_PTR(args[ARG_address].u_obj);
mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
- return common_hal_bleio_adapter_connect(self, address, timeout, args[ARG_pair].u_bool);
+ return common_hal_bleio_adapter_connect(self, address, timeout);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_connect_obj, 2, bleio_adapter_connect);
diff --git a/shared-bindings/_bleio/Adapter.h b/shared-bindings/_bleio/Adapter.h
index 2ff77f755..4340d82c1 100644
--- a/shared-bindings/_bleio/Adapter.h
+++ b/shared-bindings/_bleio/Adapter.h
@@ -55,6 +55,6 @@ void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self);
bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self);
-mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, bool pair);
+mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c
index d89da2a2f..7fcf274da 100644
--- a/shared-bindings/_bleio/Characteristic.c
+++ b/shared-bindings/_bleio/Characteristic.c
@@ -94,12 +94,12 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
const mp_obj_t service_obj = args[ARG_service].u_obj;
if (!MP_OBJ_IS_TYPE(service_obj, &bleio_service_type)) {
- mp_raise_ValueError(translate("Expected a Service"));
+ mp_raise_TypeError(translate("Expected a Service"));
}
const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
- mp_raise_ValueError(translate("Expected a UUID"));
+ mp_raise_TypeError(translate("Expected a UUID"));
}
const bleio_characteristic_properties_t properties = args[ARG_properties].u_int;
@@ -168,7 +168,7 @@ const mp_obj_property_t bleio_characteristic_properties_obj = {
//| .. attribute:: uuid
//|
//| The UUID of this characteristic. (read-only)
-//|
+//|
//| Will be ``None`` if the 128-bit UUID for this characteristic is not known.
//|
STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) {
diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c
index 9cc708eb7..fc95d0d50 100644
--- a/shared-bindings/_bleio/CharacteristicBuffer.c
+++ b/shared-bindings/_bleio/CharacteristicBuffer.c
@@ -30,13 +30,14 @@
#include "py/runtime.h"
#include "py/stream.h"
+#include "shared-bindings/_bleio/__init__.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"));
+ mp_raise_bleio_ConnectionError(translate("Not connected"));
}
}
@@ -83,7 +84,7 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type,
}
if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) {
- mp_raise_ValueError(translate("Expected a Characteristic"));
+ mp_raise_TypeError(translate("Expected a Characteristic"));
}
bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t);
@@ -151,9 +152,6 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(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;
@@ -232,6 +230,7 @@ STATIC const mp_rom_map_elem_t bleio_characteristic_buffer_locals_dict_table[] =
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 = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = bleio_characteristic_buffer_read,
.write = bleio_characteristic_buffer_write,
.ioctl = bleio_characteristic_buffer_ioctl,
diff --git a/shared-bindings/_bleio/Connection.c b/shared-bindings/_bleio/Connection.c
index 1c6931b29..c157af365 100644
--- a/shared-bindings/_bleio/Connection.c
+++ b/shared-bindings/_bleio/Connection.c
@@ -36,6 +36,7 @@
#include "py/objproperty.h"
#include "py/objstr.h"
#include "py/runtime.h"
+#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/Characteristic.h"
@@ -65,9 +66,9 @@
//| connection = _bleio.adapter.connect(my_entry.address, timeout=10)
//|
-STATIC void ensure_connected(bleio_connection_obj_t *self) {
+void bleio_connection_ensure_connected(bleio_connection_obj_t *self) {
if (!common_hal_bleio_connection_get_connected(self)) {
- mp_raise_ValueError(translate("Connection has been disconnected and can no longer be used. Create a new connection."));
+ mp_raise_bleio_ConnectionError(translate("Connection has been disconnected and can no longer be used. Create a new connection."));
}
}
@@ -79,18 +80,39 @@ STATIC void ensure_connected(bleio_connection_obj_t *self) {
//|
//| .. method:: disconnect()
//|
-//| Disconnects from the remote peripheral.
+//| Disconnects from the remote peripheral. Does nothing if already disconnected.
//|
STATIC mp_obj_t bleio_connection_disconnect(mp_obj_t self_in) {
bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
- ensure_connected(self);
-
+ // common_hal_bleio_connection_disconnect() does nothing if already disconnected.
common_hal_bleio_connection_disconnect(self->connection);
-
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_disconnect_obj, bleio_connection_disconnect);
+
+//| .. method:: pair(*, bond=True)
+//|
+//| Pair to the peer to improve security.
+//|
+STATIC mp_obj_t bleio_connection_pair(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_bond };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_bond, MP_ARG_BOOL, {.u_bool = true} },
+ };
+
+ 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);
+
+ bleio_connection_ensure_connected(self);
+
+ common_hal_bleio_connection_pair(self->connection, args[ARG_bond].u_bool);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_pair_obj, 1, bleio_connection_pair);
+
//| .. method:: discover_remote_services(service_uuids_whitelist=None)
//|
//| Do BLE discovery for all services or for the given service UUIDS,
@@ -98,19 +120,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_disconnect_obj, bleio_connecti
//| `Connection.connected` must be True.
//|
//| :param iterable service_uuids_whitelist:
-//|
+//|
//| an iterable of :py:class:~`UUID` objects for the services provided by the peripheral
//| that you want to use.
//|
//| The peripheral may provide more services, but services not listed are ignored
//| and will not be returned.
//|
-//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be
+//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be
//| slow.
//|
//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
-//| service or characteristic to be discovered. Creating the UUID causes the UUID to be
+//| service or characteristic to be discovered. Creating the UUID causes the UUID to be
//| registered for use. (This restriction may be lifted in the future.)
//|
//| :return: A tuple of `_bleio.Service` objects provided by the remote peripheral.
@@ -126,7 +148,7 @@ STATIC mp_obj_t bleio_connection_discover_remote_services(mp_uint_t n_args, cons
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);
- ensure_connected(self);
+ bleio_connection_ensure_connected(self);
return MP_OBJ_FROM_PTR(common_hal_bleio_connection_discover_remote_services(
self,
@@ -136,7 +158,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_discover_remote_services_obj,
//| .. attribute:: connected
//|
-//| True if connected to a remote peer.
+//| True if connected to the remote peer.
//|
STATIC mp_obj_t bleio_connection_get_connected(mp_obj_t self_in) {
bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -152,13 +174,76 @@ const mp_obj_property_t bleio_connection_connected_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+
+//| .. attribute:: paired
+//|
+//| True if paired to the remote peer.
+//|
+STATIC mp_obj_t bleio_connection_get_paired(mp_obj_t self_in) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_connection_get_paired(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_paired_obj, bleio_connection_get_paired);
+
+const mp_obj_property_t bleio_connection_paired_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_connection_get_paired_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+
+//| .. attribute:: connection_interval
+//|
+//| Time between transmissions in milliseconds. Will be multiple of 1.25ms. Lower numbers
+//| increase speed and decrease latency but increase power consumption.
+//|
+//| When setting connection_interval, the peer may reject the new interval and
+//| `connection_interval` will then remain the same.
+//|
+//| Apple has additional guidelines that dictate should be a multiple of 15ms except if HID is
+//| available. When HID is available Apple devices may accept 11.25ms intervals.
+//|
+//|
+STATIC mp_obj_t bleio_connection_get_connection_interval(mp_obj_t self_in) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ bleio_connection_ensure_connected(self);
+ return mp_obj_new_float(common_hal_bleio_connection_get_connection_interval(self->connection));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_connection_interval_obj, bleio_connection_get_connection_interval);
+
+STATIC mp_obj_t bleio_connection_set_connection_interval(mp_obj_t self_in, mp_obj_t interval_in) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_float_t interval = mp_obj_get_float(interval_in);
+
+ bleio_connection_ensure_connected(self);
+ common_hal_bleio_connection_set_connection_interval(self->connection, interval);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_connection_set_connection_interval_obj, bleio_connection_set_connection_interval);
+
+const mp_obj_property_t bleio_connection_connection_interval_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_connection_get_connection_interval_obj,
+ (mp_obj_t)&bleio_connection_set_connection_interval_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
STATIC const mp_rom_map_elem_t bleio_connection_locals_dict_table[] = {
// Methods
+ { MP_ROM_QSTR(MP_QSTR_pair), MP_ROM_PTR(&bleio_connection_pair_obj) },
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_connection_disconnect_obj) },
{ MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_connection_discover_remote_services_obj) },
// Properties
- { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_connection_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_connection_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_paired), MP_ROM_PTR(&bleio_connection_paired_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connection_interval), MP_ROM_PTR(&bleio_connection_connection_interval_obj) },
+
};
STATIC MP_DEFINE_CONST_DICT(bleio_connection_locals_dict, bleio_connection_locals_dict_table);
diff --git a/shared-bindings/_bleio/Connection.h b/shared-bindings/_bleio/Connection.h
index 5de6730c9..c6f260160 100644
--- a/shared-bindings/_bleio/Connection.h
+++ b/shared-bindings/_bleio/Connection.h
@@ -34,8 +34,15 @@
extern const mp_obj_type_t bleio_connection_type;
+extern void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond);
extern void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self);
extern bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self);
+extern bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self);
extern mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist);
+mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self);
+void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval);
+
+void bleio_connection_ensure_connected(bleio_connection_obj_t *self);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CONNECTION_H
diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c
index 45a95903e..f7b6b5bbf 100644
--- a/shared-bindings/_bleio/Descriptor.c
+++ b/shared-bindings/_bleio/Descriptor.c
@@ -89,12 +89,12 @@ STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o
const mp_obj_t characteristic_obj = args[ARG_characteristic].u_obj;
if (!MP_OBJ_IS_TYPE(characteristic_obj, &bleio_characteristic_type)) {
- mp_raise_ValueError(translate("Expected a Characteristic"));
+ mp_raise_TypeError(translate("Expected a Characteristic"));
}
const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
- mp_raise_ValueError(translate("Expected a UUID"));
+ mp_raise_TypeError(translate("Expected a UUID"));
}
const bleio_attribute_security_mode_t read_perm = args[ARG_read_perm].u_int;
diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c
index 3e1ad7088..bc242bc36 100644
--- a/shared-bindings/_bleio/Service.c
+++ b/shared-bindings/_bleio/Service.c
@@ -64,7 +64,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
- mp_raise_ValueError(translate("Expected a UUID"));
+ mp_raise_TypeError(translate("Expected a UUID"));
}
const bool is_secondary = args[ARG_secondary].u_bool;
@@ -136,7 +136,7 @@ const mp_obj_property_t bleio_service_secondary_obj = {
//| .. attribute:: uuid
//|
//| The UUID of this service. (read-only)
-//|
+//|
//| Will be ``None`` if the 128-bit UUID for this service is not known.
//|
STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) {
diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c
index 0c6ebb973..ba2454da4 100644
--- a/shared-bindings/_bleio/__init__.c
+++ b/shared-bindings/_bleio/__init__.c
@@ -26,6 +26,8 @@
* THE SOFTWARE.
*/
+#include "py/objexcept.h"
+#include "py/runtime.h"
#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/Attribute.h"
@@ -78,7 +80,58 @@
//| This object is the sole instance of `_bleio.Adapter`.
//|
+//| .. class:: BluetoothError(Exception)
+//|
+//| Catch all exception for Bluetooth related errors.
+//|
+MP_DEFINE_BLEIO_EXCEPTION(BluetoothError, Exception)
+
+NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t* fmt, ...) {
+ va_list argptr;
+ va_start(argptr,fmt);
+ mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_BluetoothError, fmt, argptr);
+ va_end(argptr);
+ nlr_raise(exception);
+}
+
+//| .. class:: ConnectionError(BluetoothError)
+//|
+//| Raised when a connection is unavailable.
+//|
+MP_DEFINE_BLEIO_EXCEPTION(ConnectionError, bleio_BluetoothError)
+NORETURN void mp_raise_bleio_ConnectionError(const compressed_string_t* fmt, ...) {
+ va_list argptr;
+ va_start(argptr,fmt);
+ mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_ConnectionError, fmt, argptr);
+ va_end(argptr);
+ nlr_raise(exception);
+}
+
+//| .. class:: RoleError(BluetoothError)
+//|
+//| Raised when a resource is used as the mismatched role. For example, if a local CCCD is
+//| attempted to be set but they can only be set when remote.
+//|
+MP_DEFINE_BLEIO_EXCEPTION(RoleError, bleio_BluetoothError)
+NORETURN void mp_raise_bleio_RoleError(const compressed_string_t* msg) {
+ mp_raise_msg(&mp_type_bleio_RoleError, msg);
+}
+
+//| .. class:: SecurityError(BluetoothError)
+//|
+//| Raised when a security related error occurs.
+//|
+MP_DEFINE_BLEIO_EXCEPTION(SecurityError, bleio_BluetoothError)
+NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* fmt, ...) {
+ va_list argptr;
+ va_start(argptr,fmt);
+ mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_SecurityError, fmt, argptr);
+ va_end(argptr);
+ nlr_raise(exception);
+}
+
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
+ // 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) },
@@ -94,10 +147,26 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
// Properties
{ MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) },
+
+ // 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) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);
+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;
+ bool is_subclass = kind & PRINT_EXC_SUBCLASS;
+ if (!is_subclass && (k == PRINT_EXC)) {
+ mp_print_str(print, qstr_str(MP_OBJ_QSTR_VALUE(bleio_module_globals_table[0].value)));
+ mp_print_str(print, ".");
+ }
+ mp_obj_exception_print(print, o_in, kind);
+}
+
const mp_obj_module_t bleio_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&bleio_module_globals,
diff --git a/shared-bindings/_bleio/__init__.h b/shared-bindings/_bleio/__init__.h
index 92c695fa6..5256bdaa0 100644
--- a/shared-bindings/_bleio/__init__.h
+++ b/shared-bindings/_bleio/__init__.h
@@ -38,6 +38,28 @@
extern bleio_adapter_obj_t common_hal_bleio_adapter_obj;
+void bleio_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind);
+
+#define MP_DEFINE_BLEIO_EXCEPTION(exc_name, base_name) \
+const mp_obj_type_t mp_type_bleio_ ## exc_name = { \
+ { &mp_type_type }, \
+ .name = MP_QSTR_ ## exc_name, \
+ .print = bleio_exception_print, \
+ .make_new = mp_obj_exception_make_new, \
+ .attr = mp_obj_exception_attr, \
+ .parent = &mp_type_ ## base_name, \
+};
+
+extern const mp_obj_type_t mp_type_bleio_BluetoothError;
+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;
+
+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, ...);
+
void common_hal_bleio_check_connected(uint16_t conn_handle);
uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c
index 81383c777..8f7382fde 100644
--- a/shared-bindings/audiobusio/I2SOut.c
+++ b/shared-bindings/audiobusio/I2SOut.c
@@ -117,7 +117,7 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a
assert_pin(data_obj, false);
const mcu_pin_obj_t *data = MP_OBJ_TO_PTR(data_obj);
- audiobusio_i2sout_obj_t *self = m_new_obj(audiobusio_i2sout_obj_t);
+ audiobusio_i2sout_obj_t *self = m_new_obj_with_finaliser(audiobusio_i2sout_obj_t);
self->base.type = &audiobusio_i2sout_type;
common_hal_audiobusio_i2sout_construct(self, bit_clock, word_select, data, args[ARG_left_justified].u_bool);
@@ -268,6 +268,7 @@ const mp_obj_property_t audiobusio_i2sout_paused_obj = {
STATIC const mp_rom_map_elem_t audiobusio_i2sout_locals_dict_table[] = {
// Methods
+ { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audiobusio_i2sout_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiobusio_i2sout_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiobusio_i2sout___exit___obj) },
diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c
index 07f8c683f..87d410ea1 100644
--- a/shared-bindings/audiocore/RawSample.c
+++ b/shared-bindings/audiocore/RawSample.c
@@ -180,9 +180,20 @@ STATIC const mp_rom_map_elem_t audioio_rawsample_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(audioio_rawsample_locals_dict, audioio_rawsample_locals_dict_table);
+STATIC const audiosample_p_t audioio_rawsample_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
+ .sample_rate = (audiosample_sample_rate_fun)common_hal_audioio_rawsample_get_sample_rate,
+ .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audioio_rawsample_get_bits_per_sample,
+ .channel_count = (audiosample_channel_count_fun)common_hal_audioio_rawsample_get_channel_count,
+ .reset_buffer = (audiosample_reset_buffer_fun)audioio_rawsample_reset_buffer,
+ .get_buffer = (audiosample_get_buffer_fun)audioio_rawsample_get_buffer,
+ .get_buffer_structure = (audiosample_get_buffer_structure_fun)audioio_rawsample_get_buffer_structure,
+};
+
const mp_obj_type_t audioio_rawsample_type = {
{ &mp_type_type },
.name = MP_QSTR_RawSample,
.make_new = audioio_rawsample_make_new,
.locals_dict = (mp_obj_dict_t*)&audioio_rawsample_locals_dict,
+ .protocol = &audioio_rawsample_proto,
};
diff --git a/shared-bindings/audiocore/RawSample.h b/shared-bindings/audiocore/RawSample.h
index b02778cad..61f61a066 100644
--- a/shared-bindings/audiocore/RawSample.h
+++ b/shared-bindings/audiocore/RawSample.h
@@ -39,6 +39,8 @@ void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t* self,
void common_hal_audioio_rawsample_deinit(audioio_rawsample_obj_t* self);
bool common_hal_audioio_rawsample_deinited(audioio_rawsample_obj_t* self);
uint32_t common_hal_audioio_rawsample_get_sample_rate(audioio_rawsample_obj_t* self);
+uint8_t common_hal_audioio_rawsample_get_bits_per_sample(audioio_rawsample_obj_t* self);
+uint8_t common_hal_audioio_rawsample_get_channel_count(audioio_rawsample_obj_t* self);
void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t* self, uint32_t sample_rate);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H
diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c
index 1b3a94ff3..178d2a139 100644
--- a/shared-bindings/audiocore/WaveFile.c
+++ b/shared-bindings/audiocore/WaveFile.c
@@ -206,9 +206,21 @@ STATIC const mp_rom_map_elem_t audioio_wavefile_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(audioio_wavefile_locals_dict, audioio_wavefile_locals_dict_table);
+STATIC const audiosample_p_t audioio_wavefile_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
+ .sample_rate = (audiosample_sample_rate_fun)common_hal_audioio_wavefile_get_sample_rate,
+ .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audioio_wavefile_get_bits_per_sample,
+ .channel_count = (audiosample_channel_count_fun)common_hal_audioio_wavefile_get_channel_count,
+ .reset_buffer = (audiosample_reset_buffer_fun)audioio_wavefile_reset_buffer,
+ .get_buffer = (audiosample_get_buffer_fun)audioio_wavefile_get_buffer,
+ .get_buffer_structure = (audiosample_get_buffer_structure_fun)audioio_wavefile_get_buffer_structure,
+};
+
+
const mp_obj_type_t audioio_wavefile_type = {
{ &mp_type_type },
.name = MP_QSTR_WaveFile,
.make_new = audioio_wavefile_make_new,
.locals_dict = (mp_obj_dict_t*)&audioio_wavefile_locals_dict,
+ .protocol = &audioio_wavefile_proto,
};
diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c
index ed7b95d9e..03ffb9373 100644
--- a/shared-bindings/audiomixer/Mixer.c
+++ b/shared-bindings/audiomixer/Mixer.c
@@ -291,9 +291,20 @@ STATIC const mp_rom_map_elem_t audiomixer_mixer_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(audiomixer_mixer_locals_dict, audiomixer_mixer_locals_dict_table);
+STATIC const audiosample_p_t audiomixer_mixer_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
+ .sample_rate = (audiosample_sample_rate_fun)common_hal_audiomixer_mixer_get_sample_rate,
+ .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audiomixer_mixer_get_bits_per_sample,
+ .channel_count = (audiosample_channel_count_fun)common_hal_audiomixer_mixer_get_channel_count,
+ .reset_buffer = (audiosample_reset_buffer_fun)audiomixer_mixer_reset_buffer,
+ .get_buffer = (audiosample_get_buffer_fun)audiomixer_mixer_get_buffer,
+ .get_buffer_structure = (audiosample_get_buffer_structure_fun)audiomixer_mixer_get_buffer_structure,
+};
+
const mp_obj_type_t audiomixer_mixer_type = {
{ &mp_type_type },
.name = MP_QSTR_Mixer,
.make_new = audiomixer_mixer_make_new,
.locals_dict = (mp_obj_dict_t*)&audiomixer_mixer_locals_dict,
+ .protocol = &audiomixer_mixer_proto,
};
diff --git a/shared-bindings/audiomixer/Mixer.h b/shared-bindings/audiomixer/Mixer.h
index 9eabbf61d..a99e1bf62 100644
--- a/shared-bindings/audiomixer/Mixer.h
+++ b/shared-bindings/audiomixer/Mixer.h
@@ -47,5 +47,7 @@ bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t* self);
bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self);
uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* self);
+uint8_t common_hal_audiomixer_mixer_get_channel_count(audiomixer_mixer_obj_t* self);
+uint8_t common_hal_audiomixer_mixer_get_bits_per_sample(audiomixer_mixer_obj_t* self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H
diff --git a/shared-bindings/audiomp3/MP3File.c b/shared-bindings/audiomp3/MP3File.c
new file mode 100644
index 000000000..f518bae4b
--- /dev/null
+++ b/shared-bindings/audiomp3/MP3File.c
@@ -0,0 +1,226 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Jeff Epler for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "lib/utils/context_manager_helpers.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/audiomp3/MP3File.h"
+#include "shared-bindings/util.h"
+#include "supervisor/shared/translate.h"
+
+//| .. currentmodule:: audiomp3
+//|
+//| :class:`MP3` -- Load a mp3 file for audio playback
+//| ========================================================
+//|
+//| A .mp3 file prepped for audio playback. Only mono and stereo files are supported. Samples must
+//| be 8 bit unsigned or 16 bit signed. If a buffer is provided, it will be used instead of allocating
+//| an internal buffer.
+//|
+//| .. class:: MP3(file[, buffer])
+//|
+//| Load a .mp3 file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`.
+//|
+//| :param typing.BinaryIO file: Already opened mp3 file
+//| :param bytearray buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two buffers are allocated internally. The specific buffer size required depends on the mp3 file.
+//|
+//|
+//| Playing a mp3 file from flash::
+//|
+//| import board
+//| import audiomp3
+//| import audioio
+//| import digitalio
+//|
+//| # Required for CircuitPlayground Express
+//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
+//| speaker_enable.switch_to_output(value=True)
+//|
+//| data = open("cplay-16bit-16khz-64kbps.mp3", "rb")
+//| mp3 = audiomp3.MP3File(data)
+//| a = audioio.AudioOut(board.A0)
+//|
+//| print("playing")
+//| a.play(mp3)
+//| while a.playing:
+//| pass
+//| print("stopped")
+//|
+STATIC mp_obj_t audiomp3_mp3file_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);
+
+ audiomp3_mp3file_obj_t *self = m_new_obj(audiomp3_mp3file_obj_t);
+ self->base.type = &audiomp3_mp3file_type;
+ if (!MP_OBJ_IS_TYPE(args[0], &mp_type_fileio)) {
+ mp_raise_TypeError(translate("file must be a file opened in byte mode"));
+ }
+ uint8_t *buffer = NULL;
+ size_t buffer_size = 0;
+ if (n_args >= 2) {
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
+ buffer = bufinfo.buf;
+ buffer_size = bufinfo.len;
+ }
+ common_hal_audiomp3_mp3file_construct(self, MP_OBJ_TO_PTR(args[0]),
+ buffer, buffer_size);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: deinit()
+//|
+//| Deinitialises the MP3 and releases all memory resources for reuse.
+//|
+STATIC mp_obj_t audiomp3_mp3file_deinit(mp_obj_t self_in) {
+ audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_audiomp3_mp3file_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_deinit_obj, audiomp3_mp3file_deinit);
+
+STATIC void check_for_deinit(audiomp3_mp3file_obj_t *self) {
+ if (common_hal_audiomp3_mp3file_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
+//|
+//| No-op used by Context Managers.
+//|
+// Provided by context manager helper.
+
+//| .. method:: __exit__()
+//|
+//| Automatically deinitializes the hardware when exiting a context. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+STATIC mp_obj_t audiomp3_mp3file_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ (void)n_args;
+ common_hal_audiomp3_mp3file_deinit(args[0]);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomp3_mp3file___exit___obj, 4, 4, audiomp3_mp3file_obj___exit__);
+
+//| .. attribute:: sample_rate
+//|
+//| 32 bit value that dictates how quickly samples are loaded into the DAC
+//| in Hertz (cycles per second). When the sample is looped, this can change
+//| the pitch output without changing the underlying sample.
+//|
+STATIC mp_obj_t audiomp3_mp3file_obj_get_sample_rate(mp_obj_t self_in) {
+ audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ return MP_OBJ_NEW_SMALL_INT(common_hal_audiomp3_mp3file_get_sample_rate(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_get_sample_rate_obj, audiomp3_mp3file_obj_get_sample_rate);
+
+STATIC mp_obj_t audiomp3_mp3file_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) {
+ audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ common_hal_audiomp3_mp3file_set_sample_rate(self, mp_obj_get_int(sample_rate));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(audiomp3_mp3file_set_sample_rate_obj, audiomp3_mp3file_obj_set_sample_rate);
+
+const mp_obj_property_t audiomp3_mp3file_sample_rate_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&audiomp3_mp3file_get_sample_rate_obj,
+ (mp_obj_t)&audiomp3_mp3file_set_sample_rate_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+//| .. attribute:: bits_per_sample
+//|
+//| Bits per sample. (read only)
+//|
+STATIC mp_obj_t audiomp3_mp3file_obj_get_bits_per_sample(mp_obj_t self_in) {
+ audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ return MP_OBJ_NEW_SMALL_INT(common_hal_audiomp3_mp3file_get_bits_per_sample(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_get_bits_per_sample_obj, audiomp3_mp3file_obj_get_bits_per_sample);
+
+const mp_obj_property_t audiomp3_mp3file_bits_per_sample_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&audiomp3_mp3file_get_bits_per_sample_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+//| .. attribute:: channel_count
+//|
+//| Number of audio channels. (read only)
+//|
+STATIC mp_obj_t audiomp3_mp3file_obj_get_channel_count(mp_obj_t self_in) {
+ audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ return MP_OBJ_NEW_SMALL_INT(common_hal_audiomp3_mp3file_get_channel_count(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_get_channel_count_obj, audiomp3_mp3file_obj_get_channel_count);
+
+const mp_obj_property_t audiomp3_mp3file_channel_count_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&audiomp3_mp3file_get_channel_count_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+
+STATIC const mp_rom_map_elem_t audiomp3_mp3file_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiomp3_mp3file_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiomp3_mp3file___exit___obj) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audiomp3_mp3file_sample_rate_obj) },
+ { MP_ROM_QSTR(MP_QSTR_bits_per_sample), MP_ROM_PTR(&audiomp3_mp3file_bits_per_sample_obj) },
+ { MP_ROM_QSTR(MP_QSTR_channel_count), MP_ROM_PTR(&audiomp3_mp3file_channel_count_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(audiomp3_mp3file_locals_dict, audiomp3_mp3file_locals_dict_table);
+
+STATIC const audiosample_p_t audiomp3_mp3file_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
+ .sample_rate = (audiosample_sample_rate_fun)common_hal_audiomp3_mp3file_get_sample_rate,
+ .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audiomp3_mp3file_get_bits_per_sample,
+ .channel_count = (audiosample_channel_count_fun)common_hal_audiomp3_mp3file_get_channel_count,
+ .reset_buffer = (audiosample_reset_buffer_fun)audiomp3_mp3file_reset_buffer,
+ .get_buffer = (audiosample_get_buffer_fun)audiomp3_mp3file_get_buffer,
+ .get_buffer_structure = (audiosample_get_buffer_structure_fun)audiomp3_mp3file_get_buffer_structure,
+};
+
+const mp_obj_type_t audiomp3_mp3file_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_MP3File,
+ .make_new = audiomp3_mp3file_make_new,
+ .locals_dict = (mp_obj_dict_t*)&audiomp3_mp3file_locals_dict,
+ .protocol = &audiomp3_mp3file_proto,
+};
diff --git a/shared-bindings/audiomp3/MP3File.h b/shared-bindings/audiomp3/MP3File.h
new file mode 100644
index 000000000..adc13ea2c
--- /dev/null
+++ b/shared-bindings/audiomp3/MP3File.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Jeff Epler for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MP3FILE_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MP3FILE_H
+
+#include "py/obj.h"
+#include "extmod/vfs_fat.h"
+
+#include "shared-module/audiomp3/MP3File.h"
+
+extern const mp_obj_type_t audiomp3_mp3file_type;
+
+void common_hal_audiomp3_mp3file_construct(audiomp3_mp3file_obj_t* self,
+ pyb_file_obj_t* file, uint8_t *buffer, size_t buffer_size);
+
+void common_hal_audiomp3_mp3file_deinit(audiomp3_mp3file_obj_t* self);
+bool common_hal_audiomp3_mp3file_deinited(audiomp3_mp3file_obj_t* self);
+uint32_t common_hal_audiomp3_mp3file_get_sample_rate(audiomp3_mp3file_obj_t* self);
+void common_hal_audiomp3_mp3file_set_sample_rate(audiomp3_mp3file_obj_t* self, uint32_t sample_rate);
+uint8_t common_hal_audiomp3_mp3file_get_bits_per_sample(audiomp3_mp3file_obj_t* self);
+uint8_t common_hal_audiomp3_mp3file_get_channel_count(audiomp3_mp3file_obj_t* self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MP3FILE_H
diff --git a/shared-bindings/audiomp3/__init__.c b/shared-bindings/audiomp3/__init__.c
new file mode 100644
index 000000000..06f852ff1
--- /dev/null
+++ b/shared-bindings/audiomp3/__init__.c
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Jeff Epler for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/audiomp3/MP3File.h"
+
+//| :mod:`audiomp3` --- Support for MP3-compressed audio files
+//| ==========================================================
+//|
+//| .. module:: audiomp3
+//| :synopsis: Support for mp3 files
+//|
+//| The `audiomp3` module contains an mp3 decoder
+//|
+//| Libraries
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| MP3File
+//|
+
+STATIC const mp_rom_map_elem_t audiomp3_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiomp3) },
+ { MP_ROM_QSTR(MP_QSTR_MP3File), MP_ROM_PTR(&audiomp3_mp3file_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(audiomp3_module_globals, audiomp3_module_globals_table);
+
+const mp_obj_module_t audiomp3_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&audiomp3_module_globals,
+};
diff --git a/shared-bindings/audiomp3/__init__.h b/shared-bindings/audiomp3/__init__.h
new file mode 100644
index 000000000..9026af636
--- /dev/null
+++ b/shared-bindings/audiomp3/__init__.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Jeff Epler for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMP3___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMP3___INIT___H
+
+#include "py/obj.h"
+
+// Nothing now.
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMP3___INIT___H
diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c
index 47e2d64bc..3dda59fb8 100644
--- a/shared-bindings/board/__init__.c
+++ b/shared-bindings/board/__init__.c
@@ -93,6 +93,12 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);
//|
//| Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton.
//|
+//| The object created uses the default parameter values for `busio.UART`. If you need to set
+//| parameters that are not changeable after creation, such as ``receiver_buffer_size``,
+//| do not use `board.UART()`; instead create a `busio.UART` object explicitly with the
+//| desired parameters.
+//|
+//|
#if BOARD_UART
mp_obj_t board_uart(void) {
mp_obj_t singleton = common_hal_board_get_uart();
diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c
index c7eef8c43..1fc81e78e 100644
--- a/shared-bindings/busio/UART.c
+++ b/shared-bindings/busio/UART.c
@@ -57,7 +57,7 @@
//| :param int bits: the number of bits per byte, 7, 8 or 9.
//| :param Parity parity: the parity used for error checking.
//| :param int stop: the number of stop bits, 1 or 2.
-//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters. Raises ``ValueError`` if timeout >100 seconds.
+//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters when reading. Raises ``ValueError`` if timeout >100 seconds.
//| :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.)
//|
//| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds.
@@ -69,6 +69,12 @@ 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 void validate_timeout(mp_float_t timeout) {
+ if (timeout < (mp_float_t) 0.0f || timeout > (mp_float_t) 100.0f) {
+ mp_raise_ValueError(translate("timeout must be 0.0-100.0 seconds"));
+ }
+}
+
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
@@ -116,9 +122,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co
}
mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
- if (timeout > (mp_float_t)100.0) {
- mp_raise_ValueError(translate("timeout >100 (units are now seconds, not msecs)"));
- }
+ validate_timeout(timeout);
common_hal_busio_uart_construct(self, tx, rx,
args[ARG_baudrate].u_int, bits, parity, stop, timeout,
@@ -286,6 +290,35 @@ const mp_obj_property_t busio_uart_in_waiting_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+//| .. attribute:: timeout
+//|
+//| The current timeout, in seconds (float).
+//|
+STATIC mp_obj_t busio_uart_obj_get_timeout(mp_obj_t self_in) {
+ busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ return mp_obj_new_float(common_hal_busio_uart_get_timeout(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_timeout_obj, busio_uart_obj_get_timeout);
+
+STATIC mp_obj_t busio_uart_obj_set_timeout(mp_obj_t self_in, mp_obj_t timeout) {
+ busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ mp_float_t timeout_float = mp_obj_get_float(timeout);
+ validate_timeout(timeout_float);
+ common_hal_busio_uart_set_timeout(self, timeout_float);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(busio_uart_set_timeout_obj, busio_uart_obj_set_timeout);
+
+
+const mp_obj_property_t busio_uart_timeout_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&busio_uart_get_timeout_obj,
+ (mp_obj_t)&busio_uart_set_timeout_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
//| .. method:: reset_input_buffer()
//|
//| Discard any unread characters in the input buffer.
@@ -355,8 +388,9 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&busio_uart_reset_input_buffer_obj) },
// Properties
- { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) },
- { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) },
+ { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) },
+ { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) },
+ { MP_ROM_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&busio_uart_timeout_obj) },
// Nested Enum-like Classes.
{ MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) },
@@ -364,6 +398,7 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(busio_uart_locals_dict, busio_uart_locals_dict_table);
STATIC const mp_stream_p_t uart_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = busio_uart_read,
.write = busio_uart_write,
.ioctl = busio_uart_ioctl,
diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h
index 776a996be..cfd2c800c 100644
--- a/shared-bindings/busio/UART.h
+++ b/shared-bindings/busio/UART.h
@@ -57,7 +57,8 @@ extern size_t common_hal_busio_uart_write(busio_uart_obj_t *self,
extern uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self);
extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate);
-
+extern mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self);
+extern void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout);
extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self);
extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self);
diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c
index bf00ef855..f7e2bf693 100644
--- a/shared-bindings/displayio/OnDiskBitmap.c
+++ b/shared-bindings/displayio/OnDiskBitmap.c
@@ -59,7 +59,7 @@
//|
//| with open("/sample.bmp", "rb") as f:
//| odb = displayio.OnDiskBitmap(f)
-//| face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter(), position=(0,0))
+//| face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter())
//| splash.append(face)
//| # Wait for the image to load.
//| board.DISPLAY.wait_for_frame()
diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h
index ed831b258..2d15dd5c5 100644
--- a/shared-bindings/microcontroller/Pin.h
+++ b/shared-bindings/microcontroller/Pin.h
@@ -37,5 +37,7 @@ void assert_pin(mp_obj_t obj, bool none_ok);
void assert_pin_free(const mcu_pin_obj_t* pin);
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin);
+void common_hal_never_reset_pin(const mcu_pin_obj_t* pin);
+void common_hal_reset_pin(const mcu_pin_obj_t* pin);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H
diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c
index 6d04a9893..2d6c16e90 100644
--- a/shared-bindings/socket/__init__.c
+++ b/shared-bindings/socket/__init__.c
@@ -500,6 +500,7 @@ mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *
}
STATIC const mp_stream_p_t socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.ioctl = socket_ioctl,
.is_text = false,
};
diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c
index cdde672d3..9c01fba20 100644
--- a/shared-bindings/terminalio/Terminal.c
+++ b/shared-bindings/terminalio/Terminal.c
@@ -112,6 +112,7 @@ STATIC const mp_rom_map_elem_t terminalio_terminal_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(terminalio_terminal_locals_dict, terminalio_terminal_locals_dict_table);
STATIC const mp_stream_p_t terminalio_terminal_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = NULL,
.write = terminalio_terminal_write,
.ioctl = terminalio_terminal_ioctl,
diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c
index 2654de09a..b3e4604b5 100644
--- a/shared-bindings/time/__init__.c
+++ b/shared-bindings/time/__init__.c
@@ -85,9 +85,9 @@ 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, 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"));
+ return namedtuple_make_new(type, n_args, args, kw_args);
}
- if (!MP_OBJ_IS_TYPE(args[0], &mp_type_tuple) || ((mp_obj_tuple_t*) MP_OBJ_TO_PTR(args[0]))->len != 9) {
+ if (mp_obj_get_type(args[0])->getiter != mp_obj_tuple_getiter || ((mp_obj_tuple_t*) MP_OBJ_TO_PTR(args[0]))->len != 9) {
mp_raise_TypeError(translate("time.struct_time() takes a 9-sequence"));
}
diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c
index 356a81d52..e2df56e95 100644
--- a/shared-bindings/usb_midi/PortIn.c
+++ b/shared-bindings/usb_midi/PortIn.c
@@ -107,6 +107,7 @@ STATIC const mp_rom_map_elem_t usb_midi_portin_locals_dict_table[] = {
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 = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = usb_midi_portin_read,
.write = NULL,
.ioctl = usb_midi_portin_ioctl,
diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c
index 6f4ce6716..e3eddfaf5 100644
--- a/shared-bindings/usb_midi/PortOut.c
+++ b/shared-bindings/usb_midi/PortOut.c
@@ -89,6 +89,7 @@ STATIC const mp_rom_map_elem_t usb_midi_portout_locals_dict_table[] = {
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 = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = NULL,
.write = usb_midi_portout_write,
.ioctl = usb_midi_portout_ioctl,