{{ SeeedStudio Touchscreen TFT Driver This code is more or less directly translated from the Arduino source, which was adapted for the Propeller ASC by Jazzed. }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 'Basic Colors RED = $f800 GREEN = $07e0 BLUE = $001f BLACK = $0000 YELLOW = $ffe0 WHITE = $ffff 'Other Colors CYAN = $07ff BRIGHT_RED = $f810 GRAY1 = $8410 GRAY2 = $4208 'TFT resolution 240*320 MIN_X = 0 MIN_Y = 0 MAX_X = 240 MAX_Y = 320 'pin definitions from tft.h. The pin manipulation 'macros have been converted to PRI functions. CS_BIT = $04 << 8 RS_BIT = $08 << 8 WR_BIT = $10 << 8 RD_BIT = $20 << 8 'Macro definitions for char display direction LEFT2RIGHT = 0 DOWN2UP = 1 RIGHT2LEFT = 2 UP2DOWN = 3 'PASM mailbox commands #0 pmb_idle pmb_sendCMD pmb_sendDATA pmb_repeat 'set data "extra" iterations (1 is free) ' SendRegister isn't used in the demo. var byte DisplayDirect long PASM_mailbox dat InitSeq1 word $0001, $0100 word $0002, $0700 word $0003, $1030 word $0004, $0000 word $0008, $0302 word $000A, $0000 word $000C, $0000 word $000D, $0000 word $000F, $0000 word $FFFF InitSeq2 word $0030, $0000 word $0031, $0405 word $0032, $0203 word $0035, $0004 word $0036, $0B07 word $0037, $0000 word $0038, $0405 word $0039, $0203 word $003c, $0004 word $003d, $0B07 word $0020, $0000 word $0021, $0000 word $0050, $0000 word $0051, $00ef word $0052, $0000 word $0053, $013f word $FFFF InitSeq3 word $0060, $a700 word $0061, $0001 word $0090, $003A word $0095, $021E word $0080, $0000 word $0081, $0000 word $0082, $0000 word $0083, $0000 word $0084, $0000 word $0085, $0000 word $00FF, $0001 word $00B0, $140D word $00FF, $0000 word $FFFF Font byte $00,$00,$00,$00,$00,$00,$00,$00 byte $00,$00,$5F,$00,$00,$00,$00,$00 byte $00,$00,$07,$00,$07,$00,$00,$00 byte $00,$14,$7F,$14,$7F,$14,$00,$00 byte $00,$24,$2A,$7F,$2A,$12,$00,$00 byte $00,$23,$13,$08,$64,$62,$00,$00 byte $00,$36,$49,$55,$22,$50,$00,$00 byte $00,$00,$05,$03,$00,$00,$00,$00 byte $00,$1C,$22,$41,$00,$00,$00,$00 byte $00,$41,$22,$1C,$00,$00,$00,$00 byte $00,$08,$2A,$1C,$2A,$08,$00,$00 byte $00,$08,$08,$3E,$08,$08,$00,$00 byte $00,$A0,$60,$00,$00,$00,$00,$00 byte $00,$08,$08,$08,$08,$08,$00,$00 byte $00,$60,$60,$00,$00,$00,$00,$00 byte $00,$20,$10,$08,$04,$02,$00,$00 byte $00,$3E,$51,$49,$45,$3E,$00,$00 byte $00,$00,$42,$7F,$40,$00,$00,$00 byte $00,$62,$51,$49,$49,$46,$00,$00 byte $00,$22,$41,$49,$49,$36,$00,$00 byte $00,$18,$14,$12,$7F,$10,$00,$00 byte $00,$27,$45,$45,$45,$39,$00,$00 byte $00,$3C,$4A,$49,$49,$30,$00,$00 byte $00,$01,$71,$09,$05,$03,$00,$00 byte $00,$36,$49,$49,$49,$36,$00,$00 byte $00,$06,$49,$49,$29,$1E,$00,$00 byte $00,$00,$36,$36,$00,$00,$00,$00 byte $00,$00,$AC,$6C,$00,$00,$00,$00 byte $00,$08,$14,$22,$41,$00,$00,$00 byte $00,$14,$14,$14,$14,$14,$00,$00 byte $00,$41,$22,$14,$08,$00,$00,$00 byte $00,$02,$01,$51,$09,$06,$00,$00 byte $00,$32,$49,$79,$41,$3E,$00,$00 byte $00,$7E,$09,$09,$09,$7E,$00,$00 byte $00,$7F,$49,$49,$49,$36,$00,$00 byte $00,$3E,$41,$41,$41,$22,$00,$00 byte $00,$7F,$41,$41,$22,$1C,$00,$00 byte $00,$7F,$49,$49,$49,$41,$00,$00 byte $00,$7F,$09,$09,$09,$01,$00,$00 byte $00,$3E,$41,$41,$51,$72,$00,$00 byte $00,$7F,$08,$08,$08,$7F,$00,$00 byte $00,$41,$7F,$41,$00,$00,$00,$00 byte $00,$20,$40,$41,$3F,$01,$00,$00 byte $00,$7F,$08,$14,$22,$41,$00,$00 byte $00,$7F,$40,$40,$40,$40,$00,$00 byte $00,$7F,$02,$0C,$02,$7F,$00,$00 byte $00,$7F,$04,$08,$10,$7F,$00,$00 byte $00,$3E,$41,$41,$41,$3E,$00,$00 byte $00,$7F,$09,$09,$09,$06,$00,$00 byte $00,$3E,$41,$51,$21,$5E,$00,$00 byte $00,$7F,$09,$19,$29,$46,$00,$00 byte $00,$26,$49,$49,$49,$32,$00,$00 byte $00,$01,$01,$7F,$01,$01,$00,$00 byte $00,$3F,$40,$40,$40,$3F,$00,$00 byte $00,$1F,$20,$40,$20,$1F,$00,$00 byte $00,$3F,$40,$38,$40,$3F,$00,$00 byte $00,$63,$14,$08,$14,$63,$00,$00 byte $00,$03,$04,$78,$04,$03,$00,$00 byte $00,$61,$51,$49,$45,$43,$00,$00 byte $00,$7F,$41,$41,$00,$00,$00,$00 byte $00,$02,$04,$08,$10,$20,$00,$00 byte $00,$41,$41,$7F,$00,$00,$00,$00 byte $00,$04,$02,$01,$02,$04,$00,$00 byte $00,$80,$80,$80,$80,$80,$00,$00 byte $00,$01,$02,$04,$00,$00,$00,$00 byte $00,$20,$54,$54,$54,$78,$00,$00 byte $00,$7F,$48,$44,$44,$38,$00,$00 byte $00,$38,$44,$44,$28,$00,$00,$00 byte $00,$38,$44,$44,$48,$7F,$00,$00 byte $00,$38,$54,$54,$54,$18,$00,$00 byte $00,$08,$7E,$09,$02,$00,$00,$00 byte $00,$18,$A4,$A4,$A4,$7C,$00,$00 byte $00,$7F,$08,$04,$04,$78,$00,$00 byte $00,$00,$7D,$00,$00,$00,$00,$00 byte $00,$80,$84,$7D,$00,$00,$00,$00 byte $00,$7F,$10,$28,$44,$00,$00,$00 byte $00,$41,$7F,$40,$00,$00,$00,$00 byte $00,$7C,$04,$18,$04,$78,$00,$00 byte $00,$7C,$08,$04,$7C,$00,$00,$00 byte $00,$38,$44,$44,$38,$00,$00,$00 byte $00,$FC,$24,$24,$18,$00,$00,$00 byte $00,$18,$24,$24,$FC,$00,$00,$00 byte $00,$00,$7C,$08,$04,$00,$00,$00 byte $00,$48,$54,$54,$24,$00,$00,$00 byte $00,$04,$7F,$44,$00,$00,$00,$00 byte $00,$3C,$40,$40,$7C,$00,$00,$00 byte $00,$1C,$20,$40,$20,$1C,$00,$00 byte $00,$3C,$40,$30,$40,$3C,$00,$00 byte $00,$44,$28,$10,$28,$44,$00,$00 byte $00,$1C,$A0,$A0,$7C,$00,$00,$00 byte $00,$44,$64,$54,$4C,$44,$00,$00 byte $00,$08,$36,$41,$00,$00,$00,$00 byte $00,$00,$7F,$00,$00,$00,$00,$00 byte $00,$41,$36,$08,$00,$00,$00,$00 byte $00,$02,$01,$01,$02,$01,$00,$00 byte $00,$02,$05,$05,$02,$00,$00,$00 pub main init fillrectangle(20,20,180,280,bright_red) drawcircle(100,100,60,cyan) drawcircle(100,230,60,white) drawline(20,20,200,100,cyan) drawline(20,200,100,20,cyan) drawline(20,100,200,300,cyan) drawString(string("PASMy!"),0,160,1,YELLOW) drawString(string("PASMy!"),0,200,2,GREEN) drawString(string("PASMy!"),0,240,4,WHITE) ' --------------------------------------------------- ' ' These routines ONLY used by PASM conversion candidates pri all_pin_input dira &= !all_pin_mask pri all_pin_output dira |= all_pin_mask pri all_pin_low ' outa &= !all_pin_mask ' These were defined as macros in the Arduino version pri CS_OUTPUT DIRA |= CS_BIT pri CS_HIGH OUTA |= CS_BIT pri CS_LOW OUTA &= !CS_BIT pri RS_OUTPUT DIRA |= RS_BIT pri RS_HIGH OUTA |= RS_BIT pri RS_LOW OUTA &= !RS_BIT pri WR_OUTPUT DIRA |= WR_BIT pri WR_HIGH OUTA |= WR_BIT pri WR_LOW OUTA &= !WR_BIT pri RD_OUTPUT DIRA |= RD_BIT pri RD_HIGH OUTA |= RD_BIT pri RD_LOW OUTA &= !RD_BIT pub pushData(data) ' all_pin_low outa |= (data << 2) pub getData ' delay(1) return (INA & $fc) >> 2 dat ' PAR passes the address of the Long mailbox. ' ' Mailbox = 0 = idle ' Low byte mailbox determines function org TFT_PASM_IMAGE ' 'InitStart ' mov outa,#0 mov dira,all_ctl_mask tpi_clear mov tmp, par wrlong zero, tmp ' tpi_loop mov tmp,par rdlong pmb_data, tmp test pmb_data, pmb_data wz if_z jmp #tpi_loop mov tmp,pmb_data and tmp,#$FF cmp tmp,#pmb_repeat wz if_z shr pmb_data,#8 if_z mov rcount, pmb_data if_z jmp #tpi_clear cmp tmp,#pmb_sendCMD wz if_nz jmp #tpi_notCMD ' dloop andn outa,cs_bit_mask andn outa,rs_bit_mask or outa,rd_bit_mask or outa,wr_bit_mask andn outa,wr_bit_mask andn outa,all_pin_mask 'or with zero is free or outa,wr_bit_mask andn outa,wr_bit_mask mov tmp,pmb_data shr tmp,#6 and tmp,all_pin_mask andn outa,all_pin_mask or outa,tmp or outa,wr_bit_mask or outa,cs_bit_mask jmp #tpi_clear tpi_notCMD cmp tmp,#pmb_sendDATA wz if_nz jmp #tpi_clear :loop andn outa,cs_bit_mask or outa,rs_bit_mask or outa,rd_bit_mask andn outa,wr_bit_mask ' andn outa,all_pin_mask mov tmp,pmb_data shr tmp,#14 and tmp,all_pin_mask or outa,tmp or outa,wr_bit_mask andn outa,wr_bit_mask andn outa,all_pin_mask mov tmp,pmb_data shr tmp,#6 and tmp,all_pin_mask or outa,tmp or outa,wr_bit_mask or outa,cs_bit_mask test rcount, rcount wz if_z jmp #tpi_clear sub rcount, #1 jmp #:loop CS_BIT_MASK long %0000_0100_0000_0000 '$0400 RS_BIT_MASK long %0000_1000_0000_0000 '$0800 WR_BIT_MASK long %0001_0000_0000_0000 '$1000 RD_BIT_MASK long %0010_0000_0000_0000 '$2000 all_pin_mask long %0000_0011_1111_1100 all_ctl_mask long %0011_1111_1111_1100 zero long 0 rcount long 0 pmb_data res 1 tmp res 1 ' ------------------------------------------- ' ' These routines PASM conversion candidates { pub InitStart CS_OUTPUT RD_OUTPUT WR_OUTPUT RS_OUTPUT all_pin_output all_pin_low pub sendCommand(index) ' CS_LOW RS_LOW RD_HIGH WR_HIGH WR_LOW pushData(0) WR_HIGH WR_LOW pushData(index & $ff) WR_HIGH CS_HIGH pub sendData(data) ' CS_LOW RS_HIGH RD_HIGH WR_LOW pushData((data & $ff00) >> 8) WR_HIGH WR_LOW pushData(data & $ff) WR_HIGH CS_HIGH pub sendRegister(index) CS_LOW RS_LOW RD_HIGH all_pin_output WR_LOW pushData(0) WR_HIGH WR_LOW pushData(index) WR_HIGH all_pin_input RS_HIGH RD_LOW RD_HIGH result |= getData << 8 RD_LOW RD_HIGH result |= getData CS_HIGH all_pin_output } ' ------------------------------------------ pub sendCommand(index) pasm_mailbox := index << 8 + pmb_sendcmd 'repeat while pasm_mailbox <> 0 pub sendData(data) pasm_mailbox := data << 8 + pmb_senddata 'repeat while pasm_mailbox <> 0 pub sendMultiData(data, qty) pasm_mailbox := (qty - 1) << 8 + pmb_repeat sendData(data) repeat while pasm_mailbox <> 0 pri SendCmdSeq(ptr) | c, d ' repeat c := word[ptr] if c == $FFFF return ptr += 2 d := word[ptr] ptr += 2 sendcommand(c) senddata(d) pub init cognew(@tft_pasm_image, @pasm_mailbox) delay(100) sendcmdseq(@initseq1) delay(100) sendcmdseq(@initseq2) delay(100) sendcmdseq(@initseq3) delay(100) sendcommand($0007) senddata($0133) delay(50) exitstandby sendcommand($0022) paintscreenblack pub PaintScreenBlack | i, f sendmultidata(black, 38400 * 2) return pub exitStandBy sendCommand($0010) sendData($14E0) delay(100) sendCommand($0007) sendData($0133) pub setOrientation(HV) ' Horizontal or Vertical sendCommand($03) if HV==1 'vertical senddata($5038) else 'horizontal senddata($5030) sendcommand($0022) 'start writeing to display RAM pub setDisplayDirect(Direction) DisplayDirect := Direction pub setXY(poX, poY) sendCommand($0020) 'X sendData(poX) sendCommand($0021) 'Y sendData(poY) sendCommand($0022) 'Start to write to display RAM pub setPixel(poX, poY, color) setXY(poX,poY) sendData(color) pub drawCircle(poX, poY, R, color) | x, y, err, e2 x := -r y := 0 err := 2-2*r e2 := 0 ' repeat setPixel(poX-x, poY+y,color) setPixel(poX+x, poY+y,color) setPixel(poX+x, poY-y,color) setPixel(poX-x, poY-y,color) e2 := err if (e2 =< y) err += ++y*2+1 if (-x == y and e2 =< x) e2 := 0 if (e2 > x) err += ++x*2+1 while x =< 0 pub fillCircle(poX, poY, r, color) | x, y, err, e2 x := -r y := 0 err := 2-2*r e2 := 0 ' repeat drawVerticalLine(poX-x,poY-y,2*y,color) drawVerticalLine(poX+x,poY-y,2*y,color) e2 := err if (e2 =< y) err += ++y*2+1 if (-x == y and e2 =< x) e2 := 0 if (e2 > x) err += ++x*2+1 while x =< 0 pub drawLine(x0, y0, x1, y1, color) | x, y, dx, sx, dy, sy, err, e2 x := x1-x0 y := y1-y0 dx := ||x if x0 dy) 'e_xy+e_x > 0 if (x0 == x1) quit err += dy x0 += sx if (e2 =< dx) 'e_xy+e_y < 0 if (y0 == y1) quit err += dx y0 += sy pub drawVerticalLine(poX, poY, length, color) | i setXY(poX,poY) setOrientation(1) if(length+poY>MAX_Y) length := MAX_Y-poY sendmultidata(color, length) pub drawHorizontalLine(poX, poY, length, color) | i setXY(poX,poY) setOrientation(0) if(length+poX>MAX_X) length := MAX_X-poX sendMultiData(color, length) pub drawRectangle(poX, poY, length, width, color) drawHorizontalLine(poX, poY, length, color) drawHorizontalLine(poX, poY+width, length, color) drawVerticalLine(poX, poY, width,color) drawVerticalLine(poX + length, poY, width,color) pub fillRectangle(poX, poY, length, width, color) | i repeat i from 0 to width-1 if (DisplayDirect == LEFT2RIGHT) drawHorizontalLine(poX, poY+i, length, color) elseif (DisplayDirect == DOWN2UP) drawHorizontalLine(poX, poY-i, length, color) elseif (DisplayDirect == RIGHT2LEFT) drawHorizontalLine(poX, poY-i, length, color) elseif (DisplayDirect == UP2DOWN) drawHorizontalLine(poX, poY+i, length, color) pub drawChar(ascii, poX, poY, size, fgcolor) | i, f, temp setXY(poX,poY) if ((ascii < $20) or (ascii > $7e)) 'Unsupported char. ascii := "?" repeat i from 0 to 7 temp := byte[@Font+(ascii-$20)*8 +i] repeat f from 0 to 7 if ((temp>>f) & $01) if (DisplayDirect == LEFT2RIGHT) fillRectangle(poX+i*size, poY+f*size, size, size, fgcolor) elseif (DisplayDirect == DOWN2UP) fillRectangle(poX+f*size, poY-i*size, size, size, fgcolor) elseif (DisplayDirect == RIGHT2LEFT) fillRectangle(poX-i*size, poY-f*size, size, size, fgcolor) elseif (DisplayDirect == UP2DOWN) fillRectangle(poX-f*size, poY+i*size, size, size, fgcolor) pub drawString(ptr, poX, poY, size, fgcolor) | c repeat c := byte[ptr++] if c == 0 return drawChar(c, poX, poY, size, fgcolor) if (DisplayDirect == LEFT2RIGHT) if(poX < MAX_X) poX += 8*size 'Move cursor right elseif (DisplayDirect == DOWN2UP) if(poY > 0) poY -= 8*size 'Move cursor right elseif (DisplayDirect == RIGHT2LEFT) if(poX > 0) poX -= 8*size 'Move cursor right elseif (DisplayDirect == UP2DOWN) if(poY < MAX_Y) poY += 8*size 'Move cursor right 'from arduino library in arduino verion pri delay(msec) waitcnt(cnt + clkfreq / 1000 * msec)