Probably due to memory/stack overrun, some more involved web API
requests cause the system to hang if performed during playback. For now,
block these requests during playback.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
If a timer is scheduled with the timer manager while it is already
scheduled, the new exipry time should override the prev. expiry time
instead of adding a second instance of the same timer function.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
- Remove Pin to button mapping from hwconfig, replace with a simple list
of Pins to which buttons are attached
- Add BUTTON_MAP to config.json which maps indices in the HW button list
to button names
- Update utils.Buttons to use the button map to connect the correct pins
to the matching key codes
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
Add all python code run on the device to the manifest.py to freeze
it. This has two benefits:
- It precompiles the bytecode, so it is smaller and faster
- All code (C and python) is now in the firmware image, leaving the
littlefs filesystem on the flash free for user settings.
This requires changing the way the hardware variants are handled. There
is now only one _filesystem_ image, but instead there are different
_firmware_ images for each variant.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
Allow the PlayerApp to turn off the device if it is idle for longer then
the timeout. The timeout is currently hardcoded to 1 minute, this will be
made configurable in the future.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
Move the LED control to the utils.LedManager class. For the first
implementation, support two LED patterns 'idle' and 'playing'.
Extend the PlayerApp to set the LED pattern based on playback state.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
If the tagmode setting is 'tagremains' (the default): Play as long as the
tag is on the reader, with a 5 second timeout (i.e. playback stops when
tag is gone for more than 5 seconds).
If the tagmode setting is 'tagstartstop': Playback starts when a tag is
seen. Presenting a different tag causes the playback to stop and
playback for the new tag to start. Re-presenting the same tag used to
start with a no-tag-time of 5 seconds or more in between stops playback.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
Split the tag handling in PlayerApp into two parts: The low level
handling of changed/removed tags from the Nfc reader, including the
timeout processing is moved into the nested TagStateMachine class. The
main PlayerApp has two new (internal) callbacks "onNewTag" and
"onTagRemoved" which are called when a new tag is presented or a tag was
actually removed. This will hopefully make the implementation of #28
"Configurable Tag Handling" cleaner.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
As we don't have an API to upload files and create playlists yet, we
used the convention "tag uid as directory name" to allow testing
playback. With the introduction of the database in #39 "Add playlist db"
a builddb() function to initialize the database from the tag directories
was added, but it is not automatically called. To make the developer
experience more ergonomical, add a check for that automatically runs
builddb() when no database exists.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
To simplify the playlist handling, enforce that the indices are always
formatted to the same length (5, which allows for 100000 entries, that
should be enough).
Then make the position stored in the Playlist object be a simple integer
instead of a database key. This simplifies the code, and will make
implementing shuffle much easier.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
Add documentation of playlist database schema in DEVELOP.md.
Add settings for persist and shuffle to BTreeDB. Implement the different
persist modes. Shuffle will be implemented in a followup commit.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
Apply the same pattern as in 6f155ebb55 ("audiocore: Fix small race
window in get_fifo_read_value_blocking") and 2a4033d3ca ("rp2_sd: Fix
race window in sd_spi_wait_complete") to the wait for interrupt in
i2s_stop too.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
Similar to the fix in 6f155ebb55 ("audiocore: Fix small race window in
get_fifo_read_value_blocking"), a race and deadlock is possible when
calling __wfi with interrupts enabled. Fix it in sd_spi_wait_complete by
copying the fix from the above commit.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
Add a read test to the SD tests in standalone_mp3, and also apply the
drive strength setup and higher clockrate from board_Rev1.py.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
The PIO has an internal synchronizer on each GPIO input which adds two
cycles of delay. This prevents metastabilities in the PIO logic (see
RP2040 datasheet p. 374f). For high speed synchronous interfaces such as
SPI this needs to be disabled to reduce input delay.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
The code snippet in hwconfig to adjust the drive strength was incorrect:
It was adjusting the wrong pins. This was probably not updated during
some pin shuffling in the breadboard phase.
Fix this by adjusting the correct pins. Experimentation shows that both
setting the slew rate to fast or setting the drive strength to 8 mA
(default: slow and 4 mA) is sufficient to make SD SPI work at 25 MHz on
the Rev1 PCB. For now, the combination 8 mA and slow is chosen (slow
slew rate should result in less high frequency EMI).
Also make the SD clock rate adjustable in hwconfig, and set it to 25 MHz
for Rev1 and 15 MHz for the breadboard setup.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
In order to turn the Tonberry device on more reliably even if the power
button is only pressed for a short time, move the setting of POWER_EN
pin to high from the python board_init to the MICROPY_BOARD_STARTUP
macro so that is is started in the C startup code run before the
micropython interpreter is initialized.
Measured time from power on to POWER_EN time was 600-800 ms with the
python board_init, vs. 155 ms for the MICROPY_BOARD_STARTUP.
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>