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