Once plugged in, the Sonata board should enumerate as a USB mass storage device. Bitstreams
and Sonata firmware can both be programmed by copying their respective files to the mass
storage device. Bitstreams and firmware must be in UF2 format with a maximum block size
of 256 bytes and device IDs of 0x6ce29e6b
and 0x6ce29e60
, respectively. Only the data
portion of the UF2 block is written to flash.
Note that the FPGA is currently erased during both firmware and bitstream programming, then reprogrammed afterwards.
Bitstream and firmware both have 3 flash slots, which can be selected via the 3 position Bitstream select switch by the USB port on the device. This controls both where bitstream/firmware are written to when programming, as well as where bitstreams are loaded from on device boot.
Important things such as firmware version, which slots have bitstreams/firmware, etc. is logged in LOG.TXT. Various options, such as programming speed and whether or not to write bitstreams to flash can be modified in OPTIONS.TXT.
The Sonata's firmware can be erased by holding down SW9 while plugging in the USB, after which the board should enumerate as a different USB mass storage device. New firmware is avilable in UF2 format and can be programmed by copying the UF2 file into the drive, similar to how bitstream and firmware programming works on the Sonata board.
TLDR; to setup pico-sdk and build, the quickest way is currently:
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
git clone https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk
git submodule update --init
Grab the installer from https://github.com/raspberrypi/pico-setup-windows. All the paths
should be setup, so you can omit the PICO_SDK_PATH
part of the cmake command. Note that
Windows uses ninja instead of make by default.
mkdir build
cd build
PICO_SDK_PATH=/path-to/pico-sdk cmake ..
make # or ninja if on Windows
Different logging levels are available and can be selected with -DDEBUG_LEVEL=N
where N
is
between 1 and 5. The levels available are:
- Critical
- Error
- Warning
- Info
- Debug
with Info (4) being the default. Logs are written to LOG.txt
.
Follow the Building
instructions above, but add -DCMAKE_BUILD_TYPE=Debug
to the cmake
command
Start OpenOCD by running:
openocd -f DEBUG_CONF.cfg -f target/rp2040.cfg
Start GDB from the build
directory:
cd build
arm-none-eabi-gdb usb_msc/usb_msc.elf -ex "target extended-remote localhost:3333" -ex "load" -ex "monitor reset init"
Some basic tests can be run by creating testing firmware with cmake: -DTESTING_BUILD=ON
,
then running either tests/test_linux.py
or tests/test_windows.py
, depending on your platform.
Tests should be run after a fresh boot and nothing should be uploaded to the Sonata before running the tests.
Windows is pretty lazy with reading new information from disk. This doesn't cause any issues
with programming, but ERROR.txt
won't be updated until you "eject" the disk by right clicking
the drive in Explorer and clicking eject
.
Writes to Linux drives are nonblocking by default, meaning copying things to disk returns before the copy is done.
Early PCB revisions have a few mistakes that affect running/debugging:
- On revisions before v0.3, DIN isn't routed to the RP2040, so FPGA programming is unavailable unless a flywire is soldered onto the PCB: newaetech/sonata-pcb#4
- On revisions before v0.3, a nonstandard SPI flash is used for the RP2040. On these revisions,
you must pass
PICO_DEFAULT_BOOT_STAGE2=boot2_generic_03h
tocmake
and debuggers are unable to program SPI flash.