Basic driver working

Revision:
81:7087ba9d18bb
Parent:
80:ff42f77928ad
--- 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