【兆易GD32H759I-EVAL】 移植GDemWin
[复制链接]
本帖最后由 TL-LED 于 2024-5-20 17:29 编辑
学习在兆易GD32H759I-EVAL开发板上移植emWin。
最新的emWin版本支持GD32芯片,在GD官网也有GDemWin软件包下载链接。
一、下载GDemWin
官网的版本是emWin6.38
下载地址:https://www.gd32mcu.com/cn/download/7?kw=GD32H7
下面在此版本的基础上进行移植和修改。
二、移植代码
移植代码实在freeRTOS系统的基础上进行移植。
FreeRTOS移植参考帖子:https://bbs.eeworld.com.cn/thread-1281628-1-1.html
2.1、添加GDemWin638代码到项目工程中
2.2、主要移植的代码部分
2.2.1、DisplayDriver\GUIDRV_Template.c
这部分参考之前的版本文件进行的移植。
/*********************************************************************
* Portions COPYRIGHT 2015 STMicroelectronics *
* Portions SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 1996 - 2015 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
** emWin V5.28 - Graphical user interface for embedded applications **
All Intellectual Property rights in the Software belongs to SEGGER.
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 to STMicroelectronics International
N.V. a Dutch company with a Swiss branch and its headquarters in Plan-
les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the
purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_
troller products commercialized by Licensee only, sublicensed and dis_
tributed under the terms and conditions of the End User License Agree_
ment supplied by STMicroelectronics International N.V.
Full source code is available at: www.segger.com
We appreciate your understanding and fairness.
----------------------------------------------------------------------
File : GUIDRV_Template.c
Purpose : Template driver, could be used as starting point for new
simple display drivers supporting only one color depth.
---------------------------END-OF-HEADER------------------------------
*/
/**
******************************************************************************
* @attention *
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
#include "main.h"
#include <stddef.h>
#include "LCD_Private.h"
#include "GUI_Private.h"
#include "LCD_SIM.h"
#include "LCD_ConfDefaults.h"
#define emWin_Optimize 0 /* used for emWin optimize */
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
/*********************************************************************
*
* Macros for MIRROR_, SWAP_ and LUT_
*/
#if (!defined (LCD_LUT_COM) && !defined(LCD_LUT_SEG))
#if (!LCD_MIRROR_X && !LCD_MIRROR_Y && !LCD_SWAP_XY)
#define LOG2PHYS_X(x, y) x
#define LOG2PHYS_Y(x, y) y
#elif (!LCD_MIRROR_X && !LCD_MIRROR_Y && LCD_SWAP_XY)
#define LOG2PHYS_X(x, y) y
#define LOG2PHYS_Y(x, y) x
#elif (!LCD_MIRROR_X && LCD_MIRROR_Y && !LCD_SWAP_XY)
#define LOG2PHYS_X(x, y) x
#define LOG2PHYS_Y(x, y) LCD_YSIZE - 1 - (y)
#elif (!LCD_MIRROR_X && LCD_MIRROR_Y && LCD_SWAP_XY)
#define LOG2PHYS_X(x, y) y
#define LOG2PHYS_Y(x, y) LCD_XSIZE - 1 - (x)
#elif ( LCD_MIRROR_X && !LCD_MIRROR_Y && !LCD_SWAP_XY)
#define LOG2PHYS_X(x, y) LCD_XSIZE - 1 - (x)
#define LOG2PHYS_Y(x, y) y
#elif ( LCD_MIRROR_X && !LCD_MIRROR_Y && LCD_SWAP_XY)
#define LOG2PHYS_X(x, y) LCD_YSIZE - 1 - (y)
#define LOG2PHYS_Y(x, y) x
#elif ( LCD_MIRROR_X && LCD_MIRROR_Y && !LCD_SWAP_XY)
#define LOG2PHYS_X(x, y) LCD_XSIZE - 1 - (x)
#define LOG2PHYS_Y(x, y) LCD_YSIZE - 1 - (y)
#elif ( LCD_MIRROR_X && LCD_MIRROR_Y && LCD_SWAP_XY)
#define LOG2PHYS_X(x, y) LCD_YSIZE - 1 - (y)
#define LOG2PHYS_Y(x, y) LCD_XSIZE - 1 - (x)
#endif
#else
#if ( defined (LCD_LUT_COM) && !defined(LCD_LUT_SEG))
#define LOG2PHYS_X(x, y) x
#define LOG2PHYS_Y(x, y) LCD__aLine2Com0[y]
#elif (!defined (LCD_LUT_COM) && defined(LCD_LUT_SEG))
#define LOG2PHYS_X(x, y) LCD__aCol2Seg0[x]
#define LOG2PHYS_Y(x, y) y
#elif ( defined (LCD_LUT_COM) && defined(LCD_LUT_SEG))
#define LOG2PHYS_X(x, y) LCD__aCol2Seg0[x]
#define LOG2PHYS_Y(x, y) LCD__aLine2Com0[y]
#endif
#endif
/*********************************************************************
*
* Types
*
**********************************************************************
*/
typedef struct {
U32 VRAMAddr;
int xSize, ySize;
int vxSize, vySize;
int vxSizePhys;
int BitsPerPixel;
} DRIVER_CONTEXT_TEMPLATE;
/*********************************************************************
*
* Static functions
*
**********************************************************************
*/
/*********************************************************************
*
* _SetPixelIndex
*
* Purpose:
* Sets the index of the given pixel. The upper layers
* calling this routine make sure that the coordinates are in range, so
* that no check on the parameters needs to be performed.
*/
static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX PixelIndex) {
#ifdef WIN32
LCDSIM_SetPixelIndex(x, y, PixelIndex, pDevice->LayerIndex);
#else
//
// Convert logical into physical coordinates (Dep. on LCDConf.h)
//
#if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
int xPhys, yPhys;
xPhys = LOG2PHYS_X(x, y);
yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
GUI_USE_PARA(pDevice);
GUI_USE_PARA(x);
GUI_USE_PARA(y);
GUI_USE_PARA(PixelIndex);
{
//
// Write into hardware ... Adapt to your system
//
// TBD by customer...
//
LCDDrawPoint(xPhys, yPhys, PixelIndex);
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
#endif
}
/*********************************************************************
*
* _GetPixelIndex
*
* Purpose:
* Returns the index of the given pixel. The upper layers
* calling this routine make sure that the coordinates are in range, so
* that no check on the parameters needs to be performed.
*/
static LCD_PIXELINDEX _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {
unsigned int PixelIndex;
#ifdef WIN32
PixelIndex = LCDSIM_GetPixelIndex(x, y, pDevice->LayerIndex);
#else
//
// Convert logical into physical coordinates (Dep. on LCDConf.h)
//
#if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
int xPhys, yPhys;
xPhys = LOG2PHYS_X(x, y);
yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
GUI_USE_PARA(pDevice);
GUI_USE_PARA(x);
GUI_USE_PARA(y);
{
//
// Write into hardware ... Adapt to your system
//
// TBD by customer...
//
PixelIndex = LCDReadPoint(xPhys, yPhys);
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
#endif
return PixelIndex;
}
/*********************************************************************
*
* _XorPixel
*/
static void _XorPixel(GUI_DEVICE * pDevice, int x, int y) {
LCD_PIXELINDEX PixelIndex;
LCD_PIXELINDEX IndexMask;
PixelIndex = _GetPixelIndex(pDevice, x, y);
IndexMask = pDevice->pColorConvAPI->pfGetIndexMask();
_SetPixelIndex(pDevice, x, y, PixelIndex ^ IndexMask);
}
/*********************************************************************
*
* _DrawHLine
*/
static void _DrawHLine (GUI_DEVICE * pDevice, int x0, int y, int x1) {
LCD_PIXELINDEX ColorIndex;
if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) {
for (; x0 <= x1; x0++) {
_XorPixel(pDevice, x0, y);
}
} else {
#if emWin_Optimize
ColorIndex = LCD__GetColorIndex();
LCDDrawLine(x0, y, x1, y, ColorIndex);
#else
ColorIndex = LCD__GetColorIndex();
for (; x0 <= x1; x0++) {
_SetPixelIndex(pDevice, x0, y, ColorIndex);
}
#endif
}
}
/*********************************************************************
*
* _DrawVLine, not optimized
*/
static void _DrawVLine (GUI_DEVICE * pDevice, int x, int y0, int y1) {
LCD_PIXELINDEX ColorIndex;
if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) {
for (; y0 <= y1; y0++) {
_XorPixel(pDevice, x, y0);
}
} else {
#if emWin_Optimize
ColorIndex = LCD__GetColorIndex();
LCDDrawLine(x, y0, x, y1, ColorIndex);
#else
ColorIndex = LCD__GetColorIndex();
for (; y0 <= y1; y0++) {
_SetPixelIndex(pDevice, x, y0, ColorIndex);
}
#endif
}
}
/*********************************************************************
*
* _FillRect
*/
static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) {
LCD_PIXELINDEX ColorIndex;
int x;
if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR)
{
for (; y0 <= y1; y0++)
{
for (x = x0; x <= x1; x++)
{
_XorPixel(pDevice, x, y0);
}
}
}
else
{
/* 选择进行优化 */
#if emWin_Optimize
ColorIndex = LCD__GetColorIndex();
LCDDrawRectangle(x0, y0, x1, y1, ColorIndex);
#else
for (; y0 <= y1; y0++)
{
_DrawHLine(pDevice, x0, y0, x1);
}
#endif
}
}
/*********************************************************************
*
* Draw Bitmap 1 BPP
*/
static void _DrawBitLine1BPP(GUI_DEVICE * pDevice, int x, int y, U8 const * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) {
LCD_PIXELINDEX IndexMask, Index0, Index1, Pixel;
Index0 = *(pTrans + 0);
Index1 = *(pTrans + 1);
x += Diff;
switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
case 0:
do {
_SetPixelIndex(pDevice, x++, y, (*p & (0x80 >> Diff)) ? Index1 : Index0);
if (++Diff == 8) {
Diff = 0;
p++;
}
} while (--xsize);
break;
case LCD_DRAWMODE_TRANS:
do {
if (*p & (0x80 >> Diff))
_SetPixelIndex(pDevice, x, y, Index1);
x++;
if (++Diff == 8) {
Diff = 0;
p++;
}
} while (--xsize);
break;
case LCD_DRAWMODE_XOR | LCD_DRAWMODE_TRANS:
case LCD_DRAWMODE_XOR:
IndexMask = pDevice->pColorConvAPI->pfGetIndexMask();
do {
if (*p & (0x80 >> Diff)) {
Pixel = _GetPixelIndex(pDevice, x, y);
_SetPixelIndex(pDevice, x, y, Pixel ^ IndexMask);
}
x++;
if (++Diff == 8) {
Diff = 0;
p++;
}
} while (--xsize);
break;
}
}
/*********************************************************************
*
* Draw Bitmap 2 BPP
*/
static void _DrawBitLine2BPP(GUI_DEVICE * pDevice, int x, int y, U8 const * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) {
LCD_PIXELINDEX Pixels, PixelIndex;
int CurrentPixel, Shift, Index;
Pixels = *p;
CurrentPixel = Diff;
x += Diff;
switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
case 0:
if (pTrans) {
do {
Shift = (3 - CurrentPixel) << 1;
Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift;
PixelIndex = *(pTrans + Index);
_SetPixelIndex(pDevice, x++, y, PixelIndex);
if (++CurrentPixel == 4) {
CurrentPixel = 0;
Pixels = *(++p);
}
} while (--xsize);
} else {
do {
Shift = (3 - CurrentPixel) << 1;
Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift;
_SetPixelIndex(pDevice, x++, y, Index);
if (++CurrentPixel == 4) {
CurrentPixel = 0;
Pixels = *(++p);
}
} while (--xsize);
}
break;
case LCD_DRAWMODE_TRANS:
if (pTrans) {
do {
Shift = (3 - CurrentPixel) << 1;
Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift;
if (Index) {
PixelIndex = *(pTrans + Index);
_SetPixelIndex(pDevice, x, y, PixelIndex);
}
x++;
if (++CurrentPixel == 4) {
CurrentPixel = 0;
Pixels = *(++p);
}
} while (--xsize);
} else {
do {
Shift = (3 - CurrentPixel) << 1;
Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift;
if (Index) {
_SetPixelIndex(pDevice, x, y, Index);
}
x++;
if (++CurrentPixel == 4) {
CurrentPixel = 0;
Pixels = *(++p);
}
} while (--xsize);
}
break;
}
}
/*********************************************************************
*
* Draw Bitmap 4 BPP
*/
static void _DrawBitLine4BPP(GUI_DEVICE * pDevice, int x, int y, U8 const * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) {
LCD_PIXELINDEX Pixels, PixelIndex;
int CurrentPixel, Shift, Index;
Pixels = *p;
CurrentPixel = Diff;
x += Diff;
switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
case 0:
if (pTrans) {
do {
Shift = (1 - CurrentPixel) << 2;
Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift;
PixelIndex = *(pTrans + Index);
_SetPixelIndex(pDevice, x++, y, PixelIndex);
if (++CurrentPixel == 2) {
CurrentPixel = 0;
Pixels = *(++p);
}
} while (--xsize);
} else {
do {
Shift = (1 - CurrentPixel) << 2;
Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift;
_SetPixelIndex(pDevice, x++, y, Index);
if (++CurrentPixel == 2) {
CurrentPixel = 0;
Pixels = *(++p);
}
} while (--xsize);
}
break;
case LCD_DRAWMODE_TRANS:
if (pTrans) {
do {
Shift = (1 - CurrentPixel) << 2;
Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift;
if (Index) {
PixelIndex = *(pTrans + Index);
_SetPixelIndex(pDevice, x, y, PixelIndex);
}
x++;
if (++CurrentPixel == 2) {
CurrentPixel = 0;
Pixels = *(++p);
}
} while (--xsize);
} else {
do {
Shift = (1 - CurrentPixel) << 2;
Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift;
if (Index) {
_SetPixelIndex(pDevice, x, y, Index);
}
x++;
if (++CurrentPixel == 2) {
CurrentPixel = 0;
Pixels = *(++p);
}
} while (--xsize);
}
break;
}
}
/*********************************************************************
*
* Draw Bitmap 8 BPP
*/
static void _DrawBitLine8BPP(GUI_DEVICE * pDevice, int x, int y, U8 const * p, int xsize, const LCD_PIXELINDEX * pTrans) {
LCD_PIXELINDEX Pixel;
switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
case 0:
if (pTrans) {
for (; xsize > 0; xsize--, x++, p++) {
Pixel = *p;
_SetPixelIndex(pDevice, x, y, *(pTrans + Pixel));
}
} else {
for (; xsize > 0; xsize--, x++, p++) {
_SetPixelIndex(pDevice, x, y, *p);
}
}
break;
case LCD_DRAWMODE_TRANS:
if (pTrans) {
for (; xsize > 0; xsize--, x++, p++) {
Pixel = *p;
if (Pixel) {
_SetPixelIndex(pDevice, x, y, *(pTrans + Pixel));
}
}
} else {
for (; xsize > 0; xsize--, x++, p++) {
Pixel = *p;
if (Pixel) {
_SetPixelIndex(pDevice, x, y, Pixel);
}
}
}
break;
}
}
/*********************************************************************
*
* Draw Bitmap 16 BPP, not optimized
*
* Purpose:
* Drawing of 16bpp high color bitmaps.
* Only required for 16bpp color depth of target. Should be removed otherwise.
*/
static void _DrawBitLine16BPP(GUI_DEVICE * pDevice, int x, int y, U16 const * p, int xsize) {
#if emWin_Optimize
//LCDDrawLine(x, y, xsize, y, (uint16_t *)p);
#else
for (;xsize > 0; xsize--, x++, p++)
{
_SetPixelIndex(pDevice, x, y, *p);
}
#endif
}
/*********************************************************************
*
* Draw Bitmap 32 BPP, not optimized
*
* Purpose:
* Drawing of 32bpp true color bitmaps.
* Only required for 32bpp color depth of target. Should be removed otherwise.
*/
static void _DrawBitLine32BPP(GUI_DEVICE * pDevice, int x, int y, U32 const * p, int xsize) {
#if emWin_Optimize
#else
for (;xsize > 0; xsize--, x++, p++)
{
_SetPixelIndex(pDevice, x, y, *p);
}
#endif
}
/*********************************************************************
*
* _DrawBitmap
*/
static void _DrawBitmap(GUI_DEVICE * pDevice, int x0, int y0,
int xSize, int ySize,
int BitsPerPixel,
int BytesPerLine,
const U8 * pData, int Diff,
const LCD_PIXELINDEX * pTrans) {
int i;
switch (BitsPerPixel) {
case 1:
for (i = 0; i < ySize; i++) {
_DrawBitLine1BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans);
pData += BytesPerLine;
}
break;
case 2:
for (i = 0; i < ySize; i++) {
_DrawBitLine2BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans);
pData += BytesPerLine;
}
break;
case 4:
for (i = 0; i < ySize; i++) {
_DrawBitLine4BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans);
pData += BytesPerLine;
}
break;
case 8:
for (i = 0; i < ySize; i++) {
_DrawBitLine8BPP(pDevice, x0, i + y0, pData, xSize, pTrans);
pData += BytesPerLine;
}
break;
//
// Only required for 16bpp color depth of target. Should be removed otherwise.
//
case 16:
for (i = 0; i < ySize; i++) {
_DrawBitLine16BPP(pDevice, x0, i + y0, (const U16 *)pData, xSize);
pData += BytesPerLine;
}
break;
//
// Only required for 32bpp color depth of target. Should be removed otherwise.
//
case 32:
for (i = 0; i < ySize; i++) {
_DrawBitLine32BPP(pDevice, x0, i + y0, (const U32 *)pData, xSize);
pData += BytesPerLine;
}
break;
}
}
/*********************************************************************
*
* _InitOnce
*
* Purpose:
* Allocates a fixed block for the context of the driver
*
* Return value:
* 0 on success, 1 on error
*/
static int _InitOnce(GUI_DEVICE * pDevice) {
DRIVER_CONTEXT_TEMPLATE * pContext;
if (pDevice->u.pContext == NULL) {
pDevice->u.pContext = GUI_ALLOC_GetFixedBlock(sizeof(DRIVER_CONTEXT_TEMPLATE));
pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext;
pContext->BitsPerPixel = LCD__GetBPP(pDevice->pColorConvAPI->pfGetIndexMask());
}
return pDevice->u.pContext ? 0 : 1;
}
/*********************************************************************
*
* _GetDevProp
*/
static I32 _GetDevProp(GUI_DEVICE * pDevice, int Index) {
DRIVER_CONTEXT_TEMPLATE * pContext;
pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext;
switch (Index) {
case LCD_DEVCAP_XSIZE:
return pContext->xSize;
case LCD_DEVCAP_YSIZE:
return pContext->ySize;
case LCD_DEVCAP_VXSIZE:
return pContext->vxSize;
case LCD_DEVCAP_VYSIZE:
return pContext->vySize;
case LCD_DEVCAP_BITSPERPIXEL:
return pContext->BitsPerPixel;
case LCD_DEVCAP_NUMCOLORS:
return 0;
case LCD_DEVCAP_XMAG:
return 1;
case LCD_DEVCAP_YMAG:
return 1;
case LCD_DEVCAP_MIRROR_X:
return 0;
case LCD_DEVCAP_MIRROR_Y:
return 0;
case LCD_DEVCAP_SWAP_XY:
return 0;
}
return -1;
}
/*********************************************************************
*
* _GetDevData
*/
static void * _GetDevData(GUI_DEVICE * pDevice, int Index) {
GUI_USE_PARA(pDevice);
#if GUI_SUPPORT_MEMDEV
switch (Index) {
case LCD_DEVDATA_MEMDEV:
return (void *)&GUI_MEMDEV_DEVICE_16; // TBD: Has to be adapted to the right memory device depending on the used color depth!
}
#else
GUI_USE_PARA(Index);
#endif
return NULL;
}
/*********************************************************************
*
* _GetRect
*/
static void _GetRect(GUI_DEVICE * pDevice, LCD_RECT * pRect) {
DRIVER_CONTEXT_TEMPLATE * pContext;
pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext;
pRect->x0 = 0;
pRect->y0 = 0;
pRect->x1 = pContext->vxSize - 1;
pRect->y1 = pContext->vySize - 1;
}
/*********************************************************************
*
* _SetOrg
*/
static void _SetOrg(GUI_DEVICE * pDevice, int x, int y) {
LCD_X_SETORG_INFO Data = {0};
Data.xPos = x;
Data.yPos = y;
LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETORG, (void *)&Data);
}
/*********************************************************************
*
* Static code: Functions available by _GetDevFunc()
*
**********************************************************************
*/
/*********************************************************************
*
* _SetVRAMAddr
*/
static void _SetVRAMAddr(GUI_DEVICE * pDevice, void * pVRAM) {
DRIVER_CONTEXT_TEMPLATE * pContext;
LCD_X_SETVRAMADDR_INFO Data = {0};
_InitOnce(pDevice);
if (pDevice->u.pContext) {
pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext;
pContext->VRAMAddr = (U32)pVRAM;
Data.pVRAM = pVRAM;
LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETVRAMADDR, (void *)&Data);
}
}
/*********************************************************************
*
* _SetVSize
*/
static void _SetVSize(GUI_DEVICE * pDevice, int xSize, int ySize) {
DRIVER_CONTEXT_TEMPLATE * pContext;
_InitOnce(pDevice);
if (pDevice->u.pContext) {
pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext;
pContext->vxSize = xSize;
pContext->vySize = ySize;
pContext->vxSizePhys = xSize;
}
}
/*********************************************************************
*
* _SetSize
*/
static void _SetSize(GUI_DEVICE * pDevice, int xSize, int ySize) {
DRIVER_CONTEXT_TEMPLATE * pContext;
LCD_X_SETSIZE_INFO Data = {0};
_InitOnce(pDevice);
if (pDevice->u.pContext) {
pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext;
pContext->vxSizePhys = (pContext->vxSizePhys == 0) ? xSize : pContext->vxSizePhys;
pContext->xSize = xSize;
pContext->ySize = ySize;
Data.xSize = xSize;
Data.ySize = ySize;
LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETSIZE, (void *)&Data);
}
}
/*********************************************************************
*
* _Init
*/
static int _Init(GUI_DEVICE * pDevice) {
int r;
r = _InitOnce(pDevice);
r |= LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_INITCONTROLLER, NULL);
return r;
}
/*********************************************************************
*
* _On
*/
static void _On (GUI_DEVICE * pDevice) {
LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_ON, NULL);
}
/*********************************************************************
*
* _Off
*/
static void _Off (GUI_DEVICE * pDevice) {
LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_OFF, NULL);
}
/*********************************************************************
*
* _SetLUTEntry
*/
static void _SetLUTEntry(GUI_DEVICE * pDevice, U8 Pos, LCD_COLOR Color) {
LCD_X_SETLUTENTRY_INFO Data = {0};
Data.Pos = Pos;
Data.Color = Color;
LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETLUTENTRY, (void *)&Data);
}
/*********************************************************************
*
* _GetDevFunc
*/
static void (* _GetDevFunc(GUI_DEVICE ** ppDevice, int Index))(void) {
GUI_USE_PARA(ppDevice);
switch (Index) {
case LCD_DEVFUNC_SET_VRAM_ADDR:
return (void (*)(void))_SetVRAMAddr;
case LCD_DEVFUNC_SET_VSIZE:
return (void (*)(void))_SetVSize;
case LCD_DEVFUNC_SET_SIZE:
return (void (*)(void))_SetSize;
case LCD_DEVFUNC_INIT:
return (void (*)(void))_Init;
case LCD_DEVFUNC_ON:
return (void (*)(void))_On;
case LCD_DEVFUNC_OFF:
return (void (*)(void))_Off;
case LCD_DEVFUNC_SETLUTENTRY:
return (void (*)(void))_SetLUTEntry;
}
return NULL;
}
/*********************************************************************
*
* Public data
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_DEVICE_API structure
*/
const GUI_DEVICE_API GUIDRV_Template_API = {
//
// Data
//
DEVICE_CLASS_DRIVER,
//
// Drawing functions
//
_DrawBitmap,
_DrawHLine,
_DrawVLine,
_FillRect,
_GetPixelIndex,
_SetPixelIndex,
_XorPixel,
//
// Set origin
//
_SetOrg,
//
// Request information
//
_GetDevFunc,
_GetDevProp,
_GetDevData,
_GetRect,
};
/*************************** End of file ****************************/
2.2.2、GUI_X_FreeRTOS.c
/*********************************************************************
* SEGGER Software GmbH *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 1996 - 2023 SEGGER Software GmbH *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
** emWin V6.38 - Graphical user interface for embedded applications **
All Intellectual Property rights in the Software belongs to SEGGER.
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 to GigaDevice Semiconductor Inc. whose
registered office is situated at Building No.8, IC Park, No.9 Fenghao
East Road, Haidian, Beijing, China solely for the purposes of creating
libraries for ARM Cortex-M processor-based devices, sublicensed and
distributed under the terms and conditions of the End User License
Agreement supplied by GigaDevice Semiconductor Inc.
Full source code is available at: www.segger.com
We appreciate your understanding and fairness.
----------------------------------------------------------------------
Licensing information
Licensor: SEGGER Software GmbH
Licensed to: GigaDevice Semiconductor Inc., Building No.8, IC Park, No.9 Fenghao East Road, Beijing Haidian, , CHINA
Licensed SEGGER software: emWin
License number: GUI-00918
License model: Buyout SRC [Buyout Source Code License], according to Buyout Agreement signed Sep. 12th 2023 by Ivo Geilenbruegge and Aug. 31th 2023 by Guangyi Jin
Licensed product: Any
Licensed platform: Cortex-M
Licensed number of seats: -
----------------------------------------------------------------------
Support and Update Agreement (SUA)
SUA period: 2023-08-11 - 2024-11-28
Contact to extend SUA: sales@segger.com
----------------------------------------------------------------------
File : GUI_X_FreeRTOS.c
Purpose : Config / System dependent externals for GUI
---------------------------END-OF-HEADER------------------------------
*/
#include <stdio.h>
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include "GUI.h"
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
//static SemaphoreHandle_t _Semaphore;
//static StaticSemaphore_t _Semaphore_Memory;
static xSemaphoreHandle xQueueMutex;
static xSemaphoreHandle xSemaTxDone;
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* Timing:
* GUI_GetTime()
* GUI_Delay(int)
Some timing dependent routines require a GetTime
and delay funtion. Default time unit (tick), normally is
1 ms.
*/
int GUI_X_GetTime(void) {
//return xTaskGetTickCount() * portTICK_PERIOD_MS;
return ((int) xTaskGetTickCount());
}
void GUI_X_Delay(int Period) {
//vTaskDelay(pdMS_TO_TICKS(Period));
vTaskDelay( Period );
}
/*********************************************************************
*
* GUI_X_ExecIdle()
*
*/
void GUI_X_ExecIdle(void) {
//vTaskDelay(pdMS_TO_TICKS(1));
}
/*********************************************************************
*
* Multitasking:
*
* GUI_X_InitOS()
* GUI_X_GetTaskId()
* GUI_X_Lock()
* GUI_X_Unlock()
*
* Note:
* The following routines are required only if emWin is used in a
* true multi task environment, which means you have more than one
* thread using the emWin API.
* In this case the
* #define GUI_OS 1
* needs to be in GUIConf.h
*/
void GUI_X_InitOS(void)
{
//_Semaphore = xSemaphoreCreateCountingStatic (1, 0, &_Semaphore_Memory);
/* Create Mutex lock */
xQueueMutex = xSemaphoreCreateMutex();
configASSERT (xQueueMutex != NULL);
/* Queue Semaphore */
vSemaphoreCreateBinary( xSemaTxDone );
configASSERT ( xSemaTxDone != NULL );
}
void GUI_X_Unlock(void)
{
//xSemaphoreGive(_Semaphore);
xSemaphoreGive( xQueueMutex );
}
void GUI_X_Lock(void)
{
//xSemaphoreTake(_Semaphore, 0);
if(xQueueMutex == NULL)
{
GUI_X_InitOS();
}
xSemaphoreTake( xQueueMutex, portMAX_DELAY );
}
U32 GUI_X_GetTaskId(void)
{
return (U32)xTaskGetCurrentTaskHandle();
}
void GUI_X_WaitEvent (void)
{
while( xSemaphoreTake(xSemaTxDone, portMAX_DELAY ) != pdTRUE );
}
void GUI_X_SignalEvent (void)
{
xSemaphoreGive( xSemaTxDone );
}
/*********************************************************************
*
* Logging: OS dependent
Note:
Logging is used in higher debug levels only. The typical target
build does not use logging and does therefor not require any of
the logging routines below. For a release build without logging
the routines below may be eliminated to save some space.
(If the linker is not function aware and eliminates unreferenced
functions automatically)
*/
//#define OS_SendString(s) GUI_USE_PARA(s)
//void GUI_X_Log (const char *s) { GUI_USE_PARA(s); }
//void GUI_X_Warn (const char *s) { GUI_USE_PARA(s); }
//void GUI_X_ErrorOut(const char *s) { GUI_USE_PARA(s); }
//#define OS_SendString(s) GUI_USE_PARA(s)
void GUI_X_Log (const char *s) { }
void GUI_X_Warn (const char *s) { }
void GUI_X_ErrorOut(const char *s) { }
/*********************************************************************
*
* GUI_X_Init()
*
* Note:
* This routine is called from GUI_Init() in any case whether there
* is an RTOS or not. You can use it for additional initializations
* needed.
*/
void GUI_X_Init(void) {
}
/*************************** End of file ****************************/
2.2.3、main.c
#include "main.h"
void cache_enable(void);
int main(void)
{
cache_enable();
systick_config();
init_usart(115200);
gd_eval_lcd_init();
task_create();
while(1)
{
}
}
void cache_enable(void)
{
/* enable i-cache */
SCB_EnableICache();
/* enable d-cache */
SCB_EnableDCache();
}
2.2.4、fun_task.c
#include "main.h"
#define START_TASK_PRO 1
#define START_STK_SIZE 128
TaskHandle_t StartTask_Handler;
#define GUI_TASK_PRIO 3
#define GUI_TASK_STK_SIZE 512
static TaskHandle_t guiTask_Task_Handler = NULL;
#define TOUCH_TASK_PRIO 4
#define TOUCH_TASK_STK_SIZE 512
static TaskHandle_t touchTask_Task_Handler = NULL;
#define USER_TASK_PRIO 5
#define USER_TASK_STK_SIZE 128
static TaskHandle_t userTask_Task_Handler = NULL;
void start_task(void *pvParameters);
void gui_task(void *pvParameters);
void touch_task(void *pvParameters);
void user_task(void *pvParameters);
void task_create(void)
{
//start_task
xTaskCreate((TaskFunction_t )start_task,
(const char* )"start_task",
(uint16_t )START_STK_SIZE,
(void* )NULL,
(UBaseType_t )START_TASK_PRO,
(TaskHandle_t* )&StartTask_Handler);
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
//touch_task
xTaskCreate((TaskFunction_t )touch_task,
(const char* )"touch_task",
(uint16_t )TOUCH_TASK_STK_SIZE,
(void* )NULL,
(UBaseType_t )TOUCH_TASK_PRIO,
(TaskHandle_t* )&touchTask_Task_Handler);
//gui_task
xTaskCreate((TaskFunction_t )gui_task,
(const char* )"gui_task",
(uint16_t )GUI_TASK_STK_SIZE,
(void* )NULL,
(UBaseType_t )GUI_TASK_PRIO,
(TaskHandle_t* )&guiTask_Task_Handler);
//user_task
xTaskCreate((TaskFunction_t )user_task,
(const char* )"user_task",
(uint16_t )USER_TASK_STK_SIZE,
(void* )NULL,
(UBaseType_t )USER_TASK_PRIO,
(TaskHandle_t* )&userTask_Task_Handler);
taskEXIT_CRITICAL();
vTaskDelete(StartTask_Handler);
}
//touch_task
void touch_task(void *pvParameters)
{
//GUI_CURSOR_Show();
while (1)
{
GUI_TOUCH_Exec();
vTaskDelay(5);
}
}
//gui_task
void gui_task(void *pvParameters)
{
MainTask();
while (1)
{
vTaskDelay(5);
}
}
void user_task(void *pvParameters)
{
while (1)
{
printf("user_task run ...\r\n");
vTaskDelay(500);
}
}
三、运行结果
移植完成后,下载代码到开发板,运行视频如下:
GDemWin
拍摄的视频超出上传文件上限,截取视频的前面部分。
四、附件
项目源码:
|