Programme de test pour lcd ITDB02
Fork of TFTLCD by
Revision 4:3ac4239f6c9c, committed 2012-12-02
- Comitter:
- ttodorov
- Date:
- Sun Dec 02 05:44:52 2012 +0000
- Parent:
- 3:64a5b67d5b51
- Child:
- 5:09b6d228ceea
- Commit message:
- - renamed SSD1289 implementation; - refactored base class functions and removed redundant addressing; - added sleep and wake functions; - added HX8340B serial implementation; - fixed test case
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hx8340bs.cpp Sun Dec 02 05:44:52 2012 +0000 @@ -0,0 +1,198 @@ +/* + * Copyright (C)2010-2012 Henning Karlsen. All right reserved. + * Copyright (C)2012 Todor Todorov. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to: + * + * Free Software Foundation, Inc. + * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA + * + *********************************************************************/ +#include "hx8340bs.h" +#include "helpers.h" + +HX8340S_LCD::HX8340S_LCD( PinName CS, PinName RESET, PinName SCL, PinName SDI, PinName BL ) + : LCD( 176, 220, CS, NC, RESET ), _lcd_pin_scl( SCL ), _lcd_pin_sdi( SDI ) +{ + if ( BL != NC ) _lcd_pin_bl = new DigitalOut( BL ); + else _lcd_pin_bl = 0; +} + +void HX8340S_LCD::Initialize( orientation_t orientation ) +{ + _orientation = orientation; + + wait_ms( 100 ); + _lcd_pin_reset = HIGH; + wait_ms( 5 ); + _lcd_pin_reset = LOW; + wait_ms( 15 ); + _lcd_pin_reset = HIGH; + _lcd_pin_cs = HIGH; + _lcd_pin_scl = HIGH; + _lcd_pin_sdi = HIGH; + if ( _lcd_pin_bl != 0 ) + *_lcd_pin_bl = HIGH; + wait_ms( 55 ); + + Activate(); + WriteCmd( 0xC1 ); + WriteByteData( 0xFF ); + WriteByteData( 0x83 ); + WriteByteData( 0x40 ); + WriteCmd( 0x11 ); + wait_ms( 160 ); + WriteCmd( 0xCA ); + WriteByteData( 0x70 ); + WriteByteData( 0x00 ); + WriteByteData( 0xD9 ); + WriteCmd( 0xB0 ); + WriteByteData( 0x01 ); + WriteByteData( 0x11 ); + + WriteCmd( 0xC9 ); + WriteByteData( 0x90 ); + WriteByteData( 0x49 ); + WriteByteData( 0x10 ); + WriteByteData( 0x28 ); + WriteByteData( 0x28 ); + WriteByteData( 0x10 ); + WriteByteData( 0x00 ); + WriteByteData( 0x06 ); + wait_ms( 20 ); + WriteCmd( 0xC2 ); + WriteByteData( 0x60 ); + WriteByteData( 0x71 ); + WriteByteData( 0x01 ); + WriteByteData( 0x0E ); + WriteByteData( 0x05 ); + WriteByteData( 0x02 ); + WriteByteData( 0x09 ); + WriteByteData( 0x31 ); + WriteByteData( 0x0A ); + + WriteCmd( 0xc3 ); + WriteByteData( 0x67 ); + WriteByteData( 0x30 ); + WriteByteData( 0x61 ); + WriteByteData( 0x17 ); + WriteByteData( 0x48 ); + WriteByteData( 0x07 ); + WriteByteData( 0x05 ); + WriteByteData( 0x33 ); + wait_ms( 10 ); + WriteCmd( 0xB5 ); + WriteByteData( 0x35 ); + WriteByteData( 0x20 ); + WriteByteData( 0x45 ); + + WriteCmd( 0xB4 ); + WriteByteData( 0x33 ); + WriteByteData( 0x25 ); + WriteByteData( 0x4c ); + wait_ms( 10 ); + WriteCmd( 0x3a ); + WriteByteData( 0x05 ); + WriteCmd( 0x29 ); + wait_ms( 10 ); + WriteCmd( 0x2a ); + WriteByteData( 0x00 ); + WriteByteData( 0x00 ); + WriteByteData( 0x00 ); + WriteByteData( 0xaf ); + WriteCmd( 0x2b ); + WriteByteData( 0x00 ); + WriteByteData( 0x00 ); + WriteByteData( 0x00 ); + WriteByteData( 0xdb ); + WriteCmd( 0x2c ); + Deactivate(); +} + +void HX8340S_LCD::Sleep( void ) +{ + Activate(); + WriteCmd( 0x28 ); + wait_ms( 10 ); + WriteCmd( 0x10 ); + wait_ms( 125 ); + if ( _lcd_pin_bl != 0 ) + *_lcd_pin_bl = LOW; + Deactivate(); +} + +void HX8340S_LCD::WakeUp( void ) +{ + Activate(); + WriteCmd( 0x29 ); + wait_ms( 10 ); + WriteCmd( 0x11 ); + wait_ms( 125 ); + if ( _lcd_pin_bl != 0 ) + *_lcd_pin_bl = HIGH; + Deactivate(); +} + +void HX8340S_LCD::WriteCmd( unsigned short cmd ) +{ + _lcd_pin_sdi = LOW; + pulseLow( _lcd_pin_scl ); + serializeByte( cmd & 0xFF ); +} + +void HX8340S_LCD::WriteData( unsigned short data ) +{ + _lcd_pin_sdi = HIGH; + pulseLow( _lcd_pin_scl ); + serializeByte( ( data >> 8 ) & 0xFF ); + _lcd_pin_sdi = HIGH; + pulseLow( _lcd_pin_scl ); + serializeByte( data & 0xFF ); +} + +void HX8340S_LCD::WriteByteData( unsigned char data ) +{ + _lcd_pin_sdi = HIGH; + pulseLow( _lcd_pin_scl ); + serializeByte( data ); +} + +void HX8340S_LCD::SetXY( uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 ) +{ + if ( _orientation == LANDSCAPE ) + { + swap( uint16_t, x1, y1 ) + swap( uint16_t, x2, y2 ) + y1 = _disp_height - y1; + y2 = _disp_height - y2; + swap( uint16_t, y1, y2 ) + } + + WriteCmdData( 0x2a, x1 ); + WriteData( x2 ); + WriteCmdData( 0x2b, y1 ); + WriteData( y2 ); + WriteCmd( 0x2c ); +} + +void HX8340S_LCD::serializeByte( unsigned char data ) +{ + for ( int i = 0; i < 8; i++ ) + { + if ( data & 0x80 ) _lcd_pin_sdi = HIGH; + else _lcd_pin_sdi = LOW; + pulseLow( _lcd_pin_scl ); + data = data << 1; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hx8340bs.h Sun Dec 02 05:44:52 2012 +0000 @@ -0,0 +1,173 @@ +/** \file hx8340b.h + * \brief mbed TFT LCD controller for displays with the HX8340-B IC (serial interface). + * \copyright GNU Public License, v2. or later + * + * A known display with this type of controller chip is the ITDB02-2.2SP + * from http://imall.iteadstudio.com + * + * This library is based on the Arduino/chipKIT UTFT library by Henning + * Karlsen, http://henningkarlsen.com/electronics/library.php?id=52 + * + * Copyright (C)2010-2012 Henning Karlsen. All right reserved. + * Copyright (C)2012 Todor Todorov. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to: + * + * Free Software Foundation, Inc. + * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA + * + *********************************************************************/ +#ifndef TFTLCD_HX8340B_H +#define TFTLCD_HX8340B_H + +#include "lcd_base.h" + +/** Represents a LCD instance. + * + * This is the utility class, through which the display can be manipulated + * and graphics objects can be shown to the user. A known display, which + * works with this library is the ITDB02-2.2SP from iTeadStudio - a RGB TFT + * with 176x220 pixels resolution and 65K/256K colors, using serial interface. + * + * The display needs 4 or 5 pins to work with mbed. As it uses +3.3V for power + * and logic, as well as the backlight, interfacing could happen directly + * to the mbed without the need of shields or level shifters as with Arduino. + * + * How to use: + * \code + * // include the library, this will also pull in the header for the provided fonts + * #include "hx8340bs.h" + * + * // create the lcd instance + * HX8340S_LCD lcd( p14, p13, p12, p11 ); // control pins + * + * int main() + * { + * // initialize display - place it in standard portrait mode and set background to black and + * // foreground to white color. + * lcd.Initialize(); + * // set current font to the smallest 8x12 pixels font. + * lcd.SetFont( Font8x12 ); + * // print something on the screen + * lcd.Print( "Hello, World!", CENTER, 25 ); // align text to center horizontally and use starndard colors + * + * while ( 1 ) { } + * } + * + * \endcode + * \version 0.1 + * \author Todor Todorov + */ +class HX8340S_LCD : public LCD +{ +public: + /** Creates a new instance of the class. + * + * \param CS Pin for the ChipSelect signal. + * \param RESET Pin for the RESET line. + * \param SCL Pin for the serial clock signal. + * \param SDI Pin for the serial data signal. + * \param BL Pin for controlling the backlight. By default not used. + */ + HX8340S_LCD( PinName CS, PinName RESET, PinName SCL, PinName SDI, PinName BL = NC ); + + /** Initialize display. + * + * Wakes up the display from sleep, initializes power parameters. + * This function must be called first, befor any painting on the + * display is done, otherwise the positioning of graphical elements + * will not work properly and any paynt operation will not be visible + * or produce garbage. + * + * \param oritentation The display orientation, landscape is default. + */ + virtual void Initialize( orientation_t orientation = LANDSCAPE ); + + /** Puts the display to sleep. + * + * When the display is in sleep mode, its power consumption is + * minimized. Before new pixel data can be written to the display + * memory, the controller needs to be brought out of sleep mode. + * \sa #WakeUp( void ); + * \remarks The result of this operation might not be exactly as + * expected. Putting the display to sleep will cause the + * controller to switch to the standard color of the LCD, + * so depending on whether the display is normally white, + * or normally dark, the screen might or might not go + * dark. Additional power saving can be achieved, if + * the backlight of the used display is not hardwired on + * the PCB and can be controlled via the BL pin. + */ + virtual void Sleep( void ); + + /** Wakes up the display from sleep mode. + * + * This function needs to be called before any other, when the + * display has been put into sleep mode by a previois call to + * #Sleep( void ). + */ + virtual void WakeUp( void ); + +protected: + /** Sends a command to the display. + * + * \param cmd The display command. + * \remarks Commands are controller-specific and this function needs to + * be implemented separately for each available controller. + */ + virtual void WriteCmd( unsigned short cmd ); + + /** Sends pixel data to the display. + * + * \param data The display data. + * \remarks Sendin data is controller-specific and this function needs to + * be implemented separately for each available controller. + */ + virtual void WriteData( unsigned short data ); + + /** Writes a single byte of pixel data to the display. + * + * \param data The data to be written. + * \remarks Sendin data is controller-specific and this function needs to + * be implemented separately for each available controller. + */ + virtual void WriteByteData( unsigned char data ); + + /** Assigns a chunk of the display memory to receive data. + * + * When data is sent to the display after this function completes, the opertion will + * start from the begining of the assigned address (pixel position) and the pointer + * will be automatically incremented so that the next data write operation will continue + * with the next pixel from the memory block. If more data is written than available + * pixels, at the end of the block the pointer will jump back to its beginning and + * commence again, until the next address change command is sent to the display. + * + * \param x1 The X coordinate of the pixel at the beginning of the block. + * \param y1 The Y coordinate of the pixel at the beginning of the block. + * \param x2 The X coordinate of the pixel at the end of the block. + * \param y2 The Y coordinate of the pixel at the end of the block. + * \remarks Addressing commands are controller-specific and this function needs to be + * implemented separately for each available controller. + */ + virtual void SetXY( uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 ); + +private: + void serializeByte( unsigned char data ); + +private: + DigitalOut _lcd_pin_scl, _lcd_pin_sdi; + DigitalOut* _lcd_pin_bl; +}; + +#endif /* TFTLCD_HX8340B_H */
--- a/lcd_base.cpp Sun Dec 02 01:44:23 2012 +0000 +++ b/lcd_base.cpp Sun Dec 02 05:44:52 2012 +0000 @@ -22,9 +22,13 @@ #include "lcd_base.h" #include "helpers.h" -LCD::LCD( unsigned short width, unsigned short height ,PinName CS, PinName RS ) - : _disp_width( width ), _disp_height( height ), _lcd_pin_cs( CS ), _lcd_pin_rs( RS ) -{} +LCD::LCD( unsigned short width, unsigned short height ,PinName CS, PinName RS, PinName RESET ) + : _disp_width( width ), _disp_height( height ), _lcd_pin_cs( CS ), _lcd_pin_rs( RS ), _lcd_pin_reset( RESET ) +{ + SetForeground(); + SetBackground(); + _font.font = 0; +} inline void LCD::SetForeground( unsigned short color ) @@ -64,12 +68,11 @@ void LCD::FillScreen( int color ) { unsigned short rgb = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color; - _lcd_pin_cs = LOW; + Activate(); ClearXY(); - _lcd_pin_rs = HIGH; for ( int i = 0; i < ( ( _disp_width ) * ( _disp_height ) ); i++ ) WriteData( rgb ); - _lcd_pin_cs = HIGH; + Deactivate(); } inline @@ -80,12 +83,11 @@ void LCD::DrawPixel( unsigned short x, unsigned short y, int color ) { - _lcd_pin_cs = LOW; + Activate(); SetXY( x, y, x, y ); WriteData( color == -1 ? _background : color == -2 ? _foreground : color ); - _lcd_pin_cs = HIGH; - ClearXY(); + Deactivate(); } void LCD::DrawLine( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color ) @@ -116,60 +118,58 @@ swap( ushort, y1, y2 ) DrawVLine( x1, y1, y2 - y1, color ); } - else if ( abs( x2 - x1 ) > abs( y2 - y1 ) ) + else { unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color; - _lcd_pin_cs = LOW; - delta = ( double( y2 - y1 ) / double( x2 - x1 ) ); - ty = double( y1 ); - if ( x1 > x2 ) + Activate(); + if ( abs( x2 - x1 ) > abs( y2 - y1 ) ) { - for ( int i = x1; i >= x2; i-- ) + delta = ( double( y2 - y1 ) / double( x2 - x1 ) ); + ty = double( y1 ); + if ( x1 > x2 ) { - SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) ); - WriteData( usedColor ); - ty = ty - delta; + for ( int i = x1; i >= x2; i-- ) + { + SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) ); + WriteData( usedColor ); + ty = ty - delta; + } + } + else + { + for ( int i = x1; i <= x2; i++ ) + { + SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) ); + WriteData( usedColor ); + ty = ty + delta; + } } } else { - for ( int i = x1; i <= x2; i++ ) + delta = ( float( x2 - x1 ) / float( y2 - y1 ) ); + tx = float( x1 ); + if ( y1 > y2 ) { - SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) ); - WriteData( usedColor ); - ty = ty + delta; + for ( int i = y2 + 1; i > y1; i-- ) + { + SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i ); + WriteData( usedColor ); + tx = tx + delta; + } + } + else + { + for ( int i = y1; i < y2 + 1; i++ ) + { + SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i ); + WriteData( usedColor ); + tx = tx + delta; + } } } - _lcd_pin_cs = HIGH; + Deactivate(); } - else - { - unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color; - _lcd_pin_cs = LOW; - delta = ( float( x2 - x1 ) / float( y2 - y1 ) ); - tx = float( x1 ); - if ( y1 > y2 ) - { - for ( int i = y2 + 1; i > y1; i-- ) - { - SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i ); - WriteData( usedColor ); - tx = tx + delta; - } - } - else - { - for ( int i = y1; i < y2 + 1; i++ ) - { - SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i ); - WriteData( usedColor ); - tx = tx + delta; - } - } - _lcd_pin_cs = HIGH; - } - - ClearXY(); } void LCD::DrawRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color ) @@ -263,7 +263,7 @@ int y1 = radius; unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color; - _lcd_pin_cs = LOW; + Activate(); SetXY( x, y + radius, x, y + radius ); WriteData( usedColor ); SetXY( x, y - radius, x, y - radius ); @@ -301,14 +301,13 @@ SetXY( x - y1, y - x1, x - y1, y - x1 ); WriteData( usedColor ); } - _lcd_pin_cs = HIGH; - ClearXY(); + Deactivate(); } void LCD::FillCircle( unsigned short x, unsigned short y, unsigned short radius, int color ) { unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color; - _lcd_pin_cs = LOW; + Activate(); for ( int y1 = -radius; y1 <= radius; y1++ ) for ( int x1 = -radius; x1 <= radius; x1++ ) if ( x1 * x1 + y1 * y1 <= radius * radius ) @@ -316,8 +315,7 @@ SetXY( x + x1, y + y1, x + x1, y + y1 ); WriteData( usedColor ); } - _lcd_pin_cs = HIGH; - ClearXY(); + Deactivate(); } void LCD::Print( const char *str, unsigned short x, unsigned short y, int fgColor, int bgColor, unsigned short deg ) @@ -352,33 +350,29 @@ { int tx, ty, tc, tsx, tsy; + Activate(); if ( scale == 1 ) { if ( _orientation == PORTRAIT ) { - _lcd_pin_cs = LOW; SetXY( x, y, x + sx - 1, y + sy - 1 ); for ( tc = 0; tc < ( sx * sy ); tc++ ) WriteData( data[ tc ] ); - _lcd_pin_cs = HIGH; } else { - _lcd_pin_cs = LOW; for ( ty = 0; ty < sy; ty++ ) { SetXY( x, y + ty, x + sx - 1, y + ty ); for ( tx = sx; tx >= 0; tx-- ) WriteData( data[ ( ty * sx ) + tx ] ); } - _lcd_pin_cs = HIGH; } } else { if ( _orientation == PORTRAIT ) { - _lcd_pin_cs = LOW; for ( ty = 0; ty < sy; ty++ ) { SetXY( x, y + ( ty * scale ), x + ( ( sx * scale ) - 1 ), y + ( ty * scale ) + scale ); @@ -387,11 +381,9 @@ for ( tsx = 0; tsx < scale; tsx++ ) WriteData( data[ ( ty * sx ) + tx ] ); } - _lcd_pin_cs = HIGH; } else { - _lcd_pin_cs = LOW; for ( ty = 0; ty < sy; ty++ ) { for ( tsy = 0; tsy < scale; tsy++ ) @@ -402,10 +394,9 @@ WriteData( data[ ( ty * sx ) + tx ] ); } } - _lcd_pin_cs = HIGH; } } - ClearXY(); + Deactivate(); } void LCD::DrawBitmap( unsigned short x, unsigned short y, unsigned short sx, unsigned short sy, bitmap_t data, unsigned short deg, unsigned short rox, unsigned short roy ) @@ -418,7 +409,7 @@ DrawBitmap( x, y, sx, sy, data ); else { - _lcd_pin_cs = LOW; + Activate(); for ( ty = 0; ty < sy; ty++ ) for ( tx = 0; tx < sx; tx++ ) { @@ -428,30 +419,37 @@ SetXY( newx, newy, newx, newy ); WriteData( data[ ( ty * sx ) + tx ] ); } - _lcd_pin_cs = HIGH; + Deactivate(); } - ClearXY(); +} + +inline +void LCD::Activate( void ) +{ + _lcd_pin_cs = LOW; +} + +inline +void LCD::Deactivate( void ) +{ + _lcd_pin_cs = HIGH; } /* -void LCD::writeCmd( unsigned short cmd ) +void LCD::WriteCmd( unsigned short cmd ) { _lcd_pin_rs = LOW; - _lcd_pin_cs = LOW; _lcd_port->write( cmd ); pulseLow( _lcd_pin_wr ); - _lcd_pin_cs = HIGH; } */ /* -void LCD::writeData( unsigned short data ) +void LCD::WriteData( unsigned short data ) { _lcd_pin_rs = HIGH; - _lcd_pin_cs = LOW; _lcd_port->write( data ); pulseLow( _lcd_pin_wr ); - _lcd_pin_cs = HIGH; } */ @@ -463,7 +461,7 @@ } /* -void LCD::setXY( uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 ) +void LCD::SetXY( uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 ) { if ( _orientation == LANDSCAPE ) { @@ -474,12 +472,12 @@ swap( uint16_t, y1, y2 ) } - writeCmdData( 0x44, ( x2 << 8 ) + x1 ); - writeCmdData( 0x45, y1 ); - writeCmdData( 0x46, y2 ); - writeCmdData( 0x4e, x1 ); - writeCmdData( 0x4f, y1 ); - writeCmd( 0x22 ); + WriteCmdData( 0x44, ( x2 << 8 ) + x1 ); + WriteCmdData( 0x45, y1 ); + WriteCmdData( 0x46, y2 ); + WriteCmdData( 0x4e, x1 ); + WriteCmdData( 0x4f, y1 ); + WriteCmd( 0x22 ); } */ @@ -495,24 +493,22 @@ { unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color; - _lcd_pin_cs = LOW; + Activate(); SetXY( x, y, x + len, y ); for ( int i = 0; i < len + 1; i++ ) WriteData( usedColor ); - _lcd_pin_cs = HIGH; - ClearXY(); + Deactivate(); } void LCD::DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color ) { unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color; - _lcd_pin_cs = LOW; + Activate(); SetXY( x, y, x, y + len ); for ( int i = 0; i < len; i++ ) WriteData( usedColor ); - _lcd_pin_cs = HIGH; - ClearXY(); + Deactivate(); } void LCD::PrintChar( char c, unsigned short x, unsigned short y, int fgColor, int bgColor ) @@ -523,7 +519,7 @@ unsigned short usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned short ) fgColor; unsigned short usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned short ) bgColor; - _lcd_pin_cs = LOW; + Activate(); if ( _orientation == PORTRAIT ) { @@ -564,8 +560,7 @@ temp += ( _font.width / 8 ); } } - _lcd_pin_cs = HIGH; - ClearXY(); + Deactivate(); } void LCD::RotateChar( char c, unsigned short x, unsigned short y, int pos, int fgColor, int bgColor, unsigned short deg ) @@ -579,7 +574,7 @@ unsigned short usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned short ) fgColor; unsigned short usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned short ) bgColor; - _lcd_pin_cs = LOW; + Activate(); temp = ( ( c - _font.offset ) * ( ( _font.width / 8 ) * _font.height ) ) + 4; for ( j = 0; j < _font.height; j++ ) @@ -602,6 +597,5 @@ } temp += ( _font.width / 8 ); } - _lcd_pin_cs = HIGH; - ClearXY(); + Deactivate(); }
--- a/lcd_base.h Sun Dec 02 01:44:23 2012 +0000 +++ b/lcd_base.h Sun Dec 02 05:44:52 2012 +0000 @@ -120,11 +120,40 @@ * or produce garbage. * * This function is controller-specific and needs to be implemented - * separately for each available implementation. + * separately for each available display. * \param oritentation The display orientation, landscape is default. */ virtual void Initialize( orientation_t orientation ) = 0; + /** Puts the display to sleep. + * + * When the display is in sleep mode, its power consumption is + * minimized. Before new pixel data can be written to the display + * memory, the controller needs to be brought out of sleep mode. + * \sa #WakeUp( void ); + * \remarks The result of this operation might not be exactly as + * expected. Putting the display to sleep will cause the + * controller to switch to the standard color of the LCD, + * so depending on whether the display is normally white, + * or normally dark, the screen might or might not go + * dark. Additional power saving can be achieved, if + * the backlight of the used display is not hardwired on + * the PCB and can be controlled via the BL pin. + * \remarks This function is controller-specific and needs to be + * implemented separately for each available display. + */ + virtual void Sleep( void ) = 0; + + /** Wakes up the display from sleep mode. + * + * This function needs to be called before any other, when the + * display has been put into sleep mode by a previois call to + * #Sleep( void ). + * \remarks This function is controller-specific and needs to be + * implemented separately for each available display. + */ + virtual void WakeUp( void ) = 0; + /** Set the foreground color for painting. * * This is the default foreground color to be used in painting operations. @@ -312,8 +341,21 @@ * \param height Height of the display in pixels. * \param CS Pin connected to the CS input of the display. * \param RS Pin connected to the RS input of the display. + * \param RESET Pin connected to the RESET input of the display. */ - LCD( unsigned short width, unsigned short height ,PinName CS, PinName RS ); + LCD( unsigned short width, unsigned short height ,PinName CS, PinName RS, PinName RESET ); + + /** Activates the display for command/data transfer. + * + * Usually achieved by pulling the CS pin of the display low. + */ + virtual void Activate( void ); + + /** Deactivates the display after data has been transmitted. + * + * Usually achieved by pulling the CS pin of the display high. + */ + virtual void Deactivate( void ); /** Sends a command to the display. * @@ -416,11 +458,11 @@ virtual void RotateChar( char c, unsigned short x, unsigned short y, int pos, int fgColor = -2, int bgColor = -1, unsigned short deg = 0 ); protected: - unsigned short _disp_width, _disp_height; - DigitalOut _lcd_pin_cs, _lcd_pin_rs; - orientation_t _orientation; - unsigned short _foreground, _background; - font_metrics_t _font; + unsigned short _disp_width, _disp_height; + DigitalOut _lcd_pin_cs, _lcd_pin_rs, _lcd_pin_reset; + orientation_t _orientation; + unsigned short _foreground, _background; + font_metrics_t _font; }; #endif /* TFTLCD_BASE_H */
--- a/ssd1289.cpp Sun Dec 02 01:44:23 2012 +0000 +++ b/ssd1289.cpp Sun Dec 02 05:44:52 2012 +0000 @@ -22,21 +22,17 @@ #include "ssd1289.h" #include "helpers.h" -SSD1289LCD::SSD1289LCD( PinName CS, PinName RESET, PinName RS, PinName WR, BusOut* DATA_PORT, PinName RD ) - : LCD( 240, 320, CS, RS ), _lcd_pin_reset( RESET ), _lcd_pin_wr( WR ) +SSD1289_LCD::SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, BusOut* DATA_PORT, PinName BL, PinName RD ) + : LCD( 240, 320, CS, RS, RESET ), _lcd_pin_wr( WR ) { _lcd_port = DATA_PORT; - if ( RD != NC ) - _lcd_pin_rd = new DigitalOut( RD ); - else - _lcd_pin_rd = 0; - - SetForeground(); - SetBackground(); - _font.font = 0; + if ( BL != NC ) _lcd_pin_bl = new DigitalOut( BL ); + else _lcd_pin_bl = 0; + if ( RD != NC ) _lcd_pin_rd = new DigitalOut( RD ); + else _lcd_pin_rd = 0; } -void SSD1289LCD::Initialize( orientation_t orientation ) +void SSD1289_LCD::Initialize( orientation_t orientation ) { _orientation = orientation; @@ -46,12 +42,14 @@ wait_ms( 15 ); _lcd_pin_reset = HIGH; _lcd_pin_cs = HIGH; + if ( _lcd_pin_bl != 0 ) + *_lcd_pin_bl = HIGH; if ( _lcd_pin_rd != 0 ) *_lcd_pin_rd = HIGH; _lcd_pin_wr = HIGH; wait_ms( 15 ); - + Activate(); WriteCmdData( 0x00, 0x0001 ); wait_ms( 1 ); WriteCmdData( 0x03, 0xA8A4 ); wait_ms( 1 ); WriteCmdData( 0x0C, 0x0000 ); wait_ms( 1 ); @@ -94,27 +92,38 @@ WriteCmdData( 0x4f, 0x0000 ); wait_ms( 1 ); WriteCmdData( 0x4e, 0x0000 ); wait_ms( 1 ); WriteCmd( 0x22 ); + Deactivate(); } -void SSD1289LCD::WriteCmd( unsigned short cmd ) +void SSD1289_LCD::Sleep( void ) { - _lcd_pin_rs = LOW; - _lcd_pin_cs = LOW; - _lcd_port->write( cmd ); - pulseLow( _lcd_pin_wr ); - _lcd_pin_cs = HIGH; + // TODO: figure out if the SSD1289 controller has sleep and wakeup commands + if ( _lcd_pin_bl != 0 ) + *_lcd_pin_bl = LOW; } -void SSD1289LCD::WriteData( unsigned short data ) +void SSD1289_LCD::WakeUp( void ) +{ + // TODO: figure out if the SSD1289 controller has sleep and wakeup commands + if ( _lcd_pin_bl != 0 ) + *_lcd_pin_bl = HIGH; +} + +void SSD1289_LCD::WriteCmd( unsigned short cmd ) +{ + _lcd_pin_rs = LOW; + _lcd_port->write( cmd ); + pulseLow( _lcd_pin_wr ); +} + +void SSD1289_LCD::WriteData( unsigned short data ) { _lcd_pin_rs = HIGH; - _lcd_pin_cs = LOW; _lcd_port->write( data ); pulseLow( _lcd_pin_wr ); - _lcd_pin_cs = HIGH; } -void SSD1289LCD::SetXY( uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 ) +void SSD1289_LCD::SetXY( uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 ) { if ( _orientation == LANDSCAPE ) {
--- a/ssd1289.h Sun Dec 02 01:44:23 2012 +0000 +++ b/ssd1289.h Sun Dec 02 05:44:52 2012 +0000 @@ -1,4 +1,4 @@ -/** \file ssd.h +/** \file ssd1289.h * \brief mbed TFT LCD controller for displays with the SSD1289 IC. * \copyright GNU Public License, v2. or later * @@ -40,7 +40,7 @@ * works with this library is the ITDB02-3.2S from iTeadStudio - a RGB TFT * with 240x320 pixels resolution and 65K colors, using 16-bit interface. * - * The display needs 20 or 21 pins to work with mbed, so it is possibly not + * The display needs 20 to 22 pins to work with mbed, so it is possibly not * the best of choices out there, but other than that it uses +3.3V for * power and logic, as well as the backlight, thus can be interfaced directly * to the mbed without the need of shields or level shifters as with Arduino. @@ -53,7 +53,7 @@ * // prepare the data bus for writing commands and pixel data * BusOut dataBus( p30, p29, p28, p27, p26, p25, p24, p23, p22, p21, p20, p19, p18, p17, p16, p15 ); // 16 pins * // create the lcd instance - * SSD1289 lcd( p14, p13, p12, p11, &dataBus ); // control pins and data bus + * SSD1289_LCD lcd( p14, p13, p12, p11, &dataBus ); // control pins and data bus * * int main() * { @@ -72,7 +72,7 @@ * \version 0.1 * \author Todor Todorov */ -class SSD1289LCD : public LCD +class SSD1289_LCD : public LCD { public: /** Creates a new instance of the class. @@ -82,11 +82,12 @@ * \param RS Pin for the RS signal. * \param WR Pin for the WR signal. * \param DATA_PORT Address of the data bus for transfer of commands and pixel data. + * \param BL Pin for controlling the backlight. By default not used. * \param RD Pin for the RD signal. This line is not needed by the driver, so if you would like to * use the pin on the mbed for something else, just pull-up the respective pin on the LCD high, * and do not assign a value to this parameter when creating the controller instance. */ - SSD1289LCD( PinName CS, PinName RESET, PinName RS, PinName WR, BusOut* DATA_PORT, PinName RD = NC ); + SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, BusOut* DATA_PORT, PinName BL = NC, PinName RD = NC ); /** Initialize display. * @@ -100,14 +101,70 @@ */ virtual void Initialize( orientation_t orientation = LANDSCAPE ); + /** Puts the display to sleep. + * + * When the display is in sleep mode, its power consumption is + * minimized. Before new pixel data can be written to the display + * memory, the controller needs to be brought out of sleep mode. + * \sa #WakeUp( void ); + * \remarks The result of this operation might not be exactly as + * expected. Putting the display to sleep will cause the + * controller to switch to the standard color of the LCD, + * so depending on whether the display is normally white, + * or normally dark, the screen might or might not go + * dark. Additional power saving can be achieved, if + * the backlight of the used display is not hardwired on + * the PCB and can be controlled via the BL pin. + */ + virtual void Sleep( void ); + + /** Wakes up the display from sleep mode. + * + * This function needs to be called before any other, when the + * display has been put into sleep mode by a previois call to + * #Sleep( void ). + */ + virtual void WakeUp( void ); + protected: + /** Sends a command to the display. + * + * \param cmd The display command. + * \remarks Commands are controller-specific and this function needs to + * be implemented separately for each available controller. + */ virtual void WriteCmd( unsigned short cmd ); + + /** Sends pixel data to the display. + * + * \param data The display data. + * \remarks Sendin data is controller-specific and this function needs to + * be implemented separately for each available controller. + */ virtual void WriteData( unsigned short data ); + + /** Assigns a chunk of the display memory to receive data. + * + * When data is sent to the display after this function completes, the opertion will + * start from the begining of the assigned address (pixel position) and the pointer + * will be automatically incremented so that the next data write operation will continue + * with the next pixel from the memory block. If more data is written than available + * pixels, at the end of the block the pointer will jump back to its beginning and + * commence again, until the next address change command is sent to the display. + * + * \param x1 The X coordinate of the pixel at the beginning of the block. + * \param y1 The Y coordinate of the pixel at the beginning of the block. + * \param x2 The X coordinate of the pixel at the end of the block. + * \param y2 The Y coordinate of the pixel at the end of the block. + * \remarks Addressing commands are controller-specific and this function needs to be + * implemented separately for each available controller. + */ virtual void SetXY( uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 ); private: - DigitalOut _lcd_pin_reset, _lcd_pin_wr; - BusOut* _lcd_port; + DigitalOut _lcd_pin_wr; + BusOut* _lcd_port; + DigitalOut* _lcd_pin_bl; DigitalOut* _lcd_pin_rd; };