RT1050 GUI demo using emWin library

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers emwin_support.c Source File

emwin_support.c

00001 /*
00002  * The Clear BSD License
00003  * Copyright (c) 2016, Freescale Semiconductor, Inc.
00004  * Copyright 2016-2017 NXP
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without modification,
00008  * are permitted (subject to the limitations in the disclaimer below) provided
00009  *  that the following conditions are met:
00010  *
00011  * o Redistributions of source code must retain the above copyright notice, this list
00012  *   of conditions and the following disclaimer.
00013  *
00014  * o Redistributions in binary form must reproduce the above copyright notice, this
00015  *   list of conditions and the following disclaimer in the documentation and/or
00016  *   other materials provided with the distribution.
00017  *
00018  * o Neither the name of the copyright holder nor the names of its
00019  *   contributors may be used to endorse or promote products derived from this
00020  *   software without specific prior written permission.
00021  *
00022  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00026  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00027  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00030  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 #include "GUI.h"
00036 #include "WM.h"
00037 #include "emwin_support.h"
00038 #include "GUIDRV_Lin.h"
00039 
00040 #include "fsl_elcdif.h"
00041 #include "fsl_lpi2c.h"
00042 #include "fsl_ft5406_rt.h"
00043 
00044 /*
00045 **      Define everything necessary for different color depths
00046 */
00047 #if LCD_BITS_PER_PIXEL == 8 /* Palette definition for LUT */
00048 static uint32_t lutData[ELCDIF_LUT_ENTRY_NUM];
00049 static const LCD_COLOR _aColors_256[] = {
00050     0x000000, 0x000033, 0x000066, 0x000099, 0x0000CC, 0x0000FF, 0x003300, 0x003333, 0x003366, 0x003399, 0x0033CC,
00051     0x0033FF, 0x006600, 0x006633, 0x006666, 0x006699, 0x0066CC, 0x0066FF, 0x009900, 0x009933, 0x009966, 0x009999,
00052     0x0099CC, 0x0099FF, 0x00CC00, 0x00CC33, 0x00CC66, 0x00CC99, 0x00CCCC, 0x00CCFF, 0x00FF00, 0x00FF33, 0x00FF66,
00053     0x00FF99, 0x00FFCC, 0x00FFFF, 0x330000, 0x330033, 0x330066, 0x330099, 0x3300CC, 0x3300FF, 0x333300, 0x333333,
00054     0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336600, 0x336633, 0x336666, 0x336699, 0x3366CC, 0x3366FF, 0x339900,
00055     0x339933, 0x339966, 0x339999, 0x3399CC, 0x3399FF, 0x33CC00, 0x33CC33, 0x33CC66, 0x33CC99, 0x33CCCC, 0x33CCFF,
00056     0x33FF00, 0x33FF33, 0x33FF66, 0x33FF99, 0x33FFCC, 0x33FFFF, 0x660000, 0x660033, 0x660066, 0x660099, 0x6600CC,
00057     0x6600FF, 0x663300, 0x663333, 0x663366, 0x663399, 0x6633CC, 0x6633FF, 0x666600, 0x666633, 0x666666, 0x666699,
00058     0x6666CC, 0x6666FF, 0x669900, 0x669933, 0x669966, 0x669999, 0x6699CC, 0x6699FF, 0x66CC00, 0x66CC33, 0x66CC66,
00059     0x66CC99, 0x66CCCC, 0x66CCFF, 0x66FF00, 0x66FF33, 0x66FF66, 0x66FF99, 0x66FFCC, 0x66FFFF, 0x000000, 0x000000,
00060     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
00061     0x111111, 0x222222, 0x333333, 0x444444, 0x555555, 0x666666, 0x777777, 0x888888, 0x999999, 0xAAAAAA, 0xBBBBBB,
00062     0xCCCCCC, 0xDDDDDD, 0xEEEEEE, 0xFFFFFF, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
00063     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x990000, 0x990033, 0x990066, 0x990099, 0x9900CC, 0x9900FF,
00064     0x993300, 0x993333, 0x993366, 0x993399, 0x9933CC, 0x9933FF, 0x996600, 0x996633, 0x996666, 0x996699, 0x9966CC,
00065     0x9966FF, 0x999900, 0x999933, 0x999966, 0x999999, 0x9999CC, 0x9999FF, 0x99CC00, 0x99CC33, 0x99CC66, 0x99CC99,
00066     0x99CCCC, 0x99CCFF, 0x99FF00, 0x99FF33, 0x99FF66, 0x99FF99, 0x99FFCC, 0x99FFFF, 0xCC0000, 0xCC0033, 0xCC0066,
00067     0xCC0099, 0xCC00CC, 0xCC00FF, 0xCC3300, 0xCC3333, 0xCC3366, 0xCC3399, 0xCC33CC, 0xCC33FF, 0xCC6600, 0xCC6633,
00068     0xCC6666, 0xCC6699, 0xCC66CC, 0xCC66FF, 0xCC9900, 0xCC9933, 0xCC9966, 0xCC9999, 0xCC99CC, 0xCC99FF, 0xCCCC00,
00069     0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCCC, 0xCCCCFF, 0xCCFF00, 0xCCFF33, 0xCCFF66, 0xCCFF99, 0xCCFFCC, 0xCCFFFF,
00070     0xFF0000, 0xFF0033, 0xFF0066, 0xFF0099, 0xFF00CC, 0xFF00FF, 0xFF3300, 0xFF3333, 0xFF3366, 0xFF3399, 0xFF33CC,
00071     0xFF33FF, 0xFF6600, 0xFF6633, 0xFF6666, 0xFF6699, 0xFF66CC, 0xFF66FF, 0xFF9900, 0xFF9933, 0xFF9966, 0xFF9999,
00072     0xFF99CC, 0xFF99FF, 0xFFCC00, 0xFFCC33, 0xFFCC66, 0xFFCC99, 0xFFCCCC, 0xFFCCFF, 0xFFFF00, 0xFFFF33, 0xFFFF66,
00073     0xFFFF99, 0xFFFFCC, 0xFFFFFF
00074 
00075 };
00076 static const LCD_PHYSPALETTE _aPalette_256 = {ARRAY_SIZE(_aColors_256), _aColors_256};
00077 #endif
00078 #if LCD_BITS_PER_PIXEL < 32 /* Buffer definitions for emwin and LCD framebuffer */
00079 AT_NONCACHEABLE_SECTION_ALIGN(uint8_t s_gui_memory[GUI_NUMBYTES * LCD_BYTES_PER_PIXEL], FRAME_BUFFER_ALIGN);
00080 AT_NONCACHEABLE_SECTION_ALIGN(uint8_t s_vram_buffer[VRAM_SIZE * GUI_BUFFERS * LCD_BYTES_PER_PIXEL], FRAME_BUFFER_ALIGN);
00081 #else
00082 uint32_t s_gui_memory[(GUI_NUMBYTES)];
00083 uint32_t s_vram_buffer[VRAM_SIZE * GUI_BUFFERS];
00084 #endif
00085 
00086 /* Memory address definitions */
00087 #define GUI_MEMORY_ADDR ((uint32_t)s_gui_memory)
00088 #define VRAM_ADDR ((uint32_t)s_vram_buffer)
00089 
00090 static volatile int32_t s_LCDpendingBuffer = -1;
00091 
00092 /*******************************************************************************
00093  * Implementation of PortAPI for emWin LCD driver
00094  ******************************************************************************/
00095 
00096 /* Enable interrupt. */
00097 void BOARD_EnableLcdInterrupt(void)
00098 {
00099     EnableIRQ(LCDIF_IRQn);
00100 }
00101 
00102 void APP_LCDIF_IRQHandler(void)
00103 {
00104     uint32_t intStatus;
00105 
00106     intStatus = ELCDIF_GetInterruptStatus(APP_ELCDIF);
00107 
00108     ELCDIF_ClearInterruptStatus(APP_ELCDIF, intStatus);
00109 
00110     if (intStatus & kELCDIF_CurFrameDone)
00111     {
00112         if (s_LCDpendingBuffer >= 0)
00113         {
00114             /* Send a confirmation that the given buffer is visible */
00115             GUI_MULTIBUF_Confirm(s_LCDpendingBuffer);
00116             s_LCDpendingBuffer = -1;
00117         }
00118     }
00119 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
00120   exception return operation might vector to incorrect interrupt */
00121 #if defined __CORTEX_M && (__CORTEX_M == 4U)
00122     __DSB();
00123 #endif
00124 }
00125 
00126 void LCDIF_IRQHandler(void)
00127 {
00128     APP_LCDIF_IRQHandler();
00129 }
00130 
00131 void APP_ELCDIF_Init(void)
00132 {
00133     const elcdif_rgb_mode_config_t config = {
00134         .panelWidth = APP_IMG_WIDTH,
00135         .panelHeight = APP_IMG_HEIGHT,
00136         .hsw = APP_HSW,
00137         .hfp = APP_HFP,
00138         .hbp = APP_HBP,
00139         .vsw = APP_VSW,
00140         .vfp = APP_VFP,
00141         .vbp = APP_VBP,
00142         .polarityFlags = APP_POL_FLAGS,
00143         .bufferAddr = VRAM_ADDR,
00144         .pixelFormat = ELCDIF_PIXEL_FORMAT,
00145         .dataBus = APP_LCDIF_DATA_BUS,
00146     };
00147     ELCDIF_RgbModeInit(APP_ELCDIF, &config);
00148 
00149 #if (LCD_BITS_PER_PIXEL == 8)
00150     /* Load the LUT data. */
00151     ELCDIF_UpdateLut(APP_ELCDIF, kELCDIF_Lut0, 0, lutData, ELCDIF_LUT_ENTRY_NUM);
00152     ELCDIF_EnableLut(APP_ELCDIF, true);
00153 #endif
00154     BOARD_EnableLcdInterrupt();
00155     ELCDIF_EnableInterrupts(APP_ELCDIF, kELCDIF_CurFrameDoneInterruptEnable);
00156     ELCDIF_RgbModeStart(APP_ELCDIF);
00157 }
00158 
00159 /*******************************************************************************
00160  * Implementation of communication with the touch controller
00161  ******************************************************************************/
00162 
00163 /* Touch driver handle. */
00164 static ft5406_rt_handle_t touchHandle;
00165 
00166 static void BOARD_Touch_Init(void)
00167 {
00168     lpi2c_master_config_t masterConfig = {0};
00169     /*
00170     * masterConfig.debugEnable = false;
00171     * masterConfig.ignoreAck = false;
00172     * masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
00173     * masterConfig.baudRate_Hz = 100000U;
00174     * masterConfig.busIdleTimeout_ns = 0;
00175     * masterConfig.pinLowTimeout_ns = 0;
00176     * masterConfig.sdaGlitchFilterWidth_ns = 0;
00177     * masterConfig.sclGlitchFilterWidth_ns = 0;
00178     */
00179     LPI2C_MasterGetDefaultConfig(&masterConfig);
00180 
00181     /* Change the default baudrate configuration */
00182     masterConfig.baudRate_Hz = BOARD_TOUCH_I2C_BAUDRATE;
00183 
00184     /* Initialize the LPI2C master peripheral */
00185     LPI2C_MasterInit(BOARD_TOUCH_I2C, &masterConfig, BOARD_TOUCH_I2C_CLOCK_FREQ);
00186 
00187     /* Initialize the touch handle. */
00188     FT5406_RT_Init(&touchHandle, BOARD_TOUCH_I2C);
00189 }
00190 
00191 void BOARD_Touch_Deinit(void)
00192 {
00193     LPI2C_MasterDeinit(BOARD_TOUCH_I2C);
00194 }
00195 
00196 int BOARD_Touch_Poll(void)
00197 {
00198     touch_event_t touch_event;
00199     int touch_x;
00200     int touch_y;
00201     GUI_PID_STATE pid_state;
00202 
00203     if (kStatus_Success != FT5406_RT_GetSingleTouch(&touchHandle, &touch_event, &touch_x, &touch_y))
00204     {
00205         return 0;
00206     }
00207     else if (touch_event != kTouch_Reserved )
00208     {
00209         pid_state.x = touch_y;
00210         pid_state.y = touch_x;
00211         pid_state.Pressed = ((touch_event == kTouch_Down ) || (touch_event == kTouch_Contact ));
00212         pid_state.Layer = 0;
00213         GUI_TOUCH_StoreStateEx(&pid_state);
00214         return 1;
00215     }
00216     return 0;
00217 }
00218 
00219 /*******************************************************************************
00220  * Application implemented functions required by emWin library
00221  ******************************************************************************/
00222 void LCD_X_Config(void)
00223 {
00224     GUI_MULTIBUF_Config(GUI_BUFFERS);
00225     GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0);
00226     LCD_SetSizeEx(0, LCD_WIDTH, LCD_HEIGHT);
00227     LCD_SetVSizeEx(0, LCD_WIDTH, LCD_HEIGHT);
00228     LCD_SetVRAMAddrEx(0, (void *)VRAM_ADDR);
00229 #if (LCD_BITS_PER_PIXEL == 8)
00230     LCD_SetLUT(&_aPalette_256);
00231 #endif
00232     BOARD_Touch_Init();
00233 }
00234 
00235 int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void *p)
00236 {
00237     uint32_t addr;
00238 #if (LCD_BITS_PER_PIXEL == 8)
00239     uint16_t colorR, colorG, colorB;
00240     uint32_t color;
00241 #endif
00242     int result = 0;
00243     LCD_X_SHOWBUFFER_INFO *pData;
00244     switch (Cmd)
00245     {
00246         case LCD_X_INITCONTROLLER:
00247         {
00248             APP_ELCDIF_Init();
00249             break;
00250         }
00251         case LCD_X_SHOWBUFFER:
00252         {
00253             pData = (LCD_X_SHOWBUFFER_INFO *)p;
00254             /* Calculate address of the given buffer */
00255             addr = VRAM_ADDR + VRAM_SIZE * pData->Index;
00256             /* Make the given buffer visible */
00257             ELCDIF_SetNextBufferAddr(APP_ELCDIF, addr);
00258             //
00259             // Remember buffer index to be used by ISR
00260             //
00261             s_LCDpendingBuffer = pData->Index;
00262             while (s_LCDpendingBuffer >= 0)
00263                 ;
00264             return 0;
00265         }
00266 #if (LCD_BITS_PER_PIXEL == 8)
00267         case LCD_X_SETLUTENTRY:
00268         {
00269             //
00270             // Required for setting a lookup table entry which is passed in the 'Pos' and 'Color' element of p
00271             //
00272             LCD_X_SETLUTENTRY_INFO *pData;
00273             pData = (LCD_X_SETLUTENTRY_INFO *)p;
00274             //
00275             // Call hardware routine to write a LUT entry to the controller
00276             //
00277             color = pData->Color;
00278             colorB = (color & 0xFF0000) >> 16;
00279             colorG = (color & 0x00FF00) >> 8;
00280             colorR = (color & 0x0000FF);
00281             /* 16-bit bus */
00282             lutData[pData->Pos] = ((colorR >> 3) << 11) | ((colorG >> 2) << 5) | ((colorB >> 3) << 0);
00283             return 0;
00284         }
00285 #endif
00286         default:
00287             result = -1;
00288             break;
00289     }
00290 
00291     return result;
00292 }
00293 
00294 void GUI_X_Config(void)
00295 {
00296     /* Assign work memory area to emWin */
00297     GUI_ALLOC_AssignMemory((void *)GUI_MEMORY_ADDR, GUI_NUMBYTES);
00298 
00299     /* Select default font */
00300     GUI_SetDefaultFont(GUI_FONT_6X8);
00301 }
00302 
00303 void GUI_X_Init(void)
00304 {
00305 }
00306 
00307 /* Dummy RTOS stub required by emWin */
00308 void GUI_X_InitOS(void)
00309 {
00310 }
00311 
00312 /* Dummy RTOS stub required by emWin */
00313 void GUI_X_Lock(void)
00314 {
00315 }
00316 
00317 /* Dummy RTOS stub required by emWin */
00318 void GUI_X_Unlock(void)
00319 {
00320 }
00321 
00322 /* Dummy RTOS stub required by emWin */
00323 U32 GUI_X_GetTaskId(void)
00324 {
00325     return 0;
00326 }
00327 
00328 void GUI_X_ExecIdle(void)
00329 {
00330 }
00331 
00332 GUI_TIMER_TIME GUI_X_GetTime(void)
00333 {
00334     return 0;
00335 }
00336 
00337 void GUI_X_Delay(int Period)
00338 {
00339     volatile int i;
00340     for (; Period > 0; Period--)
00341     {
00342         for (i = 15000; i > 0; i--)
00343             ;
00344     }
00345 }
00346 
00347 void *emWin_memcpy(void *pDst, const void *pSrc, long size)
00348 {
00349     return memcpy(pDst, pSrc, size);
00350 }