Nuvoton
/
NuMaker-mbed-emWin-example
NuMaker emWin HMI
Revision 10:c8165817d92a, committed 8 months ago
- Comitter:
- csyang2
- Date:
- Mon Mar 04 15:47:41 2024 +0800
- Parent:
- 9:1286ec7f3230
- Commit message:
- Support NuMaker-IoT-M467
Changed in this revision
--- a/README.md Mon Mar 04 10:01:51 2024 +0800 +++ b/README.md Mon Mar 04 15:47:41 2024 +0800 @@ -2,7 +2,7 @@ This is an example to utilize emWin library to demonstrate interactive feature. -### CLI +### CLI for NuMaker-PFM-M487 Target board "NUMAKER_PFM_M487" with GCC_ARM toolchain. 1. mbed target "NUMAKER_PFM_M487" 2. mbed toolchain "GCC_ARM" @@ -17,9 +17,24 @@ Please note that the toolchain path in step 3 may be different from your environment. +### CLI for NuMaker-IoT-M467 +Target board "NUMAKER_IOT_M467" with GCC_ARM toolchain. +1. mbed target "NUMAKER_IOT_M467" +2. mbed toolchain "GCC_ARM" +3. mbed config -G GCC_ARM_PATH "C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q1-update\bin" +4. mbed compile + +Target board "NUMAKER_IOT_M467" with ARM toolchain. +1. mbed target "NUMAKER_IOT_M467" +2. mbed toolchain "ARM" +3. mbed config -G ARMC6_PATH "C:\Keil_v5\ARM\ARMCLANG\bin" +4. mbed compile + +Please note that the toolchain path in step 3 may be different from your environment. + ### Burn Code & Execute -1. Connect the board NuMaker-PFM-XXX with your PC by USB cable, then there will be one "MBED" disk. -2. Copy the built binary file into "MBED" disk on you PC. +1. Connect the board NuMaker-PFM-XXX / NuMaker-IoT-XXX with your PC by USB cable, then there will be one "NuMicro MCU" disk. +2. Copy the built binary file into this disk. 3. Press reset button to execute, user could test emWin simple demo. ### Demo condition, document and link @@ -27,11 +42,9 @@ LCD: ILI9341 MPU-type RGB56 QVGA LCD with resistive touch panel. -Please refer to the emWin related documents in [OpenNuvoton](https://github.com/OpenNuvoton/M480BSP) for more details! +Please go to [Nuvoton website](https://www.nuvoton.com/) and search "emWin" for more details! -The link of BSP for emWin quick start guide ["M480 emWin Quick Start Guide.pdf"](https://github.com/OpenNuvoton/M480BSP) - -The link of emWin official user manual ["UM03001_emWin5.pdf"](https://github.com/OpenNuvoton/M480BSP/tree/master/ThirdParty/emWin/Doc) +The link of emWin quick start guide "M480 emWin Quick Start Guide.pdf" can be found at \emWin\Doc\ [The link of SEGGER emWin official forum](https://forum.segger.com/index.php/Board/12-emWin-related/) @@ -39,9 +52,7 @@ [NuForum](http://forum.nuvoton.com/viewforum.php?f=31) [牛卧堂](http://nuvoton-mcu.com/forum.php?mod=forumdisplay&fid=86) -### How to utilize emWin tool "GUIBuilder" in Windows OS? -The link of emWin official Windows tool ["GUIBuilder"](https://github.com/OpenNuvoton/M480BSP/tree/master/ThirdParty/emWin/Tool) - +### How to utilize emWin tool "GUIBuilder" in Windows? Please refer to the chapter 4 "EMWIN GUIBUILDER" of "M480 emWin Quick Start Guide.pdf" for more details. ### PIN @@ -57,6 +68,8 @@ LCD_YU PB_8 LCD_XL PH_4 LCD_YD PH_5 +ADC_X PB_8 +ADC_Y PB_9 M487 EBI pin: ------------- @@ -79,3 +92,24 @@ EBI_AD2 PG_11 EBI_AD1 PG_10 EBI_AD0 PG_9 + +M467 TFT pin: +------------- +LCM_DC PB_2 +LCM_LED PB_5 + +M467 TOUCH pin: +--------------- +LCD_XR PB_9 +LCD_YU PB_6 +LCD_XL PB_7 +LCD_YD PB_8 +ADC_X PB_6 +ADC_Y PB_9 + +M467 SPI pin: +------------- +SPI2_MOSI PA_8 +SPI2_MISO PA_9 +SPI2_SCLK PA_10 +SPI2_SS PA_11
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emWin/Config/TARGET_NUMAKER_IOT_M467/ILI9341.cpp Mon Mar 04 15:47:41 2024 +0800 @@ -0,0 +1,242 @@ +/**************************************************************************//** + * @file ILI9341.c + * @version V1.00 + * @brief Display controller configuration. + * + * SPDX-License-Identifier: Apache-2.0 + * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#include <stddef.h> +#include <stdio.h> + +#include "GUI.h" +#include "GUIDRV_FlexColor.h" + +#include "NuMicro.h" + +#include "mbed.h" + +#ifdef __DEMO_320x240__ +#include "TouchPanel.h" + +#include "lcm.h" + +SPI spi(PA_8, PA_9, PA_10); // mosi, miso, sclk +DigitalOut GPIO_SPI_SS(PA_11); + +DigitalOut GPIO_LCM_DC(PB_2); +DigitalOut ILI9341_LED(PB_5); + +#define SPI_PANEL_PORT SPI2 +#define SPI_PANEL_FREQ 40000000 + +/********************************************************************* +* +* _Read1 +*/ +U8 _Read1(void) +{ + /* FIXME if panel supports read back feature */ + return 0; +} + +/********************************************************************* +* +* _ReadM1 +*/ +void _ReadM1(U8 * pData, int NumItems) +{ + /* FIXME if panel supports read back feature */ +} + +/********************************************************************* +* +* _Write0 +*/ +void _Write0(U8 Cmd) +{ + GPIO_LCM_DC = 0; + GPIO_SPI_SS = 0; + + spi.write(Cmd); + + GPIO_SPI_SS = 1; +} + +/********************************************************************* +* +* _Write1 +*/ +void _Write1(U8 Data) +{ + GPIO_LCM_DC = 1; + GPIO_SPI_SS = 0; + + spi.write(Data); + + GPIO_SPI_SS = 1; +} + +/********************************************************************* +* +* _WriteM1 +*/ +void _WriteM1(U8 * pData, int NumItems) +{ + GPIO_LCM_DC = 1; + GPIO_SPI_SS = 0; + + while(NumItems--) + { + //spi.write(*pData++); +#if 1 + SPI_WRITE_TX(SPI_PANEL_PORT, *pData++); + while(SPI_IS_BUSY(SPI_PANEL_PORT)); +#endif + } + + GPIO_SPI_SS = 1; +} + +static void _Open_SPI(void) +{ + spi.format(8, 0); + spi.frequency(SPI_PANEL_FREQ); +} + +/********************************************************************* +* +* _InitController +* +* Purpose: +* Initializes the display controller +*/ +void _InitController(void) +{ + static uint8_t s_InitOnce = 0; + + if(s_InitOnce == 0) + s_InitOnce = 1; + else + return; + + _Open_SPI(); + + //Because the Reset signal of Arduino's SPI LCD is pulled together with the Reset signal of M467HJ, the Reset signal cannot be controlled. + // Reset signal = GPIO_LCM_RST + + GPIO_LCM_DC = 0; +// GPIO_LCM_RST = 0; + ILI9341_LED = 0; + + GPIO_LCM_DC = 1; +// GPIO_LCM_RST = 0; +// CLK_SysTickDelay(20000); +// GPIO_LCM_RST = 1; +// CLK_SysTickDelay(40000); + //************* Start Initial Sequence **********// + + _Write0(0xCF); + _Write1(0x00); + _Write1(0xD9); + _Write1(0X30); + + _Write0(0xED); + _Write1(0x64); + _Write1(0x03); + _Write1(0X12); + _Write1(0X81); + + _Write0(0xE8); + _Write1(0x85); + _Write1(0x10); + _Write1(0x78); + + _Write0(0xCB); + _Write1(0x39); + _Write1(0x2C); + _Write1(0x00); + _Write1(0x34); + _Write1(0x02); + + _Write0(0xF7); + _Write1(0x20); + + _Write0(0xEA); + _Write1(0x00); + _Write1(0x00); + + _Write0(0xC0); //Power control + _Write1(0x21); //VRH[5:0] + + _Write0(0xC1); //Power control + _Write1(0x12); //SAP[2:0];BT[3:0] + + _Write0(0xC5); //VCM control + _Write1(0x32); + _Write1(0x3C); + + _Write0(0xC7); //VCM control2 + _Write1(0XC1); + + _Write0(0x36); // Memory Access Control + _Write1(0xe8); + + _Write0(0x3A); + _Write1(0x55); + + _Write0(0xB1); + _Write1(0x00); + _Write1(0x18); + + _Write0(0xB6); // Display Function Control + _Write1(0x0A); + _Write1(0xA2); + + _Write0(0xF2); // 3Gamma Function Disable + _Write1(0x00); + + _Write0(0x26); //Gamma curve selected + _Write1(0x01); + + _Write0(0xE0); //Set Gamma + _Write1(0x0F); + _Write1(0x20); + _Write1(0x1E); + _Write1(0x09); + _Write1(0x12); + _Write1(0x0B); + _Write1(0x50); + _Write1(0XBA); + _Write1(0x44); + _Write1(0x09); + _Write1(0x14); + _Write1(0x05); + _Write1(0x23); + _Write1(0x21); + _Write1(0x00); + + _Write0(0XE1); //Set Gamma + _Write1(0x00); + _Write1(0x19); + _Write1(0x19); + _Write1(0x00); + _Write1(0x12); + _Write1(0x07); + _Write1(0x2D); + _Write1(0x28); + _Write1(0x3F); + _Write1(0x02); + _Write1(0x0A); + _Write1(0x08); + _Write1(0x25); + _Write1(0x2D); + _Write1(0x0F); + + _Write0(0x11); //Exit Sleep + GUI_X_Delay(120); + _Write0(0x29); //Display on + + ILI9341_LED = 1; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emWin/Config/TARGET_NUMAKER_IOT_M467/LCDConf2.c Mon Mar 04 15:47:41 2024 +0800 @@ -0,0 +1,275 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2023 SEGGER Microcontroller GmbH * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V6.34 - Graphical user interface for embedded applications ** +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. +This file may +only be used in accordance with the following terms: + +The software has been licensed by SEGGER Software GmbH to Nuvoton Technology Corporation +at the address: No. 4, Creation Rd. III, Hsinchu Science Park, Taiwan +for the purposes of creating libraries for its +Arm Cortex-A, Arm Cortex-M and Arm9 32-bit microcontrollers, commercialized and distributed by Nuvoton Technology Corporation +under the terms and conditions of an End User +License Agreement supplied with the libraries. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +Licensing information +Licensor: SEGGER Software GmbH +Licensed to: Nuvoton Technology Corporation, No. 4, Creation Rd. III, Hsinchu Science Park, 30077 Hsinchu City, Taiwan +Licensed SEGGER software: emWin +License number: GUI-00735 +License model: emWin License Agreement, signed February 27, 2018 +Licensed platform: Cortex-M, Cortex-A, and ARM9 32-bit series microcontroller designed and manufactured by Nuvoton Technology Corporation. +---------------------------------------------------------------------- +Support and Update Agreement (SUA) +SUA period: 2018-03-26 - 2024-09-04 +Contact to extend SUA: sales@segger.com +---------------------------------------------------------------------- +File : LCDConf.c +Purpose : Display controller configuration (single layer) +---------------------------END-OF-HEADER------------------------------ +*/ + +#include <stddef.h> +#include <stdio.h> + +#include "GUI.h" +#include "GUIDRV_FlexColor.h" + +#include "NuMicro.h" + +#include "TouchPanel.h" + +#include "lcm.h" + +/********************************************************************* +* +* Layer configuration +* +********************************************************************** +*/ +// +// Physical display size +// +#ifdef __DEMO_160x128__ +#define XSIZE_PHYS 128 +#define YSIZE_PHYS 160 +#else +#define XSIZE_PHYS 240 +#define YSIZE_PHYS 320 +#endif + +// +// Color conversion +// +#ifdef __DEMO_160x128__ +#define COLOR_CONVERSION GUICC_M565 +#else +#define COLOR_CONVERSION GUICC_565 +#endif + +// +// Display driver +// +#define DISPLAY_DRIVER GUIDRV_FLEXCOLOR + +// +// Orientation +// +//#define DISPLAY_ORIENTATION (0) +//#define DISPLAY_ORIENTATION (GUI_MIRROR_X) +//#define DISPLAY_ORIENTATION (GUI_MIRROR_Y) +//#define DISPLAY_ORIENTATION (GUI_MIRROR_X | GUI_MIRROR_Y) +//#define DISPLAY_ORIENTATION (GUI_SWAP_XY) +#ifdef __DEMO_160x128__ +#define DISPLAY_ORIENTATION (GUI_MIRROR_X | GUI_SWAP_XY) +#else +#define DISPLAY_ORIENTATION (GUI_MIRROR_Y | GUI_SWAP_XY) +#endif +//#define DISPLAY_ORIENTATION (GUI_MIRROR_X | GUI_MIRROR_Y | GUI_SWAP_XY) + +/********************************************************************* +* +* Configuration checking +* +********************************************************************** +*/ +#ifndef VXSIZE_PHYS + #define VXSIZE_PHYS XSIZE_PHYS +#endif +#ifndef VYSIZE_PHYS + #define VYSIZE_PHYS YSIZE_PHYS +#endif +#ifndef XSIZE_PHYS + #error Physical X size of display is not defined! +#endif +#ifndef YSIZE_PHYS + #error Physical Y size of display is not defined! +#endif +#ifndef COLOR_CONVERSION + #error Color conversion not defined! +#endif +#ifndef DISPLAY_DRIVER + #error No display driver defined! +#endif +#ifndef DISPLAY_ORIENTATION + #define DISPLAY_ORIENTATION 0 +#endif + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* LCD_X_Config +* +* Purpose: +* Called during the initialization process in order to set up the +* display driver configuration. +* +*/ +void LCD_X_Config(void) { + GUI_DEVICE * pDevice; + GUI_PORT_API PortAPI = {0}; + CONFIG_FLEXCOLOR Config = {0}; + + // + // Set display driver and color conversion for 1st layer + // + pDevice = GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0); + // + // Orientation + // + Config.Orientation = DISPLAY_ORIENTATION; + GUIDRV_FlexColor_Config(pDevice, &Config); + // + // Display driver configuration + // + if (DISPLAY_ORIENTATION & GUI_SWAP_XY) { + LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS); + LCD_SetVSizeEx(0, VYSIZE_PHYS, VXSIZE_PHYS); + } else { + LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS); + LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS); + } + // + // Function selection, hardware routines (PortAPI) and operation mode (bus, bpp and cache) + // + PortAPI.pfWrite8_A0 = _Write0; + PortAPI.pfWrite8_A1 = _Write1; + PortAPI.pfWriteM8_A0 = _WriteM1; + PortAPI.pfWriteM8_A1 = _WriteM1; + PortAPI.pfRead8_A0 = _Read1; /* FIXME if panel supports read back feature */ + PortAPI.pfRead8_A1 = _Read1; /* FIXME if panel supports read back feature */ + PortAPI.pfReadM8_A0 = _ReadM1; /* FIXME if panel supports read back feature */ + PortAPI.pfReadM8_A1 = _ReadM1; /* FIXME if panel supports read back feature */ + GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66709, GUIDRV_FLEXCOLOR_M16C0B8); + + +#if GUI_SUPPORT_TOUCH +// LCD calibration +// +// Calibrate touch screen +// + GUI_TOUCH_Calibrate(GUI_COORD_X, 0, (__DEMO_TS_WIDTH__ - 1), 0, (__DEMO_TS_WIDTH__ - 1)); + GUI_TOUCH_Calibrate(GUI_COORD_Y, 0, (__DEMO_TS_HEIGHT__- 1), 0, (__DEMO_TS_HEIGHT__ - 1)); +#endif +} + +/********************************************************************* +* +* LCD_X_DisplayDriver +* +* Purpose: +* This function is called by the display driver for several purposes. +* To support the according task the routine needs to be adapted to +* the display controller. Please note that the commands marked with +* 'optional' are not cogently required and should only be adapted if +* the display controller supports these features. +* +* Parameter: +* LayerIndex - Index of layer to be configured +* Cmd - Please refer to the details in the switch statement below +* pData - Pointer to a LCD_X_DATA structure +*/ +int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) { + int r; + + GUI_USE_PARA(LayerIndex); + GUI_USE_PARA(pData); + switch (Cmd) { + // + // Required + // + case LCD_X_INITCONTROLLER: { + // + // Called during the initialization process in order to set up the + // display controller and put it into operation. If the display + // controller is not initialized by any external routine this needs + // to be adapted by the customer... + // + _InitController(); + return 0; + } + default: + r = -1; + } + return r; +} +#if GUI_SUPPORT_TOUCH +extern int ts_phy2log(int *sumx, int *sumy); + +void GUI_TOUCH_X_ActivateX(void) { +} + +void GUI_TOUCH_X_ActivateY(void) { +} + + + +int GUI_TOUCH_X_MeasureX(void) { + int sumx; + int sumy; + if (Read_TouchPanel(&sumx, &sumy)) + { +// printf("X = %d\n", sumx); + ts_phy2log(&sumx, &sumy); + return sumx; + } + return -1; +} + +int GUI_TOUCH_X_MeasureY(void) { + int sumx; + int sumy; + if ( Read_TouchPanel(&sumx, &sumy) ) + { +// printf("Y = %d\n", sumy); + ts_phy2log(&sumx, &sumy); + return sumy; + } + return -1; +} +#endif +/*************************** End of file ****************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emWin/Config/TARGET_NUMAKER_IOT_M467/lcm.h Mon Mar 04 15:47:41 2024 +0800 @@ -0,0 +1,28 @@ +/**************************************************************************//** + * @file lcm.h + * @version V1.00 + * @brief Display controller configuration header file. + * + * SPDX-License-Identifier: Apache-2.0 + * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __LCM_H__ +#define __LCM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +U8 _Read1(void); +void _ReadM1(U8 * pData, int NumItems); +void _Write0(U8 Cmd); +void _Write1(U8 Data); +void _WriteM1(U8 * pData, int NumItems); +void _InitController(void); + +#ifdef __cplusplus +} +#endif + +#endif // __LCM_H__
--- a/emWin/Include/GUI_Version.h Mon Mar 04 10:01:51 2024 +0800 +++ b/emWin/Include/GUI_Version.h Mon Mar 04 15:47:41 2024 +0800 @@ -44,7 +44,7 @@ #ifndef GUI_VERSION_H #define GUI_VERSION_H -#define GUI_VERSION 548111 +#define GUI_VERSION 548113 #endif /* Avoid multiple inclusion */
Binary file emWin/Lib/TOOLCHAIN_ARM/NUemWin_CM4_Keil.ar has changed
Binary file emWin/Lib/TOOLCHAIN_GCC/libNUemWin_CM4_GNU.a has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tslib/TARGET_NUMAKER_IOT_M467/TouchPanel.cpp Mon Mar 04 15:47:41 2024 +0800 @@ -0,0 +1,75 @@ + +#include "NuMicro.h" + +#include "GUI.h" +#include "TouchPanel.h" + +#include "mbed.h" + +int Init_TouchPanel(void) +{ + return 1; +} + +/*-----------------------------------------------*/ +// Get X Position from Touch Panel (ADC input) +// +/*-----------------------------------------------*/ +uint16_t Get_TP_X(void) +{ + uint16_t x_adc_in; + + DigitalOut dout_xr(DOUT_XR); + DigitalIn din_yd(DIN_YD); + DigitalOut dout_xl(DOUT_XL); + dout_xr = 1; + dout_xl = 0; + AnalogIn ain(AIN_X); + ThisThread::sleep_for(1); + x_adc_in = ain.read_u16(); + + return x_adc_in; +} + + +/*-----------------------------------------------*/ +// Get Y Position from Touch Panel (ADC input) +// +/*-----------------------------------------------*/ +uint16_t Get_TP_Y(void) +{ + uint16_t y_adc_in; + + DigitalOut dout_yu(DOUT_YU); + DigitalOut dout_yd(DOUT_YD); + DigitalIn din_xl(DIN_XL); + dout_yu = 1; + dout_yd = 0; + AnalogIn ain(AIN_Y); + ThisThread::sleep_for(1); + y_adc_in = ain.read_u16(); + + return y_adc_in; +} + +int Read_TouchPanel(int *x, int *y) +{ + *x = Get_TP_X() >> ADC_SAMPLE_SHIFT; + *y = Get_TP_Y() >> ADC_SAMPLE_SHIFT; + + if ( (*x >= ADC_SAMPLE_THRESHOLD) || (*y >= ADC_SAMPLE_THRESHOLD) ) + return 0; //Pen up; + else + return 1; +} + +int Uninit_TouchPanel(void) +{ + return 1; +} + +int Check_TouchPanel(void) +{ + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tslib/TARGET_NUMAKER_IOT_M467/TouchPanel.h Mon Mar 04 15:47:41 2024 +0800 @@ -0,0 +1,38 @@ +#ifndef __TOUCHPANEL_H__ +#define __TOUCHPANEL_H__ + +#define __DEMO_TSFILE_ADDR__ 0x00040000 /* SPI flash 256KB address */ + +#define __DEMO_TS_WIDTH__ 320 +#define __DEMO_TS_HEIGHT__ 240 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define DOUT_XR PB_9 +#define DIN_YD PB_8 +#define DOUT_XL PB_7 +#define AIN_X PB_6 + +#define DOUT_YU PB_6 +#define DOUT_YD PB_8 +#define DIN_XL PB_7 +#define AIN_Y PB_9 + +#define ADC_SAMPLE_SHIFT 4 +#define ADC_SAMPLE_THRESHOLD 3600 + +int Init_TouchPanel(void); +int Read_TouchPanel(int *x, int *y); +int Uninit_TouchPanel(void); +int Check_TouchPanel(void); + +int ts_calibrate(int xsize, int ysize); +void ts_init(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif