Recent versions of gcc perform optimisations which can lead to the
following code from the MP_NLR_JUMP_HEAD macro being omitted:
top->ret_val = val; \
MP_NLR_RESTORE_PYSTACK(top); \
*_top_ptr = top->prev; \
This is noticeable (at least) in the unix coverage on x86-64 built with gcc
9.1.0. This is because the nlr_jump function is marked as no-return, so
gcc deduces that the above code has no effect.
Adding MP_UNREACHABLE tells the compiler that the asm code may branch
elsewhere, and so it cannot optimise away the code.
There were several problems with the way this worked -- the read_count
approach was too complicated and I made a mistake "simplifying" it from
WaveFile. And when the right channel was returned, it was off by 1 byte,
making it into static.
Instead, directly track which is the "other" channel that has data
available, and by using the right data type make the "+ channel"
arithmetic give the right result.
This requires a double cast (int16_t*)(void*) due to an alignment warning;
the alignment is now ensured manually, but the compiler doesn't make the
necessary inference that the low address bit must be clear.
When a playing mp3 is deinitted, it's possible to reach get_buffer,
but all the internal pointers are NULL. This would lead to a hard fault.
Avoid it by returning GET_BUFFER_ERROR instead.
It's extremely dubious that we have these handles that we think
are to GC'd memory at a time when the gc pool may not be initialized.
Hopefully, they WERE valid GC memory and are undisturbed by the teardown
of the interpreter that can lead to this state.
In this case, don't try to m_free them, the memory will become free when
the GC heap is reinitialized.
Closes: #2338 (together with previous commit)
.. a requirement that oofatfs needs to be taught to respect.
This problem can be demonstrated with the following snippet, except
that the related file ("test.bin") must also be contiguous on the
filesystem. You can ensure this by reformatting your device's filesystem
before testing, then copying any single file bigger than 4kB to test.bin.
f = open("test.bin", "rb")
f.seek(2048)
b = bytearray(2048)
v = memoryview(b)
f.readinto(v[909:])
Closes: #2332
The "spacing" of "buffer structure" is confusing, use the "channel count"
instead.
Testing performed on nrf52840 feather:
Play stereo and mono, 8- and 16-bit, 8kHz RawSamples representing 333.33Hz
square waves.
Use both mono and stereo PWMAudioOut instances.
Scope the RC-filtered signal and use the scope's frequency
measurement function, verify the frequency is 333 or 334Hz in all tested
cases.
In the "stereo output" cases, verify both the L and R channels. Verify
the output amplitude is the same in both channels.
In the "stereo output" cases, run a second test where the L channel's
amplitude is attenuated 50%. Verify the output amplitude is correct
in each channel.
This adapts the "inline assembler" code from the UF2 bootloader, which
in turn is said to be adapted from the arduino neopixel library.
This requires the cache remain ON when using M0, and be turned OFF on M4
(determined by trial and error)
Testing performed on a Metro M4:
* measured timings using o'scope and found all values within
datasheet tolerance.
* Drove a string of 96 neopixels without visible glitches
* on-board neopixel worked
Testing performed on a Circuit Playground Express (M0):
* Color wheel code works on built-in neopixels
* Color wheel code works on 96 neopixel strip
As a bonus, this may have freed up a bit of flash on M0 targets. (2988 ->
3068 bytes free on Trinket M0)
Closes: #2297