📄 lcdlin32.c
字号:
/*
*********************************************************************************************************
* uC/GUI V3.98
* Universal graphic software for embedded applications
*
* (c) Copyright 2002, Micrium Inc., Weston, FL
* (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
* 礐/GUI 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 a license and should not be redistributed
* in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File : LCDLin32.C
Purpose : Driver for accessing linear video memory with 32bit operations
---------------------------END-OF-HEADER------------------------------
*/
#include <stddef.h>
#include "LCD_Private.h" /* private modul definitions & config */
#include "GUI_Private.h"
#include "GUIDebug.h"
#if (LCD_CONTROLLER == 3200) \
&& (!defined(WIN32) | defined(LCD_SIMCONTROLLER))
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#ifndef LCD_ENDIAN_BIG
#error Please define the endian mode of the video RAM!
#endif
#ifndef LCD_INIT_CONTROLLER
#define LCD_INIT_CONTROLLER()
#endif
#ifndef LCD_SET_LUT_ENTRY
#define LCD_SET_LUT_ENTRY(Pos, Color) GUI_USE_PARA(Pos); GUI_USE_PARA(Color)
#endif
#ifndef LCD_SET_ORG
#define LCD_SET_ORG(x, y) GUI_USE_PARA(x); GUI_USE_PARA(y)
#endif
#ifndef LCD_LIN_SWAP
#define LCD_LIN_SWAP 0
#endif
/* Error for unsupported modes */
#if (LCD_BITSPERPIXEL != 1) && \
(LCD_BITSPERPIXEL != 2) && \
(LCD_BITSPERPIXEL != 4) && \
(LCD_BITSPERPIXEL != 8) && \
(LCD_BITSPERPIXEL != 16)
#error This mode is currently not supported! Please contact support!
#endif
/* Mappings for multi layer configurations */
#if LCD_DISPLAY_INDEX == 1
#define SIM_WriteMem32 SIM_WriteMem32_1
#define SIM_ReadMem32 SIM_ReadMem32_1
#elif LCD_DISPLAY_INDEX == 2
#define SIM_WriteMem32 SIM_WriteMem32_2
#define SIM_ReadMem32 SIM_ReadMem32_2
#elif LCD_DISPLAY_INDEX == 3
#define SIM_WriteMem32 SIM_WriteMem32_3
#define SIM_ReadMem32 SIM_ReadMem32_3
#elif LCD_DISPLAY_INDEX == 4
#define SIM_WriteMem32 SIM_WriteMem32_4
#define SIM_ReadMem32 SIM_ReadMem32_4
#endif
#ifdef WIN32
U32 SIM_ReadMem32 (unsigned int Off);
void SIM_WriteMem32(unsigned int Off, U32 Data);
#undef LCD_SET_ORG
#ifdef LCD_READ_MEM
#undef LCD_READ_MEM
#endif
#ifdef LCD_WRITE_MEM
#undef LCD_WRITE_MEM
#endif
#define LCD_READ_MEM(Off) SIM_ReadMem32(Off)
#define LCD_WRITE_MEM(Off, Data) SIM_WriteMem32(Off, Data)
#define LCD_SET_ORG(x, y) GUI_USE_PARA(x); GUI_USE_PARA(y)
#else
#ifndef LCD_READ_MEM
#define LCD_READ_MEM(Off) (*((U32 *)LCD_VRAM_ADR + (U32)Off))
#endif
#ifndef LCD_WRITE_MEM
#define LCD_WRITE_MEM(Off, Data) *((U32 *)LCD_VRAM_ADR + (U32)Off) = Data
#endif
#endif
#if LCD_LIN_SWAP
#define WRITE_MEM(Off, Data) LCD_WRITE_MEM(Off, _Swap(Data))
#define READ_MEM(Off) _Swap(LCD_READ_MEM(Off))
#else
#define WRITE_MEM(Off, Data) LCD_WRITE_MEM(Off, Data)
#define READ_MEM(Off) LCD_READ_MEM(Off)
#endif
#define PIXELS_PER_DWORD (32 / LCD_BITSPERPIXEL)
#define DWORDS_PER_LINE (LCD_VXSIZE_PHYS / PIXELS_PER_DWORD)
#if (LCD_BITSPERPIXEL == 16)
#define XY2OFF(x,y) ((unsigned)y * DWORDS_PER_LINE + ((unsigned)x >> 1))
#elif (LCD_BITSPERPIXEL == 8)
#define XY2OFF(x,y) ((unsigned)y * DWORDS_PER_LINE + ((unsigned)x >> 2))
#elif (LCD_BITSPERPIXEL == 4)
#define XY2OFF(x,y) ((unsigned)y * DWORDS_PER_LINE + ((unsigned)x >> 3))
#elif (LCD_BITSPERPIXEL == 2)
#define XY2OFF(x,y) ((unsigned)y * DWORDS_PER_LINE + ((unsigned)x >> 4))
#elif (LCD_BITSPERPIXEL == 1)
#define XY2OFF(x,y) ((unsigned)y * DWORDS_PER_LINE + ((unsigned)x >> 5))
#endif
/*********************************************************************
*
* 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
/*********************************************************************
*
* Static functions
*
**********************************************************************
*/
#if LCD_LIN_SWAP
static U32 _Swap(U32 Data) {
#if LCD_LIN_SWAP == 1
Data = ((Data & 0x01010101) << 7) | ((Data & 0x02020202) << 5) | ((Data & 0x04040404) << 3) | ((Data & 0x08080808) << 1) | ((Data & 0x10101010) >> 1) | ((Data & 0x20202020) >> 3) | ((Data & 0x40404040) >> 5) | ((Data & 0x80808080) >> 7);
#elif LCD_LIN_SWAP == 2
Data = ((Data & 0x03030303) << 6) | ((Data & 0x0C0C0C0C) << 2) | ((Data & 0x30303030) >> 2) | ((Data & 0xC0C0C0C0) >> 6);
#elif LCD_LIN_SWAP == 4
Data = ((Data & 0xF0F0F0F0) >> 4) | ((Data & 0x0F0F0F0F) << 4);
#else
#error Unsupported swapping mode!
#endif
return Data;
}
#endif
/*********************************************************************
*
* Draw Bitmap 1 BPP, optimized for LCD_ENDIAN_BIG == 0, LCD_BITSPERPIXEL == 16
*/
#if (LCD_ENDIAN_BIG == 0) && \
(LCD_BITSPERPIXEL == 16) && \
(!LCD_MIRROR_X) && \
(!LCD_MIRROR_Y) && \
(!LCD_SWAP_XY)
static void _DrawBitLine1BPP(unsigned x, unsigned y, U8 const GUI_UNI_PTR * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) {
LCD_PIXELINDEX Index0 = *(pTrans + 0);
LCD_PIXELINDEX Index1 = *(pTrans + 1);
x += Diff;
switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
case 0:
{
U32 Data, Color;
unsigned Pixels, PixelCnt, Off;
PixelCnt = 8 - Diff;
Pixels = LCD_aMirror[*p] >> Diff;
Off = y * DWORDS_PER_LINE + (x >> 1);
/* First DWORD */
if (x & 1) {
Data = READ_MEM(Off) & 0xFFFF;
Data |= ((Pixels & 1) ? Index1 : Index0) << 16;
WRITE_MEM(Off, Data);
Off++;
xsize--;
PixelCnt--;
Pixels >>= 1;
}
/* Complete DWORDS */
if (xsize >= 2) {
do {
/* Make sure we have enough pixels loaded */
if (PixelCnt < 2) {
Pixels |= LCD_aMirror[*(++p)] << PixelCnt;
PixelCnt += 8;
}
Color = Pixels & 1 ? Index1 : Index0;
Color |= (Pixels & 2 ? Index1 : Index0) << 16;
Pixels >>= 2;
PixelCnt -= 2;
WRITE_MEM(Off, Color);
Off++;
} while ((xsize -= 2) >= 2);
}
/* Last DWORD */
if (xsize) {
/* Make sure we have enough pixels loaded */
if (PixelCnt == 0) {
Pixels = LCD_aMirror[*(++p)];
}
Data = READ_MEM(Off) & 0xFFFF0000;
Data |= (Pixels & 1) ? Index1 : Index0;
WRITE_MEM(Off, Data);
}
}
break;
case LCD_DRAWMODE_TRANS:
{
U32 Data;
unsigned PixelPos;
unsigned Pixels, PixelCnt, Off;
PixelCnt = 8 - Diff;
Pixels = LCD_aMirror[*p] >> Diff;
do {
/* Prepare loop */
if ((int)PixelCnt > xsize) {
PixelCnt = xsize;
}
xsize -= PixelCnt;
while (Pixels && PixelCnt) {
if ((PixelCnt >= 2) && !(x & 1)) {
PixelPos = (Pixels & 3);
if (PixelPos) {
Off = y * DWORDS_PER_LINE + (x >> 1);
if (PixelPos == 3) {
WRITE_MEM(Off, Index1 * 0x00010001);
} else {
Data = READ_MEM(Off);
if (PixelPos == 1) {
Data &= 0xFFFF0000;
Data |= Index1;
} else {
Data &= 0xFFFF;
Data |= Index1 << 16;
}
WRITE_MEM(Off, Data);
}
}
x += 2;
Pixels >>= 2;
PixelCnt -= 2;
} else {
if ((Pixels & 1)) {
Off = y * DWORDS_PER_LINE + (x >> 1);;
Data = READ_MEM(Off);
if (x & (PIXELS_PER_DWORD - 1)) {
Data &= 0xFFFF;
Data |= Index1 << 16;
} else {
Data &= 0xFFFF0000;
Data |= Index1;
}
WRITE_MEM(Off, Data);
}
x++;
Pixels >>= 1;
PixelCnt--;
}
}
/* Check if an other Source byte needs to be loaded */
if (xsize == 0) {
return;
}
x += PixelCnt;
PixelCnt = 8;
Pixels = LCD_aMirror[*(++p)];
} while (1);
}
case LCD_DRAWMODE_XOR | LCD_DRAWMODE_TRANS:
case LCD_DRAWMODE_XOR:
do {
if (*p & (0x80 >> Diff)) {
int Pixel = LCD_L0_GetPixelIndex(x, y);
LCD_L0_SetPixelIndex(x, y, LCD_NUM_COLORS - 1 - Pixel);
}
x++;
if (++Diff == 8) {
Diff = 0;
p++;
}
} while (--xsize);
break;
}
}
/*********************************************************************
*
* Draw Bitmap 1 BPP, optimized for LCD_ENDIAN_BIG == 0, LCD_BITSPERPIXEL == 8
*/
#elif (LCD_ENDIAN_BIG == 0) && \
(LCD_BITSPERPIXEL == 8) && \
(!LCD_MIRROR_X) && \
(!LCD_MIRROR_Y) && \
(!LCD_SWAP_XY)
static void _DrawBitLine1BPP(unsigned x, unsigned y, U8 const GUI_UNI_PTR * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) {
U8 Mode;
LCD_PIXELINDEX Index0 = *(pTrans + 0);
LCD_PIXELINDEX Index1 = *(pTrans + 1);
x += Diff;
Mode = GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR);
if (Mode == 0) {
/* Check if filling will do ... */
if (Index0 == Index1) {
LCD_PIXELINDEX ColorIndexOld = LCD_COLORINDEX; /* Save forground color */
LCD_COLORINDEX = Index0; /* Set foreground color */
LCD_L0_DrawHLine(x, y, x + xsize - 1);
LCD_COLORINDEX = ColorIndexOld;
} else {
/* O.K., we have to draw ... */
int Off, NumPixel_0, NumPixel_1, i;
U32 Data, ColorMask, AndMask;
Off = y * DWORDS_PER_LINE + x / PIXELS_PER_DWORD;
NumPixel_0 = x & (PIXELS_PER_DWORD - 1);
NumPixel_1 = (x + xsize - 1) & (PIXELS_PER_DWORD - 1);
/* First DWORD */
if (NumPixel_0) {
ColorMask = 0;
AndMask = ~(0xFFFFFFFF << (8 * NumPixel_0));
if ((xsize < 3) && (NumPixel_1)) {
AndMask |= ~(0xFFFFFFFF >> (8 * (3 - NumPixel_1)));
}
for (i = NumPixel_0; (i < 4) && xsize; i++, xsize--) {
U8 Index = *p & (0x80 >> Diff) ? Index1 : Index0;
if (++Diff == 8) {
Diff = 0;
p++;
}
ColorMask |= Index << (8 * i);
}
Data = READ_MEM(Off);
Data &= AndMask;
Data |= ColorMask;
WRITE_MEM(Off, Data);
Off++;
}
/* Complete DWORDS */
while (xsize >= 4) {
ColorMask = 0;
for (i = 0; i < 4; i++) {
U8 Index = *p & (0x80 >> Diff) ? Index1 : Index0;
if (++Diff == 8) {
Diff = 0;
p++;
}
ColorMask |= Index << (8 * i);
}
WRITE_MEM(Off, ColorMask);
Off++;
xsize -= 4;
}
/* Last DWORD */
if (xsize) {
ColorMask = i = 0;
AndMask = 0xFFFFFF00 << (8 * NumPixel_1);
while (xsize) {
U8 Index = *p & (0x80 >> Diff) ? Index1 : Index0;
if (++Diff == 8) {
Diff = 0;
p++;
}
ColorMask |= Index << (8 * i++);
xsize--;
}
Data = READ_MEM(Off);
Data &= AndMask;
Data |= ColorMask;
WRITE_MEM(Off, Data);
}
}
} else {
switch (Mode) {
case LCD_DRAWMODE_TRANS:
do {
if (*p & (0x80 >> Diff)) {
LCD_L0_SetPixelIndex(x, y, Index1);
}
x++;
if (++Diff == 8) {
Diff = 0;
p++;
}
} while (--xsize);
break;
case LCD_DRAWMODE_XOR | LCD_DRAWMODE_TRANS:
case LCD_DRAWMODE_XOR:
do {
if (*p & (0x80 >> Diff)) {
int Pixel = LCD_L0_GetPixelIndex(x, y);
LCD_L0_SetPixelIndex(x, y, LCD_NUM_COLORS - 1 - Pixel);
}
x++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -