There’s a hardware USB device peripheral in every F103 chip. It has been quite a long journey, but the code is now finally at a stage where it can be used as serial console for Mecrisp Forth.
You will need the Folie utility, version 2.7 or later, a Blue Pill which will be re-flashed, and a way to do so over serial or SWD - such as a second Blue Pill, configured as SerPlus unit:
Here we go:
- make sure you have checked out a recent copy of the embello repository
- go to the “
suf/
” directory:cd explore/1608-forth/suf/
- launch Folie, and upload the
usb-common.hex
file:!u usb-common.hex
- quit Folie, unplug everything, and plug the target Blue pill back in via USB
- launch Folie again (don’t forget the “
-r
” flag to use raw mode this time) - if all went well, you should now see the new unit, and get a Forth prompt
Here is a transcript of the above six steps, from start to glorious finish:
$ git clone https://github.com/jeelabs/embello.git
Cloning into 'embello'...
remote: Counting objects: 10433, done.
remote: Compressing objects: 100% (584/584), done.
remote: Total 10433 (delta 368), reused 0 (delta 0), pack-reused 9847
Receiving objects: 100% (10433/10433), 4.34 MiB | 747.00 KiB/s, done.
Resolving deltas: 100% (6631/6631), done.
$ cd embello/explore/1608-forth/suf/
$ folie
Folie v2.7-1-g94cba5e
Select the serial port:
1: /dev/cu.Bluetooth-Incoming-Port
2: /dev/cu.usbmodem3430DC31
? 2
Enter '!help' for additional help, or ctrl-d to quit.
[connected to /dev/cu.usbmodem3430DC31]
!u usb-common.hex
26624b +V22 #0410 R +W +E writing: 104/104 done.
$ folie -r
Select the serial port:
1: /dev/cu.Bluetooth-Incoming-Port
2: /dev/cu.usbmodem323F3561
? 2
Enter '!help' for additional help, or ctrl-d to quit.
[connected to /dev/cu.usbmodem323F3561]
ok.
Yes, it’s that simple, when using SerPlus and once all the connections are ok.
There are (quite) a few notes to make:
- first a nice benefit: USB is consderably faster than 115,200 Baud over serial
- the SerPlus has hardware ID
3430DC31
, as shown on MacOS in the device name - in this example, the attached board was empty, with a hardware ID of
323F3561
- the upload uses
usb-common.hex
which works on the Blue Pill and the HyTiny - there are a few other pre-built firmware images for Olimexino, Maple Mini, etc
- the difference is w.r.t. how they enable USB, not all boards use the same pins
- the uploaded code is a minimal build: just the Mecrisp core and a USB driver
- the
eraseflash
word has been redefined to avoid erasing the USB driver - … otherwise, you’d lose USB and end up with a serial-only Mecrisp core (!)
- if the core or driver gets messed up, you may not be able to use USB anymore
- the “
Mecrisp Forth ... by Matthias Koch
” message is no longer shown - entering CTRL-C in Folie will not reset the unit, there is no DTR/RTS logic
- doing a
reset
in Forth will lose the USB connection and force re-enumeration - Folie can detect such lost connections and will try to reconnect to the same device
That re-enumerate-on-reset behaviour is still a major inconvenience on Linux and Windows, unfortunately (and not very different from an Arduino Leonardo, in fact).
Then again, automatic reconnection works very well on MacOS, as you can see below:
ok.
rese
[disconnected] no such file or directory
[connected to /dev/cu.usbmodem323F3561]
ok.
Note that due to the abrupt break not all the output will always be shown in the Folie console, since the USB connection is forcefully reset in mid-flight!
On Linux, the problem is that a re-enumerated USB device will not usually show
up under the same name, with “/dev/ttyACM1” instead of “/dev/ttyACM0”, for
example. This could perhaps be solved by looking up the
/dev/serial/by-path/...
names, as these do not change.
On Windows, there may be more issues (possibly even depending on the actual Win* version). Perhaps someone with good knowledge of USB / Windows / Linux can help figure this out?
For now, the only workaround seems to be: quit Folie and re-open it using the new port.
Two more caveats, caused by known bugs and/or unimplemented logic in the USB driver:
- sending data back-to-back to the F103 can lose packets - this is avoided in Folie by never sending more than 60 bytes at a time, and then adding 2 ms delays in between
- the output from F103 will hang when there is no open serial connection - it’s not enough to have the unit plugged in, you need to actually open it as serial port
Still, having said that: the current combination of Folie and Mecrisp really do work well!
One final step: you need to load the additional words which make life on an F103
under Forth a lot simpler. This is similar to a serial-based setup, jusr use the
“g6u/
” dir instead of “g6s/
“:
$ cd ../g6u
$ folie -r
Select the serial port:
1: /dev/cu.Bluetooth-Incoming-Port
2: /dev/cu.usbmodem323F3561
? 2
Enter '!help' for additional help, or ctrl-d to quit.
[connected to /dev/cu.usbmodem323F3561]
!s board.fs
1> board.fs 5: ( board start: ) 00006800 ok.
6> io.fs 11: Redefine bit. ok.
1> board.fs 37: Redefine init. ok.
1> board.fs 45: ( board end, size: ) 00008CB8 9400 ok.
!s core.fs
1> core.fs 4: cr compiletoflash
ok.
1> core.fs 5: ( core start: ) 00009000 ok.
1> core.fs 12: ( core end, size: ) 0000AFDC 8156 ok.
ok.
hello 64 KB <g6u> 323F3565 ram/flash: 17452 20480 free ok.
FYI, the “hello
” word can now be used to display the second half of the
default reset greeting.
The good news is that the above procedure doesn’t work only on the Blue Pill and the HyTiny. Here is a set of 19 different low-cost F103-based boards which have all been verified to work:
The main hurdle is that you need to figure out how to re-flash the unit, either over serial using Folie or some other STM32 uploader, or using SWD via an ST-Link, a BMP, OpenOCD, etc.
That’s it. Mecrisp Forth can now be used with just a USB cable plugged in. Onwards!