Make no sense to say this is experimental and will change in 4.0.0 when we are already above 4.0.0.
This should be removed, or updated to say it will not be in x.0.0
This enables jeplayer to allocate just one MP3File at startup, rather
than have to make repeated large allocations while the application is
running.
The buffers have to be allocated their theoretical maximum, but that
doesn't matter much as all the real-life MP3 files I checked needed
that much allocation anyway.
Protocols are nice, but there is no way for C code to verify whether
a type's "protocol" structure actually implements some particular
protocol. As a result, you can pass an object that implements the
"vfs" protocol to one that expects the "stream" protocol, and the
opposite of awesomeness ensues.
This patch adds an OPTIONAL (but enabled by default) protocol identifier
as the first member of any protocol structure. This identifier is
simply a unique QSTR chosen by the protocol designer and used by each
protocol implementer. When checking for protocol support, instead of
just checking whether the object's type has a non-NULL protocol field,
use `mp_proto_get` which implements the protocol check when possible.
The existing protocols are now named:
protocol_framebuf
protocol_i2c
protocol_pin
protocol_stream
protocol_spi
protocol_vfs
(most of these are unused in CP and are just inherited from MP; vfs and
stream are definitely used though)
I did not find any crashing examples, but here's one to give a flavor of what
is improved, using `micropython_coverage`. Before the change,
the vfs "ioctl" protocol is invoked, and the result is not intelligible
as json (but it could have resulted in a hard fault, potentially):
>>> import uos, ujson
>>> u = uos.VfsPosix('/tmp')
>>> ujson.load(u)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: syntax error in JSON
After the change, the vfs object is correctly detected as not supporting
the stream protocol:
>>> ujson.load(p)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: stream operation not supported
Whenever there is more than one argument, delegate the operation to
namedtuple_make_new. This allows other circuitpython-compatible
idioms, like with keywords
time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=0,
tm_min=0, tm_sec=14, tm_wday=5, tm_yday=5, tm_isdst=-1)
with 9 positional arguments, etc.
The only vaguely plausible CPython behavior still not permitted in
CircuitPython that I found is constructing a timetuple from a length-9
list, a la
time.struct_time(list(time.localtime())
Even better, by getting rid of an error message, the build shrinks a
tiny bit.
This doesn't cover ALL the cases that CPython permits for construction
of a struct_time, but it at least makes constructing from any namedtuple
work.
Closes: #2326
(or deinitialized, for those of us on this side of the pond)
Otherwise, a sequence like
```
audio = audiobusio.I2SOut(bit_clock=board.D6, word_select=board.D9, data=board.D10)
sine_wave_sample = audiocore.RawSample(sine_wave)
audio.play(sine_wave_sample, loop=True)
del audio
```
could free the memory associated with audio without stopping the
related background task. Later, when fresh objects are allocated within
a now-freed memory region, they can get overwritten in the background
task, leading to a hard crash.
This presumably can affect multiple I2S implementations, but it was
reported against the nRF one.
This PR refines the _bleio API. It was originally motivated by
the addition of a new CircuitPython service that enables reading
and modifying files on the device. Moving the BLE lifecycle outside
of the VM motivated a number of changes to remove heap allocations
in some APIs.
It also motivated unifying connection initiation to the Adapter class
rather than the Central and Peripheral classes which have been removed.
Adapter now handles the GAP portion of BLE including advertising, which
has moved but is largely unchanged, and scanning, which has been enhanced
to return an iterator of filtered results.
Once a connection is created (either by us (aka Central) or a remote
device (aka Peripheral)) it is represented by a new Connection class.
This class knows the current connection state and can discover and
instantiate remote Services along with their Characteristics and
Descriptors.
Relates to #586
Also, move the rendering setup code to shared-module from
shared-bindings.
In CP 5.0, displayio_display_core_set_region_to_update now starts
its own transaction, so it has to be moved outside of the transaction
started by the render call.
writeto_then_readfrom has been added to do a write -> no stop ->
repeated start -> read sequence. This is done to match the
capabilities of Blinka on Linux.
Code that uses stop=False will not work correctly on Blinka.
To fix, if stop=False then use writeto_then_readfrom otherwise use
writeto then readfrom_into.
First step in #2082
It turns out `mp_obj_int_get_checked` is not appropriate to call when
the argument is not of int or long type--the "checked" refers to guarding
against overflow/underflow, not type checking.
For compatibility with CPython, handle float arguments.
Closes: #2069
Testing performed: That the shipped .mpy files on a PyPortal (CP 4.x)
still work (play audio) with this branch, instead of erroring because
`WaveFile` can't be found in `audioio`.
Flash usage grew by 28 bytes. (I expected 24, there must be some other
effect on size/alignment that I didn't predict)