NXP Touch Cursor example for LPCXpresso54608, modified for use with Mbed OS.
The tutorial for this example can be found here: https://os.mbed.com/blog/entry/How-to-LPCXpresso54608-touch-panel/
Diff: main.cpp
- Revision:
- 0:c107a6f8c368
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Apr 11 20:46:55 2018 +0000
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Standard C Included Files */
+#include "mbed.h"
+#include <stdio.h>
+#include <string.h>
+#include "stdio_thread.h"
+#include "fsl_lcdc.h"
+#include "fsl_ft5406.h"
+#include "fsl_sctimer.h"
+#include "fsl_gpio.h"
+#include "fsl_i2c.h"
+#include "board.h"
+#include "pin_mux.h"
+#include "image.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#define APP_LCD LCD
+#define LCD_PANEL_CLK 9000000
+#define LCD_PPL 480
+#define LCD_HSW 2
+#define LCD_HFP 8
+#define LCD_HBP 43
+#define LCD_LPP 272
+#define LCD_VSW 10
+#define LCD_VFP 4
+#define LCD_VBP 12
+#define LCD_POL_FLAGS kLCDC_InvertVsyncPolarity | kLCDC_InvertHsyncPolarity
+#define IMG_HEIGHT 272
+#define IMG_WIDTH 480
+#define LCD_INPUT_CLK_FREQ CLOCK_GetFreq(kCLOCK_LCD)
+#define APP_LCD_IRQHandler LCD_IRQHandler
+#define APP_LCD_IRQn LCD_IRQn
+#define EXAMPLE_I2C_MASTER_BASE (I2C2_BASE)
+#define I2C_MASTER_CLOCK_FREQUENCY (12000000)
+#define APP_PIXEL_PER_BYTE 8
+
+#define EXAMPLE_I2C_MASTER ((I2C_Type *)EXAMPLE_I2C_MASTER_BASE)
+#define I2C_MASTER_SLAVE_ADDR_7BIT 0x7EU
+#define I2C_BAUDRATE 100000U
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+#if (defined(__CC_ARM) || defined(__GNUC__))
+__attribute__((aligned(8)))
+#elif defined(__ICCARM__)
+#pragma data_alignment = 8
+#else
+#error Toolchain not support.
+#endif
+
+void *vram_ptr = s_frameBufs;
+
+/* Frame end flag. */
+static volatile bool s_frameEndFlag;
+
+/* Color palette. */
+static const uint32_t palette[] = { 0x001F00000 }; //{0x0000001F}; //{0x001F0000U, 0x7C0003E0U};
+
+/* 32x32 pixel cursor image. */
+#if (defined(__CC_ARM) || defined(__GNUC__))
+__attribute__((aligned(4)))
+#elif defined(__ICCARM__)
+#pragma data_alignment = 4
+#else
+#error Toolchain not support.
+#endif
+static const uint8_t cursor32Img0[] = {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 1. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 2. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 3. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 4. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 5. */
+ 0xAA, 0xAA, 0xAA, 0xFA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 6. */
+ 0xAA, 0xAA, 0xAB, 0xFE, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 7. */
+ 0xAA, 0xAA, 0xAB, 0xFE, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 8. */
+ 0xAA, 0xAA, 0xAB, 0xFE, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 9. */
+ 0xAA, 0xAA, 0xAB, 0xFE, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 10 */
+ 0xAA, 0xAA, 0xAB, 0xFF, 0xEA,
+ 0xAA, 0xAA, 0xAA, /* Line 11. */
+ 0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
+ 0xAA, 0xAA, 0xAA, /* Line 12. */
+ 0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
+ 0xFA, 0xAA, 0xAA, /* Line 13. */
+ 0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
+ 0xFE, 0xAA, 0xAA, /* Line 14. */
+ 0xAA, 0xAB, 0xFB, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, /* Line 15. */
+ 0xAA, 0xAB, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, /* Line 16. */
+ 0xAA, 0xAB, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, /* Line 17. */
+ 0xAA, 0xAA, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, /* Line 18. */
+ 0xAA, 0xAA, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, /* Line 19. */
+ 0xAA, 0xAA, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, /* Line 20. */
+ 0xAA, 0xAA, 0xAF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, /* Line 21. */
+ 0xAA, 0xAA, 0xAF, 0xFF, 0xFF,
+ 0xFE, 0xAA, 0xAA, /* Line 22. */
+ 0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
+ 0xFE, 0xAA, 0xAA, /* Line 23. */
+ 0xAA, 0xAA, 0xAB, 0xFF, 0xFF,
+ 0xFE, 0xAA, 0xAA, /* Line 24. */
+ 0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
+ 0xFA, 0xAA, 0xAA, /* Line 25. */
+ 0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
+ 0xFA, 0xAA, 0xAA, /* Line 26. */
+ 0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
+ 0xFA, 0xAA, 0xAA, /* Line 27. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 28. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 29. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 30. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, /* Line 31. */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA /* Line 32. */
+};
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static void BOARD_InitPWM(void)
+{
+ sctimer_config_t config;
+ sctimer_pwm_signal_param_t pwmParam;
+ uint32_t event;
+
+ CLOCK_AttachClk(kMCLK_to_SCT_CLK);
+
+ CLOCK_SetClkDiv(kCLOCK_DivSctClk, 2, true);
+
+ SCTIMER_GetDefaultConfig(&config);
+
+ SCTIMER_Init(SCT0, &config);
+
+ pwmParam.output = kSCTIMER_Out_5;
+ pwmParam.level = kSCTIMER_HighTrue;
+ pwmParam.dutyCyclePercent = 5;
+
+ SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, 1000U, CLOCK_GetFreq(kCLOCK_Sct), &event);
+}
+
+void APP_LCD_IRQHandler(void)
+{
+ uint32_t intStatus = LCDC_GetEnabledInterruptsPendingStatus(APP_LCD);
+
+ LCDC_ClearInterruptsStatus(APP_LCD, intStatus);
+
+ if (intStatus & kLCDC_VerticalCompareInterrupt)
+ {
+ s_frameEndFlag = true;
+ }
+ __DSB();
+}
+
+status_t APP_LCDC_Init(void)
+{
+ /* Initialize the display. */
+ lcdc_config_t lcdConfig;
+ lcdc_cursor_config_t cursorConfig;
+
+ LCDC_GetDefaultConfig(&lcdConfig);
+
+ lcdConfig.panelClock_Hz = LCD_PANEL_CLK;
+ lcdConfig.ppl = LCD_PPL;
+ lcdConfig.hsw = LCD_HSW;
+ lcdConfig.hfp = LCD_HFP;
+ lcdConfig.hbp = LCD_HBP;
+ lcdConfig.lpp = LCD_LPP;
+ lcdConfig.vsw = LCD_VSW;
+ lcdConfig.vfp = LCD_VFP;
+ lcdConfig.vbp = LCD_VBP;
+ lcdConfig.polarityFlags = LCD_POL_FLAGS;
+ lcdConfig.upperPanelAddr = (uint32_t)s_frameBufs;
+ lcdConfig.bpp = kLCDC_1BPP;
+ lcdConfig.display = kLCDC_DisplayTFT;
+ lcdConfig.swapRedBlue = true; //false;
+ lcdConfig.dataFormat = kLCDC_WinCeMode;
+
+ LCDC_Init(APP_LCD, &lcdConfig, LCD_INPUT_CLK_FREQ);
+
+ LCDC_SetPalette(APP_LCD, palette, ARRAY_SIZE(palette));
+
+ /* Setup the Cursor. */
+ LCDC_CursorGetDefaultConfig(&cursorConfig);
+
+ cursorConfig.size = kLCDC_CursorSize32;
+ cursorConfig.syncMode = kLCDC_CursorSync;
+ cursorConfig.image[0] = (uint32_t *)cursor32Img0;
+
+ LCDC_SetCursorConfig(APP_LCD, &cursorConfig);
+ LCDC_ChooseCursor(APP_LCD, 0);
+
+ /* Trigger interrupt at start of every vertical back porch. */
+ LCDC_SetVerticalInterruptMode(APP_LCD, kLCDC_StartOfBackPorch);
+ LCDC_EnableInterrupts(APP_LCD, kLCDC_VerticalCompareInterrupt);
+ // NVIC_EnableIRQ(APP_LCD_IRQn);
+
+ LCDC_EnableCursor(APP_LCD, true);
+
+ LCDC_Start(APP_LCD);
+ LCDC_PowerUp(APP_LCD);
+
+ return kStatus_Success;
+}
+
+status_t APP_I2C_Init(void)
+{
+ i2c_master_config_t masterConfig;
+
+ I2C_MasterGetDefaultConfig(&masterConfig);
+
+ /* Change the default baudrate configuration */
+ masterConfig.baudRate_Bps = I2C_BAUDRATE;
+
+ /* Initialize the I2C master peripheral */
+ I2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, I2C_MASTER_CLOCK_FREQUENCY);
+
+ return kStatus_Success;
+}
+
+void APP_SetCursorPosition(int posX, int posY)
+{
+ posX -= 12;
+ posY -= 5;
+
+ LCDC_SetCursorPosition(APP_LCD, posX, posY);
+}
+
+int main(void)
+{
+ int cursorPosX = 0U;
+ int cursorPosY = 0U;
+
+ ft5406_handle_t touch_handle;
+ touch_event_t touch_event;
+
+ status_t status;
+
+ gpio_pin_config_t pin_config = {
+ kGPIO_DigitalOutput, 0,
+ };
+
+ /* Board pin, clock, debug console init */
+ /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
+ CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
+
+ /* Route Main clock to LCD. */
+ CLOCK_AttachClk(kMCLK_to_LCD_CLK);
+
+ /* attach 12 MHz clock to FLEXCOMM2 (I2C master for touch controller) */
+ CLOCK_AttachClk(kFRO12M_to_FLEXCOMM2);
+
+ CLOCK_EnableClock(kCLOCK_Gpio2);
+
+ CLOCK_SetClkDiv(kCLOCK_DivLcdClk, 1, true);
+
+ BOARD_InitPins();
+ BOARD_BootClockFROHF48M();
+ // BOARD_InitDebugConsole();
+
+ /* Set the back light PWM. */
+ BOARD_InitPWM();
+
+ // APP_FillBuffer((void *)(s_frameBufs));
+
+ status = APP_LCDC_Init();
+ if (status != kStatus_Success)
+ {
+ safe_printf("LCD init failed\n");
+ }
+ assert(status == kStatus_Success);
+
+ status = APP_I2C_Init();
+ if (status != kStatus_Success)
+ {
+ safe_printf("I2C init failed\n");
+ }
+ assert(status == kStatus_Success);
+
+ GPIO_PinInit(GPIO, 2, 27, &pin_config);
+ // GPIO_WritePinOutput(GPIO, 2, 27, 1);
+ GPIO->B[2][27] = 1;
+
+ status = FT5406_Init(&touch_handle, EXAMPLE_I2C_MASTER);
+ if (status != kStatus_Success)
+ {
+ safe_printf("Touch panel init failed\n");
+ }
+ assert(status == kStatus_Success);
+
+ uint32_t xMin = 0xbd;
+ uint32_t xMax = 0xea;
+ uint32_t yMin = 0xb7;
+ uint32_t yMax = 0x12f;
+
+ for (;;)
+ {
+ if (kStatus_Success == FT5406_GetSingleTouch(&touch_handle, &touch_event, &cursorPosX, &cursorPosY))
+ {
+ if ((touch_event == kTouch_Down) || (touch_event == kTouch_Contact))
+ {
+ /* Update cursor position */
+ APP_SetCursorPosition(cursorPosY, cursorPosX);
+ if (xMin < cursorPosX && cursorPosX < xMax && yMin < cursorPosY && cursorPosY < yMax) {
+ safe_printf("You've clicked the button! (0x%2x, 0x%2x)\r\n", cursorPosX, cursorPosY);
+ }
+ }
+ }
+ else
+ {
+ safe_printf("error reading touch controller\r\n");
+ }
+ }
+}
Jenny Plunkett