Fun with Digital Dice on Forth

Mecrisp Forth Across to MSP430G2230

5 min readJan 14, 2024

1. Forth Tethered Cross-compiler

Forth as an interactive development environment is ideal for embedded MCU prototyping.

However for limited resource MCUs, such as MSP430G2 series, there isn’t enough RAM/Flash resource to host a full-fledged Forth system. Fortunately, the tethered Forth, like Mecrisp Across comes to rescue.

Mecrisp (Forth) Across has the benefit of both an interactive Forth development environment, since the host system is still running Forth. At the same time, the host emulates GPIOs on MSP430 via SWDIO/SWCLK connections to the target system, just like a good old embedded debugger; also once the Forth code has been developed and tested, the native binary code for MSP430 is generated on the host and directly flashed into that MCU over the same SWDIO/SWCLK connections.

Now the code running on the MSP430 target is completely stand-alone, which contains no Forth elements at all.

For a better understanding of Mecrisp Across, please visit Terry Porter’s unofficial documentation (link).

2. Digital Dice Project

It all began when I used to have a small table to play board games with friends. Often when a pair of dice were rolled, they either ended up on the floor or knocked down game pieces on the board.

So why not to make a pair of digital dice for each player? The idea is to make a minimal system with LEDs and a push button. With the push of a button, the system will simulate a physical dice rolling, by showing some “animations”, after which the final dice pattern will light up by LEDs representing a dice value from 1 to 6.

This digital dice project also happened to be during the COVID-19 era when only MSP430G2230 (8-PIN SOIC) MCUs were still available to choose from due to the components shortage.

The minimal hardware system also benefits from Forth’s minimal footprint. In this case, the MSP430 cross-compiling and emulation brought by Mecrisp Across (Forth) is essential to get the hardware/software prototyped quickly.

3. MSP430G2230 (Target) and STM32F407 (Host) System

digital dice with MSP430G2230 schematic

A few words about the schematic:

  • MCU surrounding circuitry is minimal, just an external pull-up resistor and a power supply by-pass capacitor
  • six LEDs are charlieplexed onto three GPIOs of MSP430G2230
  • one push button takes the only remaining GPIO

To program and Forth with the MCU, you need both MSP430G2230 (as target) and a STM32F407 discovery board (as host). link to order STM32F407 from digikey.

1. Flash STM32F407 with Mecrisp Across bin file (currently v0.10)

2. Connect MSP430 programming/emulation header pins, in addition to VCC and GND:

  • SBWTDIO/RST — — PC-8
  • SBWTCK/TEST — — PC-9

to the STM32F407 GPIO pins. Note that on STM32F407 pins “5V” and “PA9” (VBUS sense) are wired together, and the micro-USB (not mini-USB) connection to the computer will instance a VCP.

3. From there, a Forth interactive session in a terminal window (such as Tera Term) can start using that serial port connection (VCP).

4. Interactive Forth Words

Forth words are developed interactively, and essentially from bottom up.

  1. In the serial terminal window: drop into MSP430 target emulation

2. light up single LED1 to LED6 (refer to schematic above)

: led_a_b ( D1_high D2_low -- ) over or P1DIR c! P1OUT c! ; 

: led1 ( -- ) 4 128 led_a_b ; \ P1.2 P1.7
: led2 ( -- ) 32 4 led_a_b ; \ P1.5 P1.2
: led3 ( -- ) 32 128 led_a_b ; \ P1.5 P1.7
: led4 ( -- ) 4 32 led_a_b ; \ P1.2 P1.5
: led5 ( -- ) 128 32 led_a_b ; \ P1.7 P1.5
: led6 ( -- ) 128 4 led_a_b ; \ P1.7 P1.2

: led_all_off ( -- ) 0 P1DIR c! ;

3. show dice dot pattern with charlieplexing

\ delay time, assuming 8 MHz system clock
: us 0 ?do i i + drop i i + drop loop inline ;
: ms 0 ?do 998 us loop ;

: .dice ( n -- ) \ display dice number n = 1 to 6 with charlieplexing
1 of 2 0 do led3 20 ms led_all_off loop endof
2 of 2 0 do led1 5 ms led6 5 ms led_all_off 10 ms loop endof
3 of 2 0 do led3 5 ms led2 5 ms led1 10 ms led_all_off loop endof
4 of 2 0 do led4 5 ms led3 5 ms led1 5 ms led6 5 ms led_all_off loop endof
5 of 2 0 do led3 3 ms led1 3 ms led4 3 ms led6 3 ms led5 3 ms led_all_off loop endof
6 of 2 0 do led3 3 ms led2 3 ms led1 3 ms led4 3 ms led5 3 ms led6 3 ms led_all_off loop endof
endcase ;

4. random number generator to simulate dice rolling

1 variable dice-num-nxt
7 variable seed

: random ( -- x ) \ generate a random number
seed @
dup 7 lshift xor
dup 9 rshift xor
dup 8 lshift xor
dup seed ! ;

: roll-dice ( -- ) \ roll the dice number from 1 to 6
random abs 6 mod 1+ .dice ;

5. check button press

: check_btn ( -- u )  \ p1.6 is pulled high, low when pressed ; u = 1 when pressed ; also update dice-num-nxt when pressed
P1IN c@ 64 and 0= if random dice-num-nxt ! 1 else 0 then ;

6. the main/entry code on the target to tie everything together

: main ( -- ) 
8MHz \ initialize
begin check_btn 0= if \ button not pressed
dice-num-nxt @ abs 6 mod 1+ .dice
else \ button pressed
again ;

Each section of the code is very short and can be tested before moving up to the next level.

7. The final step: move to host, cross-compile and flash the image onto the target. The resulting binary image can be saved into a .hex file as well. The .hex file can be used with a regular MSP430 Uniflash software to provision more MCUs.

$fffe vector main crosscompile flashtarget

5. Tindie Store

Here is a Tindie store link to get your hands on the digital dice hardware.

Once you connect MSP430 (need some pin header soldering) to STM32F407, using the Mecrisp Across cross compiler, you can quickly develop your own code in Forth on this piece of minimal MCU hardware.

Have fun !




memento of electronics and fun exploration for my future self