; file: f12.asm ; ; 2010.09.11 ; Experiments in controlling a NOKIA 6610 display ; This one is from www.etteam.com and includes ; voltage regulator to be 5v only. ; ; The command set is 9-bit messages clocked with ; 2 PIO pins. ; ; ; Interesting aspects of the PIC12F509 include: ; * CALL instruction has 8 bit range, so subroutines ; must be in the first 256 instructions ; * GOTO instruction has 9 bit range, so jumps must ; be in the first 512 instructions ; * Ok, actually, you can use the STATUS bit 5 "PA0" ; to set bit *nine* before either a GOTO or a ; CALL. So with care you can GOTO anywhere, ; or CALL 0x000-0x0ff and 0x200-0x2ff. So two ; quadrants cannot be CALLed at all. ; * File registers 0x07-0x1F are accessible normally ; * File registers 0x30-0x3F accessible only by FSR/INDF. ; * Two level subroutine stack ; * No interrupts ; INCLUDE "P12F509.INC" INCLUDE "macross12f509.inc" ; config ; __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_ON & _IntRC_OSC ; available file registers 0x7-0x1f (25 registers) ; (there are more at 0x30-0x3f but only by ; FSR indirect addressing.) CBLOCK 0x07 rnd t0 t1 x y ; locals for subroutines d0 d1 d2 top left width height color rectCount ; we let the watchdog timer fly after enough rects cblock7End ENDC CBLOCK 0x30 cblock30End ; keep this last ENDC IF cblock30End > 0x40 ERROR "CBLOCK30 exceeded" ENDIF ORG 0 ; lets begin GOTO Start ; ; Delay for 256 * W cycles Delay: MOVWF t1 _delay1: DECFSZ t0,f GOTO _delay1 DECFSZ t1,f GOTO _delay1 RETLW 0 DoDelay MACRO _delay MOVLW _delay CALL Delay ENDM NokClkBit EQU 0 NokDatBit EQU 1 NokRstBit EQU 2 ;active low NokClkDown MACRO BCF GPIO,NokClkBit ENDM NokClkUp MACRO BSF GPIO,NokClkBit ENDM NokDat0 MACRO BCF GPIO,NokDatBit ENDM NokDat1 MACRO BSF GPIO,NokDatBit ENDM NokDatC MACRO BCF GPIO,NokDatBit IFBS STATUS,C BSF GPIO,NokDatBit ENDM ; emit W as a command to the Nokia SendNokCmd: MOVWF d0 NokClkDown NokDat0 NokClkUp NokClkDown GOTO Nok8 ; emit W as data to the Nokia LCD SendNokDat: MOVWF d0 NokDat1 NokClkUp NokClkDown Nok8: ; clock out the eight bits i = 0 WHILE i < 8 RLF d0,f NokDatC NokClkUp NokClkDown i += 1 ENDW RETLW 0 NokCmd MACRO _cmd MOVLW _cmd CALL SendNokCmd ENDM NokDatF MACRO _datf MOVFW _datf CALL SendNokDat ENDM NokDat MACRO _dat MOVLW _dat CALL SendNokDat ENDM ; Nokia Commands ; philips command set, see http://www.nxp.com/acrobat_download2/datasheets/PCF8833_1.pdf Nok_SLEEPOUT EQU 0x11 Nok_INVON EQU 0x20 Nok_COLMOD EQU 0x3a ; data 3:12bits/pixel, 2:8bits/pixel Nok_MADCTL EQU 0x36 ; data: misc control bits Nok_SETCON EQU 0x25 ; data: contrast, 0x30 typical? Nok_DISPON EQU 0x29 ; display on Nok_RGBSET EQU 0x2d ; data: 20 bytes defining rrrgggbb ranges Nok_PASET EQU 0x2b ; data: lowest & highest pixel row to work with Nok_CASET EQU 0x2a ; data: lowest & highest pixel col to work with Nok_RAMWR EQU 0x2c ; any amt of data into rectangle, in current COLMOD format Start: ADDLF 0x3,rnd ; All five outputs to "out" ; GPIO 3 can only be "in" MOVLW 0 TRIS GPIO MOVLW b'11011111' ; 0xDF OPTION CLRF GPIO CLRF rectCount ; do some stream-of-cmds to the Nok BCF GPIO,NokRstBit DoDelay 2 BSF GPIO,NokRstBit DoDelay 2 ; philips init sequence, cribbed from http://www.sparkfun.com/tutorial/Nokia%206100%20LCD%20Display%20Driver.pdf NokCmd Nok_SLEEPOUT NokCmd Nok_INVON NokCmd Nok_COLMOD NokDat 2 ; 8-bit color NokCmd Nok_MADCTL NokDat 0xc8 NokCmd Nok_SETCON NokDat 0x48 ; DoDelay 10 NokCmd Nok_DISPON ; DoDelay 10 ; NokCmd Nok_RGBSET ; red tab, 3 bit ; NokDat b'00000000' ; NokDat b'00000010' ; NokDat b'00000100' ; NokDat b'00000110' ; NokDat b'00001001' ; NokDat b'00001011' ; NokDat b'00001101' ; NokDat b'00001111' ; green tab, 3 bit ; NokDat b'00000000' ; NokDat b'00000010' ; NokDat b'00000100' ; NokDat b'00000110' ; NokDat b'00001001' ; NokDat b'00001011' ; NokDat b'00001101' ; NokDat b'00001111' ; blue tab, 2 bit ; NokDat b'00000000' ; NokDat b'00000101' ; NokDat b'00001010' ; NokDat b'00001111' NokCmd Nok_CASET NokDat 0x4 NokDat 0x80 NokCmd Nok_PASET NokDat 0x20 NokDat 0x60 MOVLF 0,top MOVLF 0,left MOVLF 132,width MOVLF 132,height MOVLF b'1110011',color CALL Rect Rects: RANDF top,0x7f,0 RANDF left,0x7f,0 RANDF height,0x1f,1 RANDF width,0x1f,1 MOVFF height,width RANDF color,0xff,0 CALL Rect IFBC rectCount,7 INCF rectCount,f ; stop clearing the watchdog after a while. ; we like the occasional reset to perturb rand. IFBC rectCount,7 CLRWDT GOTO Rects Rect: ; let height,width be 0 here, increment later ; CASET & PASET are inclusive DECF height DECF width NokCmd Nok_PASET NokDatF top MOVFW top ADDWF height,w CALL SendNokDat NokCmd Nok_CASET NokDatF left MOVFW left ADDWF width,w CALL SendNokDat INCF height INCF width NokCmd Nok_RAMWR MOVFF width,x _rects_a: MOVFF height,y _rects_b: NokDatF color DECFSZ y,f GOTO _rects_b DECFSZ x,f GOTO _rects_a RETLW 0 SPIN: GOTO SPIN END