📄 lcdpage1bpp.c
字号:
/*
*********************************************************************************************************
* uC/GUI
* 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 : LCDPage1bpp.C
Purpose : Driver for page-organized LCD-controllers with 1bpp
----------------------------------------------------------------------
Version-Date---Author-Explanation
----------------------------------------------------------------------
1.00.08 020820 JE a) Optimized:
_DrawBitLine1BPP, _DrawBitLine8BPP
1.00.06 020814 JE a) Support for PCF8535 added
1.00.04 020510 JE a) Bugfix in LCD_L0_FillRect
1.00.02 020425 JE a) LCD_WRITEM_A1 used in optimized routines
1.00.02 020424 JE a) Optimized routines added:
_DrawBitLine1BPP, LCD_L0_DrawHLine
LCD_L0_DrawVLine, LCD_L0_FillRect
1.00.00 020422 JE a) First release
---------------------------END-OF-HEADER------------------------------
*/
#include <string.h> /* memset */
#include "LCD_Private.h" /* private modul definitions & config */
#include "GUI_Private.h"
#include "GUIDebug.h"
#include "LCD_0.h" /* Defines for first display */
#if (LCD_CONTROLLER == 8811) || (LCD_CONTROLLER == 8535)\
&& (!defined(WIN32) | defined(LCD_SIMCONTROLLER))
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#ifndef LCD_INIT_CONTROLLER
#define LCD_INIT_CONTROLLER()
#endif
#ifndef LCD_OPTIMIZE
#define LCD_OPTIMIZE 1
#endif
#ifndef LCD_CACHE
#define LCD_CACHE 1
#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) (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) (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)
#error This combination of mirroring/swapping not yet supported
#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
/*********************************************
*
* Macros for simulation
*
**********************************************
*/
#ifdef WIN32
#undef LCD_WRITE_A0
#undef LCD_WRITE_A1
#undef LCD_WRITEM_A1
#undef LCD_READ_A0
#undef LCD_READ_A1
void SIM_WriteA1C0(U8 Data);
void SIM_WriteMA1C0(U8 * pData, int NumberOfBytes);
void SIM_WriteA0C0(U8 cmd);
U8 SIM_ReadA1C0(void);
U8 SIM_ReadA0C0(void);
#define LCD_WRITE_A1(Byte) SIM_WriteA1C0(Byte)
#define LCD_WRITEM_A1(pData, NumberOfBytes) SIM_WriteMA1C0(pData, NumberOfBytes)
#define LCD_WRITE_A0(Byte) SIM_WriteA0C0(Byte)
#define LCD_READ_A1() SIM_ReadA1C0()
#define LCD_READ_A0() SIM_ReadA0C0()
#endif
/*********************************************
*
* Hardware access macros
*
**********************************************
*/
#ifndef LCD_CHECK_BUSY
#define LCD_CHECK_BUSY 0
#endif
#ifndef LCD_XOFF
#define LCD_XOFF 0
#endif
#if LCD_CHECK_BUSY
#define CHECK_BUSY() WAIT_WHILE_BUSY()
#else
#define CHECK_BUSY()
#endif
#ifdef LCD_CACHE
#if !LCD_CACHE
#error Using this driver a cache must be defined!
#endif
#else
#define LCD_CACHE 1
#endif
#if (LCD_CONTROLLER == 8811) /* PCF8811 */
#define MAX_PAGE 10
#define MAX_OFFSET 128
#define WAIT_WHILE_BUSY() { U8 Status; do { LCD_READ_A0(Status); } while (Status & (1 << 7)); }
#define WRITE_DATA(Data) CHECK_BUSY(); LCD_WRITE_A1(Data); _VRam[_Page][_Offset] = Data
#define LCD_ON() CHECK_BUSY(); LCD_WRITE_A0(0xAF)
#define LCD_OFF() CHECK_BUSY(); LCD_WRITE_A0(0xAE)
#define SET_PAGE(Page) CHECK_BUSY(); LCD_WRITE_A0(Page + 0xB0)
#define SET_OFFSET(Offset) CHECK_BUSY(); LCD_WRITE_A0(0x10 + (Offset >> 4)); \
CHECK_BUSY(); LCD_WRITE_A0(0x00 + (Offset & 0x0F))
#ifndef LCD_AUTOINC_Y
#define LCD_AUTOINC_Y MAX_OFFSET
#endif
#define INCREMENT_XY_VOLATILE
#elif (LCD_CONTROLLER == 8535) /* PCF8535 */
static U8 _aMirror[256] = {
________, X_______, _X______, XX______, __X_____, X_X_____, _XX_____, XXX_____,
___X____, X__X____, _X_X____, XX_X____, __XX____, X_XX____, _XXX____, XXXX____,
____X___, X___X___, _X__X___, XX__X___, __X_X___, X_X_X___, _XX_X___, XXX_X___,
___XX___, X__XX___, _X_XX___, XX_XX___, __XXX___, X_XXX___, _XXXX___, XXXXX___,
_____X__, X____X__, _X___X__, XX___X__, __X__X__, X_X__X__, _XX__X__, XXX__X__,
___X_X__, X__X_X__, _X_X_X__, XX_X_X__, __XX_X__, X_XX_X__, _XXX_X__, XXXX_X__,
____XX__, X___XX__, _X__XX__, XX__XX__, __X_XX__, X_X_XX__, _XX_XX__, XXX_XX__,
___XXX__, X__XXX__, _X_XXX__, XX_XXX__, __XXXX__, X_XXXX__, _XXXXX__, XXXXXX__,
______X_, X_____X_, _X____X_, XX____X_, __X___X_, X_X___X_, _XX___X_, XXX___X_,
___X__X_, X__X__X_, _X_X__X_, XX_X__X_, __XX__X_, X_XX__X_, _XXX__X_, XXXX__X_,
____X_X_, X___X_X_, _X__X_X_, XX__X_X_, __X_X_X_, X_X_X_X_, _XX_X_X_, XXX_X_X_,
___XX_X_, X__XX_X_, _X_XX_X_, XX_XX_X_, __XXX_X_, X_XXX_X_, _XXXX_X_, XXXXX_X_,
_____XX_, X____XX_, _X___XX_, XX___XX_, __X__XX_, X_X__XX_, _XX__XX_, XXX__XX_,
___X_XX_, X__X_XX_, _X_X_XX_, XX_X_XX_, __XX_XX_, X_XX_XX_, _XXX_XX_, XXXX_XX_,
____XXX_, X___XXX_, _X__XXX_, XX__XXX_, __X_XXX_, X_X_XXX_, _XX_XXX_, XXX_XXX_,
___XXXX_, X__XXXX_, _X_XXXX_, XX_XXXX_, __XXXXX_, X_XXXXX_, _XXXXXX_, XXXXXXX_,
_______X, X______X, _X_____X, XX_____X, __X____X, X_X____X, _XX____X, XXX____X,
___X___X, X__X___X, _X_X___X, XX_X___X, __XX___X, X_XX___X, _XXX___X, XXXX___X,
____X__X, X___X__X, _X__X__X, XX__X__X, __X_X__X, X_X_X__X, _XX_X__X, XXX_X__X,
___XX__X, X__XX__X, _X_XX__X, XX_XX__X, __XXX__X, X_XXX__X, _XXXX__X, XXXXX__X,
_____X_X, X____X_X, _X___X_X, XX___X_X, __X__X_X, X_X__X_X, _XX__X_X, XXX__X_X,
___X_X_X, X__X_X_X, _X_X_X_X, XX_X_X_X, __XX_X_X, X_XX_X_X, _XXX_X_X, XXXX_X_X,
____XX_X, X___XX_X, _X__XX_X, XX__XX_X, __X_XX_X, X_X_XX_X, _XX_XX_X, XXX_XX_X,
___XXX_X, X__XXX_X, _X_XXX_X, XX_XXX_X, __XXXX_X, X_XXXX_X, _XXXXX_X, XXXXXX_X,
______XX, X_____XX, _X____XX, XX____XX, __X___XX, X_X___XX, _XX___XX, XXX___XX,
___X__XX, X__X__XX, _X_X__XX, XX_X__XX, __XX__XX, X_XX__XX, _XXX__XX, XXXX__XX,
____X_XX, X___X_XX, _X__X_XX, XX__X_XX, __X_X_XX, X_X_X_XX, _XX_X_XX, XXX_X_XX,
___XX_XX, X__XX_XX, _X_XX_XX, XX_XX_XX, __XXX_XX, X_XXX_XX, _XXXX_XX, XXXXX_XX,
_____XXX, X____XXX, _X___XXX, XX___XXX, __X__XXX, X_X__XXX, _XX__XXX, XXX__XXX,
___X_XXX, X__X_XXX, _X_X_XXX, XX_X_XXX, __XX_XXX, X_XX_XXX, _XXX_XXX, XXXX_XXX,
____XXXX, X___XXXX, _X__XXXX, XX__XXXX, __X_XXXX, X_X_XXXX, _XX_XXXX, XXX_XXXX,
___XXXXX, X__XXXXX, _X_XXXXX, XX_XXXXX, __XXXXXX, X_XXXXXX, _XXXXXXX, XXXXXXXX
};
#define MAX_PAGE 9
#define MAX_OFFSET 133
#define WAIT_WHILE_BUSY() { U8 Status; do { LCD_READ_A0(Status); } while (Status & (1 << 7)); }
#define WRITE_DATA(Data) CHECK_BUSY(); \
LCD_WRITE_A1(_aMirror[Data]); \
_VRam[_Page][_Offset] = Data
#define LCD_ON()
#define LCD_OFF()
#define SET_PAGE(Page) CHECK_BUSY(); LCD_WRITE_A0(0x40 + Page)
#define SET_OFFSET(Offset) CHECK_BUSY(); \
LCD_WRITE_A0(0x20 + (((Offset + LCD_XOFF) & 0x80) >> 5)); \
LCD_WRITE_A0(0x80 + ((Offset + LCD_XOFF) & 0x7F))
#endif
#define SET_PAGE_IF_NEEDED(Page) _SetPageIfNeeded(Page) /* Function call only in debug version */
#define SET_OFFSET_IF_NEEDED(Offset) _SetOffsetIfNeeded(Offset) /* Function call only in debug version */
#define WRITE_DATA1(Data) _WriteData1(Data) /* Function call only in debug version */
#define WRITE_DATAM(pData, NumberOfBytes) _WriteDataM(pData, NumberOfBytes)
#define GET_CURRENT_BYTE() _VRam[_Page][_Offset]
#define GET_BYTE(Page, Offset) _VRam[Page][Offset]
#if !LCD_CACHE
#error Not yet supported!
#endif
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
static int _Page, _Offset;
#if LCD_CACHE
static U8 _VRam[MAX_PAGE][MAX_OFFSET];
#endif
static const LCD_PIXELINDEX _ConversionTable[2] = {0, 1};
/*********************************************************************
*
* Static functions
*
**********************************************************************
*/
#if defined(INCREMENT_XY_VOLATILE)
static int _VolatileOffset, _VolatilePage;
static void _SetPageIfNeeded(int Page) {
if (_Page == Page)
return;
_Page = Page;
SET_PAGE(_Page);
_VolatilePage = 0;
if (_VolatileOffset) {
SET_OFFSET(_Offset);
_VolatileOffset = 0;
}
}
static void _SetOffsetIfNeeded(int Offset) {
if (_Offset == Offset)
return;
_Offset = Offset;
SET_OFFSET(_Offset);
_VolatileOffset = 0;
if (_VolatilePage) {
SET_PAGE(_Page);
_VolatilePage = 0;
}
}
static void _WriteData1(U8 Data) {
WRITE_DATA(Data);
_Offset++;
_VolatileOffset = 1;
if (_Offset == MAX_OFFSET) {
_Offset = 0;
_VolatilePage = 1;
if (_Page < (MAX_PAGE - 1)) {
++_Page;
} else {
_Page = 0;
}
}
}
static void _WriteDataM(U8 * pData, int NumberOfBytes) {
LCD_WRITEM_A1(pData, NumberOfBytes);
_Offset += NumberOfBytes;
_VolatileOffset = 1;
if (_Offset == MAX_OFFSET) {
_Offset = 0;
_VolatilePage = 1;
if (_Page < (MAX_PAGE - 1)) {
++_Page;
} else {
_Page = 0;
}
}
}
#elif defined(INCREMENT_XY)
static void _SetPageIfNeeded(int Page) {
if (_Page == Page)
return;
_Page = Page;
SET_PAGE(_Page);
}
static void _SetOffsetIfNeeded(int Offset) {
if (_Offset == Offset)
return;
_Offset = Offset;
SET_OFFSET(_Offset);
}
static void _WriteData1(U8 Data) {
WRITE_DATA(Data);
_Offset++;
if (_Offset == MAX_OFFSET) {
_Offset = 0;
if (_Page < (MAX_PAGE - 1)) {
++_Page;
} else {
_Page = 0;
}
}
}
static void _WriteDataM(U8 * pData, int NumberOfBytes) {
LCD_WRITEM_A1(pData, NumberOfBytes);
_Offset += NumberOfBytes;
if (_Offset == MAX_OFFSET) {
_Offset = 0;
if (_Page < (MAX_PAGE - 1)) {
++_Page;
} else {
_Page = 0;
}
}
}
#else
static void _SetPageIfNeeded(int Page) {
_Page = Page;
SET_PAGE(_Page);
}
static void _SetOffsetIfNeeded(int Offset) {
_Offset = Offset;
SET_OFFSET(_Offset);
}
static void _WriteData1(U8 Data) {
WRITE_DATA(Data);
}
static void _WriteDataM(U8 * pData, int NumberOfBytes) {
while(NumberOfBytes) {
WRITE_DATA(*pData);
if (--NumberOfBytes) {
pData++;
_Offset++;
SET_OFFSET(_Offset);
}
}
}
#endif
/*********************************************
*
* Draw Bitmap 1 BPP (optimized)
*
**********************************************
*/
#if LCD_OPTIMIZE \
&& !LCD_SWAP_XY \
&& !LCD_MIRROR_X \
&& !LCD_MIRROR_Y
static void _DrawBitLine1BPP(int x, int y, U8 const * pData, int ysize, const LCD_PIXELINDEX * pTrans, int BytesPerLine, U8 DataMask) {
LCD_PIXELINDEX Index0 = *(pTrans + 0);
LCD_PIXELINDEX Index1 = *(pTrans + 1);
U8 PixelMask = 1 << (y & 7);
int Page = y >> 3;
U8 Data;
Data = _VRam[Page][x];
switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
case 0:
while(ysize--) {
if (*pData & DataMask) {
if (Index1) {
Data |= PixelMask;
} else {
Data &= ~PixelMask;
}
} else {
if (Index0) {
Data |= PixelMask;
} else {
Data &= ~PixelMask;
}
}
pData += BytesPerLine;
PixelMask <<= 1;
if (!PixelMask || !ysize) {
_VRam[Page][x] = Data;
if (ysize) {
PixelMask = 1;
Data = _VRam[++Page][x];
}
}
}
break;
case LCD_DRAWMODE_TRANS:
while(ysize--) {
if (*pData & DataMask) {
if (Index1) {
Data |= PixelMask;
} else {
Data &= ~PixelMask;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -