Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
diff -r ff42f77928ad -r 7087ba9d18bb display.cpp --- 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
diff -r ff42f77928ad -r 7087ba9d18bb display.h --- 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
diff -r ff42f77928ad -r 7087ba9d18bb font5x7.h --- /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 +
diff -r ff42f77928ad -r 7087ba9d18bb main.cpp --- 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); }