Basic driver working

Files at this revision

API Documentation at this revision

Comitter:
f3d
Date:
Sat Feb 20 16:34:49 2021 +0000
Parent:
80:ff42f77928ad
Commit message:
Display driver working with touch input

Changed in this revision

display.cpp Show annotated file Show diff for this revision Revisions of this file
display.h Show annotated file Show diff for this revision Revisions of this file
font5x7.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/display.cpp	Wed Feb 03 11:30:30 2021 +0000
+++ b/display.cpp	Sat Feb 20 16:34:49 2021 +0000
@@ -1,25 +1,26 @@
 #include "mbed.h"
 #include "display.h"
+#include "font5x7.h"
+extern Serial g_Serial_pc;
 //mosi,miso,clk,ss
-SPI spi(P0_25,P0_26,P0_27,P0_28);
+SPI spi(P0_25,P0_26,P0_27);
 DigitalOut Rst(P0_7);
 DigitalOut DC(P0_6);
-
+DigitalOut D_CS(P0_28);
+DigitalOut T_CS(P0_5);
+DigitalIn PenIRQ(P0_4);
 void Display::begin()
 {
-    while(0)
-    {
-        DC = 1;
-        Rst = 1;
-        wait(0.5);
-        DC = 0;
-        Rst = 0;
-        wait(0.5);
-    }
+
     spi.format(8, 0);
     spi.frequency(8000000);
+    T_CS = 1; // de-assert the touch interface for now
+    D_CS = 1;
+
     resetDisplay();
-
+    
+    LCD_Write_Data(0x21);   // Set GVDD  (varies contrast)
+    
     LCD_Write_Cmd(0xC0);    // Power control 
     LCD_Write_Data(0x21);   // Set GVDD  (varies contrast)
 
@@ -46,18 +47,17 @@
     LCD_Write_Cmd(0xB6);    // Display Function Control 
     LCD_Write_Data(0x00);   // Use default values
     LCD_Write_Data(0x82);
-    LCD_Write_Data(0x27);  
-    
+    LCD_Write_Data(0x27);      
     LCD_Write_Cmd(0x11);    //Exit Sleep 
     wait(0.120); 
-                                
+
     LCD_Write_Cmd(0x29);    //Display on 
     LCD_Write_Cmd(0x2c); 
     wait(0.005);
     
-    fillRectangle(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,RGBToWord(0,0,0));
-    
-    
+    fillRectangle(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,RGBToWord(0x00,0,0));
+    D_CS = 1;
+
 }
 
 void Display::CommandMode()
@@ -70,13 +70,19 @@
 }
 void Display::LCD_Write_Cmd(uint8_t cmd)
 {
+    
     CommandMode();
+    D_CS = 0;
     spi.write(cmd);
+    D_CS = 1;
 }
 void Display::LCD_Write_Data(uint8_t data)
 {
+    
     DataMode();
+    D_CS = 0;
     spi.write(data);
+    D_CS = 1;
 }
 void Display::resetDisplay()
 {
@@ -103,21 +109,26 @@
 void Display::putPixel(uint16_t x, uint16_t y, uint16_t Colour)
 {
     uint16_t rx;
+    
     openAperture(x,y,x+1,y+1);
     DataMode();
+    D_CS = 0;
     spi.write((const char *) &Colour,2,(char *)&rx,0);
+    D_CS = 1;
 }
-void Display::putImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *Image)
+void Display::putImage(uint16_t xofs, uint16_t yofs, uint16_t width, uint16_t height, const uint16_t *Image)
 {
     uint16_t rx;
     uint16_t Colour;
-    openAperture(x,y,width,height);
-    for (y = 0; y < height; y++)
+    
+    uint16_t x,y;
+    for (y = 0; y < height; y++) {
         for (x=0; x < width; x++)
         {
-            Colour = *(Image++);
-            spi.write((const char *) &Colour,2,(char *)&rx,0);           
-        }
+            Colour = *(Image++);            
+            putPixel(x+xofs,y+yofs,Colour);            
+        }    
+    }
 }
 void Display::fillRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t Colour)
 {
@@ -129,9 +140,10 @@
     #define BUF_SIZE 32
     uint16_t rx;
     uint16_t txBuffer[BUF_SIZE];
-    int count;
+    int count;    
     openAperture(x,y,width,height);
     DataMode();
+    D_CS = 0;
     count = (width*height)/BUF_SIZE;
     if (count)
     { // big area
@@ -160,6 +172,7 @@
         }
         
     }
+    D_CS = 1;
 }
 
 void Display::drawLineLowSlope(uint16_t x0, uint16_t y0, uint16_t x1,uint16_t y1, uint16_t Colour)
@@ -219,6 +232,7 @@
 void Display::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t Colour)
 {
     // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
+    D_CS = 0;
     if ( iabs(y1 - y0) < iabs(x1 - x0) )
     {
         if (x0 > x1)
@@ -242,6 +256,7 @@
         }
         
     }
+    D_CS = 1;
 }
 
 
@@ -345,4 +360,139 @@
             err += dx - (radius << 1);
         }
     }
+}
+void Display::print(const char *Text, uint16_t len, uint16_t x, uint16_t y, uint16_t ForeColour, uint16_t BackColour)
+{
+        // This function draws each character individually.  It uses an array called TextBox as a temporary storage
+    // location to hold the dots for the character in question.  It constructs the image of the character and then
+    // calls on putImage to place it on the screen
+    uint8_t Index = 0;
+    uint8_t Row, Col;
+    const uint8_t *CharacterCode = 0;    
+    uint16_t TextBox[FONT_WIDTH * FONT_HEIGHT];
+    for (Index = 0; Index < len; Index++)
+    {
+        CharacterCode = &Font5x7[FONT_WIDTH * (Text[Index] - 32)];
+        Col = 0;
+        while (Col < FONT_WIDTH)
+        {
+            Row = 0;
+            while (Row < FONT_HEIGHT)
+            {
+                if (CharacterCode[Col] & (1 << Row))
+                {
+                    TextBox[(Row * FONT_WIDTH) + Col] = ForeColour;
+                }
+                else
+                {
+                    TextBox[(Row * FONT_WIDTH) + Col] = BackColour;
+                }
+                Row++;
+            }
+            Col++;
+        }
+        putImage(x, y, FONT_WIDTH, FONT_HEIGHT, (const uint16_t *)TextBox);
+        x = x + FONT_WIDTH + 2;        
+    }
+}
+void Display::print(uint16_t Number, uint16_t x, uint16_t y, uint16_t ForeColour, uint16_t BackColour)
+{
+     // This function converts the supplied number into a character string and then calls on puText to
+    // write it to the display
+    char Buffer[5]; // Maximum value = 65535
+    Buffer[4] = Number % 10 + '0';
+    Number = Number / 10;
+    Buffer[3] = Number % 10 + '0';
+    Number = Number / 10;
+    Buffer[2] = Number % 10 + '0';
+    Number = Number / 10;
+    Buffer[1] = Number % 10 + '0';
+    Number = Number / 10;
+    Buffer[0] = Number % 10 + '0';
+    print(Buffer, 5, x, y, ForeColour, BackColour);
+}
+void Display::initTouch(void)
+{
+    // This display module has an XPT2046 touch screen controller connected over the SPI interface
+    // The XPT2046 
+    T_CS = 0;
+    spi.write(0b10011000); // 8 bit conversion, ratiometric measurement, read XP
+    //wait_us(100);
+    uint16_t indata,outdata;
+    outdata = 0xffff;
+    spi.write((const char *) &outdata,2,(char *)&indata,2); // write a block of colour
+    T_CS = 1;
+}
+uint16_t Display::readYTouch(void)
+{
+    // This display module has an XPT2046 touch screen controller connected over the SPI interface
+    // The XPT2046 
+    /*
+    Format of command word : 
+    b7 : must be 1
+    b6,5,4 : A2,A1,A0
+    000 : temperature
+
+    b3 : Mode
+    b2 : SER,DFR
+    b1,0 : PD1,PD0
+    */
+    uint16_t indata,outdata;    
+    spi.frequency(2000000); // Can't run the touch screen controller at high speed
+    T_CS = 0;                
+    spi.write((uint8_t)0b10011000); // 12 bit conversion, ratiometric measurement, reference off
+                                    // read XP which tells us Y (see diagram in datasheet)
+    wait_us(20);    
+    outdata = 0xffff;
+    spi.write((const char *) &outdata,2,(char *)&indata,2); 
+    T_CS = 1;        
+    spi.frequency(8000000);   
+    int calibrated_return= (indata>>12)+((indata & 0xff)<<4);
+    calibrated_return = (calibrated_return - Y_TOUCH_MIN); 
+    if (calibrated_return < 0)
+        calibrated_return = 0;
+    calibrated_return = (calibrated_return * SCREEN_HEIGHT) / (Y_TOUCH_MAX - Y_TOUCH_MIN) ;
+    return calibrated_return;
+}
+uint16_t Display::readXTouch(void)
+{
+    // This display module has an XPT2046 touch screen controller connected over the SPI interface
+    // The XPT2046 
+    /*
+    Format of command word : 
+    b7 : must be 1
+    b6,5,4 : A2,A1,A0
+    000 : temperature
+
+    b3 : Mode
+    b2 : SER,DFR
+    b1,0 : PD1,PD0
+    */
+    uint16_t indata,outdata;     
+    spi.frequency(2000000);// Can't run the touch screen controller at high speed
+    T_CS = 0;                
+    spi.write((uint8_t)0b11011000); // 12 bit conversion, ratiometric measurement, reference off
+                                    // read YP which tells us X (see diagram in datasheet)
+    wait_us(20);    
+    outdata = 0xffff;
+    spi.write((const char *) &outdata,2,(char *)&indata,2); 
+    T_CS = 1;        
+    spi.frequency(8000000);    
+    int calibrated_return= (indata>>12)+((indata & 0xff)<<4);    
+    calibrated_return = (calibrated_return - X_TOUCH_MIN);
+    if (calibrated_return < 0)
+        calibrated_return = 0;
+    calibrated_return = (calibrated_return * SCREEN_WIDTH) / (X_TOUCH_MAX - X_TOUCH_MIN);
+    // The X reading is backwards so need to subtract it from the screen width
+    calibrated_return = SCREEN_WIDTH - calibrated_return;
+    if (calibrated_return < 0)
+        calibrated_return = 0;
+    return calibrated_return;
+}
+int Display::penDown(void)
+{           
+    if (PenIRQ.read()==0)
+        return 1;
+    else
+        return 0;
 }
\ No newline at end of file
--- a/display.h	Wed Feb 03 11:30:30 2021 +0000
+++ b/display.h	Sat Feb 20 16:34:49 2021 +0000
@@ -4,6 +4,10 @@
 
 #define SCREEN_WIDTH 240
 #define SCREEN_HEIGHT 320
+#define Y_TOUCH_MAX 1952
+#define Y_TOUCH_MIN 88
+#define X_TOUCH_MAX 1920
+#define X_TOUCH_MIN 112
 class Display {
 public:        
     Display() {};
@@ -16,6 +20,12 @@
     void drawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t Colour);
     void drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour);
     void fillCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour);
+    // Graphics text functions
+    void print(const char *Text, uint16_t len, uint16_t x, uint16_t y, uint16_t ForeColour, uint16_t BackColour);
+    void print(uint16_t Number, uint16_t x, uint16_t y, uint16_t ForeColour, uint16_t BackColour); 
+    int penDown(void);
+    uint16_t readYTouch(void);
+    uint16_t readXTouch(void);
 private:
 
     void CommandMode();
@@ -33,5 +43,7 @@
         else
             return x;
     }
+    void initTouch(void);
     
+
 };
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/font5x7.h	Sat Feb 20 16:34:49 2021 +0000
@@ -0,0 +1,123 @@
+/*! \file font5x7.h \brief Graphic LCD Font (Ascii Characters). */
+//*****************************************************************************
+//
+// File Name    : 'font5x7.h'
+// Title        : Graphic LCD Font (Ascii Charaters)
+// Author       : Pascal Stang
+// Date         : 10/19/2001
+// Revised      : 10/19/2001
+// Version      : 0.1
+// Target MCU   : Atmel AVR
+// Editor Tabs  : 4
+//
+//*****************************************************************************
+
+#ifndef FONT5X7_H
+#define FONT5X7_H
+#define FONT_WIDTH 5
+#define FONT_HEIGHT 7
+#include <stdint.h>
+// standard ascii 5x7 font
+// defines ascii characters 0x20-0x7F (32-127)
+#pragma pack(1)
+const uint8_t  Font5x7[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00,// (space)
+    0x00, 0x00, 0x5F, 0x00, 0x00,// !
+    0x00, 0x07, 0x00, 0x07, 0x00,// "
+    0x14, 0x7F, 0x14, 0x7F, 0x14,// #
+    0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
+    0x23, 0x13, 0x08, 0x64, 0x62,// %
+    0x36, 0x49, 0x55, 0x22, 0x50,// &
+    0x00, 0x05, 0x03, 0x00, 0x00,// '
+    0x00, 0x1C, 0x22, 0x41, 0x00,// (
+    0x00, 0x41, 0x22, 0x1C, 0x00,// )
+    0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
+    0x08, 0x08, 0x3E, 0x08, 0x08,// +
+    0x00, 0x50, 0x30, 0x00, 0x00,// ,
+    0x08, 0x08, 0x08, 0x08, 0x08,// -
+    0x00, 0x60, 0x60, 0x00, 0x00,// .
+    0x20, 0x10, 0x08, 0x04, 0x02,// /
+    0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
+    0x00, 0x42, 0x7F, 0x40, 0x00,// 1
+    0x42, 0x61, 0x51, 0x49, 0x46,// 2
+    0x21, 0x41, 0x45, 0x4B, 0x31,// 3
+    0x18, 0x14, 0x12, 0x7F, 0x10,// 4
+    0x27, 0x45, 0x45, 0x45, 0x39,// 5
+    0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
+    0x01, 0x71, 0x09, 0x05, 0x03,// 7
+    0x36, 0x49, 0x49, 0x49, 0x36,// 8
+    0x06, 0x49, 0x49, 0x29, 0x1E,// 9
+    0x00, 0x36, 0x36, 0x00, 0x00,// :
+    0x00, 0x56, 0x36, 0x00, 0x00,// ;
+    0x00, 0x08, 0x14, 0x22, 0x41,// <
+    0x14, 0x14, 0x14, 0x14, 0x14,// =
+    0x41, 0x22, 0x14, 0x08, 0x00,// >
+    0x02, 0x01, 0x51, 0x09, 0x06,// ?
+    0x32, 0x49, 0x79, 0x41, 0x3E,// @
+    0x7E, 0x11, 0x11, 0x11, 0x7E,// A
+    0x7F, 0x49, 0x49, 0x49, 0x36,// B
+    0x3E, 0x41, 0x41, 0x41, 0x22,// C
+    0x7F, 0x41, 0x41, 0x22, 0x1C,// D
+    0x7F, 0x49, 0x49, 0x49, 0x41,// E
+    0x7F, 0x09, 0x09, 0x01, 0x01,// F
+    0x3E, 0x41, 0x41, 0x51, 0x32,// G
+    0x7F, 0x08, 0x08, 0x08, 0x7F,// H
+    0x00, 0x41, 0x7F, 0x41, 0x00,// I
+    0x20, 0x40, 0x41, 0x3F, 0x01,// J
+    0x7F, 0x08, 0x14, 0x22, 0x41,// K
+    0x7F, 0x40, 0x40, 0x40, 0x40,// L
+    0x7F, 0x02, 0x04, 0x02, 0x7F,// M
+    0x7F, 0x04, 0x08, 0x10, 0x7F,// N
+    0x3E, 0x41, 0x41, 0x41, 0x3E,// O
+    0x7F, 0x09, 0x09, 0x09, 0x06,// P
+    0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
+    0x7F, 0x09, 0x19, 0x29, 0x46,// R
+    0x46, 0x49, 0x49, 0x49, 0x31,// S
+    0x01, 0x01, 0x7F, 0x01, 0x01,// T
+    0x3F, 0x40, 0x40, 0x40, 0x3F,// U
+    0x1F, 0x20, 0x40, 0x20, 0x1F,// V
+    0x7F, 0x20, 0x18, 0x20, 0x7F,// W
+    0x63, 0x14, 0x08, 0x14, 0x63,// X
+    0x03, 0x04, 0x78, 0x04, 0x03,// Y
+    0x61, 0x51, 0x49, 0x45, 0x43,// Z
+    0x00, 0x00, 0x7F, 0x41, 0x41,// [
+    0x02, 0x04, 0x08, 0x10, 0x20,// "\"
+    0x41, 0x41, 0x7F, 0x00, 0x00,// ]
+    0x04, 0x02, 0x01, 0x02, 0x04,// ^
+    0x40, 0x40, 0x40, 0x40, 0x40,// _
+    0x00, 0x01, 0x02, 0x04, 0x00,// `
+    0x20, 0x54, 0x54, 0x54, 0x78,// a
+    0x7F, 0x48, 0x44, 0x44, 0x38,// b
+    0x38, 0x44, 0x44, 0x44, 0x20,// c
+    0x38, 0x44, 0x44, 0x48, 0x7F,// d
+    0x38, 0x54, 0x54, 0x54, 0x18,// e
+    0x08, 0x7E, 0x09, 0x01, 0x02,// f
+    0x08, 0x14, 0x54, 0x54, 0x3C,// g
+    0x7F, 0x08, 0x04, 0x04, 0x78,// h
+    0x00, 0x44, 0x7D, 0x40, 0x00,// i
+    0x20, 0x40, 0x44, 0x3D, 0x00,// j
+    0x00, 0x7F, 0x10, 0x28, 0x44,// k
+    0x00, 0x41, 0x7F, 0x40, 0x00,// l
+    0x7C, 0x04, 0x18, 0x04, 0x78,// m
+    0x7C, 0x08, 0x04, 0x04, 0x78,// n
+    0x38, 0x44, 0x44, 0x44, 0x38,// o
+    0x7C, 0x14, 0x14, 0x14, 0x08,// p
+    0x08, 0x14, 0x14, 0x18, 0x7C,// q
+    0x7C, 0x08, 0x04, 0x04, 0x08,// r
+    0x48, 0x54, 0x54, 0x54, 0x20,// s
+    0x04, 0x3F, 0x44, 0x40, 0x20,// t
+    0x3C, 0x40, 0x40, 0x20, 0x7C,// u
+    0x1C, 0x20, 0x40, 0x20, 0x1C,// v
+    0x3C, 0x40, 0x30, 0x40, 0x3C,// w
+    0x44, 0x28, 0x10, 0x28, 0x44,// x
+    0x0C, 0x50, 0x50, 0x50, 0x3C,// y
+    0x44, 0x64, 0x54, 0x4C, 0x44,// z
+    0x00, 0x08, 0x36, 0x41, 0x00,// {
+    0x00, 0x00, 0x7F, 0x00, 0x00,// |
+    0x00, 0x41, 0x36, 0x08, 0x00,// }
+    0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
+    0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
+};
+
+#endif
+
--- a/main.cpp	Wed Feb 03 11:30:30 2021 +0000
+++ b/main.cpp	Sat Feb 20 16:34:49 2021 +0000
@@ -11,7 +11,8 @@
 #define LED_ON      0
 #define LED_OFF     1
 
-DigitalOut g_DO_LedBlue(A5, LED_OFF);
+DigitalOut DataLED(A5, LED_OFF);
+
 Display display;
 
 uint32_t prbs()
@@ -39,37 +40,28 @@
 }
 int main(void) {
   
-    int Count;
+    int count;
+
+   
     display.begin();
-    
-    while(true) {
-        g_Serial_pc.printf("LED Toggle\r\n");     
-        g_DO_LedBlue = !g_DO_LedBlue;
-        
-        for (Count = 0; Count < 200; Count++)
-        {
-            display.drawRectangle(random(0,240),random(0,320),random(0,240),random(0,320),random(0,0xffff));
-        }
-        display.fillRectangle(0,0,240,320,0);
-        for (Count = 0; Count < 200; Count++)
+    while(1)    
+    {
+        DataLED = !DataLED;
+        if (display.penDown()) 
         {
-           
-           display.fillRectangle(random(0,240),random(0,320),random(0,240),random(0,320),random(0,0xffff));           
-
-        }
-        display.fillRectangle(0,0,240,320,0);
-        for (Count = 0; Count < 200; Count++)
+            display.print(display.readXTouch(),10,10,display.RGBToWord(0xff,0xff,0),display.RGBToWord(0,0,0));
+            display.print(display.readYTouch(),80,10,display.RGBToWord(0xff,0xff,0),display.RGBToWord(0,0,0));
+        }        
+        display.drawRectangle(random(0,240),random(0,320),random(0,240),random(0,320),random(0,0xffff));                                
+        //display.fillRectangle(random(0,240),random(0,320),random(0,240),random(0,320),random(0,0xffff));                   
+        display.drawCircle(random(0,240),random(0,240),random(0,320),random(0,0xffff));
+        //display.fillCircle(random(0,240),random(0,320),random(0,120),random(0,0xffff));
+        count++;
+        if (count >= 10) 
         {
-            display.drawCircle(random(0,240),random(0,240),random(0,320),random(0,0xffff));
-
+            display.fillRectangle(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,0);
+            count = 0;
         }
-        display.fillRectangle(0,0,240,320,0);
-        for (Count = 0; Count < 50; Count++)
-        {
-            display.fillCircle(random(0,240),random(0,320),random(0,120),random(0,0xffff));
-
-        }
-        display.fillRectangle(0,0,240,320,0);
         
     }