Basic driver working

Revision:
80:ff42f77928ad
Child:
81:7087ba9d18bb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/display.cpp	Wed Feb 03 11:30:30 2021 +0000
@@ -0,0 +1,348 @@
+#include "mbed.h"
+#include "display.h"
+//mosi,miso,clk,ss
+SPI spi(P0_25,P0_26,P0_27,P0_28);
+DigitalOut Rst(P0_7);
+DigitalOut DC(P0_6);
+
+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);
+    resetDisplay();
+
+    LCD_Write_Cmd(0xC0);    // Power control 
+    LCD_Write_Data(0x21);   // Set GVDD  (varies contrast)
+
+    LCD_Write_Cmd(0xC1);    // Power control 
+    LCD_Write_Data(0x10);   // default value
+
+    LCD_Write_Cmd(0xC5);    //VCM control 
+    LCD_Write_Data(0x31);   // default values
+    LCD_Write_Data(0x3c);   // 
+
+    LCD_Write_Cmd(0xC7);    //VCM control2 
+    LCD_Write_Data(0xc0);   // default value
+
+    LCD_Write_Cmd(0x36);    // Memory Access Control 
+    LCD_Write_Data(0x48);   // Set display orientation and RGB colour order
+
+    LCD_Write_Cmd(0x3A);    // Set Pixel format
+    LCD_Write_Data(0x55);   // To 16 bits per pixel
+
+    LCD_Write_Cmd(0xB1);    // Frame rate control
+    LCD_Write_Data(0x00);   // Use Fosc without divisor
+    LCD_Write_Data(0x1B);   // set 70Hz refresh rate
+
+    LCD_Write_Cmd(0xB6);    // Display Function Control 
+    LCD_Write_Data(0x00);   // Use default values
+    LCD_Write_Data(0x82);
+    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));
+    
+    
+}
+
+void Display::CommandMode()
+{
+    DC = 0;
+}
+void Display::DataMode()
+{
+    DC = 1;
+}
+void Display::LCD_Write_Cmd(uint8_t cmd)
+{
+    CommandMode();
+    spi.write(cmd);
+}
+void Display::LCD_Write_Data(uint8_t data)
+{
+    DataMode();
+    spi.write(data);
+}
+void Display::resetDisplay()
+{
+    Rst = 0;
+    wait(0.01);
+    Rst = 1;
+    wait(0.12);
+}
+void Display::openAperture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
+{   
+    LCD_Write_Cmd(0x2a); 
+    LCD_Write_Data(x1>>8);
+    LCD_Write_Data(x1);
+    LCD_Write_Data(x2>>8);
+    LCD_Write_Data(x2);
+    LCD_Write_Cmd(0x2b); 
+    LCD_Write_Data(y1>>8);
+    LCD_Write_Data(y1);
+    LCD_Write_Data(y2>>8);
+    LCD_Write_Data(y2);
+    LCD_Write_Cmd(0x2c); 
+}
+// Simple Pixel drawing routines
+void Display::putPixel(uint16_t x, uint16_t y, uint16_t Colour)
+{
+    uint16_t rx;
+    openAperture(x,y,x+1,y+1);
+    DataMode();
+    spi.write((const char *) &Colour,2,(char *)&rx,0);
+}
+void Display::putImage(uint16_t x, uint16_t y, 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++)
+        for (x=0; x < width; x++)
+        {
+            Colour = *(Image++);
+            spi.write((const char *) &Colour,2,(char *)&rx,0);           
+        }
+}
+void Display::fillRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t Colour)
+{
+    /* in an effort to reduce overhead here a large word buffer is created.  If the number of words to 
+    to write is greater than or equal to the size of this buffer then it is filled with the relevant colour
+    and used as the source of data in the spi.write function.  This greatly speeds up the writing of 
+    large arease of the screen.  The choice of buffer size is interesting.
+    */ 
+    #define BUF_SIZE 32
+    uint16_t rx;
+    uint16_t txBuffer[BUF_SIZE];
+    int count;
+    openAperture(x,y,width,height);
+    DataMode();
+    count = (width*height)/BUF_SIZE;
+    if (count)
+    { // big area
+        for (int i=0;i<BUF_SIZE;i++)
+        {
+            txBuffer[i]=Colour;
+        }
+        while(count--)
+        {
+            spi.write((const char *)txBuffer,2*BUF_SIZE,(char *)&rx,0);
+        }
+        count = (width*height)%BUF_SIZE; // write remainder of block
+        while (count--)
+        {
+            spi.write((const char *) &Colour,2,(char *)&rx,0); // write a block of colour
+        }   
+        
+    }        
+    else
+    {
+        // small area so write 1 word at a time.
+        count = (width*height);
+        while(count--)
+        {
+            spi.write((const char *) &Colour,2,(char *)&rx,0);
+        }
+        
+    }
+}
+
+void Display::drawLineLowSlope(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    
+  int dx = x1 - x0;
+  int dy = y1 - y0;
+  int yi = 1;
+  if (dy < 0)
+  {
+    yi = -1;
+    dy = -dy;
+  }
+  int D = 2*dy - dx;
+  
+  int y = y0;
+
+  for (int x=x0; x <= x1;x++)
+  {
+    putPixel(x,y,Colour);    
+    if (D > 0)
+    {
+       y = y + yi;
+       D = D - 2*dx;
+    }
+    D = D + 2*dy;
+    
+  }
+}
+
+void Display::drawLineHighSlope(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
+
+  int dx = x1 - x0;
+  int dy = y1 - y0;
+  int xi = 1;
+  if (dx < 0)
+  {
+    xi = -1;
+    dx = -dx;
+  }  
+  int D = 2*dx - dy;
+  int x = x0;
+
+  for (int y=y0; y <= y1; y++)
+  {
+    putPixel(x,y,Colour);
+    if (D > 0)
+    {
+       x = x + xi;
+       D = D - 2*dy;
+    }
+    D = D + 2*dx;
+  }
+}
+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
+    if ( iabs(y1 - y0) < iabs(x1 - x0) )
+    {
+        if (x0 > x1)
+        {
+            drawLineLowSlope(x1, y1, x0, y0, Colour);
+        }
+        else
+        {
+            drawLineLowSlope(x0, y0, x1, y1, Colour);
+        }
+    }
+    else
+    {
+        if (y0 > y1) 
+        {
+            drawLineHighSlope(x1, y1, x0, y0, Colour);
+        }
+        else
+        {
+            drawLineHighSlope(x0, y0, x1, y1, Colour);
+        }
+        
+    }
+}
+
+
+uint16_t Display::RGBToWord(uint16_t R, uint16_t G, uint16_t B)
+{
+    uint16_t rvalue = 0;
+    rvalue += G >> 5;
+    rvalue += (G & (0b111)) << 13;
+    rvalue += (B >> 3) << 8;
+    rvalue += (R >> 3) << 3;
+    return rvalue;
+}
+void Display::drawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t Colour)
+{
+    drawLine(x,y,x+w,y,Colour);
+    drawLine(x,y,x,y+h,Colour);
+    drawLine(x+w,y,x+w,y+h,Colour);
+    drawLine(x,y+h,x+w,y+h,Colour);
+}
+
+void Display::drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour)
+{
+// Reference : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
+    int x = radius-1;
+    int y = 0;
+    int dx = 1;
+    int dy = 1;
+    int err = dx - (radius << 1);
+    if (radius > x0)
+        return; // don't draw even parially off-screen circles
+    if (radius > y0)
+        return; // don't draw even parially off-screen circles
+        
+    if ((x0+radius) > SCREEN_WIDTH)
+        return; // don't draw even parially off-screen circles
+    if ((y0+radius) > SCREEN_HEIGHT)
+        return; // don't draw even parially off-screen circles    
+    while (x >= y)
+    {
+        putPixel(x0 + x, y0 + y, Colour);
+        putPixel(x0 + y, y0 + x, Colour);
+        putPixel(x0 - y, y0 + x, Colour);
+        putPixel(x0 - x, y0 + y, Colour);
+        putPixel(x0 - x, y0 - y, Colour);
+        putPixel(x0 - y, y0 - x, Colour);
+        putPixel(x0 + y, y0 - x, Colour);
+        putPixel(x0 + x, y0 - y, Colour);
+
+        if (err <= 0)
+        {
+            y++;
+            err += dy;
+            dy += 2;
+        }
+        
+        if (err > 0)
+        {
+            x--;
+            dx += 2;
+            err += dx - (radius << 1);
+        }
+    }
+}
+void Display::fillCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour)
+{
+// Reference : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
+// Similar to drawCircle but fills the circle with lines instead
+    int x = radius-1;
+    int y = 0;
+    int dx = 1;
+    int dy = 1;
+    int err = dx - (radius << 1);
+
+    if (radius > x0)
+        return; // don't draw even parially off-screen circles
+    if (radius > y0)
+        return; // don't draw even parially off-screen circles
+        
+    if ((x0+radius) > SCREEN_WIDTH)
+        return; // don't draw even parially off-screen circles
+    if ((y0+radius) > SCREEN_HEIGHT)
+        return; // don't draw even parially off-screen circles        
+    while (x >= y)
+    {
+        drawLine(x0 - x, y0 + y,x0 + x, y0 + y, Colour);        
+        drawLine(x0 - y, y0 + x,x0 + y, y0 + x, Colour);        
+        drawLine(x0 - x, y0 - y,x0 + x, y0 - y, Colour);        
+        drawLine(x0 - y, y0 - x,x0 + y, y0 - x, Colour);        
+
+        if (err <= 0)
+        {
+            y++;
+            err += dy;
+            dy += 2;
+        }
+        
+        if (err > 0)
+        {
+            x--;
+            dx += 2;
+            err += dx - (radius << 1);
+        }
+    }
+}
\ No newline at end of file