(* Convert frequency to real MSP430 values

Old version:

ACTUAL
A562 10F8  DCO   \ flash dco
8 20  SWITCH   \ mask addr
C 1 A0  BAUDRATE    \ br2 br1 br0


Example new version:

ACTUAL          \ Get current configuration
16MHZ           \ Change DCO frequency
08 20 SWITCH    \ mask addr  Change switch position
38K4            \ Change baudrate


Real board examples:

HEX
ACTUAL              \ Changes for Egel kit

16MHZ               \ DCO freq.
38K4                \ Baudrate
TEST                \ Try it out

RETAIN              \ Make permanent


ACTUAL              \ Changes for Micro Launchpad

16MHZ               \ DCO freq.
38K4                \ Baudrate
TEST                \ Try it out

RETAIN              \ Make permanent


ACTUAL              \ Changes for noForth button vsn-1a

8MHZ                \ DCO freq.
38K4                \ Baudrate
20 20 SWITCH        \ Switch S2 to P1.5
TEST                \ Try it out

RETAIN              \ Make permanent


Next step choosing UART too:

MSP430Gxxxx     Only one USCI for RS232 on P1 or P3
                * No port data needed for choosing UART

MSP430F149      Two UART's for RS232 on P3
                * Four data bytes needed for choosing UART

MSP430FR59xx    Two USCI's for RS232 on P2 or
                Four USCI's for RS232 on P2, P5 & P6
                * One cell and one byte needed for choosing UART

Changing of UART can not be tested interactively!

*)


hex     \ >DCO en >FLASH werken allen ok, nu nog BAUDRATE
value FREQ                      \ Contains DCO frequency in MHz
create 'INFO  F8 C,  FA C,  FC C,  FE C,  align
create 'FREQ  10 C,  0C C,  08 C,  01 C,  align

: >DCO      ( mhz -- lb-info ) \ Calc. low byte for INFO-A dco table
    to freq  4 0 do
        i 'freq + c@ freq =
        if  i 'info + c@  unloop exit  then
    loop
    true ?abort ;

: .DCO      ( lb-info -- )  \ Print valid DCO freq.
    4 0 do
        dup i 'info + c@ = if
            i 'freq + c@ to freq
            freq .  drop  unloop exit
        then
    loop
    true ?abort ;

: >FLASH    ( -- 'flash )   \ Calculate flash programming divider
    freq dm 100 dm 47 */mod \ Do it
    swap 3 < if  1-  then   \ Round down when small remainder only
    hx A540 or ;            \ Add access key & clock source


\ Baudrate register value calculator
: >BAUD     ( "baud" -- x y z ) \ Without overflow thanks to UM/MOD
    >r  freq  dm 10,000 um* \ Scale frequency
    r@ um/mod               \ Divide by scaled baudrate
    swap 8 * r@ /mod        \ Build remainder for modulation
    swap r> 2/ > abs +  2*  \ Round remainder, shift to register position
    swap >r  R@ >< FF and  r> FF and ; \ Leave baudrate data

\ Baudrate print routine
: .BAUD     ( baud-hi baud-lo -- )
    swap >< or >r           \ Combine hi, lo & save
    freq dm 10,000 um*      \ Build scaled frequency
    r> um/mod nip           \ Calculate baudrate
    0 <# # ch , hold #s #> type space ; \ Print in used format


hex
create TEMP  0C allot
: .CONFIG       \ Print configuration data for MSP430!
    base @ >r  decimal
    cr temp 2 + count .dco ."  DCO   \ dcofreq"
    cr count u.  @+ u. ."  SWITCH   \ mask addr"
    cr count >r count >r  drop  r>  r> .baud ."  BAUDRATE    \ baud"
    cr  r> base ! ;

: DCO       ( dcofreq -- )      >dco temp 2 + c!  >flash temp ! ;
: SWITCH    ( mask addr -- )    temp 4 + !  temp 3 + c! ;
: BAUDRATE  ( "baud" -- )       >baud  temp 6 + c!  temp 7 + c!  temp 8 + c! ;

: TEST      ( -- )              temp config ;
: ACTUAL    ( -- )              frozen2 temp 0C move  .config ;

: RETAIN    ( -- )
    frozen  here  frozen2 frozen -  tidy)
    temp  frozen2 0C rommove ;

: 1MHZ      01 dco ;
: 8MHZ      08 dco ;
: 12MHZ     0C dco ;
: 16MHZ     10 dco ;

decimal
: 1200B     1,2 baudrate ;
: 2400B     2,4 baudrate ;
: 4800B     4,8 baudrate ;
: 9600B     9,6 baudrate ;
: 19K2      19,2 baudrate ;
: 38K4      38,4 baudrate ;
: 57K6      57,6 baudrate ;
: 115K2     115,2 baudrate ;
hex

\ End
