Single Photo displayed on LPC4088

Dependencies:   DMBasicGUI DMSupport

Revision:
0:9140ec6aa604
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/easyGUIFixed/GuiDisplay.c	Fri Jul 28 14:19:12 2017 +0000
@@ -0,0 +1,742 @@
+/* ************************************************************************ */
+/*                                                                          */
+/*                     (C)2004-2014 IBIS Solutions ApS                      */
+/*                            sales@easyGUI.com                             */
+/*                             www.easyGUI.com                              */
+/*                                                                          */
+/*                       easyGUI display driver unit                        */
+/*                               v6.0.23.002                                */
+/*                                                                          */
+/* ************************************************************************ */
+
+#include "GuiConst.h"
+#include "GuiDisplay.h"
+#include "GuiLib.h"
+#include <stdlib.h>
+
+#define WANT_DOUBLE_BUFFERING // Also in GuiGraph16.h, GuiLib.c - *** all three must match ***
+
+#define USE_WAIT_MS
+#ifdef USE_WAIT_MS
+extern void EasyGUIWaitMs(GuiConst_INT32U msec); // in main.cpp
+#endif
+
+extern void SetupQSPIBitmapArray(int stageNumber); // In main.cpp
+
+// Make FRAME_ADDRESS able to be set at runtime, not hardcoded
+static unsigned long frameAddress = 0L;
+// Global function (actually called from the main function, in main.cpp) 
+// to set the frame address at startup
+void GuiDisplay_SetFrameAddress(void *newFrameAddress)
+{
+    // C/C++ is not happy copying a pointer value direct to an unsigned long
+    union {
+        void *ptrValue;
+        unsigned long ulValue;
+    } frameAddressUnion;
+    
+    frameAddressUnion.ptrValue = newFrameAddress;
+    
+    frameAddress = frameAddressUnion.ulValue;
+}
+
+// Select LCD controller type by removing double slashes
+//
+// Many of the drivers listed here supports more than one display controller.
+// To find your driver simply make a text search in this file. Omit eventual
+// letters after the display controller type number. Example: For an NJU6450A
+// display controller make a search for "NJU6450" - make sure it is a plain
+// text search, not a word search.
+//
+// If your display controller is not found you can contact support at
+// sales@ibissolutions.com. We will then quickly supply a driver for it.
+//
+// You only need to use the relevant display driver, all others may be deleted.
+// Make a copy of this file before modifying it.
+//
+// -----------------------------------------------------------------------------
+// #define LCD_CONTROLLER_TYPE_AT32AP7000
+// #define LCD_CONTROLLER_TYPE_AT91RM9200_ST7565
+// #define LCD_CONTROLLER_TYPE_AT91SAM9263
+// #define LCD_CONTROLLER_TYPE_BVGP
+// #define LCD_CONTROLLER_TYPE_D51E5TA7601
+// #define LCD_CONTROLLER_TYPE_F5529
+// #define LCD_CONTROLLER_TYPE_FLEVIPER
+// #define LCD_CONTROLLER_TYPE_FSA506
+// #define LCD_CONTROLLER_TYPE_H8S2378
+// #define LCD_CONTROLLER_TYPE_HD61202_2H
+// #define LCD_CONTROLLER_TYPE_HD61202_4H
+// #define LCD_CONTROLLER_TYPE_HD61202_2H2V
+// #define LCD_CONTROLLER_TYPE_HX8238_AT32AP7000
+// #define LCD_CONTROLLER_TYPE_HX8238_TMP92CH21
+// #define LCD_CONTROLLER_TYPE_HX8312
+// #define LCD_CONTROLLER_TYPE_HX8345
+// #define LCD_CONTROLLER_TYPE_HX8346
+// #define LCD_CONTROLLER_TYPE_HX8347
+// #define LCD_CONTROLLER_TYPE_HX8347G
+// #define LCD_CONTROLLER_TYPE_HX8352A
+// #define LCD_CONTROLLER_TYPE_ILI9341
+// #define LCD_CONTROLLER_TYPE_K70
+// #define LCD_CONTROLLER_TYPE_LC7981
+// #define LCD_CONTROLLER_TYPE_LS027
+// #define LCD_CONTROLLER_TYPE_LS044
+// #define LCD_CONTROLLER_TYPE_LH155BA
+// #define LCD_CONTROLLER_TYPE_LH75401
+// #define LCD_CONTROLLER_TYPE_LH7A400
+// #define LCD_CONTROLLER_TYPE_LPC1788
+// #define LCD_CONTROLLER_TYPE_LPC1850
+// #define LCD_CONTROLLER_TYPE_LPC2478
+// #define LCD_CONTROLLER_TYPE_LPC3230
+#define LCD_CONTROLLER_TYPE_LPC408X
+// #define LCD_CONTROLLER_TYPE_MPC5606S
+// #define LCD_CONTROLLER_TYPE_MX257
+// #define LCD_CONTROLLER_TYPE_NJU6450A
+// #define LCD_CONTROLLER_TYPE_NT39016D
+// #define LCD_CONTROLLER_TYPE_NT75451
+// #define LCD_CONTROLLER_TYPE_OTM2201A
+// #define LCD_CONTROLLER_TYPE_PCF8548
+// #define LCD_CONTROLLER_TYPE_PCF8813
+// #define LCD_CONTROLLER_TYPE_PIC24FJ256
+// #define LCD_CONTROLLER_TYPE_PXA320
+// #define LCD_CONTROLLER_TYPE_R61509
+// #define LCD_CONTROLLER_TYPE_R61526
+// #define LCD_CONTROLLER_TYPE_R61580
+// #define LCD_CONTROLLER_TYPE_RA8822
+// #define LCD_CONTROLLER_TYPE_RA8875
+// #define LCD_CONTROLLER_TYPE_S1D13505
+// #define LCD_CONTROLLER_TYPE_S1D13506
+// #define LCD_CONTROLLER_TYPE_S1D13700
+// #define LCD_CONTROLLER_TYPE_S1D13705
+// #define LCD_CONTROLLER_TYPE_S1D13706
+// #define LCD_CONTROLLER_TYPE_S1D13715
+// #define LCD_CONTROLLER_TYPE_S1D13743
+// #define LCD_CONTROLLER_TYPE_S1D13748
+// #define LCD_CONTROLLER_TYPE_S1D13781
+// #define LCD_CONTROLLER_TYPE_S1D13781_DIRECT
+// #define LCD_CONTROLLER_TYPE_S1D13A04
+// #define LCD_CONTROLLER_TYPE_S1D13A05
+// #define LCD_CONTROLLER_TYPE_S1D15721
+// #define LCD_CONTROLLER_TYPE_S6B0741
+// #define LCD_CONTROLLER_TYPE_S6B33BL
+// #define LCD_CONTROLLER_TYPE_S6D0139
+// #define LCD_CONTROLLER_TYPE_S6E63D6
+// #define LCD_CONTROLLER_TYPE_SBN1661_2H_SBN0080
+// #define LCD_CONTROLLER_TYPE_SED1335
+// #define LCD_CONTROLLER_TYPE_SEPS525
+// #define LCD_CONTROLLER_TYPE_SH1101A
+// #define LCD_CONTROLLER_TYPE_SH1123
+// #define LCD_CONTROLLER_TYPE_SPFD5408
+// #define LCD_CONTROLLER_TYPE_SPLC502
+// #define LCD_CONTROLLER_TYPE_SSD0323
+// #define LCD_CONTROLLER_TYPE_SSD1289
+// #define LCD_CONTROLLER_TYPE_SSD1305
+// #define LCD_CONTROLLER_TYPE_SSD1322
+// #define LCD_CONTROLLER_TYPE_SSD1339
+// #define LCD_CONTROLLER_TYPE_SSD1815
+// #define LCD_CONTROLLER_TYPE_SSD1815_2H
+// #define LCD_CONTROLLER_TYPE_SSD1848
+// #define LCD_CONTROLLER_TYPE_SSD1858
+// #define LCD_CONTROLLER_TYPE_SSD1926
+// #define LCD_CONTROLLER_TYPE_SSD1963
+// #define LCD_CONTROLLER_TYPE_SSD2119
+// #define LCD_CONTROLLER_TYPE_ST7529
+// #define LCD_CONTROLLER_TYPE_ST7541
+// #define LCD_CONTROLLER_TYPE_ST7561
+// #define LCD_CONTROLLER_TYPE_ST7565
+// #define LCD_CONTROLLER_TYPE_ST7586
+// #define LCD_CONTROLLER_TYPE_ST7637
+// #define LCD_CONTROLLER_TYPE_ST7715
+// #define LCD_CONTROLLER_TYPE_ST7920
+// #define LCD_CONTROLLER_TYPE_STM32F429
+// #define LCD_CONTROLLER_TYPE_T6963
+// #define LCD_CONTROLLER_TYPE_TLS8201
+// #define LCD_CONTROLLER_TYPE_TMPA900
+// #define LCD_CONTROLLER_TYPE_TS7390
+// #define LCD_CONTROLLER_TYPE_UC1608
+// #define LCD_CONTROLLER_TYPE_UC1610
+// #define LCD_CONTROLLER_TYPE_UC1611
+// #define LCD_CONTROLLER_TYPE_UC1617
+// #define LCD_CONTROLLER_TYPE_UC1698
+// #define LCD_CONTROLLER_TYPE_UPD161607
+// #define LCD_CONTROLLER_TYPE_UC1701
+
+// ============================================================================
+//
+// COMMON PART - NOT DEPENDENT ON DISPLAY CONTROLLER TYPE
+//
+// Do not delete this part of the GuiDisplay.c file.
+//
+// If your operating system uses pre-emptive execution, i.e. it interrupts tasks
+// at random instances, and transfers control to other tasks, display writing
+// must be protected from this, by writing code for the two protection
+// functions:
+//
+//   o  GuiDisplay_Lock     Prevent the OS from switching tasks
+//   o  GuiDisplay_Unlock   Open up normal task execution again
+//
+// If your operating system does not use pre-emptive execution, i.e. if you
+// must specifically release control in one tasks in order for other tasks to
+// be serviced, or if you don't employ an operating system at all, you can just
+// leave the two protection functions empty. Failing to write proper code for
+// the protection functions will result in a system with unpredictable
+// behavior.
+//
+// ============================================================================
+
+void GuiDisplay_Lock (void)
+{
+}
+
+void GuiDisplay_Unlock (void)
+{
+}
+
+// ============================================================================
+//
+// DISPLAY DRIVER PART
+//
+// You only need to use the relevant display driver, all others may be deleted.
+// Modify the driver so that it fits your specific hardware.
+// Make a copy of this file before modifying it.
+//
+// ============================================================================
+
+#ifdef LCD_CONTROLLER_TYPE_LPC408X
+
+// ============================================================================
+//
+// LPC408x MICROCONTROLLER WITH BUILT-IN DISPLAY CONTROLLER
+//
+// This driver uses internal LCD controller of LPC408x microcontroller.
+// LCD driver of LPC408x in 24 bit RGB parallel interface for TFT type
+// display or 4bit parallel interface for STN type display.
+// Graphic modes up to 1024x768 pixels.
+//
+// Compatible display controllers:
+//   None
+//
+// easyGUI setup should be (Parameters window, Display controller tab page):
+//   Horizontal bytes
+//   Bit 0 at right
+//   Number of color planes: 1
+//   Color mode: Grayscale, palette or RGB
+//   Color depth: 1 bit (B/W), 8 bits, 16 bits, 24 bits
+//   Display orientation: Normal, Upside down, 90 degrees left, 90 degrees right
+//   Display words with reversed bytes: Off
+//   Number of display controllers, horizontally: 1
+//   Number of display controllers, vertically: 1
+//
+// Port addresses (Px.x) must be altered to correspond to your microcontroller
+// hardware and compiler syntax.
+//
+// ============================================================================
+
+// Hardware connection for TFT display
+// LPC408x                        generic TFT display
+// LCD_FP               -         VSYNC
+// LCD_LP               -         HSYNC
+// LCD_LE               -         Line End
+// LCD_DCLK             -         Pixel CLK
+// LCD_ENAB_M           -         DATA_ENABLE
+// LCD_VD[0-7]          -         R0-R7 (for 16bit RGB mode connect R0,R1,R2 to 0)
+// LCD_VD[8-15]         -         G0-G7 (for 16bit RGB mode connect G0,G1 to 0)
+// LCD_VD[16-23]        -         B0-B7 (for 16bit RGB mode connect B0,B1,B2 to 0)
+
+// Hardware connection for STN display
+// LCD_PWR              -         DISP
+// LCD_DCLK             -         CL2
+// LCD_FP               -         Frame Pulse
+// LCD_LP               -         Line Sync Pulse
+// LCD_LE               -         Line End
+// LCD_VD[3:0]          -         UD[3:0]
+
+// Power Control registers
+#define PCONP          (*(volatile unsigned long *)0x400FC0C4)
+// LCD controller power control bit
+#define PCLCD          0
+
+// Pin setup registers (IOCON)
+#define IOCON_P0_4         (*(volatile unsigned long *)0x4002C010)
+#define IOCON_P0_5         (*(volatile unsigned long *)0x4002C014)
+#define IOCON_P0_6         (*(volatile unsigned long *)0x4002C018)
+#define IOCON_P0_7         (*(volatile unsigned long *)0x4002C01C)
+#define IOCON_P0_8         (*(volatile unsigned long *)0x4002C020)
+#define IOCON_P0_9         (*(volatile unsigned long *)0x4002C024)
+#define IOCON_P1_20        (*(volatile unsigned long *)0x4002C0D0)
+#define IOCON_P1_21        (*(volatile unsigned long *)0x4002C0D4)
+#define IOCON_P1_22        (*(volatile unsigned long *)0x4002C0D8)
+#define IOCON_P1_23        (*(volatile unsigned long *)0x4002C0DC)
+#define IOCON_P1_24        (*(volatile unsigned long *)0x4002C0E0)
+#define IOCON_P1_25        (*(volatile unsigned long *)0x4002C0E4)
+#define IOCON_P1_26        (*(volatile unsigned long *)0x4002C0E8)
+#define IOCON_P1_27        (*(volatile unsigned long *)0x4002C0EC)
+#define IOCON_P1_28        (*(volatile unsigned long *)0x4002C0F0)
+#define IOCON_P1_29        (*(volatile unsigned long *)0x4002C0F4)
+#define IOCON_P2_0         (*(volatile unsigned long *)0x4002C100)
+#define IOCON_P2_1         (*(volatile unsigned long *)0x4002C104)
+#define IOCON_P2_2         (*(volatile unsigned long *)0x4002C108)
+#define IOCON_P2_3         (*(volatile unsigned long *)0x4002C10C)
+#define IOCON_P2_4         (*(volatile unsigned long *)0x4002C110)
+#define IOCON_P2_5         (*(volatile unsigned long *)0x4002C114)
+#define IOCON_P2_6         (*(volatile unsigned long *)0x4002C118)
+#define IOCON_P2_7         (*(volatile unsigned long *)0x4002C11C)
+#define IOCON_P2_8         (*(volatile unsigned long *)0x4002C120)
+#define IOCON_P2_9         (*(volatile unsigned long *)0x4002C124)
+#define IOCON_P2_11        (*(volatile unsigned long *)0x4002C12C)
+#define IOCON_P2_12        (*(volatile unsigned long *)0x4002C130)
+#define IOCON_P2_13        (*(volatile unsigned long *)0x4002C134)
+#define IOCON_P4_28        (*(volatile unsigned long *)0x4002C270)
+#define IOCON_P4_29        (*(volatile unsigned long *)0x4002C274)
+
+// LCD Port Enable
+#define LCDPE           1
+
+// LCD controller registers
+// LCD configuration register
+#define LCD_CFG         (*(volatile unsigned long *)0x400FC1B8)
+
+// LCD Controller Base Address
+#define LCD_BASE       0x20088000
+
+// Horizontal Timing Control
+#define LCD_TIMH       (*(volatile unsigned long *)(LCD_BASE+0x000))
+// Vertical Timing Control
+#define LCD_TIMV       (*(volatile unsigned long *)(LCD_BASE+0x004))
+// Clock and Signal Polarity Control register
+#define LCD_POL        (*(volatile unsigned long *)(LCD_BASE+0x008))
+// Line End Control register
+#define LCD_LE         (*(volatile unsigned long *)(LCD_BASE+0x00C))
+// Upper Panel Frame Base Address register
+#define LCD_UPBASE     (*(volatile unsigned long *)(LCD_BASE+0x010))
+// Lower Panel Frame Base Address register
+#define LCD_LPBASE     (*(volatile unsigned long *)(LCD_BASE+0x014))
+// LCD Control register
+#define LCD_CTRL       (*(volatile unsigned long *)(LCD_BASE+0x018))
+// Interrupt Mask register
+#define LCD_INTMSK     (*(volatile unsigned long *)(LCD_BASE+0x01C))
+// Raw Interrupt Status register
+#define LCD_INTRAW     (*(volatile unsigned long *)(LCD_BASE+0x020))
+// Masked Interrupt Status register
+#define LCD_INTSTAT    (*(volatile unsigned long *)(LCD_BASE+0x024))
+// Interrupt Clear register
+#define LCD_INTCLR     (*(volatile unsigned long *)(LCD_BASE+0x028))
+// Upper Panel Current Address Value register
+#define LCD_UPCURR     (*(volatile unsigned long *)(LCD_BASE+0x02C))
+// Lower Panel Current Address Value register
+#define LCD_LPCURR     (*(volatile unsigned long *)(LCD_BASE+0x030))
+// 256x16-bit Color Palette registers
+#define LCD_PAL        (*(volatile unsigned long *)(LCD_BASE+0x200))
+// Cursor Image registers
+#define CRSR_IMG       (*(volatile unsigned long *)(LCD_BASE+0x800))
+// Cursor Control register
+#define CRSR_CTRL      (*(volatile unsigned long *)(LCD_BASE+0xC00))
+
+// LCD controller enable bit
+#define LCDEN          0
+// LCD controller power bit
+#define LCDPWR         11
+// Bypass pixel clock divider - for TFT display must be 1
+#ifdef GuiConst_COLOR_DEPTH_1
+#define BCD            0
+#else
+#define BCD            1
+#endif
+// Adjust these values according your display
+// PLL clock prescaler selection - only odd numbers 0,1,3,5,..255
+// 0 - PLL/1, 1 - PLL/2, 3 - PLL/4
+#define PLLDIV         0
+// LCD panel clock prescaler selection,  range 0 - 31
+// LCD freq = MCU freq /(CLKDIV+1)
+#define CLKDIV         7
+// Horizontal back porch in pixels, range 3 - 256
+#ifdef GuiConst_COLOR_DEPTH_1
+#define HBP            5
+#else
+#define HBP            40
+#endif
+// Horizontal front porch in pixels, range 3 - 256
+#ifdef GuiConst_COLOR_DEPTH_1
+#define HFP            5
+#else
+#define HFP            79
+#endif
+// Horizontal synchronization pulse width in pixels, range 3 - 256
+#ifdef GuiConst_COLOR_DEPTH_1
+#define HSW            3
+#else
+#define HSW            48
+#endif
+// Pixels-per-line in pixels, must be multiple of 16
+#define PPL            GuiConst_DISPLAY_WIDTH_HW
+// Vertical back porch in lines, range 1 - 256
+#ifdef GuiConst_COLOR_DEPTH_1
+#define VBP            2
+#else
+#define VBP            29
+#endif
+// Vertical front porch in lines, range 1 - 256
+#ifdef GuiConst_COLOR_DEPTH_1
+#define VFP            2
+#else
+#define VFP            40
+#endif
+// Vertical synchronization pulse width in lines, range 1 - 31
+#ifdef GuiConst_COLOR_DEPTH_1
+#define VSW            1
+#else
+#define VSW            3
+#endif
+// Lines per panel
+#define LPP            GuiConst_BYTE_LINES
+// Clocks per line
+#ifdef GuiConst_COLOR_DEPTH_1
+#define CPL            GuiConst_DISPLAY_WIDTH_HW/4
+#else
+#define CPL            GuiConst_DISPLAY_WIDTH_HW
+#endif
+// Invert output enable
+// 0 = LCDENAB output pin is active HIGH in TFT mode
+// 1 = LCDENAB output pin is active LOW in TFT mode
+#define IOE            0
+// Invert panel clock
+// 0 = Data is driven on the LCD data lines on the rising edge of LCDDCLK
+// 1 = Data is driven on the LCD data lines on the falling edge of LCDDCLK
+#define IPC            0
+// Invert horizontal synchronization
+// 0 = LCDLP pin is active HIGH and inactive LOW
+// 1 = LCDLP pin is active LOW and inactive HIGH
+#ifdef GuiConst_COLOR_DEPTH_1
+#define IHS            0
+#else
+#define IHS            1
+#endif
+// IVS Invert vertical synchronization
+// 0 = LCDFP pin is active HIGH and inactive LOW
+// 1 = LCDFP pin is active LOW and inactive HIGH
+#ifdef GuiConst_COLOR_DEPTH_1
+#define IVS            0
+#else
+#define IVS            1
+#endif
+// Lower five bits of panel clock divisor
+#define PCD_LO         2
+// CLKSEL Clock Select
+// 0 = the clock source for the LCD block is CCLK
+// 1 = the clock source for the LCD block is LCD_DCLK
+#define CLKSEL         0
+
+/****************************************************************************/
+/* IMPORTANT!!!                                                             */
+/****************************************************************************/
+// Set start address of frame buffer in RAM memory
+// 0x4000 0000 - 0x4000 FFFF RAM (64 kB)
+// 0x8000 0000 - 0x80FF FFFF Static memory bank 0 (16 MB)
+// 0x8100 0000 - 0x81FF FFFF Static memory bank 1 (16 MB)
+// 0xA000 0000 - 0xAFFF FFFF Dynamic memory bank 0 (256 MB)
+// 0xB000 0000 - 0xBFFF FFFF Dynamic memory bank 1 (256 MB)
+//#define FRAME_ADDRESS  0xA0000008
+//#define FRAME_ADDRESS  0xA00017D8 // As of 26 Oct 2016
+#define FRAME_ADDRESS (frameAddress) // Use the static variable set at the top of this file
+/****************************************************************************/
+
+// Address of pallete registers
+#define PALETTE_RAM_ADDR LCD_PAL
+
+// Delay routine
+// This constant must be adjusted according to speed of microcontroller
+#define ONE_MS               100
+// Param msec is delay in miliseconds
+void millisecond_delay(GuiConst_INT32U msec)
+{
+#ifdef USE_WAIT_MS
+  EasyGUIWaitMs(msec);
+#else
+  GuiConst_INT32U j;
+
+  for (j = 0; j < (ONE_MS * msec) ; j++);
+#endif
+}
+
+// Initialises the module and the display
+void GuiDisplay_Init (void)
+{
+//  return; // Test - do we need any display initialisation here? Let the BIOS do it?
+          // No flickering - but red and blue reversed (again)
+// So - can we reinstate some of the code in this function, and get the red and blue 
+// the correct way round without flickering?
+//#define ALLOW_LPC4088_INIT
+// Now allowing initialisation of the LCD control register even with ALLOW_LPC4088_INIT not #defined.
+// This appears to have eliminated the flickering while keeping the red and blue components 
+// the correct way round.
+  
+  GuiConst_INT32U i;
+#ifdef GuiConst_COLOR_DEPTH_24
+  GuiConst_INT32U *framePtr;
+#else
+#ifdef GuiConst_COLOR_DEPTH_16
+  GuiConst_INT16U *framePtr;
+#else
+  GuiConst_INT32U PaletteData;
+  GuiConst_INT8U *framePtr;
+  GuiConst_INT32U * pDst;
+#endif
+#endif
+
+//  SetupQSPIBitmapArray(1);
+
+/**************************************************/
+/* Carefully adjust the IO pins for your system   */
+/* Following settings for TFT panel 16/24 bit     */
+/**************************************************/
+
+/* *** DEBUG *** COMMENT OUT THIS BLOCK OF CODE - WHAT HAPPENS?
+// PI         SETTING     RGB888      RGB565
+  IOCON_P1_29  |= 7;   // BLUE7       BLUE4
+  IOCON_P1_28  |= 7;   // BLUE6       BLUE3
+  IOCON_P1_27  |= 7;   // BLUE5       BLUE2
+  IOCON_P1_26  |= 7;   // BLUE4       BLUE1
+  IOCON_P2_13  |= 7;   // BLUE3       BLUE0
+  //IOCON_P2_12  |= 7;   // BLUE2       -       !! Comment out for RGB565
+  //IOCON_P0_9   |= 7;   // BLUE1       -       !! Comment out for RGB565
+  //IOCON_P0_8   |= 7;   // BLUE0       -       !! Comment out for RGB565
+  IOCON_P1_25  |= 7;   // GREEN7      GREEN5
+  IOCON_P1_24  |= 7;   // GREEN6      GREEN4
+  IOCON_P1_23  |= 7;   // GREEN5      GREEN3
+  IOCON_P1_22  |= 7;   // GREEN4      GREEN2
+  IOCON_P1_21  |= 7;   // GREEN3      GREEN1
+  IOCON_P1_20  |= 7;   // GREEN2      GREEN0
+  //IOCON_P0_7   |= 7;   // GREEN1      -       !! Comment out for RGB565
+  //IOCON_P0_6   |= 7;   // GREEN0      -       !! Comment out for RGB565
+  IOCON_P2_9   |= 7;   // RED7        RED4
+  IOCON_P2_8   |= 7;   // RED6        RED3
+  IOCON_P2_7   |= 7;   // RED5        RED2
+  IOCON_P2_6   |= 7;   // RED4        RED1
+  //IOCON_P4_29  |= 7;   // RED3        -       !! Comment out for RGB565
+  IOCON_P2_12  |= 5;   // -           RED0  !! Comment out for RGB888 !!
+  //IOCON_P4_28  |= 7;   // RED2        -       !! Comment out for RGB565
+  //IOCON_P0_5   |= 7;   // RED1        -       !! Comment out for RGB565
+  //IOCON_P0_4   |= 7;   // RED0        -       !! Comment out for RGB565
+  IOCON_P2_5   |= 7;   // LCD_LP      LCD_LP
+  IOCON_P2_4   |= 7;   // LCD_ENAB_M  LCD_ENAB_M
+  IOCON_P2_3   |= 7;   // LCD_FP      LCD_FP
+  IOCON_P2_2   |= 7;   // LCD_DCLK    LCD_DCLK
+  IOCON_P2_1   |= 7;   // LCD_LE      LCD_LE
+  IOCON_P2_0   |= 7;   // LCD_PWR     LCD_PWR
+  IOCON_P2_11  |= 7;   // LCD_CLKIN   LCD_CLKIN
+*/ // DEBUG - ANSWER - *** EVERYTHING STILL APPEARS TO WORK ***
+
+/**************************************************/
+
+//  SetupQSPIBitmapArray(2);
+  
+#ifdef ALLOW_LPC4088_INIT
+  // Disable power
+  LCD_CTRL &= ~(1 << LCDEN);
+  millisecond_delay(100);
+  LCD_CTRL &= ~(1 << LCDPWR);
+  
+  // ====================================
+  // Initialize Clock(PLL),EMC and SDRAM!
+  // ====================================
+
+  // Enable LCD controller
+  PCONP |= 1<<PCLCD;
+
+  // LCD Configuration init pixel clock
+  LCD_CFG |= (CLKDIV);
+
+  // Horizontal Timing register
+  LCD_TIMH |= ((HBP-1) << 24)|((HFP-1) << 16)|((HSW-1) << 8)|((PPL/16-1) << 2);
+
+  // Vertical Timing register
+  LCD_TIMV |= (VBP << 24)|(VFP << 16)|((VSW-1) << 10)|(LPP-1);
+
+  // Clock and Signal Polarity register
+  LCD_POL |= (BCD << 26)|((CPL-1) << 16)|(IOE << 14)|(IPC << 13)|
+             (IHS << 12)|(IVS << 11)|(CLKSEL << 5)| PCD_LO;
+
+  LCD_LE = 0;
+  LCD_INTMSK = 0;
+
+#endif // ALLOW_LPC4088_INIT
+// If we include the initialisation of the LCD control register,
+// does this get red and blue the correct way round without flickering?
+
+  // LCD Control register
+#ifdef GuiConst_COLOR_DEPTH_24
+  // TFT single panel,24bit, normal output
+  LCD_CTRL = 0x0000002A;
+#else
+#ifdef GuiConst_COLOR_DEPTH_16
+  // TFT single panel,16bit, normal output (BGR)
+  LCD_CTRL = 0x0000102C;
+#else
+#ifdef GuiConst_COLOR_DEPTH_8
+  // TFT single panel,8bit, normal output
+  LCD_CTRL = 0x00000026;
+#else
+  // STN single panel, monochrome, 4bit bus, normal output
+  LCD_CTRL = 0x00000010;
+#endif
+#endif
+#endif
+
+
+#ifdef GuiConst_COLOR_DEPTH_24
+  framePtr = (GuiConst_INT32U *)FRAME_ADDRESS;
+#else
+#ifdef GuiConst_COLOR_DEPTH_16
+  framePtr = (GuiConst_INT16U *)FRAME_ADDRESS;
+#else
+  framePtr = (GuiConst_INT8U *)FRAME_ADDRESS;
+  pDst = (GuiConst_INT32U *)PALETTE_RAM_ADDR;
+  for (i = 0; i < 128; i++)
+  {
+#ifdef GuiConst_COLOR_DEPTH_1
+    PaletteData = 0xFFFF0000;
+#else
+    PaletteData = GuiStruct_Palette[2*i][0];
+    PaletteData |= (GuiConst_INT32U)GuiStruct_Palette[2*i][1]<<8;
+    PaletteData |= (GuiConst_INT32U)GuiStruct_Palette[2*i+1][0]<<16;
+    PaletteData |= (GuiConst_INT32U)GuiStruct_Palette[2*i+1][1]<<24;
+#endif
+    *pDst++ = PaletteData;
+  }
+#endif
+#endif
+
+  // Clear frame buffer by copying the data into frame buffer
+#ifdef GuiConst_COLOR_DEPTH_24
+  for (i = 0; i < GuiConst_DISPLAY_BYTES/3; i++)
+    *framePtr++ = 0x00000000; // Color
+#else
+#ifdef GuiConst_COLOR_DEPTH_16
+    for (i = 0; i < GuiConst_DISPLAY_BYTES/2; i++)
+    *framePtr++ = 0x0000; // Color
+#else
+  for (i = 0; i < GuiConst_DISPLAY_BYTES; i++)
+    *framePtr++ = 0x00;  // Color
+#endif
+#endif
+
+//  LCD_CFG = 0;
+
+  millisecond_delay(100);
+  // Power-up sequence
+  LCD_CTRL |= 1<<LCDEN;
+  // Apply contrast voltage to LCD panel
+  // (not controlled or supplied by the LCD controller)
+  millisecond_delay(100);
+  LCD_CTRL |= 1<<LCDPWR;
+
+  // Set start address of frame buffer in RAM memory
+  LCD_LPBASE = FRAME_ADDRESS;
+  LCD_UPBASE = FRAME_ADDRESS;
+}
+
+#ifdef WANT_DOUBLE_BUFFERING
+// *** Need complete GuiDisplay_Refresh ***
+
+// Refreshes display buffer to display
+void GuiDisplay_Refresh (void)
+{
+  GuiConst_INT32U Pixel, X, Y, LastByte;
+#ifdef GuiConst_COLOR_DEPTH_24
+  GuiConst_INT32U *framePtr;
+#else
+#ifdef GuiConst_COLOR_DEPTH_16
+  GuiConst_INT16U *framePtr;
+#else
+  // Valid also for monochrome STN display
+  GuiConst_INT8U *framePtr;
+#endif
+#endif
+
+  GuiDisplay_Lock ();
+
+  // Walk through all lines
+  for (Y = 0; Y < GuiConst_BYTE_LINES; Y++)
+  {
+    if (GuiLib_DisplayRepaint[Y].ByteEnd >= 0)
+    // Something to redraw in this line
+    {
+#ifdef GuiConst_COLOR_DEPTH_24
+      // Set video ram base address
+      framePtr = (GuiConst_INT32U *)FRAME_ADDRESS;
+      // Pointer offset calculation
+      framePtr += Y * GuiConst_BYTES_PR_LINE/3 +
+                  GuiLib_DisplayRepaint[Y].ByteBegin;
+      // Set amount of data to be changed
+      LastByte = GuiConst_BYTES_PR_LINE/3 - 1;
+#else
+#ifdef GuiConst_COLOR_DEPTH_16
+      // Set video ram base address
+      framePtr = (GuiConst_INT16U *)FRAME_ADDRESS;
+      // Pointer offset calculation
+      framePtr += Y * GuiConst_BYTES_PR_LINE/2 +
+                  GuiLib_DisplayRepaint[Y].ByteBegin;
+      // Set amount of data to be changed
+      LastByte = GuiConst_BYTES_PR_LINE/2 - 1;
+#else
+      // Valid also for monochrome STN display
+      // Set video ram base address
+      framePtr = (GuiConst_INT8U *)FRAME_ADDRESS;
+      // Pointer offset calculation
+      framePtr += Y * GuiConst_BYTES_PR_LINE +
+                  GuiLib_DisplayRepaint[Y].ByteBegin;
+      // Set amount of data to be changed
+      LastByte = GuiConst_BYTES_PR_LINE - 1;
+#endif
+#endif
+      if (GuiLib_DisplayRepaint[Y].ByteEnd < LastByte)
+        LastByte = GuiLib_DisplayRepaint[Y].ByteEnd;
+
+      // Write data for one line to framebuffer from GuiLib_DisplayBuf
+#ifdef GuiConst_COLOR_DEPTH_24
+      for (X = GuiLib_DisplayRepaint[Y].ByteBegin * 3;
+               X <= (LastByte * 3 + 2);
+               X = X + 3)
+      {
+        Pixel = GuiLib_DisplayBuf[Y][X];
+        Pixel |= (GuiConst_INT32U)GuiLib_DisplayBuf[Y][X+1]<<8;
+        Pixel |= (GuiConst_INT32U)GuiLib_DisplayBuf[Y][X+2]<<16;
+        *framePtr++ = Pixel;
+      }
+#else
+#ifdef GuiConst_COLOR_DEPTH_16
+      for (X = GuiLib_DisplayRepaint[Y].ByteBegin; X <= LastByte; X++)
+      {
+        *framePtr++ = GuiLib_DisplayBuf.Words[Y][X];
+      }
+#else
+      // Valid also for monochrome STN display
+      for (X = GuiLib_DisplayRepaint[Y].ByteBegin; X <= LastByte; X++)
+        *framePtr++ = GuiLib_DisplayBuf[Y][X];
+#endif
+#endif
+      // Reset repaint parameters
+      GuiLib_DisplayRepaint[Y].ByteEnd = -1;
+    }
+  }
+  GuiDisplay_Unlock ();
+}
+
+#else // WANT_DOUBLE_BUFFERING
+
+// We are already writing direct to the display - 
+// GuiDisplay_Refresh does not need to do anything
+// (but other code still expects it to exist)
+void GuiDisplay_Refresh (void)
+{
+}
+
+#endif // WANT_DOUBLE_BUFFERING
+
+#endif // LCD_CONTROLLER_TYPE_LPC408X
+
+// ============================================================================
+//
+// DISPLAY DRIVER PART ENDS
+//
+// ============================================================================
+