Basic driver working

Committer:
f3d
Date:
Wed Feb 03 11:30:30 2021 +0000
Revision:
80:ff42f77928ad
Child:
81:7087ba9d18bb
Basic driver working

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 80:ff42f77928ad 3 //mosi,miso,clk,ss
f3d 80:ff42f77928ad 4 SPI spi(P0_25,P0_26,P0_27,P0_28);
f3d 80:ff42f77928ad 5 DigitalOut Rst(P0_7);
f3d 80:ff42f77928ad 6 DigitalOut DC(P0_6);
f3d 80:ff42f77928ad 7
f3d 80:ff42f77928ad 8 void Display::begin()
f3d 80:ff42f77928ad 9 {
f3d 80:ff42f77928ad 10 while(0)
f3d 80:ff42f77928ad 11 {
f3d 80:ff42f77928ad 12 DC = 1;
f3d 80:ff42f77928ad 13 Rst = 1;
f3d 80:ff42f77928ad 14 wait(0.5);
f3d 80:ff42f77928ad 15 DC = 0;
f3d 80:ff42f77928ad 16 Rst = 0;
f3d 80:ff42f77928ad 17 wait(0.5);
f3d 80:ff42f77928ad 18 }
f3d 80:ff42f77928ad 19 spi.format(8, 0);
f3d 80:ff42f77928ad 20 spi.frequency(8000000);
f3d 80:ff42f77928ad 21 resetDisplay();
f3d 80:ff42f77928ad 22
f3d 80:ff42f77928ad 23 LCD_Write_Cmd(0xC0); // Power control
f3d 80:ff42f77928ad 24 LCD_Write_Data(0x21); // Set GVDD (varies contrast)
f3d 80:ff42f77928ad 25
f3d 80:ff42f77928ad 26 LCD_Write_Cmd(0xC1); // Power control
f3d 80:ff42f77928ad 27 LCD_Write_Data(0x10); // default value
f3d 80:ff42f77928ad 28
f3d 80:ff42f77928ad 29 LCD_Write_Cmd(0xC5); //VCM control
f3d 80:ff42f77928ad 30 LCD_Write_Data(0x31); // default values
f3d 80:ff42f77928ad 31 LCD_Write_Data(0x3c); //
f3d 80:ff42f77928ad 32
f3d 80:ff42f77928ad 33 LCD_Write_Cmd(0xC7); //VCM control2
f3d 80:ff42f77928ad 34 LCD_Write_Data(0xc0); // default value
f3d 80:ff42f77928ad 35
f3d 80:ff42f77928ad 36 LCD_Write_Cmd(0x36); // Memory Access Control
f3d 80:ff42f77928ad 37 LCD_Write_Data(0x48); // Set display orientation and RGB colour order
f3d 80:ff42f77928ad 38
f3d 80:ff42f77928ad 39 LCD_Write_Cmd(0x3A); // Set Pixel format
f3d 80:ff42f77928ad 40 LCD_Write_Data(0x55); // To 16 bits per pixel
f3d 80:ff42f77928ad 41
f3d 80:ff42f77928ad 42 LCD_Write_Cmd(0xB1); // Frame rate control
f3d 80:ff42f77928ad 43 LCD_Write_Data(0x00); // Use Fosc without divisor
f3d 80:ff42f77928ad 44 LCD_Write_Data(0x1B); // set 70Hz refresh rate
f3d 80:ff42f77928ad 45
f3d 80:ff42f77928ad 46 LCD_Write_Cmd(0xB6); // Display Function Control
f3d 80:ff42f77928ad 47 LCD_Write_Data(0x00); // Use default values
f3d 80:ff42f77928ad 48 LCD_Write_Data(0x82);
f3d 80:ff42f77928ad 49 LCD_Write_Data(0x27);
f3d 80:ff42f77928ad 50
f3d 80:ff42f77928ad 51 LCD_Write_Cmd(0x11); //Exit Sleep
f3d 80:ff42f77928ad 52 wait(0.120);
f3d 80:ff42f77928ad 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 80:ff42f77928ad 58 fillRectangle(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,RGBToWord(0,0,0));
f3d 80:ff42f77928ad 59
f3d 80:ff42f77928ad 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 80:ff42f77928ad 73 CommandMode();
f3d 80:ff42f77928ad 74 spi.write(cmd);
f3d 80:ff42f77928ad 75 }
f3d 80:ff42f77928ad 76 void Display::LCD_Write_Data(uint8_t data)
f3d 80:ff42f77928ad 77 {
f3d 80:ff42f77928ad 78 DataMode();
f3d 80:ff42f77928ad 79 spi.write(data);
f3d 80:ff42f77928ad 80 }
f3d 80:ff42f77928ad 81 void Display::resetDisplay()
f3d 80:ff42f77928ad 82 {
f3d 80:ff42f77928ad 83 Rst = 0;
f3d 80:ff42f77928ad 84 wait(0.01);
f3d 80:ff42f77928ad 85 Rst = 1;
f3d 80:ff42f77928ad 86 wait(0.12);
f3d 80:ff42f77928ad 87 }
f3d 80:ff42f77928ad 88 void Display::openAperture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
f3d 80:ff42f77928ad 89 {
f3d 80:ff42f77928ad 90 LCD_Write_Cmd(0x2a);
f3d 80:ff42f77928ad 91 LCD_Write_Data(x1>>8);
f3d 80:ff42f77928ad 92 LCD_Write_Data(x1);
f3d 80:ff42f77928ad 93 LCD_Write_Data(x2>>8);
f3d 80:ff42f77928ad 94 LCD_Write_Data(x2);
f3d 80:ff42f77928ad 95 LCD_Write_Cmd(0x2b);
f3d 80:ff42f77928ad 96 LCD_Write_Data(y1>>8);
f3d 80:ff42f77928ad 97 LCD_Write_Data(y1);
f3d 80:ff42f77928ad 98 LCD_Write_Data(y2>>8);
f3d 80:ff42f77928ad 99 LCD_Write_Data(y2);
f3d 80:ff42f77928ad 100 LCD_Write_Cmd(0x2c);
f3d 80:ff42f77928ad 101 }
f3d 80:ff42f77928ad 102 // Simple Pixel drawing routines
f3d 80:ff42f77928ad 103 void Display::putPixel(uint16_t x, uint16_t y, uint16_t Colour)
f3d 80:ff42f77928ad 104 {
f3d 80:ff42f77928ad 105 uint16_t rx;
f3d 80:ff42f77928ad 106 openAperture(x,y,x+1,y+1);
f3d 80:ff42f77928ad 107 DataMode();
f3d 80:ff42f77928ad 108 spi.write((const char *) &Colour,2,(char *)&rx,0);
f3d 80:ff42f77928ad 109 }
f3d 80:ff42f77928ad 110 void Display::putImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *Image)
f3d 80:ff42f77928ad 111 {
f3d 80:ff42f77928ad 112 uint16_t rx;
f3d 80:ff42f77928ad 113 uint16_t Colour;
f3d 80:ff42f77928ad 114 openAperture(x,y,width,height);
f3d 80:ff42f77928ad 115 for (y = 0; y < height; y++)
f3d 80:ff42f77928ad 116 for (x=0; x < width; x++)
f3d 80:ff42f77928ad 117 {
f3d 80:ff42f77928ad 118 Colour = *(Image++);
f3d 80:ff42f77928ad 119 spi.write((const char *) &Colour,2,(char *)&rx,0);
f3d 80:ff42f77928ad 120 }
f3d 80:ff42f77928ad 121 }
f3d 80:ff42f77928ad 122 void Display::fillRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t Colour)
f3d 80:ff42f77928ad 123 {
f3d 80:ff42f77928ad 124 /* in an effort to reduce overhead here a large word buffer is created. If the number of words to
f3d 80:ff42f77928ad 125 to write is greater than or equal to the size of this buffer then it is filled with the relevant colour
f3d 80:ff42f77928ad 126 and used as the source of data in the spi.write function. This greatly speeds up the writing of
f3d 80:ff42f77928ad 127 large arease of the screen. The choice of buffer size is interesting.
f3d 80:ff42f77928ad 128 */
f3d 80:ff42f77928ad 129 #define BUF_SIZE 32
f3d 80:ff42f77928ad 130 uint16_t rx;
f3d 80:ff42f77928ad 131 uint16_t txBuffer[BUF_SIZE];
f3d 80:ff42f77928ad 132 int count;
f3d 80:ff42f77928ad 133 openAperture(x,y,width,height);
f3d 80:ff42f77928ad 134 DataMode();
f3d 80:ff42f77928ad 135 count = (width*height)/BUF_SIZE;
f3d 80:ff42f77928ad 136 if (count)
f3d 80:ff42f77928ad 137 { // big area
f3d 80:ff42f77928ad 138 for (int i=0;i<BUF_SIZE;i++)
f3d 80:ff42f77928ad 139 {
f3d 80:ff42f77928ad 140 txBuffer[i]=Colour;
f3d 80:ff42f77928ad 141 }
f3d 80:ff42f77928ad 142 while(count--)
f3d 80:ff42f77928ad 143 {
f3d 80:ff42f77928ad 144 spi.write((const char *)txBuffer,2*BUF_SIZE,(char *)&rx,0);
f3d 80:ff42f77928ad 145 }
f3d 80:ff42f77928ad 146 count = (width*height)%BUF_SIZE; // write remainder of block
f3d 80:ff42f77928ad 147 while (count--)
f3d 80:ff42f77928ad 148 {
f3d 80:ff42f77928ad 149 spi.write((const char *) &Colour,2,(char *)&rx,0); // write a block of colour
f3d 80:ff42f77928ad 150 }
f3d 80:ff42f77928ad 151
f3d 80:ff42f77928ad 152 }
f3d 80:ff42f77928ad 153 else
f3d 80:ff42f77928ad 154 {
f3d 80:ff42f77928ad 155 // small area so write 1 word at a time.
f3d 80:ff42f77928ad 156 count = (width*height);
f3d 80:ff42f77928ad 157 while(count--)
f3d 80:ff42f77928ad 158 {
f3d 80:ff42f77928ad 159 spi.write((const char *) &Colour,2,(char *)&rx,0);
f3d 80:ff42f77928ad 160 }
f3d 80:ff42f77928ad 161
f3d 80:ff42f77928ad 162 }
f3d 80:ff42f77928ad 163 }
f3d 80:ff42f77928ad 164
f3d 80:ff42f77928ad 165 void Display::drawLineLowSlope(uint16_t x0, uint16_t y0, uint16_t x1,uint16_t y1, uint16_t Colour)
f3d 80:ff42f77928ad 166 {
f3d 80:ff42f77928ad 167 // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
f3d 80:ff42f77928ad 168 int dx = x1 - x0;
f3d 80:ff42f77928ad 169 int dy = y1 - y0;
f3d 80:ff42f77928ad 170 int yi = 1;
f3d 80:ff42f77928ad 171 if (dy < 0)
f3d 80:ff42f77928ad 172 {
f3d 80:ff42f77928ad 173 yi = -1;
f3d 80:ff42f77928ad 174 dy = -dy;
f3d 80:ff42f77928ad 175 }
f3d 80:ff42f77928ad 176 int D = 2*dy - dx;
f3d 80:ff42f77928ad 177
f3d 80:ff42f77928ad 178 int y = y0;
f3d 80:ff42f77928ad 179
f3d 80:ff42f77928ad 180 for (int x=x0; x <= x1;x++)
f3d 80:ff42f77928ad 181 {
f3d 80:ff42f77928ad 182 putPixel(x,y,Colour);
f3d 80:ff42f77928ad 183 if (D > 0)
f3d 80:ff42f77928ad 184 {
f3d 80:ff42f77928ad 185 y = y + yi;
f3d 80:ff42f77928ad 186 D = D - 2*dx;
f3d 80:ff42f77928ad 187 }
f3d 80:ff42f77928ad 188 D = D + 2*dy;
f3d 80:ff42f77928ad 189
f3d 80:ff42f77928ad 190 }
f3d 80:ff42f77928ad 191 }
f3d 80:ff42f77928ad 192
f3d 80:ff42f77928ad 193 void Display::drawLineHighSlope(uint16_t x0, uint16_t y0, uint16_t x1,uint16_t y1, uint16_t Colour)
f3d 80:ff42f77928ad 194 {
f3d 80:ff42f77928ad 195 // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
f3d 80:ff42f77928ad 196
f3d 80:ff42f77928ad 197 int dx = x1 - x0;
f3d 80:ff42f77928ad 198 int dy = y1 - y0;
f3d 80:ff42f77928ad 199 int xi = 1;
f3d 80:ff42f77928ad 200 if (dx < 0)
f3d 80:ff42f77928ad 201 {
f3d 80:ff42f77928ad 202 xi = -1;
f3d 80:ff42f77928ad 203 dx = -dx;
f3d 80:ff42f77928ad 204 }
f3d 80:ff42f77928ad 205 int D = 2*dx - dy;
f3d 80:ff42f77928ad 206 int x = x0;
f3d 80:ff42f77928ad 207
f3d 80:ff42f77928ad 208 for (int y=y0; y <= y1; y++)
f3d 80:ff42f77928ad 209 {
f3d 80:ff42f77928ad 210 putPixel(x,y,Colour);
f3d 80:ff42f77928ad 211 if (D > 0)
f3d 80:ff42f77928ad 212 {
f3d 80:ff42f77928ad 213 x = x + xi;
f3d 80:ff42f77928ad 214 D = D - 2*dy;
f3d 80:ff42f77928ad 215 }
f3d 80:ff42f77928ad 216 D = D + 2*dx;
f3d 80:ff42f77928ad 217 }
f3d 80:ff42f77928ad 218 }
f3d 80:ff42f77928ad 219 void Display::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t Colour)
f3d 80:ff42f77928ad 220 {
f3d 80:ff42f77928ad 221 // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
f3d 80:ff42f77928ad 222 if ( iabs(y1 - y0) < iabs(x1 - x0) )
f3d 80:ff42f77928ad 223 {
f3d 80:ff42f77928ad 224 if (x0 > x1)
f3d 80:ff42f77928ad 225 {
f3d 80:ff42f77928ad 226 drawLineLowSlope(x1, y1, x0, y0, Colour);
f3d 80:ff42f77928ad 227 }
f3d 80:ff42f77928ad 228 else
f3d 80:ff42f77928ad 229 {
f3d 80:ff42f77928ad 230 drawLineLowSlope(x0, y0, x1, y1, Colour);
f3d 80:ff42f77928ad 231 }
f3d 80:ff42f77928ad 232 }
f3d 80:ff42f77928ad 233 else
f3d 80:ff42f77928ad 234 {
f3d 80:ff42f77928ad 235 if (y0 > y1)
f3d 80:ff42f77928ad 236 {
f3d 80:ff42f77928ad 237 drawLineHighSlope(x1, y1, x0, y0, Colour);
f3d 80:ff42f77928ad 238 }
f3d 80:ff42f77928ad 239 else
f3d 80:ff42f77928ad 240 {
f3d 80:ff42f77928ad 241 drawLineHighSlope(x0, y0, x1, y1, Colour);
f3d 80:ff42f77928ad 242 }
f3d 80:ff42f77928ad 243
f3d 80:ff42f77928ad 244 }
f3d 80:ff42f77928ad 245 }
f3d 80:ff42f77928ad 246
f3d 80:ff42f77928ad 247
f3d 80:ff42f77928ad 248 uint16_t Display::RGBToWord(uint16_t R, uint16_t G, uint16_t B)
f3d 80:ff42f77928ad 249 {
f3d 80:ff42f77928ad 250 uint16_t rvalue = 0;
f3d 80:ff42f77928ad 251 rvalue += G >> 5;
f3d 80:ff42f77928ad 252 rvalue += (G & (0b111)) << 13;
f3d 80:ff42f77928ad 253 rvalue += (B >> 3) << 8;
f3d 80:ff42f77928ad 254 rvalue += (R >> 3) << 3;
f3d 80:ff42f77928ad 255 return rvalue;
f3d 80:ff42f77928ad 256 }
f3d 80:ff42f77928ad 257 void Display::drawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t Colour)
f3d 80:ff42f77928ad 258 {
f3d 80:ff42f77928ad 259 drawLine(x,y,x+w,y,Colour);
f3d 80:ff42f77928ad 260 drawLine(x,y,x,y+h,Colour);
f3d 80:ff42f77928ad 261 drawLine(x+w,y,x+w,y+h,Colour);
f3d 80:ff42f77928ad 262 drawLine(x,y+h,x+w,y+h,Colour);
f3d 80:ff42f77928ad 263 }
f3d 80:ff42f77928ad 264
f3d 80:ff42f77928ad 265 void Display::drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour)
f3d 80:ff42f77928ad 266 {
f3d 80:ff42f77928ad 267 // Reference : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
f3d 80:ff42f77928ad 268 int x = radius-1;
f3d 80:ff42f77928ad 269 int y = 0;
f3d 80:ff42f77928ad 270 int dx = 1;
f3d 80:ff42f77928ad 271 int dy = 1;
f3d 80:ff42f77928ad 272 int err = dx - (radius << 1);
f3d 80:ff42f77928ad 273 if (radius > x0)
f3d 80:ff42f77928ad 274 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 275 if (radius > y0)
f3d 80:ff42f77928ad 276 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 277
f3d 80:ff42f77928ad 278 if ((x0+radius) > SCREEN_WIDTH)
f3d 80:ff42f77928ad 279 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 280 if ((y0+radius) > SCREEN_HEIGHT)
f3d 80:ff42f77928ad 281 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 282 while (x >= y)
f3d 80:ff42f77928ad 283 {
f3d 80:ff42f77928ad 284 putPixel(x0 + x, y0 + y, Colour);
f3d 80:ff42f77928ad 285 putPixel(x0 + y, y0 + x, Colour);
f3d 80:ff42f77928ad 286 putPixel(x0 - y, y0 + x, Colour);
f3d 80:ff42f77928ad 287 putPixel(x0 - x, y0 + y, Colour);
f3d 80:ff42f77928ad 288 putPixel(x0 - x, y0 - y, Colour);
f3d 80:ff42f77928ad 289 putPixel(x0 - y, y0 - x, Colour);
f3d 80:ff42f77928ad 290 putPixel(x0 + y, y0 - x, Colour);
f3d 80:ff42f77928ad 291 putPixel(x0 + x, y0 - y, Colour);
f3d 80:ff42f77928ad 292
f3d 80:ff42f77928ad 293 if (err <= 0)
f3d 80:ff42f77928ad 294 {
f3d 80:ff42f77928ad 295 y++;
f3d 80:ff42f77928ad 296 err += dy;
f3d 80:ff42f77928ad 297 dy += 2;
f3d 80:ff42f77928ad 298 }
f3d 80:ff42f77928ad 299
f3d 80:ff42f77928ad 300 if (err > 0)
f3d 80:ff42f77928ad 301 {
f3d 80:ff42f77928ad 302 x--;
f3d 80:ff42f77928ad 303 dx += 2;
f3d 80:ff42f77928ad 304 err += dx - (radius << 1);
f3d 80:ff42f77928ad 305 }
f3d 80:ff42f77928ad 306 }
f3d 80:ff42f77928ad 307 }
f3d 80:ff42f77928ad 308 void Display::fillCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour)
f3d 80:ff42f77928ad 309 {
f3d 80:ff42f77928ad 310 // Reference : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
f3d 80:ff42f77928ad 311 // Similar to drawCircle but fills the circle with lines instead
f3d 80:ff42f77928ad 312 int x = radius-1;
f3d 80:ff42f77928ad 313 int y = 0;
f3d 80:ff42f77928ad 314 int dx = 1;
f3d 80:ff42f77928ad 315 int dy = 1;
f3d 80:ff42f77928ad 316 int err = dx - (radius << 1);
f3d 80:ff42f77928ad 317
f3d 80:ff42f77928ad 318 if (radius > x0)
f3d 80:ff42f77928ad 319 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 320 if (radius > y0)
f3d 80:ff42f77928ad 321 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 322
f3d 80:ff42f77928ad 323 if ((x0+radius) > SCREEN_WIDTH)
f3d 80:ff42f77928ad 324 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 325 if ((y0+radius) > SCREEN_HEIGHT)
f3d 80:ff42f77928ad 326 return; // don't draw even parially off-screen circles
f3d 80:ff42f77928ad 327 while (x >= y)
f3d 80:ff42f77928ad 328 {
f3d 80:ff42f77928ad 329 drawLine(x0 - x, y0 + y,x0 + x, y0 + y, Colour);
f3d 80:ff42f77928ad 330 drawLine(x0 - y, y0 + x,x0 + y, y0 + x, Colour);
f3d 80:ff42f77928ad 331 drawLine(x0 - x, y0 - y,x0 + x, y0 - y, Colour);
f3d 80:ff42f77928ad 332 drawLine(x0 - y, y0 - x,x0 + y, y0 - x, Colour);
f3d 80:ff42f77928ad 333
f3d 80:ff42f77928ad 334 if (err <= 0)
f3d 80:ff42f77928ad 335 {
f3d 80:ff42f77928ad 336 y++;
f3d 80:ff42f77928ad 337 err += dy;
f3d 80:ff42f77928ad 338 dy += 2;
f3d 80:ff42f77928ad 339 }
f3d 80:ff42f77928ad 340
f3d 80:ff42f77928ad 341 if (err > 0)
f3d 80:ff42f77928ad 342 {
f3d 80:ff42f77928ad 343 x--;
f3d 80:ff42f77928ad 344 dx += 2;
f3d 80:ff42f77928ad 345 err += dx - (radius << 1);
f3d 80:ff42f77928ad 346 }
f3d 80:ff42f77928ad 347 }
f3d 80:ff42f77928ad 348 }