ILI9340_Driver_Lib
ILI9340_Driver.cpp@0:ea46340642a9, 2014-05-27 (annotated)
- Committer:
- dextorslabs
- Date:
- Tue May 27 19:40:20 2014 +0000
- Revision:
- 0:ea46340642a9
- Child:
- 1:216d35e347b8
V1.0 of the ILI9340 Driver and graphics library.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dextorslabs | 0:ea46340642a9 | 1 | /*************************************************************** |
dextorslabs | 0:ea46340642a9 | 2 | ILI9340_Driver v1.0 26.05.14 Ian Weston |
dextorslabs | 0:ea46340642a9 | 3 | |
dextorslabs | 0:ea46340642a9 | 4 | Driver and integrated graphics library for displays that use the |
dextorslabs | 0:ea46340642a9 | 5 | ILI9340 controller in SPI mode. |
dextorslabs | 0:ea46340642a9 | 6 | |
dextorslabs | 0:ea46340642a9 | 7 | The code was prted from several sources, the driver section |
dextorslabs | 0:ea46340642a9 | 8 | was completely ported from the Adafruits Arduino source code, and |
dextorslabs | 0:ea46340642a9 | 9 | the graphics functions were ported from the Adafruits GFX library |
dextorslabs | 0:ea46340642a9 | 10 | and some elements were ported from code by Elmicros seeduio port. |
dextorslabs | 0:ea46340642a9 | 11 | |
dextorslabs | 0:ea46340642a9 | 12 | Future revisions will include more advanced graphics functions. |
dextorslabs | 0:ea46340642a9 | 13 | |
dextorslabs | 0:ea46340642a9 | 14 | ***************************************************************/ |
dextorslabs | 0:ea46340642a9 | 15 | |
dextorslabs | 0:ea46340642a9 | 16 | |
dextorslabs | 0:ea46340642a9 | 17 | #include "mbed.h" |
dextorslabs | 0:ea46340642a9 | 18 | #include "ILI9340_Driver.h" |
dextorslabs | 0:ea46340642a9 | 19 | #include "SimpleFont.cpp" |
dextorslabs | 0:ea46340642a9 | 20 | |
dextorslabs | 0:ea46340642a9 | 21 | |
dextorslabs | 0:ea46340642a9 | 22 | // Constructor, assigns the pins to the SPI object, set orientation, and sets screen dims. |
dextorslabs | 0:ea46340642a9 | 23 | ILI9340_Display::ILI9340_Display(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dc) |
dextorslabs | 0:ea46340642a9 | 24 | : spi(mosi, miso, sclk), cs(cs), rst(rst), dc(dc) { |
dextorslabs | 0:ea46340642a9 | 25 | _height = _TFTHEIGHT; |
dextorslabs | 0:ea46340642a9 | 26 | _width = _TFTWIDTH; |
dextorslabs | 0:ea46340642a9 | 27 | orientation = 0; |
dextorslabs | 0:ea46340642a9 | 28 | } |
dextorslabs | 0:ea46340642a9 | 29 | |
dextorslabs | 0:ea46340642a9 | 30 | |
dextorslabs | 0:ea46340642a9 | 31 | // Command writing code |
dextorslabs | 0:ea46340642a9 | 32 | void ILI9340_Display::WriteCommand(uint8_t command) { |
dextorslabs | 0:ea46340642a9 | 33 | dc = 0; |
dextorslabs | 0:ea46340642a9 | 34 | cs = 0; |
dextorslabs | 0:ea46340642a9 | 35 | spi.write(command); |
dextorslabs | 0:ea46340642a9 | 36 | cs = 1; |
dextorslabs | 0:ea46340642a9 | 37 | } |
dextorslabs | 0:ea46340642a9 | 38 | |
dextorslabs | 0:ea46340642a9 | 39 | |
dextorslabs | 0:ea46340642a9 | 40 | // Data writing code |
dextorslabs | 0:ea46340642a9 | 41 | void ILI9340_Display::WriteData(uint8_t data) { |
dextorslabs | 0:ea46340642a9 | 42 | cs = 0; |
dextorslabs | 0:ea46340642a9 | 43 | dc = 1; |
dextorslabs | 0:ea46340642a9 | 44 | spi.write(data); |
dextorslabs | 0:ea46340642a9 | 45 | cs = 1; |
dextorslabs | 0:ea46340642a9 | 46 | } |
dextorslabs | 0:ea46340642a9 | 47 | |
dextorslabs | 0:ea46340642a9 | 48 | |
dextorslabs | 0:ea46340642a9 | 49 | // Initilise the display |
dextorslabs | 0:ea46340642a9 | 50 | void ILI9340_Display::DispInit(void) { |
dextorslabs | 0:ea46340642a9 | 51 | //CtrlOutput(); |
dextorslabs | 0:ea46340642a9 | 52 | |
dextorslabs | 0:ea46340642a9 | 53 | rst = 0; |
dextorslabs | 0:ea46340642a9 | 54 | |
dextorslabs | 0:ea46340642a9 | 55 | // Setup the spi for 8 bit data, high steady state clock, |
dextorslabs | 0:ea46340642a9 | 56 | // second edge capture, with a 1MHz clock rate |
dextorslabs | 0:ea46340642a9 | 57 | //spi.format(8,3); |
dextorslabs | 0:ea46340642a9 | 58 | spi.frequency(24000000); // actually seems to work up to about 20Mhz... way better than the 8mhz as std. |
dextorslabs | 0:ea46340642a9 | 59 | |
dextorslabs | 0:ea46340642a9 | 60 | // Toggle rst to reset |
dextorslabs | 0:ea46340642a9 | 61 | rst = 1; |
dextorslabs | 0:ea46340642a9 | 62 | wait(0.005); |
dextorslabs | 0:ea46340642a9 | 63 | rst = 0; |
dextorslabs | 0:ea46340642a9 | 64 | wait(0.020); |
dextorslabs | 0:ea46340642a9 | 65 | rst = 1; |
dextorslabs | 0:ea46340642a9 | 66 | wait(0.150); |
dextorslabs | 0:ea46340642a9 | 67 | |
dextorslabs | 0:ea46340642a9 | 68 | WriteCommand(0xEF); |
dextorslabs | 0:ea46340642a9 | 69 | WriteData(0x03); |
dextorslabs | 0:ea46340642a9 | 70 | WriteData(0x80); |
dextorslabs | 0:ea46340642a9 | 71 | WriteData(0x02); |
dextorslabs | 0:ea46340642a9 | 72 | |
dextorslabs | 0:ea46340642a9 | 73 | WriteCommand(0xCF); |
dextorslabs | 0:ea46340642a9 | 74 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 75 | WriteData(0xC1); |
dextorslabs | 0:ea46340642a9 | 76 | WriteData(0x30); |
dextorslabs | 0:ea46340642a9 | 77 | |
dextorslabs | 0:ea46340642a9 | 78 | WriteCommand(0xED); |
dextorslabs | 0:ea46340642a9 | 79 | WriteData(0x64); |
dextorslabs | 0:ea46340642a9 | 80 | WriteData(0x03); |
dextorslabs | 0:ea46340642a9 | 81 | WriteData(0x12); |
dextorslabs | 0:ea46340642a9 | 82 | WriteData(0x81); |
dextorslabs | 0:ea46340642a9 | 83 | |
dextorslabs | 0:ea46340642a9 | 84 | WriteCommand(0xE8); |
dextorslabs | 0:ea46340642a9 | 85 | WriteData(0x85); |
dextorslabs | 0:ea46340642a9 | 86 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 87 | WriteData(0x78); |
dextorslabs | 0:ea46340642a9 | 88 | |
dextorslabs | 0:ea46340642a9 | 89 | WriteCommand(0xCB); |
dextorslabs | 0:ea46340642a9 | 90 | WriteData(0x39); |
dextorslabs | 0:ea46340642a9 | 91 | WriteData(0x2C); |
dextorslabs | 0:ea46340642a9 | 92 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 93 | WriteData(0x34); |
dextorslabs | 0:ea46340642a9 | 94 | WriteData(0x02); |
dextorslabs | 0:ea46340642a9 | 95 | |
dextorslabs | 0:ea46340642a9 | 96 | WriteCommand(0xF7); |
dextorslabs | 0:ea46340642a9 | 97 | WriteData(0x20); |
dextorslabs | 0:ea46340642a9 | 98 | |
dextorslabs | 0:ea46340642a9 | 99 | WriteCommand(0xEA); |
dextorslabs | 0:ea46340642a9 | 100 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 101 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 102 | |
dextorslabs | 0:ea46340642a9 | 103 | WriteCommand(ILI9340_PWCTR1); //Power control |
dextorslabs | 0:ea46340642a9 | 104 | WriteData(0x23); //VRH[5:0] |
dextorslabs | 0:ea46340642a9 | 105 | |
dextorslabs | 0:ea46340642a9 | 106 | WriteCommand(ILI9340_PWCTR2); //Power control |
dextorslabs | 0:ea46340642a9 | 107 | WriteData(0x10); //SAP[2:0];BT[3:0] |
dextorslabs | 0:ea46340642a9 | 108 | |
dextorslabs | 0:ea46340642a9 | 109 | WriteCommand(ILI9340_VMCTR1); //VCM control |
dextorslabs | 0:ea46340642a9 | 110 | WriteData(0x3e); //�Աȶȵ��� |
dextorslabs | 0:ea46340642a9 | 111 | WriteData(0x28); |
dextorslabs | 0:ea46340642a9 | 112 | |
dextorslabs | 0:ea46340642a9 | 113 | WriteCommand(ILI9340_VMCTR2); //VCM control2 |
dextorslabs | 0:ea46340642a9 | 114 | WriteData(0x86); //-- |
dextorslabs | 0:ea46340642a9 | 115 | |
dextorslabs | 0:ea46340642a9 | 116 | WriteCommand(ILI9340_MADCTL); // Memory Access Control |
dextorslabs | 0:ea46340642a9 | 117 | WriteData(ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR); |
dextorslabs | 0:ea46340642a9 | 118 | |
dextorslabs | 0:ea46340642a9 | 119 | WriteCommand(ILI9340_PIXFMT); |
dextorslabs | 0:ea46340642a9 | 120 | WriteData(0x55); |
dextorslabs | 0:ea46340642a9 | 121 | |
dextorslabs | 0:ea46340642a9 | 122 | WriteCommand(ILI9340_FRMCTR1); |
dextorslabs | 0:ea46340642a9 | 123 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 124 | WriteData(0x18); |
dextorslabs | 0:ea46340642a9 | 125 | |
dextorslabs | 0:ea46340642a9 | 126 | WriteCommand(ILI9340_DFUNCTR); // Display Function Control |
dextorslabs | 0:ea46340642a9 | 127 | WriteData(0x08); |
dextorslabs | 0:ea46340642a9 | 128 | WriteData(0x82); |
dextorslabs | 0:ea46340642a9 | 129 | WriteData(0x27); |
dextorslabs | 0:ea46340642a9 | 130 | |
dextorslabs | 0:ea46340642a9 | 131 | WriteCommand(0xF2); // 3Gamma Function Disable |
dextorslabs | 0:ea46340642a9 | 132 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 133 | |
dextorslabs | 0:ea46340642a9 | 134 | WriteCommand(ILI9340_GAMMASET); //Gamma curve selected |
dextorslabs | 0:ea46340642a9 | 135 | WriteData(0x01); |
dextorslabs | 0:ea46340642a9 | 136 | |
dextorslabs | 0:ea46340642a9 | 137 | WriteCommand(ILI9340_GMCTRP1); //Set Gamma |
dextorslabs | 0:ea46340642a9 | 138 | WriteData(0x0F); |
dextorslabs | 0:ea46340642a9 | 139 | WriteData(0x31); |
dextorslabs | 0:ea46340642a9 | 140 | WriteData(0x2B); |
dextorslabs | 0:ea46340642a9 | 141 | WriteData(0x0C); |
dextorslabs | 0:ea46340642a9 | 142 | WriteData(0x0E); |
dextorslabs | 0:ea46340642a9 | 143 | WriteData(0x08); |
dextorslabs | 0:ea46340642a9 | 144 | WriteData(0x4E); |
dextorslabs | 0:ea46340642a9 | 145 | WriteData(0xF1); |
dextorslabs | 0:ea46340642a9 | 146 | WriteData(0x37); |
dextorslabs | 0:ea46340642a9 | 147 | WriteData(0x07); |
dextorslabs | 0:ea46340642a9 | 148 | WriteData(0x10); |
dextorslabs | 0:ea46340642a9 | 149 | WriteData(0x03); |
dextorslabs | 0:ea46340642a9 | 150 | WriteData(0x0E); |
dextorslabs | 0:ea46340642a9 | 151 | WriteData(0x09); |
dextorslabs | 0:ea46340642a9 | 152 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 153 | |
dextorslabs | 0:ea46340642a9 | 154 | WriteCommand(ILI9340_GMCTRN1); //Set Gamma |
dextorslabs | 0:ea46340642a9 | 155 | WriteData(0x00); |
dextorslabs | 0:ea46340642a9 | 156 | WriteData(0x0E); |
dextorslabs | 0:ea46340642a9 | 157 | WriteData(0x14); |
dextorslabs | 0:ea46340642a9 | 158 | WriteData(0x03); |
dextorslabs | 0:ea46340642a9 | 159 | WriteData(0x11); |
dextorslabs | 0:ea46340642a9 | 160 | WriteData(0x07); |
dextorslabs | 0:ea46340642a9 | 161 | WriteData(0x31); |
dextorslabs | 0:ea46340642a9 | 162 | WriteData(0xC1); |
dextorslabs | 0:ea46340642a9 | 163 | WriteData(0x48); |
dextorslabs | 0:ea46340642a9 | 164 | WriteData(0x08); |
dextorslabs | 0:ea46340642a9 | 165 | WriteData(0x0F); |
dextorslabs | 0:ea46340642a9 | 166 | WriteData(0x0C); |
dextorslabs | 0:ea46340642a9 | 167 | WriteData(0x31); |
dextorslabs | 0:ea46340642a9 | 168 | WriteData(0x36); |
dextorslabs | 0:ea46340642a9 | 169 | WriteData(0x0F); |
dextorslabs | 0:ea46340642a9 | 170 | |
dextorslabs | 0:ea46340642a9 | 171 | WriteCommand(ILI9340_SLPOUT); //Exit Sleep |
dextorslabs | 0:ea46340642a9 | 172 | wait(0.120); |
dextorslabs | 0:ea46340642a9 | 173 | WriteCommand(ILI9340_DISPON); //Display on |
dextorslabs | 0:ea46340642a9 | 174 | |
dextorslabs | 0:ea46340642a9 | 175 | } |
dextorslabs | 0:ea46340642a9 | 176 | |
dextorslabs | 0:ea46340642a9 | 177 | |
dextorslabs | 0:ea46340642a9 | 178 | // Sets the rotation of the display |
dextorslabs | 0:ea46340642a9 | 179 | void ILI9340_Display::SetRotation(uint8_t m) { |
dextorslabs | 0:ea46340642a9 | 180 | |
dextorslabs | 0:ea46340642a9 | 181 | WriteCommand(ILI9340_MADCTL); |
dextorslabs | 0:ea46340642a9 | 182 | orientation = m % 4; // can't be higher than 3 |
dextorslabs | 0:ea46340642a9 | 183 | |
dextorslabs | 0:ea46340642a9 | 184 | switch (orientation) { |
dextorslabs | 0:ea46340642a9 | 185 | case 0: |
dextorslabs | 0:ea46340642a9 | 186 | WriteData(ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR); |
dextorslabs | 0:ea46340642a9 | 187 | _width = _TFTWIDTH; |
dextorslabs | 0:ea46340642a9 | 188 | _height = _TFTHEIGHT; |
dextorslabs | 0:ea46340642a9 | 189 | break; |
dextorslabs | 0:ea46340642a9 | 190 | case 1: |
dextorslabs | 0:ea46340642a9 | 191 | WriteData(ILI9340_MADCTL_MV | ILI9340_MADCTL_BGR); |
dextorslabs | 0:ea46340642a9 | 192 | _width = _TFTHEIGHT; |
dextorslabs | 0:ea46340642a9 | 193 | _height = _TFTWIDTH; |
dextorslabs | 0:ea46340642a9 | 194 | break; |
dextorslabs | 0:ea46340642a9 | 195 | case 2: |
dextorslabs | 0:ea46340642a9 | 196 | WriteData(ILI9340_MADCTL_MY | ILI9340_MADCTL_BGR); |
dextorslabs | 0:ea46340642a9 | 197 | _width = _TFTWIDTH; |
dextorslabs | 0:ea46340642a9 | 198 | _height = _TFTHEIGHT; |
dextorslabs | 0:ea46340642a9 | 199 | break; |
dextorslabs | 0:ea46340642a9 | 200 | case 3: |
dextorslabs | 0:ea46340642a9 | 201 | WriteData(ILI9340_MADCTL_MV | ILI9340_MADCTL_MY | ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR); |
dextorslabs | 0:ea46340642a9 | 202 | _width = _TFTHEIGHT; |
dextorslabs | 0:ea46340642a9 | 203 | _height = _TFTWIDTH; |
dextorslabs | 0:ea46340642a9 | 204 | break; |
dextorslabs | 0:ea46340642a9 | 205 | } |
dextorslabs | 0:ea46340642a9 | 206 | } |
dextorslabs | 0:ea46340642a9 | 207 | |
dextorslabs | 0:ea46340642a9 | 208 | |
dextorslabs | 0:ea46340642a9 | 209 | // Invert the colours of the display in hardware |
dextorslabs | 0:ea46340642a9 | 210 | void ILI9340_Display::InvertDisplay(bool i) { |
dextorslabs | 0:ea46340642a9 | 211 | WriteCommand(i ? ILI9340_INVON : ILI9340_INVOFF); |
dextorslabs | 0:ea46340642a9 | 212 | } |
dextorslabs | 0:ea46340642a9 | 213 | |
dextorslabs | 0:ea46340642a9 | 214 | |
dextorslabs | 0:ea46340642a9 | 215 | |
dextorslabs | 0:ea46340642a9 | 216 | // Set address window for writing data to. |
dextorslabs | 0:ea46340642a9 | 217 | void ILI9340_Display::SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { |
dextorslabs | 0:ea46340642a9 | 218 | |
dextorslabs | 0:ea46340642a9 | 219 | WriteCommand(ILI9340_CASET); // Column addr set |
dextorslabs | 0:ea46340642a9 | 220 | WriteData(x0 >> 8); |
dextorslabs | 0:ea46340642a9 | 221 | WriteData(x0 & 0xFF); // XSTART |
dextorslabs | 0:ea46340642a9 | 222 | WriteData(x1 >> 8); |
dextorslabs | 0:ea46340642a9 | 223 | WriteData(x1 & 0xFF); // XEND |
dextorslabs | 0:ea46340642a9 | 224 | |
dextorslabs | 0:ea46340642a9 | 225 | WriteCommand(ILI9340_PASET); // Row addr set |
dextorslabs | 0:ea46340642a9 | 226 | WriteData(y0>>8); |
dextorslabs | 0:ea46340642a9 | 227 | WriteData(y0); // YSTART |
dextorslabs | 0:ea46340642a9 | 228 | WriteData(y1>>8); |
dextorslabs | 0:ea46340642a9 | 229 | WriteData(y1); // YEND |
dextorslabs | 0:ea46340642a9 | 230 | |
dextorslabs | 0:ea46340642a9 | 231 | WriteCommand(ILI9340_RAMWR); // write to RAM |
dextorslabs | 0:ea46340642a9 | 232 | } |
dextorslabs | 0:ea46340642a9 | 233 | |
dextorslabs | 0:ea46340642a9 | 234 | |
dextorslabs | 0:ea46340642a9 | 235 | |
dextorslabs | 0:ea46340642a9 | 236 | // To draw the humble pixel |
dextorslabs | 0:ea46340642a9 | 237 | void ILI9340_Display::DrawPixel(uint16_t x, uint16_t y, uint16_t colour) { |
dextorslabs | 0:ea46340642a9 | 238 | if((x < 1) ||(x >= _width) || (y < 1) || (y >= _height)) return; |
dextorslabs | 0:ea46340642a9 | 239 | |
dextorslabs | 0:ea46340642a9 | 240 | SetAddrWindow(x,y,x+1,y+1); |
dextorslabs | 0:ea46340642a9 | 241 | |
dextorslabs | 0:ea46340642a9 | 242 | dc = 1; |
dextorslabs | 0:ea46340642a9 | 243 | cs = 0; |
dextorslabs | 0:ea46340642a9 | 244 | |
dextorslabs | 0:ea46340642a9 | 245 | spi.write(colour >> 8); |
dextorslabs | 0:ea46340642a9 | 246 | spi.write(colour); |
dextorslabs | 0:ea46340642a9 | 247 | |
dextorslabs | 0:ea46340642a9 | 248 | cs = 1; |
dextorslabs | 0:ea46340642a9 | 249 | } |
dextorslabs | 0:ea46340642a9 | 250 | |
dextorslabs | 0:ea46340642a9 | 251 | |
dextorslabs | 0:ea46340642a9 | 252 | // Fill the screen with a colour |
dextorslabs | 0:ea46340642a9 | 253 | void ILI9340_Display::FillScreen(uint16_t colour) { |
dextorslabs | 0:ea46340642a9 | 254 | SetAddrWindow(0,0,_width,_height); |
dextorslabs | 0:ea46340642a9 | 255 | |
dextorslabs | 0:ea46340642a9 | 256 | dc = 1; |
dextorslabs | 0:ea46340642a9 | 257 | cs = 0; |
dextorslabs | 0:ea46340642a9 | 258 | |
dextorslabs | 0:ea46340642a9 | 259 | unsigned int total = _width * _height; |
dextorslabs | 0:ea46340642a9 | 260 | unsigned int position = 0; |
dextorslabs | 0:ea46340642a9 | 261 | |
dextorslabs | 0:ea46340642a9 | 262 | while (position < total) { |
dextorslabs | 0:ea46340642a9 | 263 | spi.write(colour >> 8); |
dextorslabs | 0:ea46340642a9 | 264 | spi.write(colour); |
dextorslabs | 0:ea46340642a9 | 265 | position++; |
dextorslabs | 0:ea46340642a9 | 266 | } |
dextorslabs | 0:ea46340642a9 | 267 | cs = 1; |
dextorslabs | 0:ea46340642a9 | 268 | } |
dextorslabs | 0:ea46340642a9 | 269 | |
dextorslabs | 0:ea46340642a9 | 270 | |
dextorslabs | 0:ea46340642a9 | 271 | // Draws a vertical line fast |
dextorslabs | 0:ea46340642a9 | 272 | void ILI9340_Display::DrawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t colour) { |
dextorslabs | 0:ea46340642a9 | 273 | |
dextorslabs | 0:ea46340642a9 | 274 | // Rudimentary clipping |
dextorslabs | 0:ea46340642a9 | 275 | if((x >= _width) || (y >= _height)) return; |
dextorslabs | 0:ea46340642a9 | 276 | |
dextorslabs | 0:ea46340642a9 | 277 | if((y+h-1) >= _height) |
dextorslabs | 0:ea46340642a9 | 278 | h = _height-y; |
dextorslabs | 0:ea46340642a9 | 279 | |
dextorslabs | 0:ea46340642a9 | 280 | SetAddrWindow(x, y, x, y+h-1); |
dextorslabs | 0:ea46340642a9 | 281 | |
dextorslabs | 0:ea46340642a9 | 282 | uint8_t hi = colour >> 8, lo = colour; |
dextorslabs | 0:ea46340642a9 | 283 | |
dextorslabs | 0:ea46340642a9 | 284 | dc = 1; |
dextorslabs | 0:ea46340642a9 | 285 | cs = 0; |
dextorslabs | 0:ea46340642a9 | 286 | |
dextorslabs | 0:ea46340642a9 | 287 | while (h--) { |
dextorslabs | 0:ea46340642a9 | 288 | spi.write(hi); |
dextorslabs | 0:ea46340642a9 | 289 | spi.write(lo); |
dextorslabs | 0:ea46340642a9 | 290 | } |
dextorslabs | 0:ea46340642a9 | 291 | cs = 1; |
dextorslabs | 0:ea46340642a9 | 292 | } |
dextorslabs | 0:ea46340642a9 | 293 | |
dextorslabs | 0:ea46340642a9 | 294 | |
dextorslabs | 0:ea46340642a9 | 295 | // Draws a horizontal line fast |
dextorslabs | 0:ea46340642a9 | 296 | void ILI9340_Display::DrawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t colour) { |
dextorslabs | 0:ea46340642a9 | 297 | |
dextorslabs | 0:ea46340642a9 | 298 | // Rudimentary clipping |
dextorslabs | 0:ea46340642a9 | 299 | if((x >= _width) || (y >= _height)) return; |
dextorslabs | 0:ea46340642a9 | 300 | if((x+w-1) >= _height) w = _width-x; |
dextorslabs | 0:ea46340642a9 | 301 | SetAddrWindow(x, y, x+w-1, y); |
dextorslabs | 0:ea46340642a9 | 302 | |
dextorslabs | 0:ea46340642a9 | 303 | uint8_t hi = colour >> 8, lo = colour; |
dextorslabs | 0:ea46340642a9 | 304 | dc = 1; |
dextorslabs | 0:ea46340642a9 | 305 | cs = 0; |
dextorslabs | 0:ea46340642a9 | 306 | while (w--) { |
dextorslabs | 0:ea46340642a9 | 307 | spi.write(hi); |
dextorslabs | 0:ea46340642a9 | 308 | spi.write(lo); |
dextorslabs | 0:ea46340642a9 | 309 | } |
dextorslabs | 0:ea46340642a9 | 310 | cs = 1; |
dextorslabs | 0:ea46340642a9 | 311 | } |
dextorslabs | 0:ea46340642a9 | 312 | |
dextorslabs | 0:ea46340642a9 | 313 | |
dextorslabs | 0:ea46340642a9 | 314 | // Draws a filled rectangle |
dextorslabs | 0:ea46340642a9 | 315 | void ILI9340_Display::FillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colour) { |
dextorslabs | 0:ea46340642a9 | 316 | |
dextorslabs | 0:ea46340642a9 | 317 | // rudimentary clipping (drawChar w/big text requires this) |
dextorslabs | 0:ea46340642a9 | 318 | if((x >= _width) || (y >= _height)) return; |
dextorslabs | 0:ea46340642a9 | 319 | if((x + w - 1) >= _width) w = _width - x; |
dextorslabs | 0:ea46340642a9 | 320 | if((y + h - 1) >= _height) h = _height - y; |
dextorslabs | 0:ea46340642a9 | 321 | |
dextorslabs | 0:ea46340642a9 | 322 | SetAddrWindow(x, y, x+w-1, y+h-1); |
dextorslabs | 0:ea46340642a9 | 323 | |
dextorslabs | 0:ea46340642a9 | 324 | uint8_t hi = colour >> 8, lo = colour; |
dextorslabs | 0:ea46340642a9 | 325 | |
dextorslabs | 0:ea46340642a9 | 326 | dc = 1; |
dextorslabs | 0:ea46340642a9 | 327 | cs = 0; |
dextorslabs | 0:ea46340642a9 | 328 | |
dextorslabs | 0:ea46340642a9 | 329 | for(y=h; y>0; y--) { |
dextorslabs | 0:ea46340642a9 | 330 | for(x=w; x>0; x--) { |
dextorslabs | 0:ea46340642a9 | 331 | spi.write(hi); |
dextorslabs | 0:ea46340642a9 | 332 | spi.write(lo); |
dextorslabs | 0:ea46340642a9 | 333 | } |
dextorslabs | 0:ea46340642a9 | 334 | } |
dextorslabs | 0:ea46340642a9 | 335 | cs = 1; |
dextorslabs | 0:ea46340642a9 | 336 | } |
dextorslabs | 0:ea46340642a9 | 337 | |
dextorslabs | 0:ea46340642a9 | 338 | |
dextorslabs | 0:ea46340642a9 | 339 | |
dextorslabs | 0:ea46340642a9 | 340 | // Draw an unfilled rectangle |
dextorslabs | 0:ea46340642a9 | 341 | void ILI9340_Display::DrawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ |
dextorslabs | 0:ea46340642a9 | 342 | DrawFastHLine(x, y, w, color); |
dextorslabs | 0:ea46340642a9 | 343 | DrawFastHLine(x, y+h-1, w, color); |
dextorslabs | 0:ea46340642a9 | 344 | DrawFastVLine(x, y, h, color); |
dextorslabs | 0:ea46340642a9 | 345 | DrawFastVLine(x+w-1, y, h, color); |
dextorslabs | 0:ea46340642a9 | 346 | } |
dextorslabs | 0:ea46340642a9 | 347 | |
dextorslabs | 0:ea46340642a9 | 348 | |
dextorslabs | 0:ea46340642a9 | 349 | // draw an unfilled circle |
dextorslabs | 0:ea46340642a9 | 350 | void ILI9340_Display::DrawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t colour){ |
dextorslabs | 0:ea46340642a9 | 351 | int16_t f = 1 - r; |
dextorslabs | 0:ea46340642a9 | 352 | int16_t ddF_x = 1; |
dextorslabs | 0:ea46340642a9 | 353 | int16_t ddF_y = -2 * r; |
dextorslabs | 0:ea46340642a9 | 354 | int16_t x = 0; |
dextorslabs | 0:ea46340642a9 | 355 | int16_t y = r; |
dextorslabs | 0:ea46340642a9 | 356 | |
dextorslabs | 0:ea46340642a9 | 357 | DrawPixel(x0 , y0+r, colour); |
dextorslabs | 0:ea46340642a9 | 358 | DrawPixel(x0 , y0-r, colour); |
dextorslabs | 0:ea46340642a9 | 359 | DrawPixel(x0+r, y0 , colour); |
dextorslabs | 0:ea46340642a9 | 360 | DrawPixel(x0-r, y0 , colour); |
dextorslabs | 0:ea46340642a9 | 361 | |
dextorslabs | 0:ea46340642a9 | 362 | while (x<y) { |
dextorslabs | 0:ea46340642a9 | 363 | if (f >= 0) { |
dextorslabs | 0:ea46340642a9 | 364 | y--; |
dextorslabs | 0:ea46340642a9 | 365 | ddF_y += 2; |
dextorslabs | 0:ea46340642a9 | 366 | f += ddF_y; |
dextorslabs | 0:ea46340642a9 | 367 | } |
dextorslabs | 0:ea46340642a9 | 368 | x++; |
dextorslabs | 0:ea46340642a9 | 369 | ddF_x += 2; |
dextorslabs | 0:ea46340642a9 | 370 | f += ddF_x; |
dextorslabs | 0:ea46340642a9 | 371 | |
dextorslabs | 0:ea46340642a9 | 372 | DrawPixel(x0 + x, y0 + y, colour); |
dextorslabs | 0:ea46340642a9 | 373 | DrawPixel(x0 - x, y0 + y, colour); |
dextorslabs | 0:ea46340642a9 | 374 | DrawPixel(x0 + x, y0 - y, colour); |
dextorslabs | 0:ea46340642a9 | 375 | DrawPixel(x0 - x, y0 - y, colour); |
dextorslabs | 0:ea46340642a9 | 376 | DrawPixel(x0 + y, y0 + x, colour); |
dextorslabs | 0:ea46340642a9 | 377 | DrawPixel(x0 - y, y0 + x, colour); |
dextorslabs | 0:ea46340642a9 | 378 | DrawPixel(x0 + y, y0 - x, colour); |
dextorslabs | 0:ea46340642a9 | 379 | DrawPixel(x0 - y, y0 - x, colour); |
dextorslabs | 0:ea46340642a9 | 380 | } |
dextorslabs | 0:ea46340642a9 | 381 | } |
dextorslabs | 0:ea46340642a9 | 382 | |
dextorslabs | 0:ea46340642a9 | 383 | |
dextorslabs | 0:ea46340642a9 | 384 | // Pass 8-bit (each) R,G,B, get back 16-bit packed color |
dextorslabs | 0:ea46340642a9 | 385 | uint16_t ILI9340_Display::Colour565(uint8_t r, uint8_t g, uint8_t b) { |
dextorslabs | 0:ea46340642a9 | 386 | return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); |
dextorslabs | 0:ea46340642a9 | 387 | } |
dextorslabs | 0:ea46340642a9 | 388 | |
dextorslabs | 0:ea46340642a9 | 389 | |
dextorslabs | 0:ea46340642a9 | 390 | // Writes an ascii character to the display |
dextorslabs | 0:ea46340642a9 | 391 | void ILI9340_Display::DrawAscii(unsigned char ascii, uint16_t x, uint16_t y, uint16_t size, uint16_t colour) { |
dextorslabs | 0:ea46340642a9 | 392 | SetAddrWindow(x, y, x+size, y+size); |
dextorslabs | 0:ea46340642a9 | 393 | |
dextorslabs | 0:ea46340642a9 | 394 | if( (ascii < 0x20) || (ascii > 0x7e) ) //check for valid ASCII char |
dextorslabs | 0:ea46340642a9 | 395 | { |
dextorslabs | 0:ea46340642a9 | 396 | ascii = '?'; //char not supported |
dextorslabs | 0:ea46340642a9 | 397 | } |
dextorslabs | 0:ea46340642a9 | 398 | for(unsigned char i=0; i<8; i++) |
dextorslabs | 0:ea46340642a9 | 399 | { |
dextorslabs | 0:ea46340642a9 | 400 | unsigned char temp = simpleFont[ascii - 0x20][i]; |
dextorslabs | 0:ea46340642a9 | 401 | for(unsigned char f=0; f<8; f++) |
dextorslabs | 0:ea46340642a9 | 402 | { |
dextorslabs | 0:ea46340642a9 | 403 | if( (temp>>f) & 0x01 ) |
dextorslabs | 0:ea46340642a9 | 404 | { |
dextorslabs | 0:ea46340642a9 | 405 | switch(orientation) |
dextorslabs | 0:ea46340642a9 | 406 | { |
dextorslabs | 0:ea46340642a9 | 407 | case '0': |
dextorslabs | 0:ea46340642a9 | 408 | FillRect(x+f*size, y-i*size, size, size, colour); |
dextorslabs | 0:ea46340642a9 | 409 | break; |
dextorslabs | 0:ea46340642a9 | 410 | case '1': |
dextorslabs | 0:ea46340642a9 | 411 | FillRect(x-i*size, x-f*size, size, size, colour); |
dextorslabs | 0:ea46340642a9 | 412 | break; |
dextorslabs | 0:ea46340642a9 | 413 | case '2': |
dextorslabs | 0:ea46340642a9 | 414 | FillRect(x-f*size, y+i*size, size, size, colour); |
dextorslabs | 0:ea46340642a9 | 415 | break; |
dextorslabs | 0:ea46340642a9 | 416 | case '3': |
dextorslabs | 0:ea46340642a9 | 417 | default: |
dextorslabs | 0:ea46340642a9 | 418 | FillRect(x+i*size, y+f*size, size, size, colour); |
dextorslabs | 0:ea46340642a9 | 419 | } |
dextorslabs | 0:ea46340642a9 | 420 | } |
dextorslabs | 0:ea46340642a9 | 421 | } |
dextorslabs | 0:ea46340642a9 | 422 | } |
dextorslabs | 0:ea46340642a9 | 423 | } |
dextorslabs | 0:ea46340642a9 | 424 | |
dextorslabs | 0:ea46340642a9 | 425 | |
dextorslabs | 0:ea46340642a9 | 426 | // Writes a character array to the display |
dextorslabs | 0:ea46340642a9 | 427 | void ILI9340_Display::DrawString(char *string, uint16_t x, uint16_t y, uint8_t size, uint16_t colour) |
dextorslabs | 0:ea46340642a9 | 428 | { |
dextorslabs | 0:ea46340642a9 | 429 | while(*string) |
dextorslabs | 0:ea46340642a9 | 430 | { |
dextorslabs | 0:ea46340642a9 | 431 | DrawAscii(*string, x, y, size, colour); |
dextorslabs | 0:ea46340642a9 | 432 | *string++; |
dextorslabs | 0:ea46340642a9 | 433 | switch(orientation) |
dextorslabs | 0:ea46340642a9 | 434 | { |
dextorslabs | 0:ea46340642a9 | 435 | case '0': |
dextorslabs | 0:ea46340642a9 | 436 | if(y > 0) y-=8*size; //Change position to next char |
dextorslabs | 0:ea46340642a9 | 437 | break; |
dextorslabs | 0:ea46340642a9 | 438 | case '1': |
dextorslabs | 0:ea46340642a9 | 439 | if(x > 0) x-=8*size; |
dextorslabs | 0:ea46340642a9 | 440 | break; |
dextorslabs | 0:ea46340642a9 | 441 | case '2': |
dextorslabs | 0:ea46340642a9 | 442 | if(y < _height) y+=8*size; |
dextorslabs | 0:ea46340642a9 | 443 | break; |
dextorslabs | 0:ea46340642a9 | 444 | case '3': |
dextorslabs | 0:ea46340642a9 | 445 | default: |
dextorslabs | 0:ea46340642a9 | 446 | if(x < _width) x+=8*size; |
dextorslabs | 0:ea46340642a9 | 447 | } |
dextorslabs | 0:ea46340642a9 | 448 | } |
dextorslabs | 0:ea46340642a9 | 449 | } |
dextorslabs | 0:ea46340642a9 | 450 | |
dextorslabs | 0:ea46340642a9 | 451 | // Converts integers into a character array |
dextorslabs | 0:ea46340642a9 | 452 | void ILI9340_Display::IntToChars (char* buffer, int value, uint8_t spaceonbuffer, uint8_t countbase, uint16_t x, uint16_t y, uint8_t size, uint16_t colour) { |
dextorslabs | 0:ea46340642a9 | 453 | int workvalue = value; |
dextorslabs | 0:ea46340642a9 | 454 | int i; |
dextorslabs | 0:ea46340642a9 | 455 | int valuetowrite; |
dextorslabs | 0:ea46340642a9 | 456 | int end_i = 0; |
dextorslabs | 0:ea46340642a9 | 457 | |
dextorslabs | 0:ea46340642a9 | 458 | if (value < 0) |
dextorslabs | 0:ea46340642a9 | 459 | { |
dextorslabs | 0:ea46340642a9 | 460 | workvalue = -value; |
dextorslabs | 0:ea46340642a9 | 461 | end_i = 1; |
dextorslabs | 0:ea46340642a9 | 462 | buffer[0] = '-'; |
dextorslabs | 0:ea46340642a9 | 463 | } |
dextorslabs | 0:ea46340642a9 | 464 | |
dextorslabs | 0:ea46340642a9 | 465 | for (i = spaceonbuffer - 1; i >= end_i; i--) |
dextorslabs | 0:ea46340642a9 | 466 | { |
dextorslabs | 0:ea46340642a9 | 467 | valuetowrite = (workvalue % countbase); |
dextorslabs | 0:ea46340642a9 | 468 | if (workvalue == 0) |
dextorslabs | 0:ea46340642a9 | 469 | { |
dextorslabs | 0:ea46340642a9 | 470 | if (i == (spaceonbuffer - 1)) |
dextorslabs | 0:ea46340642a9 | 471 | { |
dextorslabs | 0:ea46340642a9 | 472 | buffer[i] = 48; // ASCII 0 |
dextorslabs | 0:ea46340642a9 | 473 | } else { |
dextorslabs | 0:ea46340642a9 | 474 | buffer[i] = 32; // ASCII SPACE |
dextorslabs | 0:ea46340642a9 | 475 | } |
dextorslabs | 0:ea46340642a9 | 476 | } else { |
dextorslabs | 0:ea46340642a9 | 477 | if (valuetowrite > 9) |
dextorslabs | 0:ea46340642a9 | 478 | { |
dextorslabs | 0:ea46340642a9 | 479 | buffer[i] = valuetowrite + 55; // ASCII A-Z |
dextorslabs | 0:ea46340642a9 | 480 | } else { |
dextorslabs | 0:ea46340642a9 | 481 | buffer[i] = valuetowrite + 48; // ASCII of that character |
dextorslabs | 0:ea46340642a9 | 482 | } |
dextorslabs | 0:ea46340642a9 | 483 | }; |
dextorslabs | 0:ea46340642a9 | 484 | workvalue = (workvalue - valuetowrite) / countbase; |
dextorslabs | 0:ea46340642a9 | 485 | } |
dextorslabs | 0:ea46340642a9 | 486 | |
dextorslabs | 0:ea46340642a9 | 487 | DrawString(buffer, x, y, size, colour); |
dextorslabs | 0:ea46340642a9 | 488 | } |
dextorslabs | 0:ea46340642a9 | 489 | |
dextorslabs | 0:ea46340642a9 | 490 | |
dextorslabs | 0:ea46340642a9 | 491 | |
dextorslabs | 0:ea46340642a9 | 492 | // Functional code to swap data contents of 16bit registers |
dextorslabs | 0:ea46340642a9 | 493 | void ILI9340_Display::Swap(int16_t *a, int16_t *b) { |
dextorslabs | 0:ea46340642a9 | 494 | |
dextorslabs | 0:ea46340642a9 | 495 | int16_t x = *a; |
dextorslabs | 0:ea46340642a9 | 496 | *a = *b; |
dextorslabs | 0:ea46340642a9 | 497 | *b = x; |
dextorslabs | 0:ea46340642a9 | 498 | } |
dextorslabs | 0:ea46340642a9 | 499 | |
dextorslabs | 0:ea46340642a9 | 500 | |
dextorslabs | 0:ea46340642a9 | 501 | // Draws a line with any length and orientation |
dextorslabs | 0:ea46340642a9 | 502 | void ILI9340_Display::DrawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour){ |
dextorslabs | 0:ea46340642a9 | 503 | int16_t steep = abs(y1 - y0) > abs(x1 - x0); |
dextorslabs | 0:ea46340642a9 | 504 | if (steep) { |
dextorslabs | 0:ea46340642a9 | 505 | Swap(&x0, &y0); |
dextorslabs | 0:ea46340642a9 | 506 | Swap(&x1, &y1); |
dextorslabs | 0:ea46340642a9 | 507 | } |
dextorslabs | 0:ea46340642a9 | 508 | |
dextorslabs | 0:ea46340642a9 | 509 | if (x0 > x1) { |
dextorslabs | 0:ea46340642a9 | 510 | Swap(&x0, &x1); |
dextorslabs | 0:ea46340642a9 | 511 | Swap(&y0, &y1); |
dextorslabs | 0:ea46340642a9 | 512 | } |
dextorslabs | 0:ea46340642a9 | 513 | |
dextorslabs | 0:ea46340642a9 | 514 | int16_t dx, dy; |
dextorslabs | 0:ea46340642a9 | 515 | dx = x1 - x0; |
dextorslabs | 0:ea46340642a9 | 516 | dy = abs(y1 - y0); |
dextorslabs | 0:ea46340642a9 | 517 | |
dextorslabs | 0:ea46340642a9 | 518 | int16_t err = dx / 2; |
dextorslabs | 0:ea46340642a9 | 519 | int16_t ystep; |
dextorslabs | 0:ea46340642a9 | 520 | |
dextorslabs | 0:ea46340642a9 | 521 | if (y0 < y1) { |
dextorslabs | 0:ea46340642a9 | 522 | ystep = 1; |
dextorslabs | 0:ea46340642a9 | 523 | } else { |
dextorslabs | 0:ea46340642a9 | 524 | ystep = -1; |
dextorslabs | 0:ea46340642a9 | 525 | } |
dextorslabs | 0:ea46340642a9 | 526 | |
dextorslabs | 0:ea46340642a9 | 527 | for (; x0<=x1; x0++) { |
dextorslabs | 0:ea46340642a9 | 528 | if (steep) { |
dextorslabs | 0:ea46340642a9 | 529 | DrawPixel(y0, x0, colour); |
dextorslabs | 0:ea46340642a9 | 530 | } else { |
dextorslabs | 0:ea46340642a9 | 531 | DrawPixel(x0, y0, colour); |
dextorslabs | 0:ea46340642a9 | 532 | } |
dextorslabs | 0:ea46340642a9 | 533 | err -= dy; |
dextorslabs | 0:ea46340642a9 | 534 | if (err < 0) { |
dextorslabs | 0:ea46340642a9 | 535 | y0 += ystep; |
dextorslabs | 0:ea46340642a9 | 536 | err += dx; |
dextorslabs | 0:ea46340642a9 | 537 | } |
dextorslabs | 0:ea46340642a9 | 538 | } |
dextorslabs | 0:ea46340642a9 | 539 | } |
dextorslabs | 0:ea46340642a9 | 540 | |
dextorslabs | 0:ea46340642a9 | 541 | |
dextorslabs | 0:ea46340642a9 | 542 | |
dextorslabs | 0:ea46340642a9 | 543 | |
dextorslabs | 0:ea46340642a9 | 544 | |
dextorslabs | 0:ea46340642a9 | 545 | |
dextorslabs | 0:ea46340642a9 | 546 | |
dextorslabs | 0:ea46340642a9 | 547 |