Operation

Manipulate Numbers

12345 234 / . 52 ok.

Turn on a LED

Unlike the MSP-EXP430G2 Board in this picture I’m using a MSP430F2013 Target chip which has only 14 pin so the chip ends on the dotted white line in the above picture.

Nevertheless the Target variant makes no difference here and with the on board RED LED connected to P1.0 and the Green LED connected to P1.6 this code will turn them on and off.

$00 p1out c!                        \ Zero all bits of P1
$41 p1dir c!                        \ Initialization; Set P1,1 and P1,6 as outputs
: off 0 p1out c! ;                  \ Turn off  P1: bits 0 - 15
: red 1 p1out c@ or p1out c! ;      \ Turn on RED led at P1:0
: green $40 p1out c@ or p1out c! ;  \ Turn on GREEN led at P1:6 ($40 binary = 1000000 )

Typing “red” will make the red led turn on, “green” will make the green led turn on, without affecting the red led. Typing “off” turns all leds off.

What is happening ?

The terminal is talking to the TM4C1294 Tiva Connected Launchpad, which is compiling code and running it on the MSP430F2013 Target chip via JTAG, transparently to us.

It is so fast and smooth it seems as tho the terminal is connected to the MSP430F2013 directly, but that will never work, can you guess why ?

The MSP430F2013 has only 2KB of Flash, and a Mecrisp Binary is at least 11KB, so it would never fit!

Blinky

This blinky.fs will blink the red and green leds 10 times and then stop, to allow proceeding to the nest stage.

Enter the following code into the terminal, copy and paste each line into Picocom, or simply upload blinky.fs via Picocom with :

Action Command Comments
FILE UPLOAD <CTL> A S blinky.fs (this command has TAB file completion).
new
+jtag
target

$00 p1out c!
: off ( -- ) 0 p1out c! ;
: red ( -- ) 1 p1out c@ or p1out c! ;
: green ( -- ) $40 p1out c@ or p1out c! ;
: delay ( -- ) 8000 0 do loop ;
: blink ( -- ) 8mhz $41 p1dir c! 10 0 do red delay off delay green delay off delay loop ;

Now type ‘blink’ to start the Blinky which will stop blinking after 10 blinks of each led.

See The Compiled Words

While in Target Mode, the contents are in Forth, rather than Machine Code

see off
: off
00006394 : 0000 : $00000000
000063A0 : 0000 : $00000021
000063AC : 0000 : c!
000063B8 : 0000 : ;
ok.

see red
: red
000063FC : 0000 : $00000001
00006408 : 0000 : $00000021
00006414 : 0000 : c@
00006420 : 0000 : or
0000642C : 0000 : $00000021
00006438 : 0000 : c!
00006444 : 0000 : ;
ok.

see green
: green
0000648C : 0000 : $00000040
00006498 : 0000 : $00000021
000064A4 : 0000 : c@
000064B0 : 0000 : or
000064BC : 0000 : $00000021
000064C8 : 0000 : c!
000064D4 : 0000 : ;
ok.

see delay
: delay
0000651C : 0000 : $00001F40
00006528 : 0000 : $00000000
00006534 : 0000 : swap
00006540 : 0000 : >r
0000654C : 0000 : >r
00006558 : 0000 : <--
00006590 : 0000 : r>
0000659C : 0000 : $00000001
000065A8 : 0000 : +
000065B4 : 0000 : r@
000065C0 : 0000 : >r
000065CC : 0000 : dup
000065D8 : 0000 : r>
000065E4 : 0000 : swap
000065F0 : 0000 : >r
000065FC : 0000 : =
00006608 : 0000 : 0-Branch $00006558
00006614 : 0000 : r>
00006620 : 0000 : drop
0000662C : 0000 : r>
00006638 : 0000 : drop
00006644 : 0000 : ;

Compile and Flash to Target

This process will flash the Machine Code Image to the Target, which will run the Blinky program and flash the LEDS 10 times every time power is applied or the chip is reset, in other words it is now standalone and operates independently of the Host TM4C1294 Tiva Connected Launchpad

Note

The Standalone Blinky runs about 25 times faster than it did under Mecrisp-Across.

host
$FFFE vector blink crosscompile flashtarget -jtag run

Speicherbedarf Flash ohne Vektortabelle 124 Bytes.
Speicherbedarf RAM ohne Stacks 0 Bytes.
Zahl der benötigten Pässe: 1
ok.

English Translation

\ compile and flash to target
host
$FFFE vector b crosscompile flashtarget -jtag run

memory requirements Flash without a vector table 124 Bytes.
memory requirements RAM without Stacks 0 Bytes.
Number of required passes: 1
ok.

What has the Compiler Done ?

t-listing

: dup ( Primitive ) ;
: swap ( Primitive ) ;
: drop ( Primitive ) ;
: >r ( Primitive ) ;
: r@ ( Primitive ) ;
: r> ( Primitive ) ;
: + ( Primitive ) ;
: or ( Primitive ) ;
: = ( Primitive ) ;
: c@ ( Primitive ) ;
: c! ( Primitive ) ;

: off
00006394 : F800 : $00000000
000063A0 : F800 : $00000021
000063AC : F800 : c!
000063B8 : F804 : ;

: red
000063FC : F83A : $00000001
00006408 : F83A : $00000021
00006414 : F83A : c@
00006420 : F83A : or
0000642C : F842 : $00000021
00006438 : F842 : c!
00006444 : F846 : ;

: green
0000648C : F856 : $00000040
00006498 : F856 : $00000021
000064A4 : F856 : c@
000064B0 : F856 : or
000064BC : F860 : $00000021
000064C8 : F860 : c!
000064D4 : F864 : ;

: delay
0000651C : F806 : $00001F40
00006528 : F806 : $00000000
00006534 : F806 : swap
00006540 : F806 : >r
0000654C : F806 : >r
00006558 : F80C : <--
00006590 : F80C : r>
0000659C : F80C : $00000001
000065A8 : F80C : +
000065B4 : F80C : r@
000065C0 : F80E : >r
000065CC : F80E : dup
000065D8 : F80E : r>
000065E4 : F80E : swap
000065F0 : F80E : >r
000065FC : F80E : =
00006608 : F80E : 0-Branch $00006558
00006614 : F812 : r>
00006620 : F812 : drop
0000662C : F812 : r>
00006638 : F812 : drop
00006644 : F812 : ;

: blink
0000668C : F822 : $000010FD
00006698 : F822 : c@
000066A4 : F822 : $00000057
000066B0 : F822 : c!
000066BC : F828 : $000010FC
000066C8 : F828 : c@
000066D4 : F828 : $00000056
000066E0 : F828 : c!
000066EC : F82E : $00000041
000066F8 : F82E : $00000022
00006704 : F82E : c!
00006710 : F834 : $0000000A
0000671C : F834 : $00000000
00006728 : F834 : swap
00006734 : F834 : >r
00006740 : F834 : >r
0000674C : F83A : <--
00006784 : F83A : red
00006790 : F846 : delay
0000679C : F84E : off
000067A8 : F852 : delay
000067B4 : F856 : green
000067C0 : F864 : delay
000067CC : F868 : off
000067D8 : F86C : delay
000067E4 : F870 : r>
000067F0 : F872 : $00000001
000067FC : F872 : +
00006808 : F872 : r@
00006814 : F876 : >r
00006820 : F876 : dup
0000682C : F876 : r>
00006838 : F876 : swap
00006844 : F876 : >r
00006850 : F876 : =
0000685C : F876 : 0-Branch $0000674C
00006868 : F87A : r>
00006874 : F87A : drop
00006880 : F87A : r>
0000688C : F87A : drop
00006898 : F87A : ;

: irq-$FFFE
000068E4 : F822 : blink
000068F0 : F87A : ;

ok.

Dissasemble the Generated Image

To inspect the generated Machine Code!

disimage
F800: 43C2  mov.b #0h, &21h
F802: 0021
F804: 4130  mov.w @r1+, r0

F806: 4307  mov.w #0h, r7
F808: 4038  mov.w #1F40h, r8
F80A: 1F40
F80C: 5317  add.w #1h, r7
F80E: 9807  cmp.w r8, r7
F810: 23FD  jnz F80C
F812: 4130  mov.w @r1+, r0

F814: 40B2  mov.w #5A80h, &120h
F816: 5A80
F818: 0120
F81A: 4031  mov.w #280h, r1
F81C: 0280
F81E: 4034  mov.w #260h, r4
F820: 0260
F822: 42D2  mov.b &10FDh, &57h
F824: 10FD
F826: 0057
F828: 42D2  mov.b &10FCh, &56h
F82A: 10FC
F82C: 0056
F82E: 40F2  mov.b #41h, &22h
F830: 0041
F832: 0022
F834: 4307  mov.w #0h, r7
F836: 4038  mov.w #Ah, r8
F838: 000A
F83A: 4259  mov.b &21h, r9
F83C: 0021
F83E: 431A  mov.w #1h, r10
F840: D90A  bis.w r9, r10
F842: 4AC2  mov.b r10, &21h
F844: 0021
F846: 1208  push.w r8
F848: 1207  push.w r7
F84A: 12B0  call.w #F806h
F84C: F806
F84E: 12B0  call.w #F800h
F850: F800
F852: 12B0  call.w #F806h
F854: F806
F856: 4257  mov.b &21h, r7
F858: 0021
F85A: 4038  mov.w #40h, r8
F85C: 0040
F85E: D708  bis.w r7, r8
F860: 48C2  mov.b r8, &21h
F862: 0021
F864: 12B0  call.w #F806h
F866: F806
F868: 12B0  call.w #F800h
F86A: F800
F86C: 12B0  call.w #F806h
F86E: F806
F870: 4137  mov.w @r1+, r7
F872: 5317  add.w #1h, r7
F874: 4138  mov.w @r1+, r8
F876: 9807  cmp.w r8, r7
F878: 23E0  jnz F83A
F87A: 3FFF  jmp F87A

Speicherbedarf Flash ohne Vektortabelle 124 Bytes.
Speicherbedarf RAM ohne Stacks 0 Bytes.
ok.

Generate a Hexdump

Save it to flash other Targets.

hexdump
:10F80000C2432100304107433840401F1753079837
:10F81000FD233041B240805A200131408002344003
:10F820006002D242FD105700D242FC105600F24056
:10F8300041002200074338400A00594221001A4380
:10F840000AD9C24A210008120712B01206F8B012F3
:10F8500000F8B01206F8574221003840400008D79F
:10F86000C2482100B01206F8B01200F8B01206F833
:10F870003741175338410798E023FF3FFFFFFFFF51
:10FFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFF14F803
:00000001FF
 ok.

Test The Target

The Target is now standalone, press the Target reset button, the leds blink 10 times each and will forever or until the Target has been flashed with another Forth program.

A Bonus Mecrisp-Across Feature

Now I’m going to swap the MSP430F2013 Target for a MSP430G2452.

Read the Target Word List

Note

+jtag reported the chip as a “2452”

new
+jtag
target
words

Address: 000061EC Flags: --- --- --- Name: hex.
Address: 000060F8 Flags: --- --- --- Name: hex-digit-emit
Address: 00005FD4 Flags: --- --- --- Name: .digit
Address: 00005F00 Flags: --- Inl --- Name: space
Address: 00005E30 Flags: --- Inl --- Name: cr
Address: 00005CC4 Flags: --- --- --- Name: uart-init
Address: 00005BFC Flags: --- Inl --- Name: emit
...
...
Address: 000002BC Flags: Imm --- 0-f Name: 1-foldable
Address: 0000027C Flags: Imm --- 0-f Name: 0-foldable
Address: 00000240 Flags: Imm --- 0-f Name: inline
Address: 00000200 Flags: Imm --- 0-f Name: immediate
ok.

Ok, that worked as expected, I read the MSP430G2452 Wordlist via the serial terminal.

What’s the bonus feature ?

The MSP430G2452 is a cheaper member of the MSP430 family with the following specifications but it lacks a important Peripheral used in all Forths, can you guess what it is ?

MSP430G2452 Specifications  
Low Supply Voltage Range: 1.8 V to 3.6 V
Ultra-Low Power Consumption  
Active Mode: 220 µA at 1 MHz, 2.2 V
Standby Mode: 0.5 µA  
Off Mode (RAM Retention): 0.1 µA
Five Power-Saving Modes  
Ultra-Fast Wake-Up From Standby Mode in less than 1 µs  
16-Bit RISC Architecture, 62.5-ns Instruction Cycle Time
Basic Clock Module Configurations  
Internal Frequencies up to 16 MHz With Four Calibrated Frequencies  
  • Internal Very-Low-Power Low-Frequency
 
  • (LF) Oscillator
 
  • 32-kHz Crystal
 
  • External Digital Clock Source
 
One 16-Bit Timer_A With Three Capture/Compare Registers  
Up to 16 Capacitive-Touch Enabled I/O Pins  
Universal Serial Interface (USI) Supporting SPI and I2C  
10-Bit 200-ksps Analog-to-Digital (A/D) Converter With Internal Reference, Sample- and-Hold, and Autoscan MSP430G2x52 Only
On-Chip Comparator for Analog  
Brownout Detector  
Serial Onboard Programming,  
  • No External Programming Voltage Needed,
 
  • Programmable Code Protection by Security
 
  • Fuse
 
On-Chip Emulation Logic With Spy-Bi-Wire Interface  

The MSP430G2452 has no **SERIAL UARTs!!**

There is no way for a serial terminal to actually talk to it, short of writing a assembly language Bit Banging USART and flashing the Target with it first. This MSP430G2452 is a brand new unused chip.

There is no need to prepare the chip before it can be used, unlike Arduino or Mecrisp, both of which must be pre-flashed with a bootloader or Forth Kernel respectively.

Mecrisp-Across is talking to the MSP430G2452 via JTAG, and our serial terminal is talking not to the Target, but to the Host, (which has already been mentioned), but it’s quite easy to overlook because the Mecrisp-Across serial terminal experience seems perfectly normal.

In fact, the terminal response is a lot faster than talking to a MSP430G2553 with a USART and running a pre-flashed 9600 Baud Mecrisp Forth which requires 11 KBytes of Flash and 512 bytes of Ram

And the Bonus Feature is ...

Mecrisp-Across can provide USART facilities on the HOST for MCU’s without a USART with the following command executed on the Host before switching to Target Emulation.

true hostterminal? !

Otherwise Words that use the Target USART such as

emit, key, cr and space

Won’t work until the Target is running standalone following the

$FFFE vector main crosscompile flashtarget -jtag run

command.

Printf()

Using “true hostterminal? !” I can create all kinds of debugging aids using Emit, key, cr and space words. I can do this in real or near real time (in the case of Mecrisp-Across) to debug my Forth programs like in the contrived example below on a (cheaper) Target chip with no USART:

: A? ( what is the value of variable A ? )  65 EMIT 61 EMIT A @ . cr ;

When “A?” is entered at the terminal, the following is returned:

A? A=100

Now What ?

Now you can write and debug your own programs in Forth and flash them to a target chip that is too small to run Mecrisp Forth.

The final outcome is a MSP430 chip ready for standalone (turnkey) operation with no license obligations.

Previous topic

Smallest Blinky, only 36 Bytes!

Next topic

Special Behaviour You Should Be Aware Of