This is a port of Henning Kralsen's UTFT library for Arduino/chipKIT to mbed, refactored to make full use of C++ inheritance and access control, in order to reduce work when implementing new drivers and at the same time make the code more readable and easier to maintain. As of now supported are SSD1289 (16-bit interface), HX8340-B (serial interface) and ST7735 (serial interface). Drivers for other controllers will be added as time and resources to acquire the displays to test the code permit.

Dependents:   test SDCard capstone_display capstone_display_2 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ili9328.cpp Source File

ili9328.cpp

00001 /*
00002  * Copyright (C)2010-2012 Henning Karlsen. All right reserved.
00003  * Copyright (C)2012-2013 Todor Todorov.
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to:
00017  *
00018  * Free Software Foundation, Inc.
00019  * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA
00020  *
00021  *********************************************************************/
00022 #include "ili9328.h"
00023 #include "helpers.h"
00024 
00025 ILI9328_LCD::ILI9328_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, BusOut* DATA_PORT, PinName BL, PinName RD, backlight_t blType, float defaultBackLightLevel )
00026     : LCD( 240, 320, CS, RS, RESET, BL, blType, defaultBackLightLevel ), _lcd_pin_wr( WR )
00027 {
00028     _lcd_port = DATA_PORT;
00029     if ( RD != NC ) _lcd_pin_rd = new DigitalOut( RD );
00030     else _lcd_pin_rd = 0;
00031 }
00032 
00033 void ILI9328_LCD::Initialize( orientation_t orientation, colordepth_t colors )
00034 {
00035     _orientation = orientation;
00036     _colorDepth = colors;
00037     
00038     _lcd_pin_reset = HIGH;
00039     wait_ms( 50 );
00040     _lcd_pin_reset = LOW;
00041     wait_ms( 100 );
00042     _lcd_pin_reset = HIGH;
00043     wait_ms( 1000 );
00044     _lcd_pin_cs = HIGH;
00045     if ( _lcd_pin_bl != 0 )
00046         *_lcd_pin_bl = HIGH;
00047     else if ( _bl_pwm != 0 )
00048         *_bl_pwm = _bl_pwm_default;
00049     if ( _lcd_pin_rd != 0 )
00050         *_lcd_pin_rd = HIGH;
00051     _lcd_pin_wr = HIGH;
00052     wait_ms( 15 );
00053     
00054     Activate();
00055     
00056     short drivOut = 0;
00057     short entryMod = 0;
00058     short gateScan = 0x2700;
00059     switch ( _orientation )
00060     {
00061         case LANDSCAPE:
00062             drivOut = 0x0100;
00063             entryMod |= 0x0038;
00064             gateScan |= 0x0000;
00065             break;
00066             
00067         case LANDSCAPE_REV:
00068             drivOut = 0x0000;
00069             entryMod |= 0x0038;
00070             gateScan |= 0x8000;
00071             break;
00072             
00073         case PORTRAIT_REV:
00074             drivOut = 0x0000;
00075             entryMod |= 0x0030;
00076             gateScan |= 0x0000;
00077             break;
00078             
00079         case PORTRAIT:
00080         default:
00081             drivOut = 0x0100;
00082             entryMod |= 0x0030;
00083             gateScan |= 0x8000;
00084             break;
00085     }
00086     switch ( _colorDepth )
00087     {
00088         case RGB18:
00089             entryMod |= 0x9000;
00090             break;
00091             
00092         case RGB16:
00093         default:
00094             entryMod |= 0x1000;
00095             break;
00096     }
00097     
00098     WriteCmdData( 0xE5, 0x78F0 ); // set SRAM internal timing
00099     WriteCmdData( 0x01, drivOut ); // set Driver Output Control
00100     WriteCmdData( 0x02, 0x0200 ); // set 1 line inversion
00101     WriteCmdData( 0x03, entryMod ); // set GRAM write direction and BGR=1.
00102     WriteCmdData( 0x04, 0x0000 ); // Resize register
00103     WriteCmdData( 0x08, 0x0207 ); // set the back porch and front porch
00104     WriteCmdData( 0x09, 0x0000 ); // set non-display area refresh cycle ISC[3:0]
00105     WriteCmdData( 0x0A, 0x0000 ); // FMARK function
00106     WriteCmdData( 0x0C, 0x0000 ); // RGB interface setting
00107     WriteCmdData( 0x0D, 0x0000 ); // Frame marker Position
00108     WriteCmdData( 0x0F, 0x0000 ); // RGB interface polarity
00109     // ----------- Power On sequence ----------- //
00110     WriteCmdData( 0x10, 0x0000 ); // SAP, BT[3:0], AP, DSTB, SLP, STB
00111     WriteCmdData( 0x11, 0x0007 ); // DC1[2:0], DC0[2:0], VC[2:0]
00112     WriteCmdData( 0x12, 0x0000 ); // VREG1OUT voltage
00113     WriteCmdData( 0x13, 0x0000 ); // VDV[4:0] for VCOM amplitude
00114     WriteCmdData( 0x07, 0x0001 );
00115     wait_ms( 200 ); // Dis-charge capacitor power voltage
00116     WriteCmdData( 0x10, 0x1690 ); // SAP, BT[3:0], AP, DSTB, SLP, STB
00117     WriteCmdData( 0x11, 0x0227 ); // Set DC1[2:0], DC0[2:0], VC[2:0]
00118     wait_ms( 50 ); // Delay 50ms
00119     WriteCmdData( 0x12, 0x000D ); // 0012
00120     wait_ms( 50 ); // Delay 50ms
00121     WriteCmdData( 0x13, 0x1200 ); // VDV[4:0] for VCOM amplitude
00122     WriteCmdData( 0x29, 0x000A ); // 04  VCM[5:0] for VCOMH
00123     WriteCmdData( 0x2B, 0x000D ); // Set Frame Rate
00124     wait_ms( 50 ); // Delay 50ms
00125     WriteCmdData( 0x20, 0x0000 ); // GRAM horizontal Address
00126     WriteCmdData( 0x21, 0x0000 ); // GRAM Vertical Address
00127     // ----------- Adjust the Gamma Curve ----------//
00128     WriteCmdData( 0x30, 0x0000 );
00129     WriteCmdData( 0x31, 0x0404 );
00130     WriteCmdData( 0x32, 0x0003 );
00131     WriteCmdData( 0x35, 0x0405 );
00132     WriteCmdData( 0x36, 0x0808 );
00133     WriteCmdData( 0x37, 0x0407 );
00134     WriteCmdData( 0x38, 0x0303 );
00135     WriteCmdData( 0x39, 0x0707 );
00136     WriteCmdData( 0x3C, 0x0504 );
00137     WriteCmdData( 0x3D, 0x0808 );
00138     //------------------ Set GRAM area ---------------//
00139     WriteCmdData( 0x50, 0x0000 ); // Horizontal GRAM Start Address
00140     WriteCmdData( 0x51, 0x00EF ); // Horizontal GRAM End Address
00141     WriteCmdData( 0x52, 0x0000 ); // Vertical GRAM Start Address
00142     WriteCmdData( 0x53, 0x013F ); // Vertical GRAM Start Address
00143     WriteCmdData( 0x60, gateScan ); // Gate Scan Line (0xA700)
00144     WriteCmdData( 0x61, 0x0000 ); // NDL,VLE, REV
00145     WriteCmdData( 0x6A, 0x0000 ); // set scrolling line
00146     //-------------- Partial Display Control ---------//
00147     WriteCmdData( 0x80, 0x0000 );
00148     WriteCmdData( 0x81, 0x0000 );
00149     WriteCmdData( 0x82, 0x0000 );
00150     WriteCmdData( 0x83, 0x0000 );
00151     WriteCmdData( 0x84, 0x0000 );
00152     WriteCmdData( 0x85, 0x0000 );
00153     //-------------- Panel Control -------------------//
00154     WriteCmdData( 0x90, 0x0010 ); 
00155     WriteCmdData( 0x92, 0x0000 );
00156     WriteCmdData( 0x07, 0x0133 ); // 262K color and display ON
00157     
00158     Deactivate();
00159 }
00160 
00161 void ILI9328_LCD::Sleep( void )
00162 {
00163     Activate();
00164     WriteCmdData( 0x10, 0x1692 ); // enter sleep mode
00165     wait_ms( 200 );
00166     LCD::Sleep();
00167     Deactivate();
00168 }
00169 
00170 void ILI9328_LCD::WakeUp( void )
00171 {
00172     Activate();
00173     WriteCmdData( 0x10, 0x1690 ); // exit sleep mode
00174     wait_ms( 200 );
00175     LCD::WakeUp();
00176     Deactivate();
00177 }
00178 
00179 void ILI9328_LCD::WriteCmd( unsigned short cmd )
00180 {
00181     _lcd_pin_rs = LOW;
00182     _lcd_port->write( cmd );
00183     pulseLow( _lcd_pin_wr );
00184 }
00185 
00186 void ILI9328_LCD::WriteData( unsigned short data )
00187 {
00188     _lcd_pin_rs = HIGH;
00189     _lcd_port->write( data );
00190     pulseLow( _lcd_pin_wr );
00191 }
00192 
00193 void ILI9328_LCD::SetXY( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2 )
00194 {
00195     switch ( _orientation )
00196     {
00197         case LANDSCAPE:
00198         case LANDSCAPE_REV:
00199             WriteCmdData( 0x20, y1 );
00200             WriteCmdData( 0x21, x1 );
00201             WriteCmdData( 0x50, y1 );
00202             WriteCmdData( 0x52, x1 );
00203             WriteCmdData( 0x51, y2 );
00204             WriteCmdData( 0x53, x2 );
00205             break;
00206             
00207         case PORTRAIT_REV:
00208         case PORTRAIT:
00209         default:
00210             WriteCmdData( 0x20, x1 );
00211             WriteCmdData( 0x21, y1 );
00212             WriteCmdData( 0x50, x1 );
00213             WriteCmdData( 0x52, y1 );
00214             WriteCmdData( 0x51, x2 );
00215             WriteCmdData( 0x53, y2 );
00216             break;
00217     }
00218     WriteCmd( 0x22 );
00219 }
00220 
00221 void ILI9328_LCD::SetPixelColor( unsigned int color, colordepth_t mode )
00222 {
00223     unsigned char r, g, b;
00224     unsigned short clr;
00225     r = g = b = 0;
00226     if ( _colorDepth == RGB16 )
00227     {
00228         switch ( mode )
00229         {
00230             case RGB16:
00231                 WriteData( color & 0xFFFF );
00232                 break;
00233             case RGB18:
00234                 r = ( color >> 10 ) & 0xF8;
00235                 g = ( color >> 4 ) & 0xFC;
00236                 b = ( color >> 1 ) & 0x1F;
00237                 clr = ( ( r | ( g >> 5 ) ) << 8 ) | ( ( g << 3 ) | b );
00238                 WriteData( clr );
00239                 break;
00240             case RGB24:
00241                 r = ( color >> 16 ) & 0xF8;
00242                 g = ( color >> 8 ) & 0xFC;
00243                 b = color & 0xF8;
00244                 clr = ( ( r | ( g >> 5 ) ) << 8 ) | ( ( g << 3 ) | ( b >> 3 ) );
00245                 WriteData( clr );
00246                 break;
00247         }
00248     }
00249     else if ( _colorDepth == RGB18 )
00250     {
00251         switch ( mode )
00252         {
00253             case RGB16:
00254                 r = ( ( color >> 8 ) & 0xF8 ) | ( ( color & 0x8000 ) >> 13 );
00255                 g = ( color >> 3 ) & 0xFC;
00256                 b = ( ( color << 3 ) & 0xFC ) | ( ( color >> 3 ) & 0x01 );
00257                 break;
00258             case RGB18:
00259                 b = ( color << 2 ) & 0xFC;
00260                 g = ( color >> 4 ) & 0xFC;
00261                 r = ( color >> 10 ) & 0xFC;
00262                 break;
00263             case RGB24:
00264                 r = ( color >> 16 ) & 0xFC;
00265                 g = ( color >> 8 ) & 0xFC;
00266                 b = color & 0xFC;
00267                 break;
00268         }
00269         clr = ( r << 8 ) | ( g << 2 ) | ( b >> 4 );
00270         WriteData( clr );
00271         WriteData( b << 4 );
00272     }
00273 }