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.
Dependents: GR-PEACH_TFTLCD_8bit
Fork of TFTLCD_8bit 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;
};
