Library for MI0283QT-2 LCD

Revision:
0:7ad454fed160
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MI0283QTlib.cpp	Wed May 23 06:25:31 2012 +0000
@@ -0,0 +1,1332 @@
+/* mbed Graphics LCD library. Library for MI0283QT-2 screen.
+
+    Copyright (c) 2011 NXP 3803 
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    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 "MI0283QTlib.h"
+#include "mbed.h"
+#include "Terminal24x12.h"
+#include "Terminal12x6.h"
+
+#ifdef _USE_FILE
+#include "SDFileSystem.h"
+#endif
+
+/* GLCD definition and functions. */
+#define LCD_MODE_262K        5          // 5=65K, 6=262K colors.
+
+/* */
+#define LCD_FAST_SPEED      40000000
+#define LCD_SLOW_SPEED       3000000
+//
+#define LCD_ID               (0)
+#define LCD_DATA             ((0x72)|(LCD_ID<<2))
+#define LCD_REGISTER         ((0x70)|(LCD_ID<<2))
+//
+#define LCD_WIDTH            (320)
+#define LCD_HEIGHT           (240)
+
+#if ( LCD_MODE_262K==6 )
+    #define RGB(r,g,b)           (((r&0xFC)<<16)|((g&0xFC)<<8)|((b&0xFC))) //6 red | 6 green | 6 blue
+#else
+    #define RGB(r,g,b)           (((r&0xF8)<<8)|((g&0xFC)<<3)|((b&0xF8)>>3)) //5 red | 6 green | 5 blue
+ #endif
+
+#define LCD_RST_DISABLE()    _rst = 1;
+#define LCD_RST_ENABLE()     _rst = 0;
+#define LCD_CS_DISABLE()     _cs = 1;
+#define LCD_CS_ENABLE()      _cs = 0;
+
+//MODDMA dma;
+
+GLCD::GLCD(  PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName bklgh) : _spi( mosi, miso, sclk), _cs( cs), _rst( rst), _bklgh( bklgh) {
+    // deselect the device
+    LCD_CS_DISABLE();
+    LCD_RST_ENABLE();
+    // defaults params
+    SPIClkSpeed=LCD_FAST_SPEED;
+    SPISlowClkSpeed=LCD_SLOW_SPEED;
+    SPIMode=3;
+    LCDBkLight=0.5;
+    //
+    BackGroundColor=LCD_BLACK;
+    //
+#if 0
+struct _FONTINFO {
+    unsigned char *pText;
+    unsigned int h_size;
+    unsigned int v_size;
+    unsigned int h_line;
+};
+#endif
+  
+    FontInfo[0].pText=(unsigned char*)&Text12x6[0];
+    FontInfo[0].h_size=6;
+    FontInfo[0].v_size=12;
+    FontInfo[0].h_line=1;
+    
+    FontInfo[1].pText=(unsigned char*)&Text24x12[0];
+    FontInfo[1].h_size=12;
+    FontInfo[1].v_size=24;
+    FontInfo[1].h_line=2;
+    
+    FontIdx=0;
+}
+
+void GLCD::backlighton( void)
+{
+    backlightset( 1);
+}
+
+void GLCD::backlightoff( void)
+{
+    backlightset( 0);
+}
+
+void GLCD::backlightset( double val)
+{
+    LCDBkLight=val;
+    _bklgh = LCDBkLight;    
+}
+
+void GLCD::lcd_init( void)
+{
+    _spi.format(8,SPIMode);
+    _spi.frequency( SPIClkSpeed);
+    _bklgh = LCDBkLight;
+    
+    lcd_reset();
+
+}
+
+void GLCD::lcd_init( unsigned int speedf)
+{
+    _spi.format(8,SPIMode);
+    _spi.frequency( speedf);
+    SPIClkSpeed=speedf;
+    _bklgh = LCDBkLight;
+    
+    lcd_reset();
+
+}
+
+void GLCD::lcd_init( unsigned int speedf, unsigned int speeds)
+{
+    _spi.format(8,SPIMode);
+    _spi.frequency( speedf);
+    SPIClkSpeed=speedf;
+    SPISlowClkSpeed=speeds;
+    _bklgh = LCDBkLight;
+    
+    lcd_reset();
+
+}
+
+void GLCD::lcd_setfontsmall(  void)
+{
+    FontIdx=0;
+}
+
+void GLCD::lcd_setfontbig(  void)
+{
+    FontIdx=1;
+}
+
+void GLCD::lcd_setbackgroundcolor( unsigned int color) {
+    BackGroundColor=color;
+}
+
+void GLCD::lcd_drawstr(char *__putstr, unsigned int xpos, unsigned int ypos, unsigned int color)
+{
+    char __ps;
+    unsigned int xp,yp;
+    
+    /* Set the fast SPI speed. */
+    _spi.frequency( SPIClkSpeed);
+    
+    xp=xpos; yp=ypos;
+    
+    while((__ps = *__putstr))
+    {
+        __putstr++;
+        if (__ps== 0) break;
+        lcd_drawch(__ps,xp,yp, color);
+        xp+=FontInfo[FontIdx].h_size;           // la dimensione del font per adesso è impostata manualmente.
+    }
+    /* Reset to slow speed. */
+    _spi.frequency( SPISlowClkSpeed);
+}
+    
+void GLCD::lcd_drawch( unsigned ch, unsigned int xpos, unsigned int ypos, unsigned int color)
+{
+    unsigned int H_Line, H_Size, V_Size, SrcInc;
+    unsigned char *pSrc;
+    unsigned int i, j, txtcolor;
+    
+    /* Set the fast SPI speed. */
+    _spi.frequency( SPIClkSpeed);
+    
+    // per adesso imposto i valori di queste grandezze manualmente
+    H_Line=FontInfo[FontIdx].h_line;
+    H_Size=FontInfo[FontIdx].h_size;
+    V_Size=FontInfo[FontIdx].v_size;
+    
+    //
+    lcd_area(xpos, ypos, (H_Size-1)+xpos, (V_Size-1)+ypos);
+    // printf("Programmo area: xpos=%d, ypos=%d, Hs=%d, Vs=%d\r\n", xpos,ypos,(H_Size-1)+xpos, (V_Size-1)+ypos);
+    // wait( 1);
+    //
+    pSrc=(unsigned char*)&FontInfo[FontIdx].pText[0]+(H_Line*V_Size*ch);
+    // printf("Carico il puntatore @ Text[%d]\r\n", (H_Line*V_Size*ch));
+    // wait( 1);
+
+    lcd_drawstart();
+  
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+#endif 
+
+    //
+    for ( i=0; i<V_Size; i++) {
+        SrcInc=H_Line;
+        for ( j=0; j<H_Size; j++) {
+            txtcolor=(*pSrc & (1UL<<(j&0x07)))?color:BackGroundColor;
+#if (LCD_MODE_262K==6 )    
+            _spi.write( (txtcolor&0x00FC0000)>>18 );
+            _spi.write( (txtcolor&0x0000FC00)>>10 );
+            _spi.write( (txtcolor&0x000000FC)>>2);
+#else  
+            lcd_draw( txtcolor);
+#endif            //
+            if ((j&0x07) == 7) {
+                ++pSrc;
+                --SrcInc;
+            }
+        }
+        pSrc += SrcInc;
+    }
+    //
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+#endif   
+    lcd_drawstop();
+   /* Reset to the slow SPI speed. */
+    _spi.frequency( SPISlowClkSpeed);
+}
+
+void GLCD::lcd_draw(unsigned int color)
+{
+  _spi.write(color>>8);
+  _spi.write(color);
+
+  return;
+}
+
+
+void GLCD::lcd_drawstop(void)
+{
+  LCD_CS_DISABLE();
+
+  return;
+}
+
+
+void GLCD::lcd_drawstart(void)
+{
+  LCD_CS_ENABLE();
+  _spi.write(LCD_REGISTER);
+  _spi.write(0x22);
+  LCD_CS_DISABLE();
+
+  LCD_CS_ENABLE();
+  _spi.write(LCD_DATA);
+
+  return;
+}
+
+inline void GLCD::lcd_cmd(unsigned int reg, unsigned int param)
+{
+  LCD_CS_ENABLE();
+  _spi.write( LCD_REGISTER);
+  _spi.write( reg);
+  LCD_CS_DISABLE();
+
+  LCD_CS_ENABLE();
+  _spi.write( LCD_DATA);
+  _spi.write( param);
+  LCD_CS_DISABLE();
+
+  return;
+}
+
+
+void GLCD::lcd_data(unsigned int c)
+{
+  LCD_CS_ENABLE();
+  _spi.write(LCD_DATA);
+  _spi.write(c>>8);
+  _spi.write(c);
+  LCD_CS_DISABLE();
+
+  return;
+}
+
+void GLCD::lcd_area(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1)
+{
+  lcd_cmd(0x03, (x0>>0)); //set x0
+  lcd_cmd(0x02, (x0>>8)); //set x0
+  lcd_cmd(0x05, (x1>>0)); //set x1
+  lcd_cmd(0x04, (x1>>8)); //set x1
+  lcd_cmd(0x07, (y0>>0)); //set y0
+  lcd_cmd(0x06, (y0>>8)); //set y0
+  lcd_cmd(0x09, (y1>>0)); //set y1
+  lcd_cmd(0x08, (y1>>8)); //set y1
+
+  return;
+}
+
+void GLCD::lcd_setverticalarea( unsigned int topf, unsigned int height, unsigned int butf)
+{
+    if ( (topf+height+butf) > 320)
+        return;
+        
+    lcd_cmd( 0x0F, (topf>>0));
+    lcd_cmd( 0x0E, (topf>>8));
+    lcd_cmd( 0x11, (height>>0));
+    lcd_cmd( 0x10, (height>>8));
+    lcd_cmd( 0x13, (butf>>0));
+    lcd_cmd( 0x12, (butf>>8));
+}
+
+void GLCD::lcd_scrollstartadd( unsigned int ssa)
+{
+    lcd_cmd( 0x15, (ssa>>0));
+    lcd_cmd( 0x14, (ssa>>8));
+}
+
+void GLCD::lcd_scrollstart( void)
+{
+    lcd_cmd( 0x01, 0x0008);
+}
+
+void GLCD::lcd_scrollstop( void)
+{
+    lcd_cmd( 0x01, 0x0000);
+}
+
+unsigned int GLCD::lcd_RGB( unsigned int color)
+{
+
+     return ( RGB( (( color&0x00FF0000)>>16), ( ( color&0x0000FF00)>>8), ( color&0x000000FF)) );
+
+}
+
+unsigned int GLCD::lcd_RGB( unsigned int r, unsigned int g, unsigned int b)
+{
+    return ( RGB( r, g, b));
+}
+
+
+void GLCD::lcd_clear(unsigned int color)
+{
+  unsigned int i;
+
+  /* Set the fast SPI speed. */
+  _spi.frequency( SPIClkSpeed);
+  
+  lcd_area(0, 0, (LCD_WIDTH-1), (LCD_HEIGHT-1));
+
+  lcd_drawstart();
+  
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+    _spi.frequency( SPIClkSpeed);
+#endif 
+  
+  for(i=(LCD_WIDTH*LCD_HEIGHT); i!=0; i--)
+  {
+#if (LCD_MODE_262K==6 )    
+    _spi.write( (color&0x00FC0000)>>18 );
+    _spi.write( (color&0x0000FC00)>>10 );
+    _spi.write( (color&0x000000FC)>>2);
+#else  
+    lcd_draw( color);
+#endif    
+  }
+    //   
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+    _spi.frequency( SPIClkSpeed);
+#endif   
+  lcd_drawstop();
+
+  /* Reset to the slow SPI speed. */
+  _spi.frequency( SPISlowClkSpeed);
+  return;
+}
+
+void GLCD::lcd_clear(unsigned int x0, unsigned int y0, unsigned int w, unsigned int h, unsigned int color)
+{
+  unsigned int i;
+
+  /* Set the fast SPI speed. */
+  _spi.frequency( SPIClkSpeed);
+  
+  lcd_area(x0, y0, (w-1)+x0, (h-1)+y0);
+
+  lcd_drawstart();
+  
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+    _spi.frequency( SPIClkSpeed);
+#endif 
+  
+  for(i=(w*h); i!=0; i--)
+  {
+#if (LCD_MODE_262K==6 )    
+    _spi.write( (color&0x00FC0000)>>18 );
+    _spi.write( (color&0x0000FC00)>>10 );
+    _spi.write( (color&0x000000FC)>>2);
+#else  
+    lcd_draw( color);
+#endif    
+  }
+    //   
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+    _spi.frequency( SPIClkSpeed);
+#endif   
+  lcd_drawstop();
+
+  /* Reset to the slow SPI speed. */
+  _spi.frequency( SPISlowClkSpeed);
+  return;
+}
+
+
+#ifdef _USE_FILE
+unsigned int GLCD::lcd_drawimage(char *fname)
+{
+    unsigned int i;
+    unsigned char  r, g, b;
+    
+    FILE *fp;
+    
+    if ( (fp=fopen( fname, "r")) == NULL ) {
+        return 0;
+    }
+
+    lcd_area(0, 0, (LCD_WIDTH-1), (LCD_HEIGHT-1));
+    
+    lcd_drawstart();
+    
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,3);
+#endif   
+
+    for(i=(LCD_WIDTH*LCD_HEIGHT); i!=0; i--)
+    {
+        //
+        r=fgetc( fp);
+        g=fgetc( fp);
+        b=fgetc( fp);
+        //    
+#if ( LCD_MODE_262K==6 )        
+        _spi.write( (r&0xFC)>>2 );
+        _spi.write( (g&0xFC)>>2 );
+        _spi.write( (b&0xFC)>>2 );        
+#else
+        lcd_draw( RGB( r, g, b));
+#endif        
+        //
+        if ( feof( fp)) {
+            fclose( fp);
+            break;
+        }
+    }
+    //
+    if ( fp)
+        fclose( fp);
+    //   
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,3);
+#endif      
+    lcd_drawstop();
+
+    return 1;
+}
+#endif
+
+
+#ifdef _USE_FILE
+
+unsigned int GLCD::lcd_drawimagebuff(char *fname)
+{
+    unsigned int i;
+    unsigned char  r, g, b;
+    unsigned char buffer[320*BUFFER_LINE*3];
+    unsigned int size, idx, y=0;
+    
+    FILE *fp;
+    
+    if ( (fp=fopen( fname, "r")) == NULL ) {
+        return 0;
+    }
+
+    size=fread( &buffer[0], sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp);
+
+    /* Set the fast SPI speed. */
+    _spi.frequency( SPIClkSpeed);
+        
+    lcd_area(0, 0, (LCD_WIDTH-1), (LCD_HEIGHT-1));
+    
+    lcd_drawstart();
+    
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+#endif   
+    
+    idx=0;
+    for(i=(LCD_WIDTH*LCD_HEIGHT); i!=0; i--)
+    {
+        //
+        r=buffer[idx++];
+        g=buffer[idx++];
+        b=buffer[idx++];
+        //    
+#if ( LCD_MODE_262K==6 )  
+        _spi.write( (r&0xFC)>>2 );
+        _spi.write( (g&0xFC)>>2 );
+        _spi.write( (b&0xFC)>>2 );        
+#else
+        lcd_draw( RGB( r, g, b));
+#endif        
+        //
+        if ( idx>=size){
+#if ( LCD_MODE_262K==6 )
+            _spi.format(8,SPIMode);
+#endif             
+            lcd_drawstop();
+            //
+            if ( feof( fp)) {
+                fclose( fp);
+                break;
+            }
+            //
+            size=fread( &buffer[0], sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp);
+            idx=0;
+            y+=BUFFER_LINE;
+            lcd_area(0, y, (LCD_WIDTH-1), (LCD_HEIGHT-1));
+            lcd_drawstart();
+#if ( LCD_MODE_262K==6 )
+            _spi.format(6,SPIMode);
+#endif                 
+        }            
+    }
+    //   
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+#endif          
+    //
+    lcd_drawstop();
+    /* Reset to the slow SPI speed. */
+    _spi.frequency( SPISlowClkSpeed);    
+    //
+    if ( fp)
+        fclose( fp);
+
+    return 1;
+}
+#endif
+
+#ifdef _USE_FILE
+unsigned int GLCD::lcd_drawimagebyline(unsigned char *buffer, unsigned int lnum, unsigned int xstart, unsigned int ystart, unsigned int scale)
+{
+    unsigned int i, idx;
+    unsigned char  r, g, b;
+
+    /* Set the fast SPI speed. */
+    _spi.frequency( SPIClkSpeed);
+        
+    lcd_area(xstart, lnum+ystart, ((LCD_WIDTH/scale)-1)+xstart, lnum+ystart);
+    
+    lcd_drawstart();
+    
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+#endif   
+    
+    idx=0;
+    for(i=LCD_WIDTH/scale; i!=0; i--)
+    {
+        //
+        r=buffer[idx];
+        g=buffer[idx+1];
+        b=buffer[idx+2];
+        //
+        idx+=(scale*3);
+        //    
+#if ( LCD_MODE_262K==6 )  
+        _spi.write( (r&0xFC)>>2 );
+        _spi.write( (g&0xFC)>>2 );
+        _spi.write( (b&0xFC)>>2 );        
+#else
+        lcd_draw( RGB( r, g, b));
+#endif        
+    }
+    //   
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+#endif          
+    //
+    lcd_drawstop();
+    /* Reset to the slow SPI speed. */
+    _spi.frequency( SPISlowClkSpeed);    
+    
+    return 1;
+}
+#endif
+
+#ifdef _USE_FILE
+unsigned int GLCD::lcd_drawimagebyline(unsigned char *buffer, unsigned int lnum)
+{
+    unsigned int i, idx;
+    unsigned char  r, g, b;
+
+    /* Set the fast SPI speed. */
+    _spi.frequency( SPIClkSpeed);
+        
+    lcd_area(0, lnum, (LCD_WIDTH-1), lnum);
+    
+    lcd_drawstart();
+    
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+#endif   
+    
+    idx=0;
+    for(i=LCD_WIDTH; i!=0; i--)
+    {
+        //
+        r=buffer[idx++];
+        g=buffer[idx++];
+        b=buffer[idx++];
+        //    
+#if ( LCD_MODE_262K==6 )  
+        _spi.write( (r&0xFC)>>2 );
+        _spi.write( (g&0xFC)>>2 );
+        _spi.write( (b&0xFC)>>2 );        
+#else
+        lcd_draw( RGB( r, g, b));
+#endif        
+    }
+    //   
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+#endif          
+    //
+    lcd_drawstop();
+    /* Reset to the slow SPI speed. */
+    _spi.frequency( SPISlowClkSpeed);    
+    
+    return 1;
+}
+#endif
+
+#ifdef _USE_FILE
+
+unsigned int GLCD::lcd_drawmovie(char *fname, unsigned int x_start, unsigned int y_start)
+{
+    unsigned int i;
+    unsigned char  r, g, b;
+    
+    FILE *fp;
+    
+    if ( (fp=fopen( fname, "r")) == NULL ) {
+        return 0;
+    }
+
+    /* Set the fast SPI speed. */
+    _spi.frequency( SPIClkSpeed);
+
+    lcd_drawstop();
+    // lcd_area(0, 0, (LCD_WIDTH-1), (LCD_HEIGHT-1));
+    lcd_area(x_start, y_start, (80-1)+x_start, (60-1)+y_start);
+    
+    lcd_drawstart();
+    
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+#endif   
+
+    while( 1)
+    {
+        //
+        r=fgetc( fp);
+        g=fgetc( fp);
+        b=fgetc( fp);
+        //    
+#if ( LCD_MODE_262K==6 )        
+        _spi.write( (r&0xFC)>>2 );
+        _spi.write( (g&0xFC)>>2 );
+        _spi.write( (b&0xFC)>>2 );        
+#else
+        lcd_draw( RGB( r, g, b));
+#endif        
+        //
+        if ( feof( fp)) {
+            fclose( fp);
+            break;
+        }
+    }
+    //
+    if ( fp)
+        fclose( fp);
+    //   
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+#endif      
+    lcd_drawstop();
+
+    /* Reset to the slow SPI speed. */
+    _spi.frequency( SPISlowClkSpeed);    
+
+    return 1;
+}
+#endif
+
+#ifdef _USE_FILE
+#if ( LCD_MODE_262K==5 )
+
+// I will use a portion of memory proportional to a defined number of rows.
+#define cLINE_NUMBER    40
+
+// Ping-pong buffer. The buffer are proportional to the number of pixel per row (160), to the
+// numeber of line I want to read and to the number of byte for each pixel. In this case I have
+// a ready-made file with each pixel defined with 16bit (RGB==565bit)
+unsigned char buffer[160*cLINE_NUMBER*2] __attribute((section("AHBSRAM1"),aligned));
+unsigned char buffer1[160*cLINE_NUMBER*2] __attribute((section("AHBSRAM0"),aligned));
+
+/** DMA_IRQHandler Called by DMA.
+ *  Please to learn more read: http://mbed.org/users/AjK/programs/SOWB/lg489e/docs/flash__read_8c_source.html
+ */
+volatile int DMA_flag;
+extern "C" void DMA_IRQHandler(void) __irq {
+    if (LPC_GPDMA->DMACIntStat & 1) {
+        if (LPC_GPDMA->DMACIntTCStat & 1) {
+            DMA_flag=1;
+            LPC_GPDMA->DMACIntTCClear = 1;
+        }
+        if (LPC_GPDMA->DMACIntErrStat & 1) {
+            LPC_GPDMA->DMACIntErrClr = 1;
+        }
+    }
+}
+
+/** Linked List structure. I use this structure to send with one shot 3x3200 byte to the GLCD.
+ */
+typedef struct {
+    uint32_t SrcAddr;    /* Source Address */
+    uint32_t DstAddr;    /* Destination address  */
+    uint32_t NextLLI;    /* Next LLI address, otherwise set to '0'  */
+    uint32_t Control;    /* GPDMA Control Register of this LLI. Reflect the content of LPC_GPDMACH0->DMACCControl */
+} GPDMA_LLI;
+
+/* Let declare the 3 linked list. The first LLI address will be programmed inside the DMA registers. */
+GPDMA_LLI LLI0, LLI1, LLI2;
+
+#define DMA_CHANNEL_ENABLE      1
+#define DMA_TRANSFER_TYPE_M2P   (1UL << 11)   
+#define DMA_CHANNEL_TCIE        (1UL << 31)
+#define DMA_CHANNEL_SRC_INC     (1UL << 26)
+#define DMA_MASK_IE             (1UL << 14)
+#define DMA_MASK_ITC            (1UL << 15)
+#define DMA_CHANNEL_SRC_PERIPHERAL_SSP0_RX  (1UL << 1)
+#define DMA_CHANNEL_SRC_PERIPHERAL_SSP0_TX  (0UL << 1)
+#define DMA_CHANNEL_DST_PERIPHERAL_SSP0_RX  (1UL << 6)
+#define DMA_CHANNEL_DST_PERIPHERAL_SSP0_TX  (0UL << 6)
+
+/** Display a movie file. The file is ready made to speed up the entire process.
+ *
+ * @param the name file.
+ *
+ */
+unsigned int GLCD::lcd_drawmoviebuff(char *fname, unsigned int x_start, unsigned int y_start)
+{
+    unsigned int i;
+    unsigned char  r, g, b;
+    unsigned int size, idx, y=0;
+    unsigned char *pframe;
+    FILE *fp;
+    
+    LPC_SSP0->DMACR=2;
+
+    /* Load the content to the LLI */    
+    /* The LLI are chained, so I load the address to the corrispondent LLI*/
+    LLI0.NextLLI=(uint32_t)&LLI1;
+    LLI1.NextLLI=(uint32_t)&LLI2;
+    LLI2.NextLLI=0;                 // The last is NULL to stop the chain.
+    
+    /* The dimension of the buffer are fixed. So each LLI have a fixed pointer to the owned block of memory */
+    /* Each buffer is 16KB long but I use fixed chunk following this rule: */
+    /* The image is 160x120x2 = 38400 byte big. I have divided this amount by three so that it can */
+    /* use the two memory buffer. Each chunk is now 12800 byte. But the DMA can only transfer 4KB of RAM, */ 
+    /* so I divided this amount of memory by four, 3200 byte, and use three LLI to let the DMA to send the entire buffer all at once. */
+    /* The LLI are three because the DMA is programmed with the first chund of buffer. At the end of this operation, the DMA load the LLI */
+    /* and sends the remaining buffers. */
+    LLI0.SrcAddr=(uint32_t)&buffer[3200];
+    LLI1.SrcAddr=(uint32_t)&buffer[3200+3200];
+    LLI2.SrcAddr=(uint32_t)&buffer[3200+3200+3200];
+    /* OK, the destination address is the same for all LLI. Please change if you use a different SPI. */
+    LLI0.DstAddr=(uint32_t)&LPC_SSP0->DR;
+    LLI1.DstAddr=(uint32_t)&LPC_SSP0->DR;
+    LLI2.DstAddr=(uint32_t)&LPC_SSP0->DR;
+    /* This is the control register. */
+    LLI0.Control= DMA_CHANNEL_TCIE | DMA_CHANNEL_SRC_INC | 3200;
+    LLI1.Control= DMA_CHANNEL_TCIE | DMA_CHANNEL_SRC_INC | 3200;
+    LLI2.Control= DMA_CHANNEL_TCIE | DMA_CHANNEL_SRC_INC | 3200;
+    /* ****************************************************** */
+    
+    /* Power up the GPDMA. */
+    LPC_SC->PCONP |= (1UL << 29);
+    LPC_GPDMA->DMACConfig = 1;
+    LPC_GPDMA->DMACIntTCClear = 0x1;
+    // LPC_GPDMA->DMACSoftSReq   = 0xC;
+    LPC_GPDMA->DMACSoftSReq   = 0x3;
+    
+    /* Enable the IRQ */
+    NVIC_EnableIRQ(DMA_IRQn);
+    
+    /* Open the file */
+    if ( (fp=fopen( fname, "rb")) == NULL ) {
+        return 0;
+    }
+        
+    /* Set the fast SPI speed. */
+    _spi.frequency( SPIClkSpeed);
+    _spi.format(8,SPIMode);
+    /* Define a fixed area to display the movie. */
+    lcd_area(x_start, y_start, (160-1)+x_start, (120-1)+y_start);
+    lcd_drawstart();
+
+    /* read the first buffer... */
+    size=fread( &buffer[0], sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp);
+    
+    /* Loop untile the whole file is read. */
+    while( 1) {
+        pframe=&buffer[0];
+        /* set the source buffer... */
+        LLI0.SrcAddr=(uint32_t)&pframe[3200];
+        LLI1.SrcAddr=(uint32_t)&pframe[3200+3200];
+        LLI2.SrcAddr=(uint32_t)&pframe[3200+3200+3200];
+
+        /* configure the DMA channell... */
+        LPC_GPDMACH0->DMACCSrcAddr  = (uint32_t)pframe;
+        LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR;
+        LPC_GPDMACH0->DMACCLLI      = (uint32_t)&LLI0;
+        LPC_GPDMACH0->DMACCControl  = DMA_CHANNEL_TCIE | DMA_CHANNEL_SRC_INC | 3200;
+
+        DMA_flag=0;
+        /* Fire GPDMA Channel0 */
+        LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | 
+                                    DMA_CHANNEL_DST_PERIPHERAL_SSP0_TX |
+                                    DMA_TRANSFER_TYPE_M2P |
+                                    DMA_MASK_IE |
+                                    DMA_MASK_ITC;
+
+        if ( feof( fp)) {
+            fclose( fp);
+            break;
+        }    
+        /* Read the second chunk of the frame... */
+        size=fread( &buffer1[0], sizeof(buffer1[0]), sizeof(buffer1)/sizeof(buffer1[0]), fp);
+        /* OK, the buffer from the SDCar is read but now we must check if the DMA it's work... */
+        while( !DMA_flag);
+        DMA_flag=0;
+        /* At this point I check if I'm at end of the file. */
+        if ( feof( fp) || size != sizeof(buffer1)/sizeof(buffer1[0]) ) {
+            //
+            LPC_SSP0->IMSC = (1UL << 3);
+
+            LPC_GPDMACH0->DMACCConfig = 0;
+            LPC_GPDMA->DMACIntTCClear = 1;
+            
+            fclose( fp);
+            while(LPC_SSP0->SR & (1UL << 2)) {
+                /* This loop ensures we read the last byte in the
+                RX FIFO and test that. */
+                int sr = LPC_SSP0->DR;
+            }
+
+            // lcd_drawstop();
+            NVIC_DisableIRQ(DMA_IRQn);
+            LPC_GPDMA->DMACIntTCClear = 1;
+            LPC_SSP0->DMACR=0;
+            LPC_GPDMA->DMACConfig = 0;
+            LPC_GPDMA->DMACIntTCClear = 0x1;
+            LPC_GPDMA->DMACSoftSReq   = 0;
+            LPC_SC->PCONP &= ~(1UL << 29);
+            LPC_GPDMA->DMACIntTCClear = 1;
+            //
+            lcd_drawstop();
+            break;
+        }        
+        /* Now I have a buffer full with new data and the DMA stopped. I can start it again. */
+        pframe=&buffer1[0];
+        /* I set the new buffer inside the LLI... */
+        LLI0.SrcAddr=(uint32_t)&pframe[3200];
+        LLI1.SrcAddr=(uint32_t)&pframe[3200+3200];
+        LLI2.SrcAddr=(uint32_t)&pframe[3200+3200+3200];
+        /* DMA configuration. */    
+        LPC_GPDMACH0->DMACCSrcAddr  = (uint32_t)pframe;
+        LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR;
+        LPC_GPDMACH0->DMACCLLI      = (uint32_t)&LLI0;
+        LPC_GPDMACH0->DMACCControl  = DMA_CHANNEL_TCIE | DMA_CHANNEL_SRC_INC | 3200;
+        /* Fire GPDMA Channel0 */
+        LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | 
+                                    DMA_CHANNEL_DST_PERIPHERAL_SSP0_TX |
+                                    DMA_TRANSFER_TYPE_M2P |
+                                    DMA_MASK_IE |
+                                    DMA_MASK_ITC;
+                
+        if ( feof( fp)) {
+            fclose( fp);
+            break;
+        }        
+        /* A new read from the SDCad... */
+        size=fread( &buffer[0], sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp);
+        /* just wait is the DMA it's working... */
+        while( !DMA_flag);
+        DMA_flag=0;
+        /* At this point I check if I'm at end of the file. */
+        if ( feof( fp) || size != sizeof(buffer)/sizeof(buffer[0]) ) {
+            fclose( fp);
+            break;
+        }        
+        /* */
+        pframe=&buffer[0];
+        /* programmo nella LLI il nvuovo buffer... */
+        LLI0.SrcAddr=(uint32_t)&pframe[3200];
+        LLI1.SrcAddr=(uint32_t)&pframe[3200+3200];
+        LLI2.SrcAddr=(uint32_t)&pframe[3200+3200+3200];
+        /* programmo il DMA */    
+        LPC_GPDMACH0->DMACCSrcAddr  = (uint32_t)pframe;
+        LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR;
+        LPC_GPDMACH0->DMACCLLI      = (uint32_t)&LLI0;
+        LPC_GPDMACH0->DMACCControl  = DMA_CHANNEL_TCIE | DMA_CHANNEL_SRC_INC | 3200;
+        /* Fire GPDMA Channel0 */
+        LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | 
+                                    DMA_CHANNEL_DST_PERIPHERAL_SSP0_TX |
+                                    DMA_TRANSFER_TYPE_M2P |
+                                    DMA_MASK_IE |
+                                    DMA_MASK_ITC;
+        if ( feof( fp)) {
+            fclose( fp);
+            break;
+        }
+        /* */
+        size=fread( &buffer1[0], sizeof(buffer1[0]), sizeof(buffer1)/sizeof(buffer1[0]), fp);
+        /* Aspetto che il DMA completi l'ultimo transfer... */
+        while( !DMA_flag);
+        DMA_flag=0;
+        /* At this point I check if I'm at end of the file. */
+        if ( feof( fp) || size != sizeof(buffer1)/sizeof(buffer1[0]) ) {
+            fclose( fp);
+            break;
+        }                
+        /* */
+        pframe=&buffer1[0];
+        /* At this point I reset the display area resending the xy value*/
+        lcd_drawstop();        
+        LPC_SSP0->DMACR=0;
+        /* Invio un nuovo comando di lcd_area */
+        lcd_area(x_start, y_start, (160-1)+x_start, (120-1)+y_start);
+        lcd_drawstart();
+        /* */
+        LPC_SSP0->DMACR=2;
+
+        /* programmo nella LLI il nvuovo buffer... */
+        LLI0.SrcAddr=(uint32_t)&pframe[3200];
+        LLI1.SrcAddr=(uint32_t)&pframe[3200+3200];
+        LLI2.SrcAddr=(uint32_t)&pframe[3200+3200+3200];
+        /* programmo il DMA */    
+        LPC_GPDMACH0->DMACCSrcAddr  = (uint32_t)pframe;
+        LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR;
+        LPC_GPDMACH0->DMACCLLI      = (uint32_t)&LLI0;
+        LPC_GPDMACH0->DMACCControl  = DMA_CHANNEL_TCIE | DMA_CHANNEL_SRC_INC | 3200;
+        /* Fire GPDMA Channel0 */
+        LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | 
+                                    DMA_CHANNEL_DST_PERIPHERAL_SSP0_TX |
+                                    DMA_TRANSFER_TYPE_M2P |
+                                    DMA_MASK_IE |
+                                    DMA_MASK_ITC;
+
+        if ( feof( fp)) {
+            fclose( fp);
+            break;
+        }                
+        /* Ultima lettura del buffer da SDCard... */
+        size=fread( &buffer[0], sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp);
+        /* Aspetto che il DMA completi il transfer... */
+        while( !DMA_flag);
+        DMA_flag=0;
+        /* At this point I check if I'm at end of the file. */
+        if ( feof( fp) || size != sizeof(buffer)/sizeof(buffer[0]) ) {
+            fclose( fp);
+            break;
+        }        
+    }
+    //
+    LPC_SSP0->IMSC = (1UL << 3);
+    while(LPC_SSP0->SR & (1UL << 2)) {
+        /* This loop ensures we read the last byte in the
+        RX FIFO and test that. */
+        int sr = LPC_SSP0->DR;
+    }    
+    
+    LPC_GPDMACH0->DMACCConfig = 0;
+    LPC_SSP0->DMACR=0;
+    LPC_GPDMA->DMACConfig = 0;
+    LPC_GPDMA->DMACIntTCClear = 0x1;
+    LPC_GPDMA->DMACSoftSReq   = 0;
+    LPC_SC->PCONP &= ~(1UL << 29);
+    //
+    lcd_drawstop();
+    //
+    LPC_SSP0->DMACR=0;
+    LPC_GPDMA->DMACConfig = 0;
+    LPC_GPDMA->DMACIntTCClear = 0x1;
+    LPC_GPDMA->DMACSoftSReq   = 0;
+    LPC_SC->PCONP &= ~(1UL << 29);
+    //
+    /* Reset to the slow SPI speed. */
+    _spi.frequency( SPISlowClkSpeed);    
+    _spi.format(8,SPIMode);    
+    //
+    lcd_drawstop();
+    
+    lcd_area(0, 0, (320-1), (240-1));
+
+    /* Disable the IRQ */
+    NVIC_DisableIRQ(DMA_IRQn);    
+    return 1;
+}
+#endif      // #if ( LCD_MODE_262K==5 ) 
+#endif      // #ifdef _USE_FILE
+
+void GLCD::lcd_drawicon( const unsigned char *icon, unsigned int x, unsigned int y, unsigned int size)
+{
+  unsigned int i;
+  unsigned char r, g, b;
+
+  /* Set the fast SPI speed. */
+  _spi.frequency( SPIClkSpeed);
+  
+  lcd_area(x, y, ((size-1)+x), ((size-1)+y));
+
+  lcd_drawstart();
+  
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+#endif 
+  
+  for(i=(size*size); i!=0; i--)
+  {
+    r=*icon++;
+    g=*icon++;
+    b=*icon++;
+
+#if ( LCD_MODE_262K==6 )
+    _spi.write( (r&0xFC)>>2 );
+    _spi.write( (g&0xFC)>>2 );
+    _spi.write( (b&0xFC)>>2);
+#else
+    lcd_draw( RGB( r, g, b ) );
+#endif   
+  }
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+#endif  
+  lcd_drawstop();
+  /* Reset to the slow SPI speed. */
+  _spi.frequency( SPISlowClkSpeed);
+  return;
+}
+
+void GLCD::lcd_drawicon( const unsigned char *icon, unsigned int x, unsigned int y, unsigned int xsize, unsigned int ysize)
+{
+  unsigned int i;
+  unsigned char r, g, b;
+  
+  /* Set the fast SPI speed. */
+  _spi.frequency( SPIClkSpeed);
+  
+  lcd_area(x, y, ((xsize-1)+x), ((ysize-1)+y));
+
+  lcd_drawstart();
+  
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+#endif 
+  
+  for(i=(xsize*ysize); i!=0; i--)
+  {
+    r=*icon++;
+    g=*icon++;
+    b=*icon++;
+
+#if ( LCD_MODE_262K==6 )
+    _spi.write( (r&0xFC)>>2 );
+    _spi.write( (g&0xFC)>>2 );
+    _spi.write( (b&0xFC)>>2);
+#else
+    lcd_draw( RGB( r, g, b ) );
+#endif   
+  }
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+#endif  
+  lcd_drawstop();
+  /* Reset to the slow SPI speed. */
+  _spi.frequency( SPISlowClkSpeed);
+  return;
+}
+
+
+void GLCD::lcd_drawicon( const unsigned int *icon, unsigned int x, unsigned int y, unsigned int size)
+{
+  unsigned int i, tmp;
+  
+  /* Set the fast SPI speed. */
+  _spi.frequency( SPIClkSpeed);
+  
+  lcd_area(x, y, ((size-1)+x), ((size-1)+y));
+
+  lcd_drawstart();
+  
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+#endif 
+  
+  for(i=(size*size); i!=0; i--)
+  {
+    tmp = *icon++;
+#if ( LCD_MODE_262K==6 )
+    _spi.write( (tmp&0x00FC0000)>>18 );
+    _spi.write( (tmp&0x0000FC00)>>10 );
+    _spi.write( (tmp&0x000000FC)>>2);
+#else
+    lcd_draw( RGB( (( tmp&0x00FF0000)>>16), ( ( tmp&0x0000FF00)>>8), ( tmp&0x000000FF)) );
+#endif   
+  }
+#if ( LCD_MODE_262K==6 )
+    _spi.format(8,SPIMode);
+#endif  
+  lcd_drawstop();
+  /* Reset to the slow SPI speed. */
+  _spi.frequency( SPISlowClkSpeed);
+  return;
+}
+
+void GLCD::lcd_drawpixel(unsigned int x0, unsigned int y0, unsigned int color) {
+
+  /* Set the fast SPI speed. */
+  _spi.frequency( SPIClkSpeed);
+  
+  lcd_area( x0, y0, x0, y0);
+  lcd_drawstart();
+
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+    _spi.write( (color&0x00FC0000)>>18 );
+    _spi.write( (color&0x0000FC00)>>10 );
+    _spi.write( (color&0x000000FC)>>2);
+    _spi.format(8,SPIMode);
+#else  
+  lcd_draw(color);
+#endif
+
+  lcd_drawstop();
+  /* Reset to the slow SPI speed. */
+  _spi.frequency( SPISlowClkSpeed);
+
+}
+
+void GLCD::lcd_drawline(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int color) {
+  //
+  // pInt32U pData = ((pInt32U) LCD_VRAM_BASE_ADDR) + x0 + (y0 * LCD_HEIGHT);
+  // pInt32U pData = ((pInt32U) pCurrFrmBuff) + x0 + (y0 * LCD_HEIGHT);
+  
+  int dy = y1 - y0;
+  int dx = x1 - x0;
+  int stepx, stepy;
+  
+  if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
+  if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
+  
+  dy <<= 1; // dy is now 2*dy
+  dx <<= 1; // dx is now 2*dx
+  
+  /* Set the fast SPI speed. */
+  _spi.frequency( SPIClkSpeed);
+  
+  lcd_area( x0, y0, x0, y0);
+  lcd_drawstart();
+
+#if ( LCD_MODE_262K==6 )
+    _spi.format(6,SPIMode);
+    _spi.write( (color&0x00FC0000)>>18 );
+    _spi.write( (color&0x0000FC00)>>10 );
+    _spi.write( (color&0x000000FC)>>2);
+    _spi.format(8,SPIMode);
+#else  
+  lcd_draw(color);
+#endif
+
+  lcd_drawstop();
+  
+  // *(pData)= color;
+  
+  if (dx > dy) {
+          int fraction = dy - (dx >> 1);          // same as 2*dy - dx
+          while (x0 != x1) {
+                  if (fraction >= 0) {
+                          y0 += stepy;
+                          fraction -= dx;           // same as fraction -= 2*dx
+                  }
+                  x0 += stepx;
+                  fraction += dy;                   // same as fraction -= 2*dy
+                  // pData = ((pInt32U) LCD_VRAM_BASE_ADDR) + x0 + (y0 * C_GLCD_H_SIZE);
+                  // pData = ((pInt32U) pCurrFrmBuff) + x0 + (y0 * C_GLCD_H_SIZE);
+                  // *(pData)= color;
+                  lcd_area( x0, y0, x0, y0);
+                  lcd_drawstart();
+
+#if ( LCD_MODE_262K==6 )
+                   _spi.format(6,SPIMode);
+                   _spi.write( (color&0x00FC0000)>>18 );
+                   _spi.write( (color&0x0000FC00)>>10 );
+                   _spi.write( (color&0x000000FC)>>2);
+                   _spi.format(8,SPIMode);
+#else  
+                  lcd_draw(color);
+#endif
+                  
+                  lcd_drawstop();
+ 
+          }
+  } else {
+          int fraction = dx - (dy >> 1);
+          while (y0 != y1) {
+                  if (fraction >= 0) {
+                          x0 += stepx;
+                          fraction -= dy;
+                  }
+                  y0 += stepy;
+                  fraction += dx;
+                  // pData = ((pInt32U) LCD_VRAM_BASE_ADDR) + x0 + (y0 * C_GLCD_H_SIZE);
+                  // pData = ((pInt32U) pCurrFrmBuff) + x0 + (y0 * C_GLCD_H_SIZE);
+                  // *(pData)= color;
+                  lcd_area( x0, y0, x0, y0);
+                  lcd_drawstart();
+                  
+#if ( LCD_MODE_262K==6 )
+                   _spi.format(6,SPIMode);
+                   _spi.write( (color&0x00FC0000)>>18 );
+                   _spi.write( (color&0x0000FC00)>>10 );
+                   _spi.write( (color&0x000000FC)>>2);
+                   _spi.format(8,SPIMode);
+#else  
+                  lcd_draw(color);
+#endif
+                  
+                  lcd_drawstop();
+          }
+  }
+  /* Reset to the slow SPI speed. */
+  _spi.frequency( SPISlowClkSpeed);
+}
+
+void GLCD::lcd_reset(void)
+{
+  //reset
+  LCD_CS_DISABLE();
+  LCD_RST_ENABLE();
+  wait_ms(50);
+  LCD_RST_DISABLE();
+  wait_ms(50);
+
+  //driving ability
+  lcd_cmd(0xEA, 0x0000);
+  lcd_cmd(0xEB, 0x0020);
+  lcd_cmd(0xEC, 0x000C);
+  lcd_cmd(0xED, 0x00C4);
+  lcd_cmd(0xE8, 0x0040);
+  lcd_cmd(0xE9, 0x0038);
+  lcd_cmd(0xF1, 0x0001);
+  lcd_cmd(0xF2, 0x0010);
+  lcd_cmd(0x27, 0x00A3);
+
+  //power voltage
+  lcd_cmd(0x1B, 0x001B);
+  lcd_cmd(0x1A, 0x0001);
+  lcd_cmd(0x24, 0x002F);
+  lcd_cmd(0x25, 0x0057);
+
+  //VCOM offset
+  lcd_cmd(0x23, 0x008D); //for flicker adjust
+
+  //power on
+  lcd_cmd(0x18, 0x0036);
+  lcd_cmd(0x19, 0x0001); //start osc
+  lcd_cmd(0x01, 0x0000); //wakeup
+  lcd_cmd(0x1F, 0x0088);
+  wait_ms(5);
+  lcd_cmd(0x1F, 0x0080);
+  wait_ms(5);
+  lcd_cmd(0x1F, 0x0090);
+  wait_ms(5);
+  lcd_cmd(0x1F, 0x00D0);
+  wait_ms(5);
+
+  //color selection
+  lcd_cmd(0x17, LCD_MODE_262K); //0x0005=65k, 0x0006=262k 
+
+  //panel characteristic
+  lcd_cmd(0x36, 0x0000);
+
+  //display on
+  lcd_cmd(0x28, 0x0038);
+  wait_ms(40);
+  lcd_cmd(0x28, 0x003C);
+
+  //display options
+#ifdef LCD_MIRROR
+  lcd_cmd(0x16, 0x0068); //MY=0 MX=1 MV=1 ML=0 BGR=1
+#else
+  lcd_cmd(0x16, 0x00A8); //MY=1 MX=0 MV=1 ML=0 BGR=1
+#endif
+
+  lcd_area(0, 0, (LCD_WIDTH-1), (LCD_HEIGHT-1));
+
+  return;
+}
+