V1.1 of the ILI9340 driver for SPI with integrated graphics functions.

Dependents:   ILI9340_Driver SDCard_Aitendo_2p2TFT TFT22ok_test_ILI9340_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 !

Files at this revision

API Documentation at this revision

Comitter:
dextorslabs
Date:
Sun Jun 01 16:52:16 2014 +0000
Parent:
0:ea46340642a9
Commit message:
Added more graphics functions to give rectangles with rounded corners and filled circles.

Changed in this revision

ILI9340_Driver.cpp Show annotated file Show diff for this revision Revisions of this file
ILI9340_Driver.h Show annotated file Show diff for this revision Revisions of this file
--- a/ILI9340_Driver.cpp	Tue May 27 19:40:20 2014 +0000
+++ b/ILI9340_Driver.cpp	Sun Jun 01 16:52:16 2014 +0000
@@ -1,10 +1,10 @@
 /***************************************************************
-    ILI9340_Driver  v1.0    26.05.14    Ian Weston
+    ILI9340_Driver  v1.1    01.06.14    Ian Weston
     
 Driver and integrated graphics library for displays that use the 
-ILI9340 controller in SPI mode.
+ILI9340 controller in SPI mode. Such as the Adafruit 2.2" display.
 
-The code was prted from several sources, the driver section
+This code has been ported from several sources. The driver section
 was completely ported from the Adafruits Arduino source code, and
 the graphics functions were ported from the Adafruits GFX library
 and some elements were ported from code by Elmicros seeduio port.
@@ -19,7 +19,10 @@
 #include "SimpleFont.cpp"
 
 
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Constructor, assigns the pins to the SPI object, set orientation, and sets screen dims.
+////////////////////////////////////////////////////////////////////////////////////////////////
 ILI9340_Display::ILI9340_Display(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dc)
     : spi(mosi, miso, sclk), cs(cs), rst(rst), dc(dc) {
     _height = _TFTHEIGHT;
@@ -28,7 +31,10 @@
     }
 
 
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Command writing code
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::WriteCommand(uint8_t command) {
     dc = 0;
     cs = 0;
@@ -36,8 +42,11 @@
     cs = 1;
     }
   
-    
+  
+  
+////////////////////////////////////////////////////////////////////////////////////////////////  
 // Data writing code
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::WriteData(uint8_t data) {
     cs = 0;
     dc = 1;
@@ -46,7 +55,10 @@
     }
     
     
+    
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Initilise the display
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DispInit(void) {
     //CtrlOutput();
     
@@ -175,7 +187,10 @@
     }
     
 
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Sets the rotation of the display
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::SetRotation(uint8_t m) {
 
   WriteCommand(ILI9340_MADCTL);
@@ -206,14 +221,21 @@
 }
 
 
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Invert the colours of the display in hardware
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::InvertDisplay(bool i) {
   WriteCommand(i ? ILI9340_INVON : ILI9340_INVOFF);
 }
 
 
-    
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////    
 // Set address window for writing data to.
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
 
   WriteCommand(ILI9340_CASET); // Column addr set
@@ -233,7 +255,10 @@
 
 
 
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // To draw the humble pixel
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DrawPixel(uint16_t x, uint16_t y, uint16_t colour) {
     if((x < 1) ||(x >= _width) || (y < 1) || (y >= _height)) return;
    
@@ -249,7 +274,10 @@
     }
     
 
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Fill the screen with a colour
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::FillScreen(uint16_t colour) {
     SetAddrWindow(0,0,_width,_height);
     
@@ -268,7 +296,10 @@
     }
     
 
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Draws a vertical line fast
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DrawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t colour) {
 
   // Rudimentary clipping
@@ -292,7 +323,10 @@
 }
 
 
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Draws a horizontal line fast
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DrawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t colour) {
 
   // Rudimentary clipping
@@ -311,7 +345,11 @@
 }
 
 
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Draws a filled rectangle 
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::FillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colour) {
 
   // rudimentary clipping (drawChar w/big text requires this)
@@ -337,7 +375,10 @@
 
 
 
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Draw an unfilled rectangle
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DrawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){
     DrawFastHLine(x, y, w, color);
     DrawFastHLine(x, y+h-1, w, color);
@@ -346,7 +387,12 @@
 }
 
 
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // draw an unfilled circle
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DrawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t colour){
     int16_t f = 1 - r;
     int16_t ddF_x = 1;
@@ -381,13 +427,147 @@
 }
 
 
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Draw a filled circle
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::FillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t colour) {
+  DrawFastVLine(x0, y0-r, 2*r+1, colour);
+  FillCircleHelper(x0, y0, r, 3, 0, colour);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// used to draw circles and roundrects!
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::FillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t colour) {
+ 
+  int16_t f     = 1 - r;
+  int16_t ddF_x = 1;
+  int16_t ddF_y = -2 * r;
+  int16_t x     = 0;
+  int16_t y     = r;
+ 
+  while (x<y) {
+    if (f >= 0) {
+      y--;
+      ddF_y += 2;
+      f     += ddF_y;
+    }
+    x++;
+    ddF_x += 2;
+    f     += ddF_x;
+ 
+    if (cornername & 0x1) {
+      DrawFastVLine(x0+x, y0-y, 2*y+1+delta, colour);
+      DrawFastVLine(x0+y, y0-x, 2*x+1+delta, colour);
+    }
+    if (cornername & 0x2) {
+      DrawFastVLine(x0-x, y0-y, 2*y+1+delta, colour);
+      DrawFastVLine(x0-y, y0-x, 2*x+1+delta, colour);
+    }
+  }
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// used for drawing rounded corner radii
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t colour) {
+  int16_t f     = 1 - r;
+  int16_t ddF_x = 1;
+  int16_t ddF_y = -2 * r;
+  int16_t x     = 0;
+  int16_t y     = r;
+ 
+  while (x<y) {
+    if (f >= 0) {
+      y--;
+      ddF_y += 2;
+      f     += ddF_y;
+    }
+    x++;
+    ddF_x += 2;
+    f     += ddF_x;
+    if (cornername & 0x4) {
+      DrawPixel(x0 + x, y0 + y, colour);
+      DrawPixel(x0 + y, y0 + x, colour);
+    } 
+    if (cornername & 0x2) {
+      DrawPixel(x0 + x, y0 - y, colour);
+      DrawPixel(x0 + y, y0 - x, colour);
+    }
+    if (cornername & 0x8) {
+      DrawPixel(x0 - y, y0 + x, colour);
+      DrawPixel(x0 - x, y0 + y, colour);
+    }
+    if (cornername & 0x1) {
+      DrawPixel(x0 - y, y0 - x, colour);
+      DrawPixel(x0 - x, y0 - y, colour);
+    }
+  }
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// draw a rounded rectangle!
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t colour) {
+  // smarter version
+  DrawFastHLine(x+r  , y    , w-2*r, colour); // Top
+  DrawFastHLine(x+r  , y+h-1, w-2*r, colour); // Bottom
+  DrawFastVLine(  x    , y+r  , h-2*r, colour); // Left
+  DrawFastVLine(  x+w-1, y+r  , h-2*r, colour); // Right
+  // draw four corners
+  DrawCircleHelper(x+r    , y+r    , r, 1, colour);
+  DrawCircleHelper(x+w-r-1, y+r    , r, 2, colour);
+  DrawCircleHelper(x+w-r-1, y+h-r-1, r, 4, colour);
+  DrawCircleHelper(x+r    , y+h-r-1, r, 8, colour);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// fill a rounded rectangle!
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::FillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t colour) {
+  // smarter version
+  FillRect(x+r, y, w-2*r, h, colour);
+ 
+  // draw four corners
+  FillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, colour);
+  FillCircleHelper(x+r    , y+r, r, 2, h-2*r-1, colour);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Pass 8-bit (each) R,G,B, get back 16-bit packed color
+////////////////////////////////////////////////////////////////////////////////////////////////
 uint16_t ILI9340_Display::Colour565(uint8_t r, uint8_t g, uint8_t b) {
   return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
 }
 
 
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Writes an ascii character to the display
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DrawAscii(unsigned char ascii, uint16_t x, uint16_t y, uint16_t size, uint16_t colour) {
     SetAddrWindow(x, y, x+size, y+size);
     
@@ -423,7 +603,12 @@
 }
 
 
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Writes a character array to the display
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DrawString(char *string, uint16_t x, uint16_t y, uint8_t size, uint16_t colour)
 {
     while(*string)
@@ -448,7 +633,13 @@
     }
 }
 
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Converts integers into a character array
+////////////////////////////////////////////////////////////////////////////////////////////////
 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) {
     int workvalue = value;
     int i;
@@ -489,7 +680,11 @@
 
 
 
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Functional code to swap data contents of 16bit registers
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::Swap(int16_t *a, int16_t *b) {
     
     int16_t x = *a;
@@ -498,7 +693,11 @@
     }
 
 
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
 // Draws a line with any length and orientation
+////////////////////////////////////////////////////////////////////////////////////////////////
 void ILI9340_Display::DrawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour){
     int16_t steep = abs(y1 - y0) > abs(x1 - x0);
     if (steep) {
--- a/ILI9340_Driver.h	Tue May 27 19:40:20 2014 +0000
+++ b/ILI9340_Driver.h	Sun Jun 01 16:52:16 2014 +0000
@@ -1,10 +1,10 @@
 /***************************************************************
-    ILI9340_Driver  v1.0    26.05.14    Ian Weston
+    ILI9340_Driver  v1.1    01.06.14    Ian Weston
     
 Driver and integrated graphics library for displays that use the 
-ILI9340 controller in SPI mode.
+ILI9340 controller in SPI mode. Such as the Adafruit 2.2" display.
 
-The code was prted from several sources, the driver section
+This code has been ported from several sources. The driver section
 was completely ported from the Adafruits Arduino source code, and
 the graphics functions were ported from the Adafruits GFX library
 and some elements were ported from code by Elmicros seeduio port.
@@ -126,6 +126,11 @@
     void FillRect(int16_t, int16_t, int16_t, int16_t, uint16_t);
     void DrawRect(int16_t, int16_t, int16_t, int16_t, uint16_t);
     void DrawCircle(int16_t, int16_t, int16_t, uint16_t);
+    void FillCircle(int16_t, int16_t, int16_t, uint16_t);
+    void FillCircleHelper(int16_t, int16_t, int16_t, uint8_t, int16_t, uint16_t);
+    void DrawCircleHelper( int16_t, int16_t, int16_t, uint8_t, uint16_t);
+    void DrawRoundRect(int16_t, int16_t, int16_t, int16_t, int16_t, uint16_t);
+    void FillRoundRect(int16_t, int16_t, int16_t, int16_t, int16_t, uint16_t);
     uint16_t Colour565(uint8_t, uint8_t, uint8_t);
     
     void DrawAscii(unsigned char, uint16_t, uint16_t, uint16_t, uint16_t);