;Dick Cappels' project pages projects@cappels.org - you should be able to copy and paste this text into an assembler file.
;©2003 Richard Cappels All Rights Reserved. No liability for resuls of use is assumed.See disclaimer on
;web site.email projects@cappels.org
;Use of information presented on this page is for personal, nonprofit educational
;and noncommercial use only. This material (including object files) is copyrighted
;by Richard Cappels and may not be republished or used directly for commercial
;purposes without explicit permission. For commercial license, click HERE.
;
;HOME
;*********************************
;2313 serial to Sekio Epson 1216 display panel interface program
;*********************************
.include "2313def.inc"
;Driver for Seiko 1216 LCD display. 128 X 64, with separate drivers for left and right
;halves of the screen. See the specification and app. notes for Seiko G1216B1N000.
; Here is how the AT90S2313 is connected to the display:
;Port B is connected to the 8 bit data input/ouput on the display.
;Port D, bits 0 and 1 are not available as the corresponding pins are used for the UART.
; these bits should be written as zero.
;Port D, bit 2 is connected to the R/W input on the display. This is
; more of a data direction and mode pin.
; Actual writes are clocked by the Enable pin.
;Port D, bit 3 is conntected to the D/I (Data/Instruction) pin on the display.
; Low signifies insturction on the data port.
;Port D, bit 4 is connected to the enable input on the display. Instructions and
; data are clocked into the display on the negative edge.
;Port D, bit 5 is to the RESET input on the display. Low resets the display.
;Port D, bit 6 is connected to CS1 on the dispaly and to the input of an inverter,
; the output of which, drives CS2. It is therefore a right side/left side
; select signal. Low for left side, high for right side.
;I/O Pin assignment
.equ Enable =$04
;Display control codes
.equ instructionleft = $30
.equ instructionright = $70
.equ writedataleft = $38
;.equ writedataright = $78
;.equ readstatusleft = $34
;.equ readstatusright = $74
;Displays Instructions
.equ displayon = $3F
;.equ displayoff = $3E
.equ XtoZero = $B8
.equ YtoZero = $40
.equ Slinetozero = $C0
;Flag bit assignments for reigster YH
;YH bit 0 if = 1 then in bindary mode for serial data, if 0, ASCII-HEX mode
;YH bit 1 if = 1 then adds dot without erasing 8 bits in column (read-modify-write; slow)
;UART clock parameters
.equ clock = 4000000 ;clock frequency
.equ baudrate = 19200 ;choose a baudrate
.equ baudconstant = (clock/(16*baudrate))-1
;Register Assignments
.def temp = r16
.def xtarget = r17
.def ytarget = r18
.def dispdata = r19
.def temp2 = r20
.def delayreg = r23
.def delay2 = r24
;.def inchar = r25
;.def outchar = r26
.org $00
rjmp reset ;Reset handle
reset: rjmp init ;Start init.
init:
ldi temp,ramend ;low(ramend)
out spl,temp ;Set the stack pointer
ldi temp,baudconstant
out ubrr,temp ;Load UART bard rate
sbi ucr,txen ;enable UART xmit
sbi ucr,rxen ;Enable UART receiver
ldi YH,$00 ;Clear all flags
rcall waitlongtime ;Allow dispay to come on.
ldi temp,$FF ;Issue reset.
rcall odd
ldi temp,$00
rcall opd
ldi temp,instructionleft ;Address left half of display
rcall opd
ldi temp,$FF
rcall odb
ldi temp,displayon ;Turn left display half on.
rcall opb
rcall strobeE
ldi temp,SlinetoZero ;Set left start line to zero.
rcall opb
rcall shortdelay
rcall strobeE
ldi temp,instructionright ;Address right half of display.
rcall opd
ldi temp,$FF
rcall odb
ldi temp,displayon ;Turn right half on.
rcall opb
rcall strobeE
ldi temp,SlinetoZero ;Set rightstart lien to zero.
rcall opb
rcall shortdelay
rcall strobeE
rcall erasedisplay ;Fill display with zeros (clear screen).
ldi xtarget,$00 ;Draw A "V" on the screen. uses each row and each column.
ldi ytarget,$00
moredots:
rcall WriteDotAtXY
inc xtarget
inc ytarget
cpi xtarget,63
brne moredots
moredotsT:
rcall WriteDotAtXY
dec xtarget
inc ytarget
cpi xtarget,$FF
brne moredotsT
defaultloop: ;*****Default loop****
;Until a command is received, which is distinguished by the MSb (bit 7)
;being set hight, receive x value, then y value, then write a dot there,
;notify when the dot write is complete, and get another. When a command
;is received, to interpret it.
;Message format:
;bit 7: 1 if command.
;bit 6: msb of y address, or zero if x address
;bits 5 hrough 0 remaining bits of address
;Host should send x, then y, then wait for completion notification.
;IN THIS ROUTINE, THE AXES ARE CORRECTED. X IS THE HORIZONAL AXIS (VALUE 0..127)
;AND Y IS THE VERTICAL AXIS (VALUE 0..63).
;SENSE IS CORRECTED ALSO. O,O IS LEFT,BOTTOM
rcall GetASCIIorBinary ;Get char and put into xtarget.
mov temp2,temp
andi temp2,$80
brne ItsaCommand
andi temp,$7F
mov ytarget,temp
rcall GetASCIIorBinary ;Get char and put into ytarget.
mov temp2,temp
andi temp2,$80
brne ItsaCommand
andi temp,$3F
ldi temp2,$3F
sub temp2,temp
mov xtarget,temp2
; mov xtarget,temp
rcall WriteDotAtXY ;Write dot.
ldi temp,$2A ;Notify write is complete.
rcall emitchar
rjmp defaultloop
GetASCIIorBinary: ;Get byte value from host to temp. If YH bit 0 is set, gets binary
;from host. If YH bit 0 is set, then gets ASCII-HEX from host.
rcall recvchar
sbrc YH,0
ret ;Binary mode - return after first byte
cpi temp,$30
brmi GetASCIIorBinary;If comma, ignore and use next char instead
mov temp2,temp ;Get second char and make binary. No error checking.
rcall recvchar
;If comma, out of sync - start receiving byte over
cpi temp,$30
brmi GetASCIIorBinary
sbrc temp2,6 ;convert high byte
subi temp2,$f7 ;if bit 6 is set, add $09
andi temp2,$0F
sbrc temp,6 ;convert low byte
subi temp,$f7 ;if bit 6 is set, add $09
andi temp,$0F
lsl temp2 ;combine them
lsl temp2
lsl temp2
lsl temp2
or temp,temp2
ret
;convert ascii in inbyteh,inbytel to byte in inbytel
ItsaCommand:
cpi temp,$80 ;Command $80 erase display and reset
breq ClearAndReset
cpi temp,$81 ;Command $81 switch to ASCII mode
breq SwitchToAscii
cpi temp,$82 ;Command $82 switch to binary mode
breq SwitchToBinary
cpi temp,$83 ;Command $83 restart controller
brne drs1
rjmp init
drs1:
; cpi $84
; breq ?????
ldi temp,$21 ;Else, Nack command and reset
rcall emitchar ;Exclaimation mark is printable Nack
rjmp defaultloop
SwitchToAscii:
andi YH,$FE
rjmp defaultloop
SwitchtoBinary:
ori YH,$01
rjmp defaultloop
ClearAndReset: ;Clear display and reset default interperetation loop (can be used to sycn)
rcall erasedisplay
rjmp AckAndReset
AckAndReset:
ldi temp,$2A ;Send asterisk, which is printable ack
rcall emitchar ;and go back to start of default loop.
rjmp defaultloop
erasedisplay:
ldi dispdata,$00
ldi xtarget,$00
anotherx:
ldi ytarget,$00
anothery:
rcall WriteByteAtXY
inc ytarget
cpi ytarget,128
brne anothery
inc xtarget
cpi xtarget,8
brne anotherx
ret
WriteDotAtXY: ;Write a dot at X Y location
;(0=<X=<63, 0=<Y=<127.
;Enter with X in xtarget and
;Y in ytarget (nothing to do with Y but pass it along.
push xtarget ;Save xtarget on stack for later
push ytarget
andi xtarget,$3F
andi ytarget,$7F
mov temp,xtarget ;Make display data from 3 lsb of xtarget
andi temp,$07
rcall bitpositiontoormask
mov dispdata,temp
;Make X page address from xtarget. Put in xtarget.
lsr xtarget
lsr xtarget
lsr xtarget
andi xtarget,$07
rcall WriteByteAtXY
pop ytarget
pop xtarget
ret
WriteByteAtXY: ;Write 8 bits at X and Y locaton per data sheet
sbi portd,2 ;Put R/W on display in Read to
ldi temp,instructionleft ;prevent ghost right write in column 1.
mov temp2,ytarget
andi temp2,$40
breq notrights
ldi temp,instructionright
notrights:
rcall opd
mov temp,xtarget
ldi temp2,XtoZero
add temp,temp2
rcall opb
rcall strobeE
mov temp,ytarget
andi temp,$3F
ldi temp2,YtoZero
add temp,temp2
rcall opb
rcall strobeE
notright:
sbi portd,3 ;Make this a data write.
rcall shortdelay
mov temp,dispdata
rcall opb
rcall strobeE
ldi temp,$00 ;Prevent glitching starting line register
rcall opb
ret
odd:
out ddrd,temp
ret
opd:
out portd,temp
rcall shortdelay
ret
odb:
out ddrb,temp
ret
opb:
out portb,temp
; rcall shortdelay
ret
strobeE:
; rcall shortdelay
cbi portd,4
rcall shortdelay
sbi portd,4
ret
bitpositiontoormask: ;Convert bit position (0..7) to OR mask value
;Enter with bit position in temp, Exit with
;mask in temp
ldi temp2,$07
cp temp2,temp
brmi error
ldi temp2,$01 ;Put 0000 0001 pattern into temp for shifting
rotatesomemore:
cpi temp,$00
breq finishedshifting
lsl temp2
dec temp
rjmp rotatesomemore
finishedshifting:
mov temp,temp2
ret
error: ;Report error - for now, just return.
ldi temp,$21 ;Else, Nack command and reset
rcall emitchar ;Exclaimation mark is printable Nack
ret
emitchar: ;Send byte in temp to terminal
sbis usr,udre ;wait until the register is cleared
rjmp emitchar
out udr,temp ;send the byte
ret ;go back
recvchar: ;Receive a byte from the terminal and put into temp
sbis usr,rxc ;Wait for byte to be received
rjmp recvchar
in temp,udr ;Read byte
ret
shortdelay:
ldi delayreg,$04
delaymore:
dec delayreg
brne delaymore
ret
longdelay:
ldi delayreg,$00
ldi delay2,$00
delaymore2:
dec delayreg
brne delaymore2
dec delay2
brne delaymore2
ret
waitlongtime:
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
rcall longdelay
ret
;http://projects.cappels.org/
;HOME