| 1 | //----------------------------------------------------------------------------- |
| 2 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, |
| 3 | // at your option, any later version. See the LICENSE.txt file for the text of |
| 4 | // the license. |
| 5 | //----------------------------------------------------------------------------- |
| 6 | // LCD code |
| 7 | //----------------------------------------------------------------------------- |
| 8 | |
| 9 | #include "proxmark3.h" |
| 10 | #include "apps.h" |
| 11 | #include "LCD.h" |
| 12 | #include "fonts.h" |
| 13 | |
| 14 | void LCDSend(unsigned int data) |
| 15 | { |
| 16 | // 9th bit set for data, clear for command |
| 17 | while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete |
| 18 | // For clarity's sake we pass data with 9th bit clear and commands with 9th |
| 19 | // bit set since they're implemented as defines, se we need to invert bit |
| 20 | AT91C_BASE_SPI->SPI_TDR = data^0x100; // Send the data/command |
| 21 | } |
| 22 | |
| 23 | void LCDSetXY(unsigned char x, unsigned char y) |
| 24 | { |
| 25 | LCDSend(PPASET); // page start/end ram |
| 26 | LCDSend(y); // Start Page to display to |
| 27 | LCDSend(131); // End Page to display to |
| 28 | |
| 29 | LCDSend(PCASET); // column start/end ram |
| 30 | LCDSend(x); // Start Column to display to |
| 31 | LCDSend(131); // End Column to display to |
| 32 | } |
| 33 | |
| 34 | void LCDSetPixel(unsigned char x, unsigned char y, unsigned char color) |
| 35 | { |
| 36 | LCDSetXY(x,y); // Set position |
| 37 | LCDSend(PRAMWR); // Now write the pixel to the display |
| 38 | LCDSend(color); // Write the data in the specified Color |
| 39 | } |
| 40 | |
| 41 | void LCDFill (unsigned char xs,unsigned char ys,unsigned char width,unsigned char height, unsigned char color) |
| 42 | { |
| 43 | unsigned char i,j; |
| 44 | |
| 45 | for (i=0;i < height;i++) // Number of horizontal lines |
| 46 | { |
| 47 | LCDSetXY(xs,ys+i); // Goto start of fill area (Top Left) |
| 48 | LCDSend(PRAMWR); // Write to display |
| 49 | |
| 50 | for (j=0;j < width;j++) // pixels per line |
| 51 | LCDSend(color); |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | void LCDString (char *lcd_string, const char *font_style,unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor) |
| 56 | { |
| 57 | unsigned int i; |
| 58 | unsigned char mask=0, px, py, xme, yme, offset; |
| 59 | const char *data; |
| 60 | |
| 61 | data = font_style; // point to the start of the font table |
| 62 | |
| 63 | xme = *data; // get font x width |
| 64 | data++; |
| 65 | yme = *data; // get font y length |
| 66 | data++; |
| 67 | offset = *data; // get data bytes per font |
| 68 | |
| 69 | do |
| 70 | { |
| 71 | // point to data in table to be loaded |
| 72 | data = (font_style + offset) + (offset * (int)(*lcd_string - 32)); |
| 73 | |
| 74 | for (i=0;i < yme;i++) { |
| 75 | mask |=0x80; |
| 76 | |
| 77 | for (px=x; px < (x + xme); px++) { |
| 78 | py= y + i; |
| 79 | |
| 80 | if (*data & mask) LCDSetPixel (px,py,fcolor); |
| 81 | else LCDSetPixel (px,py,bcolor); |
| 82 | |
| 83 | mask>>=1; |
| 84 | } |
| 85 | data++; |
| 86 | } |
| 87 | x+=xme; |
| 88 | |
| 89 | lcd_string++; // next character in string |
| 90 | |
| 91 | } while(*lcd_string !='\0'); // keep spitting chars out until end of string |
| 92 | } |
| 93 | |
| 94 | void LCDReset(void) |
| 95 | { |
| 96 | LED_A_ON(); |
| 97 | SetupSpi(SPI_LCD_MODE); |
| 98 | LOW(GPIO_LRST); |
| 99 | SpinDelay(100); |
| 100 | |
| 101 | HIGH(GPIO_LRST); |
| 102 | SpinDelay(100); |
| 103 | LED_A_OFF(); |
| 104 | } |
| 105 | |
| 106 | void LCDInit(void) |
| 107 | { |
| 108 | int i; |
| 109 | |
| 110 | LCDReset(); |
| 111 | |
| 112 | LCDSend(PSWRESET); // software reset |
| 113 | SpinDelay(100); |
| 114 | LCDSend(PSLEEPOUT); // exit sleep mode |
| 115 | LCDSend(PBSTRON); // booster on |
| 116 | LCDSend(PDISPON); // display on |
| 117 | LCDSend(PNORON); // normal on |
| 118 | LCDSend(PMADCTL); // rotate display 180 deg |
| 119 | LCDSend(0xC0); |
| 120 | |
| 121 | LCDSend(PCOLMOD); // color mode |
| 122 | LCDSend(0x02); // 8bpp color mode |
| 123 | |
| 124 | LCDSend(PSETCON); // set contrast |
| 125 | LCDSend(0xDC); |
| 126 | |
| 127 | // clear display |
| 128 | LCDSetXY(0,0); |
| 129 | LCDSend(PRAMWR); // Write to display |
| 130 | i=LCD_XRES*LCD_YRES; |
| 131 | while(i--) LCDSend(WHITE); |
| 132 | |
| 133 | // test text on different colored backgrounds |
| 134 | LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK ); |
| 135 | LCDString(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE ); |
| 136 | LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED ); |
| 137 | LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN ); |
| 138 | LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE ); |
| 139 | LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW); |
| 140 | LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8,1,1+8*6,BLACK ,CYAN ); |
| 141 | LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA); |
| 142 | |
| 143 | // color bands |
| 144 | LCDFill(0, 1+8* 8, 132, 8, BLACK); |
| 145 | LCDFill(0, 1+8* 9, 132, 8, WHITE); |
| 146 | LCDFill(0, 1+8*10, 132, 8, RED); |
| 147 | LCDFill(0, 1+8*11, 132, 8, GREEN); |
| 148 | LCDFill(0, 1+8*12, 132, 8, BLUE); |
| 149 | LCDFill(0, 1+8*13, 132, 8, YELLOW); |
| 150 | LCDFill(0, 1+8*14, 132, 8, CYAN); |
| 151 | LCDFill(0, 1+8*15, 132, 8, MAGENTA); |
| 152 | |
| 153 | } |