Basic driver working
Revision 81:7087ba9d18bb, committed 2021-02-20
- 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
--- 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);
}