Basic driver working

Committer:
f3d
Date:
Sat Feb 20 16:34:49 2021 +0000
Revision:
81:7087ba9d18bb
Parent:
80:ff42f77928ad
Display driver working with touch input

Who changed what in which revision?

UserRevisionLine numberNew contents of line
f3d 80:ff42f77928ad 1 #include "mbed.h"
f3d 80:ff42f77928ad 2 #include "display.h"
f3d 81:7087ba9d18bb 3 #include "font5x7.h"
f3d 81:7087ba9d18bb 4 extern Serial g_Serial_pc;
f3d 80:ff42f77928ad 5 //mosi,miso,clk,ss
f3d 81:7087ba9d18bb 6 SPI spi(P0_25,P0_26,P0_27);
f3d 80:ff42f77928ad 7 DigitalOut Rst(P0_7);
f3d 80:ff42f77928ad 8 DigitalOut DC(P0_6);
f3d 81:7087ba9d18bb 9 DigitalOut D_CS(P0_28);
f3d 81:7087ba9d18bb 10 DigitalOut T_CS(P0_5);
f3d 81:7087ba9d18bb 11 DigitalIn PenIRQ(P0_4);
f3d 80:ff42f77928ad 12 void Display::begin()
f3d 80:ff42f77928ad 13 {
f3d 81:7087ba9d18bb 14
f3d 80:ff42f77928ad 15 spi.format(8, 0);
f3d 80:ff42f77928ad 16 spi.frequency(8000000);
f3d 81:7087ba9d18bb 17 T_CS = 1; // de-assert the touch interface for now
f3d 81:7087ba9d18bb 18 D_CS = 1;
f3d 81:7087ba9d18bb 19
f3d 80:ff42f77928ad 20 resetDisplay();
f3d 81:7087ba9d18bb 21
f3d 81:7087ba9d18bb 22 LCD_Write_Data(0x21); // Set GVDD (varies contrast)
f3d 81:7087ba9d18bb 23
f3d 80:ff42f77928ad 24 LCD_Write_Cmd(0xC0); // Power control
f3d 80:ff42f77928ad 25 LCD_Write_Data(0x21); // Set GVDD (varies contrast)
f3d 80:ff42f77928ad 26
f3d 80:ff42f77928ad 27 LCD_Write_Cmd(0xC1); // Power control
f3d 80:ff42f77928ad 28 LCD_Write_Data(0x10); // default value
f3d 80:ff42f77928ad 29
f3d 80:ff42f77928ad 30 LCD_Write_Cmd(0xC5); //VCM control
f3d 80:ff42f77928ad 31 LCD_Write_Data(0x31); // default values
f3d 80:ff42f77928ad 32 LCD_Write_Data(0x3c); //
f3d 80:ff42f77928ad 33
f3d 80:ff42f77928ad 34 LCD_Write_Cmd(0xC7); //VCM control2
f3d 80:ff42f77928ad 35 LCD_Write_Data(0xc0); // default value
f3d 80:ff42f77928ad 36
f3d 80:ff42f77928ad 37 LCD_Write_Cmd(0x36); // Memory Access Control
f3d 80:ff42f77928ad 38 LCD_Write_Data(0x48); // Set display orientation and RGB colour order
f3d 80:ff42f77928ad 39
f3d 80:ff42f77928ad 40 LCD_Write_Cmd(0x3A); // Set Pixel format
f3d 80:ff42f77928ad 41 LCD_Write_Data(0x55); // To 16 bits per pixel
f3d 80:ff42f77928ad 42
f3d 80:ff42f77928ad 43 LCD_Write_Cmd(0xB1); // Frame rate control
f3d 80:ff42f77928ad 44 LCD_Write_Data(0x00); // Use Fosc without divisor
f3d 80:ff42f77928ad 45 LCD_Write_Data(0x1B); // set 70Hz refresh rate
f3d 80:ff42f77928ad 46
f3d 80:ff42f77928ad 47 LCD_Write_Cmd(0xB6); // Display Function Control
f3d 80:ff42f77928ad 48 LCD_Write_Data(0x00); // Use default values
f3d 80:ff42f77928ad 49 LCD_Write_Data(0x82);
f3d 81:7087ba9d18bb 50 LCD_Write_Data(0x27);
f3d 80:ff42f77928ad 51 LCD_Write_Cmd(0x11); //Exit Sleep
f3d 80:ff42f77928ad 52 wait(0.120);
f3d 81:7087ba9d18bb 53
f3d 80:ff42f77928ad 54 LCD_Write_Cmd(0x29); //Display on
f3d 80:ff42f77928ad 55 LCD_Write_Cmd(0x2c);
f3d 80:ff42f77928ad 56 wait(0.005);
f3d 80:ff42f77928ad 57
f3d 81:7087ba9d18bb 58 fillRectangle(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,RGBToWord(0x00,0,0));
f3d 81:7087ba9d18bb 59 D_CS = 1;
f3d 81:7087ba9d18bb 60
f3d 80:ff42f77928ad 61 }
f3d 80:ff42f77928ad 62
f3d 80:ff42f77928ad 63 void Display::CommandMode()
f3d 80:ff42f77928ad 64 {
f3d 80:ff42f77928ad 65 DC = 0;
f3d 80:ff42f77928ad 66 }
f3d 80:ff42f77928ad 67 void Display::DataMode()
f3d 80:ff42f77928ad 68 {
f3d 80:ff42f77928ad 69 DC = 1;
f3d 80:ff42f77928ad 70 }
f3d 80:ff42f77928ad 71 void Display::LCD_Write_Cmd(uint8_t cmd)
f3d 80:ff42f77928ad 72 {
f3d 81:7087ba9d18bb 73
f3d 80:ff42f77928ad 74 CommandMode();
f3d 81:7087ba9d18bb 75 D_CS = 0;
f3d 80:ff42f77928ad 76 spi.write(cmd);
f3d 81:7087ba9d18bb 77 D_CS = 1;
f3d 80:ff42f77928ad 78 }
f3d 80:ff42f77928ad 79 void Display::LCD_Write_Data(uint8_t data)
f3d 80:ff42f77928ad 80 {
f3d 81:7087ba9d18bb 81
f3d 80:ff42f77928ad 82 DataMode();
f3d 81:7087ba9d18bb 83 D_CS = 0;
f3d 80:ff42f77928ad 84 spi.write(data);
f3d 81:7087ba9d18bb 85 D_CS = 1;
f3d 80:ff42f77928ad 86 }
f3d 80:ff42f77928ad 87 void Display::resetDisplay()
f3d 80:ff42f77928ad 88 {
f3d 80:ff42f77928ad 89 Rst = 0;
f3d 80:ff42f77928ad 90 wait(0.01);
f3d 80:ff42f77928ad 91 Rst = 1;
f3d 80:ff42f77928ad 92 wait(0.12);
f3d 80:ff42f77928ad 93 }
f3d 80:ff42f77928ad 94 void Display::openAperture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
f3d 80:ff42f77928ad 95 {
f3d 80:ff42f77928ad 96 LCD_Write_Cmd(0x2a);
f3d 80:ff42f77928ad 97 LCD_Write_Data(x1>>8);
f3d 80:ff42f77928ad 98 LCD_Write_Data(x1);
f3d 80:ff42f77928ad 99 LCD_Write_Data(x2>>8);
f3d 80:ff42f77928ad 100 LCD_Write_Data(x2);
f3d 80:ff42f77928ad 101 LCD_Write_Cmd(0x2b);
f3d 80:ff42f77928ad 102 LCD_Write_Data(y1>>8);
f3d 80:ff42f77928ad 103 LCD_Write_Data(y1);
f3d 80:ff42f77928ad 104 LCD_Write_Data(y2>>8);
f3d 80:ff42f77928ad 105 LCD_Write_Data(y2);
f3d 80:ff42f77928ad 106 LCD_Write_Cmd(0x2c);
f3d 80:ff42f77928ad 107 }
f3d 80:ff42f77928ad 108 // Simple Pixel drawing routines
f3d 80:ff42f77928ad 109 void Display::putPixel(uint16_t x, uint16_t y, uint16_t Colour)
f3d 80:ff42f77928ad 110 {
f3d 80:ff42f77928ad 111 uint16_t rx;
f3d 81:7087ba9d18bb 112
f3d 80:ff42f77928ad 113 openAperture(x,y,x+1,y+1);
f3d 80:ff42f77928ad 114 DataMode();
f3d 81:7087ba9d18bb 115 D_CS = 0;
f3d 80:ff42f77928ad 116 spi.write((const char *) &Colour,2,(char *)&rx,0);
f3d 81:7087ba9d18bb 117 D_CS = 1;
f3d 80:ff42f77928ad 118 }
f3d 81:7087ba9d18bb 119 void Display::putImage(uint16_t xofs, uint16_t yofs, uint16_t width, uint16_t height, const uint16_t *Image)
f3d 80:ff42f77928ad 120 {
f3d 80:ff42f77928ad 121 uint16_t rx;
f3d 80:ff42f77928ad 122 uint16_t Colour;
f3d 81:7087ba9d18bb 123
f3d 81:7087ba9d18bb 124 uint16_t x,y;
f3d 81:7087ba9d18bb 125 for (y = 0; y < height; y++) {
f3d 80:ff42f77928ad 126 for (x=0; x < width; x++)
f3d 80:ff42f77928ad 127 {
f3d 81:7087ba9d18bb 128 Colour = *(Image++);
f3d 81:7087ba9d18bb 129 putPixel(x+xofs,y+yofs,Colour);
f3d 81:7087ba9d18bb 130 }
f3d 81:7087ba9d18bb 131 }
f3d 80:ff42f77928ad 132 }
f3d 80:ff42f77928ad 133 void Display::fillRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t Colour)
f3d 80:ff42f77928ad 134 {
f3d 80:ff42f77928ad 135 /* in an effort to reduce overhead here a large word buffer is created. If the number of words to
f3d 80:ff42f77928ad 136 to write is greater than or equal to the size of this buffer then it is filled with the relevant colour
f3d 80:ff42f77928ad 137 and used as the source of data in the spi.write function. This greatly speeds up the writing of
f3d 80:ff42f77928ad 138 large arease of the screen. The choice of buffer size is interesting.
f3d 80:ff42f77928ad 139 */
f3d 80:ff42f77928ad 140 #define BUF_SIZE 32
f3d 80:ff42f77928ad 141 uint16_t rx;
f3d 80:ff42f77928ad 142 uint16_t txBuffer[BUF_SIZE];
f3d 81:7087ba9d18bb 143 int count;
f3d 80:ff42f77928ad 144 openAperture(x,y,width,height);
f3d 80:ff42f77928ad 145 DataMode();
f3d 81:7087ba9d18bb 146 D_CS = 0;
f3d 80:ff42f77928ad 147 count = (width*height)/BUF_SIZE;
f3d 80:ff42f77928ad 148 if (count)
f3d 80:ff42f77928ad 149 { // big area
f3d 80:ff42f77928ad 150 for (int i=0;i<BUF_SIZE;i++)
f3d 80:ff42f77928ad 151 {
f3d 80:ff42f77928ad 152 txBuffer[i]=Colour;
f3d 80:ff42f77928ad 153 }
f3d 80:ff42f77928ad 154 while(count--)
f3d 80:ff42f77928ad 155 {
f3d 80:ff42f77928ad 156 spi.write((const char *)txBuffer,2*BUF_SIZE,(char *)&rx,0);
f3d 80:ff42f77928ad 157 }
f3d 80:ff42f77928ad 158 count = (width*height)%BUF_SIZE; // write remainder of block
f3d 80:ff42f77928ad 159 while (count--)
f3d 80:ff42f77928ad 160 {
f3d 80:ff42f77928ad 161 spi.write((const char *) &Colour,2,(char *)&rx,0); // write a block of colour
f3d 80:ff42f77928ad 162 }
f3d 80:ff42f77928ad 163
f3d 80:ff42f77928ad 164 }
f3d 80:ff42f77928ad 165 else
f3d 80:ff42f77928ad 166 {
f3d 80:ff42f77928ad 167 // small area so write 1 word at a time.
f3d 80:ff42f77928ad 168 count = (width*height);
f3d 80:ff42f77928ad 169 while(count--)
f3d 80:ff42f77928ad 170 {
f3d 80:ff42f77928ad 171 spi.write((const char *) &Colour,2,(char *)&rx,0);
f3d 80:ff42f77928ad 172 }
f3d 80:ff42f77928ad 173
f3d 80:ff42f77928ad 174 }
f3d 81:7087ba9d18bb 175 D_CS = 1;
f3d 80:ff42f77928ad 176 }
f3d 80:ff42f77928ad 177
f3d 80:ff42f77928ad 178 void Display::drawLineLowSlope(uint16_t x0, uint16_t y0, uint16_t x1,uint16_t y1, uint16_t Colour)
f3d 80:ff42f77928ad 179 {
f3d 80:ff42f77928ad 180 // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
f3d 80:ff42f77928ad 181 int dx = x1 - x0;
f3d 80:ff42f77928ad 182 int dy = y1 - y0;
f3d 80:ff42f77928ad 183 int yi = 1;
f3d 80:ff42f77928ad 184 if (dy < 0)
f3d 80:ff42f77928ad 185 {
f3d 80:ff42f77928ad 186 yi = -1;
f3d 80:ff42f77928ad 187 dy = -dy;
f3d 80:ff42f77928ad 188 }
f3d 80:ff42f77928ad 189 int D = 2*dy - dx;
f3d 80:ff42f77928ad 190
f3d 80:ff42f77928ad 191 int y = y0;
f3d 80:ff42f77928ad 192
f3d 80:ff42f77928ad 193 for (int x=x0; x <= x1;x++)
f3d 80:ff42f77928ad 194 {
f3d 80:ff42f77928ad 195 putPixel(x,y,Colour);
f3d 80:ff42f77928ad 196 if (D > 0)
f3d 80:ff42f77928ad 197 {
f3d 80:ff42f77928ad 198 y = y + yi;
f3d 80:ff42f77928ad 199 D = D - 2*dx;
f3d 80:ff42f77928ad 200 }
f3d 80:ff42f77928ad 201 D = D + 2*dy;
f3d 80:ff42f77928ad 202
f3d 80:ff42f77928ad 203 }
f3d 80:ff42f77928ad 204 }
f3d 80:ff42f77928ad 205
f3d 80:ff42f77928ad 206 void Display::drawLineHighSlope(uint16_t x0, uint16_t y0, uint16_t x1,uint16_t y1, uint16_t Colour)
f3d 80:ff42f77928ad 207 {
f3d 80:ff42f77928ad 208 // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
f3d 80:ff42f77928ad 209
f3d 80:ff42f77928ad 210 int dx = x1 - x0;
f3d 80:ff42f77928ad 211 int dy = y1 - y0;
f3d 80:ff42f77928ad 212 int xi = 1;
f3d 80:ff42f77928ad 213 if (dx < 0)
f3d 80:ff42f77928ad 214 {
f3d 80:ff42f77928ad 215 xi = -1;
f3d 80:ff42f77928ad 216 dx = -dx;
f3d 80:ff42f77928ad 217 }
f3d 80:ff42f77928ad 218 int D = 2*dx - dy;
f3d 80:ff42f77928ad 219 int x = x0;
f3d 80:ff42f77928ad 220
f3d 80:ff42f77928ad 221 for (int y=y0; y <= y1; y++)
f3d 80:ff42f77928ad 222 {
f3d 80:ff42f77928ad 223 putPixel(x,y,Colour);
f3d 80:ff42f77928ad 224 if (D > 0)
f3d 80:ff42f77928ad 225 {
f3d 80:ff42f77928ad 226 x = x + xi;
f3d 80:ff42f77928ad 227 D = D - 2*dy;
f3d 80:ff42f77928ad 228 }
f3d 80:ff42f77928ad 229 D = D + 2*dx;
f3d 80:ff42f77928ad 230 }
f3d 80:ff42f77928ad 231 }
f3d 80:ff42f77928ad 232 void Display::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t Colour)
f3d 80:ff42f77928ad 233 {
f3d 80:ff42f77928ad 234 // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
f3d 81:7087ba9d18bb 235 D_CS = 0;
f3d 80:ff42f77928ad 236 if ( iabs(y1 - y0) < iabs(x1 - x0) )
f3d 80:ff42f77928ad 237 {
f3d 80:ff42f77928ad 238 if (x0 > x1)
f3d 80:ff42f77928ad 239 {
f3d 80:ff42f77928ad 240 drawLineLowSlope(x1, y1, x0, y0, Colour);
f3d 80:ff42f77928ad 241 }
f3d 80:ff42f77928ad 242 else
f3d 80:ff42f77928ad 243 {
f3d 80:ff42f77928ad 244 drawLineLowSlope(x0, y0, x1, y1, Colour);
f3d 80:ff42f77928ad 245 }
f3d 80:ff42f77928ad 246 }
f3d 80:ff42f77928ad 247 else
f3d 80:ff42f77928ad 248 {
f3d 80:ff42f77928ad 249 if (y0 > y1)
f3d 80:ff42f77928ad 250 {
f3d 80:ff42f77928ad 251 drawLineHighSlope(x1, y1, x0, y0, Colour);
f3d 80:ff42f77928ad 252 }
f3d 80:ff42f77928ad 253 else
f3d 80:ff42f77928ad 254 {
f3d 80:ff42f77928ad 255 drawLineHighSlope(x0, y0, x1, y1, Colour);
f3d 80:ff42f77928ad 256 }
f3d 80:ff42f77928ad 257
f3d 80:ff42f77928ad 258 }
f3d 81:7087ba9d18bb 259 D_CS = 1;
f3d 80:ff42f77928ad 260 }
f3d 80:ff42f77928ad 261
f3d 80:ff42f77928ad 262
f3d 80:ff42f77928ad 263 uint16_t Display::RGBToWord(uint16_t R, uint16_t G, uint16_t B)
f3d 80:ff42f77928ad 264 {
f3d 80:ff42f77928ad 265 uint16_t rvalue = 0;
f3d 80:ff42f77928ad 266 rvalue += G >> 5;
f3d 80:ff42f77928ad 267 rvalue += (G & (0b111)) << 13;
f3d 80:ff42f77928ad 268 rvalue += (B >> 3) << 8;
f3d 80:ff42f77928ad 269 rvalue += (R >> 3) << 3;
f3d 80:ff42f77928ad 270 return rvalue;
f3d 80:ff42f77928ad 271 }
f3d 80:ff42f77928ad 272 void Display::drawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t Colour)
f3d 80:ff42f77928ad 273 {
f3d 80:ff42f77928ad 274 drawLine(x,y,x+w,y,Colour);
f3d 80:ff42f77928ad 275 drawLine(x,y,x,y+h,Colour);
f3d 80:ff42f77928ad 276 drawLine(x+w,y,x+w,y+h,Colour);
f3d 80:ff42f77928ad 277 drawLine(x,y+h,x+w,y+h,Colour);
f3d 80:ff42f77928ad 278 }
f3d 80:ff42f77928ad 279
f3d 80:ff42f77928ad 280 void Display::drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour)
f3d 80:ff42f77928ad 281 {
f3d 80:ff42f77928ad 282 // Reference : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
f3d 80:ff42f77928ad 283 int x = radius-1;
f3d 80:ff42f77928ad 284 int y = 0;
f3d 80:ff42f77928ad 285 int dx = 1;
f3d 80:ff42f77928ad 286 int dy = 1;
f3d 80:ff42f77928ad 287 int err = dx - (radius << 1);
f3d 80:ff42f77928ad 288 if (radius > x0)
f3d 80:ff42f77928ad 289 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 290 if (radius > y0)
f3d 80:ff42f77928ad 291 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 292
f3d 80:ff42f77928ad 293 if ((x0+radius) > SCREEN_WIDTH)
f3d 80:ff42f77928ad 294 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 295 if ((y0+radius) > SCREEN_HEIGHT)
f3d 80:ff42f77928ad 296 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 297 while (x >= y)
f3d 80:ff42f77928ad 298 {
f3d 80:ff42f77928ad 299 putPixel(x0 + x, y0 + y, Colour);
f3d 80:ff42f77928ad 300 putPixel(x0 + y, y0 + x, Colour);
f3d 80:ff42f77928ad 301 putPixel(x0 - y, y0 + x, Colour);
f3d 80:ff42f77928ad 302 putPixel(x0 - x, y0 + y, Colour);
f3d 80:ff42f77928ad 303 putPixel(x0 - x, y0 - y, Colour);
f3d 80:ff42f77928ad 304 putPixel(x0 - y, y0 - x, Colour);
f3d 80:ff42f77928ad 305 putPixel(x0 + y, y0 - x, Colour);
f3d 80:ff42f77928ad 306 putPixel(x0 + x, y0 - y, Colour);
f3d 80:ff42f77928ad 307
f3d 80:ff42f77928ad 308 if (err <= 0)
f3d 80:ff42f77928ad 309 {
f3d 80:ff42f77928ad 310 y++;
f3d 80:ff42f77928ad 311 err += dy;
f3d 80:ff42f77928ad 312 dy += 2;
f3d 80:ff42f77928ad 313 }
f3d 80:ff42f77928ad 314
f3d 80:ff42f77928ad 315 if (err > 0)
f3d 80:ff42f77928ad 316 {
f3d 80:ff42f77928ad 317 x--;
f3d 80:ff42f77928ad 318 dx += 2;
f3d 80:ff42f77928ad 319 err += dx - (radius << 1);
f3d 80:ff42f77928ad 320 }
f3d 80:ff42f77928ad 321 }
f3d 80:ff42f77928ad 322 }
f3d 80:ff42f77928ad 323 void Display::fillCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour)
f3d 80:ff42f77928ad 324 {
f3d 80:ff42f77928ad 325 // Reference : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
f3d 80:ff42f77928ad 326 // Similar to drawCircle but fills the circle with lines instead
f3d 80:ff42f77928ad 327 int x = radius-1;
f3d 80:ff42f77928ad 328 int y = 0;
f3d 80:ff42f77928ad 329 int dx = 1;
f3d 80:ff42f77928ad 330 int dy = 1;
f3d 80:ff42f77928ad 331 int err = dx - (radius << 1);
f3d 80:ff42f77928ad 332
f3d 80:ff42f77928ad 333 if (radius > x0)
f3d 80:ff42f77928ad 334 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 335 if (radius > y0)
f3d 80:ff42f77928ad 336 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 337
f3d 80:ff42f77928ad 338 if ((x0+radius) > SCREEN_WIDTH)
f3d 80:ff42f77928ad 339 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 340 if ((y0+radius) > SCREEN_HEIGHT)
f3d 80:ff42f77928ad 341 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 342 while (x >= y)
f3d 80:ff42f77928ad 343 {
f3d 80:ff42f77928ad 344 drawLine(x0 - x, y0 + y,x0 + x, y0 + y, Colour);
f3d 80:ff42f77928ad 345 drawLine(x0 - y, y0 + x,x0 + y, y0 + x, Colour);
f3d 80:ff42f77928ad 346 drawLine(x0 - x, y0 - y,x0 + x, y0 - y, Colour);
f3d 80:ff42f77928ad 347 drawLine(x0 - y, y0 - x,x0 + y, y0 - x, Colour);
f3d 80:ff42f77928ad 348
f3d 80:ff42f77928ad 349 if (err <= 0)
f3d 80:ff42f77928ad 350 {
f3d 80:ff42f77928ad 351 y++;
f3d 80:ff42f77928ad 352 err += dy;
f3d 80:ff42f77928ad 353 dy += 2;
f3d 80:ff42f77928ad 354 }
f3d 80:ff42f77928ad 355
f3d 80:ff42f77928ad 356 if (err > 0)
f3d 80:ff42f77928ad 357 {
f3d 80:ff42f77928ad 358 x--;
f3d 80:ff42f77928ad 359 dx += 2;
f3d 80:ff42f77928ad 360 err += dx - (radius << 1);
f3d 80:ff42f77928ad 361 }
f3d 80:ff42f77928ad 362 }
f3d 81:7087ba9d18bb 363 }
f3d 81:7087ba9d18bb 364 void Display::print(const char *Text, uint16_t len, uint16_t x, uint16_t y, uint16_t ForeColour, uint16_t BackColour)
f3d 81:7087ba9d18bb 365 {
f3d 81:7087ba9d18bb 366 // This function draws each character individually. It uses an array called TextBox as a temporary storage
f3d 81:7087ba9d18bb 367 // location to hold the dots for the character in question. It constructs the image of the character and then
f3d 81:7087ba9d18bb 368 // calls on putImage to place it on the screen
f3d 81:7087ba9d18bb 369 uint8_t Index = 0;
f3d 81:7087ba9d18bb 370 uint8_t Row, Col;
f3d 81:7087ba9d18bb 371 const uint8_t *CharacterCode = 0;
f3d 81:7087ba9d18bb 372 uint16_t TextBox[FONT_WIDTH * FONT_HEIGHT];
f3d 81:7087ba9d18bb 373 for (Index = 0; Index < len; Index++)
f3d 81:7087ba9d18bb 374 {
f3d 81:7087ba9d18bb 375 CharacterCode = &Font5x7[FONT_WIDTH * (Text[Index] - 32)];
f3d 81:7087ba9d18bb 376 Col = 0;
f3d 81:7087ba9d18bb 377 while (Col < FONT_WIDTH)
f3d 81:7087ba9d18bb 378 {
f3d 81:7087ba9d18bb 379 Row = 0;
f3d 81:7087ba9d18bb 380 while (Row < FONT_HEIGHT)
f3d 81:7087ba9d18bb 381 {
f3d 81:7087ba9d18bb 382 if (CharacterCode[Col] & (1 << Row))
f3d 81:7087ba9d18bb 383 {
f3d 81:7087ba9d18bb 384 TextBox[(Row * FONT_WIDTH) + Col] = ForeColour;
f3d 81:7087ba9d18bb 385 }
f3d 81:7087ba9d18bb 386 else
f3d 81:7087ba9d18bb 387 {
f3d 81:7087ba9d18bb 388 TextBox[(Row * FONT_WIDTH) + Col] = BackColour;
f3d 81:7087ba9d18bb 389 }
f3d 81:7087ba9d18bb 390 Row++;
f3d 81:7087ba9d18bb 391 }
f3d 81:7087ba9d18bb 392 Col++;
f3d 81:7087ba9d18bb 393 }
f3d 81:7087ba9d18bb 394 putImage(x, y, FONT_WIDTH, FONT_HEIGHT, (const uint16_t *)TextBox);
f3d 81:7087ba9d18bb 395 x = x + FONT_WIDTH + 2;
f3d 81:7087ba9d18bb 396 }
f3d 81:7087ba9d18bb 397 }
f3d 81:7087ba9d18bb 398 void Display::print(uint16_t Number, uint16_t x, uint16_t y, uint16_t ForeColour, uint16_t BackColour)
f3d 81:7087ba9d18bb 399 {
f3d 81:7087ba9d18bb 400 // This function converts the supplied number into a character string and then calls on puText to
f3d 81:7087ba9d18bb 401 // write it to the display
f3d 81:7087ba9d18bb 402 char Buffer[5]; // Maximum value = 65535
f3d 81:7087ba9d18bb 403 Buffer[4] = Number % 10 + '0';
f3d 81:7087ba9d18bb 404 Number = Number / 10;
f3d 81:7087ba9d18bb 405 Buffer[3] = Number % 10 + '0';
f3d 81:7087ba9d18bb 406 Number = Number / 10;
f3d 81:7087ba9d18bb 407 Buffer[2] = Number % 10 + '0';
f3d 81:7087ba9d18bb 408 Number = Number / 10;
f3d 81:7087ba9d18bb 409 Buffer[1] = Number % 10 + '0';
f3d 81:7087ba9d18bb 410 Number = Number / 10;
f3d 81:7087ba9d18bb 411 Buffer[0] = Number % 10 + '0';
f3d 81:7087ba9d18bb 412 print(Buffer, 5, x, y, ForeColour, BackColour);
f3d 81:7087ba9d18bb 413 }
f3d 81:7087ba9d18bb 414 void Display::initTouch(void)
f3d 81:7087ba9d18bb 415 {
f3d 81:7087ba9d18bb 416 // This display module has an XPT2046 touch screen controller connected over the SPI interface
f3d 81:7087ba9d18bb 417 // The XPT2046
f3d 81:7087ba9d18bb 418 T_CS = 0;
f3d 81:7087ba9d18bb 419 spi.write(0b10011000); // 8 bit conversion, ratiometric measurement, read XP
f3d 81:7087ba9d18bb 420 //wait_us(100);
f3d 81:7087ba9d18bb 421 uint16_t indata,outdata;
f3d 81:7087ba9d18bb 422 outdata = 0xffff;
f3d 81:7087ba9d18bb 423 spi.write((const char *) &outdata,2,(char *)&indata,2); // write a block of colour
f3d 81:7087ba9d18bb 424 T_CS = 1;
f3d 81:7087ba9d18bb 425 }
f3d 81:7087ba9d18bb 426 uint16_t Display::readYTouch(void)
f3d 81:7087ba9d18bb 427 {
f3d 81:7087ba9d18bb 428 // This display module has an XPT2046 touch screen controller connected over the SPI interface
f3d 81:7087ba9d18bb 429 // The XPT2046
f3d 81:7087ba9d18bb 430 /*
f3d 81:7087ba9d18bb 431 Format of command word :
f3d 81:7087ba9d18bb 432 b7 : must be 1
f3d 81:7087ba9d18bb 433 b6,5,4 : A2,A1,A0
f3d 81:7087ba9d18bb 434 000 : temperature
f3d 81:7087ba9d18bb 435
f3d 81:7087ba9d18bb 436 b3 : Mode
f3d 81:7087ba9d18bb 437 b2 : SER,DFR
f3d 81:7087ba9d18bb 438 b1,0 : PD1,PD0
f3d 81:7087ba9d18bb 439 */
f3d 81:7087ba9d18bb 440 uint16_t indata,outdata;
f3d 81:7087ba9d18bb 441 spi.frequency(2000000); // Can't run the touch screen controller at high speed
f3d 81:7087ba9d18bb 442 T_CS = 0;
f3d 81:7087ba9d18bb 443 spi.write((uint8_t)0b10011000); // 12 bit conversion, ratiometric measurement, reference off
f3d 81:7087ba9d18bb 444 // read XP which tells us Y (see diagram in datasheet)
f3d 81:7087ba9d18bb 445 wait_us(20);
f3d 81:7087ba9d18bb 446 outdata = 0xffff;
f3d 81:7087ba9d18bb 447 spi.write((const char *) &outdata,2,(char *)&indata,2);
f3d 81:7087ba9d18bb 448 T_CS = 1;
f3d 81:7087ba9d18bb 449 spi.frequency(8000000);
f3d 81:7087ba9d18bb 450 int calibrated_return= (indata>>12)+((indata & 0xff)<<4);
f3d 81:7087ba9d18bb 451 calibrated_return = (calibrated_return - Y_TOUCH_MIN);
f3d 81:7087ba9d18bb 452 if (calibrated_return < 0)
f3d 81:7087ba9d18bb 453 calibrated_return = 0;
f3d 81:7087ba9d18bb 454 calibrated_return = (calibrated_return * SCREEN_HEIGHT) / (Y_TOUCH_MAX - Y_TOUCH_MIN) ;
f3d 81:7087ba9d18bb 455 return calibrated_return;
f3d 81:7087ba9d18bb 456 }
f3d 81:7087ba9d18bb 457 uint16_t Display::readXTouch(void)
f3d 81:7087ba9d18bb 458 {
f3d 81:7087ba9d18bb 459 // This display module has an XPT2046 touch screen controller connected over the SPI interface
f3d 81:7087ba9d18bb 460 // The XPT2046
f3d 81:7087ba9d18bb 461 /*
f3d 81:7087ba9d18bb 462 Format of command word :
f3d 81:7087ba9d18bb 463 b7 : must be 1
f3d 81:7087ba9d18bb 464 b6,5,4 : A2,A1,A0
f3d 81:7087ba9d18bb 465 000 : temperature
f3d 81:7087ba9d18bb 466
f3d 81:7087ba9d18bb 467 b3 : Mode
f3d 81:7087ba9d18bb 468 b2 : SER,DFR
f3d 81:7087ba9d18bb 469 b1,0 : PD1,PD0
f3d 81:7087ba9d18bb 470 */
f3d 81:7087ba9d18bb 471 uint16_t indata,outdata;
f3d 81:7087ba9d18bb 472 spi.frequency(2000000);// Can't run the touch screen controller at high speed
f3d 81:7087ba9d18bb 473 T_CS = 0;
f3d 81:7087ba9d18bb 474 spi.write((uint8_t)0b11011000); // 12 bit conversion, ratiometric measurement, reference off
f3d 81:7087ba9d18bb 475 // read YP which tells us X (see diagram in datasheet)
f3d 81:7087ba9d18bb 476 wait_us(20);
f3d 81:7087ba9d18bb 477 outdata = 0xffff;
f3d 81:7087ba9d18bb 478 spi.write((const char *) &outdata,2,(char *)&indata,2);
f3d 81:7087ba9d18bb 479 T_CS = 1;
f3d 81:7087ba9d18bb 480 spi.frequency(8000000);
f3d 81:7087ba9d18bb 481 int calibrated_return= (indata>>12)+((indata & 0xff)<<4);
f3d 81:7087ba9d18bb 482 calibrated_return = (calibrated_return - X_TOUCH_MIN);
f3d 81:7087ba9d18bb 483 if (calibrated_return < 0)
f3d 81:7087ba9d18bb 484 calibrated_return = 0;
f3d 81:7087ba9d18bb 485 calibrated_return = (calibrated_return * SCREEN_WIDTH) / (X_TOUCH_MAX - X_TOUCH_MIN);
f3d 81:7087ba9d18bb 486 // The X reading is backwards so need to subtract it from the screen width
f3d 81:7087ba9d18bb 487 calibrated_return = SCREEN_WIDTH - calibrated_return;
f3d 81:7087ba9d18bb 488 if (calibrated_return < 0)
f3d 81:7087ba9d18bb 489 calibrated_return = 0;
f3d 81:7087ba9d18bb 490 return calibrated_return;
f3d 81:7087ba9d18bb 491 }
f3d 81:7087ba9d18bb 492 int Display::penDown(void)
f3d 81:7087ba9d18bb 493 {
f3d 81:7087ba9d18bb 494 if (PenIRQ.read()==0)
f3d 81:7087ba9d18bb 495 return 1;
f3d 81:7087ba9d18bb 496 else
f3d 81:7087ba9d18bb 497 return 0;
f3d 80:ff42f77928ad 498 }