comparison src/tft.asm @ 0:11d4fc797f74

init
author heinrichsweikamp
date Wed, 24 Apr 2013 19:22:45 +0200
parents
children eb72c8865f47
comparison
equal deleted inserted replaced
-1:000000000000 0:11d4fc797f74
1 ;=============================================================================
2 ;
3 ; File tft.asm
4 ;
5 ; Managing the TFT screen
6 ;
7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
8 ;=============================================================================
9 ; HISTORY
10 ; 2011-05-24 : [jDG] Cleanups from initial Matthias code.
11
12 #include "ostc3.inc"
13 #include "wait.inc"
14 #include "varargs.inc"
15 #include "external_flash.inc"
16 #include "tft_outputs.inc"
17 #include "eeprom_rs232.inc"
18
19 ;=============================================================================
20 ; TFT_frame needs to backup coordinates.
21 CBLOCK tmp
22 save_top
23 save_height
24 save_left
25 save_width
26 ds_line ; Current line (0..239).
27 ds_column ; Current columnx2 (0..159)
28 ds_pixel:2 ; Current pixel color.
29 ds_count ; Repetition count.
30 ENDC
31
32 ;=============================================================================
33 ; Basic bit-level macros
34
35 RD_H macro
36 bsf tft_rd,0
37 endm
38
39 RD_L macro
40 bcf tft_rd,0
41 endm
42
43 RS_H macro
44 bsf tft_rs,0
45 endm
46
47 RS_L macro
48 bcf tft_rs,0
49 endm
50
51 NCS_H macro
52 bsf tft_cs,0
53 endm
54
55 NCS_L macro
56 bcf tft_cs,0
57 endm
58
59 WR_H macro
60 bsf tft_nwr,0
61 endm
62
63 WR_L macro
64 bcf tft_nwr,0
65 endm
66
67 ;=============================================================================
68 ; Byte-leve macros
69 ;
70 Index_out macro low_b
71 movlw low_b
72 rcall TFT_CmdWrite
73 endm
74
75 Parameter_out macro high_b, low_b
76 movlw high_b
77 movwf PORTA ; Upper
78 movlw low_b
79 rcall TFT_DataWrite
80 endm
81
82
83 basic CODE
84
85
86 ;=============================================================================
87 ; TFT_write_flash_image
88 ;
89 ; Inputs: FSR2 = EEPROM address / 256
90 ; win_left, win_top : imagte CENTER position
91 ; Outputs: win_height, win_width.
92 ; image copyed on screen.
93 ; Trashed: PROD, hi, lo
94 ;
95 global TFT_write_flash_image
96 TFT_write_flash_image:
97 ; Get back the full 24bit EEPROM address
98 clrf ext_flash_address+0
99 movff FSR2L,ext_flash_address+1
100 movf FSR2H,W
101 iorlw 0x30
102 movwf ext_flash_address+2
103
104 ; Read header: width and height
105 global TFT_write_flash_image_addr
106 TFT_write_flash_image_addr:
107 call ext_flash_read_block_start
108 movff SSP2BUF,win_width+0
109 movwf SSP2BUF ; Write to buffer to initiate new read
110 btfss SSP2STAT, BF ; Next byte ready ?
111 bra $-2 ; NO: wait...
112 movff SSP2BUF,win_width+1
113 movwf SSP2BUF ; Write to buffer to initiate new read
114 btfss SSP2STAT, BF ; Next byte ready ?
115 bra $-2 ; NO: wait...
116 movff SSP2BUF,win_height
117 movwf SSP2BUF ; Write to buffer to initiate new read
118 btfss SSP2STAT, BF ; Next byte ready ?
119 bra $-2 ; NO: wait...
120 movff SSP2BUF,WREG ; drop 4th byte.
121 movwf SSP2BUF ; Write to buffer to initiate new read
122 btfss SSP2STAT, BF ; Next byte ready ?
123 bra $-2 ; NO: wait...
124
125 ; Sanity check on header to avoid badly uploaded images.
126 iorwf WREG ; Check height < 256
127 bnz TFT_write_flash_image_failed
128 movf win_width+1,W ; Check width < 512
129 andlw 0xFE
130 bnz TFT_write_flash_image_failed
131
132 ; Center image on win_top, win_left values
133 bcf STATUS,C ; Clear carry
134 rrcf win_height,W ; And get height/2
135 subwf win_top,F ; top -= height/2
136 rrcf win_width+1,W ; Get 9th bit into carry
137 rrcf win_width+0,W ; Get width/2 (in 0..320 range)
138 bcf STATUS,C
139 rrcf WREG,W ; Get width/2 in 0..160 range
140 subwf win_leftx2,F ; left -= width/2
141
142 rcall TFT_box_write ; Inputs : win_top, win_leftx2, win_height, win_width(in 1..320 range)
143
144 ; Compute number of pixels to move (result on 17 bits !)
145 clrf TBLPTRU
146 movf win_width+0,W
147 mulwf win_height ; Result in PRODL:H
148 movf win_width+1,W
149 bz TFT_write_flash_image_1 ; width > 8bits ?
150 movf win_height,W ; YES: add extra
151 addwf PRODH,F
152 rlcf TBLPTRU ; And carry into upper register.
153 TFT_write_flash_image_1:
154 incf PRODH,F ; Pre-condition nested loops
155 incf TBLPTRU,F
156
157 ; Write pixels
158 Index_out 0x22 ; Frame Memory Data Write start
159 RS_H ; Data
160
161 TFT_write_flash_image_loop:
162 btfss SSP2STAT, BF ; Buffer full?
163 bra $-2 ; NO: wait...
164 movff SSP2BUF,PORTH ; Read lo
165 movwf SSP2BUF ; Write to buffer to initiate new read
166
167 btfss SSP2STAT, BF ; Buffer full?
168 bra $-2 ; NO: wait...
169 movff SSP2BUF,PORTA ; And read hi
170 movwf SSP2BUF ; Write to buffer to initiate new read
171 WR_L
172 WR_H ; Write 1 Pixel
173
174 decfsz PRODL,F
175 bra TFT_write_flash_image_loop
176 decfsz PRODH,F
177 bra TFT_write_flash_image_loop
178 decfsz TBLPTRU,F
179 bra TFT_write_flash_image_loop
180
181 btfss SSP2STAT, BF ; Buffer full?
182 bra $-2 ; No, wait
183 movf SSP2BUF,W ; Read dummy byte
184
185 bsf flash_ncs ; CS=1
186 movlw 0x00 ; NOP, to stop window mode
187 bra TFT_CmdWrite ; This routine "returns"
188
189 ;---- Draw a 4x4 red square in place of missing images...
190 TFT_write_flash_image_failed:
191 movlw -1
192 addwf win_leftx2,F
193 movlw -2
194 addwf win_top,F
195 movlw 2
196 movwf win_width+0
197 clrf win_width+1
198 movlw 4
199 movwf win_height
200 movlw color_red
201 rcall TFT_set_color
202 goto TFT_box
203
204 ;=============================================================================
205 ;
206
207 global TFT_CmdWrite
208 TFT_CmdWrite:
209 RS_L ; Command
210 clrf PORTA ; Upper
211 movwf PORTH ; Lower
212 WR_L
213 WR_H ; Tick
214 return;
215
216 global TFT_DataWrite
217 TFT_DataWrite:
218 RS_H ; Data
219 movwf PORTH ; Lower
220 WR_L
221 WR_H ; Tick
222 return
223
224 ;=============================================================================
225 ;
226 global TFT_ClearScreen
227 TFT_ClearScreen:
228 Index_out 0x50 ; Window Horizontal Start Address
229 Parameter_out 0x00, 0x00 ; 0-239
230 Index_out 0x51 ; Window Horizontal End Address
231 Parameter_out 0x00, 0xEF ; 0-239
232 Index_out 0x52 ; Window Vertical Start Address
233 Parameter_out 0x00, 0x00 ; 0-319
234 Index_out 0x53 ; Window Vertical End Address
235 Parameter_out 0x01, 0x3F ; 0-319
236 Index_out 0x20 ; Frame Memory Horizontal Address
237 Parameter_out 0x00, 0x00 ; 0-239
238 Index_out 0x21 ; Frame Memory Vertical Address
239 Parameter_out 0x01, 0x3F ; 0-319
240
241 Index_out 0x22 ; Frame Memory Data Write start
242
243 RD_H ; Not Read
244 RS_H ; Data
245 NCS_L ; Not CS
246 clrf PORTA ; Data Upper
247 clrf PORTH ; Data Lower
248
249 movlw d'10'
250 movwf tft_temp3
251 TFT_ClearScreen2:
252 movlw d'30'
253 movwf tft_temp2
254 TFT_ClearScreen3:
255 clrf tft_temp1 ; 30*10*256=76800 Pixels -> Clear complete 240*320
256 TFT_ClearScreen4:
257 WR_L
258 WR_H ; Tick
259 decfsz tft_temp1,F
260 bra TFT_ClearScreen4
261 decfsz tft_temp2,F
262 bra TFT_ClearScreen3
263 decfsz tft_temp3,F
264 bra TFT_ClearScreen2
265 return
266
267 ;=============================================================================
268 ;
269 global TFT_DisplayOff
270 TFT_DisplayOff:
271 clrf CCPR1L ; PWM OFF
272 clrf PORTA
273 clrf PORTH
274 RD_L ; LOW
275 nop
276 RS_L ; LOW
277 bcf tft_nwr
278 nop
279 bcf tft_cs
280 nop
281 bcf tft_nreset
282 WAITMS d'1'
283 bsf tft_power ; inverted...
284 bcf lightsen_power ; power-down light sensor
285 return
286
287 ; -----------------------------
288 ; TFT boot
289 ; -----------------------------
290 global TFT_boot
291 TFT_boot:
292 clrf PORTA
293 clrf PORTH
294 RD_L ; LOW
295 bcf tft_nwr
296 nop
297 bcf tft_cs
298 nop
299 bcf tft_nreset
300 WAITMS d'1'
301 bcf tft_power ; inverted...
302 WAITMS d'1'
303
304 RD_H ; Keep high
305 WR_H ;
306 NCS_L ; Not CS
307
308 WAITMS d'2'
309 bsf tft_nreset
310 WAITMS d'150'
311 bsf lightsen_power ; Supply power to light sensor
312
313 ; Data Transfer Synchronization
314 Parameter_out 0x00, 0x00
315 Parameter_out 0x00, 0x00
316
317 ; Init through config table...
318 movlw LOW display0_config_table
319 movwf TBLPTRL
320 movlw HIGH display0_config_table
321 movwf TBLPTRH
322 movlw UPPER display0_config_table
323 movwf TBLPTRU
324 rcall display0_init_loop
325
326 Index_out 0x22
327 ; WAITMS d'81' ; 46
328 call TFT_ClearScreen
329 Index_out 0x07
330 Parameter_out 0x01, 0x00
331 return
332
333
334 display0_config_table:
335 ; Reg, Dat0, Dat1 or 0xFF,0x00,0x00 for end
336 db 0xA4,0x00,0x01,0xFF,.002,0x00
337 db 0x09,0x00,0x01,0x92,0x04,0x00
338 db 0x93,0x04,0x02,0x94,0x00,0x02
339 db 0x07,0x00,0x00,0x10,0x04,0x30
340 db 0x11,0x02,0x37,0x12,0x11,0x8D
341 db 0x13,0x11,0x00,0x01,0x01,0x00
342 db 0x02,0x02,0x00,0x03,0x50,0x20
343 db 0x0A,0x00,0x08,0x0D,0x00,0x00
344 db 0x0E,0x00,0x30,0xFF,.151,0x00
345 db 0x12,0x11,0xBD,0x20,0x00,0x00
346 db 0x21,0x00,0x00,0x30,0x06,0x02
347 db 0x31,0x56,0x0D,0x32,0x05,0x07
348 db 0x33,0x06,0x09,0x34,0x00,0x00
349 db 0x35,0x09,0x06,0x36,0x57,0x05
350 db 0x37,0x0D,0x06,0x38,0x02,0x06
351 db 0x39,0x00,0x00,0xFF,0x00,0x00
352
353 display0_init_loop:
354 TBLRD*+
355 movlw 0xFF
356 cpfseq TABLAT
357 bra display0_config_write ; Write Config pair to Display
358 ; Delay ms or quit (return)
359 TBLRD*+
360 tstfsz TABLAT ; End of config?
361 bra $+4 ; No
362 return ; Done.
363 movf TABLAT,W
364 call WAITMSX ; Wait WREG milliseconds
365 TBLRD*+ ; Dummy read (Third byte of delay command)
366 bra display0_init_loop ; Loop
367
368 display0_config_write: ; With command in WREG
369 movf TABLAT,W
370 rcall TFT_CmdWrite ; Write command
371 TBLRD*+ ; Get config0
372 movff TABLAT,PORTA
373 TBLRD*+ ; Get config1
374 movf TABLAT,W
375 rcall TFT_DataWrite ; Write config
376 bra display0_init_loop ; Loop
377
378
379 ;=============================================================================
380 ; Smooth lighting-up of the display:
381 ;
382 ; Trashes: WREG, PRODL
383 ; Typical usage:
384 ; clrf CCPR1L ; Backlight off
385 ; [draw splash screen]
386 ; call TFT_DisplayFadeIn
387 ;
388 global TFT_Display_FadeIn
389 TFT_Display_FadeIn:
390 movlw CCP1CON_VALUE ; See ostc3.inc
391 movwf CCP1CON
392 bsf tft_is_dimming ; TFT is dimming, ignore ambient sensor!
393 clrf CCPR1L ; Backlight off - to be sure
394 movff max_CCPR1L,PRODL
395 TFT_Display_FadeIn_0:
396 incf CCPR1L,F ; Duty cycle
397 WAITMS d'2'
398 decfsz PRODL,F
399 bra TFT_Display_FadeIn_0
400 bcf tft_is_dimming ; dimming done.
401 return
402
403 ;=============================================================================
404 ; Smooth lighting-off of the display:
405 ; Trashes: WREG, PRODL
406 global TFT_Display_FadeOut
407 TFT_Display_FadeOut:
408 movff max_CCPR1L,PRODL
409 bsf tft_is_dimming ; TFT is dimming, ignore ambient sensor!
410 TFT_Display_FadeOut_0:
411 movff PRODL,CCPR1L ; Duty cycle
412 WAITMS d'1'
413 decfsz PRODL,F
414 bra TFT_Display_FadeOut_0
415 clrf CCPR1L
416 return
417
418 ;=============================================================================
419
420 start_common:
421 VARARGS_BEGIN
422 VARARGS_GET8 win_leftx2
423 VARARGS_GET8 win_top
424 VARARGS_END
425 return
426
427 ;=============================================================================
428
429 global box_std_block, box_black_block, box_color_block
430
431 box_std_block: ; Use white color
432 setf WREG
433 bra box_common
434 box_black_block: ; Use black color
435 clrf WREG
436 box_common:
437 box_color_block:
438 rcall TFT_set_color
439 VARARGS_BEGIN
440 VARARGS_GET8 win_top
441 VARARGS_GET8 win_height
442 VARARGS_GET8 win_leftx2
443 VARARGS_GET8 win_width
444 VARARGS_END
445 bra TFT_box
446
447 ;-----------------------------------------------------------------------------
448
449 global box_frame_std, box_frame_common, box_frame_color, box_frame_color16
450
451 box_frame_std:
452 setf WREG
453 rcall TFT_set_color
454
455 box_frame_common:
456 VARARGS_BEGIN
457 VARARGS_GET8 win_top
458 VARARGS_GET8 win_height
459 VARARGS_GET8 win_leftx2
460 VARARGS_GET8 win_width
461 VARARGS_END
462 bra TFT_frame
463
464 box_frame_color:
465 rcall TFT_set_color
466 box_frame_color16:
467 bra box_frame_common
468
469 ;=============================================================================
470 ; Init for half_pixel_write
471 ; Set column register on TFT device, and current color.
472 ; Inputs: win_leftx2
473 ; Outputs: win_color:2
474 ; Trashed: WREG, PROD
475 global init_pixel_write
476 init_pixel_write:
477 movff win_leftx2,WREG
478 mullw 2
479 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
480 setf WREG
481 bra TFT_set_color
482
483 ;-----------------------------------------------------------------------------
484 ; Writes two half-pixels at position (win_top,win_leftx2)
485 ; Inputs: win_leftx2, win_top, win_color:2
486 ; Trashed: WREG, PROD
487 global pixel_write
488 pixel_write:
489 movff win_leftx2,WREG
490 mullw 2 ; win_leftx2 x 2 -> PRODH:PRODL
491 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
492 rcall half_pixel_write ; Write this half-one.
493
494 movff win_leftx2,WREG ; Address of next one
495 mullw 2
496 infsnz PRODL ; +1
497 incf PRODH
498 rcall pixel_write_col320
499 bra half_pixel_write ; Note: Cmd 0x20 is mandatory, because
500 ; of the autoincrement going vertical
501
502 global pixel_write_col320
503 pixel_write_col320:
504 Index_out 0x21 ; Frame Memory Vertical Address
505 bra TFT_DataWrite_PROD
506
507 ;-----------------------------------------------------------------------------
508 ; Writes one half-pixel at position (win_top,win_leftx2).
509 ; Inputs: win_leftx2, win_top, win_color:2
510 ; Trashed: WREG, PROD
511 global half_pixel_write
512 half_pixel_write:
513 movff win_top,WREG ; d'0' ... d'239'
514 ; Variant with Y position in WREG.
515 half_pixel_write_1:
516 sublw .239 ; 239-Y --> Y
517
518 mullw 1 ; Copy row to PRODH:L
519 Index_out 0x20 ; Frame Memory Horizontal Address
520 rcall TFT_DataWrite_PROD
521
522 Index_out 0x22 ; Frame Memory Data Write start
523 RS_H ; Data
524 movff win_color1,PORTA ; Upper
525 movff win_color2,PORTH ; Lower
526 WR_L
527 WR_H ; Tick
528 return
529
530 ;-----------------------------------------------------------------------------
531 ; Writes a vertical line of half-pixel at position (win_top,win_leftx2,win_height).
532 ; Inputs: win_leftx2, win_top, win_height, win_color:2
533 ; Trashed: WREG, PROD, TABLAT, TBLPTRL
534 global half_vertical_line
535 half_vertical_line:
536 clrf TABLAT ; Loop index.
537
538 half_vertical_line_loop:
539 movff win_leftx2,WREG ; Init X position.
540 mullw 2
541 movf TABLAT,W ; Get loop index
542 andlw 1 ; Just low bit
543 xorwf PRODL,F ; And use it to jitter current X position
544 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
545
546 movff win_height,WREG ; Index reached height (Bank0 read) ?
547 xorwf TABLAT,W
548 btfsc STATUS,Z ; Equals ?
549 return ; Yes: done.
550 movff win_top,WREG ; Y = top + index (Bank0 read)
551 addwf TABLAT,W
552 rcall half_pixel_write_1
553 incf TABLAT,F ; index++
554 bra half_vertical_line_loop
555
556 ;-----------------------------------------------------------------------------
557 ; Writes a horizontal line of half-pixel at position (win_top,win_leftx2,win_width).
558 ; Inputs: win_leftx2, win_top, win_width, win_color:2
559 ; Trashed: WREG, PROD, TABLAT, TBLPTRL
560 global half_horizontal_line
561 half_horizontal_line:
562 clrf TABLAT ; Loop index.
563
564 half_horizontal_line_loop:
565 movff win_leftx2,WREG ; Init X position.
566 mullw 2
567 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
568 movff win_width,WREG ; Index reached height (Bank0 read) ?
569 xorwf TABLAT,W
570 btfsc STATUS,Z ; Equals ?
571 return ; Yes: done.
572 movff win_top,WREG ; Y = top + index (Bank0 read)
573 addwf TABLAT,W
574 rcall half_pixel_write_1
575 incf TABLAT,F ; index++
576 bra half_horizontal_line_loop
577
578
579 ;-----------------------------------------------------------------------------
580 ; TFT Data Cmd via W
581 ;
582 global TFT_DataWrite_PROD
583 TFT_DataWrite_PROD:
584 ; RD_H ; Keep high
585 RS_H ; Data
586 movff PRODH,PORTA ; Move high byte to PORTA
587 movff PRODL,PORTH ; Move low byte to PORTH
588 WR_L
589 WR_H ; Tick
590 return
591
592 TFT_DataRead_PROD:
593 Index_out 0x22 ; Frame Memory Data Read start
594 setf TRISA ; PortA as input.
595 setf TRISH ; PortH as input.
596 RS_H ; Data
597 WR_H ; Not write
598 RD_L ; Read!
599 nop
600 nop
601 nop
602 RD_H ; Tick
603 nop
604 RD_L ; Read!
605 nop
606 nop
607 nop
608 movff PORTA,PRODH
609 movff PORTH,PRODL
610 RD_H ; Tick
611 nop
612 clrf TRISA ; PortA as output
613 clrf TRISH ; PortH as output
614 return
615
616
617
618 ;=============================================================================
619 ; Output TFT Window Address commands.
620 ; Inputs : win_top, win_leftx2, win_height, win_width.
621 ; Output : PortA/PortH commands.
622 ; Trashed: PROD
623 ;
624 global TFT_box_write
625 TFT_box_write:
626 movff win_leftx2,WREG ; Compute left = 2*leftx2 --> PROD
627 mullw 2
628
629 ;---- Normal horizontal window ---------------------------------------
630 ; Output 0x35 left,
631 ; 0x36 right == left + width - 1.
632
633 Index_out 0x52 ; Window Vertical Start Address
634 rcall TFT_DataWrite_PROD ; Output left
635 Index_out 0x21 ; Frame Memory Vertical Address
636 rcall TFT_DataWrite_PROD ; Output left
637
638 movff win_width+0,WREG ; right = left + width - 1
639 addwf PRODL,F
640 movff win_width+1,WREG
641 addwfc PRODH,F
642 decf PRODL,F ; decrement result
643 btfss STATUS,C
644 decf PRODH,F
645
646 Index_out 0x53 ; Window Vertical End Address
647 rcall TFT_DataWrite_PROD
648
649 ;---- Flipped vertical window ----------------------------------------
650 ; Output 0x37 flipped(bottom) = 239-bottom = 240 - top - height
651 ; flipped(top) = 239-top
652 TFT_box_flip_V:
653 movff win_top,PRODL
654 movff win_height,WREG
655 addwf PRODL,W
656 sublw .240 ; 240 - top - height
657 movwf PRODH ; First byte
658
659 movf PRODL,W
660 sublw .239 ; 249-top
661 movwf PRODL ; --> second byte.
662
663 Index_out 0x50 ; Window Horizontal Start Address
664 clrf PORTA ; Upper
665 movf PRODH,W
666 rcall TFT_DataWrite ; Lower (and tick)
667
668 Index_out 0x51 ; Window Horizontal End Address
669 clrf PORTA ; Upper
670 movf PRODL,W
671 rcall TFT_DataWrite ; Lower (and tick)
672
673 Index_out 0x20 ; Frame Memory Horizontal Address
674 clrf PORTA ; Upper
675 movf PRODL,W
676 rcall TFT_DataWrite ; Lower (and tick)
677 return
678
679
680 ;=============================================================================
681 ; TFT_frame : draw a frame around current box with current color.
682 ; Inputs: win_top, win_leftx2, win_height, win_width, win_color1, win_color2
683 ; Outputs: (none)
684 ; Trashed: WREG, PROD, aa_start:2, aa_end:2
685 global TFT_frame
686 TFT_frame:
687 movff win_top,save_top ; Backup everything.
688 movff win_height,save_height
689 movff win_leftx2,save_left
690 movff win_width,save_width
691
692 ;---- TOP line -----------------------------------------------------------
693 movlw 1 ; row ~ height=1
694 movff WREG,win_height
695 rcall TFT_box
696
697 ;---- BOTTOM line --------------------------------------------------------
698 movff save_top,PRODL ; Get back top,
699 movff save_height,WREG ; and height
700 addwf PRODL,W ; top+height
701 decf WREG ; top+height-1
702 movff WREG,win_top ; top+height-1 --> top
703 rcall TFT_box
704
705 ;---- LEFT column --------------------------------------------------------
706 movff save_top,win_top ; Restore top/height.
707 movff save_height,win_height
708 movlw 1 ; column ~ width=1
709 movff WREG,win_width
710 rcall TFT_box
711
712 ;---- RIGHT column -------------------------------------------------------
713 movff save_left,WREG
714 movff save_width,PRODL
715 addwf PRODL,W
716 decf WREG
717 movff WREG,win_leftx2
718 rcall TFT_box
719
720 ;---- Restore everything -------------------------------------------------
721 movff save_left,win_leftx2
722 movff save_width,win_width
723 return
724
725 ;=============================================================================
726 ; TFT_box : fills current box with current color.
727 ; Inputs: win_top, win_leftx2, win_height, win_width, win_color1, win_color2
728 ; Outputs: (none)
729 ; Trashed: WREG, PROD
730 global TFT_box
731
732 TFT_box:
733 ;---- Define Window ------------------------------------------------------
734 movf win_width,W
735 bcf STATUS,C
736 rlcf WREG
737 movwf win_width+0
738 movlw 0
739 rlcf WREG
740 movwf win_width+1
741 rcall TFT_box_write
742
743 rrcf win_width+1,W ; width /= 2
744 rrcf win_width+0,W
745 movwf win_width
746
747 ;---- Fill Window --------------------------------------------------------
748 Index_out 0x22 ; Frame Memory Data Write start
749
750 clrf PRODH ; Column counter.
751 RS_H ; Data
752
753 TFT_box2: ; Loop height times
754 movff win_height,PRODL
755
756 TFT_box3: ; loop width times
757 movff win_color1,PORTA ; Upper
758 movff win_color2,PORTH ; Lower
759 WR_L
760 WR_H ; Tick
761
762 movff win_color1,PORTA ; Upper
763 movff win_color2,PORTH ; Lower
764 WR_L
765 WR_H ; Tick
766
767 decfsz PRODL,F ; row loop finished ?
768 bra TFT_box3 ; No: continue.
769
770 incf PRODH,F ; column count ++
771
772 movff win_bargraph,WREG ; current column == bargraph ?
773 cpfseq PRODH
774 bra TFT_box4 ; No: just loop.
775
776 clrf WREG ; Yes: switch to black
777 movff WREG,win_color1
778 movff WREG,win_color2
779 TFT_box4:
780
781 movff win_width+0,WREG ; compare ?
782 xorwf PRODH,W
783 bnz TFT_box2 ; Loop not finished.
784
785 movlw 0x00 ; NOP, to stop window mode
786 rcall TFT_CmdWrite
787
788 setf WREG ; Reset bargraph mode...
789 movff WREG,win_bargraph
790
791 return
792
793 ;=============================================================================
794 ;Converts 8Bit RGB b'RRRGGGBB' into 16Bit RGB b'RRRRRGGGGGGBBBBB'
795 global TFT_set_color
796
797 TFT_set_color:
798 movwf tft_temp1 ; Get 8Bit RGB b'RRRGGGBB'
799 movwf tft_temp2 ; Copy
800
801 ; Mask Bit 7,6,5,4,3,2
802 movlw b'00000011'
803 andwf tft_temp2,F
804
805 movlw b'00000000'
806 dcfsnz tft_temp2,F
807 movlw b'01010000'
808 dcfsnz tft_temp2,F
809 movlw b'10100000'
810 dcfsnz tft_temp2,F
811 movlw b'11111000'
812 movwf tft_temp3 ; Blue done.
813
814 movff tft_temp1, tft_temp2 ; Copy
815 ; Mask Bit 7,6,5,1,0
816 movlw b'00011100'
817 andwf tft_temp2,F
818 rrncf tft_temp2,F
819 rrncf tft_temp2,F
820
821 movlw b'00000000'
822 dcfsnz tft_temp2,F
823 movlw b'00000100'
824 dcfsnz tft_temp2,F
825 movlw b'00001000'
826 dcfsnz tft_temp2,F
827 movlw b'00001100'
828 dcfsnz tft_temp2,F
829 movlw b'00010000'
830 dcfsnz tft_temp2,F
831 movlw b'00010100'
832 dcfsnz tft_temp2,F
833 movlw b'00100000'
834 dcfsnz tft_temp2,F
835 movlw b'00111111'
836 movwf tft_temp4
837
838 rrcf tft_temp4,F
839 rrcf tft_temp3,F
840
841 rrcf tft_temp4,F
842 rrcf tft_temp3,F
843
844 rrcf tft_temp4,F
845 rrcf tft_temp3,F ; tft_temp3 (b'GGGBBBBB') done.
846
847 movff tft_temp1, tft_temp2 ; Copy
848 clrf tft_temp1
849
850 rrcf tft_temp4,F
851 rrcf tft_temp1,F
852
853 rrcf tft_temp4,F
854 rrcf tft_temp1,F
855
856 rrcf tft_temp4,F
857 rrcf tft_temp1,F ; Green done.
858
859 ; Mask Bit 4,3,2,1,0
860 movlw b'11100000'
861 andwf tft_temp2,F
862
863 rrncf tft_temp2,F
864 rrncf tft_temp2,F
865 rrncf tft_temp2,F
866 rrncf tft_temp2,F
867 rrncf tft_temp2,F
868
869 movlw b'00000000'
870 dcfsnz tft_temp2,F
871 movlw b'00000100'
872 dcfsnz tft_temp2,F
873 movlw b'00001000'
874 dcfsnz tft_temp2,F
875 movlw b'00001100'
876 dcfsnz tft_temp2,F
877 movlw b'00010000'
878 dcfsnz tft_temp2,F
879 movlw b'00010100'
880 dcfsnz tft_temp2,F
881 movlw b'00100000'
882 dcfsnz tft_temp2,F
883 movlw b'00111111'
884 movwf tft_temp4
885
886 rrcf tft_temp4,F
887 rrcf tft_temp1,F
888
889 rrcf tft_temp4,F
890 rrcf tft_temp1,F
891
892 rrcf tft_temp4,F
893 rrcf tft_temp1,F
894
895 rrcf tft_temp4,F
896 rrcf tft_temp1,F
897
898 rrcf tft_temp4,F
899 rrcf tft_temp1,F ; Red done.
900
901 movff tft_temp1,win_color1
902 movff tft_temp3,win_color2 ; Set Bank0 Color registers...
903 return
904
905 ;=============================================================================
906 ; Dump screen contents to the UART
907
908 global TFT_dump_screen
909 TFT_dump_screen:
910 bsf no_sensor_int
911 movlw 'l'
912 movwf TXREG ; Send command echo.
913 call rs232_wait_tx ; wait for UART
914 ;---- Send DISPLAY box command for the full screen window -------------------
915 Index_out 0x50 ; Window Horizontal Start Address
916 Parameter_out 0x00, 0x00 ; 0-239
917 Index_out 0x51 ; Window Horizontal End Address
918 Parameter_out 0x00, 0xEF ; 0-239
919 Index_out 0x52 ; Window Vertical Start Address
920 Parameter_out 0x00, 0x00 ; 0-319
921 Index_out 0x53 ; Window Vertical End Address
922 Parameter_out 0x01, 0x3F ; 0-319
923
924 clrf ds_column
925 rcall dump_screen_pixel_reset
926 dump_screen_1:
927 btg LEDr ; LED activity toggle
928 ; Dump even column
929 movlw .240 ; 240 lines, once.
930 movwf ds_line
931 dump_screen_2:
932 Index_out 0x20 ; Frame Memory Horizontal Address
933 movff ds_line,WREG ; d'0' ... d'239'
934 mullw 1 ; Copy row to PRODH:L
935 rcall TFT_DataWrite_PROD
936
937 movff ds_column,WREG ; Init X position.
938 mullw 2
939 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
940
941 rcall TFT_DataRead_PROD ; read pixel
942 rcall dump_screen_pixel
943
944 decfsz ds_line,F
945 bra dump_screen_2
946 rcall dump_screen_pixel_flush
947
948 ; Dump odd column
949 movlw .240 ; 240 lines, twice.
950 movwf ds_line
951 dump_screen_3:
952 Index_out 0x20 ; Frame Memory Horizontal Address
953 movff ds_line,WREG ; d'0' ... d'239'
954 mullw 1 ; Copy row to PRODH:L
955 rcall TFT_DataWrite_PROD
956
957 movff ds_column,WREG ; Init X position.
958 mullw 2
959 movlw .1
960 addwf PRODL,F
961 movlw 0
962 addwfc PRODH,F ; +1
963 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
964
965 rcall TFT_DataRead_PROD ; read pixel
966 rcall dump_screen_pixel
967
968 decfsz ds_line,F
969 bra dump_screen_3
970 rcall dump_screen_pixel_flush
971
972 incf ds_column,F
973 movlw .160
974 cpfseq ds_column
975 bra dump_screen_1
976
977 bcf no_sensor_int
978 clrf RCREG1 ; Clear receive buffer
979 bcf RCSTA1,CREN ; Clear receiver status
980 bsf RCSTA1,CREN
981 bsf enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (Screen dump)
982 return
983
984
985 ;=============================================================================
986 ; Pixel compression
987 ;
988 ; Input: PRODH:L = pixel.
989 ; Output: Compressed stream on output.
990 ; Compressed format:
991 ; 0ccccccc : BLACK pixel, repeated ccccccc+1 times (1..128).
992 ; 11cccccc : WHITE pixel, repeated cccccc+1 times (1..64).
993 ; 10cccccc HIGH LOW : color pixel (H:L) repeated ccccc+1 times (1..64).
994 ;
995 dump_screen_pixel:
996 movf PRODH,W ; Compare pixel-high
997 xorwf ds_pixel+1,W
998 bnz dump_screen_pixel_1 ; Different -> dump.
999
1000 movf PRODL,W ; Compare pixel-low
1001 xorwf ds_pixel+0,W
1002 bnz dump_screen_pixel_1 ; Different -> dump.
1003
1004 incf ds_count,F ; Same color: just increment.
1005 return
1006
1007 dump_screen_pixel_1: ; Send (pixel,count) tuple
1008 movf ds_count,W ; Is count zero ?
1009 bz dump_screen_pixel_2 ; Yes: skip sending.
1010
1011 movf ds_pixel+1,W ; This is a BLACK pixel ?
1012 iorwf ds_pixel+0,W
1013 bz dump_screen_pix_black ; YES.
1014
1015 movf ds_pixel+1,W ; This is a white pixel ?
1016 andwf ds_pixel+0,W
1017 incf WREG
1018 bz dump_screen_pix_white ; YES.
1019
1020 ; No: write the pixel itself...
1021 movlw .64 ; Max color pixel on a single byte.
1022 cpfsgt ds_count ; Skip if count > 64
1023 movf ds_count,W ; W <- min(64,count)
1024 subwf ds_count,F ; ds_count <- ds_count-W
1025 decf WREG ; Save as 0..63
1026 iorlw b'10000000' ; MARK as a color pixel.
1027
1028 movwf TXREG
1029 call rs232_wait_tx ; wait for UART
1030 movff ds_pixel+1,TXREG
1031 call rs232_wait_tx ; wait for UART
1032 movff ds_pixel+0,TXREG
1033 call rs232_wait_tx ; wait for UART
1034 bra dump_screen_pixel_1
1035
1036 dump_screen_pixel_2:
1037 movff PRODH,ds_pixel+1 ; Save new pixel color
1038 movff PRODL,ds_pixel+0
1039 movlw 1
1040 movwf ds_count ; And set count=1.
1041 return
1042
1043 dump_screen_pix_black:
1044 movlw .128 ; Max black pixel on a single byte.
1045 cpfsgt ds_count ; Skip if count > 128
1046 movf ds_count,W ; W <- min(128,count)
1047 subwf ds_count,F ; ds_count <- ds_count-W
1048 decf WREG ; Save as 0..127
1049 dump_screen_pix_3:
1050 movwf TXREG
1051 call rs232_wait_tx
1052 bra dump_screen_pixel_1 ; More to dump ?
1053
1054 dump_screen_pix_white:
1055 movlw .64 ; Max white pixel on a single byte.
1056 cpfsgt ds_count ; Skip if count > 64
1057 movf ds_count,W ; W <- min(64,count)
1058 subwf ds_count,F ; ds_count <- ds_count-W
1059 decf WREG ; Save as 0..63
1060 iorlw b'11000000' ; MARK as a compressed white.
1061 bra dump_screen_pix_3
1062
1063 dump_screen_pixel_flush:
1064 clrf PRODH
1065 clrf PRODL
1066 rcall dump_screen_pixel_1 ; Send it
1067 dump_screen_pixel_reset:
1068 clrf ds_count ; But clear count.
1069 return
1070
1071 end