\ lcd.fs

\ Nibble mode LCD driver for C8051F300 -- 22Aug06 cws/rjn
\ based on working driver written in AMR Forth, amrlcd.fs

0 [if]

LCD 	PORT	300    	FUNCTION
PIN		PIN
---	-------	-----	-------------------------------------
 1	----   	11	GND
 2	----   		+5 Volts (used 78L05 on Gadget MB)
 3	----		Contrast Voltage 0-5 Volts (10K pot)
 4	P0.7	10	RS - Instruction Register Select
 5	GND	11	R/W - H=READ L=WRITE Registers (GND)
 6	P0.6	9	E - Enable  P0.6
 7	GND	11	byte DB0
 8	GND	11	byte DB1		
 9	GND	11	byte DB2
10	GND	11	byte DB3
11	P0.0	1	byte DB4 - nibble DB0 
12	P0.1	2	byte DB5 - nibble DB1
13	P0.2	4	byte DB6 - nibble DB2
14	P0.3	5	byte DB7 - nibble DB3

[then]

\ SFR definitions are included in job.fs

] \ Target Forth

\ ---------- I/O
\ set all outputs as push-pull
:m push-pull  $FF # P0MDOUT ior! m;

:m pins  P0 m;
:m dirs  P0MDOUT m;

:m .E    6 .P0 m;
:m .RS   7 .P0 m;
: instruction  [ .RS clr ] ;
: data  [ .RS set ] ;

\ ---------- delays
: us  ( n - )   
   7 #for  
      6 #  6 #for 6 #next
   7 #next ;
: ms  ( n - )   
   7 #for 
      100 # 6 #for 
         81 #  5 #for 5 #next
      6 #next 
   7 #next ;

\ 160 us may be ok at half the value given
: strobe   [ .E set ] 100 # us [ .E clr ]  160 # us  160 # us ;

\ ---------- lcd words 
\ $c4 swaps nibbles in the accumulator in one cycle
: lcd  ( c - )
    $b0 # pins and!	\ output high nibble first
    dup $f0 # and [ $c4 ] ,  pins ior!
    strobe
    $b0 # pins and!	\ now output do low nibble
    $0f # and pins ior!
    strobe ;

: clear-lcd  instruction 1 # lcd data 100 # ms ;

: init-lcd 
\    instruction
    $30 # pins #!	\ RS=0, instruction mode
    $cf # dirs ior!	\ configure pins as outputs
    30 # ms		\ power on delay
    $03 # pins #!	\ initialization pattern
    strobe 10 # ms	
    strobe
    strobe
    $02 # pins #!
    strobe 10 # ms
    $28 # lcd 10 # ms
    $0e # lcd
    $01 # lcd 10 # ms
    $02 # lcd
    data  10 # ms  ;

: init  push-pull init-lcd ;

\ ---------- Strings.
: lcd-type ( da) p! @p+ begin @p+ lcd 1- 0=until drop ;
:m " 34 parse here there place here there [ c@ 1 + ] allot m;
: string pop pop swap lcd-type ;
: greet string " It's MyForth!"


\ Example: init greet
