Mercurial > public > mk2
diff code_part1/OSTC_code_asm_part1/oled_samsung.asm @ 142:8b75ba28d641
Screen-flipping custom function.
- Fix bank safe addressings.
author | JeanDo |
---|---|
date | Fri, 07 Jan 2011 03:01:02 +0100 |
parents | d721b49b8934 |
children | c09b0be2e1e6 |
line wrap: on
line diff
--- a/code_part1/OSTC_code_asm_part1/oled_samsung.asm Thu Jan 06 18:36:22 2011 +0100 +++ b/code_part1/OSTC_code_asm_part1/oled_samsung.asm Fri Jan 07 03:01:02 2011 +0100 @@ -18,9 +18,11 @@ ; hardware routines for S6E6D6 Samsung OLED Driver IC ; written by: Matthias Heinrichs, info@heinrichsweikamp.com ; written: 090801 -; last updated: 090830 -; known bugs: -; ToDo: Optimise PLED_box calls +; History: +; 2009-08-30: [MH] last updated. +; 2011-01-07: [jDG] Added flip_screen option +; known bugs: pixel-write (loogbok curves) not done yet... +; ToDo: WIN_FONT macro win_font_input movlw win_font_input @@ -46,29 +48,31 @@ movlw win_color_input call PLED_set_color endm - + +;============================================================================= + word_processor: ; word_processor: - clrf POSTINC2 ; Required, to mark end of string. - call aa_wordprocessor - movlb b'00000001' ; Back to Rambank1 - return + clrf POSTINC2 ; Required, to mark end of string. + call aa_wordprocessor + movlb b'00000001' ; Back to Rambank1 + return -; ----------------------------- +;============================================================================= ; PLED_SetColumnPixel: -; ----------------------------- +; PLED_SetColumnPixel: - movff WREG,win_leftx2 ; d'0' ... d'159' - mullw 2 ; Copy to PROD, times 2. + movff WREG,win_leftx2 ; d'0' ... d'159' + mullw 2 ; Copy to PROD, times 2. - movlw 0x21 ; Start Address Vertical (.0 - .319) + movlw 0x21 ; Start Address Vertical (.0 - .319) rcall PLED_CmdWrite bra PLED_DataWrite_PROD -; ----------------------------- +;============================================================================= ; PLED_SetRow: ; Backup WREG --> win_top, for the next write pixel. ; Setup OLED pixel horizontal address. -; ----------------------------- +; PLED_SetRow: movff WREG,win_top ; d'0' ... d'239' mullw 1 ; Copy row to PRODH:L @@ -76,9 +80,9 @@ rcall PLED_CmdWrite bra PLED_DataWrite_PROD -; ----------------------------- +;============================================================================= ; PLED Write Two Pixel -; ----------------------------- +; PLED_PxlWrite: rcall PLED_PxlWrite_Single ; Write first pixel. @@ -125,28 +129,168 @@ return ;============================================================================= +; Fast macros to write to OLED display. +; Adding a call/return adds 3 words and a pipeline flush, hence make it +; nearly twice slower... +; +; Input : commande as macro parameter. +; Output : NONE +; Trash : WREG +; +AA_CMD_WRITE macro cmd + movlw cmd + rcall PLED_CmdWrite +; bcf oled_rs ; Cmd mode +; movwf PORTD,A +; bcf oled_rw ; Tick the clock +; bsf oled_rw + endm +; +; Input : PRODH:L as 16bits data. +; Output : NONE +; Trash : NONE +; +AA_DATA_WRITE_PROD macro + rcall PLED_DataWrite_PROD +; bsf oled_rs ; Data mode +; movff PRODH,PORTD ; NOTE: OLED is BIGENDIAN! +; bcf oled_rw ; Tick the clock +; bsf oled_rw +; movff PRODL,PORTD +; bcf oled_rw ; Tick the clock +; bsf oled_rw + endm + +;============================================================================= +; Output OLED Window Address commands. +; Inputs : win_top, win_leftx2, win_height, aa_width. +; Output : PortD commands. +; Trashed: PROD +; +PLED_box_write: + movff win_leftx2,WREG ; Compute left = 2*leftx2 --> PROD + mullw 2 + + movff win_flags,WREG ; BEWARE: bank0 bit-test + btfsc WREG,0 ; 180° rotation ? + bra PLED_box_flip_H ; YES: + + ;---- Normal horizontal window --------------------------------------- + ; Output 0x35 left, + ; 0x36 right == left + width - 1. + AA_CMD_WRITE 0x35 ; this is the left border + AA_DATA_WRITE_PROD ; Output left + AA_CMD_WRITE 0x21 ; Also the horizontal first pix coord. + AA_DATA_WRITE_PROD + + movf aa_width+0,W,ACCESS ; right = left + width - 1 + addwf PRODL,F + movf aa_width+1,W,ACCESS + addwfc PRODH,F + decf PRODL,F,A ; decrement result + btfss STATUS,C + decf PRODH,F,A + + AA_CMD_WRITE 0x36 ; Write and the right border + AA_DATA_WRITE_PROD + + bra PLED_box_noflip_H + + ;---- Flipped horizontal window -------------------------------------- +PLED_box_flip_H: + ; Output 0x36 flipped(left) = 319-left + ; 0x35 flipped(right) = 319-right = 320 - left - width + movf PRODL,W ; 16bits 319 - PROD --> PROD + sublw LOW(.319) ; 319-W --> W + movwf PRODL + movf PRODH,W + btfss STATUS,C ; Borrow = /CARRY + incf WREG + sublw HIGH(.319) + movwf PRODH + AA_CMD_WRITE 0x36 ; this is the left border + AA_DATA_WRITE_PROD ; Output left + AA_CMD_WRITE 0x21 + AA_DATA_WRITE_PROD + + movf aa_width+0,W ; 16bits PROD - width --> PROD + subwf PRODL,F ; PRODL - WREG --> PRODL + movf aa_width+1,W + subwfb PRODH,F + infsnz PRODL ; PROD+1 --> PROD + incf PRODH + AA_CMD_WRITE 0x35 ; this is the left border + AA_DATA_WRITE_PROD ; Output left + +PLED_box_noflip_H: + movff win_flags,WREG ; BEWARE: bank0 bit-test + btfsc WREG,0 ; 180° rotation ? + bra PLED_box_flip_V + + ;---- Normal vertical window ----------------------------------------- + ; Output 0x37 (top) (bottom) + movff win_top,PRODH ; top --> PRODH (first byte) + movff win_height,WREG + addwf PRODH,W + decf WREG + movwf PRODL ; top+height-1 --> PRODL (second byte) + + AA_CMD_WRITE 0x37 + AA_DATA_WRITE_PROD + + movff PRODH,PRODL + clrf PRODH ; Start pixel V coord == top. + AA_CMD_WRITE 0x20 + AA_DATA_WRITE_PROD + + return + + ;---- Flipped vertical window ---------------------------------------- + ; Output 0x37 flipped(bottom) = 239-bottom = 240 - top - height + ; flipped(top) = 239-top +PLED_box_flip_V: + movff win_top,PRODL + movff win_height,WREG + addwf PRODL,W + sublw .240 ; 240 - top - height + movwf PRODH ; First byte + + movf PRODL,W + sublw .239 ; 249-top + movwf PRODL ; --> second byte. + + AA_CMD_WRITE 0x37 + AA_DATA_WRITE_PROD + + clrf PRODH ; Start pixel V coord. + AA_CMD_WRITE 0x20 + AA_DATA_WRITE_PROD + + return + +;============================================================================= ; PLED_frame : draw a frame around current box with current color. ; Inputs: win_top, win_leftx2, win_height, win_width, win_color1, win_color2 ; Outputs: (none) ; Trashed: WREG, PROD, aa_start:2, aa_end:2, win_leftx2, win_width:1 -PLED_frame: - movff win_top,aa_start+0 ; Backup everything. +PLED_frame: + movff win_top,aa_start+0 ; Backup everything. movff win_height,aa_start+1 movff win_leftx2,aa_end+0 movff win_width,aa_end+1 ;---- TOP line ----------------------------------------------------------- - movlw 1 ; row ~ height=1 + movlw 1 ; row ~ height=1 movff WREG,win_height rcall PLED_box ;---- BOTTOM line -------------------------------------------------------- - movff aa_start+0,PRODL ; Get back top, - movff aa_start+1,WREG ; and height - addwf PRODL,W ; top+height - decf WREG ; top+height-1 - movff WREG,win_top ; top+height-1 --> top + movff aa_start+0,PRODL ; Get back top, + movff aa_start+1,WREG ; and height + addwf PRODL,W ; top+height + decf WREG ; top+height-1 + movff WREG,win_top ; top+height-1 --> top rcall PLED_box ;---- LEFT column -------------------------------------------------------- @@ -172,74 +316,46 @@ PLED_box: ;---- Define Window ------------------------------------------------------ - movlw 0x35 ; VerticalStartAddress HIGH:LOW - rcall PLED_CmdWrite - movff win_leftx2,WREG - mullw 2 - rcall PLED_DataWrite_PROD - - movlw 0x36 ; VerticalEndAddress HIGH:LOW - rcall PLED_CmdWrite - movff win_width,PRODL ; Bank-safe addressing - movff win_leftx2,WREG - addwf PRODL,W ; left+width - decf WREG ; left+width-1 - mullw 2 ; times 2 --> rightx2 - rcall PLED_DataWrite_PROD - - movlw 0x37 ; HorizontalAddress START:END - rcall PLED_CmdWrite - movff win_top,PRODH ; Start row. - movff win_height,PRODL ; height - movf PRODH,W - addwf PRODL,F ; top + height - decf PRODL,F ; top + height - 1 --> bottom. - rcall PLED_DataWrite_PROD - - ;---- Start pointer ------------------------------------------------------ - movlw 0x20 ; Start Address Horizontal (.0 - .239) - rcall PLED_CmdWrite - movff win_top,WREG - mullw 1 - rcall PLED_DataWrite_PROD - - movlw 0x21 ; Start Address Vertical (.0 - .319) - rcall PLED_CmdWrite - movff win_leftx2,WREG - mullw 2 - rcall PLED_DataWrite_PROD + movff win_width,WREG + bcf STATUS,C + rlcf WREG + movwf aa_width + movlw 0 + rlcf WREG + movwf aa_width+1 + rcall PLED_box_write ;---- Fill Window -------------------------------------------------------- - movlw 0x22 ; Start Writing Data to GRAM + movlw 0x22 ; Start Writing Data to GRAM rcall PLED_CmdWrite - movff win_height,PRODH - bsf oled_rs ; Data! + movff win_width,PRODH + bsf oled_rs ; Data! -PLED_box2: ; Loop height times - movff win_width,PRODL -PLED_box3: ; loop width times +PLED_box2: ; Loop height times + movff win_height,PRODL +PLED_box3: ; loop width times movff win_color1,PORTD bcf oled_rw - bsf oled_rw ; Upper + bsf oled_rw ; Upper movff win_color2,PORTD bcf oled_rw - bsf oled_rw ; Lower + bsf oled_rw ; Lower movff win_color1,PORTD bcf oled_rw - bsf oled_rw ; Upper + bsf oled_rw ; Upper movff win_color2,PORTD bcf oled_rw - bsf oled_rw ; Lower + bsf oled_rw ; Lower decfsz PRODL,F bra PLED_box3 decfsz PRODH,F bra PLED_box2 - movlw 0x00 ; NOP, to stop Address Update Counter - bra PLED_CmdWrite ; Returns... + movlw 0x00 ; NOP, to stop Address Update Counter + bra PLED_CmdWrite ; returns... ;============================================================================= ; PLED_ClearScreen: An optimized version of PLEX_box, for full screen black. @@ -375,9 +491,15 @@ movlw 0x03 ; Entry Mode (S6E63D6 Datasheet page 46) rcall PLED_CmdWrite - movlw 0x00 ; =b'00000000' CLS MDT1 MDT0 BGR X X X SS 65k Color + movlw 0x00 ; CLS MDT1 MDT0 BGR X X X SS 65k Color rcall PLED_DataWrite - movlw b'00110000' ; =b'00110000' X X I/D1 I/D0 X X X AM + + ; Change direction for block-writes of pixels + lfsr FSR0,win_flags + btfss INDF0,0 ; BANK-SAFE bit test. + movlw b'00110000' ; [normal] X X I/D1 I/D0 X X X AM + btfsc INDF0,0 + movlw b'00000000' ; [flipped] X X I/D1 I/D0 X X X AM rcall PLED_DataWrite movlw 0x18