The hard work of updating the Badge from V1 to V2 was largely done as a capstone project at the University of British Columbia. The team comprised of:
The design for this manual is based off The Proportional Web by Oskar Wickström
Congratulations, you’re the owner of a brand new SYCL Badge V2. With any luck, you’re currently at Tables Day, hanging out with your friends during Software You Can Love 2026. If you don’t have a badge there is a simulator that runs in the browser.
The Badge is a constrained, programmable device for you to write, share, and run programs called “carts”. The custom OS allows for multiple carts to be installed, executing only one at a time. There exist several means for carts to interact with the outside world, including but not limited to: buttons, a nav stick, an LCD screen, and five RGB LEDs. Carts can be loaded from your personal computer onto the Badge through USB.
This second version of the Badge largely came about due to part sourcing issues. Modernizing components fixed this issue, reduced costs, and improved performance. The most notable upgrade was changing the MCU to an RP2354. It has a hardware USB bootloader, which allows users to recover from a bricked state if they decide to author their own OS. The hardware upgrades include:
| Feature | V1 | V2 |
|---|---|---|
| MCU | ATSAMD51J19 | RP2354B |
| CPU Count | 1 | 2 |
| CPU Frequency | 120 MHz | 155 MHz |
| CPU Core | Cortex M3 | Cortex M33/RISC-V |
| Flash | 512 KB | 4 MB |
| RAM | 192 KB | 520 KB |
| Battery | 3.7V LiPo | 3x AAAs |
* RISC-V cores are not utilized in the Badge V2 at the time of writing.
Carts are currently written in Zig, but more languages will be supported in the future. The Zig version required is currently 0.15.2. Clone the repository with:
git clone https://github.com/ZigEmbeddedGroup/sycl-badge
Then from within the project you may build all the examples (and more) with:
zig build
This will take a few moments. It builds all the tools in MicroZig needed to generate code, as well as the Badge OS.
Once the build is complete you will find a mix of file extensions:
elf: The original container file, not usually useful unless debugging, developing the kernel, or inspecting generated output of the compiler.uf2: The file that will be used to load carts onto the Badge. These are transferred over USB using a Mass Storage Class Interface. This will typically be presented to the user as a mounted drive.wasm: The same application, but cross-compiled for the browser-based simulator.We will be using the uf2 file to upload our cart here. when you plug in and turn the power on the badge, most PC operating systems will automatically mount the drive. Our drive will be named SYCL BADGE V2. To load a particualar cart, copy or move the file to the mounted drive. You will see a progess indicator on the screen until it is completely transfered. It may be run at this time.
If you are familiar with the Zig build system, and wish to publish your cart as a standalone code repository, then using sycl-badge as a dependency is suggested. If you wish to contribute your application, are unfamiliar with the Zig build system, or want to hack on the Badge OS, then it’s suggested to fork this repository.
For SYCL 2026, the Badge will come with the OS installed. For beta testers or those wishing to hack on the kernel, there are two methods to flash the Badge with a new kernel. The first is to use the pico debugger that came with the badge. See Using the Pico Debugger.
The second is to use a similar process as loading a cart, but instead of the OS loading a cart to external flash, you’ll be using the RP2350’s hardware UF2 bootloader to install the kernel. Once you have built from source you need to:
RESET and BOOT_SEL buttons at the same time.RESET button.BOOT_SELL button.RASPI mounted drive shows up. Linux may require manully mounting it.zig-out/firmware/sycl-os-kernel.uf2 to the newly mounted drive.This will cause the drive to disappear and the Badge will reset, running your new OS firmware build.
OpenOCD is not required for regular programming of the Badge. It is, however, required if one wishes to use the debug probe. At the time of writing, RP2350 support has not been upstreamed to OpenOCD version available on Debian, so we include instructions to build it from source.
git clone https://github.com/raspberrypi/openocd
This section will be filled in later with detailed instructions.
From within the openocd directory:
sudo src/openocd -s tcl -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000"
Make sure you have gdb-multiarch or arm-none-eabi-gdb installed, you need support for ARM:
arm-none-eabi-gdb ./zig-out/firmware/sycl-os
The following command tells GDB to speak with OpenOCD on localhost port 3333 using the GDB remote serial protocol.
target extended-remote :3333
You should see some logs from OpenOCD, and you can flash the Badge with the load command. From there you have a regular GDB debug session set up and you can begin poking around the program.
Do not use this method to flash carts, it does not currently work.
RTT provides a method of IO between your Badge’s microcontroller with your PC over the pico debug probe. It can be used to set up multiplexed streams in either direction. It makes use of static buffers, and can be configured to skip, trim, or block when there is not enough room in those buffers.
RTT does not require the CPU to halt in order to transfer data. The debug access port is able to issue it’s own bus transactions separate from the CPU, though this does mean the two may contend for memory bandwidth. The Badge is currently set up to use RTT for logging and sending profile data to Tracy.
When working on the kernel and using RTT for logging, adding this to your .gdbinit file is useful for iterating. It connects to OpenOCD on the default port, runs the kernel until the RTT control block is initialized, and registers it as port 60000 on your localhost.
target extended-remote :3333
define rtt-init
set $rtt_addr = &RttControlBlock
eval "monitor rtt setup 0x%x 0x40 \"SEGGER RTT\"", $rtt_addr
monitor rtt start
monitor rtt server start 60000 0
end
monitor reset halt
load
break init.zig:120
run
rtt-init
delete 1
Start off by putting the Badge into the right state with:
gdb ./zig-out/firmware/sycl-os-kernel.elf
Confirm that the control block was found, and that the port has been opened, you will see this in both the GDB and OpenOCD logs. Then in a separate terminal run:
nc localhost 60000
Or some other raw port dumping command like telnet, and you should see the first couple logs. From here you can continue debugging, and you’ll find the logs show in this session. Note that when you rebuild the kernel, you’ll be able to reflash the Badge with the load command. The RTT session will persist and you’ll see the printout for when the kernel starts up as you continue to debug.
SWD and UART JST connectors are wired incorrectly, the pins are reverse from what they need to be in order to match the cable for the pico debug.