( Half_Step)
( GPIO Pins 0,1,4,7 used for stepper motor)
OSCLI" RMEnsure GPIO 0.00 RMLoad GPIO"
OSCLI" RMEnsure GPIO 0.40 ERROR HELP can't find GPIO module"
( GPIO setup ----------------------------------)
HEX
( addresses of SWI commands for GPIO module)
58FBD CONSTANT GPIO_EnableI2C  
58F85 CONSTANT GPIO_ExpAsGPIO
58F81 CONSTANT GPIO_WriteData

CODE GPEnabI2C   ( 0....)
 R0 POP,                    ( equivalent: ldmfd sp !,{r0})
 GPIO_EnableI2C SWI,                    ( swi &58FBD)
PC R14 MOV,                             ( mov pc,r14)
END-CODE

CODE GPExpGPIO   ( n....)
 R0 POP,
 GPIO_ExpAsGPIO SWI,
PC R14 MOV,
END-CODE

CODE GPWrData         ( n1,n2.....n3,flg)
 R0 POP,              ( pin no. from stack to R0)
 R1 POP,              ( 0 for low and 1 for high to R1)
 GPIO_WriteData SWI,
 R1 PUSH,             ( pin mask)
 R0 PUSH,             ( -1 if pin not valid, or logical address of pin)
PC R14 MOV,
END-CODE

( Forth words for half-stepping ---------------)
DECIMAL 
9 ARRAY Half           ( half steps - sequence of GPIO lines)
100000 VARIABLE dT     ( dT determines motor speed)

( short delay using only Forth words)
: sm_delay  0 DO I I * DROP LOOP ;  ( n ...) 

: ProtectI2C   1 GPEnabI2C ;
: UnprotectI2C 0 GPEnabI2C ;
: OutputsGPIO  2 GPExpGPIO ;   ( all pins as outputs)

: init_motors  ( ...)
   UnprotectI2C OutputsGPIO
   200000 dT !                ( initial 'slow' speed value)
   0 0 1 1 4 4 7 7 0          ( sequence of pins for pulses)
   0 8 DO I Half ! -1 +LOOP ; ( fill array with sequence)

: GPIOpin_ON  1 SWAP GPWrData DROP DROP ;  ( n ...)
: GPIOpin_OFF 0 SWAP GPWrData DROP DROP ;  ( n ...)

: 1_OFF ( n...) dT @ sm_delay GPIOpin_OFF ; ( note dT here)

: half_step_clock
  8 0 DO  I    Half @ DUP GPIOpin_ON
          I 1+ Half @     GPIOpin_ON
          1_OFF      ( 1st of pair switched OFF after delay)
      LOOP ;

: half_step_anticlock
   1 8 DO I    Half @ DUP GPIOpin_ON
          I 1- Half @     GPIOpin_ON
          1_OFF      ( 1st of pair switched OFF after delay)
    -1 +LOOP ;

: nh_clock  0 DO half_step_clock     LOOP ;   ( n...)
: nh_aclock 0 DO half_step_anticlock LOOP ;   ( n...)

: fast 50000 dT ! ;
: slow 200000 dT ! ;

( Test - clockwise then anti-clockwise)
: step_demo  init_motors fast
    400 nh_clock  400 nh_aclock ProtectI2C ;

