STM32F103C8T6 ARM STM32 Minimum System Development Board

September 5, 2020

libmaple - try the USB serial example

I made two changes to the example. I changed the BOARD_LED to 14 to match the blue pill. I removed a second argument from the call to usb_cdcacm_putc() as follows:
// usb_cdcacm_putc((char)c1, 1);
usb_cdcacm_putc((char)c1);
After this it compiled and flashed into my blue pill board. The LED is on, but not blinking. When I connect a USB cable, I see this on my Fedora logs:
Sep  6 17:25:22 trona kernel: usb 1-1.1.2: new full-speed USB device number 83 using ehci-pci
Sep  6 17:25:22 trona kernel: usb 1-1.1.2: New USB device found, idVendor=1eaf, idProduct=0004, bcdDevice= 2.00
Sep  6 17:25:22 trona kernel: usb 1-1.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Sep  6 17:25:22 trona kernel: usb 1-1.1.2: Product: Maple
Sep  6 17:25:22 trona kernel: usb 1-1.1.2: Manufacturer: LeafLabs
Sep  6 17:25:22 trona kernel: cdc_acm 1-1.1.2:1.0: ttyACM0: USB ACM device
Sep  6 17:25:22 trona kernel: usbcore: registered new interface driver cdc_acm
Sep  6 17:25:22 trona kernel: cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
Sep  6 17:25:39 trona ModemManager[816]:   [device /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1.2]
    creating modem with plugin 'Generic' and '1' ports
Sep  6 17:25:39 trona ModemManager[816]:   Could not grab port (tty/ttyACM0): 'Cannot add port 'tty/ttyACM0', unhandled serial type'
Sep  6 17:25:39 trona ModemManager[816]:   Couldn't create modem for device '/sys/devices/pci0000:00/0000:00:1a.
So, this is exciting. Looking at the example, it ought to be waiting for input on Serial port 2. The LED is not on, but see below. I dig up a USB to serial dongle and connect it to pins A2 and A3. I use picocom, set 9600 baud, push reset on the STM32 and voila! I see:
This is the debug channel. Press any key.
At first it didn't seem to work, but perhaps I simply wasn't patient enough after typing a character to Serial2. I need to have two terminals open. Both run picocom. One talks to /dev/TTYUSB0 (my serial dongle on port 2). The other talks to /dev/ttyACM0. Both at 9600 baud, for starters.

It doesn't seem to matter what baud rate you set picocom on for ttyACM0, it just works, which sort of makes sense. This is pure USB with no actual serial port in the path.

The LED never blinks, but that turns out to be a bug in the demo. I make the following change:

// toggleLED();
togglePin(BOARD_LED_PIN);
No doubt toggleLED() was fooling with the offical maple mini board LED which is incorrect for our hardware. After rebuilding with this change and reflashing, things are acting as expected. The LED turns on for one second, then off for one second. Each time you press a key to Serial2, you get a different demo.

All in all, this demo works fine, with just a bit of fiddling around. The demo only uses USB Serial as an output device by calling:

SerialUSB.print('.');
SerialUSB.println(3.14159265);
SerialUSB.write('a');
SerialUSB.println("Hello World!");
The final demo calls SerialUSB.end() then SerialUSB.begin() -- this seems to hang. Note that I find it necessary to disconnect/reconnect the USB cable to recover. This needs extra attention someday.

These SerialUSB routines are in "wirish/usb_serial.cpp". There are read() routines. Both read() and write() are polymorphic, making use of C++ trickery. There is a bunch of special code to support the bootloader. Weirdly, the routines in this file have names USBSerial. The file usb_serial.h has the following statement that seems to take care of this:

extern USBSerial SerialUSB;

Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org