; Dick Cappels' project pages projects@cappels.org 
;
; You should be able to copy and paste this text into an assembler file and name that file
;"2x16lcd.inc".
;
; No liability for use of this code is assumed. See full disclaimer on web site at
; www.projects.cappels.org.
;.
;
; Please email comments or corrections to projectsxcappels.org where x is the @ sign.
; (the above is to mask the address from email address gathering robots).
;
;HOME
;
;2x16040727A ;First incarnation of the driver file.
; Character receive and display for Truly MTC-C162DPLY-2N 2 line X 16 char LCD.
; Requires AT90S2313 or equivalent with 4 MHz clock.
;
; Below are the connections to the Truly Display
; Pin Function (connection)
; 1 GND
; 2 VCC (+5V)
; 3 Contrast (0to +5V from wiper of 10 pot)
; 4 RS (Register Select 1=data 0=command)
; 5 R/W (tie to ground for write-only)
; 6 OE (Enable - data clocked on neg transition)
; 7-10 D0 - D3 lower 4 data bits (not used - ground these)
; 11-14 D4-D7 upper 4 data bits (connects to AVR90S2313 PB4 through PB7 respectively).
;
; The AT90S2313 routines to control the display, based on the Hitachi HD44780, and the initialization
; code in particular, are based on code originally published by Richard Hosking.
; The display is driven in the 4 bit mode. The Truly display uses a Samsung KS0070B controller
; that appears to differ from the Hitachi HD44780 controller in that the Samsung requires an
; additional 4 bit write operation during "Function set" when in 4 bit mode. This was accomplished
; by writing the "Function set" command twice to the controller twice instead of once.
; I suspect that this would work without modification with the Hitachi
; controller as the second write would be a redundant command for the Hitachi controller.
;
; Note that
;
; Below re the connections for the AT90S2313
; Pin Function (Connection)
; VCC +5V (decoupled)
; GND ground
; XTAL1 Clock (see data sheet)
; XTAL2 Clcok (see data sheet)
; TXD Serial out (RS-232 inverting buffer to remote device - NOT USED)
; RXD Serial in (RS-232 inverting receive buffer)
; PD2-PD6 Unassigned (not connected)
; PB0,PB1 Unassigned (not connected)
; PB2 R/S pin on Truly LCD (Truly module pin 4)
; PB3 OE pin on Truly LCD (Truly module pin 6)
; PB4-PB7 D4-D7 on Truly LCD (Truly module pins 11-14 respectively)
;

;////////////////START LCD DRIVER\\\\\\\\\\\\
;Parameters are passed to this routine in register temp. Temp cannot be r17.
;(temp is global).
;The following routines are intened to be called externally:
;InitDisplay
;HomeOne
;HomeTwo
;SendData
;SendComamnd


HomeOne: ;Home cursor to start of first top line of display.
ldi temp,$80
rcall SendCommand
ret

HomeTwo: ;Home cursor to start of bottom line of display
ldi temp,$C0
rcall SendCommand
ret

Delay2us: ;Delay about 1.75 us (4 MHz clock).
ret

Delay50: ;Delay about 50 us.
push temp
ldi temp,$45 ;4 MHz clock.
d50l: dec temp
brne d50l
pop temp
ret ;Return to calling routine


delay2ms:
push temp
ldi temp,$0B
w2ms2: ldi r17,$FF
w2ms1: dec r17
brne w2ms1
dec temp
brne w2ms2
pop temp
ret

SendDisplay: ;Send contents of temp as data if carry clear, as
;command if carry is set.
push r17 ;Save this register
push temp ;Save a copy of the data on stack to work on later.
andi temp,$F0 ;Mask off lower nybble.
sbr temp,OE ;Make OE bit high.
brcs sd1 ;Skip next if this is a command.
sbr temp,RS ;Set data/command bit high ;*For sending Data
sd1:
out PORTB,temp ;Write upper nybble to display.
rcall delay2us ;Wait 1.75 us (could be only 1 us).
pop temp ;Retrieve copy of input data.
cbi PORTB,3 ;Set OE low to clock in data.
swap temp ;Swap upper and lower nybbles.
andi temp,$F0 ;Mask off lower nybble and make OE and RS low.
sbr temp,OE ;Make OE high.
brcs sd2 ;Skip next if this is a command.
sbr temp,RS ;Set data/command bit high ;*For sending Data
sd2:
out PORTB,temp ;Write lower nybble to LCD.
rcall delay2us ;Wait 1.75 us (could be only 1 us).
cbi PORTB,3 ;Make OE low to clock in data.
rcall Delay50 ;Wait about 50 us before next action.
pop r17 ;Restore this register
ret ;Return to calling routine.


SendCommand:
sec
rjmp SendDisplay


SendData:
clc
rjmp SendDisplay



InitDisplay: ;Initialize Display
ldi temp,50 ;Wait at least 15msec after power applied befoer writing.
ID1: rcall delay2ms
dec temp
brne ID1
ldi temp,0b00111000 ;System set
out PORTB,temp
rcall delay2us ;Wait 1.75 us (could be only 1 us).
cbi PORTB,3 ;Set OE low to clock in data.
rcall delay2ms ;Wait about 4 msec.
rcall delay2ms
ldi temp,0b00111000
out PORTB,temp
rcall delay2ms ;Wait more than 100usec
ldi temp,0b00111000 ;System set.
out PORTB,temp
rcall delay2us ;Wait 1.75 us (could be only 1 us). ;
rcall delay2ms ;Wait at least 40usec (2 msec)
ldi temp,0b00101000 ;Function set 4 bit mode, 2 lines 5X7 pixels.
rcall SendCommand ;Write to display -first write sets 4 bit mode.
ldi temp,0b00101000 ;Function set 4 bit mode, 2 lines 5X7 pixels (OMIT FOR HITACHI)
rcall SendCommand ;write to display -second write to set N and F (OMIT FOR HITACHI)
ldi temp,0b00001000 ;Display, cursor and blink off.
rcall SendCommand
ldi temp,0b00000001 ;Clear display.
rcall SendCommand
rcall delay2ms ;Need to wait more than 1.6 msec after clear.
ldi temp,0b00000110 ;Set entry mode. ;Increment RAM, dont shift display.
rcall SendCommand
ldi temp,0b00001110 ;Display and cursor on, blink off.
rcall SendCommand
rcall delay2ms ;Need to wait more than 1.6 msec after clear.
ret ;Return to calling routine.


;////////////////END LCD DRIVER\\\\\\\\\\\\


;HOME


;http://projects.cappels.org/
;Richard Cappels