[C] 纯文本查看 复制代码
/*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: [url]www.segger.com[/url] Support: [email]support@segger.com[/email] *
* *
**********************************************************************
** emWin V5.44 - 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: [url]www.segger.com[/url]
We appreciate your understanding and fairness.
----------------------------------------------------------------------
File : LCDConf_Lin_Template.c
Purpose : Display controller configuration (single layer)
---------------------------END-OF-HEADER------------------------------
*/
/**
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2018 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license SLA0044,
* the "License"; You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
* [url]http://www.st.com/SLA0044[/url]
*
******************************************************************************
*/
#include "GUI.h"
#include "GUIDRV_Lin.h"
#include "ltdc.h"
#include "dma2d.h"
#include "drv_rgb_lcd.h"
#include "log_output.h"
/*********************************************************************
*
* Layer configuration (to be modified)
*
**********************************************************************
*/
//
// Physical display size /* 显示屏的物理分辨率 */
//
#define XSIZE_PHYS SCREEN_WIDTH
#define YSIZE_PHYS SCREEN_HEIGHT
//
// Color conversion
//
#define COLOR_CONVERSION GUICC_M888
//
// Display driver
//
#define DISPLAY_DRIVER GUIDRV_LIN_24
//
// Buffers / VScreens /* 多缓冲 / 虚拟屏,多缓冲和虚拟屏不可同时使用,emWin不支持 */
//
#define NUM_BUFFERS (3) // Number of multiple buffers to be used /* 定义多缓冲个数,仅可以设置1,2和3,也就是最大支持三缓冲 */
#define NUM_VSCREENS (1) // Number of virtual screens to be used /* 定义虚拟屏个数 */
// 定义图层数
#undef GUI_NUM_LAYERS
#define GUI_NUM_LAYERS (1)
/*********************************************************************
*
* Configuration checking
*
**********************************************************************
*/
#ifndef VRAM_ADDR
#define VRAM_ADDR 0 // TBD by customer: This has to be the frame buffer start address
#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 NUM_VSCREENS
#define NUM_VSCREENS 1
#else
#if (NUM_VSCREENS <= 0)
#error At least one screeen needs to be defined!
#endif
#endif
#if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
#error Virtual screens and multiple buffers are not allowed!
#endif
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/************************************************ 以下基于反客科技的驱动例程,自己修改只针对我当前使用的屏幕 ***************************************************************************/
// emwin底层驱动,移植于ST官方评估板的例程
/**************************************************************************
* 宏 *
**************************************************************************/
/* 使用DMA2D重定向颜色的批量转换 */
#define DEFINE_DMA2D_COLORCONVERSION(PFIX, PIXELFORMAT) \
static void _Color2IndexBulk_##PFIX##_DMA2D(LCD_COLOR * pColor, void * pIndex, U32 NumItems, U8 SizeOfIndex) { \
_DMA_Color2IndexBulk(pColor, pIndex, NumItems, SizeOfIndex, PIXELFORMAT); \
} \
static void _Index2ColorBulk_##PFIX##_DMA2D(void * pIndex, LCD_COLOR * pColor, U32 NumItems, U8 SizeOfIndex) { \
_DMA_Index2ColorBulk(pIndex, pColor, NumItems, SizeOfIndex, PIXELFORMAT); \
}
/**************************************************************************
* 数据类型 *
**************************************************************************/
typedef struct
{
uint32_t address;
volatile int32_t pending_buffer;
uint32_t buffer_index;
uint32_t xSize;
uint32_t ySize;
uint32_t BytesPerPixel;
LCD_API_COLOR_CONV *pColorConvAPI;
}
LCD_LayerPropTypedef;
/**************************************************************************
* 常量/常变量 *
**************************************************************************/
/**************************************************************************
* 全局变量 *
**************************************************************************/
static LCD_LayerPropTypedef layer_prop[GUI_NUM_LAYERS] = {
{
.address = 0,
.pending_buffer = -1,
.buffer_index = 0,
.xSize = XSIZE_PHYS,
.ySize = YSIZE_PHYS,
.BytesPerPixel = 0,
.pColorConvAPI = NULL
},
};
static const LCD_API_COLOR_CONV *apColorConvAPI[] = {
GUICC_M888,
};
static uint32_t _pBuffer_DMA2D[XSIZE_PHYS];
static void _DMA_Index2ColorBulk(void * pIndex, LCD_COLOR * pColor, U32 NumItems, U8 SizeOfIndex, U32 PixelFormat);
static void _DMA_Color2IndexBulk(LCD_COLOR * pColor, void * pIndex, U32 NumItems, U8 SizeOfIndex, U32 PixelFormat);
DEFINE_DMA2D_COLORCONVERSION(M8888I, LTDC_PIXEL_FORMAT_ARGB8888)
DEFINE_DMA2D_COLORCONVERSION(M888, LTDC_PIXEL_FORMAT_ARGB8888)
DEFINE_DMA2D_COLORCONVERSION(M565, LTDC_PIXEL_FORMAT_RGB565)
DEFINE_DMA2D_COLORCONVERSION(M1555I, LTDC_PIXEL_FORMAT_ARGB1555)
DEFINE_DMA2D_COLORCONVERSION(M4444I, LTDC_PIXEL_FORMAT_ARGB4444)
/**************************************************************************
* 局部函数原型 *
**************************************************************************/
static void _DMA_Index2ColorBulk(void * pIndex, LCD_COLOR * pColor, U32 NumItems, U8 SizeOfIndex, U32 PixelFormat)
{
uint32_t blkCnt;
uint32_t *ptr1 = (uint32_t *)pColor;
uint32_t *ptr2 = (uint32_t *)_pBuffer_DMA2D;
/* 配置DMA2D */
DMA2D->CR = 0x00010000UL; /* 0x00010000UL | (1 << 9) 没开DMA2D中断 */
DMA2D->FGMAR = (U32)pIndex;
DMA2D->OMAR = (U32)_pBuffer_DMA2D;
DMA2D->FGOR = 0;
DMA2D->OOR = 0;
DMA2D->FGPFCCR = PixelFormat;
DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_ARGB8888
| (0x00000001U << 20)
| (0x00000001U << 21);
DMA2D->NLR = (U32)(NumItems << 16) | 1;
/* 启动传输 */
DMA2D->CR |= DMA2D_CR_START;
/* 等待DMA2D传输完成 */
while (DMA2D->CR & DMA2D_CR_START);
/* 将数据从_pBuffer_DMA2D复制到pColor */
blkCnt = NumItems / 0x4U;
while (blkCnt > 0U)
{
*ptr1++ = *ptr2++;
*ptr1++ = *ptr2++;
*ptr1++ = *ptr2++;
*ptr1++ = *ptr2++;
blkCnt--;
}
blkCnt = NumItems % 0x4U;
while (blkCnt > 0U)
{
*ptr1++ = *ptr2++;
blkCnt--;
}
slog(log_verbose, "_DMA_Index2ColorBulk \r\n");
}
static void _DMA_Color2IndexBulk(LCD_COLOR * pColor, void * pIndex, U32 NumItems, U8 SizeOfIndex, U32 PixelFormat)
{
/* 配置DMA2D */
DMA2D->CR = 0x00010000UL; /* 0x00010000UL | (1 << 9) 没开DMA2D中断 */
DMA2D->FGMAR = (U32)pColor;
DMA2D->OMAR = (U32)pIndex;
DMA2D->FGOR = 0;
DMA2D->OOR = 0;
DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888
| (0x00000001U << 20)
| (0x00000001U << 21);
DMA2D->OPFCCR = PixelFormat;
DMA2D->NLR = (U32)(NumItems << 16) | 1;
/* 启动传输 */
DMA2D->CR |= DMA2D_CR_START;
/* 等待DMA2D传输完成 */
while (DMA2D->CR & DMA2D_CR_START);
slog(log_verbose, "_DMA_Color2IndexBulk \r\n");
}
static void LTDC_SetLUTEntry(LTDC_HandleTypeDef *hltdc,int LayerIndex, uint32_t Color, int Pos)
{
uint32_t r, g, b, a;
r = ( Color & 0xff) << 16;
g = ((Color >> 8) & 0xff) << 8;
b = ((Color >> 16) & 0xff);
a = Pos << 24;
LTDC_LAYER(hltdc, LayerIndex)->CLUTWR &= ~(LTDC_LxCLUTWR_BLUE | LTDC_LxCLUTWR_GREEN | LTDC_LxCLUTWR_RED | LTDC_LxCLUTWR_CLUTADD);
LTDC_LAYER(hltdc, LayerIndex)->CLUTWR = r | g | b | a;
__HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(hltdc);
}
/*********************************************************************
*
* CopyBuffer
*/
static void DMA2D_CopyBuffer(uint32_t LayerIndex, void * pSrc, void * pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLineSrc, uint32_t OffLineDst)
{
DMA2D->CR = 0x00000000UL; /* 0x00000000UL | (1 << 9) 没开DMA2D中断 */
/* Set up pointers */
DMA2D->FGMAR = (uint32_t)pSrc;
DMA2D->OMAR = (uint32_t)pDst;
DMA2D->FGOR = OffLineSrc;
DMA2D->OOR = OffLineDst;
/* Set up pixel format */
DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_RGB888;
/* Set up size */
DMA2D->NLR = (uint32_t)(xSize << 16) | (uint16_t)ySize;
DMA2D->CR |= DMA2D_CR_START;
/* Wait until transfer is done */
while (DMA2D->CR & DMA2D_CR_START);
}
/*********************************************************************
*
* FillBuffer
*/
static void DMA2D_FillBuffer(uint32_t LayerIndex, void * pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex)
{
/* Set up mode */
DMA2D->CR = 0x00030000UL; /* 0x00030000UL | (1 << 9) 没开DMA2D中断 */
DMA2D->OCOLR = ColorIndex;
/* Set up pointers */
DMA2D->OMAR = (uint32_t)pDst;
/* Set up offsets */
DMA2D->OOR = OffLine;
/* Set up pixel format */
DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_RGB888;
/* Set up size */
DMA2D->NLR = (uint32_t)(xSize << 16) | (uint16_t)ySize;
DMA2D->CR |= DMA2D_CR_START;
/* Wait until transfer is done */
while (DMA2D->CR & DMA2D_CR_START);
}
/*********************************************************************
*
* GetBufferSize
*/
static inline uint32_t GetBufferSize(uint32_t LayerIndex)
{
return FULL_SCREEN_SIZE;
// return (layer_prop[LayerIndex].xSize * layer_prop[LayerIndex].ySize * layer_prop[LayerIndex].BytesPerPixel);
}
/*********************************************************************
*
* CUSTOM_CopyBuffer
*/
static void CUSTOM_CopyBuffer(int32_t LayerIndex, int32_t IndexSrc, int32_t IndexDst)
{
uint32_t BufferSize = GetBufferSize(LayerIndex);
uint32_t AddrSrc = layer_prop[LayerIndex].address + BufferSize * IndexSrc;
uint32_t AddrDst = layer_prop[LayerIndex].address + BufferSize * IndexDst;
DMA2D_CopyBuffer(LayerIndex, (void *)AddrSrc, (void *)AddrDst, layer_prop[LayerIndex].xSize, layer_prop[LayerIndex].ySize, 0, 0);
layer_prop[LayerIndex].buffer_index = IndexDst;
// slog(log_verbose, "CUSTOM_CopyBuffer \r\n");
}
/*********************************************************************
*
* CUSTOM_CopyRect
*/
/**
* @brief Copy rectangle
* @param LayerIndex : Layer Index
* @param x0: X0 position
* @param y0: Y0 position
* @param x1: X1 position
* @param y1: Y1 position
* @param xSize: X size.
* @param ySize: Y size.
* @retval None
*/
static void CUSTOM_CopyRect(int32_t LayerIndex, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t xSize, int32_t ySize)
{
uint32_t AddrSrc = layer_prop[LayerIndex].address + (y0 * layer_prop[LayerIndex].xSize + x0) * layer_prop[LayerIndex].BytesPerPixel;
uint32_t AddrDst = layer_prop[LayerIndex].address + (y1 * layer_prop[LayerIndex].xSize + x1) * layer_prop[LayerIndex].BytesPerPixel;
DMA2D_CopyBuffer(LayerIndex, (void *)AddrSrc, (void *)AddrDst, xSize, ySize, layer_prop[LayerIndex].xSize - xSize, layer_prop[LayerIndex].xSize - xSize);
// slog(log_verbose, "CUSTOM_CopyRect \r\n");
}
/*********************************************************************
*
* CUSTOM_FillRect
*/
static void CUSTOM_FillRect(int32_t LayerIndex, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t PixelIndex)
{
if (GUI_GetDrawMode() == GUI_DM_XOR) {
LCD_SetDevFunc(LayerIndex, LCD_DEVFUNC_FILLRECT, NULL);
LCD_FillRect(x0, y0, x1, y1);
LCD_SetDevFunc(LayerIndex, LCD_DEVFUNC_FILLRECT, (void(*)(void))CUSTOM_FillRect);
} else {
uint32_t xSize = x1 - x0 + 1;
uint32_t ySize = y1 - y0 + 1;
uint32_t BufferSize = GetBufferSize(LayerIndex);
uint32_t AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y0 * layer_prop[LayerIndex].xSize + x0) * layer_prop[LayerIndex].BytesPerPixel;
DMA2D_FillBuffer(LayerIndex, (void *)AddrDst, xSize, ySize, layer_prop[LayerIndex].xSize - xSize, PixelIndex);
}
// slog(log_verbose, "CUSTOM_FillRect \r\n");
}
/**
* @brief
* @param LayerIndex
* @param x
* @param y
* @param p
* @param xSize
* @param ySize
* @param BytesPerLine
* @retval None
*/
static void LCD_DrawBitmap32bpp(int32_t LayerIndex, int32_t x, int32_t y, U16 const * p, int32_t xSize, int32_t ySize, int32_t BytesPerLine)
{
uint32_t BufferSize = GetBufferSize(LayerIndex);
uint32_t AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y * layer_prop[LayerIndex].xSize + x) * layer_prop[LayerIndex].BytesPerPixel;
uint32_t OffLineSrc = (BytesPerLine / 4) - xSize;
uint32_t OffLineDst = layer_prop[LayerIndex].xSize - xSize;
DMA2D_CopyBuffer(LayerIndex, (void *)p, (void *)AddrDst, xSize, ySize, OffLineSrc, OffLineDst);
}
/**
* @brief
* @param LayerIndex
* @param x
* @param y
* @param p
* @param xSize
* @param ySize
* @param BytesPerLine
* @retval None
*/
static void LCD_DrawBitmap16bpp(int32_t LayerIndex, int32_t x, int32_t y, U16 const * p, int32_t xSize, int32_t ySize, int32_t BytesPerLine)
{
uint32_t BufferSize = GetBufferSize(LayerIndex);
uint32_t AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y * layer_prop[LayerIndex].xSize + x) * layer_prop[LayerIndex].BytesPerPixel;
uint32_t OffLineSrc = (BytesPerLine / 2) - xSize;
uint32_t OffLineDst = layer_prop[LayerIndex].xSize - xSize;
DMA2D_CopyBuffer(LayerIndex, (void *)p, (void *)AddrDst, xSize, ySize, OffLineSrc, OffLineDst);
}
/**************************************************************************
* 全局函数实现 *
**************************************************************************/
/**
* @brief Line Event callback.
* @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains
* the configuration information for the specified LTDC.
* @retval None
*/
void HAL_LTDC_LineEvenCallback(LTDC_HandleTypeDef *hltdc)
{
uint32_t Addr;
if (layer_prop[0].pending_buffer >= 0)
{
SCB_CleanInvalidateDCache();
/* Calculate address of buffer to be used as visible frame buffer */
Addr = layer_prop[0].address + layer_prop[0].xSize * layer_prop[0].ySize * layer_prop[0].pending_buffer * layer_prop[0].BytesPerPixel;
HAL_LTDC_SetAddress(hltdc, Addr, 0); // __HAL_LTDC_LAYER(&hltdc, i)->CFBAR = Addr;
__HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(hltdc);
/* Notify STemWin that buffer is used */
GUI_MULTIBUF_ConfirmEx(0, layer_prop[0].pending_buffer);
/* Clear pending buffer flag of layer */
layer_prop[0].pending_buffer = -1;
}
HAL_LTDC_ProgramLineEvent(hltdc, 0);
}
/*********************************************************************
*
* LCD_X_Config
*
* Purpose:
* Called during the initialization process in order to set up the
* display driver configuration.
*
*/
void LCD_X_Config(void) {
//
// At first initialize use of multiple buffers on demand /* 初始化多缓冲 */
//
#if (NUM_BUFFERS > 1)
GUI_MULTIBUF_ConfigEx(0, NUM_BUFFERS);
#endif
//
// Set display driver and color conversion for 1st layer /* 设置显示驱动和颜色格式转换 */
//
GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0);
//
// Display driver configuration, required for Lin-driver
//
if (LCD_GetSwapXY()) {
LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
LCD_SetVSizeEx(0, YSIZE_PHYS * NUM_VSCREENS, XSIZE_PHYS);
} else {
LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS * NUM_VSCREENS);
}
//
// Set user palette data (only required if no fixed palette is used)
//
#if defined(PALETTE)
LCD_SetLUTEx(0, PALETTE);
#endif
layer_prop[0].address = (uint32_t)drv_Get_Layer_Mem_Adress(0);
layer_prop[0].pColorConvAPI = (LCD_API_COLOR_CONV *)apColorConvAPI[0];
layer_prop[0].pending_buffer = -1;
/* Set VRAM address */
LCD_SetVRAMAddrEx(0, (void *)layer_prop[0].address);
/* Remember color depth for further operations */
layer_prop[0].BytesPerPixel = LCD_GetBitsPerPixelEx(0) >> 3;
slog(log_verbose, "layer_prop[0].BytesPerPixel = %d \r\n", layer_prop[0].BytesPerPixel);
//
// Set custom functions for several operations to optimize native processes
//
LCD_SetDevFunc(0, LCD_DEVFUNC_COPYBUFFER, (void(*)(void))CUSTOM_CopyBuffer);
LCD_SetDevFunc(0, LCD_DEVFUNC_COPYRECT, (void(*)(void))CUSTOM_CopyRect);
/* Filling via DMA2D does only work with 16bpp or more */
if (LTDC_PIXEL_FORMAT_RGB888 <= LTDC_PIXEL_FORMAT_ARGB4444) {
LCD_SetDevFunc(0, LCD_DEVFUNC_FILLRECT, (void(*)(void))CUSTOM_FillRect);
}
/* Set up drawing routine for 16bpp bitmap using DMA2D */
if (LTDC_PIXEL_FORMAT_RGB888 == LTDC_PIXEL_FORMAT_RGB565) {
LCD_SetDevFunc(0, LCD_DEVFUNC_DRAWBMP_16BPP, (void(*)(void))LCD_DrawBitmap16bpp); /* Set up drawing routine for 16bpp bitmap using DMA2D. Makes only sense with RGB565 */
}
/* Set up drawing routine for 32bpp bitmap using DMA2D */
if (LTDC_PIXEL_FORMAT_RGB888 == LTDC_PIXEL_FORMAT_ARGB8888) {
LCD_SetDevFunc(0, LCD_DEVFUNC_DRAWBMP_32BPP, (void(*)(void))LCD_DrawBitmap32bpp); /* Set up drawing routine for 32bpp bitmap using DMA2D. Makes only sense with ARGB8888 */
}
/* DMA2D for ARGB1555 */
GUICC_M1555I_SetCustColorConv(_Color2IndexBulk_M1555I_DMA2D, _Index2ColorBulk_M1555I_DMA2D);
/* DMA2D for RGB565 */
GUICC_M565_SetCustColorConv (_Color2IndexBulk_M565_DMA2D, _Index2ColorBulk_M565_DMA2D);
/* DMA2D for ARGB4444 */
GUICC_M4444I_SetCustColorConv(_Color2IndexBulk_M4444I_DMA2D, _Index2ColorBulk_M4444I_DMA2D);
/* DMA2D for RGB888 */
GUICC_M888_SetCustColorConv (_Color2IndexBulk_M888_DMA2D, _Index2ColorBulk_M888_DMA2D);
/* DMA2D for ARGB8888 */
GUICC_M8888I_SetCustColorConv(_Color2IndexBulk_M8888I_DMA2D, _Index2ColorBulk_M8888I_DMA2D);
}
/*********************************************************************
*
* 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
*
* Return Value:
* < -1 - Error
* -1 - Command not handled
* 0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData)
{
int r = 0;
switch (Cmd) {
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...
//
slog(log_verbose, "emwin cmd LCD_X_INITCONTROLLER\r\n");
return 0;
}
case LCD_X_SETVRAMADDR:
{
// Required for setting the address of the video RAM for drivers
// with memory mapped video RAM which is passed in the 'pVRAM' element of p
LCD_X_SETVRAMADDR_INFO * p;
p = (LCD_X_SETVRAMADDR_INFO *)pData;
slog(log_verbose, "emwin cmd LCD_X_SETVRAMADDR pVRAM = %p \r\n", p->pVRAM);
return 0;
}
case LCD_X_SETORG:
{
// Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p
slog(log_verbose, "emwin cmd LCD_X_SETORG xPos = %d yPos = %d \r\n", ((LCD_X_SETORG_INFO *)pData)->xPos, ((LCD_X_SETORG_INFO *)pData)->yPos);
uint32_t addr = layer_prop[LayerIndex].address + ((LCD_X_SETORG_INFO *)pData)->yPos * layer_prop[LayerIndex].xSize * layer_prop[LayerIndex].BytesPerPixel;
HAL_LTDC_SetAddress(&hltdc, addr, LayerIndex);
return 0;
}
case LCD_X_SHOWBUFFER:
{
// Required if multiple buffers are used. The 'Index' element of p contains the buffer index.
// slog(log_verbose, "emwin cmd LCD_X_SHOWBUFFER LayerIndex = %d value = %d \r\n", LayerIndex, ((LCD_X_SHOWBUFFER_INFO *)pData)->Index);
layer_prop[LayerIndex].pending_buffer = ((LCD_X_SHOWBUFFER_INFO *)pData)->Index;
return 0;
}
case LCD_X_SETLUTENTRY:
{
// Required for setting a lookup table entry which is passed in the 'Pos' and 'Color' element of p
LCD_X_SETLUTENTRY_INFO * p;
p = (LCD_X_SETLUTENTRY_INFO *)pData;
slog(log_verbose, "emwin cmd LCD_X_SETLUTENTRY LayerIndex = %d Color = %d Pos = %d \r\n", LayerIndex, p->Color, p->Pos);
LTDC_SetLUTEntry(&hltdc, LayerIndex, p->Color, p->Pos) ;
return 0;
}
case LCD_X_ON:
{
// Required if the display controller should support switching on and off
slog(log_verbose, "emwin cmd LCD_X_ON\r\n");
return 0;
}
case LCD_X_OFF:
{
// Required if the display controller should support switching on and off
slog(log_verbose, "emwin cmd LCD_X_OFF\r\n");
return 0;
}
case LCD_X_SETSIZE:
{
LCD_X_SETSIZE_INFO * p;
p = (LCD_X_SETSIZE_INFO *)pData;
slog(log_verbose, "emwin cmd LCD_X_SETSIZE xSize = %d ySize = %d \r\n", p->xSize, p->ySize);
return 0;
}
default:
slog(log_error, "emwin not support cmd = %02X \r\n", Cmd);
while(1);
r = -1;
}
return r;
}
/*************************** End of file ****************************/