Mercurial > public > hwos_code
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 |