;************************************************************************** ; ; LCD_NEC.inc LCD code to drive an Epson EAN16025 using NEC D7228G chips ; ; Description: Drive ; ; Author: Doug Rice ; ; ; ; ; ;************************************************************************** ;-------------------------------------------------------------------------- ; Sec 3.3 LCD routines stuff ;-------------------------------------------------------------------------- cblock LCDtemp ; LCDcnt ; LCDcnt2 LCDcnt1 ; LCDcursorStart ; used to store the start LDPI LCDnibble ; LCDPortB ; image of port B for unused bits LCDeraseCnt ; LCDstrPtr ; LCDcntrl ; bit map for CND and which chip is used LCDdata ; endc ;-------------------------------------------------------------------------- ; Sec 3.3.4.2 LCD procedures LCD string write displayes ;-------------------------------------------------------------------------- ifdef buildLCDgetByte LCDgetByte ; we should have set up PCLATH ; and reset LCDgetCharFlag BCF LCDPortB,LCDgetCharFlag MOVLW high $ MOVWF PCLATH MOVFW LCDstrPtr; INCF LCDstrPtr,f ADDWF PCL,f LCDstrs LCDstrLTime equ $ - LCDstrs DT "Hello" GOTO LCDgetByteEnd4 ; now print out 4 blanks LCDstrLblank equ $ - LCDstrs DT " " GOTO LCDgetByteEnd6 LCDstrLOff equ $ - LCDstrs DT "OFF" GOTO LCDgetByteEnd6 LCDstrLOn equ $ - LCDstrs DT "ON " GOTO LCDgetByteEnd6 LCDstrLOnp equ $ - LCDstrs DT "ON+" GOTO LCDgetByteEnd6 LCDLastStr IF 0 != ( high ( LCDLastStr ) - high ( LCDgetByte ) ) Error "String Table straddles Page Boundary " ENDIF ; Jump into these to select how many spaces printed ; at the end, so that 9 chars are printed. LCDgetByteEnd0 DECF LCDeraseCnt,f LCDgetByteEnd1 DECF LCDeraseCnt,f LCDgetByteEnd2 DECF LCDeraseCnt,f LCDgetByteEnd3 DECF LCDeraseCnt,f LCDgetByteEnd4 DECF LCDeraseCnt,f LCDgetByteEnd5 DECF LCDeraseCnt,f LCDgetByteEnd6 BSF LCDPortB,LCDgetCharFlag RETURN endif ; buildLCDgetByte ;-------------------------------------------------------------------------- ; Sec 3.3.4.3 LCD procedures LCD string write displayes ;-------------------------------------------------------------------------- LCDwrtStr ; W contains the string offset MOVWF LCDstrPtr; ; Erase upto 6 chars at end of string MOVLW 0x06 MOVWF LCDeraseCnt ; treat first Character as a Display Command - normally cursor position CALL LCDclearLeftTop GOTO LCDwrtStr1 LCDwrtStrBL ; W contains the string offset MOVWF LCDstrPtr; ; Erase upto 6 chars at end of string MOVLW 0x06 MOVWF LCDeraseCnt ; treat first Character as a Display Command - normally cursor position CALL LCDclearLeftBottom GOTO LCDwrtStr1 LCDwrtStrBR ; W contains the string offset MOVWF LCDstrPtr; ; Erase upto 6 chars at end of string MOVLW 0x06 MOVWF LCDeraseCnt ; treat first Character as a Display Command - normally cursor position CALL LCDclearRightBottom GOTO LCDwrtStr1 LCDaddStr MOVWF LCDstrPtr; ; Erase upto 6 chars at end of string MOVLW 0x06 MOVWF LCDeraseCnt LCDwrtStr1 CALL LCDgetByte BTFSC LCDPortB,LCDgetCharFlag GOTO LCDwrtStrFlush CALL LCDwrtChar GOTO LCDwrtStr1 ; write 10 chars to blank rest of right LCDwrtStrFlush ; W contains the number of Chars to flush LCDwrtStrLoop DECFSZ LCDeraseCnt,f GOTO LCDwrtStrLoop1 RETURN LCDwrtStrLoop1 MOVLW 0x20 CALL LCDwrtChar GOTO LCDwrtStrLoop ;-------------------------------------------------------------------------- ; Sec 3.3.1 LCD introduction ;-------------------------------------------------------------------------- ;LCD Information ;================== ; ;Having brought a number of displays for a bargin price, and finding that the ;information provided was inadequate, this document summarizes what has been ;found out. ;-------------------------------------------------------------------------- ; Sec 3.3.2 LCD control line / hardware to port mapping equates ;-------------------------------------------------------------------------- ;EA-N16025AR uses a pair of NEC D7228G LCD chips ;=============================================== ;A later form of te chip is uPD16434 in 10299e10.pdf currently downloadable ;as a 1.8Mb scanned it data sheet. ; ;The NEC web page is http://www.nec.de/index2.htm. ; ;Looking from the Display side, the connector has 14 pins. ;I will number them from left to right ; ;[ DISPLAY ] ;[ ] ; ;14 13 12 11 10 9 8 7 6 5 4 3 2 1 ; ;LPT conn chip name ;db0 14 27 D0 SI I,O ;db1 13 28 D1 P/-S I,O Data 1 or Parrallel /serial mode ;db2 12 29 D2 CAE I,O ;db3 11 30 +D3 S0 I,O ;NC 10 32 /BUSY O ;db5 9 35 /STB /SCK I Strobes each nibble into chip ;db6 8 36 C /D I Command /data 1 for command, 0 for data and reading ;db4 6 39 /CS I Selects the display ;db7 7 40 RESET I RESET ;clk 5 41 CLOCK I ;NC 4 CASE ;-ve 3 - Vlcd ;gnd 2 34 Vss GND ;+4.5V 1 33 Vdd +ve ;The D7228G can be programmed Parrallel or serially. ;} ; { The Epson EA-N 16025AR uses 2 NEC D 7228G chip in a pair } LCDbitNSTB equ 0; { 0; /Strobe } LCDbitCND equ 1; { 1; Command /DATA} LCDbitNCS equ 2; { 2; } LCDbitRESETline equ 3; { 3; } LCDbitD0 equ 4; { 4; } LCDbitD1 equ 5; { 5; } LCDbitD2 equ 6; { 6; } LCDbitD3 equ 7; { 7; } LCDbitSI equ LCDbitD0; { 4; Serial Input } LCDbitPNS equ LCDbitD1; { 5; select parrallel/-Serial on falling RESETline } LCDbitCAE equ LCDbitD2; { 6; Chip Address Enable ( for serial mode only ) } LCDbitSO equ LCDbitD3; { 7; Serial Output } LCDbitCA0 equ LCDbitD0; { 4; CA = chip select, CAE enabled or always during parrallel } LCDbitCA1 equ LCDbitD1; { 5; if D0,D1 = CA0,CA1 pins as STRB goes low } NSTB equ 1 << LCDbitNSTB ;{ 0; /Strobe } CND equ 1 << LCDbitCND ;{ 1; Command /DATA} NCS equ 1 << LCDbitNCS ;{ 2; } RESETline equ 1 << LCDbitRESETline ;{ 3; } D0 equ 1 << LCDbitD0 ; { 0; } D1 equ 1 << LCDbitD1 ; { 1; } D2 equ 1 << LCDbitD2 ; { 2; } D3 equ 1 << LCDbitD3 ; { 3; } SI equ D0; { 0; Serial Input } PNS equ D1; { 1; select parrallel/-Serial on falling RESETline } CAE equ D2; { 2; Chip Address Enable ( for serial mode only ) } SO equ D3; { 3; Serial Output } CA0 equ D0; { 0; CA = chip select, CAE enabled or always during parrallel } CA1 equ D1; { 1; if D0,D1 = CA0,CA1 pins as STRB goes low } CA03 equ D1 | D0 NUM_OF_CHARS equ 8 LCDgetCharFlag equ LCDbitCA1 ;-------------------------------------------------------------------------- ; Sec 3.3.2 LCD command equates ;-------------------------------------------------------------------------- ; { Commands } ; { Set Frame Frequency } SFF_0 equ 0x10; { div 2^14 } SFF_1 equ 0x11; SFF_2 equ 0x12; SFF_3 equ 0x13; SFF_4 equ 0x14; { div 2^10 } ;{ Set Multiplexing Mode } ;{ ;| ; The two chips work together. ;| ; The sync pins are joined together. ;| ; Configure sync as output on one chip, and IP on the others ;| ; Select the Chip by putting the CA on DB0,DB1 ;| ; during falling edge of NSTB. ;| ;|; The nibbles of the data are read in on rising edge of NSTB ;| ;|; The display forms four segments. ;| R0-R7 [ ][ ] ;| R8-R15 [ ][ ] ;| C0-C49 C0-C49 ;| CA=0, CA=3 ;| Row pins are either R0 to R7 or R8 to R15. ;| Col pins 42 to 49 can be configured to be R8 to R15 ;| The SMM command confiures these ;} SMM equ 0x18; { See Data Sheet } ;{ ;SMM_8_R07_C42_ip_mem0 = $18+0; ;SMM_8_R07_C42_ip_mem1 = $18+1; ;SMM_8_R07_C42_op_mem0 = $18+2; ;SMM_8_R07_C42_op_mem1 = $18+3; ;SMM_16_R815_C42_ip_mem0 = $18+4; ;SMM_16_R815_C42_ip_mem1 = $18+5; ;SMM_16_R07_C42_op_mem0 = $18+6; ;SMM_16_R07_R158_op_mem1 = $18+7; ;{ Display On } DISP_ON equ 0x09; ;{ Display Off } DISP_OFF equ 0x08; ;{ Load Data Pointer Immediate } LDPI equ 0x80; { There are two banks, add $40 for Bank 1 } ; { In Char mode the pointer increments by 5} LCDCurX1Y0 equ 5*NUM_OF_CHARS-1 SRM equ 0x60; { Set Read Mode } ;{ Set Write Mode - The LSB is top pixel, the MSB is pixel in cursor } SWM equ 0x64; { Set Write mode - replace } SORM equ 0x68; { Set OR mode - OR new bits with those present } SANDM equ 0x6C; { Set AND mode - AND new bits with those present } ;{ Add to SWM,SORM,SANDM,BRESET,BSET, to change Data Pointer } INC equ 0; DEC equ 1; EQUAL equ 3; ;{ Character Commands - The data causes a Char to be copied to screen } SCML equ 0x71; { Set Char mode, copy Char from Char rom } SCMR equ 0x72; ;{ Bit Commands, BIT to be set needs to be x 4 then added } BRESET equ 0x20; BSET equ 0x40; ;{ When in Char mode the cursor is set or cleared } CLCURS equ 0x7C; WRCURS equ 0x7D; ; These are similar, but are not the same, and need modifying LCDCurOn equ WRCURS LCDCurOff equ CLCURS ;{ put the display into sleep mode } STOP equ 0x01; ;-------------------------------------------------------------------------- ; Sec 3.3.4 LCD procedures ;-------------------------------------------------------------------------- ;-------------------------------------------------------------------------- ; Sec 3.3.4.1 LCD procedures - Multi entry display procedure for commands, nibbles,bytes,chars ;-------------------------------------------------------------------------- LCDdispByte MOVWF LCDnibble ; Display top nipple SWAPF LCDnibble,w CALL LCDwrtDecNibble ; Display bottom nipple MOVFW LCDnibble CALL LCDwrtDecNibble RETURN LCDwrtCmd BSF LCDcntrl,LCDbitCND GOTO LCDwrtByte LCDwrtDecNibble ; currently only displays 0..9, A..F ANDLW 0x0F ADDLW 0x06 ; is it A..F, if so trigger a digit overflow SKPNDC ADDLW 7; subtract 10, then add 'A'-'0' ADDLW 0x30-6 ; Subtract extra 6 added to cause DC ; MOVWF SRout ; CALL SRtxChar LCDwrtChar BCF LCDcntrl,LCDbitCND GOTO LCDwrtByte LCDwrtData BCF LCDcntrl,LCDbitCND GOTO LCDwrtByte LCDreset ; { Select Parrallel mode ; RESET -----______ When RESET is goes low sample line ; P/-S ----------- ; CAE ----------- only used in serial mode. ; CS ------------ I think that it should be high ; } movlw NSTB | PNS | CAE | NCS ; movwf PORTB ; now set the LCDbitRESETline BSF PORTB,LCDbitRESETline BCF PORTB,LCDbitRESETline RETURN LCDwrtByte ;Port B ;0 CS ---___________________-- Chip Select ;4,7 D0,D3----CA---DDD--CA--DDD--- Data Lines or CA lines ;1 STRB -----_____-----____----- Strobe ;2 CND =x====================x= Command/ not data ;3 RESET________________________ Reset ; 0 123 45 67 89 A ; On entry, assume CND set up on PORTB ; There are two words. - LCDdata and LCDcntrl ; These words store the byte to be displayed. ; LCDcntrl keeps the state of the Cmommand/Data line ; and which uPD7228G chip is being displayed. ; LCDwrtByte ; set up PORTB<0:7> to Outputs BSF STATUS, RP0 CLRF TRISB BCF STATUS, RP0 ; on entry W contains the byte ; and LCDcntlr,CA0 has been set for Chip CA= 3, and reset for CA=0 ; and LCDcntrl,CND has been set for Command or Data MOVWF LCDdata ; CND set up movlw NSTB | NCS btfsc LCDcntrl,LCDbitCA0 IORLW CA03 btfsc LCDcntrl,LCDbitCND IORLW CND MOVWF PORTB ; this should drive CS and RESETline low NOP BCF PORTB,LCDbitNCS NOP BCF PORTB,LCDbitNSTB NOP ; Now write the high nibble MOVFW LCDdata ANDLW 0xF0 btfsc LCDcntrl,LCDbitCND IORLW CND MOVWF PORTB NOP BSF PORTB,LCDbitNSTB NOP ; CND set up movlw NSTB btfsc LCDcntrl,LCDbitCA0 IORLW CA03 btfsc LCDcntrl,LCDbitCND IORLW CND MOVWF PORTB ; this should drive CS and RESETline low NOP BCF PORTB,LCDbitNSTB ; Now write the low nibble SWAPF LCDdata,w ANDLW 0xF0 btfsc LCDcntrl,LCDbitCND IORLW CND MOVWF PORTB NOP BSF PORTB,LCDbitNSTB BSF PORTB,LCDbitNCS NOP ; set up PORTB<0:3> to Outputs,PORTB<4:7> to Inputs BSF STATUS, RP0 MOVLW 0xF0 MOVWF TRISB BCF STATUS, RP0 ; Now clear Bit change bits. RETURN ;-------------------------------------------------------------------------- ; Sec 3.3.4.2 LCD procedures - Initilization ;-------------------------------------------------------------------------- LCDstart ; set up PORTB<0:7> to Outputs BSF STATUS, RP0 CLRF TRISB BCF STATUS, RP0 ; wlcdReset; ; { Select Parrallel mode ; RESET -----______ When RESET is goes low sample line ; P/-S ----------- ; CAE ----------- only used in serial mode. ; CS ------------ I think that it should be high ; } movlw NSTB | PNS | CAE | NCS ; movwf PORTB ; now set the RESETline BSF PORTB,LCDbitRESETline NOP NOP NOP BCF PORTB,LCDbitRESETline ; Select Right Chip BCF LCDcntrl,LCDbitCA0 ; Configure left chip as the master, sync is output ; LCD system reset MOVLW SMM + 7 ; set Sync pin to output CALL LCDwrtCmd MOVLW SFF_0 CALL LCDwrtCmd MOVLW DISP_ON CALL LCDwrtCmd ; Select Left Chip BSF LCDcntrl,LCDbitCA0 ; LCD system reset MOVLW SMM + 4 ; set Sync pin to input CALL LCDwrtCmd MOVLW SFF_0 CALL LCDwrtCmd MOVLW DISP_ON CALL LCDwrtCmd CALL LCDclearLeftTop MOVLW 'L' CALL LCDwrtData MOVLW 'o' CALL LCDwrtData MOVLW 'g' CALL LCDwrtData MOVLW 'i' CALL LCDwrtData MOVLW 'P' CALL LCDwrtData MOVLW 'i' CALL LCDwrtData MOVLW 'c' CALL LCDwrtData MOVLW ' ' CALL LCDwrtData CALL LCDclearRightTop MOVLW 'A' CALL LCDwrtData MOVLW 'n' CALL LCDwrtData MOVLW 'a' CALL LCDwrtData MOVLW 'l' CALL LCDwrtData MOVLW 'y' CALL LCDwrtData MOVLW 's' CALL LCDwrtData MOVLW 'e' CALL LCDwrtData MOVLW 'r' CALL LCDwrtData CALL LCDclearLeftBottom MOVLW '(' CALL LCDwrtData MOVLW 'c' CALL LCDwrtData MOVLW ')' CALL LCDwrtData MOVLW ' ' CALL LCDwrtData MOVLW '1' CALL LCDwrtData MOVLW '9' CALL LCDwrtData MOVLW '9' CALL LCDwrtData MOVLW '9' CALL LCDwrtData CALL LCDclearRightBottom MOVLW ' ' CALL LCDwrtData MOVLW 'D' CALL LCDwrtData MOVLW 'H' CALL LCDwrtData MOVLW ' ' CALL LCDwrtData MOVLW 'R' CALL LCDwrtData MOVLW 'i' CALL LCDwrtData MOVLW 'c' CALL LCDwrtData MOVLW 'e' CALL LCDwrtData RETURN MOVLW 10 MOVWF LCDcnt ; now write some characters LCDloop5 MOVLW 0x20 CALL LCDwrtChar DECFSZ LCDcnt,f GOTO LCDloop5 ; LCD Cursor Home MOVLW LCDCurX1Y0 CALL LCDwrtCmd MOVLW 10 MOVWF LCDcnt LCDloop6 MOVLW 0x20 CALL LCDwrtChar DECFSZ LCDcnt,f GOTO LCDloop6 LCDloop2A ; Now actually display something ; MOVLW LCDstrLTime ; CALL LCDwrtStr RETURN LCDclearLeftTop ; Now clear the display ;Select Left Chip BSF LCDcntrl,LCDbitCA0 goto LCDclearAtop LCDclearRightTop ; Now clear the display ;Select Left Chip BCF LCDcntrl,LCDbitCA0 LCDclearAtop MOVLW LDPI + 5*NUM_OF_CHARS -1 GOTO LCDclearAquarter LCDclearLeftBottom ; Now clear the display ;Select Left Chip BSF LCDcntrl,LCDbitCA0 goto LCDclearAbottom LCDclearRightBottom ; Now clear the display ;Select Left Chip BCF LCDcntrl,LCDbitCA0 LCDclearAbottom MOVLW LDPI + 5*NUM_OF_CHARS -1 + 0x40 LCDclearAquarter MOVWF LCDcursorStart CALL LCDwrtCmd MOVLW SCML CALL LCDwrtCmd MOVLW 10 MOVWF LCDcnt2 LCDloop7 MOVLW CLCURS CALL LCDwrtCmd DECFSZ LCDcnt2,f GOTO LCDloop7 ; Move Cursor to start MOVFW LCDcursorStart CALL LCDwrtCmd RETURN ;-------------------------------------------------------------------------- ; END OF FILE ;--------------------------------------------------------------------------