Single Photo displayed on LPC4088
Dependencies: DMBasicGUI DMSupport
Diff: easyGUIFixed/GuiDisplay.c
- 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 +// +// ============================================================================ +