\ MMT Source Code of Version 1.0 

: .MMT#   \ --   \  print version number 
  ." MMT Version 1.0 2014-11-19" ; 
\ ----------------------------------------------------------
\ Mini Multi Tool  4bit I/O "MMT4"
\ using 4e4th Release 0.34 on TI MSP430G2553 MCU LaunchPad
\ started: mka, 2014_10_26
\ Idea: Juergen Pintaske and his "swiss knife"

\ "Starting with Forth is hard work. Add a bit of fun 
\ and have something running immediately in Forth. 
\ Even without understanding it in the beginning.
\ This was our starting point for MMT." (JP)

\ ----------------------------------------------------------
\ Table of Contents
\ Defining the I/O for this application, basic definitions
  \ Device Pinout: MSP430G2553 20-Pin PDIP 
  \ Some scratch variables 
  \ Juggling nibbles for packing and unpacking into 16 bit 
  \ I/O initialisation, I/O words, test switches, time delays
\ Utilities for this MCU
  \ Square wave at P1.5 (Pin7) using timer TA0.0
  \ Midi tones B3 to B5, 2 octaves; pitch list, play a note
  \ PWM of 16KHz for 8MHZ DCO using timer TA0
  \ ADC - init ADC0 and ADC4, get ADC value
  \ Servos - position 4 servos using digital OUT, double function
  \ Initialisation of MMT4
\ Example Programs - using switches only
  \ EX0  - Leave demo loop, run Forth
  \ EX1  - Display IN at OUT
  \ EX2  - Display IN at OUT, set PWM-LED too
  \ EX3  - Falling edge detector (1)
  \ EX4  - Falling edge detector with tone (2)
  \ EX5  - Dance of 4 servos (test servos)
  \ EX6  - Servo follows analog input on pin ADC4
  \ EX7  - Get analog input from ADC channel 4
  \ EX8  - Audio visual display of ADC4 value
  \ EX9 - Play demo song
  \ DEMOLOOP - Select an example programm by its nummber.
\ More Example Programs - using serial interface to PC. 
  \ EX11 - Echo any key
  \ EX12 - Toggle OUT bits manually

\ ----------------------------------------------------------
\ History: 
\ 20141117: We are ready for a release - V10 
\ Added help lines to PC examples. 
\ Made MMT4 images. 
\ Split examples in MMT and PC part.
\ 20141109: Made duration of notes selectable. 
\ Use TONE@ TON+ now instead of NOTE in soem EXs. 
\ Better EX8, wait after output, not before.
\ Better visualisation of EX3 and EX4, LEDs switch.
\ Better EX2, no delay any more.
\ Renamed file to mmt4ue2.4th because this name was unique
\ while "swiss knife" and its abreviations are not.
\ Renamed S1 to S3 since S1=reset on MSP-LaunchPad.
\ Added: DEMOLOOP to select examples using S2 and S3 switches.
\ 20141103: Cleaning up examples, added another example.
\ 20141102: Added 2 servo examples.
\ 20141030: Added pulses for 4 servos to OUT.  
\ 20141029: Renamed demos to EXn.
\ Made some demos Pn.
\ Added: ADC 
\ 20141026: First test today.
\   Compiles in target without errors.
\   blocks with mk0 mark = tested ok on first glance ...
\   ... functioning, stack ok.
\   MYBONNIE is playing, no stack error - ok
\   PWM running, SWEEP is ok. 
\   I/O and nibbels working on variables.

\ Issues:
\ Glitches while setting upper nibble of P2 - fixed OUT! .
\ port name P2 is in conflict with example name P2 -
\ renamed examples to EXn. 
\ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
\ Start of Program MMT4 programmed in Forth 
\ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

\ This program uses some routines planned to help Learning 
\ for the next project: Learning Programming without PC.
\ And we use them here as an example of how to program the 
\ MSP430 Controller in Forth.
\ Add the 5 resistor LED combinations and the 
\ 3 switches to the 430 board or any type of breadboard
\ and run routines completely in the MSP430, 
\ using this program running on top of Forth 
\ either interfaced to a PC or some parts independent of the PC



\ Defining the I/O for this application

\ Device Pinout: MSP430G2553 20-Pin PDIP 
\ (TOP VIEW) 

\ VCC-----------------[01   20]---------------------VSS
\ (LED1 LP) AD0 P1.0--[02   19]--P2.6 OUT2 ------------
\ RXD-----------P1.1--[03   18]--P2.7 OUT3 ------------
\ TXD-----------P1.2--[04   17]--test -----------------
\ -----------S2 P1.3--[05   16]--RST  S1 --------------
\ ..........AD4 P1.4--[06   15]--P1.7 S3 ---------SPI* 
\ _-_-_-_-_-FRQ P1.5--[07   14]--P1.6 PWM LED2-LP SPI* 
\ ----------IN0 P2.0--[08   13]--P2.5 OUT1-------------
\ ----------IN1 P2.1--[09   12]--P2.4 OUT0-------------
\ ----------IN2 P2.2--[10   11]--P2.3 IN3--------------
\ * SPI optional.


\ P1.0 used as Input, later on as Analog Input 1
\ P1.1 RX and 
\ P1.2 TX are used as the serial interface to the PC
\ P1.3 used as S2 as on the TI Launchpad, 
\      internal pull-up resistor enabled
\ P1.4 used as Input, later on as Analog Input 2
\ P1.5 used as Output, later on to output
\      one of 16 frequencies with defined length
\ P1.6 Output, later on as Pulse Width Modulation output
\      just like a simple D/A Output
\ P1.7 Input S3, internal pull-up resistor enabled

\ All P2.x Inputs have internal resistor enabled, 
\ so open input means HIGH signal
\ P2.0 Input 0  
\ P2.1 Input 1  
\ P2.2 Input 2  
\ P2.3 Input 3  

\ P2.4 Output 0
\ P2.5 Output 1
\ P2.6 Output 2
\ P2.7 Output 3

 \ Yes, we downgraded from 16 bit to 4 bit IO - but the pin
 \ numbers were limited, and if you add a PC via USBtoTTL3.3V
 \  you can do more (within the memory constraints).



\ The MSP 430 will be rather fully used. 
\ So to save Program Space, the 4 Bit Nibbles are packed 
\ into 4x4 nibbles to be one Variable (16Bit cell).
\ This will save on RAM used.



\ Source code start ----------------------------------------
\ Some scratch variables 
\ IN  4 bit input, when used reflects status of 4 Input lines
\ F   4 bit value for tones
\ A   4 bit A register
\ B   4 bit B register
variable IFAB  \ define one variable with these 4 nibbles in it

\ W   4 bit W variable
\ X   4 bit A variable
\ Y   4 bit Y variable
\ Z   4 bit Z variable
variable WXYZ  \ define one variable with these 4 nibbles in it

\ A1  4 bit analog in channel 1
\ A2  4 bit analog in channel 2
\ P   4 bit pulse width modulated output 
\ O   4 bit output register
variable 12PO  \ define one variable with these 4 nibbles in it

: INITSV \ -- \ init these 3 scratch variables to 0
  0 IFAB !    0 WXYZ !    0 12PO ! ;   
initsv 

\ define a Word to show a cell at address unsigned   mk0
: ? ( adr -- )   @ u. ;  



\ juggling nibbles  
HEX 
: n0! \ n adr -- \ store nibble 0 to variable at address 
  >r r@ @ FFF0 and swap F and + r> ! ; 

: n1! \ n adr -- \ store nibble 1 to variable at address 
  >r r@ @ FF0F and swap F and 4 lshift + r> ! ; 

: n2! \ n adr -- \ store nibble 2 to variable at address 
  >r r@ @ F0FF and swap F and 8 lshift + r> ! ; 

: n3! \ n adr -- \ store nibble 3 to variable at address 
  >r r@ @ 0FFF and swap F and C lshift + r> ! ; 

: n0@ \ adr - n \ fetch nibble 0 of variable at address 
  @ 000F and ; 

: n1@ \ adr - n \ fetch nibble 1 of variable at address 
  @ 00F0 and 0004 rshift ; 

: n2@ \ adr - n \ fetch nibble 2 of variable at address 
  @ 0F00 and 0008 rshift ; 

: n3@ \ adr - n \ fetch nibble 3 of variable at address 
  @ F000 and 000C rshift ; 


\ As  a first step we have to define the relevant IO Bits
\ as Input (with enabling internal pull-up resistor)
\ or as output.
\ Here you can find the relevant memory mapped addresses
\ to set functionality, read Input Data, write Output Data
\ Some of the functions used are rather complex, 
\ so in the beginning we will test as Input and Output only, 
\ see separate Forth Code
\ for details, 
\ see 1 http://www.ti.com/product/msp430g2553
\ and 2 http://www.ti.com/product/MSP430G2553/technicaldocuments
\ and 3 http://www.ti.com/lit/ds/symlink/msp430g2553.pdf our reference
\ we plan to show page numbers, here in document 3 page 18 onwards


\ In 4e4th, P1 and P2 are already predefined 2constants.
HEX 
: INITIO \ -- \ I/O initialisation of MMT ports   mk0
\ mask adr op 
\       76543210 
[ bin ] 10011001 [ hex ] 0022 ( P1DIR ) cclr \ P1 INs 
[ bin ] 01100110 [ hex ] 0022 ( P1DIR ) cset \ P1 OUTs 
[ bin ] 10001000 [ hex ] 0024 ( P1IES ) cset \ falling edge detect
[ bin ] 00100000 [ hex ] 0026 ( P1SEL ) cset \ P1.5 sec func TA0.0 (FRQ) 
[ bin ] 10001000 [ hex ] 0027 ( P1REN ) cset \ pull-up selected 
[ bin ] 10000000 [ hex ] P1             cset \ P1.7 pullup enabled 
[ bin ] 00001111 [ hex ] 002A ( P2DIR ) cclr \ P2 INs 
[ bin ] 11110000 [ hex ] 002A ( P2DIR ) cset \ P2 OUTs 
[ bin ] 00001111 [ hex ] 002F ( P2REN ) cset \ P2 pullups selected 
[ bin ] 00001111 [ hex ] P2             cset \ P2 pullups enabled 
[ bin ] 11000000 [ hex ] 002E ( P2SEL ) cclr \ clear these bits to I/O 
; 
INITIO 



\ Basic I/O          mk0
HEX 
: OUT!  \ n -- \ write OUT to P2 upper nibble (4 LEDS) 
  04 lshift    \ move to n upper nibble
  0F or        \ keep input pullups set! 
  p2 c! ;      \ write port 

: OUT>  \ --   \ copy O to OUT!
  12PO n0@ out! ;  

: OUT   \ n --   \ save n to O-nibble and do OUT! too.
  12PO n0! out> ; 

: IN@ \ -- n \ read digital input pins, lower nibble of P2. 
  P2 1- c@ 000F and ; 

: IN  \ -- n  \ do IN, save n to I-nibble too.
  in@ 
  dup IFAB n3! ; \ copy to I-nibble of IFAB



\ output a nibble to terminal
HEX
: 4#  \ n --  \ display 4 digits unsigned 
  <#  00 # # # #   #> TYPE SPACE ; 
: 2#  \ n --  \ display 2 digits unsigned 
  <#  00 # #    #> TYPE SPACE ; 



\ test falling edge at switch S3 and S2      mk0
023 constant P1IFG
: S3?  080 P1IFG cget ;   \ -- f   \ set on edge event
: S2?  008 P1IFG cget ;   \ -- f   \ set on edge event
: S3-  080 P1IFG cclr ;   \ --   \ reset edge event flag
: S2-  008 P1IFG cclr ;   \ --   \ reset edge event flag



\ Delays    mk0
\ 1MS is predefined in 4e4th. Its an empty loop,
\ predefined for MCUs running with 8Mhz DCO = default.
\ Use Forth word MS to make any ms delay. 
\ Example: 
\ decimal 10 ms   \ delay of 10 miliseconds.

DECIMAL
: 1SEC  \ -- \ delay of one second
  1000 ms ;

: SECS  \ n --   \ delay of n seconds      mk0
  0 DO 1sec LOOP ;  \ put the seconds value before the SECS word



\ ----------------------------------------------------------
\ Utilities for this MCU
\ ----------------------------------------------------------

\ ----------------------------------------------------------
\ Tones and notes

HEX
\ Output a square wave at P1.5 (pin 7) using timer TA0.0      mk0

\ Use P1.5 as timer TA0.0 ouput.
\ This is done by setting P1.5 to its second function.
\ Then set and start Timer.
\ Note: In second function, this pin is no longer 
\ a general purpose I/O pin. It is switched to another I/O
\ mode called 'second function' of the pin.

: P15SEC   \ set P1.5 to its second function  
  020 dup p1 1+ cset  026 cset ;   

: P15IO     \ set back P1.5 to its general GPIO function
  020 026 cclr  020 041 cclr ;   

: TON-  \ --    \ Tone off.
  00 0160 !   \ stop timer
  p15io         \ P1.5 back to I/O 
  20 p1 cclr  ; \ shut down current through speaker.

: TON+ \ n --   \ start timer-A with interval n
       \ MSP430G2553, 8Mhz DCO and SMCLK /2
  p15sec        \ init pin
  0080  0162 !  \ CCTL0  set timer output mode
  ( n ) 0172 !  \ CCR0   set interval
  0254  0160 !  \ CTL    start timer clock, mode and divider
  ;

\ Midi tones B3 to B5, 2 octaves; pitch list for TON+   mk0
DECIMAL  
IHERE  
0000 i,  \ no tone
7962 i,  \ B3 
7515 i,  \ C4 
6695 i,  \ D4 
5965 i,  \ E4 
5630 i,  \ F4 
5016 i,  \ G4 
4469 i,  \ A4 
3981 i,  \ B4 
3758 i,  \ C5 
3348 i,  \ D5 
2983 i,  \ E5 
2815 i,  \ F5 
2508 i,  \ G5 
2235 i,  \ A5 
1991 i,  \ B5 
constant TONELIST

HEX
: TONE@   \ i -- n   \ get pitch using index i 
  cells tonelist + @ ;

: NOTE   \ i d --   \ play note i of duration d
  swap   tone@ ton+   ms ton-  ;

: PAUSE  \ q --   \ play pause (quiet) of duration q
  ton-  ms ;  \ 

\ see example melody below



\ ----------------------------------------------------------
\ PWM of 16KHz for 8MHZ DCO using timer TA0

HEX
: P16IO   \ --   \ set P1.6 to GPIO 
  0040 0022 cset    \ P1DIR   P1.6 OUT 
  0040 0026 cclr    \ P1SEL   P1.6 GPIO 
  ; 

: P16SEC  \ --   \ set P1.6 to second function
  0040 0022 cset    \ P1DIR   P1.6 OUT 
  0040 0026 cset    \ P1SEL   P1.6 select second function 
  ; 

: PWM-   
  00 160 !  \ TA0CTL   stop timer 
  p16io 0040 0021 cclr ; \ set p1.6 I/O and clear p1.6

: PWM+  \ n --  \ init and start PWM at P1.6  
  01F4 0172 !   \ TA0CCR0    set period 16KHz at 8MHZ DCO
  00E0 0164 !   \ TA0CCTL1   set output mode 
       0174 !   \ TA0CCR1    set pulse width 
  0210 0160 !   \ TA0CTL     set to timer mode and run 
  ;
 
: PWM  \ n --   \ set PWM at P1.6   n = 0...F
  ton- 000F and
  dup 0= IF drop pwm- 
  ELSE 001F * pwm+ p16sec THEN ;



\ ----------------------------------------------------------
\ ADC - init ADC0 and ADC4, get ADC value
HEX
\ address name \ function
\ 01B0 constant ADC10CTL0 \ ADC10 control register 0
\ 01B2 constant ADC10CTL1 \ ADC10 control register 1 
\ 004A constant ADC10AE0  \ ADC10 input enable register 0
\ 01B4 constant ADC10MEM  \ ADC10 Memory, conversion result

\ some named bits
\ 0002 constant ENC       \ ADC10 Enable Conversion bit
\ 4000 constant INCH_4    \ Selects Channel 4
\   10 constant BIT4      \ for P1.4 Analog Input Enable 
\ 0001 constant ADC10SC   \ start conversion bit
\ 0004 constant ADC10IFG  \ ADC10 Interrupt Flag

\ option bits are:
\ 2000 constant SREF_1     \ set VR+ = VREF+ and VR- = AVSS
\ 1000 constant ADC10SHT_2 \ 16 x ADC10CLKs
\ 0040 constant REF2_5V    \ ADC10 Ref 0:1.5V / 1:2.5V
\ 0020 constant REFON      \ ADC10 Reference on
\ 0010 constant ADC10ON    \ ADC10 On/Enable
\ ----
\ 3070 <-- sum of option bits in hexadecimal

: ADCOFF   \ --  \ stop ADC10 ...
  00 01B0 ! ;   \ ... can be modified only when ENC = 0  

: ADCON    \ --  \ start ADC10
  0002 01B0 set ;  \ Set ENC

: ADC@   \  -- x   \ get ADC value 
  03 01B0 SET \ start conversion (ENC+ADC10SC bits)
  BEGIN 04 01B0 cget UNTIL \ test BIT2 (ADC10IFG)
  01B4 @  ; \ get result

: ADC0     \ --   \ select and init ADC channel 0    
  adcoff
  3070 01B0 !      \ set options (see MCU user manual) 
  0100 01B2 !      \ select input channel (A0 at P1.0)
  01 004A cset ;   \ set pin, analog input enable

: ADC4     \ --   \ select and init ADC channel 4    
  adcoff
  3070 01B0 !      \ set options (see MCU user manual) 
  4000 01B2 !      \ select input channel (A4 at P1.4)
  10 004A cset ;   \ set pin, analog input enable

\ Example: 
\ adc4 adcon adc@ .  \ print single conversion



\ ----------------------------------------------------------
\ RC Servo Control - position 4 RC servos connected to OUT

\ Use external DC power supply for servos for sufficient voltage
\ Connect servo-GND to MCU-GND.
\ Connect servo control lines to OUTx. 
\ Control line needs a pulse between 1..2ms pulse, 
\ 1ms left end, 1,5ms middle, 2ms right end. 
\ Minimum pulse repetition rate is every 20ms, ~$40x, 
\ for one position

HEX
variable x0
variable x1
variable x2
variable x3

: LDX    \ x0 x1 x2 x3 -- \ load variables X0 .. X3
  x3 ! x2 ! x1 ! x0 ! ;

DECIMAL
: INITX  \ -- \ load X0 .. X3 with &500
  500 dup dup dup ldx ; 
  initx

\ linit x to &480 ... &1700 (Range is ~1200 steps)
 480 constant sermin 
1700 constant sermax
: limit \ x -- x' \ linit x to servo minimum an maximum
  sermin max sermax min ;

HEX
: x?     \ -- \  print all X
  x0 ? x1 ? x2 ? x3 ? ;

: DEX    \ x -- \ waste time x  
  0 DO LOOP ;

: PULS  \ x n -- \ send puls x to bit n of P2; n=80,40,20,10
  >r r@ p2 cset dex r> p2 cclr 4 ms ;

: SERVE   \ -- \ send one puls to all servos
  x0 @ 10 puls 
  x1 @ 20 puls
  x2 @ 40 puls
  x3 @ 80 puls ;

: SERVOS \ -- \ position all servos
  initio
  30 0 DO serve LOOP ;

DECIMAL
\ set x to &480 ... &1700 (Range is ~1200 steps)
: SER0 \ x -- \ reposition servo0
  x0 ! servos ;
: SER1 \ x -- \ reposition servo1
  x1 ! servos ;
: SER2 \ x -- \ reposition servo2
  x2 ! servos ;
: SER3 \ x -- \ reposition servo3
  x3 ! servos ;

\ adjust x-min and x-max to match your servo.

\ test, look at pulses on an oscilloscope
: SERTEST \ -- \ position all servos, permanent
  initio BEGIN serve key? UNTIl ;



\ ----------------------------------------------------------
\ Initialisation of MMT4
DECIMAL 
: INIT \ -- \ set pin I/O and variables.
  initio initsv initx ; 



\ --> up to here the image is saved as file
\     4e4th+mmt4-V10.txt in TI format
\ ----------------------------------------------------------
\ Example Programs made for MiniTool 
\ You need 3 switches S1 S2 S3, and 5 LED  + 470Ohm at OUT and PWM.
\ ----------------------------------------------------------
\ Note: (solo) means no PC connection needed.
\ ----------------------------------------------------------
\ Example 1 - display IN. (solo)
HEX
: EX1  \ -- \  display IN at OUT.                   mk0
  initio  
  BEGIN 
  in out               \ get IN and store it to OUT
  key? UNTIL key drop ; \ leave loop, clean up



\ ----------------------------------------------------------
\ Example 2 - display IN at OUT, set PWM-LED too. (solo)
HEX
: EX2 \ -- \   IN to PWM and OUT                     mk0
  initio in drop
  BEGIN 
  in@                \ get INex5
  ifab n3@ <>
    IF in dup out pwm THEN \ store IN to OUT and PWM
  key? UNTIL   \ leave loop, clean up
  key drop  pwm- ;       



\ ----------------------------------------------------------
\ Example 3 - falling edge detector (1) (solo)
HEX
: EX3  \ -- \   falling edge detector S2 to OUT,
            \   reset with S3.
  initio   \ init system 
  s2- s3-  \ and reset edge detection
  1 out    \ set initial OUT value
  BEGIN
  s2? IF s2-  08 out THEN  \ set %1000 on edge detect
  s3? IF s3-  01 out THEN  \ set %0001 on edge detect
  key? UNTIL         \ leave loop, clean up
  key drop  ;       



\ ----------------------------------------------------------
\ Example 4 - falling edge detector (2) (solo)
HEX
: EX4  \ -- \   falling edge detector S2, play note too.
  initio   \ init system 
  s2- s3-  \ and reset edge detection
  1 out    \ set initial OUT value=1
  01 tone@ ton+  \ start low tone
  BEGIN
  s2? IF s2-  08 out 0F tone@ ton+ THEN  \ set high tone ..
  s3? IF s3-  01 out 01 tone@ ton+ THEN  \ or low tone as well. 
  key? UNTIL  \ leave loop
  key drop    \ clean up
  00 out 
  ton- ;       



\ ----------------------------------------------------------
\ Example 5 - dance of 4 servos. To test the 4 servos (solo) 
DECIMAL
0480 constant SL
1700 constant SR
1000 constant SM

IHERE        \ create a list of moves
SL i, SL i, SL i, SL i,
SR i, SR i, SM i, SR i,
SM i, SM i, SR i, SM i,
SL i, SL i, SM i, SL i,
SM i, SM i, SL i, SM i,
SR i, SR i, SR i, SR i,
CONSTANT M0  \ -- adr \ get list address

: ROWS   \ i -- n   \ calculate row offset in bytes
  4 cells * ;
 
: ROW@  \ adr -- x0 x1 x2 x3  \ get 4 values from adr
  dup 4 cells + swap  
  DO  i @  cell +LOOP ;

: DANCE  \ adr n -- \ play list at address, n rows.
  rows over + swap    \ calculate end of list
  DO   \ from beginning till end of list 
  ( i u. ) \ testing
  i row@ ldx servos   \ drive servos to positions of row
  1 rows +LOOP ;      \ advance one row

: EX5 \ --  \ dance until key is pressed
  initio
  BEGIN   
  m0 6 dance   \ set list and rows, then play it once ... 
  key? UNTIL   \ ... again until key is pressed.
  key drop  ;   \ clean up.


\ ----------------------------------------------------------
\ Example 6 - servo follows analog input pin (ADC4) (solo)

\ ADC@ is 0 .. $3FF 
\ SERVO is &480 .. &1700

DECIMAL
: POSITION \ adc -- pos \ scale adc value to servo position
  480 + ;

: EX6 \ --  \ Position of servo2 given by potentiometer
  initio       \ init ports,
  adc4 adcon   \ init ADC
  initx        \ statposition of servos
  BEGIN   
  adc@ position x2 ! serve 
  key? UNTIL 
  key drop  ;   \ clean up.


\ ----------------------------------------------------------
\ Example 7 - get analog input from ADC channel 4. (solo)
HEX
: EX7 \ -- \ ADC to OUT and terminal                 mk0
  initio adc4 adcon  \ init all modules
  s2-
  BEGIN 
  adc@ 44 /          \ scale 10Bit value, 3FF..0 --> F...0
  dup out            \ display scaled value
  . 1sec             \ print to terminal, wait 1 second
  key? UNTIL         \ leave loop, clean up
  key drop  ton- ; 



\ ----------------------------------------------------------
\ Example 8 - audio visual display of ADC. (solo)
HEX
: EX8  \ -- \  ADC to OUT and play note       mk0
  initio adc4 adcon  \ init all modules
  BEGIN 
  adc@ 44 /          \ scale 10Bit value, 3FF..0 --> F...0
  dup out            \ display scaled value
      200 note       \ play apropriate tone
  key? UNTIL         \ leave loop, clean up
  key drop  ton- ;       



\ ----------------------------------------------------------
\ Example 9 - play demo song. (solo)
\ Connect speaker between P1.5 (pin 7) and GND.

variable BEAT      \ holds delay time in ms

: whole   \ -- n   \ duration of whole note 
  beat @ ; 
: quarter \ -- n   \ duration of quarter note
  whole 4 / ;
: eighth  \ -- n   \ duration of eighth note
  quarter 2 / ;

: n1 \ i -- \ play whole note i
  whole note ;
: n4 \ i -- \ play quarter note i
  quarter note ;
: n8 \ i -- \ play eighth note i
  eighth note ;

: p1 \ -- \ play whole pause
  whole pause ;
: p4 \ -- \ play quarter pause
  quarter pause ;


: EX9 \ -- \ play MYBONNIE once  
  500 beat !  
  06 n4  \ G4 
  0C n4  \ F5 
  0A n4  \ D5 
  09 n4  \ C5 
  0A n4  \ D5 
  09 n4  \ C5 
  07 n4  \ A4 
  06 n4  \ G4 
  04 n1  \ E4 
  06 n4  \ G4 
  0C n4  \ F5 
  0A n4  \ D5 
  09 n4  \ C5 
  09 n4  \ C5 
  08 n4  \ B4 
  09 n4  \ C5 
  0A n1  \ D5 
  ton-  ; \ try to make it sound better ...



\ ----------------------------------------------------------
\ Example 0 - leave demo loop, run forth. 
: EX0 
  cr .ver
  cr ." forth - command me." abort ;



\ ----------------------------------------------------------
\ DEMOLOOP is the main programm starting at power up or reset.
  \ Select an example program by it's number using S2.
  \ Press S3 to run it. 
  \ Select and run Example 11 to enter forth.
 
: DEMOLOOP \ -- 
  initio s2- S3- \ init system and reset edge detection
  0000 OUT       \ initial OUT value
  000F out!      \ indicate 'ready', turn all LEDs on
  BEGIN
    s2? IF       \ select demo with S2
      12po n0@ 1+ F and 12po n0! \ increment OUT nibble
      out>       \ display it
      100 ms s2- \ wait, then reset S2
      THEN  
    S3? IF       \ run demo with S3
      12po n0@
     dup  0 = IF EX0  THEN \ run example ...
     dup  1 = IF EX1  THEN
     dup  2 = IF EX2  THEN
     dup  3 = IF EX3  THEN
     dup  4 = IF EX4  THEN
     dup  5 = IF EX5  THEN
     dup  6 = IF EX6  THEN
     dup  7 = IF EX7  THEN
     dup  8 = IF EX8  THEN
     dup  9 = IF EX9  THEN
     drop S3-  \ clean up stack, reset S3
     00 out    \ back to start value
    THEN
  AGAIN ;


\ --> up to here the image is saved as file
\ --> 4e4th+mmt4+ex-V10.txt in TI format
\ ----------------------------------------------------------
\ More example programs made for terminal interaction. 
\ You need a serial PC connection to the MSP430 MCU.
\ How to do that is shown in the documentation of MMT4.  
\ ----------------------------------------------------------

\ ----------------------------------------------------------
\ Example 11 - echo any key. (PC)
HEX
: EX11 \ --    \ terminal KEY to OUT with echo 
  base @  hex  \ save number base on stack, set hex output
  initio   0000 out 
  cr ." press any key to start, "
  cr ." Esc to quit ... "
  cr  \ new line
  BEGIN 
  key                   \ get key 
  dup over 20 < IF 
    5E emit 40 + emit   \ echo control character
    ELSE emit THEN      \ echo character
  dup space 2# space    \ print character value
  dup out               \ send lower nibble to OUT
  1B ( esc ) = UNTIL 
  base ! 
  ; \ exit on esc-character



\ ----------------------------------------------------------
\ Example 12 - toggle OUT bits manually. (PC)
HEX
: tout \ c -- c \ 
  dup [char] 1 = IF 01 12po ctoggle out> exit THEN 
  dup [char] 2 = IF 02 12po ctoggle out> exit  THEN 
  dup [char] 3 = IF 04 12po ctoggle out> exit  THEN 
  dup [char] 4 = IF 08 12po ctoggle out> exit  THEN 
  dup [char] 0 = IF 00 out exit THEN 
  dup [char] f = IF 0f out exit  THEN  ;

: EX12 \ -- \  press 1 2 3 4 to toggel OUT bits,
          \ 0 to clear all, F to set all.
  initio 00 out
  cr ." press 1 2 3 4 "
  cr ." Esc to quit ... "
  cr  \ new line
  BEGIN 
  key tout 
  1B ( esc ) = UNTIL 
  ; \ exit on esc-character

\ --> up to here the image is saved as file
\ --> 4e4th+mmt4+ex+pcex-V10.txt in TI format
\ Add your own examples here.
\ SAVE when compiled.
\ ----------------------------------------------------------
\ todo ***

decimal 
unused u. \ RAM
mem u.    \ FLASH
hex .s 
( finis )