Features
Calculator
- RPN
- Keyboard layout similar to HP 42
- Stack 64 elements
- 10 registers
- 3 top elements (x, y, and z) are displayed
- Floating-point
- Single precision floating-point IEEE.754
- Elementary arithmetic
- trigometric and exponential functions
- Display modes: fixed, scientific, engineering (metric unit prefix)
- Integer
- Hex, decimal, octal, and binary number base
- Signed (2's complement) and unsigned numbers
- Elementary arithmetic
- logical and shift operations
- Forth programmable
Standard Mecrisp-Cube Forth Features
- 63 KiB RAM dictionary
- 128 KiB Flash Forth dictionary
- 50 KiB for C code
- Serial console USB CDC / BLE Terminal-IO
- Filesystem (FAT), Internal Flash drive 0:, 384 KiB
- Integration in STM32 Cube Ecosystem.
- Create C code from CubeMX for internal peripherals and use it in Forth
- Calling C Functions from Forth and vice versa
- RTOS
- Forth as CMSIS-RTOS thread.
- CMSIS-RTOS API to use FreeRTOS from Forth.
- Buffered terminal I/O (5 KiB buffer for UART Rx). Interrupt driven and RTOS aware, key and emit block the calling thread.
- USB
- USB-CDC for serial communication via USB, redirect console I/O like cdc-emit, cdc-key
- USB-MSC Device: The USB mass storage device class (also known as USB MSC or UMS). You can use your Forth system as a flash drive (also thumb drive [US], memory stick [UK], and pen drive/pendrive elsewhere)
- BLE 5.0 GAP Peripheral Role (STM32WB)
- DIS Device Information Service
- HRS Heart Rate Service (heart rate depends on A0 for Nucleo and A2 for Dongle)
- CRS Cable Replacement Server service (proprietary service from STM, similar to Classic Bluetooth SPP). Redirect console I/O like crs-emit, crs-key.
- Floating-Point Unit FPU
- Support for the floating-point unit FPU, single precision for M4F MPUs and double precision for M7 MPUs
- CMSIS-DSP
- vi editor
- Real Time Clock RTC
- Watchdog
- Assertion and Logging
How to Use the Calculator
There are a few differences in operation compared to HP calculators.
This applies in particular to entering numbers.
Floating-point numbers must have an exponent e.g. 100e
, 3.14e
, 2.72e0
, -10e-12
,
or end in a metric unit prefix like 10k
, 270n
, 3.3u
.
ENTER reads the number and push it onto the stack. An ENTER without a number do not duplicate the x register (top of stack). If you want to duplicate, you have to use DUP. A stack element is always 32 bit, the content can be float or integer. You have to convert float to integer F→S if you want to use a float number in the integer mode or vice versa S→F.
Warning! If you enter a number with a . but without an exponent e.g.12.34
Forth interprets this as a double cell integer and put0
to the x register and1234
to the y register.
R↓ is actually the Forth word rot
, z→y, y→x, x→z.
STO and RCL takes x as register index 0..9.
Caution! If there is an error, the entire stack will be erased. No error message is showed on display, but you can see the error message in the terminal.
How it Works
The idea behind this is to use as much of the Forth interpreter as possible.
There is already a data stack, but with 64 elements and not only x, y, z, and t registers.
The calculator keyboard acts as an ordinary keyboard (terminal), but one key can send several characters (string),
e.g. the key COS sends a string " fcos\n"
. The interpreter executes the float cosinus on the top of the stack.
After the successful execution of a line, the stack content is then shown on the display.
Digits (0..9, A..F) are forwarded to the display and are interpreted after hitting the ENTER key.
If you connect a terminal and hit the TERM key, you can see how the interpreter works.
For implementation details see
About Forth
Forth is an interactive and extensible language, with built-in lexical analysis (tokenizer, parser) and interpreter/compiler, needs less than 20 KiB Flash and 4 KiB RAM, unbelievable for a self-contained (self-hosted) system.
Forth is perfect for embedded systems where some sort of user interactivity like CLI and extensibility (at runtime) are needed.
C & Forth in the 21st Century. C and Forth are both about 50 years old. The combination of the strength of this two worlds results in a powerful system that outperforms other much newer systems like Python. Good design withstands the test of time.
The goal of Mecrisp-Cube is to be a complete Forth programming environment for STM32 MCUs. There are three flavors (branches) available:
- STM32WB55 (
master
branch) for the STM32WB55 Nucleo Board and dongle and variants for the Firefly Dev Board (firefly
), Katydid Dev Board (katydid
), WB5M Discovery (WB55M
) and the STM32WB Feather (WBfeather
). In work Flipper Zero (Flipper
): - STM32F405 (
F405
) for Adafruit's Feather STM32F405. - STM32H74x (
H743
) for STM NUCLEO-H743ZI and Arduino Portenta H7 Development Board.
May the Forth Be With You!
Use the Terminal (USB CDC)
Connect the WB55 Dongle USB to the PC. Start the terminal emulator application on the PC.
Check for the serial communication port (e.g. for Linux /dev/ttyACM0
).
With tio
you can list available devices, look for 4TH devices
$ tio -l Device TID Uptime [s] Driver Description ----------------- ---- ------------- ---------------- -------------------------- /dev/ttyACM0 38E5 8567.913 cdc_acm ST-Link VCP Ctrl /dev/ttyACM1 PESx 873.742 cdc_acm 4TH CDC By-id -------------------------------------------------------------------------------- /dev/serial/by-id/usb-spyr.ch_4TH_Calculator_43003F0013504D5943373420-if00 /dev/serial/by-id/usb-STMicroelectronics_STLINK-V3_002700073156501320323443-if02 By-path -------------------------------------------------------------------------------- /dev/serial/by-path/pci-0000:00:14.0-usb-0:2:1.0 /dev/serial/by-path/pci-0000:00:14.0-usb-0:1:1.2
I set the terminal configuration (e.g. putty) to
- Implicit CR in every LF
- Local echo: off
- Local line editing: off
- Keyboard Backspace: Control-H
- Keyboard Function: Keys VT100
- Remote character set: CP850
With tio
tio --map ICRNL,INLCRNL /dev/serial/by-id/usb-spyr.ch_4TH_Calculator_43003F0013504D5943373420-if00
The greeting screen should apear after pushing the TERM button on the Calculator:
4TH Calculator -------------- Mecrisp-Cube 1.6.0 deb for STM32WB Nucleo, 63/128 KiB RAM/FLASH dictionary (C) 2024 peter@spyr.ch * Mecrisp-Stellaris RA 2.5.4 by Matthias Koch. * Firmware Package STM32Cube FW_WB V1.17.3, BLE Stack 5.3 (C) 2023 STMicroelectronics * CMSIS-RTOS V2 FreeRTOS wrapper, FreeRTOS Kernel V10.3.1 (C) 2020 Amazon.com * FatFs for internal flash and microSD - Generic FAT fs module R0.12c (C) 2017 ChaN * tiny vi - part of BusyBox (C) 2000, 2001 Sterling Huxley * TinyUSB CDC, MSC v0.16.0 (C) 2023, hathach (tinyusb.org)
Use the interpreter (reverse polnish notation, like HP calculators):
23 5 / .
This looks like this on your terminal (bold is the Forth answer):
23 5 / .[CR] 4 ok.
The ok.
is the Forth prompt and apears at the end of the line (Forth does it differently, like most things ;-).
If you don't like it, change it.
[CR]
is the Enter-key.
The display on the calculator is also updated. The display number mode is probably FLOAT, to see decimal values, hit the DEC button.
Type in your first Forth program (create a word in the RAM dictionray):
: hello ." World" ;
and execute the the program
hello
again the terminal output:
: hello ." World" ;[CR] ok. hello[CR] World ok.
The program hello
ist not persistent, after power cycle or even reset the RAM dictionray is erased.
But it is easy to add a word to the Flash dictionray:
compiletoflash : hello ." World" ;
The program source is not saved, only the executable machine code is compiled into the flash.
You can use the built-in editor vi and save your source to the
filesystem either on internal flash drive 0:
or on the microSD card drive 1:
.
The following part is only for people who are interested how Forth works and have knowledge about
the ARM Assembler.
There is a built-in disassembler (consider the machine code B500
is 16 bit hex number, but it is stored
as 00
B5
):
see hello 08043558: B500 push { lr } 0804355A: F7BF bl 08002BE4 --> .' World' 0804355C: FB43 0804355E: 5705 08043560: 726F 08043562: 646C 08043564: BD00 pop { pc }
The dictionray entry looks like this (you can see the 'hello' and the string constant 'World'):
$08043558 10 dump 08043550 : 00 00 05 68 65 6C 6C 6F 00 B5 BF F7 43 FB 05 57 | ...hello ....C..W | 08043560 : 6F 72 6C 64 00 BD 00 00 FF FF FF FF FF FF FF FF | orld.... ........ |
The compiled word hello
needs only 14 bytes in the dictionary.
Buttons, LED
Special Functions on Startup
- SW1 do not include
0:/etc/rc.local
on startup
LEDs as Status Indicator
The LEDs on the dongle displays the status
- Green USB enumerated
- Red Error occured
- Blue BLE connected
- flashing Red "disk" (serial flash or SD) write operation
- flashing Yellow "disk" (serial flash or SD) read operation
Acknowledgments
- http://mecrisp.sourceforge.net/ Original Mecrisp project, Matthias Koch
- https://mecrisp-stellaris-folkdoc.sourceforge.io/ Mecrisp Stellaris Unofficial UserDoc, Terry Porter