CoreForth-0

avr/boards/arduino.ft.md


Arduino CoreForth

CoreForth-0 for Arduino Uno boards, with simple UART and LED functionality.

::host::

cr

ROM starts at 0x0000 and RAM at 0x0200:

$00000000 to trom
$00000200 to tram

trom tdp !
tram tvp !

The actual code starts at 0x0910, where the space from 0x0900 to 0x0910 is reserved for variables passed from the compilation phase to the system runtime. Using 0x0900 as the start allows distinguishing addresses between RAM and flash (all values below 0x0900 are RAM), at the expense of losing about 2k of flash.

$910 torg

::itc:: include ../janus/host-itc.ft
::itc:: include ../janus/target-itc.ft
::stc:: include ../janus/host-stc-mega.ft
::stc:: include ../janus/target-stc-mega.ft

::target::

System variables

$900 constant  init-latest
$902 constant  init-dp

$8ff constant  r0
$8bf constant  s0

Include the rest of the system:

../atmega328p.ft

../memory-mega.ft

../core.ft

../wdt-mega.ft

: emit          begin UCSR0A c@ %00100000 and until UDR0 c! ;
: key?          UCSR0A c@ %10000000 and ;
: key           begin key? until UDR0 c@ ;

../../common/exception.ft

../../common/timeout.ft

../../common/core.ft

../../common/output.ft

../../common/input.ft

../dictionary.ft

../utils.ft

::itc:: include ../compiler-itc.ft
::stc:: include ../compiler-stc.ft

../../common/control-flow.ft

../../common/interpret.ft

Hardware initialization

Set the UART to 38400bps at 16MHz

: uart-init    #25 UBRR0L c! 0 UBRR0H c!
               %00011000 UCSR0B c!
               %00000110 UCSR0C c! ;

LED at PB5 (D13)

: led-init     %00100000 >DDRB ;
: +led         %00100000 >PORTB ;
: ~led         %00100000 >PINB ;
: -led         %00000000 >PORTB ;

SPI

: +spi         PORTB> %11111011 and >PORTB ;
: -spi         PORTB> %00000100 or >PORTB ;
: spi-init     DDRB>  %00101100 or >DDRB   %01010000 >SPCR   -spi ;
: >spi>        ( c -- c )
               >SPDR begin SPSR> %10000000 and until SPDR> ; 
: >spi         >spi> drop ;
: spi>         $ff >spi> ;

NRF24

: rf-ce-init   DDRB>  %00000010 or >DDRB ;
: -rf-ce       PORTB> %11111101 and >PORTB ;
: +rf-ce       PORTB> %00000010 or >PORTB ;
: rf-irq?      PORTB> %00000001 and ;

Initialize the UART and LED, and enable sleep mode

: hw-init      uart-init led-init %00000001 >smcr ;

A simple IRQ handler which toggles the LED:

i: t0-handler  ~led ;i

Simple handler which increments the tick variable:

i: tick-handler
               1 tick +! ;i

System start: Initialize the dictionary pointers (here and latest).

: setup-pointers
               init-latest @ latest !
               init-dp @ dp !
               ;

Declare a default application word which starts the interpreter. This can be overridden in files loaded as extras:

: turnkey      0 (source-id) !
::itc::        s" CoreForth-0 AVR ITC ready" type cr
::stc::        s" CoreForth-0 AVR STC ready" type cr
               hex
               quit
               ;

Include any extra files:

include-extras

Cold start of the system:

: cold         hw-init
               setup-pointers
               turnkey
               reset ;

Finalize the compilation back in host mode:

::host::

Set the IRQ handlers for reset, the watchdog and timer 0:

 #1 t' reset-handler irq-handler!
 #7 t' tick-handler irq-handler!
#17 t' t0-handler irq-handler!

Store the values for latest and here (using the latest allocated address in RAM), and let execution start with cold:

    tlast @ $900 >target w!
      tvp @ $902 >target w!
t' cold t' start tcell + >target w!

Finally, write out the Intel HEX file with the compiled program:

::itc:: s" arduino-itc.hex" write-hex
::stc:: s" arduino-stc.hex" write-hex