USB CDC on the stm32 in Zig

April 20, 2022

I finally managed to get the stm32g4 USB driver to work as a ACM port with Zig.

This is the output from dmesg:

USB CDC port

It shows up in linux and I'm able to see messages printed by running cat /dev/ttyACM2. Yay!

Now if any stm32's ever come back in stock I can finally make a board...

USB is complicated

USB is a lot more complicated than other protocols like I2C / UART. It took quite a bit longer than the other peripherals...

Thankfully there's a lot of helpful websites (eg usb in a nutshell and usb made simple) that explain the protocol. I also made a page with some of the setup packets needed for usb enumeration on linux (not entirely complete).

The code is loosely based on tinyusb by haltech. It takes a slightly different approach for writing to endpoints leveraging zig's comptime types. It also uses Zig's builtin fixed buffer allocator to allocate PMA memory (that just works out of the box, nice!).

Unfortunately a bug with zig's packed structs prevents it from compiling on zig's master branch, but a pending pull request fixes the problem so hopefully that can be merged soon.

Scopy decoder table

In the process of developing this I added a little decoder table to Scopy (the logic analyzer I use). It's not perfect but hopefully some variant can get merged in at some point as it's helpful for jumping to the next message in a longer capture (see branch here if interested).

Scopy decoder table

It's nice that the software is FOSS... that's one of the main reasons I got it.

And that's enough rambling.. this blog is mainly to help me keep track of things down the road. Have a good day!