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 |
