Reloj en pantalla LCD Nokia con tres botones de ajuste.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
jaume
Date:
Sat Jul 12 10:27:13 2014 +0000
Commit message:
Reloj con FRDM-KL25Z y placa Color LCD de Sparkfun

Changed in this revision

ColorLCDShield.cpp Show annotated file Show diff for this revision Revisions of this file
ColorLCDShield.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ColorLCDShield.cpp	Sat Jul 12 10:27:13 2014 +0000
@@ -0,0 +1,625 @@
+// ColorLCDShield.cpp
+// ------------------
+// Sparkfun's Color LCD Shield (LCD-09363) library for mbed FRDM-KL25Z boards.
+//   - https://www.sparkfun.com/products/9363
+//     This library has modified from Sparkfun's Arduino library code
+//   - Command/data transmissions are implemented as software SPI communication
+//     because the FRDM board's MCUs are not 9-bit SPI capable :(
+//   - License is `CC BY-SA 3.0'
+//   - Original descriptions are below
+
+/*
+  LCDShield.cpp - Arduino Library to control a Nokia 6100 LCD, 
+  specifically that found on SparkFun's Color LCD Shield.
+  This code should work for both Epson and Phillips display drivers 
+  normally found on the Color LCD Shield.
+    
+  License: CC BY-SA 3.0: Creative Commons Share-alike 3.0. Feel free 
+  to use and abuse this code however you'd like. If you find it useful
+  please attribute, and SHARE-ALIKE!
+  
+  This is based on code by Mark Sproul, and Peter Davenport.
+  Thanks to Coleman Sellers and Harold Timmis for help getting it to work with the Phillips Driver 7-31-2011
+*/
+
+#include "ColorLCDShield.h"
+
+/*extern "C" {
+    #include "wiring.h"
+}*/
+
+#include "mbed.h"
+// #include "Arduino.h"
+
+static char x_offset = 0;
+static char y_offset = 0;
+
+DigitalOut res(PTA13);  // Arduino D8
+DigitalOut cs(PTD5);    // Arduino D9
+DigitalOut dio(PTD2);   // Arduino D11
+DigitalOut sck(PTD1);   // Arduino D13
+
+LCDShield::LCDShield()
+{
+}
+
+void LCDShield::LCDCommand(unsigned char data)
+{
+    char jj;
+
+    cs = 0;     // enable chip
+    dio = 0;   // output low on data out (9th bit low = command)
+
+    sck = 0;   // send clock pulse
+    // wait_us(1);
+    sck = 1;
+
+    for (jj = 0; jj < 8; jj++)
+    {
+        if ((data & 0x80) == 0x80)
+            dio = 1;
+        else
+            dio = 0;
+
+        sck = 0; // send clock pulse
+        // wait_us(1);
+        sck = 1;
+
+        data <<= 1;
+    }
+
+    cs = 1;     // disable
+}
+
+void LCDShield::LCDData(unsigned char data)
+{
+    char j;
+
+    cs = 0;     // enable chip
+    dio = 1;   // output high on data out (9th bit high = data)
+
+    sck = 0;   // send clock pulse
+    // wait_us(1);
+    sck = 1;   // send clock pulse
+
+    for (j = 0; j < 8; j++)
+    {
+        if ((data & 0x80) == 0x80)
+            dio = 1;
+        else
+            dio = 0;
+    
+        sck = 0; // send clock pulse
+        // wait_us(1);
+        sck = 1;
+
+        data <<= 1;
+    }
+
+    cs = 1;  // disable
+}
+
+void LCDShield::init(int type, bool colorSwap)
+{
+    driver = type;
+    
+    // Initialize the control pins, and reset display:
+    sck = 0; // CLK = LOW
+    dio = 0;     // DIO = LOW
+    wait_us(10);      // 10us delay
+    cs = 1;       // CS = HIGH
+    wait_us(10);      // 10uS Delay
+    res = 0; // RESET = LOW
+    wait_ms(200);                 // 200ms delay
+    res = 1; // RESET = HIGH
+    wait_ms(200);                 // 200ms delay
+    sck = 1; // SCK_PIN = HIGH
+    dio = 1;     // DIO = HIGH
+    wait_us(10);      // 10us delay
+    
+    if (driver == EPSON)
+    {
+        LCDCommand(DISCTL); // Display control (0xCA)
+        LCDData(0x0C);      // 12 = 1100 - CL dividing ratio [don't divide] switching period 8H (default)
+        LCDData(0x20);      // nlines/4 - 1 = 132/4 - 1 = 32 duty
+        LCDData(0x00);      // No inversely highlighted lines
+        
+        LCDCommand(COMSCN); // common scanning direction (0xBB)
+        LCDData(0x01);      // 1->68, 132<-69 scan direction
+        
+        LCDCommand(OSCON);  // internal oscialltor ON (0xD1)
+        LCDCommand(SLPOUT); // sleep out (0x94)
+        
+        LCDCommand(PWRCTR); // power ctrl (0x20)
+        LCDData(0x0F);      // everything on, no external reference resistors
+        
+        LCDCommand(DISINV); // invert display mode (0xA7)
+        
+        LCDCommand(DATCTL); // data control (0xBC)
+        LCDData(0x03);      // Inverse page address, reverse rotation column address, column scan-direction !!! try 0x01
+        LCDData(0x00);      // normal RGB arrangement
+        LCDData(0x02);      // 16-bit Grayscale Type A (12-bit color)
+        
+        LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness (0x81)
+        LCDData(32);        // volume (contrast) setting - fine tuning, original (0-63)
+        LCDData(3);         // internal resistor ratio - coarse adjustment (0-7)
+        
+        LCDCommand(NOP);    // nop (0x25)
+
+        wait_ms(100);
+
+        LCDCommand(DISON);  // display on (0xAF)
+    }
+    else if (driver == PHILIPS)
+    {
+        LCDCommand(SLEEPOUT);   // Sleep Out (0x11)
+        LCDCommand(BSTRON);     // Booster voltage on (0x03)
+        LCDCommand(DISPON);     // Display on (0x29)
+        
+        //LCDCommand(INVON);        // Inversion on (0x20)
+        
+        // 12-bit color pixel format:
+        LCDCommand(COLMOD);     // Color interface format (0x3A)
+        LCDData(0x03);          // 0b011 is 12-bit/pixel mode
+        
+        LCDCommand(MADCTL);     // Memory Access Control(PHILLIPS)
+        if (colorSwap) 
+            LCDData(0x08);
+        else
+            LCDData(0x00);
+        
+        LCDCommand(SETCON);     // Set Contrast(PHILLIPS)
+        LCDData(0x30);
+        
+        LCDCommand(NOPP);       // nop(PHILLIPS)
+    }
+}
+
+void LCDShield::clear(int color)
+{
+    if (driver) // if it's an Epson
+    {
+        LCDCommand(PASET);
+        LCDData(0);
+        LCDData(131);
+
+        LCDCommand(CASET);
+        LCDData(0);
+        LCDData(131);
+
+        LCDCommand(RAMWR);
+    }
+    else // otherwise it's a phillips
+    {
+        LCDCommand(PASETP);
+        LCDData(0);
+        LCDData(131);
+
+        LCDCommand(CASETP);
+        LCDData(0);
+        LCDData(131);
+
+        LCDCommand(RAMWRP);
+    }
+
+    for(unsigned int i=0; i < (131*131)/2; i++)
+    {
+        LCDData((color>>4)&0x00FF);
+        LCDData(((color&0x0F)<<4)|(color>>8));
+        LCDData(color&0x0FF);
+    }
+
+    x_offset = 0;
+    y_offset = 0;
+}
+
+void LCDShield::contrast(char setting)
+{
+    if (driver == EPSON)
+    {
+        setting &= 0x3F;    // 2 msb's not used, mask out
+        LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness(EPSON)
+        LCDData(setting);   // volume (contrast) setting - course adjustment,  -- original was 24
+        LCDData(3);         // TODO: Make this coarse adjustment variable, 3's a good place to stay
+    }
+    else if (driver == PHILIPS)
+    {
+        setting &= 0x7F;    // msb is not used, mask it out
+        LCDCommand(SETCON); // contrast command (PHILLIPS)
+        LCDData(setting);   // volume (contrast) setting - course adjustment,  -- original was 24
+    }
+}
+
+// Added by Steve Sparks @ Big Nerd Ranch.
+// This swaps the Epson RGB order into the Philips RGB order. (Or, vice versa, I suppose.)
+uint16_t LCDShield::swapColors(uint16_t in) {
+    return ((in & 0x000F)<<8)|(in & 0x00F0)|((in & 0x0F00)>>8);
+}
+
+void LCDShield::setPixel(int color, unsigned char x, unsigned char y)
+{
+    y   =   (COL_HEIGHT - 1) - y;
+    x = (ROW_LENGTH - 1) - x;
+
+    if (driver == EPSON) // if it's an epson
+    {
+        LCDCommand(PASET);  // page start/end ram
+        LCDData(x);
+        LCDData(ENDPAGE);
+
+        LCDCommand(CASET);  // column start/end ram
+        LCDData(y);
+        LCDData(ENDCOL);
+
+        LCDCommand(RAMWR);  // write
+        LCDData((color>>4)&0x00FF);
+        LCDData(((color&0x0F)<<4)|(color>>8));
+        LCDData(color&0x0FF);
+    }
+    else if (driver == PHILIPS)  // otherwise it's a phillips
+    {
+        LCDCommand(PASETP); // page start/end ram
+        LCDData(x);
+        LCDData(x);
+
+        LCDCommand(CASETP); // column start/end ram
+        LCDData(y);
+        LCDData(y);
+
+        LCDCommand(RAMWRP); // write
+
+        LCDData((unsigned char)((color>>4)&0x00FF));
+        LCDData((unsigned char)(((color&0x0F)<<4)|0x00));
+    }
+}
+// 2/18/2013 This Methos added by Tony Contrada in order to create arc segments in varied line thickness, or Filled
+void LCDShield::setArc(int x0, int y0, int radius, int arcSegments[], int numSegments, int lineThickness, int color)
+{
+    //Line Thickness (Num Pixels)
+    if(lineThickness == FILL) lineThickness = radius;
+    for(int i = 0; i < lineThickness; i++)
+    {
+        int f = 1 - radius;
+        int ddF_x = 0;
+        int ddF_y = -2 * radius;
+        int x = 0;
+        int y = radius;
+        while(x < y)
+        {
+            if(f >= 0)
+            {
+                y--;
+                ddF_y += 2;
+                f += ddF_y;
+            }
+            x++;
+            ddF_x += 2;
+            f += ddF_x + 1;
+
+            for(int i = 0; i < numSegments; i++)
+            {
+                if(arcSegments[i] == NNE) setPixel(color, x0 - y, y0 + x); //SHOW NNE
+                if(arcSegments[i] == ENE) setPixel(color, x0 - x, y0 + y); //SHOW ENE
+                if(arcSegments[i] == ESE) setPixel(color, x0 + x, y0 + y); //SHOW ESE
+                if(arcSegments[i] == SSE) setPixel(color, x0 + y, y0 + x); //SHOW SSE
+                if(arcSegments[i] == SSW) setPixel(color, x0 + y, y0 - x); //SHOW SSW
+                if(arcSegments[i] == WSW) setPixel(color, x0 + x, y0 - y); //SHOW WSW 
+                if(arcSegments[i] == WNW) setPixel(color, x0 - x, y0 - y); //SHOW WNW
+                if(arcSegments[i] == NNW) setPixel(color, x0 - y, y0 - x); //SHOW NNW
+            }
+        
+        }
+        radius--;
+    }
+
+}
+
+// 2/22/2013 - Modified by Tony Contrada to include Line Thickness (in pixels) or a Filled Circle
+void LCDShield::setCircle (int x0, int y0, int radius, int color, int lineThickness)
+{
+    if(lineThickness == FILL) lineThickness = radius;
+    
+    for(int r = 0; r < lineThickness; r++)
+    {
+        int f = 1 - radius;
+        int ddF_x = 0;
+        int ddF_y = -2 * radius;
+        int x = 0;
+        int y = radius;
+
+        setPixel(color, x0, y0 + radius);
+        setPixel(color, x0, y0 - radius);
+        setPixel(color, x0 + radius, y0);
+        setPixel(color, x0 - radius, y0);
+
+        while(x < y)
+        {
+            if(f >= 0)
+            {
+                y--;
+                ddF_y += 2;
+                f += ddF_y;
+            }
+            x++;
+            ddF_x += 2;
+            f += ddF_x + 1;
+
+            setPixel(color, x0 + x, y0 + y);
+            setPixel(color, x0 - x, y0 + y);
+            setPixel(color, x0 + x, y0 - y);
+            setPixel(color, x0 - x, y0 - y);
+            setPixel(color, x0 + y, y0 + x);
+            setPixel(color, x0 - y, y0 + x);
+            setPixel(color, x0 + y, y0 - x);
+            setPixel(color, x0 - y, y0 - x);
+        }
+        radius--;
+    }
+
+}
+
+void LCDShield::setChar(char c, int x, int y, int fColor, int bColor)
+{
+    y   =   (COL_HEIGHT - 1) - y; // make display "right" side up
+    x   =   (ROW_LENGTH - 2) - x;
+
+    int             i,j;
+    unsigned int    nCols;
+    unsigned int    nRows;
+    unsigned int    nBytes;
+    unsigned char   PixelRow;
+    unsigned char   Mask;
+    unsigned int    Word0;
+    unsigned int    Word1;
+    const unsigned char   *pFont;
+    const unsigned char   *pChar;
+
+    // get pointer to the beginning of the selected font table
+    pFont = *FONT8x16;
+    // get the nColumns, nRows and nBytes
+    nCols = *pFont;
+    nRows = *(pFont + 1);
+    nBytes = *(pFont + 2);
+    // get pointer to the last byte of the desired character
+    pChar = pFont + (nBytes * (c - 0x1F)) + nBytes - 1;
+
+    if (driver) // if it's an epson
+    {
+        // Row address set (command 0x2B)
+        LCDCommand(PASET);
+        LCDData(x);
+        LCDData(x + nRows - 1);
+        // Column address set (command 0x2A)
+        LCDCommand(CASET);
+        LCDData(y);
+        LCDData(y + nCols - 1);
+    
+        // WRITE MEMORY
+        LCDCommand(RAMWR);
+        // loop on each row, working backwards from the bottom to the top
+        for (i = nRows - 1; i >= 0; i--) {
+            // copy pixel row from font table and then decrement row
+            PixelRow = *(pChar++);
+            // loop on each pixel in the row (left to right)
+            // Note: we do two pixels each loop
+            Mask = 0x80;
+            for (j = 0; j < nCols; j += 2) 
+            {
+                // if pixel bit set, use foreground color; else use the background color
+                // now get the pixel color for two successive pixels
+                if ((PixelRow & Mask) == 0)
+                    Word0 = bColor;
+                else
+                    Word0 = fColor;
+                Mask = Mask >> 1;
+                if ((PixelRow & Mask) == 0)
+                    Word1 = bColor;
+                else
+                    Word1 = fColor;
+                Mask = Mask >> 1;
+                // use this information to output three data bytes
+                LCDData((Word0 >> 4) & 0xFF);
+                LCDData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF));
+                LCDData(Word1 & 0xFF);
+            }
+        }
+    }
+    else
+    {
+        fColor = swapColors(fColor);
+        bColor = swapColors(bColor);
+
+        // Row address set (command 0x2B)
+        LCDCommand(PASETP);
+        LCDData(x);
+        LCDData(x + nRows - 1);
+        // Column address set (command 0x2A)
+        LCDCommand(CASETP);
+        LCDData(y);
+        LCDData(y + nCols - 1);
+    
+        // WRITE MEMORY
+        LCDCommand(RAMWRP);
+        // loop on each row, working backwards from the bottom to the top
+        pChar+=nBytes-1;  // stick pChar at the end of the row - gonna reverse print on phillips
+        for (i = nRows - 1; i >= 0; i--) {
+            // copy pixel row from font table and then decrement row
+            PixelRow = *(pChar--);
+            // loop on each pixel in the row (left to right)
+            // Note: we do two pixels each loop
+            Mask = 0x01;  // <- opposite of epson
+            for (j = 0; j < nCols; j += 2) 
+            {
+                // if pixel bit set, use foreground color; else use the background color
+                // now get the pixel color for two successive pixels
+                if ((PixelRow & Mask) == 0)
+                    Word0 = bColor;
+                else
+                    Word0 = fColor;
+                Mask = Mask << 1; // <- opposite of epson
+                if ((PixelRow & Mask) == 0)
+                    Word1 = bColor;
+                else
+                    Word1 = fColor;
+                Mask = Mask << 1; // <- opposite of epson
+                // use this information to output three data bytes
+                LCDData((Word0 >> 4) & 0xFF);
+                LCDData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF));
+                LCDData(Word1 & 0xFF);
+            }
+        }
+    }
+}
+
+
+void LCDShield::setStr(char *pString, int x, int y, int fColor, int bColor)
+{
+    x = x + 16;
+    y = y + 8;
+    int originalY = y;
+
+    // loop until null-terminator is seen
+    while (*pString != 0x00) {
+        // draw the character
+        setChar(*pString++, x, y, fColor, bColor);
+        // advance the y position
+        y = y + 8;
+        // bail out if y exceeds 131
+        if (y > 131) {
+            x = x + 16;
+            y = originalY;
+        }
+        if (x > 123) break;
+    }
+}
+
+void LCDShield::setLine(int x0, int y0, int x1, int y1, int color)
+{
+    int dy = y1 - y0; // Difference between y0 and y1
+    int dx = x1 - x0; // Difference between x0 and x1
+    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
+    setPixel(color, x0, y0);
+
+    if (dx > dy) 
+    {
+        int fraction = dy - (dx >> 1);
+        while (x0 != x1)
+        {
+            if (fraction >= 0)
+            {
+                y0 += stepy;
+                fraction -= dx;
+            }
+            x0 += stepx;
+            fraction += dy;
+            setPixel(color, x0, y0);
+        }
+    }
+    else
+    {
+        int fraction = dx - (dy >> 1);
+        while (y0 != y1)
+        {
+            if (fraction >= 0)
+            {
+                x0 += stepx;
+                fraction -= dy;
+            }
+            y0 += stepy;
+            fraction += dx;
+            setPixel(color, x0, y0);
+        }
+    }
+}
+
+void LCDShield::setRect(int x0, int y0, int x1, int y1, unsigned char fill, int color)
+{
+    // check if the rectangle is to be filled
+    if (fill == 1)
+    {
+        int xDiff;
+    
+        if(x0 > x1)
+            xDiff = x0 - x1; //Find the difference between the x vars
+        else
+            xDiff = x1 - x0;
+    
+        while(xDiff > 0)
+        {
+            setLine(x0, y0, x0, y1, color);
+        
+            if(x0 > x1)
+                x0--;
+            else
+                x0++;
+        
+            xDiff--;
+        }
+
+    }
+    else 
+    {
+        // best way to draw an unfilled rectangle is to draw four lines
+        setLine(x0, y0, x1, y0, color);
+        setLine(x0, y1, x1, y1, color);
+        setLine(x0, y0, x0, y1, color);
+        setLine(x1, y0, x1, y1, color);
+    }
+}
+
+void LCDShield::printLogo(void)
+{
+    int x = 4, y = 25, logo_ix = 0, z;
+    char logo;
+
+    for (logo_ix = 0; logo_ix < 1120; logo_ix++)
+    {
+        logo = logo_spark[logo_ix];
+        for (z = 0; z < 8; z++)
+        {
+            if ((logo & 0x80) == 0x80) setPixel(RED, y, x);
+            x++;
+            if (x == 132)
+            {
+                x = 4;
+                y++;
+            }
+            logo <<= 1;
+        }
+    }
+}
+
+void LCDShield::off(void)
+{
+    if (driver) // If it's an epson
+        LCDCommand(DISOFF);
+    else // otherwise it's a phillips
+        LCDCommand(DISPOFF);
+}
+
+void LCDShield::on(void)
+{
+    if (driver) // If it's an epson
+        LCDCommand(DISON);
+    else // otherwise it's a phillips
+        LCDCommand(DISPON);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ColorLCDShield.h	Sat Jul 12 10:27:13 2014 +0000
@@ -0,0 +1,358 @@
+// ColorLCDShield.h
+// ----------------
+// Sparkfun's Color LCD Shield (LCD-09363) library for mbed FRDM-KL25Z boards.
+//   - https://www.sparkfun.com/products/9363
+//     This library has modified from Sparkfun's Arduino library code
+//   - Command/data transmissions are implemented as software SPI communication
+//     because the FRDM board's MCUs are not 9-bit SPI capable :(
+//   - License is `CC BY-SA 3.0'
+//   - Original descriptions are below
+
+/*
+  ColorLCDShield.h - Arduino Library to control a Nokia 6100 LCD, 
+  specifically that found on SparkFun's Color LCD Shield.
+  This code should work for both Epson and Phillips display drivers 
+  normally found on the Color LCD Shield.
+    
+  License: CC BY-SA 3.0: Creative Commons Share-alike 3.0. Feel free 
+  to use and abuse this code however you'd like. If you find it useful
+  please attribute, and SHARE-ALIKE!
+  
+  This is based on code by Mark Sproul, and Peter Davenport.
+*/
+
+#ifndef ColorLCDShield_H
+#define ColorLCDShield_H
+
+#define PHILLIPS    0
+#define PHILIPS     0
+#define EPSON       1
+
+#include "mbed.h"
+#include <stdint.h>
+
+//#include <WProgram.h>
+
+// #include <inttypes.h>
+// #include <avr/pgmspace.h>
+
+//*******************************************************
+//                      Macros
+//*******************************************************
+// #define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
+// #define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))
+
+//********************************************************************
+//
+//                  LCD Dimension Definitions
+//
+//********************************************************************
+#define ROW_LENGTH  132
+#define COL_HEIGHT  132
+#define ENDPAGE     132
+#define ENDCOL      130
+
+//********************************************************************
+//
+//                  EPSON Controller Definitions
+//
+//********************************************************************
+#define DISON       0xAF    // Display on
+#define DISOFF      0xAE    // Display off
+#define DISNOR      0xA6    // Normal display
+#define DISINV      0xA7    // Inverse display
+#define SLPIN       0x95    // Sleep in
+#define SLPOUT      0x94    // Sleep out
+#define COMSCN      0xBB    // Common scan direction
+#define DISCTL      0xCA    // Display control
+#define PASET       0x75    // Page address set
+#define CASET       0x15    // Column address set
+#define DATCTL      0xBC    // Data scan direction, etc.
+#define RGBSET8     0xCE    // 256-color position set
+#define RAMWR       0x5C    // Writing to memory
+#define RAMRD       0x5D    // Reading from memory
+#define PTLIN       0xA8    // Partial display in
+#define PTLOUT      0xA9    // Partial display out
+#define RMWIN       0xE0    // Read and modify write
+#define RMWOUT      0xEE    // End
+#define ASCSET      0xAA    // Area scroll set
+#define SCSTART     0xAB    // Scroll start set
+#define OSCON       0xD1    // Internal oscillation on
+#define OSCOFF      0xD2    // Internal osciallation off
+#define PWRCTR      0x20    // Power control
+#define VOLCTR      0x81    // Electronic volume control
+#define VOLUP       0xD6    // Increment electronic control by 1
+#define VOLDOWN     0xD7    // Decrement electronic control by 1
+#define TMPGRD      0x82    // Temperature gradient set
+#define EPCTIN      0xCD    // Control EEPROM
+#define EPCOUT      0xCC    // Cancel EEPROM control
+#define EPMWR       0xFC    // Write into EEPROM
+#define EPMRD       0xFD    // Read from EEPROM
+#define EPSRRD1     0x7C    // Read register 1
+#define EPSRRD2     0x7D    // Read register 2
+#define NOP         0x25    // No op
+
+//********************************************************************
+//
+//          PHILLIPS Controller Definitions
+//
+//********************************************************************
+//LCD Commands
+#define NOPP        0x00    // No operation
+#define BSTRON      0x03    // Booster voltage on
+#define SLEEPIN     0x10    // Sleep in
+#define SLEEPOUT    0x11    // Sleep out
+#define NORON       0x13    // Normal display mode on
+#define INVOFF      0x20    // Display inversion off
+#define INVON       0x21    // Display inversion on
+#define SETCON      0x25    // Set contrast
+#define DISPOFF     0x28    // Display off
+#define DISPON      0x29    // Display on
+#define CASETP      0x2A    // Column address set
+#define PASETP      0x2B    // Page address set
+#define RAMWRP      0x2C    // Memory write
+#define RGBSET      0x2D    // Color set
+#define MADCTL      0x36    // Memory data access control
+#define COLMOD      0x3A    // Interface pixel format
+#define DISCTR      0xB9    // Super frame inversion
+#define EC          0xC0    // Internal or external oscillator
+
+//*******************************************************
+//              12-Bit Color Definitions
+//*******************************************************
+#define BLACK       0x000
+#define NAVY        0x008
+#define BLUE        0x00F
+#define TEAL        0x088
+#define EMERALD     0x0C5
+#define GREEN       0x0F0
+#define CYAN        0x0FF
+#define SLATE       0x244
+#define INDIGO      0x408
+#define TURQUOISE   0x4ED
+#define OLIVE       0x682
+#define MAROON      0x800
+#define PURPLE      0x808
+#define GRAY        0x888
+#define SKYBLUE     0x8CE
+#define BROWN       0xB22
+#define CRIMSON     0xD13
+#define ORCHID      0xD7D
+#define RED         0xF00
+#define MAGENTA     0xF0F
+#define ORANGE      0xF40
+#define PINK        0xF6A
+#define CORAL       0xF75
+#define SALMON      0xF87
+#define GOLD        0xFD0
+#define YELLOW      0xFF0
+#define WHITE       0xFFF
+
+//*******************************************************
+//                              Circle Definitions
+//*******************************************************
+#define FILL 0
+
+//******************************************************
+//                       Arc Definitions
+//******************************************************
+#define ESE 1
+#define ENE 2
+#define WSW 3
+#define WNW 4
+#define SSE 5
+#define NNE 6
+#define SSW 7
+#define NNW 8
+
+const unsigned char FONT8x16[97][16] = {
+{0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},  // columns, rows, bytes, ...
+{0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},  // columns, rows, bytes, ...
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},  // ' '
+{0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00},  // '!'
+{0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},  // '"'
+{0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00},  // '#'
+{0x0C,0x0C,0x3E,0x63,0x61,0x60,0x3E,0x03,0x03,0x43,0x63,0x3E,0x0C,0x0C,0x00,0x00},  // '$'
+{0x00,0x00,0x00,0x00,0x00,0x61,0x63,0x06,0x0C,0x18,0x33,0x63,0x00,0x00,0x00,0x00},  // '%'
+{0x00,0x00,0x00,0x1C,0x36,0x36,0x1C,0x3B,0x6E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00},
+{0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x42,0x66,0x3C,0xFF,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x63,0x63,0x6B,0x6B,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00},  // '0'
+{0x00,0x00,0x0C,0x1C,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x03,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x03,0x03,0x1E,0x03,0x03,0x03,0x63,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0x66,0x7F,0x06,0x06,0x0F,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x03,0x03,0x63,0x73,0x3E,0x00,0x00,0x00,0x00},  // '5'
+{0x00,0x00,0x1C,0x30,0x60,0x60,0x7E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x7F,0x63,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x3F,0x03,0x03,0x06,0x3C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00},  // ':'
+{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00},
+{0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x63,0x06,0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x63,0x6F,0x6B,0x6B,0x6E,0x60,0x60,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x08,0x1C,0x36,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x00,0x00,0x00,0x00},  // 'A'
+{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x33,0x33,0x33,0x33,0x7E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1E,0x00,0x00,0x00,0x00},  // 'C'
+{0x00,0x00,0x7C,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x6F,0x63,0x63,0x37,0x1D,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x63,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00},  // 'H'
+{0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x73,0x33,0x36,0x36,0x3C,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x63,0x63,0x73,0x7B,0x7F,0x6F,0x67,0x63,0x63,0x63,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x1C,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x6B,0x6F,0x3E,0x06,0x07,0x00,0x00},
+{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x3E,0x63,0x63,0x30,0x1C,0x06,0x03,0x63,0x63,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x08,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x36,0x00,0x00,0x00,0x00},
+{0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00},
+{0x00,0x00,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x7F,0x63,0x43,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00},  // 'Z'
+{0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00},  // '\'
+{0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00},
+{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},  // '^'
+{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x3C,0x46,0x06,0x3E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00},  // '_'
+{0x00,0x00,0x70,0x30,0x30,0x3C,0x36,0x33,0x33,0x33,0x33,0x6E,0x00,0x00,0x00,0x00},  // '`'
+{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00,0x00},  // 'a'
+{0x00,0x00,0x0E,0x06,0x06,0x1E,0x36,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x7E,0x60,0x63,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x1C,0x36,0x32,0x30,0x7C,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00},
+{0x00,0x00,0x70,0x30,0x30,0x36,0x3B,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00},
+{0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3C,0x36,0x33,0x73,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x6E,0x7F,0x6B,0x6B,0x6B,0x6B,0x6B,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x3E,0x30,0x30,0x78,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x38,0x0E,0x03,0x63,0x3E,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x08,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x1B,0x0E,0x00,0x00,0x00,0x00},  // 't'
+{0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1C,0x1C,0x08,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x63,0x36,0x1C,0x1C,0x1C,0x36,0x63,0x00,0x00,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x3F,0x03,0x06,0x3C,0x00,0x00},
+{0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x0C,0x18,0x30,0x63,0x7F,0x00,0x00,0x00,0x00},  // 'z'
+{0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00},  // '{'
+{0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00},  // '|'
+{0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00},  // '}'
+{0x00,0x00,0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}   // '~'
+};
+
+static unsigned char logo_spark[1120] =  {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfb,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x3f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x3f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x7f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x20,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x0f,0xe0,0x9f,0x01,0xfc,0x09,0x9e,0x1e,0x7f,0x70,0x73,0x9f,0x00,0x00,0x00,0x00,
+0x3f,0xf1,0xff,0x87,0xfe,0x3f,0xde,0x3d,0xff,0x78,0xf3,0xff,0x80,0x00,0x00,0x00,
+0x3c,0xf9,0xff,0xc7,0xdf,0x3f,0xde,0x79,0xff,0x78,0xf3,0xff,0xc0,0x00,0x00,0x00,
+0x78,0x79,0xc3,0xcf,0x0f,0x3f,0x1c,0xf0,0x3c,0x78,0xf3,0xe3,0xc0,0x00,0x00,0x00,
+0x7c,0x01,0xc1,0xe0,0x0f,0x3e,0x1f,0xe0,0x3c,0x78,0xf3,0xc3,0xc0,0x00,0x00,0x00,
+0x3f,0xc1,0x81,0xe0,0x3f,0x3c,0x1f,0xe0,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00,
+0x1f,0xf1,0x81,0xe3,0xff,0x3c,0x1f,0xe0,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00,
+0x07,0xf9,0x81,0xe7,0xef,0x3c,0x1f,0xf0,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00,
+0x00,0xf9,0x81,0xef,0x07,0x3c,0x1e,0xf8,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00,
+0x78,0x79,0xc1,0xef,0x0f,0x3c,0x1e,0x78,0x3c,0x78,0xf3,0xc1,0xc0,0x00,0x00,0x00,
+0x78,0x79,0xe3,0xcf,0x0f,0x3c,0x1e,0x3c,0x3c,0x7c,0xf3,0xc1,0xc0,0x00,0x00,0x00,
+0x3f,0xf9,0xff,0xcf,0xff,0x3c,0x1e,0x3e,0x3c,0x7f,0xf3,0xc1,0xcf,0x00,0x00,0x00,
+0x1f,0xf1,0xff,0x87,0xff,0x3c,0x1e,0x1e,0x3c,0x3f,0xf3,0xc1,0xc7,0x00,0x00,0x00,
+0x07,0xc1,0x9e,0x03,0xe0,0x00,0x00,0x02,0x00,0x0e,0x20,0x00,0x00,0x00,0x00,0x00,
+0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x03,0x80,0x00,0x00,0x00,0xc0,0x00,0x00,0x18,0x00,0x00,0x08,0x08,0x00,0x00,
+0x00,0x01,0x87,0xc3,0x03,0xe0,0xe1,0xf0,0xf8,0x3e,0x33,0x08,0x3e,0x1e,0x00,0x00,
+0x00,0x01,0x86,0x03,0x03,0x01,0xb0,0xe0,0xdc,0x66,0x3b,0x08,0x66,0x32,0x00,0x00,
+0x00,0x00,0x87,0xc3,0x03,0xe1,0x80,0x40,0xd8,0x63,0x3b,0x08,0x60,0x3c,0x00,0x00,
+0x00,0x00,0x87,0x83,0x03,0xc1,0x80,0x40,0xf8,0x63,0x3f,0x08,0x60,0x0e,0x00,0x00,
+0x00,0x00,0x06,0x03,0x03,0x01,0xb0,0x40,0xd8,0x66,0x37,0x08,0x66,0x32,0x00,0x00,
+0x00,0x00,0x07,0xc3,0xe3,0xe0,0xe0,0x40,0xc8,0x3e,0x33,0x08,0x3e,0x3e,0x00,0x00,
+0x00,0x00,0x07,0xc3,0xe3,0xe0,0xe0,0x40,0x88,0x3c,0x33,0x08,0x3c,0x1e,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+class LCDShield
+{
+private:
+    void LCDCommand(unsigned char data);
+    void LCDData(unsigned char data);
+    uint8_t driver;
+    uint16_t swapColors(uint16_t in);
+public:
+    LCDShield();
+
+    void init(int type, bool colorSwap = 0);
+    void clear(int color);
+    void contrast(char setting);
+
+    void setPixel(int color, unsigned char x, unsigned char y);
+    void setCircle (int x0, int y0, int radius, int color, int lineThickness = 1);
+    void setArc(int x0, int y0, int radius, int segments[], int numSegments, int lineThickness, int color);
+
+    void setChar(char c, int x, int y, int fColor, int bColor);
+    void setStr(char *pString, int x, int y, int fColor, int bColor);
+    
+
+    void setLine(int x0, int y0, int x1, int y1, int color);
+    void setRect(int x0, int y0, int x1, int y1, unsigned char fill, int color);
+
+    void printLogo(void);
+
+    void on(void);
+    void off(void);
+};
+
+#endif  // ColorLCDShield_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Jul 12 10:27:13 2014 +0000
@@ -0,0 +1,187 @@
+/* Reloj en Color LCD Shield Sparkfun desde Jim Lindblom fecha: 3-2014 */
+#include "mbed.h"  
+#include <ColorLCDShield.h>
+
+#define HOURS 03
+#define MINUTES 00
+#define SECONDS 00
+#define AMPM 0  // enter 0 for AM, 1 for PM
+#define CLOCK_RADIUS 50 // radio de la circunferencia de reloj
+#define CLOCK_CENTER 55 // Ajusta del radio, igual es necesario reajustar
+#define H_LENGTH  30    // length of hour hand
+#define M_LENGTH 40     // length of minute hand
+#define S_LENGTH 48     // length of second hand
+#define BACKGROUND BLACK  // room for growth, adjusta color de fondo segun luz de dia
+#define C_COLOR RED     // This is the color of the clock face, and digital clock
+#define H_COLOR BLUE    // color de las horas
+#define M_COLOR GREEN   // color de los minutos
+#define S_COLOR YELLOW  // color de los segundos
+
+LCDShield lcd;
+DigitalIn buttonPin3(PTA12);
+DigitalIn buttonPin4(PTA4);
+DigitalIn buttonPin5(PTA5);
+DigitalOut g(LED_GREEN);
+
+Ticker reloj;
+int hours, minutes, seconds, ampm;
+
+void drawClock() {
+/* drawClock() dibuja el circulo del reloj con las cifras 12,3,6 y 9 */
+
+  lcd.setCircle(CLOCK_CENTER, 66, CLOCK_RADIUS, C_COLOR); // pinta circulo
+
+  lcd.setStr("12", CLOCK_CENTER - CLOCK_RADIUS, 66-9, C_COLOR, BACKGROUND);
+  lcd.setStr("3", CLOCK_CENTER - 9, 66 + CLOCK_RADIUS - 12, C_COLOR, BACKGROUND);
+  lcd.setStr("6", CLOCK_CENTER + CLOCK_RADIUS - 18, 66-4, C_COLOR, BACKGROUND);
+  lcd.setStr("9", CLOCK_CENTER - 9, 66 - CLOCK_RADIUS + 4, C_COLOR, BACKGROUND);
+}
+
+void displayAnalogTime(int h, int m, int s) {
+ /* displayAnalogTime() dibuja hhmmss en su posicion correspondiente */
+  double midHours;  // this will be used to slightly adjust the hour hand
+  static int hx, hy, mx, my, sx, sy;
+  
+  /* Adjusta el tiempo para mostrar 90 grados ccw y gira en el reloj el texto */
+  h -= 3;
+  m -= 15;
+  s -= 15;
+  if (h <= 0) h += 12;
+  if (m < 0)  m += 60;
+  if (s < 0)  s += 60;
+    
+  /* Borra lineas anteriores */
+  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, BACKGROUND);  // borra segundos
+  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, BACKGROUND);  // borra minutos
+  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, BACKGROUND);  // borra horas
+  
+  /* Calcula y dibuja nuevas lineas */
+  //s = map(s, 0, 60, 0, 360);  // ajusta de 0-60, a "360 degrees"
+  s = (s-0)*(360-0)/(60-0)+360;
+  sx = S_LENGTH * sin(3.14 * ((double) s)/180);  // woo trig!
+  sy = S_LENGTH * cos(3.14 * ((double) s)/180);  // woo trig!
+  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, S_COLOR);  // print second hand
+  
+  //m = map(m, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
+  m = (m-0)*(360-0)/(60-0)+360;
+  mx = M_LENGTH * sin(3.14 * ((double) m)/180);  // woo trig!
+  my = M_LENGTH * cos(3.14 * ((double) m)/180);  // woo trig!
+  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, M_COLOR);  // print minute hand
+  
+  midHours = minutes/12;  // midHours is used to set the hours hand to middling levels between whole hours
+  h *= 5;           // Get hours and midhours to the same scale
+  h += midHours;    // add hours and midhours
+  
+  //h = map(h, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
+  h = (h-0)*(360-0)/(60-0)+360;
+  hx = H_LENGTH * sin(3.14 * ((double) h)/180);  // woo trig!
+  hy = H_LENGTH * cos(3.14 * ((double) h)/180);  // woo trig!
+  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, H_COLOR);  // print hour hand
+}
+
+void displayDigitalTime(int h, int m, int s, int ap) {
+/* displayDigitalTime() muestra hh:mm:ss am/pm en parte inferior */
+  char timeChar[11] = {'x','x',0x0A,'x','x',0x0A,'x','x',' ',' ',' '};
+  
+  /* Convierte los valores */
+  timeChar[0] = h/10;
+  timeChar[1] = h - (timeChar[0] * 10);
+  timeChar[3] = m/10;
+  timeChar[4] = m - (timeChar[3] * 10);
+  timeChar[6] = s/10;
+  timeChar[7] = s - (timeChar[6] * 10);
+  
+  /* once we have each integer separated, we need to turn them
+     into displayable characters. Adding 0x30 does this (check an
+     ASCII table. We set the colons to 0x0A initially, this will
+     turn them into the proper 0x3A.*/
+  for (int i=0; i<8; i++) timeChar[i] += 0x30;
+  timeChar[8] = ' ';  // add a space between the time and AM/PM
+  
+  /* Add AM or PM to the end of the timeChar string */
+  if (!ap) {
+    timeChar[9] = 'A';
+    timeChar[10] = 'M';
+  }
+  else {
+    timeChar[9] = 'P';
+    timeChar[10] = 'M';
+  }
+  
+  /* añade espacios despues hora, otherwise it'll display unwanted characters */
+  //timeChar[11] = ' ';
+  //timeChar[12] = ' ';
+    
+  /* Print the time on the clock */
+  for (int i=0; i<12; i++) {
+    lcd.setChar(timeChar[i], CLOCK_CENTER + CLOCK_RADIUS + 16, 22+8*i, C_COLOR, BACKGROUND);
+  }
+  lcd.setStr("    ", CLOCK_CENTER + CLOCK_RADIUS + 16, 118, C_COLOR, BACKGROUND);
+}
+
+void setTime() {
+  /* setTime Incrementa con S1 horas, S2 segundos y S3 para salir */ 
+  /* Pone el reloj a 12 horas */
+  lcd.setStr("Ajusta el reloj", 20, 1, C_COLOR, BACKGROUND);
+  lcd.setStr("S1 para horas  ", 40, 1, H_COLOR, BACKGROUND);
+  lcd.setStr("S2 para minutos", 60, 1, M_COLOR, BACKGROUND);
+  lcd.setStr("S3 para salir  ", 80, 1, S_COLOR, BACKGROUND);
+  seconds = 0;
+  minutes = 0;
+  hours = 12;
+  ampm = 0;
+  displayDigitalTime(hours, minutes, seconds, ampm);
+  wait_ms(100);
+
+  /* Mientras no pulses S3 sigues ajustando el reloj */
+  while(buttonPin5) {
+    /* Si pulsas S1 ajustar horas */
+    if (!buttonPin3) {
+      hours++;  // Increase hours by 1
+      if (hours == 12) ampm ^= 1;  // Flip am/pm if it's 12 o'clock
+      if (hours >= 13) hours = 1;  // Set hours to 1 if it's 13. 12-hour clock.
+    }
+    /* Si pulsas S2 ajustar minutos*/
+    if (!buttonPin4) {
+      minutes++;  // Increase minutes by 1
+      if (minutes >= 60) minutes = 0;  // If minutes is 60, set it back to 0
+    }
+    /* and update the clock, so we can see it */ 
+    displayDigitalTime(hours, minutes, seconds, ampm);
+    wait_ms(100);
+  }
+}
+
+void cadasegundo(){
+  /* cada segundo recalcula y redibuja agujas y reloj */
+  g = !g;
+  if (seconds >= 60) {
+    seconds = 0;  // Al llegar a 60 vuelve a 0
+    minutes++;    // e incrementa los minutos
+    if (minutes >= 60) {
+        minutes = 0;  // Al llegar a 60 vuelve a 0
+        hours++;      // e incrementa las horas
+        if (hours == 12) ampm ^= 1;  // Si llega a 12 o'clock, alterna ampm
+        if (hours >= 13) hours = 1;  // Si llega a 13, vuelve a 1.
+    }
+  }
+  drawClock();
+  displayAnalogTime(hours, minutes, seconds);
+  displayDigitalTime(hours, minutes, seconds, ampm);
+  seconds++;
+}
+    
+int main() {
+  hours = HOURS;
+  minutes = MINUTES;
+  seconds = SECONDS;
+  ampm = AMPM;
+  lcd.init(PHILLIPS);
+  lcd.contrast(50);
+  lcd.clear(BACKGROUND);
+  setTime();
+  lcd.clear(BACKGROUND);
+  reloj.attach(&cadasegundo,1.0); // Cada segundo pinta y actualiza el reloj */
+  
+  while(1) {}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Jul 12 10:27:13 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/8e73be2a2ac1
\ No newline at end of file