buck50: Test and measurement firmware for “Blue Pill” STM32F103
buck50 is open-source firmware that turns a “Blue Pill” STM32F103 development board (widely available for approx. US$1.50) into a multi-purpose test and measurement instrument, including:
- 8 channel, 6+ MHz logic analyzer
- Approx. 5K sample buffer depth
- Samples stored only at signal edges for efficient memory usage
- Units may be ganged for increased number of channels
- Complex triggering via user-defined state machine supporting combinations of sequential (“A then B then C”) and logical-OR (“A or B or C”) conditionals
- Output to VCD and other file formats for export to waveform viewing software 1
- Live monitoring and logging of digital, analog, USART (sync/async), SPI (MOSI/MISO), and I2C (master/slave/TX/RX) data
- Simple dual-channel approx. 1 MHz digital storage oscilloscope, approx. 5K sample buffer depth (10K if single channel)
- 3 channel digital pulse train generator with user-defined frequency and per-channel duty cycle and polarity
- Bidirectional bridge/converter from USART/UART (async/synchro), SPI (master/slave), or I2C … to USB … to host terminal, UNIX socket, or UNIX pty device file
- 8-bit parallel output counter (binary or gray code)
- Host terminal ascii or binary input data to 8-bit parallel output
- Firmware written in a combination of C++ and ARM Thumb-2 assembly code, with several non-standard hacks^H^H^H^H^Htechniques of possible general interest to advanced software developers
- Python host driver program with comprehensive inline help system and usability features
- Coffee maker attachment sold separately, not included in base price 2
Contents
License
buck50: Test and measurement firmware for “Blue Pill” STM32F103 development board
Copyright © 2019,2020 Mark R. Rubin aka “thanks4opensource”
This file is part of buck50.
The buck50 program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
The buck50 program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with the buck50 program. If not, see https://www.gnu.org/licenses/gpl.html
Firmware installation
buck50 is provided as ready-to-flash files in ELF (buck50.elf), binary (buck50.bin), and Intel hex (buck50.hex) formats in addition to source code (see Building from source, below).
Instructions on how to flash code onto microcontrollers such as the STM32F103 are beyond the scope of this document. Briefly, the STM32F103 cannot be flashed via its USB port (except 3), so other techniques must be employed.
Probably the best method is via the “Blue Pill” SWD port (see Hardware connections, below) using either a Black Magic Probe (website, wiki) or an ST-Link (website) or clone thereof (Google search). Note that the former is used with GDB from the GNU Arm Embedded Toolchain and the latter either with GDB or stlink (GitHub repository) among other software front ends.
Alternately, the “Blue Pill” can be flashed via its USART1 serial port (RX on port PA10, TX on PA9, see below). This typically requires a USB-to-serial converter
(Google search) (or, ironically, another already-flashed “buck50” 4) as modern host computers rarely include an RS-232 port. Instructions and software required for doing so can be found at the stm32flash SourceForge website, this tutorial web page, and/or a GitHub wiki, among other resources. If using a serial port method remember to change the BOOT0 jumper (see directly below) back to its “0” position after flashing with it set to “1”.
Hardware connections
The following is a highly simplified, edited version of the incredibly useful image created by Rasmus Friis Kjeldsen 5, available at http://reblag.dk/stm32/ (direct link: http://reblag.dk/wordpress/wp-content/uploads/2016/07/The-Generic-STM32F103-Pinout-Diagram.pdf). The edited and original versions are included in this repository under terms in compliance with the original’s license.

WARNING! Incorrect hookups to the “Blue Pill” (or any other microcontroller’s) ports may cause permanent damage. Examples: Connecting a push-pull output port directly to a positive voltage source or ground sink, or to another push-pull output on the same or different MCU set to the opposite polarity. Readers of this document and users of the firmware it describes assume all responsibility for their actions.
Pin descriptions
The buck50 firmware configures and uses the “Blue Pill” STM32F103 GPIO ports as follows. Note that many pins have multiple uses depending on which buck50.py host command is in effect, including changing roles to be either inputs, outputs, or bidirectional.
Pin(s) Type Purpose buck50.py commands
====== ============================== ================================= ==================
PB4-11 input weak pull-down digital input logic, monitor
PB10,11 in/out open-drain I2C i2c, monitor
PA0-7 output push-pull digital output numbers, gpio
PA0-7 input analog analog input oscope, monitor
PA1-3 output push-pull digital pulse outputs pulse
PA0 input weak pull-up usart CTS usart
PA1 output push-pull usart RTS usart
PA2 output push-pull usart TX usart
PA3 input weak pull-up usart RX usart
PA4 output push-pull SPI select output (master) spi, monitor
PA4 input floating SPI select input (slave) spi, monitor
PA5 output push-pull SPI clock (master) spi, monitor
PA5 input floating SPI clock (slave) spi, monitor
PA6 input floating/pull-up/-down SPI MISO spi, monitor
PA7 output push-pull SPI MOSI spi, monitor
PA8 output push-pull USART clock (synchronous) usart, monitor
PA9 output push-pull USART TX usart, monitor
PA10 input weak pullup USART RX usart, monitor
PB13 output push-pull sampling indicator, sync logic, oscope
PB14 output open-drain external/ganged trigger logic, oscope
PB15 output open-drain external/ganged trigger ack logic, oscope
PC13 output open-drain status/fault/sampling/triggering <all>, logic, oscope
PA11 output open-drain USB negative (do not connect) <all>
PA12 output open-drain USB positive (do not connect) <all>
See logic, monitor, numbers, spi, and usart, below.
Notes:
- See buck50.py driver program, below, for command usage.
- PA0-7 are multipurpose pins, as per above.
- PC13 connected to on-board user LED
- On: Firmware running and connected to USB
- Off: Triggering and/or sampling
- Blinking 2 Hz:
reset blink command (used to identify physical device)
- Blinking 4 Hz: Firmware error (requires hardware reboot and host software reconnect 6).
- PB13 outputs approx. 2.15 Hz 50% duty cycle square wave during digital sampling. Can be connected to an external LED (with appropriate current-limiting resistor) or other external monitoring as sampling indicator, and/or connected to ganged buck50s as additional sync signal for post-processing alignment of captured data.
- PB14 and PB15 can be used to synchronize triggering across multiple buck50 "Blue Pill"s. Connect all PB14 pins to an open-drain bus line (with pull-up resistor), and similarly for PB15. See
buck50.py’s help reset ganged=, help reset ext-trig, and help trigger, and logic command and reset command, below.
Python
buck50.py is (obviously) written in Python. Python3 (7) (3.6 to be precise). It was developed under Linux and should be portable any Linux distribution or other UNIX-like operating system. External library and file system assumptions (/dev/ttyACMn, /dev/pts/NN) may require modification for use under macOS. It is unlikely that buck50.py will function in a Microsoft Windows® environment without fairly extensive code modifications.
Where’s the GUI?
(Note to the impatient: If reading sequentially, skip ahead to TL;DNR (“Too Long, Did Not Read”), below.)
Good question. The original intent for buck50 was to integrate the host-based driver into an existing open source waveform viewer program. This was abandoned due to limitations in the ones I could find (see Waveform viewing software, below), and also as the scope of buck50 grew beyond it’s original beginnings as a logical analyzer and evolved into the many-headed Hydra it eventually became. (Its capabilities no longer fit into the basic design of a logic analyzer program.)
In addition, many of those capabilities are inherently text based (monitoring, SPI and USART bridges, etc). Sure, any decent GUI library provides a scrolling text widget, but a text-based program inherently leverages the features of the many excellent Linux terminal emulator programs available. As an analogy, consider the difference between the typical on-screen GUI calculator program that mimics a handheld device with only one numeric display line compared to a full featured text-based program like bc (or, for that matter, Python).
The buck50.py interface was expressly written for fast and easy usage in an active test and measurement environment. Think of it as an ugly-looking GUI with many, many “hot key” shortcuts. (Just like the GUI calculators: What’s faster? Typing numbers on a keyboard or mousing around clicking virtual GUI buttons? Also 8.) Try buck50.py, and if dissatisfied but still want to use the firmware, feel free to write a GUI driver (respect the GPL license above). A wrapper layer around the buck50.py module would be fairly easy to implement.
All the above notwithstanding, buck50.py does attempt to integrate nicely with external waveform viewing software (see below). If gnuplot is installed on the host system, the code will by default to automatically dump captured digital or analog data to a temporary file and load that (see gnuplot, below) with the appropriate commands 9. Other viewers may be manually configured/enabled as well.
TL;DNR (“Too Long, Did Not Read”)
The buck50 firmware and buck50.py driver implement many complex capabilities. The interface is thus necessarily complex but has been designed to allow simple default usage when fine-grained control is not needed.
Examples:
Output 4Hz incrementing binary counter on output ports PA0 through PB77:
$1.50: numbers
<ENTER> to halt ...
Monitor input ports PB4 through PB11:
$1.50: monitor
<ENTER> to end
0.000 00111001 ... ... blu grn yel ... ... brn
0.250 00111010 ... ... blu grn yel ... red ...
0.500 00111011 ... ... blu grn yel ... red brn
0.750 00111100 ... ... blu grn yel org ... ...
1.000 00111101 ... ... blu grn yel org ... brn
1.250 00111110 ... ... blu grn yel org red ...
1.500 00111111 ... ... blu grn yel org red brn
1.750 01000000 ... vio ... ... ... ... ... ...
2.000 01000001 ... vio ... ... ... ... ... brn
2.250 01000010 ... vio ... ... ... ... red ...
2.500 01000011 ... vio ... ... ... ... red brn
2.750 01000100 ... vio ... ... ... org ... ...
3.000 01000101 ... vio ... ... ... org ... brn
3.250 01000110 ... vio ... ... ... org red ...
Logic analyzer, capture first 32 signal level changes on ports PB4 through PB11:
$1.50: logic edges=32
logic: edges=32
Waiting for sampling finish (<ENTER> to abort) ...
Triggered at state #0: 32 samples (6.26MHz) in 0.00 seconds. Stopped by number of samples.
The captured sample data will be automatically uploaded and an external viewer program launched if configured (see above). Otherwise (or in addition), data can be manually uploaded and saved, for example:
$1.50: dump digital-frmt=vcd file=capture
logic samples: 0...31 of 32 @ 6.26MHz ... saving to file capture.vcd
Logic analyzer, as above, but trigger on rising edge of input port PB8
$1.50: trigger 0=xxx0xxxx-1-0 # wait for PB8 low
$1.50: trigger 1=xxx1xxxx-0-1 # wait for PB8 high
$1.50: logic edges=32
logic: edges=32
Waiting for sampling finish (<ENTER> to abort) ...
Triggered at state #1: 32 samples (6.26MHz) in 5.18 seconds. Stopped by number of samples.
logic samples: 0...31 of 32 @ 6.26MHz ... saving to file /tmp/temp.csv
USART bridge:
$1.50: usart
<ENTER> to input, then input ascii text with optional "\n", "\t", and "\x<two hex digits>" escape sequences ...
received data
more received data
-- <ENTER> key pressed here --
"END" to finish: data to send
yet more received data
-- <ENTER> key pressed here --
"END" to finish: END
flushing USB CDC-ACM pipe for 1 second (<ENTER> to abort) ...
or alternately:
$1.50: usart ipc external pty enable
ipc: external
pty: enable
pty /dev/pts/41 ready
I/O active, press <ENTER> to exit ...
and then run an external terminal application (screen, miniterm), or more simply:
$ cat /dev/pts/41 & cat > /dev/pts/41
I2C bridge (slave @ address 31, initialize register 0x5b with 1, register 0x2a with 0x39, then read 6 byte wide register 0x33 twice):
$1.50: i2c master
i2c: master
Input format: <slave address> <rx size> <tx data <2hex|3dec|1ascii>) ...> [; ...]
"0 0" to end: 0x1f 0 5b 01 ; 0x1f 0 2a 39
stat= OK tx=2 rx=0 :
stat= OK tx=2 rx=0 :
"0 0" to end: 0x1f 6 33
stat= OK tx=1 rx=6 : 255-ff-. 215-d7-. 254-fe-. 044-2c-, 003-03-. 208-d0-.
"0 0" to end: 0x1f 6 33
stat= OK tx=1 rx=6 : 255-ff-. 212-d4-. 254-fe-. 043-2b-+ 003-03-. 212-d4-.
"0 0" to end: 0 0
Continuously read register after above I2C address 31 device initialization:
$1.50: monitor pb4-11=disabled rate=1s i2c master addr=31 tx-data=33 rx-size=6
i2c: master
monitor: pb4-11=disabled
monitor: rate=1Hz=1s
i2c: addr=31
i2c: tx-data=33
i2c: rx-size=6
<ENTER> to end
0.001 i:ff.d9.fe.2e.03.d5
1.002 i:ff.d5.fe.2c.03.d4
2.003 i:ff.d7.fe.2f.03.d5
3.003 i:ff.d1.fe.28.03.cf
4.004 i:ff.d2.fe.31.03.d4
5.005 i:ff.d9.fe.2a.03.dd
6.006 i:ff.d5.fe.2c.03.d9
7.007 i:ff.d2.fe.27.03.d0
8.008 i:ff.cd.fe.2a.03.da
...
Output 1kHz square waves on port PA1 through PA3, rising edges at 250, 500, and 750 ms respectively in total period:
$1.50: pulse enable
Capture analog values from inputs PA4 and PA5, triggering on positive slope at 1.65V on channel PA4
$1.50: oscope trgr-chnl=4 scnd-chnl=5 trigger=0:3.3:0.15:0.01
oscope: trgr-chnl=4
oscope: scnd-chnl=5
Waiting for sampling finish (<ENTER> to abort) ...
3257 samples, 2 channels (PA4,PA5) at 239.5+12.5@12MHz->47.6kHz in 3.83s wall clock time. Stopped by number of samples.
Samples 0...3256 (3257 total) 2 channels (PA4,PA5) per sample at 239.5+12.5@12MHz->47.6kHz
NLE;WTRSBNTMM (“Not Long Enough, Want To Read Some But Not Too Much More”)
After reading the above, an reasonable reaction might be: You want me to type all those complicated commands? How is that “fast and easy” usage?
A valid criticism … but there is hope. That’s why you, the sophisticated user, chose to read this section. ;) Remember all that stuff that got printed when the program started?
buck50.py 0.9.2
Copyright 2020 Mark R. Rubin aka "thanks4opensource"
This is free software with ABSOLUTELY NO WARRANTY.
For details type "warranty" or "help warranty".
Type "using" for program usage.
Type "help" for commands, configurations, parameters, values.
...
Well, after reading the full license (you did type “warranty” or “help warranty”, didn’t you?), those with inquisitive minds might try:
$1.50: using
Input:
- Type "<command> ..." followed by ENTER key
- Abbreviate any command, configuration, parameter, or value to its unique prefix
Example:
m d=i r=4k a w=2 spe=6
same as:
monitor duration=infinite rate=4kHz adc weight=2 speed=600kHz=1.66667μs
- "#" in line: rest of line ignored
Completion:
key(s) result:
------ -------
<TAB> Completes partially typed command, configuration, parameter,
or value (if unique prefix), else ...
<TAB><TAB> ... sounds terminal bell and second <TAB> prints list
of possible completions
...
The using help natters on for quite a while (violating this section’s "Not Too Much More” promise) with examples, information on input editing, history, and more. But the two important points are:
- Abbreviate anything, and/or …
- … use
TAB key completion.
#2 is the “FTW” secret. If you take away nothing else from reading this document, remember:
- PRESS THE
TAB KEY!!! (10)
That, along with the the program’s built-in help system, largely make this entire README.md redundant. The help system is hierarchical, starting with general information:
$1.50: help
Help:
Commands, Configurations, Actions, Parameters, Values:
<command> [[<action>] [<parameter>=<value>] ...] [<configuration> [<action>]
[<parameter>=<value>] ...] ... [# comment ...]
Syntax:
symbol explanation
------ -----------
<command> command name
[...] optional
[<action>] optional action name
[<parameter>=<value>] optional parameter=value names
<configuration> configuration name
... optional repeats
[# comment ...] text from "#" to end of line ignored
Verbose explanation:
- Program executes Commands
- Commands use Parameter=Value settings
- Parameter=Value settings are grouped into Configurations
- Configurations may have optional Actions
- Parameters have default Values
- Parameters retain their Values until changed by new Parameter=Value setting,
"configure load", or program exit/restart.
- Commands have a primary Configuration, with same name as the Command
- Commands may have one or more secondary Configurations
- Primary configuration is initial current Configuration
- Configuration remains current until changed by explicit new Configuration
- Only current Configuration's Parameters=Values can be set
- Configurations may be used by multiple Commands
- Only one Action allowed per Configuration per Command
...
and continuing on with examples and hints on how to dive deeper into the help hierarchy.
Beyond that, experimenting with the commands and their configurations and parameters (and the TAB key!) should suffice to get started. Or continue with reading the next section …
OK;TSIGMTW9Y (“OK, This Sounds Interesting, Give Me The Whole 9 Yards”)
Kudos to those who ended up (or skipped directly to) here. A brief review 11, particularly for the latter, of the buck50.py program’s usage features …
First, any input can be fully typed, or abbreviated to its unique prefix. Each of the following sets of lines produces an identical result:
$1.50 h
$1.50 he
$1.50 help
$1.50 m
$1.50 mon
$1.50 monitor
$1.50: n o=p r=1k m=b
$1.50: num op=pu ra=1kh mo=bin
$1.50: numbers open-pull=push-pull rate=1kHz mode=binary
Note that all commands echo any changed parameters, both as a reminder and more importantly to confirm the expansion of any abbreviations:
$1.50: n o=p r=1k m=b
numbers: open-pull=push-pull
numbers: rate=1kHz=1ms
numbers: mode=binary
$1.50: num op=pu ra=1kh mo=bin
numbers: open-pull=push-pull
numbers: rate=1kHz=1ms
numbers: mode=binary
$1.50: numbers open-pull=push-pull rate=1kHz mode=binary
numbers: open-pull=push-pull
numbers: rate=1kHz=1ms
numbers: mode=binary
Second, the keyboard TAB key completes any unambiguous partially-typed entry, possibly up a common prefix of multiple valid choices. It sounds the system “bell” otherwise, and when pressed a second time presents a list of valid choices (if any). TAB can be used with blank space to give a full list of valid entries in the current context.
$1.50: s<TAB>
$1.50: spi <TAB><TAB>
ascii-num= endian= mode= pull= snoop= xmit-only=
baud= idle= nss-time= rate= socket
busy-wait= ipc nss= rx-wait= speed=
disable master phase= select= spi
end= miso= pty slave tx-data=
$1.50: spi b<TAB><TAB>
baud= busy-wait=
$1.50: spi ba<TAB>
$1.50: spi baud=
1.125MHz 2.25MHz 36MHz 562.5KHz
18MHz 281.25KHz 4.5MHz 9MHz
$1.50: spi baud=2<TAB><TAB>
2.25MHz 281.25KHz
$1.50: spi baud=28<TAB>
$1.50: spi baud=281.25KHz
The painstaking example above is more complicated and time-consuming to go through than actually using the TAB key in the buck50.py itself. Just keep pressing TAB and follow the suggestions.
As described in the previous section, buck50.py features an extensive build-in help system. The following is a (largely depth-first) guided tour through it, with occasional brief additional comments.
First, however, the program needs to be started from a UNIX shell …
buck50.py startup and device connection
Commandline arguments:
$ ./buck50.py --help
usage: buck50.py [-h] [-v] [-q] [-f [FILE]] [-x]
[--halt {monitor,gpio,usart,spi,i2c,numbers}]
[acm]
positional arguments:
acm CDC/ACM device (with or without "/dev" or "/dev/tty"
prefix) (default: /dev/ttyACM0)
optional arguments:
-h, --help show this help message and exit
-v, --version Print program/protocol version and exit (default:
False)
-q, --quiet Don't print startup info (default: False)
-f [FILE], --file [FILE]
Config file to load at startup (see "help configure
load" (default: None)
-x, --no-auto-viewer Disable automatic, pre-"--file" search for waveform
viewing software and setting of "logic autodump=",
"oscope autodump=", and "dump auto-digital= auto-
analog= viewer-csv= viewer-vcd= digital-frmt= analog-
frmt=" parameters. See "help xxx ..." for those
commands/configurations/parameters. (default: False)
--halt {monitor,gpio,usart,spi,i2c,numbers}
Experimental. Reset firmware if buck50.py exit while
command in progress. Must be done before buck50.py
without "--halt", and must specify correct command
name, else firmware/hardware reset and/or power cycle,
and USB re-enumeration required. (default: none)
Normal startup:
$ buck50.py
buck50.py 0.9.2
Copyright 2020 Mark R. Rubin aka "thanks4opensource"
This is free software with ABSOLUTELY NO WARRANTY.
For details type "warranty" or "help warranty".
Type "using" for program usage.
Type "help" for commands, configurations, parameters, values.
Connecting to buck50 device (press CTRL-C to abort ... )
Firmware identity match: 0xea017af5
Firmware version match: 0.9.2
Device serial number: 123456789abcdef987654321
Found /usr/bin/pulseview and /usr/bin/gnuplot. Have now set:
configure logic autodump=enabled oscope autodump=enabled dump output=file auto-digital=enabled auto-analog=enabled digital-frmt=csv viewer-csv=gnuplot viewer-vcd=pulseview
Note that the correct /dev CDC/ACM USB special file corresponding to the STM32F103 “Blue Pill” device running the buck50 firmware must given as a commandline argument if it is not the default /dev/ttyACM0. On Linux systems the default should be correct if no other CDC/ACM USB devices are connected (or the buck50 device was connected first, before the others).
If not, the correct /dev file is reported when the “Blue Pill” is connected via USB. The utilities dmesg, journalctl, and others will show output similar to:
usb m-n.p.q: new full-speed USB device number N using xhci_hcd
usb m-n.p.q: New USB device found, idVendor=0483, idProduct=5740
usb m-n.p.q: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb m-n.p.q: Product: STM32 Virtual COM Port
usb m-n.p.q: Manufacturer: STMicroelectronics
usb m-n.p.q: SerialNumber: 1234567890abcdef01234567
cdc_acm m-n.p.q:1.0: ttyACMn: USB ACM device
where “m”, “n”, “p”, “q”, “N”, the SerialNumber, and the “n” in ttyACMn are arbitrary values.
If the “Blue Pill” is already plugged in and more than one /devttyACMn file exists, various Linux utilities can be used to determine which is correct. For example:
$ for NAME in /dev/ttyACM* ; do
> echo $NAME
> udevadm info --name=$NAME | egrep '0483|5740|ID_SERIAL_SHORT'
> done
Each /dev/tttyACMn corresponding to a buck50 “Blue Pill” will output lines of the form:
/dev/ttyACMn
E: ID_MODEL_ID=5740
E: ID_SERIAL_SHORT=1234567890abcdef01234567
E: ID_VENDOR_ID=0483
while non-“Blue Pill”/non-buck50 devices will not have the E: ID_MODEL_ID=5740 and ID_VENDOR_ID=0483 lines.
If multiple buck50 "Blue Pill"s are connected (which can be very useful 12) (type help reset ganged= for a usage example), once again the easiest way to tell which /dev/ttyACMn file corresponds to which is to plug them into USB sequentially and watch the dmesg, etc. output.
After multiple buck50.py programs are connected to the multiple buck50 devices via the appropriate /dev/ttyACM0 files, which one is which can be determined by the serial numbers reported at program startup. The serial numbers can matched to physical hardware by noting the dmesg, etc. output, or by the udevadm command described above.
Finally (and easier), the reset blink command will blink the user LED of the connected “Blue Pill” device for identification purposes.
On macOS the device special files should be of the form /dev/tty.usbmodemWXYZ... for some value of “WXYZ…” 13. As noted above, it is unlikely that the buck50.py program will function in a Microsoft Windows® environment without significant revisions.
review license
Review the license:
$1.50: warranty
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License , or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to
The Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor
Boston, MA 02110-1335 USA
help
$1.50: help
Help:
Commands, Configurations, Actions, Parameters, Values:
<command> [[<action>] [<parameter>=<value>] ...] [<configuration> [<action>]
[<parameter>=<value>] ...] ... [# comment ...]
Syntax:
symbol explanation
------ -----------
<command> command name
[...] optional
[<action>] optional action name
[<parameter>=<value>] optional parameter=value names
<configuration> configuration name
... optional repeats
[# comment ...] text from "#" to end of line ignored
Verbose explanation:
- Program executes Commands
- Commands use Parameter=Value settings
- Parameter=Value settings are grouped into Configurations
- Configurations may have optional Actions
- Parameters have default Values
- Parameters retain their Values until changed by new Parameter=Value setting,
"configure load", or program exit/restart.
- Commands have a primary Configuration, with same name as the Command
- Commands may have one or more secondary Configurations
- Primary configuration is initial current Configuration
- Configuration remains current until changed by explicit new Configuration
- Only current Configuration's Parameters=Values can be set
- Configurations may be used by multiple Commands
- Only one Action allowed per Configuration per Command
Examples:
logic
- Command with no Parameter=Value settings, Actions, or secondary
Configurations
usart baud=19.2kHz
- Command with Parameter=Value setting in primary Configuration
pulse time=125ms mode1=rise time1=15%
- Command with multiple Parameters=Values settings in primary Configuration
monitor lines 6=clock 7=data
- Command with multiple Parameter=Value settings in secondary Configuration
reset halt
- Command with Action in primary Configuration
monitor spi master
- Command with Action in secondary Configuration
monitor rate=10Hz pb4-11=disabled adc0 enable
s/h+adc=239.5+12.5@12MHz->47.6kHz spi slave miso=push-pull monitor
file=monitored.txt output=both
- Command with multiple Parameters=Values settings in primary Configuration,
two secondary Configurations each with a Parameter=Value setting and an
Action, then explicit primary Configuration with two more Parameter=Value
settings
Commands:
configure, trigger, logic, oscope, dump, monitor, pulse, gpio, usart, spi,
i2c, numbers, reset, warranty, help, using, quit
Configurations:
configure, monitor, pulse, numbers, gpio, usart, spi, i2c, adc0, adc1, adc2,
adc3, adc4, adc5, adc6, adc7, logic, oscope, dump, lines, reset, socket,
pty, ipc
Time/Frequency Errors:
- Many time and/or frequency parameters have limited precision due to their
STM32F103 hardware implementations (32 bit register values, etc). Arbitrary
Parameter=Values are rounded to the nearest achievable value and the error
difference reported. Examples:
31.125μs(error:-5.5ns)
- time is 5.5ns shorter than requested
3.13043MHz=319.444ns(error:-28.8452kHz,+2.91663ns)
- frequency is 28.8452kHz lower, time 2.91663ns longer, than requested
monitor
- Command with no Parameters=Values settings, Actions, or Configurations.
All current Parameter=Value settings in all Configurations remain in
effect.
More help:
help using
help <command>
help <command> <parameter>
help <command> <configuration>
help <command> <configuration> <parameter>
Commands, configurations, actions, parameters, values: What could be simpler? ;) Hopefully further help, below, experimenting using the program (and, as always 11, using the tab key) will clarify.
usage help
$1.50: help using
Help for command "using":
Input:
- Type "<command> ..." followed by ENTER key
- Abbreviate any command, configuration, parameter, or value to its unique
prefix
Example:
m d=i r=4k a w=2 spe=6
same as:
monitor duration=infinite rate=4kHz adc weight=2 speed=600kHz=1.66667μs
- "#" in line: rest of line ignored
Completion:
key(s) result:
------ -------
<TAB> Completes partially typed command, configuration, parameter,
or value (if unique prefix), else ...
<TAB><TAB> ... sounds terminal bell and second <TAB> prints list
of possible completions
Example:
n<TAB> i<TAB>3 o<TAB>p<TAB> m<TAB><TAB>g<TAB> l<TAB><TAB>o<TAB>16
completes:
numbers increment=3 open-pull=push-pull mode=gray low=16
(note could use abbreviations instead):
n i=3 o=p m=g lo=16
Example:
usart p<TAB><TAB>
prints list:
parity= phase= ports= pty
then:
usart pa<TAB>
completes:
usart parity=
Example (note space after "usart", before double <TAB> press):
spi <TAB><TAB>
prints list:
ascii-num= endian= mode= pull= snoop= xmit-only=
baud= idle= nss-time= rate= socket
busy-wait= ipc nss= rx-wait= speed=
disable master phase= select= spi
end= miso= pty slave tx-data=
then:
spi x<TAB>
completes:
spi xmit-only=
and:
spi xmit-only=<TAB><TAB>
prints list:
disabled enabled
and finally:
spi xmit-only=e<TAB>
results in:
spi xmit-only=enabled
Editing, history:
(only basics listed, web search "GNU readline" for more)
key result:
------------------------- -------
<LEFT-ARROW> or <CTRL+b> cursor left
<RIGHT-ARROW> or <CTRL+f> cursor right
<BACKSPACE> or <DELETE> delete character
<HOME> or <CTRL+a> cursor to start of line
<END> or <CTRL+f> cursor to end of line
<UP-ARROW> or <CTRL+p> previous input line
<DOWN-ARROW> or <CTRL+n> next input line
<CTRL+r> search input history
<CTRL+g> clear input line
Alternate "?" help syntax:
"?" anywhere in line same as "help <line>" (line truncated at "?")
"?" can immediately follow command/configuration/parameter/value or be
separated by space
Examples ("?", " ?", and " ? " always equivalent):
"?" syntax same as:
---------- --------
usart? help usart
usart ? help usart
numbers rate? help numbers rate
numbers rate=? help numbers rate=
numbers rate=2Hz? help numbers rate=2Hz
monitor adc3? help monitor adc3
configure usart baud? help configure usart baud
configure pulse time=1kHz spi? help configure spi
spi mode=? endian=lsb help spi mode=
monitor duration=? adc weight=3 help monitor duration
configure gpio end=XX rate=? pulse time=1s help gpio rate
More help:
Type "help" for general help on commands, configurations, actions, and
parameters
There it is: Abbreviations, the full TAB key magic, the rest of the line editing capabilities, and a quicker way to get help. Commands and other elements in the following examples are fully typed, but remember that abbreviations or TAB completion can always be used instead.
Once more, it cannot be overemphasized:
- PRESS THE
TAB KEY OFTEN!!! 14
See Future work, below, for small problem with “?” alternate help syntax implementation.
Also note that the non-intuitive command names (gpio instead of parallel, numbers instead of counter) were chosen in an attempt to make commands (and other strings) unique in their first letter (or first few) for easy TAB completion.
Continuing the help system tour …
The configure command displays, changes, saves, and or loads any parameters in any or all configurations.
$1.50: help configure
Help for command "configure":
View, change, load, and/or save settings
- View any or all configurations' parameters:
- Save or load all configurations' parameters to/from disk file
- Adjust all time output values (trim hardware CPU clock)
Command usage:
configure [<parameter>=<value> ...] [<action>] [<configuration>
<parameter>=<value ...] [<action>]
Configurations (primary="configure"):
configure, lines, numbers, gpio, usart, adc0, adc1, adc2, adc3, adc4, adc5,
adc6, adc7, spi, i2c, pulse, monitor, logic, oscope, dump, reset, socket,
pty, ipc
Type "help configure <configuration>" for configuration description,
parameters, and actions
Type "help configure <configuration> <parameter>" for parameter description
As with all commands, configure has its own default configuration, also named “configure” 15, with a set of parameters and actions:
$1.50: help configure configure
Help for configuration "configure" (e.g. "configure configure"):
Load and/or save all configuration parameters to file
- Will append ".b50" to file name if missing
- Supports <TAB> completion of filenames
Command/configuration usage:
configure [<parameter>=<value> ...] [<action>]
Actions:
save Save all configurations/parameters to file, name...
load Load all configurations/parameters to file, name...
adjust Adjust reported times by "trim" parameter value
Parameters:
file= Name of ".b50" file to load or save configuratio...
trim= Trim all reported times by factor of X/Y where X...
Configuration "configure" used by commands:
configure
Type "help configure" for command description
Type "help configure configure <parameter>" for parameter description
Type "help configure configure <action>" for action description
Configuration help (for any configuration) truncates long explanations. To see the full text:
$1.50: help configure save
Help for action "save" (e.g. "configure configure save"):
- Save all configurations/parameters to file, name specified with"file="
parameter
Type "help configure configure" for list of configure configuration actions
Type "help configure" for command description
$1.50: help configure load
Help for action "load" (e.g. "configure configure load"):
- Load all configurations/parameters to file, name specified with"file="
parameter
Type "help configure configure" for list of configure configuration actions
Type "help configure" for command description
$1.50: help configure adjust
Help for action "adjust" (e.g. "configure configure adjust"):
- Adjust reported times by "trim" parameter value
Type "help configure configure" for list of configure configuration actions
Type "help configure" for command description
$1.50: help configure file=
Help for parameter "file=" (e.g. "configure configure file="):
- Name of ".b50" file to load or save configurations and parameters. ".b50"
suffix will be appended if missing. See "load" and "save" actions.
Current value:
Valid values: <any valid file or path name>
Type "help configure configure" for list of configure configuration parameters
Type "help configure" for command description
$1.50: help configure trim=
Help for parameter "trim=" (e.g. "configure configure trim="):
- Trim all reported times by factor of X/Y where X is currently reported time
and Y is desired. Use "adjust" action to effect.
Current value: 1.00000/1.00000
Valid values: <X/Y with X and Y floating point numbers>
Type "help configure configure" for list of configure configuration parameters
Type "help configure" for command description
Customization of buck50.py can be done by changing any of the various commands’ configuration parameters and saving with configure file=<filename> save 16. The customizations can manually loaded with configure file=<filename> load, or automatically at buck50.py startup with the --file= commandline option.
Note that buck50.py has no explicit “reset defaults” command or action. Again, this can be easily implemented via configure file=<filename> save before any configuration changes (and without commandline --file=) and reloaded as desired.
Note that the configure command is useful not only for changing its own configuration parameters, but also for changing other command’s configurations’ parameters without executing those commands. Examples:
$1.50: configure trim=1.00/0.97
configure: trim=1.00000/0.970000
configure:
file : default.b50
trim : 1.00000/0.970000
$1.50: configure monitor duration=90s
monitor: duration=1.5m
monitor:
rate : 4Hz=250ms
duration : 1.5m
pb4-11 : enabled
file :
output : both
printf : %7.3f
$1.50: configure lines 4=NSS 5=SCK 6=MISO 7=MOSI spi slave miso=push-pull tx-data=12.34.56
spi: slave
lines: 4=NSS
lines: 5=SCK
lines: 6=MISO
lines: 7=MOSI
spi: miso=push-pull
spi: tx-data=12.34.56
lines:
4 : NSS
5 : SCK
6 : MISO
7 : MOSI
8 : grn
9 : blu
10 : vio
11 : gry
spi:
mode : slave
xmit-only : disabled
snoop : disabled
select : software
baud : 281.25KHz
endian : msb
idle : low
phase : 1st
miso : push-pull
pull : floating
speed : 2MHz
nss : floating
tx-data : 12.34.56
rate : unlimited
busy-wait : 1ms
rx-wait : 10ms
nss-time : zero
ascii-num : numeric
end : END
Moving on to the actual functional, results–producing commands and their configurations …
logic command
$1.50: help logic
Help for command "logic":
Digital logic analyzer.
- capture samples of logic levels on ports PB4(lsb) through PB11(msb)
- samples recorded only if level changes on any port
- samples also recorded every 0.233016889 seconds regardless if any change
- sampling starts when trigger condition met (see "help trigger")
- sampling continues until first of:
. user interrupt (<ENTER> key)
. duration elapsed ("logic duration=")
. number of samples ("logic edges=") (incl. extra samples @ 233ms)
. memory full
- see "help logic mode" for sampling speed
- see "help trigger" for triggering
- see "help reset ganged=" and "help reset ext-trig" for external triggering and
multiple device synchronization
- on-board user LED off at start of triggering, back on when sampling finished
- port PB13 toggles at c. 4.29 Hz during sampling, can monitored by external
device, drive LED at 3mA max, and/or aid post-processing of multiple device
captures
- Use "dump" command to upload, print, save, and/or view samples.
Command usage:
logic [<parameter>=<value> ...] [<action>]
Configuration: logic
Type "help logic logic" for configuration description, parameters, and actions
Type "help logic <parameter>" for parameter description
logic configuration
$1.50: help logic logic
Help for configuration "logic" (e.g. "logic logic"):
Digital (logic analyzer) capture parameters.
Command/configuration usage:
logic [<parameter>=<value> ...]
Parameters:
mode= Sampling mode...
duration= Sampling time limit
edges= Maximum number of digital samples (including ext...
code-mem= Sampling code memory bank. "ram" faster, "flash"...
autodump= Automatically (CAUTION!) do "dump" command after...
Configuration "logic" used by commands:
configure
logic
Type "help logic" for command description
Type "help logic <parameter>" for parameter description
logic parameters
$1.50: help logic mode=
Help for parameter "mode=" (e.g. "logic logic mode="):
- Sampling mode
- digital digital ports PB4(lsb)...PB11(msb)
- all clock counts @ 72MHz main CPU)
- see https://github.com/thanks4opensource/buck50/#why_so_slow
- if "code-mem=flash":
6.26MHz : sequence 5@11+1@14 CPU clocks/sample (72*6/69 = 6.26MHz)
irregular : alternating 11 + 14 " " " (72*2/25 = 5.76MHz)
uniform : constant 15 " " " (72 /15 = 4.80MHz)
4MHz : constant 18 " " " (72 /18 = 4.00MHz)
- if "code-mem=ram":
6.26MHz : sequence 5@13+1@17 CPU clocks/sample (72*6/69 = 5.27MHz)
irregular : alternating 13 + 17 " " " (72*2/30 = 4.80MHz)
uniform : constant 17 " " " (72 /17 = 4.24MHz)
4MHz : constant 18 " " " (72 /18 = 3.43MHz)
Current value: 6.26MHz
Valid values: "6.26MHz", "irregular", "uniform", or "4MHz"
Type "help logic logic" for list of logic configuration parameters
Type "help logic" for command description
Limitations of the digital sampling speeds is a long and unhappy topic. See Why so slow?, below.
$1.50: help logic duration=
Help for parameter "duration=" (e.g. "logic logic duration="):
- Sampling time limit
Current value: infinite
Valid values: floating point number with "y", "d", "our", "min", "s", "ms",
"us", "μs", or "ns" suffix in range [910.222μs ... 59.6514s], or
"infinite"
Type "help logic logic" for list of logic configuration parameters
Type "help logic" for command description
Note the funky our abbreviation for “hour” in the mandatory units suffix for time values. Units are required for all time and time-or-frequency parameters (see below for one of many examples of the latter). The rationale is that hour is very rarely used while Hz is very common – implementing our instead of hour avoids having to explicitly type “hz” vs “ho” to disambiguate between the two in abbreviations and TAB completion. 17
$1.50: help logic edges=
Help for parameter "edges=" (e.g. "logic logic edges="):
- Maximum number of digital samples (including extra timing samples at c. 4Hz)
Current value: unlimited
Valid values: "unlimited" or integer in range [0 ... 65535]
Type "help logic logic" for list of logic configuration parameters
Type "help logic" for command description
$1.50: help logic code-mem=
Help for parameter "code-mem=" (e.g. "logic logic code-mem="):
- Sampling code memory bank. See "help logic logic" and
https://github.com/thanks4opensource/buck50/#flash_vs_ram
Current value: flash
Valid values: "ram" or "flash"
Type "help logic logic" for list of logic configuration parameters
Type "help logic" for command description
Sampling code can be run either directly from flash memory, or copied to RAM and executed there. Current tests show flash being faster despite generally accepted wisdom to the contrary, so there is little reason to use the code-mem=ram option (it also slightly reduces available sample memory). See below for more details.
$1.50: help logic autodump=
Help for parameter "autodump=" (e.g. "logic logic autodump="):
- Automatically (CAUTION!) do "dump" command after completion. See "CAUTION!" in
"help dump auto-digital."
Current value: enabled
Valid values: "enabled" or "disabled"
Type "help logic logic" for list of logic configuration parameters
Type "help logic" for command description
oscope command
The oscope command implements a primitive two channel digital storage oscilloscope. Bandwidth, sampling rate, and particularly sample storage depth are limited.
$1.50: help oscope
Help for command "oscope":
Primitive DSO (digital storage oscilloscope)
- samples one or two analog channels chosen from ports PB0...PB7
- primary/trigger channel: "trgr-chnl="
- second channel: "scnd-chnl=", (set to "none" for single channel operation)
- triggered at specified level (with hysteresis) and slope
. see "help oscope trigger=" and "help oscope slope="
. hysteresis implemented due to ADC conversion noise (otherwise slowly rising
or falling signals will trigger near level regardless of "slope=" setting)
(as noise dithers around level)
. trigger when signal rises above level after first falling below level minus
hysteresis if "slope=positive"
. trigger when signal falls below level after first rising above level plus
hysteresis if "slope=negative"
. use "slope=disabled" to trigger immediately without regard to level
- samples recorded continuously at rate specified by "s/h+adc="
- sampling continues number specified by "samples=" parameter
. triggering and/or sampling interruptible via <ENTER> key
- on-board user LED off, and output port PB13 toggles at c. 4 Hz, during
triggering and sampling
- Use "dump" command to upload, print, save, and/or view samples.
- See "help reset ganged=" and "help reset ext-trig" for external/sync'd
triggering.
Command usage:
oscope [<parameter>=<value> ...] [<action>] [<configuration>
<parameter>=<value ...] [<action>]
Configurations (primary="oscope"):
oscope, adc0, adc1, adc2, adc3, adc4, adc5, adc6, adc7
Type "help oscope <configuration>" for configuration description, parameters,
and actions
Type "help oscope <configuration> <parameter>" for parameter description
oscope configuration
$1.50: help oscope oscope
Help for configuration "oscope" (e.g. "oscope oscope"):
Analog DSO (digital storage oscilloscope) parameters
Command/configuration usage:
oscope [<parameter>=<value> ...]
Parameters:
samples= Maximum number of single or dual analog samples
trgr-chnl= Port number PA<x> (x=0...7) of trigger/first/sin...
scnd-chnl= Port number PA<x> (x=0...7) of second channel, o...
trigger= Triggering scaling, level, and hysteresis. Level...
slope= Analog triggering slope (or "disabled" for immed...
s/h+adc= Sampling rate, sample and hold time plus analog ...
time-scale= Scale factor for time values in "dump" command o...
printf= C format string for time values in "dump" comman...
autodump= Automatically do "dump" command after completion
Configuration "oscope" used by commands:
configure
oscope
dump
Type "help oscope" for command description
Type "help oscope oscope <parameter>" for parameter description
oscope parameters
$1.50: help oscope samples=
Help for parameter "samples=" (e.g. "oscope oscope samples="):
- Maximum number of single or dual analog samples
Current value: unlimited
Valid values: "unlimited" or integer in range [0 ... 65535]
Type "help oscope oscope" for list of oscope configuration parameters
Type "help oscope" for command description
$1.50: help oscope trgr-chnl=
Help for parameter "trgr-chnl=" (e.g. "oscope oscope trgr-chnl="):
- Port number PA<x> (x=0...7) of trigger/first/single channel
Current value: 0
Valid values: decimal or hex integer in range [0 ... 7]
Type "help oscope oscope" for list of oscope configuration parameters
Type "help oscope" for command description
$1.50: help oscope scnd-chnl=
Help for parameter "scnd-chnl=" (e.g. "oscope oscope scnd-chnl="):
- Port number PA<x> (x=0...7) of second channel, or "none" for single channel
sampling
Current value: none
Valid values: "none" or integer in range [0 ... 15]
Type "help oscope oscope" for list of oscope configuration parameters
Type "help oscope" for command description
$1.50: help oscope trigger=
Help for parameter "trigger=" (e.g. "oscope oscope trigger="):
- Triggering scaling, level, and hysteresis. Level and hysteresis in scaling
(low-to-high) units/range.
Current value: 0:3.3:1.65:0.05
Valid values: <four ":"-separated floating point values>
(<low>:<high>:<level>:<hysteresis>)
Type "help oscope oscope" for list of oscope configuration parameters
Type "help oscope" for command description
As noted in help oscope above, hysteresis is implemented due ADC input and conversion noise. If slope=positive, the signal must fall to level - hysteresis and then rise back above level to trigger. If slope=negative, above level + hysteresis then below level. Without hysteresis or with it set too low, slowly changing signals will trigger immediately as they approach level regardless of slope (as noise sends the measurement above and below the level value).
Level and hysteresis are expressed in trigger= low-to-high units/range.
$1.50: help oscope slope=
Help for parameter "slope=" (e.g. "oscope oscope slope="):
- Analog triggering slope (or "disabled" for immediate start of sampling)
Current value: positive
Valid values: "disabled", "positive", or "negative"
Type "help oscope oscope" for list of oscope configuration parameters
Type "help oscope" for command description
$1.50: help oscope s/h+adc=
Help for parameter "s/h+adc=" (e.g. "oscope oscope s/h+adc="):
- Sampling rate, sample and hold time plus analog conversion time. Limited set
of values supported by hardware.
Current value: 239.5+12.5@12MHz->47.6kHz
Valid values: "1.5+12.5@12MHz->857kHz", "7.5+12.5@12MHz->600kHz",
"13.5+12.5@12MHz->462kHz", "28.5+12.5@12MHz->293kHz",
"41.5+12.5@12MHz->222kHz", "55.5+12.5@12MHz->176kHz",
"71.5+12.5@12MHz->143kHz", or "239.5+12.5@12MHz->47.6kHz"
Type "help oscope oscope" for list of oscope configuration parameters
Type "help oscope" for command description
$1.50: help oscope time-scale=
Help for parameter "time-scale=" (e.g. "oscope oscope time-scale="):
- Scale factor for time values in "dump" command output
Current value: 1000000.0
Valid values: <any floating point number>
Type "help oscope oscope" for list of oscope configuration parameters
Type "help oscope" for command description
$1.50: help oscope printf=
Help for parameter "printf=" (e.g. "oscope oscope printf="):
- C format string for time values in "dump" command
Current value: %10.2f μs
Valid values: <"printf"-style format string with </any></hysteresis></level></high></low></four></x></x></parameter></x></x></value></parameter></parameter></configuration></configuration></value></parameter></configuration></action></value></parameter></enter></parameter></value></parameter></parameter></action></value></parameter></enter></filename></filename></filename></x></any></action></parameter></action></value></parameter></tab></parameter></configuration></configuration></value></parameter></configuration></action></value></parameter></line></ctrl></ctrl></ctrl></down-arrow></ctrl></up-arrow></ctrl></end></ctrl></home></delete></backspace></ctrl></right-arrow></ctrl></left-arrow></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></tab></command></parameter></configuration></command></configuration></command></parameter></command></command></configuration></value></parameter></action></command></value></parameter></action></configuration></value></parameter></action></command></tab></tab></tab></tab></tab></tab></tab></tab></tab></configuration></value></parameter></action></command></value></parameter></action></configuration></value></parameter></action></command></tab></tab></tab></tab></command></enter></enter></tx></rx></slave></enter></enter></enter></enter></two></enter></enter></enter></enter></enter></all></all></all></http:></https:>
README 内容过长,已截取前 64 KB。完整内容请前往 GitHub 仓库查看。
评论