This was not added as part of the initial v7.0.1 patchset because
.hex files are in this project's .gitignore, and so git ignored it.
Signed-off-by: Sean Cross <sean@xobs.io>
Previously, we were using v6.1.1 which worked, but was unsupported.
v7.0.1 is the first version of s140 that supports the nRF52833.
Signed-off-by: Sean Cross <sean@xobs.io>
Allow for setting various softradio memory settings as part of a
board in order to support lower-memory configurations. If a
parameter is unspecified then the previously-defined value is used.
Signed-off-by: Sean Cross <sean@xobs.io>
Conditionally set variables such as the softdevice RAM size, bootloader
size, and the spi m3 buffer size. This allows ports to adjust these
values to suit their needs.
Signed-off-by: Sean Cross <sean@xobs.io>
The BLE Config area needs to be subtracted from the size of the firmware.
THis is because the firmware is counted by walking backwards from the end
of memory, and the BLE config area is placed lower in memory than the
firmware. Subtracting the BLE config size ensures the internal flash
filesystem doesn't try to use the firmware as storage.
Signed-off-by: Sean Cross <sean@xobs.io>
This adds preliminary support for the nRF52833, which is a variant of
the nRF52840 with half the RAM, half the flash, and fewer peripherals.
Signed-off-by: Sean Cross <sean@xobs.io>
Ports can set CIRCUITPY_RGBMATRIX and CIRCUITPY_FRAMEBUFFERIO to 0
in their .mk file in order to prevent these from being built. This
is necessary for resource-constrained devices.
Signed-off-by: Sean Cross <sean@xobs.io>
This gets all the purely internal references. Some uses of
protomatter/Protomatter/PROTOMATTER remain, as they are references
to symbols in the Protomatter C library itself.
I originally believed that there would be a wrapper library around it,
like with _pixelbuf; but this proves not to be the case, as there's
too little for the library to do.
The backlight enable is active low on our board so the driver doesn't like it.
Toggling to GPIO manually for now.
As fixed the improper SPI bus pins definitions and it works!
Signed-off-by: Michael Welling <mwelling@ieee.org>
PacketBuffer facilitates packet oriented BLE protocols such as BLE
MIDI and the Apple Media Service.
This also adds PHY, MTU and connection event extension negotiation
to speed up data transfer when possible.
disable only turns off ENABLE but doesn't set the init tracking that
nrfx uses. uninit hangs if ENABLE is off and is called because it
waits forever for TX to stop.
.. 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.
The sample width register was never set, so all samples were played
as though they were 16 bit.
After this change, 8-bit samples no longer produce audio on the MAX 98357A
BOB, because only 16-, 24-, and 32-bit samples are supported by the
hardware. This will be addressed by a future change to pad samples to
16 bits; see #2323 and the 98357A datasheet page 6.
The meaning of the "single channel" parameter is not well-documented,
but in fact it seems that "true" must be passed or else the returned
channel_count is always 1. This caused stereo samples to be played
incorrectly.
This caused two problems when playing unsigned samples:
* When an even number of samples were present, it "worked" but only
every other sample was copied into the output, changing the waveform
* When an odd number of samples were present, the copy continued beyond
the end of the buffers and caused a hard fault
If we put no samples into the buffer, then there is no last
sample to fill out hold_value with. (and, in fact, the expression such
as *(uint32_t*)(buffer-4) is outside an allocated region)
Detect this condition, and leave the prior value in place.
This improves clicks heard when pausing and resuming a waveform.
This code is shared by most parts, except where not all the #ifdefs
inside the tick function were present in all ports. This mostly would
have broken gamepad tick support on non-samd ports.
The "ms32" and "ms64" variants of the tick functions are introduced
because there is no 64-bit atomic read. Disabling interrupts avoids
a low probability bug where milliseconds could be off by ~49.5 days
once every ~49.5 days (2^32 ms).
Avoiding disabling interrupts when only the low 32 bits are needed is a minor
optimization.
Testing performed: on metro m4 express, USB still works and
time.monotonic_ns() still counts up
This allows the board to disable the onboard speaker until explicitly
enabled in user code.
Testing performed on a CPB:
* Touching the AUDIO pin with a fingertip no longer generates noise/buzz
* Generating a waveform with `simpleio.tone` produces no sound by default
* When the board.SPEAKER_ENABLE is configured as a digital output and
set True, `simpleio.tone` does produce sound
Note that while guides should include information about SPEAKER_ENABLE, it's
possible that some users who omitted it could view this as a breaking change.
They can fix it by simply adding code similar to
speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
speaker_enable.direction = digitalio.Direction.OUTPUT
speaker_enable.value = True
before using the internal speaker.
Closes: #2258
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
.. otherwise, when an AudioPWMOut object was deinitted without being
explicitly stop()ped, it would use up a slot in active_audio[]; the
5th iteration would create a non-working audio object which would just
buzz instead of playing the right thing.
Closes: #2203
@ladyada says:
"having this be adjustable (reference) would be ideal cause you can get
absolute voltages but for now, VCC/4 + 4x matches every other chip :)"
... and indeed doing it this way happens to give a much more steady
reading when using a VCC-referenced resistance, and so many of the simple
things you'd wire up are actually VCC-referenced anyway.
.. based on some tasks I found that caused stuttering:
# Test SD and printing
while True: os.listdir('.')
# Test bulk I/O
while True: len(open('somefile.wav', 'rb').read())
Each of these tasks *WAS* worse and I am improving them in a separate
PR by adding RUN_BACKGROUND_TASKS to them.
This enables the highest level of debug symbols, and all optimizations
except lto that do NOT interfere with debugging, in the view of the gcc
maintainers.
Testing performed: I used a Particle Xenon with a HDA1334 I2S DAC.
I played a variety of mono 16-bit samples at 11025 and 22050Hz nominal
bit rates. With this setup, all the 11025Hz samples sound good.
I tested play, pause, and loop functionality.
During some runs with 22050Hz samples, there were glitches. However,
these may have only occurred during runs where I had set breakpoints
and watchpoints in gdb.
I also tested with a MAX98357A I2S amplifier. On this device, everything
sounded "scratchy". I was powering it from 5V and the 5V rail seemed
steady, so I don't have an explanation for this. However, I haven't
tried it with a SAMD board.
So far, this supports only 16kHz and 16-bit samples with a fixed gain.
This is enough to support the basic functionality of e.g., sensing
ambient audio levels.
The original formulation was because I saw the need to avoid a transition
from playing to stopped exactly when a resume was taking place. However,
@tannewt was concerned about this pause causing trouble, because it could
be relatively lengthy (several ms even in a typical case).
After reflection, I've convinced myself that updating the registers
in this order in resume avoids a window where a "stopped" event can
be missed as long as the shortcut is updated first.
Testing re-performed: pause/resume testing of looped RawSample and
WaveFile audio sources.
Testing performed: installed freshly built .uf2 on a Particle Xenon.
Checked that circuitpython still starts.
Checked that the size of all .uf2 files for nrf builds are plausible.
Aside from memory savings, the performance of Python code (pystone)
increased by about +14%.
However, this adds about 12-16 seconds to each nrf build.
Timings & Sizes (build system: i5-3320M, -j5 parallelism on 4 threads):
Before:
$ make -j5 BOARD=particle_xenon
765004 bytes free in flash out of 1048576 bytes ( 1024.0 kb ).
232076 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ).
68.54user 11.83system 0:34.34elapsed 234%CPU
pystones before: 570
After:
$ make -j5 BOARD=particle_xenon
804284 bytes free in flash out of 1048576 bytes ( 1024.0 kb ).
232072 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ).
71.06user 11.77system 0:46.91elapsed 176%CPU
pystones after: 650
Timings on travis:
Before:
Build feather_nrf52840_express for pl took 55.79s and succeeded
Build feather_nrf52840_express for zh_Latn_pinyin took 3.18s and succeeded
After:
Build feather_nrf52840_express for pl took 62.72s and succeeded
Build feather_nrf52840_express for zh_Latn_pinyin took 19.10s
Closes: #1396
This implements AudioOut, with known caveats:
* pause/resume are not yet implemented (this is just a bug)
* at best, the sample fidelity is 8 bits (this is a hardware limitation)
Testing performed:
My test system is a Particle Xenon with a PAM8302 op-amp
https://www.adafruit.com/product/2130 and 8-ohm speaker. There's no
analog filtering between the Xenon's PWM pin and the "A+" input of
the amplifier; the "A-" pin is disconnected. It is powered from
VUSB.
I used pin D4, which is *NOT* listed as a low-speed-only pin, but
the code does NOT switch the pin to high drive. This is related to
an open issue for general inability to set drive level for pins
being used by a "special function" on nrf:
https://github.com/adafruit/circuitpython/issues/1270
Nothing about the code I've written should limit the usable pins.
All samples I played were 16-bit, generally monophonic at 11025Hz
and 22050Hz from the Debian LibreOffice package.