Examples: Word Usage

Brief Word examples, linked from the Dictionary page

WFI ($BF30)

WFI is a hint instruction that suspends execution until one of the following events occurs:
  • An exception
  • An interrupt becomes pending which would preempt if PRIMASK was clear
  • A Debug Entry request, regardless of whether Debug is enabled.

WFI is intended for power saving only. When writing software assume that WFI might behave as a NOP operation.

: wfi ( -- mcu asleep ) [ $BF30 h, ] inline ;  \ WFI Opcode, Wait For Interrupt, enters sleep mode
see wfi
2000055E: B500  push { lr }
20000560: BF30
20000562: BD00  pop { pc }
ok.

<builds does>

This example prints some GPIO Modes, i.e. IN, OUT, ANALOG, etc to demonstrate the versatility of <builds does>, often described as the ‘jewel of forth’.
  • Developed on: ST32F0 Discovery board
  • MCU: Cortex M0
\ Peripheral constants
\ ------------------------------------------------------------------- \
   $48000000   constant GPIOA_MODER
   $48000400   constant GPIOB_MODER
   $48000800   constant GPIOC_MODER

\ Register inits, note: This is a mecrisp-stellaris machine and
\ GPIOA-2 and 3 are already defined as AF and used as USART 1
\ ------------------------------------------------------------------- \
 %01  0 lshift GPIOA_MODER bis!        \ GPIOA_MODER0 as output
 %11  8 lshift GPIOA_MODER bis!        \ GPIOA_MODER4 as analog input

\ The <builds  does> example
\ ------------------------------------------------------------------- \
: moder? cr <builds , , does>  2@
   dup >r lshift and r> rshift
   case
   %00 of ." IN "     cr endof
   %01 of ." OUT "    cr endof
   %10 of ." AF "     cr endof
   %11 of ." ANALOG " cr endof
   endcase
 ;

\ Create moderx? words
\ ------------------------------------------------------------------- \
 %11  0 moder?  moder0?
 %11  2 moder?  moder1?
 %11  4 moder?  moder2?
 %11  6 moder?  moder3?
 %11  8 moder?  moder4?

\ Find the moderx? modes on a live system
\ ------------------------------------------------------------------- \
 gpioa_moder @ moder0?
 gpioa_moder @ moder1?
 gpioa_moder @ moder2?
 gpioa_moder @ moder3?
 gpioa_moder @ moder4?

\  Actual realtime status of gpioa_moder
\  gpioa_moder. GPIOA_MODER (read-write) $000003A1
\  15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00
\  00 00 00 00 00 00 00 00 00 00 00 11 10 10 00 01

\   gpioa_moder @ moder0? OUT
\   gpioa_moder @ moder1? IN
\   gpioa_moder @ moder2? AF
\   gpioa_moder @ moder3? AF
\   gpioa_moder @ moder4? ANALOG

\ Previously defined moderx? words apply to gpiob and gpioc also
\ ------------------------------------------------------------------- \
\   gpiob_moder @ moder0? IN
\   gpioc_moder @ moder0? IN

bit@

GPIOA_IDR (read-only) $0000B0F8
1|1|1|1|1|1|
5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0
1 0 1 1 0 0 0 0 1 1 1 1 1 0 0 0

: pa0?
  ." gpioa bit 0 "
  %1 0 lshift gpioa_idr bit@
     if ." is high" cr
     else ." is low" cr
  then ;

: pa3?
  ." gpioa bit 3 "
  %1 3 lshift gpioa_idr bit@
     if ." is high" cr
     else ." is low" cr
  then ;

pa0? gpioa bit 0 is low
ok.
pa3? gpioa bit 3 is high
ok.

compare

2dup s" tos" compare if 2drop 6 exit then
2dup s" psp" compare if 2drop 7 exit then
2dup s" sp"  compare if 2drop 13 exit then
2dup s" lr"  compare if 2drop 14 exit then
2dup s" pc"  compare if 2drop 15 exit then

+loop

: backwards ( -- )
  0 10 do I . -1 +loop ;

backwards 10 9 8 7 6 5 4 3 2 1 0  ok.

+LOOP can be misused to set I to any value e.g. to set it to 13 if has the value 5

: misused cr 20 0 do i . i 5 = if 8 else 1 then +loop ;

misused
0 1 2 3 4 5 13 14 15 16 17 18 19  ok.

loop

: forwards ( -- )
  10 0 do I . loop ;

forwards 0 1 2 3 4 5 6 7 8 9  ok.

min

10 20 min . 10  ok.

max

10 20 max . 20  ok.

min-max window

100 0 max 63 min . 63  ok.

-10 0 max 63 min . 0  ok.

umin

-10 0 umax . -10  ok.

Return Stack

Return Stack Words

>r
r@
r>
rdrop
rdepth
rpick
2>r
2r@
2r>
2rdrop

Warning

It’s often convenient to be able to put a stack item temporarily in the return stack, but the following rules must be observed.

  • Data put on the return stack must be taken back within the same word.
  • Data put on the return stack outside a ?DO (DO) ... LOOP (+LOOP) cannot be accessed within the loop.
  • Data put on the return stack within a ?DO (DO) ... LOOP (+LOOP) must be taken back before leaving the loop.
  • Data cannot be on the return stack when executing I or J in a loop.

A multasking delay

: msdelay ( u -- ) cr        \ delay for x milliseconds
 >r                          \ save delay value on the return stack
 0 ms_second_counter !       \ reset ms_second_counter to zero. "ms_second_counter" is incremented by Systick every 1 ms
 begin
 r@                          \ get the delay value from the return stack
 ms_second_counter @         \ get ms_second_counter value
 =                           \ loop until equal to  ms_second_counter
 pause                       \ allows a cooperative multitasker to use the dead time between each millisecond
 until
 r> drop                     \ balance the return stack
 ;                           \ finished, delay is over

Table Of Contents

Previous topic

Example Forth Programs

Next topic

F0 Discovery: 48 MHz Clock

This Page