Circuit Playground Express - writing to USB

Hi embedded Rustaceans! Is anyone else here writing Rust code for the Circuit Playground Express using the atsamd project?

I got the blinky_basic example to compile. I figured out how to convert it from elf to bin format, then from bin to uf2 format, and get it flashed on my Circuit Playground Express board. I got the little red LED light blinking. So far so good.

The trickiest part for me was, after running cargo build --example blinky_basic --release, figuring out how to turn the result into a UF2 file that could be flashed onto my Circuit Playground Express. Here are the notes on the final steps I had to figure out myself, in case it helps someone else: circuit-playground - Computer Programming is Fun!

Now I'd like to write bytes from the Circuit Playground Express to the USB port to send messages and data to a connected PC. I'd like to implement something like println! for simple debugging, and also eventually send data from the ADC to a connected PC. I searched the example code for other boards in the atsamd project and found some for reading from USB, which maybe could be adapted for the Circuit Playground Express, but I haven't tried them yet (pretty sure there will be a lot of trial and error due to differences between the boards.) But I didn't see any examples of writing to the USB.

Has anyone got a complete, working example of writing bytes from the Circuit Playground Express to the USB port? Or any advice or pointers?
Thanks!

1 Like

Update: It turns out that writing to USB as if it were a serial port is pretty complex. Lots of registers to control, timing, state to keep track of, events to respond to in a timely manner, etc.

circuitpython does a great job of this transparently - you just call print() and text magically appears in your terminal program on the computer connected via USB. It turns out that circuitpython uses another library to make this happen: tinyusb

I checked out out the tinyusb library, built its example program for BOARD=circuitplayground_express, flashed it to my device ... and it didn't work. On the (Fedora Linux) computer connected via USB I got a bunch of error messages in the log like this

kernel: usb 3-2: new full-speed USB device number 16 using xhci_hcd
kernel: usb 3-2: unable to read config index 0 descriptor/start: -32
kernel: usb 3-2: chopping to 0 config(s)
kernel: usb 3-2: can't read configurations, error -32

And the /dev/ttyACM0 device never got created. And therefore I couldn't get any messages from the device via USB.

The copy of tinyusb included with circuitpython works much better than this. I suspect that the circuitpython folks tweaked it a bit.

To make forward progress, I might give up on stand-alone pure Rust programming, and just embed some Rust code in circuitpython, which I know works. I would need to trim down circuitpython to make room for my code (since circuitpython uses most of the 256k code space.)

I would use some other hardware if it had ADC converters and documented Rust code examples for sending data at high speed over USB to a PC. The STM32F3DISCOVERY that the Embedded Rust Book covers doesn't have an ADC.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.