UniGraphic-Fork for ST7920-LCD-controller and SH1106. Tested with 128x64 LCD with SPI and 128x64-OLED with IIC
Dependents: UniGraphic-St7920-Test AfficheurUTILECO
Fork of UniGraphic by
Fork of the UniGraphic-Library for monochrome LCDs with ST7920 controller and 128x64-IIC-OLED-Display with SH1106-Controller
Had to adapt LCD for following reasons:
- Give access to screenbuffer buffer[] to parent class
- pixel() and pixel_read() as they are hardware-dependent
- added reset-pin to IIC-Interface
GraphicDisplay:: sends buffer to LCD when auto_update is set to true.
Testprogram for ST7920 can be found here:
https://developer.mbed.org/users/charly/code/UniGraphic-St7920-Test/
Revision 21:ae0a4eedfc90, committed 2015-03-31
- Comitter:
- Geremia
- Date:
- Tue Mar 31 21:14:48 2015 +0000
- Parent:
- 20:14daa48ffd4c
- Child:
- 22:f9a37f22b9cb
- Commit message:
- Add BUS_8 and BUS_16 (slow as expected)
Changed in this revision
--- a/Display/LCD.cpp Mon Mar 23 14:08:04 2015 +0000 +++ b/Display/LCD.cpp Tue Mar 31 21:14:48 2015 +0000 @@ -41,6 +41,28 @@ // cls(); // locate(0,0); } +LCD::LCD(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name) + : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y), _LCDPAGES(lcdsize_y>>3), _IC_X_SEGS(ic_x_segs), _IC_Y_COMS(ic_y_coms), _IC_PAGES(ic_y_coms>>3) +{ + if(displayproto==BUS_8) + { + PinName pins[16]; + for(int i=0; i<16; i++) pins[i]=NC; + for(int i=0; i<8; i++) pins[i]=buspins[i]; + proto = new BUS8(pins, CS, reset, DC, WR, RD); + } + useNOP=false; + buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); + buffer16 = (unsigned short*)buffer; + draw_mode = NORMAL; + set_orientation(1); + foreground(White); + background(Black); + set_auto_up(true); + tftID=0; + // cls(); + // locate(0,0); +} LCD::LCD(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name) : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y), _LCDPAGES(lcdsize_y>>3), _IC_X_SEGS(ic_x_segs), _IC_Y_COMS(ic_y_coms), _IC_PAGES(ic_y_coms>>3) {
--- a/Display/LCD.h Mon Mar 23 14:08:04 2015 +0000 +++ b/Display/LCD.h Tue Mar 31 21:14:48 2015 +0000 @@ -4,6 +4,7 @@ #include "GraphicsDisplay.h" #include "PAR8.h" +#include "BUS8.h" #include "SPI8.h" #include "SPI16.h" #include "Protocols.h" @@ -30,11 +31,16 @@ public: - /** Create a monochrome LCD Parallel interface + /** Create a monochrome LCD Parallel Port interface * @param name The name used by the parent class to access the interface */ LCD(proto_t displayproto,PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char* name); + /** Create a monochrome LCD Parallel Bus interface + * @param name The name used by the parent class to access the interface + */ + LCD(proto_t displayproto,PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char* name); + /** Create a monochrome LCD SPI interface * @param name The name used by the parent class to access the interface */
--- a/Display/TFT.cpp Mon Mar 23 14:08:04 2015 +0000 +++ b/Display/TFT.cpp Tue Mar 31 21:14:48 2015 +0000 @@ -43,6 +43,36 @@ // cls(); // locate(0,0); } +TFT::TFT(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char *name) + : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) +{ + if(displayproto==BUS_8) + { + PinName pins[16]; + for(int i=0; i<16; i++) pins[i]=NC; + for(int i=0; i<8; i++) pins[i]=buspins[i]; + proto = new BUS8(pins, CS, reset, DC, WR, RD); + } + else if(displayproto==BUS_16) + { + proto = new BUS16(buspins, CS, reset, DC, WR, RD); + } + useNOP=false; + scrollbugfix=0; + mipistd=false; + set_orientation(0); + foreground(White); + background(Black); + set_auto_up(false); //we don't have framebuffer + topfixedareasize=0; + scrollareasize=0; + usefastwindow=false; + fastwindowready=false; + is18bit=false; + isBGR=false; + // cls(); + // locate(0,0); +} TFT::TFT(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const char *name) : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) {
--- a/Display/TFT.h Mon Mar 23 14:08:04 2015 +0000 +++ b/Display/TFT.h Tue Mar 31 21:14:48 2015 +0000 @@ -4,6 +4,8 @@ #include "GraphicsDisplay.h" #include "PAR8.h" #include "PAR16.h" +#include "BUS8.h" +#include "BUS16.h" #include "SPI8.h" #include "SPI16.h" #include "Protocols.h" @@ -16,12 +18,17 @@ public: - /** Create a monochrome LCD Parallel interface + /** Create a TFT Parallel Port interface * @param name The name used by the parent class to access the interface */ TFT(proto_t displayproto,PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char* name); - /** Create a monochrome LCD SPI interface + /** Create a TFT Parallel Bus interface + * @param name The name used by the parent class to access the interface + */ + TFT(proto_t displayproto,PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char* name); + + /** Create a TFT SPI interface * @param name The name used by the parent class to access the interface */ TFT(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const char* name);
--- a/Display/TFT932x.cpp Mon Mar 23 14:08:04 2015 +0000 +++ b/Display/TFT932x.cpp Tue Mar 31 21:14:48 2015 +0000 @@ -33,6 +33,33 @@ // cls(); // locate(0,0); } +TFT932x::TFT932x(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char *name) + : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) +{ + if(displayproto==BUS_8) + { + PinName pins[16]; + for(int i=0; i<16; i++) pins[i]=NC; + for(int i=0; i<8; i++) pins[i]=buspins[i]; + proto = new BUS8(pins, CS, reset, DC, WR, RD); + dummycycles=1; + } + else if(displayproto==BUS_16) + { + proto = new BUS16(buspins, CS, reset, DC, WR, RD); + dummycycles=0; + } + // set_orientation(0); + foreground(White); + background(Black); + set_auto_up(false); //we don't have framebuffer + usefastwindow=false; + fastwindowready=false; + is18bit=false; + isBGR=false; + // cls(); + // locate(0,0); +} TFT932x::TFT932x(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, const int lcdsize_x, const int lcdsize_y, const char *name) : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) {
--- a/Display/TFT932x.h Mon Mar 23 14:08:04 2015 +0000 +++ b/Display/TFT932x.h Tue Mar 31 21:14:48 2015 +0000 @@ -4,6 +4,8 @@ #include "GraphicsDisplay.h" #include "PAR8.h" #include "PAR16.h" +#include "BUS8.h" +#include "BUS16.h" #include "SPI8.h" #include "SPI16.h" #include "Protocols.h" @@ -16,12 +18,17 @@ public: - /** Create a monochrome LCD Parallel interface + /** Create TFT Parallel Port interface * @param name The name used by the parent class to access the interface */ - TFT932x(proto_t displayproto,PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char* name); + TFT932x(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char* name); - /** Create a monochrome LCD SPI interface + /** Create TFT Parallel Bus interface + * @param name The name used by the parent class to access the interface + */ + TFT932x(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char* name); + + /** Create TFT SPI interface * @note ILI9325D has different SPI protocol, not supported here * @param name The name used by the parent class to access the interface */
--- a/Inits/ILI932x.cpp Mon Mar 23 14:08:04 2015 +0000 +++ b/Inits/ILI932x.cpp Tue Mar 31 21:14:48 2015 +0000 @@ -24,6 +24,19 @@ cls(); locate(0,0); } +ILI932x::ILI932x(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char *name , unsigned int LCDSIZE_X, unsigned int LCDSIZE_Y) + : TFT932x(displayproto, buspins, CS, reset, DC, WR, RD, LCDSIZE_X, LCDSIZE_Y, name) +{ + hw_reset(); + BusEnable(true); //set CS low, will stay low untill manually set high with BusEnable(false); + identify(); // will collect tftID + if(tftID==0x9325) init9325(); + auto_gram_read_format();// try to get read gram pixel format, could be 16bit or 18bit, RGB or BGR. Will set flags accordingly + set_orientation(0); + FastWindow(true); // most but not all controllers support this, even if datasheet tells they should. + cls(); + locate(0,0); +} ILI932x::ILI932x(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, const char *name, unsigned int LCDSIZE_X, unsigned int LCDSIZE_Y) : TFT932x(displayproto, Hz, mosi, miso, sclk, CS, reset, LCDSIZE_X, LCDSIZE_Y, name) {
--- a/Inits/ILI932x.h Mon Mar 23 14:08:04 2015 +0000 +++ b/Inits/ILI932x.h Tue Mar 31 21:14:48 2015 +0000 @@ -27,6 +27,21 @@ * @param LCDSIZE_Y y size in pixel - optional */ ILI932x(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name, unsigned int LCDSIZE_X = 240, unsigned int LCDSIZE_Y = 320); + + /** Create a BUS display interface + * @param displayproto BUS_8 or BUS_16 + * @param buspins array of PinName to group as Bus + * , i.e. PinName buspins[8]={PC_0,PC_1,PC_2,PC_3,D9,D8,D7,D6}; + * @param CS pin connected to CS of display + * @param reset pin connected to RESET of display + * @param DC pin connected to data/command of display + * @param WR pin connected to SDI of display + * @param RD pin connected to RS of display + * @param name The name used by the parent class to access the interface + * @param LCDSIZE_X x size in pixel - optional + * @param LCDSIZE_Y y size in pixel - optional + */ + ILI932x(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name, unsigned int LCDSIZE_X = 240, unsigned int LCDSIZE_Y = 320); /** Create an SPI display interface * @param displayproto SPI_8 or SPI_16
--- a/Inits/ILI9341.cpp Mon Mar 23 14:08:04 2015 +0000 +++ b/Inits/ILI9341.cpp Tue Mar 31 21:14:48 2015 +0000 @@ -29,6 +29,19 @@ FastWindow(true); // most but not all controllers support this, even if datasheet tells they should. locate(0,0); } +ILI9341::ILI9341(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char *name, unsigned int LCDSIZE_X, unsigned int LCDSIZE_Y) + : TFT(displayproto, buspins, CS, reset, DC, WR, RD, LCDSIZE_X, LCDSIZE_Y, name) +{ + hw_reset(); + BusEnable(true); + identify(); // will collect tftID and set mipistd flag + init(); + auto_gram_read_format(); + set_orientation(0); + cls(); + FastWindow(true); // most but not all controllers support this, even if datasheet tells they should. + locate(0,0); +} ILI9341::ILI9341(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char *name, unsigned int LCDSIZE_X , unsigned int LCDSIZE_Y) : TFT(displayproto, Hz, mosi, miso, sclk, CS, reset, DC, LCDSIZE_X, LCDSIZE_Y, name) {
--- a/Inits/ILI9341.h Mon Mar 23 14:08:04 2015 +0000 +++ b/Inits/ILI9341.h Tue Mar 31 21:14:48 2015 +0000 @@ -26,8 +26,21 @@ * @param LCDSIZE_X x size in pixel - optional * @param LCDSIZE_Y y size in pixel - optional */ - //ILI9341(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name); ILI9341(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name ,const unsigned int LCDSIZE_X = 240, unsigned int LCDSIZE_Y = 320); + + /** Create a BUS display interface + * @param displayproto BUS_8 or BUS_16 + * @param buspins array of PinName to group as Bus + * @param CS pin connected to CS of display + * @param reset pin connected to RESET of display + * @param DC pin connected to data/command of display + * @param WR pin connected to SDI of display + * @param RD pin connected to RS of display + * @param name The name used by the parent class to access the interface + * @param LCDSIZE_X x size in pixel - optional + * @param LCDSIZE_Y y size in pixel - optional + */ + ILI9341(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name ,const unsigned int LCDSIZE_X = 240, unsigned int LCDSIZE_Y = 320); /** Create an SPI display interface * @param displayproto SPI_8 or SPI_16 @@ -42,7 +55,6 @@ * @param LCDSIZE_X x size in pixel - optional * @param LCDSIZE_Y y size in pixel - optional */ - //ILI9341(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char* name); ILI9341(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char* name ,unsigned int LCDSIZE_X = 240, unsigned int LCDSIZE_Y = 320);
--- a/Inits/ST7565.cpp Mon Mar 23 14:08:04 2015 +0000 +++ b/Inits/ST7565.cpp Tue Mar 31 21:14:48 2015 +0000 @@ -28,6 +28,16 @@ set_orientation(1); locate(0,0); } +ST7565::ST7565(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char *name, unsigned int LCDSIZE_X, unsigned int LCDSIZE_Y) + : LCD(displayproto, buspins, CS, reset, DC, WR, RD, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name) +{ + hw_reset(); + BusEnable(true); + init(); + cls(); + set_orientation(1); + locate(0,0); +} ST7565::ST7565(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char *name, unsigned int LCDSIZE_X, unsigned int LCDSIZE_Y) : LCD(displayproto, Hz, mosi, miso, sclk, CS, reset, DC, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name) {
--- a/Inits/ST7565.h Mon Mar 23 14:08:04 2015 +0000 +++ b/Inits/ST7565.h Tue Mar 31 21:14:48 2015 +0000 @@ -27,6 +27,20 @@ * @param LCDSIZE_Y y size in pixel - optional */ ST7565(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name, unsigned int LCDSIZE_X = 132, unsigned int LCDSIZE_Y = 64); + + /** Create a BUS display interface + * @param displayproto only supports BUS_8 + * @param buspins array of PinName to group as Bus + * @param CS pin connected to CS of display + * @param reset pin connected to RESET of display + * @param DC pin connected to data/command of display + * @param WR pin connected to SDI of display + * @param RD pin connected to RS of display + * @param name The name used by the parent class to access the interface + * @param LCDSIZE_X x size in pixel - optional + * @param LCDSIZE_Y y size in pixel - optional + */ + ST7565(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name, unsigned int LCDSIZE_X = 132, unsigned int LCDSIZE_Y = 64); /** Create an SPI display interface * @param displayproto SPI_8 or SPI_16
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Protocols/BUS16.cpp Tue Mar 31 21:14:48 2015 +0000 @@ -0,0 +1,227 @@ + /* mbed UniGraphic library - BUS16 protocol class + * Copyright (c) 2015 Giuliano Dianda + * Released under the MIT License: http://mbed.org/license/mit + * + * Derived work of: + * + * mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller + * Copyright (c) 2013 Peter Drescher - DC2PD + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "BUS16.h" + +BUS16::BUS16(PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD) + : _bus(buspins), _CS(CS), _reset(reset), _DC(DC), _WR(WR), _RD(RD) +{ + _reset = 1; + _DC=1; + _WR=1; + _RD=1; + _CS=1; + _bus.mode(PullNone); + _bus.output(); // will re-enable our GPIO port + hw_reset(); +} + +void BUS16::wr_cmd8(unsigned char cmd) +{ + _DC = 0; // 0=cmd + _bus.write(cmd); // write 8bit + _WR=0; + _WR=1; + _DC = 1; // 1=data next +} +void BUS16::wr_data8(unsigned char data) +{ + _bus.write(data); // write 8bit + _WR=0; + _WR=1; +} +void BUS16::wr_cmd16(unsigned short cmd) +{ + _DC = 0; // 0=cmd + _bus.write(cmd>>8); // write 8bit + _WR=0; + _WR=1; + _bus.write(cmd&0xFF); // write 8bit + _WR=0; + _WR=1; + _DC = 1; // 1=data next +} +void BUS16::wr_data16(unsigned short data) +{ + _bus.write(data>>8); // write 8bit + _WR=0; + _WR=1; + _bus.write(data&0xFF); // write 8bit + _WR=0; + _WR=1; +} +void BUS16::wr_gram(unsigned short data) +{ + _bus.write(data); // write 16bit + _WR=0; + _WR=1; +} +void BUS16::wr_gram(unsigned short data, unsigned int count) +{ + while(count) + { + _bus.write(data); // rewrite even if same data, otherwise too much fast + _WR=0; + _WR=1; + count--; + } +} +void BUS16::wr_grambuf(unsigned short* data, unsigned int lenght) +{ + while(lenght) + { + _bus.write(*data); // write 16bit + _WR=0; + _WR=1; + data++; + lenght--; + } +} +unsigned short BUS16::rd_gram(bool convert) +{ + unsigned int r=0; + _bus.input(); + + _RD = 0; + _bus.read(); //dummy read + _RD = 1; + + _RD = 0; + // _RD = 0; // add wait + r |= _bus.read(); + _RD = 1; + if(convert) + { + r <<= 8; + _RD = 0; + // _RD = 0; // add wait + r |= _bus.read()>>8; //MSB of port read is blue, LSB is red of next pixel + _RD = 1; + // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit + // during reading, you read the raw 18bit gram + r = RGB24to16((r&0xFF0000)>>16, (r&0xFF00)>>8, r&0xFF);// 18bit pixel padded to 24bits, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit + } + _bus.output(); + return (unsigned short)r; +} +unsigned int BUS16::rd_reg_data32(unsigned char reg) +{ + wr_cmd8(reg); + unsigned int r=0; + // _DC = 1; // 1=data + _bus.input(); + + _RD = 0; + _bus.read(); //dummy read + _RD = 1; + + _RD = 0; +// _RD = 0; // add wait + r |= (_bus.read()&0xFF); + r <<= 8; + _RD = 1; + + _RD = 0; +// _RD = 0; // add wait + r |= (_bus.read()&0xFF); + r <<= 8; + _RD = 1; + + _RD = 0; +// _RD = 0; // add wait + r |= (_bus.read()&0xFF); + r <<= 8; + _RD = 1; + + _RD = 0; +// _RD = 0; // add wait + r |= (_bus.read()&0xFF); + _RD = 1; + + _CS = 1; // toggle CS to interupt the cmd in case was not supported + _CS = 0; + + _bus.output(); + return r; +} +// in Par mode EXTC regs (0xB0-0xFF) can be directly read +unsigned int BUS16::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd) +{ + return rd_reg_data32(reg); +} +// ILI932x specific +void BUS16::dummyread() +{ + _bus.input(); + _RD = 0; + _bus.read(); // dummy read + _RD=1; + // _bus.output(); +} +// ILI932x specific +void BUS16::reg_select(unsigned char reg, bool forread) +{ + _DC = 0; + _bus.write(reg); // write 16bit + _WR=0; + _WR=1; + _DC = 1; // 1=data next +} +// ILI932x specific +void BUS16::reg_write(unsigned char reg, unsigned short data) +{ + _DC = 0; + _bus.write(reg); // write 16bit + _WR=0; + _WR=1; + _DC = 1; + _bus.write(data); // write 16bit + _WR=0; + _WR=1; +} +// ILI932x specific +unsigned short BUS16::reg_read(unsigned char reg) +{ + unsigned short r=0; + _DC = 0; + _bus.write(reg); // write 16bit + _WR=0; + _WR=1; + _DC = 1; + _bus.input(); + _RD=0; + r |= _bus.read(); // read 16bit + _RD=1; + _bus.output(); + return r; +} +void BUS16::hw_reset() +{ + wait_ms(15); + _DC = 1; + _CS = 1; + _WR = 1; + _RD = 1; + _reset = 0; // display reset + wait_ms(2); + _reset = 1; // end reset + wait_ms(100); +} +void BUS16::BusEnable(bool enable) +{ + _CS = enable ? 0:1; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Protocols/BUS16.h Tue Mar 31 21:14:48 2015 +0000 @@ -0,0 +1,149 @@ +#ifndef BUS16_H +#define BUS16_H + +#include "mbed.h" +#include "Protocols.h" +//#include "GraphicsDisplay.h" + +/** Parallel 16bit interface +*/ +class BUS16 : public Protocols +{ + public: + + /** Create a BUS16 display interface with scattered pins and 5 control pins + * + * @param buspins array of PinNames to group as Bus + * @param CS pin connected to CS of display + * @param reset pin connected to RESET of display + * @param DC pin connected to data/command of display + * @param WR pin connected to SDI of display + * @param RD pin connected to RS of display + */ + BUS16(PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD); + +protected: + + /** Send 8bit command to display controller + * + * @param cmd: byte to send + * + */ + virtual void wr_cmd8(unsigned char cmd); + + /** Send 8bit data to display controller + * + * @param data: byte to send + * + */ + virtual void wr_data8(unsigned char data); + + /** Send 2x8bit command to display controller + * + * @param cmd: halfword to send + * @note 2cycles using pins[7:0] + */ + virtual void wr_cmd16(unsigned short cmd); + + /** Send 2x8bit data to display controller + * + * @param data: halfword to send + * @note 2cycles using pins[7:0], only gram write cmd uses pins[15:8] + */ + virtual void wr_data16(unsigned short data); + + /** Send 16bit pixeldata to display controller + * + * @param data: halfword to send + * @note here using all pins[15:0] + */ + virtual void wr_gram(unsigned short data); + + /** Send same 16bit pixeldata to display controller multiple times + * + * @param data: halfword to send + * @param count: how many + * @note here using all pins[15:0] + */ + virtual void wr_gram(unsigned short data, unsigned int count); + + /** Send array of pixeldata shorts to display controller + * + * @param data: unsigned short pixeldata array + * @param lenght: lenght (in shorts) + * @note here using all pins[15:0] + */ + virtual void wr_grambuf(unsigned short* data, unsigned int lenght); + + /** Read 16bit pixeldata from display controller (with dummy cycle) + * + * @param convert true/false. Convert 18bit to 16bit, some controllers returns 18bit + * @returns 16bit color + */ + virtual unsigned short rd_gram(bool convert); + + /** Read 4x8bit register data (with dummy cycle) + * @param reg the register to read + * @returns data as uint + * + */ + virtual unsigned int rd_reg_data32(unsigned char reg); + + /** Read 3x8bit ExtendedCommands register data + * @param reg the register to read + * @returns data as uint + * @note EXTC regs (0xB0 to 0xFF) are read/write registers, for Parallel mode directly accessible in both directions + */ + virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd); + + /** ILI932x specific, does a dummy read cycle, number of bits is protocol dependent + * for PAR protocols: a signle RD bit toggle + * for SPI8: 8clocks + * for SPI16: 16 clocks + */ + virtual void dummyread (); + + /** ILI932x specific, select register for a successive write or read + * + * @param reg register to be selected + * @param forread false = a write next (default), true = a read next + * @note forread only used by SPI protocols + */ + virtual void reg_select(unsigned char reg, bool forread =false); + + /** ILI932x specific, write register with data + * + * @param reg register to write + * @param data 16bit data + */ + virtual void reg_write(unsigned char reg, unsigned short data); + + /** ILI932x specific, read register + * + * @param reg register to be read + * @returns 16bit register value + */ + virtual unsigned short reg_read(unsigned char reg); + + /** HW reset sequence (without display init commands) + */ + virtual void hw_reset(); + + /** Set ChipSelect high or low + * @param enable 0/1 + */ + virtual void BusEnable(bool enable); + + + +private: + + BusInOut _bus; + DigitalOut _CS; + DigitalOut _reset; + DigitalOut _DC; + DigitalOut _WR; + DigitalOut _RD; + +}; +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Protocols/BUS8.cpp Tue Mar 31 21:14:48 2015 +0000 @@ -0,0 +1,275 @@ + /* mbed UniGraphic library - BUS8 protocol class + * Copyright (c) 2015 Giuliano Dianda + * Released under the MIT License: http://mbed.org/license/mit + * + * Derived work of: + * + * mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller + * Copyright (c) 2013 Peter Drescher - DC2PD + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "BUS8.h" + +BUS8::BUS8(PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD) + : _bus(buspins), _CS(CS), _reset(reset), _DC(DC), _WR(WR), _RD(RD) +{ + _reset = 1; + _DC=1; + _WR=1; + _RD=1; + _CS=1; + _bus.mode(PullNone); + _bus.output(); // will re-enable our GPIO port + hw_reset(); +} + +void BUS8::wr_cmd8(unsigned char cmd) +{ + _DC = 0; // 0=cmd + _bus.write(cmd); // write 8bit + _WR=0; + _WR=1; + _DC = 1; // 1=data next +} +void BUS8::wr_data8(unsigned char data) +{ + _bus.write(data); // write 8bit + _WR=0; + _WR=1; +} +void BUS8::wr_cmd16(unsigned short cmd) +{ + _DC = 0; // 0=cmd + _bus.write(cmd>>8); // write 8bit + _WR=0; + _WR=1; + _bus.write(cmd&0xFF); // write 8bit + _WR=0; + _WR=1; + _DC = 1; // 1=data next +} +void BUS8::wr_data16(unsigned short data) +{ + _bus.write(data>>8); // write 8bit + _WR=0; + _WR=1; + _bus.write(data&0xFF); // write 8bit + _WR=0; + _WR=1; +} +void BUS8::wr_gram(unsigned short data) +{ + _bus.write(data>>8); // write 8bit + _WR=0; + _WR=1; + _bus.write(data&0xFF); // write 8bit + _WR=0; + _WR=1; +} +void BUS8::wr_gram(unsigned short data, unsigned int count) +{ + if((data>>8)==(data&0xFF)) + { + count<<=1; + // _bus.write(data); // write 8bit + while(count) + { + _bus.write(data); // rewrite even if same data, otherwise too much fast + _WR=0; + _WR=1; + count--; + } + } + else + { + while(count) + { + _bus.write(data>>8); // write 8bit + _WR=0; + _WR=1; + _bus.write(data&0xFF); // write 8bit + _WR=0; + _WR=1; + count--; + } + } +} +void BUS8::wr_grambuf(unsigned short* data, unsigned int lenght) +{ + while(lenght) + { + _bus.write((*data)>>8); // write 8bit + _WR=0; + _WR=1; + _bus.write((*data)&0xFF); // write 8bit + _WR=0; + _WR=1; + data++; + lenght--; + } +} +unsigned short BUS8::rd_gram(bool convert) +{ + unsigned int r=0; + _bus.input(); + + _RD = 0; + _RD = 0; // add wait + _bus.read(); //dummy read + _RD = 1; + + _RD = 0; + _RD = 0; // add wait + r |= _bus.read(); + _RD = 1; + r <<= 8; + + _RD = 0; + _RD = 0; // add wait + r |= _bus.read(); + _RD = 1; + if(convert) + { + r <<= 8; + _RD = 0; + // _RD = 0; // add wait + r |= _bus.read(); + _RD = 1; + // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit + // during reading, you read the raw 18bit gram + r = RGB24to16((r&0xFF0000)>>16, (r&0xFF00)>>8, r&0xFF);// 18bit pixel padded to 24bits, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit + } + _bus.output(); + return (unsigned short)r; +} +unsigned int BUS8::rd_reg_data32(unsigned char reg) +{ + wr_cmd8(reg); + unsigned int r=0; + _bus.input(); + + _RD = 0; + _bus.read(); //dummy read + _RD = 1; + + _RD = 0; + // _RD = 0; // add wait + r |= (_bus.read()&0xFF); + r <<= 8; + _RD = 1; + + _RD = 0; + // _RD = 0; // add wait + r |= (_bus.read()&0xFF); + r <<= 8; + _RD = 1; + + _RD = 0; +// _RD = 0; // add wait + r |= (_bus.read()&0xFF); + r <<= 8; + _RD = 1; + + _RD = 0; + // _RD = 0; // add wait + r |= (_bus.read()&0xFF); + _RD = 1; + + _CS = 1; // force CS HIG to interupt the cmd in case was not supported + _CS = 0; + _bus.output(); + return r; +} +// in Par mode EXTC regs (0xB0-0xFF) can be directly read +unsigned int BUS8::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd) +{ + return rd_reg_data32(reg); +} +// ILI932x specific +void BUS8::dummyread() +{ + _bus.input(); + _RD=0; + _RD=0; // add wait + _bus.read(); // dummy read + _RD=1; + // _bus.output(); +} +// ILI932x specific +void BUS8::reg_select(unsigned char reg, bool forread) +{ + _DC = 0; + _bus.write(0); // write MSB + _WR=0; + _WR=1; + _bus.write(reg); // write LSB + _WR=0; + _WR=1; + _DC = 1; // 1=data next +} +// ILI932x specific +void BUS8::reg_write(unsigned char reg, unsigned short data) +{ + _DC = 0; + _bus.write(0); // write MSB + _WR=0; + _WR=1; + _bus.write(reg); // write MSB + _WR=0; + _WR=1; + _DC = 1; + _bus.write(data>>8); + _WR=0; + _WR=1; + _bus.write(data&0xFF); + _WR=0; + _WR=1; +} +// ILI932x specific +unsigned short BUS8::reg_read(unsigned char reg) +{ + unsigned short r=0; + _DC = 0; + _bus.write(0); + _WR=0; + _WR=1; + _bus.write(reg); + _WR=0; + _WR=1; + _DC = 1; + _bus.input(); + _RD=0; + r |= _bus.read(); // read 8bit + _RD=1; + r <<= 8; + _RD=0; + r |= _bus.read(); // read 8bit + _RD=1; + _bus.output(); + + return r; +} +void BUS8::hw_reset() +{ + wait_ms(15); + _DC = 1; + _CS = 1; + _WR = 1; + _RD = 1; + _reset = 0; // display reset + wait_ms(2); + _reset = 1; // end reset + wait_ms(100); +} +void BUS8::BusEnable(bool enable) +{ + _CS = enable ? 0:1; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Protocols/BUS8.h Tue Mar 31 21:14:48 2015 +0000 @@ -0,0 +1,150 @@ +#ifndef BUS8_H +#define BUS8_H + +#include "mbed.h" +#include "Protocols.h" +//#include "GraphicsDisplay.h" + +/** Parallel 8bit interface +*/ +class BUS8 : public Protocols +{ + public: + + /** Create a BUS8 display interface with scattered pins and 5 control pins + * + * @param buspins array of PinName to group as Bus + * , i.e PinName buspins[8]={PC_0,PC_1,PC_2,PC_3,D9,D8,D7,D6}; + * @param CS pin connected to CS of display + * @param reset pin connected to RESET of display + * @param DC pin connected to data/command of display + * @param WR pin connected to SDI of display + * @param RD pin connected to RS of display + */ + BUS8(PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD); + +protected: + + /** Send 8bit command to display controller + * + * @param cmd: byte to send + * + */ + virtual void wr_cmd8(unsigned char cmd); + + /** Send 8bit data to display controller + * + * @param data: byte to send + * + */ + virtual void wr_data8(unsigned char data); + + /** Send 2x8bit command to display controller + * + * @param cmd: halfword to send + * + */ + virtual void wr_cmd16(unsigned short cmd); + + /** Send 2x8bit data to display controller + * + * @param data: halfword to send + * + */ + virtual void wr_data16(unsigned short data); + + /** Send 16bit pixeldata to display controller + * + * @param data: halfword to send + * + */ + virtual void wr_gram(unsigned short data); + + /** Send same 16bit pixeldata to display controller multiple times + * + * @param data: halfword to send + * @param count: how many + * + */ + virtual void wr_gram(unsigned short data, unsigned int count); + + /** Send array of pixeldata shorts to display controller + * + * @param data: unsigned short pixeldata array + * @param lenght: lenght (in shorts) + * + */ + virtual void wr_grambuf(unsigned short* data, unsigned int lenght); + + /** Read 16bit pixeldata from display controller (with dummy cycle) + * + * @param convert true/false. Convert 18bit to 16bit, some controllers returns 18bit + * @returns 16bit color + */ + virtual unsigned short rd_gram(bool convert); + + /** Read 4x8bit register data (with dummy cycle) + * @param reg the register to read + * @returns data as uint + * + */ + virtual unsigned int rd_reg_data32(unsigned char reg); + + /** Read 3x8bit ExtendedCommands register data + * @param reg the register to read + * @returns data as uint + * @note EXTC regs (0xB0 to 0xFF) are read/write registers, for Parallel mode directly accessible in both directions + */ + virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd); + + /** ILI932x specific, does a dummy read cycle, number of bits is protocol dependent + * for PAR protocols: a signle RD bit toggle + * for SPI8: 8clocks + * for SPI16: 16 clocks + */ + virtual void dummyread (); + + /** ILI932x specific, select register for a successive write or read + * + * @param reg register to be selected + * @param forread false = a write next (default), true = a read next + * @note forread only used by SPI protocols + */ + virtual void reg_select(unsigned char reg, bool forread =false); + + /** ILI932x specific, write register with data + * + * @param reg register to write + * @param data 16bit data + */ + virtual void reg_write(unsigned char reg, unsigned short data); + + /** ILI932x specific, read register + * + * @param reg register to be read + * @returns 16bit register value + */ + virtual unsigned short reg_read(unsigned char reg); + + /** HW reset sequence (without display init commands) + */ + virtual void hw_reset(); + + /** Set ChipSelect high or low + * @param enable 0/1 + */ + virtual void BusEnable(bool enable); + + + +private: + + BusInOut _bus; + DigitalOut _CS; + DigitalOut _reset; + DigitalOut _DC; + DigitalOut _WR; + DigitalOut _RD; + +}; +#endif \ No newline at end of file
--- a/Protocols/Protocols.h Mon Mar 23 14:08:04 2015 +0000 +++ b/Protocols/Protocols.h Tue Mar 31 21:14:48 2015 +0000 @@ -18,8 +18,10 @@ /** Protocol types */ enum proto_t { - PAR_8 /**< Parallel 8bit, pins 0 to 7 */ - ,PAR_16 /**< Parallel 16bit, pins 0 to 15 */ + PAR_8 /**< Parallel 8bit, port pins 0 to 7 */ + ,PAR_16 /**< Parallel 16bit, port pins 0 to 15 */ + ,BUS_8 /**< Parallel 8bit, scattered pins */ + ,BUS_16 /**< Parallel 16bit, scattered pins */ ,SPI_8 /**< SPI 8bit */ ,SPI_16 /**< SPI 16bit */ };