A modifiedversion of TFTLCD by Todor Todorov with ultra-fast operation for SSD1289 controller. TODO: speed-up fonts, add my own fonts Can work out-of-the-box with ST Nucleo F401RE
Dependents: TFT_320QVT_Window_Drag_Demo TFT_320QVT_HelloWorld
Fork of TFTLCD by
Diff: ssd1289.cpp
- Revision:
- 28:2f24de90cb46
- Parent:
- 22:4c169297f374
--- a/ssd1289.cpp Mon Jul 22 01:48:06 2013 +0000 +++ b/ssd1289.cpp Mon Jan 11 09:35:06 2016 +0000 @@ -26,6 +26,30 @@ : LCD( 240, 320, CS, RS, RESET, BL, blType, defaultBackLightLevel ), _lcd_pin_wr( WR ) { _lcd_port = DATA_PORT; + _use_fast_port = false; + _use_separate_port = false; + if ( RD != NC ) _lcd_pin_rd = new DigitalOut( RD ); + else _lcd_pin_rd = 0; +} + +SSD1289_LCD::SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, PortOut* FAST_DATA_PORT, PinName BL, PinName RD, backlight_t blType, float defaultBackLightLevel ) + : LCD( 240, 320, CS, RS, RESET, BL, blType, defaultBackLightLevel ), _lcd_pin_wr( WR ) +{ + if ( RD != NC ) _lcd_pin_rd = new DigitalOut( RD ); + else _lcd_pin_rd = 0; + _lp = FAST_DATA_PORT; + _use_fast_port = true; + _use_separate_port = false; + +} + +SSD1289_LCD::SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, PortOut* FAST_DATA_PORT_H, PortOut* FAST_DATA_PORT_L, PinName BL, PinName RD, backlight_t blType, float defaultBackLightLevel ) + : LCD( 240, 320, CS, RS, RESET, BL, blType, defaultBackLightLevel ), _lcd_pin_wr( WR ) +{ + _hp = FAST_DATA_PORT_H; + _lp = FAST_DATA_PORT_L; + _use_fast_port = true; + _use_separate_port = true; if ( RD != NC ) _lcd_pin_rd = new DigitalOut( RD ); else _lcd_pin_rd = 0; } @@ -209,17 +233,136 @@ void SSD1289_LCD::WriteCmd( unsigned short cmd ) { _lcd_pin_rs = LOW; - _lcd_port->write( cmd ); + if(_use_fast_port) + { + _lp->write(cmd); + if(_use_separate_port) + { + _hp->write(cmd); + } + } + else + { + _lcd_port->write( cmd ); + } + pulseLow( _lcd_pin_wr ); } void SSD1289_LCD::WriteData( unsigned short data ) { _lcd_pin_rs = HIGH; - _lcd_port->write( data ); + if(_use_fast_port) + { + _lp->write(data); + if(_use_separate_port) + { + _hp->write(data); + } + } + else + { + _lcd_port->write( data ); + } + pulseLow( _lcd_pin_wr ); } +void SSD1289_LCD::_fast_fill_16(int color, long pix) +{ + long blocks; + uint16_t i; + unsigned char r, g, b; + unsigned short clr; + r = ( color >> 16 ) & 0xF8; + g = ( color >> 8 ) & 0xFC; + b = color & 0xF8; + clr = ( ( r | ( g >> 5 ) ) << 8 ) | ( ( g << 3 ) | ( b >> 3 ) ); + + if(_use_fast_port) + { + _lp->write(clr); + if(_use_separate_port) + { + _hp->write(clr); + } + } + else + { + _lcd_port->write(clr); + } + blocks = pix/16; + for (i=0; i<blocks; i++) + { + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + pulseLow( _lcd_pin_wr ); + } + if ((pix % 16) != 0) + for (i=0; i<(pix % 16)+1; i++) + { + pulseLow( _lcd_pin_wr ); + } +} + +void SSD1289_LCD::FillScreen( int color ) +{ + + Activate(); + ClearXY(); + _lcd_pin_rs = HIGH; + _fast_fill_16(color, _disp_width*_disp_height); + Deactivate(); +} + +void SSD1289_LCD::FillRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color ) +{ + if ( x1 > x2 ) swap( ushort, x1, x2 ); + if ( y1 > y2 ) swap( ushort, y1, y2 ); + + Activate(); + SetXY(x1, y1, x2, y2); + _lcd_pin_rs = HIGH; + _fast_fill_16(color, (x2-x1+1)*(y2-y1+1)); + Deactivate(); +} + +void SSD1289_LCD::DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color ) +{ + unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color; + + Activate(); + SetXY( x, y, x + len-1, y ); + _lcd_pin_rs = HIGH; + _fast_fill_16(usedColor, len); + Deactivate(); +} + +void SSD1289_LCD::DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color ) +{ + unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color; + + Activate(); + SetXY( x, y, x, y + len-1 ); + _lcd_pin_rs = HIGH; + _fast_fill_16(usedColor, len); + Deactivate(); +} + + void SSD1289_LCD::SetXY( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2 ) { if ( _orientation == PORTRAIT || _orientation == PORTRAIT_REV )