NXP Touch Cursor example for LPCXpresso54608, modified for use with Mbed OS.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2016, Freescale Semiconductor, Inc.
00003  * Copyright 2016-2017 NXP
00004  *
00005  * Redistribution and use in source and binary forms, with or without modification,
00006  * are permitted provided that the following conditions are met:
00007  *
00008  * o Redistributions of source code must retain the above copyright notice, this list
00009  *   of conditions and the following disclaimer.
00010  *
00011  * o Redistributions in binary form must reproduce the above copyright notice, this
00012  *   list of conditions and the following disclaimer in the documentation and/or
00013  *   other materials provided with the distribution.
00014  *
00015  * o Neither the name of the copyright holder nor the names of its
00016  *   contributors may be used to endorse or promote products derived from this
00017  *   software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00020  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00023  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00026  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  */
00030 
00031 /*  Standard C Included Files */
00032 #include "mbed.h"
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include "stdio_thread.h"
00036 #include "fsl_lcdc.h"
00037 #include "fsl_ft5406.h"
00038 #include "fsl_sctimer.h"
00039 #include "fsl_gpio.h"
00040 #include "fsl_i2c.h"
00041 #include "board.h"
00042 #include "pin_mux.h"
00043 #include "image.h"
00044 
00045 /*******************************************************************************
00046  * Definitions
00047  ******************************************************************************/
00048 #define APP_LCD LCD
00049 #define LCD_PANEL_CLK 9000000
00050 #define LCD_PPL 480
00051 #define LCD_HSW 2
00052 #define LCD_HFP 8
00053 #define LCD_HBP 43
00054 #define LCD_LPP 272
00055 #define LCD_VSW 10
00056 #define LCD_VFP 4
00057 #define LCD_VBP 12
00058 #define LCD_POL_FLAGS kLCDC_InvertVsyncPolarity | kLCDC_InvertHsyncPolarity
00059 #define IMG_HEIGHT 272
00060 #define IMG_WIDTH 480
00061 #define LCD_INPUT_CLK_FREQ CLOCK_GetFreq(kCLOCK_LCD)
00062 #define APP_LCD_IRQHandler LCD_IRQHandler
00063 #define APP_LCD_IRQn LCD_IRQn
00064 #define EXAMPLE_I2C_MASTER_BASE (I2C2_BASE)
00065 #define I2C_MASTER_CLOCK_FREQUENCY (12000000)
00066 #define APP_PIXEL_PER_BYTE 8
00067 
00068 #define EXAMPLE_I2C_MASTER ((I2C_Type *)EXAMPLE_I2C_MASTER_BASE)
00069 #define I2C_MASTER_SLAVE_ADDR_7BIT 0x7EU
00070 #define I2C_BAUDRATE 100000U
00071 
00072 /*******************************************************************************
00073  * Prototypes
00074  ******************************************************************************/
00075 
00076 /*******************************************************************************
00077  * Variables
00078  ******************************************************************************/
00079 
00080 #if (defined(__CC_ARM) || defined(__GNUC__))
00081 __attribute__((aligned(8)))
00082 #elif defined(__ICCARM__)
00083 #pragma data_alignment = 8
00084 #else
00085 #error Toolchain not support.
00086 #endif
00087 
00088 void *vram_ptr = s_frameBufs;
00089 
00090 /* Frame end flag. */
00091 static volatile bool s_frameEndFlag;
00092 
00093 /* Color palette. */
00094 static const uint32_t palette[] = { 0x001F00000 }; //{0x0000001F}; //{0x001F0000U, 0x7C0003E0U};
00095 
00096 /* 32x32 pixel cursor image. */
00097 #if (defined(__CC_ARM) || defined(__GNUC__))
00098 __attribute__((aligned(4)))
00099 #elif defined(__ICCARM__)
00100 #pragma data_alignment = 4
00101 #else
00102 #error Toolchain not support.
00103 #endif
00104 static const uint8_t cursor32Img0[] = {
00105     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00106     0xAA, 0xAA, 0xAA, /* Line 1.  */
00107     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00108     0xAA, 0xAA, 0xAA, /* Line 2.  */
00109     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00110     0xAA, 0xAA, 0xAA, /* Line 3.  */
00111     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00112     0xAA, 0xAA, 0xAA, /* Line 4.  */
00113     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00114     0xAA, 0xAA, 0xAA, /* Line 5.  */
00115     0xAA, 0xAA, 0xAA, 0xFA, 0xAA,
00116     0xAA, 0xAA, 0xAA, /* Line 6.  */
00117     0xAA, 0xAA, 0xAB, 0xFE, 0xAA,
00118     0xAA, 0xAA, 0xAA, /* Line 7.  */
00119     0xAA, 0xAA, 0xAB, 0xFE, 0xAA,
00120     0xAA, 0xAA, 0xAA, /* Line 8.  */
00121     0xAA, 0xAA, 0xAB, 0xFE, 0xAA,
00122     0xAA, 0xAA, 0xAA, /* Line 9.  */
00123     0xAA, 0xAA, 0xAB, 0xFE, 0xAA,
00124     0xAA, 0xAA, 0xAA, /* Line 10  */
00125     0xAA, 0xAA, 0xAB, 0xFF, 0xEA,
00126     0xAA, 0xAA, 0xAA, /* Line 11. */
00127     0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
00128     0xAA, 0xAA, 0xAA, /* Line 12. */
00129     0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
00130     0xFA, 0xAA, 0xAA, /* Line 13. */
00131     0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
00132     0xFE, 0xAA, 0xAA, /* Line 14. */
00133     0xAA, 0xAB, 0xFB, 0xFF, 0xFF,
00134     0xFF, 0xAA, 0xAA, /* Line 15. */
00135     0xAA, 0xAB, 0xFF, 0xFF, 0xFF,
00136     0xFF, 0xAA, 0xAA, /* Line 16. */
00137     0xAA, 0xAB, 0xFF, 0xFF, 0xFF,
00138     0xFF, 0xAA, 0xAA, /* Line 17. */
00139     0xAA, 0xAA, 0xFF, 0xFF, 0xFF,
00140     0xFF, 0xAA, 0xAA, /* Line 18. */
00141     0xAA, 0xAA, 0xBF, 0xFF, 0xFF,
00142     0xFF, 0xAA, 0xAA, /* Line 19. */
00143     0xAA, 0xAA, 0xBF, 0xFF, 0xFF,
00144     0xFF, 0xAA, 0xAA, /* Line 20. */
00145     0xAA, 0xAA, 0xAF, 0xFF, 0xFF,
00146     0xFF, 0xAA, 0xAA, /* Line 21. */
00147     0xAA, 0xAA, 0xAF, 0xFF, 0xFF,
00148     0xFE, 0xAA, 0xAA, /* Line 22. */
00149     0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
00150     0xFE, 0xAA, 0xAA, /* Line 23. */
00151     0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
00152     0xFE, 0xAA, 0xAA, /* Line 24. */
00153     0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
00154     0xFA, 0xAA, 0xAA, /* Line 25. */
00155     0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
00156     0xFA, 0xAA, 0xAA, /* Line 26. */
00157     0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
00158     0xFA, 0xAA, 0xAA, /* Line 27. */
00159     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00160     0xAA, 0xAA, 0xAA, /* Line 28. */
00161     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00162     0xAA, 0xAA, 0xAA, /* Line 29. */
00163     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00164     0xAA, 0xAA, 0xAA, /* Line 30. */
00165     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00166     0xAA, 0xAA, 0xAA, /* Line 31. */
00167     0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00168     0xAA, 0xAA, 0xAA /* Line 32. */
00169 };
00170 
00171 /*******************************************************************************
00172  * Code
00173  ******************************************************************************/
00174 static void BOARD_InitPWM(void)
00175 {
00176     sctimer_config_t config;
00177     sctimer_pwm_signal_param_t pwmParam;
00178     uint32_t event;
00179 
00180     CLOCK_AttachClk(kMCLK_to_SCT_CLK);
00181 
00182     CLOCK_SetClkDiv(kCLOCK_DivSctClk, 2, true);
00183 
00184     SCTIMER_GetDefaultConfig(&config);
00185 
00186     SCTIMER_Init(SCT0, &config);
00187 
00188     pwmParam.output = kSCTIMER_Out_5;
00189     pwmParam.level = kSCTIMER_HighTrue;
00190     pwmParam.dutyCyclePercent = 5;
00191 
00192     SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, 1000U, CLOCK_GetFreq(kCLOCK_Sct), &event);
00193 }
00194 
00195 void APP_LCD_IRQHandler(void)
00196 {
00197     uint32_t intStatus = LCDC_GetEnabledInterruptsPendingStatus(APP_LCD);
00198 
00199     LCDC_ClearInterruptsStatus(APP_LCD, intStatus);
00200 
00201     if (intStatus & kLCDC_VerticalCompareInterrupt)
00202     {
00203         s_frameEndFlag = true;
00204     }
00205     __DSB();
00206 }
00207 
00208 status_t APP_LCDC_Init(void)
00209 {
00210     /* Initialize the display. */
00211     lcdc_config_t lcdConfig;
00212     lcdc_cursor_config_t cursorConfig;
00213 
00214     LCDC_GetDefaultConfig(&lcdConfig);
00215 
00216     lcdConfig.panelClock_Hz = LCD_PANEL_CLK;
00217     lcdConfig.ppl = LCD_PPL;
00218     lcdConfig.hsw = LCD_HSW;
00219     lcdConfig.hfp = LCD_HFP;
00220     lcdConfig.hbp = LCD_HBP;
00221     lcdConfig.lpp = LCD_LPP;
00222     lcdConfig.vsw = LCD_VSW;
00223     lcdConfig.vfp = LCD_VFP;
00224     lcdConfig.vbp = LCD_VBP;
00225     lcdConfig.polarityFlags = LCD_POL_FLAGS;
00226     lcdConfig.upperPanelAddr = (uint32_t)s_frameBufs;
00227     lcdConfig.bpp = kLCDC_1BPP;
00228     lcdConfig.display = kLCDC_DisplayTFT;
00229     lcdConfig.swapRedBlue = true;  //false;
00230     lcdConfig.dataFormat = kLCDC_WinCeMode;
00231 
00232     LCDC_Init(APP_LCD, &lcdConfig, LCD_INPUT_CLK_FREQ);
00233 
00234     LCDC_SetPalette(APP_LCD, palette, ARRAY_SIZE(palette));
00235 
00236     /* Setup the Cursor. */
00237     LCDC_CursorGetDefaultConfig(&cursorConfig);
00238 
00239     cursorConfig.size = kLCDC_CursorSize32;
00240     cursorConfig.syncMode = kLCDC_CursorSync;
00241     cursorConfig.image[0] = (uint32_t *)cursor32Img0;
00242 
00243     LCDC_SetCursorConfig(APP_LCD, &cursorConfig);
00244     LCDC_ChooseCursor(APP_LCD, 0);
00245 
00246     /* Trigger interrupt at start of every vertical back porch. */
00247     LCDC_SetVerticalInterruptMode(APP_LCD, kLCDC_StartOfBackPorch);
00248     LCDC_EnableInterrupts(APP_LCD, kLCDC_VerticalCompareInterrupt);
00249     // NVIC_EnableIRQ(APP_LCD_IRQn);
00250 
00251     LCDC_EnableCursor(APP_LCD, true);
00252 
00253     LCDC_Start(APP_LCD);
00254     LCDC_PowerUp(APP_LCD);
00255 
00256     return kStatus_Success;
00257 }
00258 
00259 status_t APP_I2C_Init(void)
00260 {
00261     i2c_master_config_t masterConfig;
00262 
00263     I2C_MasterGetDefaultConfig(&masterConfig);
00264 
00265     /* Change the default baudrate configuration */
00266     masterConfig.baudRate_Bps = I2C_BAUDRATE;
00267 
00268     /* Initialize the I2C master peripheral */
00269     I2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, I2C_MASTER_CLOCK_FREQUENCY);
00270 
00271     return kStatus_Success;
00272 }
00273 
00274 void APP_SetCursorPosition(int posX, int posY)
00275 {
00276     posX -= 12;
00277     posY -= 5;
00278 
00279     LCDC_SetCursorPosition(APP_LCD, posX, posY);
00280 }
00281 
00282 int main(void)
00283 {
00284     int cursorPosX = 0U;
00285     int cursorPosY = 0U;
00286 
00287     ft5406_handle_t touch_handle;
00288     touch_event_t touch_event;
00289 
00290     status_t status;
00291 
00292     gpio_pin_config_t pin_config = {
00293         kGPIO_DigitalOutput, 0,
00294     };
00295 
00296     /* Board pin, clock, debug console init */
00297     /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
00298     CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
00299 
00300     /* Route Main clock to LCD. */
00301     CLOCK_AttachClk(kMCLK_to_LCD_CLK);
00302 
00303     /* attach 12 MHz clock to FLEXCOMM2 (I2C master for touch controller) */
00304     CLOCK_AttachClk(kFRO12M_to_FLEXCOMM2);
00305 
00306     CLOCK_EnableClock(kCLOCK_Gpio2);
00307 
00308     CLOCK_SetClkDiv(kCLOCK_DivLcdClk, 1, true);
00309 
00310     BOARD_InitPins();
00311     BOARD_BootClockFROHF48M();
00312     // BOARD_InitDebugConsole();
00313 
00314     /* Set the back light PWM. */
00315     BOARD_InitPWM();
00316 
00317     // APP_FillBuffer((void *)(s_frameBufs));
00318 
00319     status = APP_LCDC_Init();
00320     if (status != kStatus_Success)
00321     {
00322         safe_printf("LCD init failed\n");
00323     }
00324     assert(status == kStatus_Success);
00325 
00326     status = APP_I2C_Init();
00327     if (status != kStatus_Success)
00328     {
00329         safe_printf("I2C init failed\n");
00330     }
00331     assert(status == kStatus_Success);
00332 
00333     GPIO_PinInit(GPIO, 2, 27, &pin_config);
00334     // GPIO_WritePinOutput(GPIO, 2, 27, 1);
00335     GPIO->B[2][27] = 1;
00336 
00337     status = FT5406_Init(&touch_handle, EXAMPLE_I2C_MASTER);
00338     if (status != kStatus_Success)
00339     {
00340         safe_printf("Touch panel init failed\n");
00341     }
00342     assert(status == kStatus_Success);
00343 
00344     uint32_t xMin = 0xbd;
00345     uint32_t xMax = 0xea;
00346     uint32_t yMin = 0xb7;
00347     uint32_t yMax = 0x12f;
00348 
00349     for (;;)
00350     {
00351         if (kStatus_Success == FT5406_GetSingleTouch(&touch_handle, &touch_event, &cursorPosX, &cursorPosY))
00352         {
00353             if ((touch_event == kTouch_Down ) || (touch_event == kTouch_Contact ))
00354             {
00355                 /* Update cursor position */
00356                 APP_SetCursorPosition(cursorPosY, cursorPosX);
00357                 if (xMin < cursorPosX && cursorPosX < xMax && yMin < cursorPosY && cursorPosY < yMax) {
00358                   safe_printf("You've clicked the button! (0x%2x, 0x%2x)\r\n", cursorPosX, cursorPosY);
00359                 }
00360             }
00361         }
00362         else
00363         {
00364             safe_printf("error reading touch controller\r\n");
00365         }
00366     }
00367 }