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:
: emit begin UCSR0A c@ %00100000 and until UDR0 c! ;
: key? UCSR0A c@ %10000000 and ;
: key begin key? until UDR0 c@ ;
::itc:: include ../compiler-itc.ft
::stc:: include ../compiler-stc.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