?? lcd15xx.c
字號:
static int DataCacheY1;
#if LCD_SUPPORT_COMTRANS
static int DataCacheYBit0;
#else
#define DataCacheYBit0 DataCacheY0
#endif
/*
*****************************************
* *
* Set Page routines *
* *
*****************************************
These routines set the page-register of their respective
LCD-controller. Note that page is not what you might imagine,
but is a section of the controllers internal video RAM.
For details, please refer to the datasheet.
*/
static void SetPage0(void) {
SET_PAGE0(Page);
aPage[0] = Page;
}
#if (LCD_NUM_CONTROLLERS > 1)
static void SetPage1(void) {
SET_PAGE1(Page);
aPage[1] = Page;
}
#endif
#if (LCD_NUM_CONTROLLERS > 2)
static void SetPage2(void) {
SET_PAGE2(Page);
aPage[2] = Page;
}
#endif
#if (LCD_NUM_CONTROLLERS > 3)
static void SetPage3(void) {
SET_PAGE3(Page);
aPage[3] = Page;
}
#endif
/*
*****************************************
* *
* Set column routines *
* *
*****************************************
*/
static void SetCAdr0(void) {
#if LCD_SEGOFF0
U8 ColP = Col+LCD_SEGOFF0;
#else
#define ColP Col
#endif
SET_CADR0(ColP);
aCAdr[0] = Col;
#if !LCD_SEGOFF0
#undef ColP
#endif
}
#if (LCD_NUM_CONTROLLERS > 1)
static void SetCAdr1(void) {
#if LCD_SEGOFF1
U8 ColP = Col+LCD_SEGOFF1;
#else
#define ColP Col
#endif
SET_CADR1(ColP);
aCAdr[1] = Col;
#if !LCD_SEGOFF1
#undef ColP
#endif
}
#endif
#if (LCD_NUM_CONTROLLERS > 2)
static void SetCAdr2(void) {
#if LCD_SEGOFF2
U8 ColP = Col+LCD_SEGOFF2;
#else
#define ColP Col
#endif
SET_CADR2(ColP);
aCAdr[2] = Col;
#if !LCD_SEGOFF2
#undef ColP
#endif
}
#endif
#if (LCD_NUM_CONTROLLERS > 3)
static void SetCAdr3(void) {
#if LCD_SEGOFF3
U8 ColP = Col+LCD_SEGOFF3;
#else
#define ColP Col
#endif
SET_CADR3(ColP);
aCAdr[3] = Col;
#if !LCD_SEGOFF3
#undef ColP
#endif
}
#endif
/*
*****************************************
* *
* Read video memory routines *
* *
*****************************************
*/
#if !LCD_CACHE
static U8 ReadVMem0() {
if (Page !=aPage[0])
SetPage0();
if (Col != aCAdr[0])
SetCAdr0();
aCAdr[0]+=2;
LCD_ReadData0(Data); /* Dummy read */
return LCD_ReadData0(Data);
}
#else
#define ReadVMem0() (*pCacheByte)
#endif
#if (LCD_NUM_CONTROLLERS > 1)
#if !LCD_CACHE
U8 ReadVMem1() {
if (Page !=aPage[1])
SetPage1();
if (Col != aCAdr[1])
SetCAdr1();
aCAdr[1]+=2;
LCD_ReadData1(Data); /* Dummy read */
return LCD_ReadData1(Data);
}
#else
#define ReadVMem1() (*pCacheByte)
#endif
#endif /* LCD_NUM_CONTROLLERS >1 */
#if (LCD_NUM_CONTROLLERS > 2)
#if !LCD_CACHE
U8 ReadVMem2() {
if (Page !=aPage[2])
SetPage2();
if (Col != aCAdr[2])
SetCAdr2();
aCAdr[2]+=2;
LCD_ReadData2(Data); /* Dummy read */
return LCD_ReadData2(Data);
}
#else
#define ReadVMem2() (*pCacheByte)
#endif
#endif
#if (LCD_NUM_CONTROLLERS > 3)
#if !LCD_CACHE
U8 ReadVMem3() {
if (Page !=aPage[3])
SetPage3();
if (Col != aCAdr[3])
SetCAdr3();
aCAdr[3]+=2;
LCD_ReadData3(Data); /* Dummy read */
return LCD_ReadData3(Data);
}
#else
#define ReadVMem3() (*pCacheByte)
#endif
#endif
/*
*****************************************
* *
* Write video memory routines *
* *
*****************************************
*/
#if LCD_SUPPORT_CACHECONTROL
#define CHECK_CACHE_LOCK(Con) \
if (CacheLocked) { \
U8 ColOff = Col -LCD_FIRSTSEG##Con; \
U8 Bit = ColOff&7; \
aaCacheDirtyTag##Con[Page][ColOff>>3] |= (1<<Bit); \
CacheStat = 1; /* Mark cache as dirty */ \
return; \
}
#else
#define CHECK_CACHE_LOCK(LCDCON)
#endif
#define WRITE_VMEM(Con) \
CHECK_CACHE_LOCK(Con); \
if (Page !=aPage[Con]) \
SetPage##Con(); \
if (Col != aCAdr[Con]) \
SetCAdr##Con(); \
LCD_LOCK(); \
WRITE_DATA##Con(DataW_Cache); \
LCD_UNLOCK(); \
aCAdr[Con]++;
#if !LCD_CACHE_WRITETHRU
#define RETURN_IF_WRITE_NOT_NEEDED(Con) \
if ( *pCacheByte == DataW_Cache) \
return;
#else
#define RETURN_IF_WRITE_NOT_NEEDED(Con)
#endif
#if LCD_CACHE
#define CHECK_VMEM_CACHE(Con) \
RETURN_IF_WRITE_NOT_NEEDED(Con); \
*pCacheByte = DataW_Cache;
#else
#define CHECK_VMEM_CACHE(Con)
#endif
static void WriteVMem0(void) {
CHECK_VMEM_CACHE(0);
WRITE_VMEM(0);
}
#if (LCD_NUM_CONTROLLERS > 1)
static void WriteVMem1(void) {
CHECK_VMEM_CACHE(1);
WRITE_VMEM(1);
}
#endif
#if (LCD_NUM_CONTROLLERS > 2)
static void WriteVMem2(void) {
CHECK_VMEM_CACHE(2);
WRITE_VMEM(2);
}
#endif
#if (LCD_NUM_CONTROLLERS > 3)
static void WriteVMem3(void) {
CHECK_VMEM_CACHE(3);
WRITE_VMEM(3);
}
#endif
/*
********************************************************************
* *
* Write Cache control *
* *
********************************************************************
In order to speed up access to the LCD and to avoid flickering, it
can be necessary to lock the write cache. This means that all drawing
commands do not affect the hardware it the cache is locked until
the flush (or unlock) command is given.
Note: The code could be shortened a bit by defining an add. macro
for the code for every controller. This has not been done
because it would make debugging even harder.
(It is already hard enough)
*/
#define CHECK_CACHE_BYTE_DIRTY(Controller,Bit) \
if (Dirty&(1<<Bit)) { \
if (page !=aPage[Controller]) { \
Page = page; \
SetPage##Controller(); \
} \
if (col+Bit != aCAdr[Controller]) { \
Col = col+Bit; \
SetCAdr##Controller(); \
} \
LCD_WriteData##Controller(Cache##Controller[page][col+Bit]); \
aCAdr[Controller]++; \
}
#define FLUSH_CACHE_X(Con) \
for (page=0; page<NUM_PAGES##Con; page++) { \
for (col8=0; col8<(NUM_COLS##Con+7)/8; col8++) { \
U8 Dirty; \
if ((Dirty=aaCacheDirtyTag##Con[page][col8]) !=0) { \
int col = col8<<3; \
aaCacheDirtyTag##Con[page][col8] =0; \
CHECK_CACHE_BYTE_DIRTY(Con,0); \
CHECK_CACHE_BYTE_DIRTY(Con,1); \
CHECK_CACHE_BYTE_DIRTY(Con,2); \
CHECK_CACHE_BYTE_DIRTY(Con,3); \
CHECK_CACHE_BYTE_DIRTY(Con,4); \
CHECK_CACHE_BYTE_DIRTY(Con,5); \
CHECK_CACHE_BYTE_DIRTY(Con,6); \
CHECK_CACHE_BYTE_DIRTY(Con,7); \
} \
} \
}
#if LCD_SUPPORT_CACHECONTROL
static void FlushCache(void) {
int page;
int col8; /* Column index, 1 inc skips 8 bytes */
FLUSH_CACHE_X(0);
#if (LCD_NUM_CONTROLLERS >1)
FLUSH_CACHE_X(1);
#endif
#if (LCD_NUM_CONTROLLERS >2)
FLUSH_CACHE_X(2);
#endif
#if (LCD_NUM_CONTROLLERS >3)
FLUSH_CACHE_X(3);
#endif
/* Important !!!
We have to make sure that the byte-level cache is not level
inconsistent because we have modified the Page/Col values. This
is done by invalidating the x-position. */
DataCacheX=-1;
}
U8 LCD_L0_ControlCache(U8 cmd) {
switch (cmd) {
case LCD_CC_LOCK: /* Set Cache to lock state.*/
CacheLocked =1;
break;
case LCD_CC_UNLOCK: /* Set Cache to unlock state ... must flush !*/
CacheLocked =0;
case LCD_CC_FLUSH: /* Flush cache */
if (CacheStat) {
CacheStat =0;
FlushCache();
}
}
return CacheStat;
}
#endif
/*
********************************************************************
* *
* *
* Internal video memory management *
* *
* *
********************************************************************
This contains the internal video management of this driver, which is
the core of it. It has been designed with the following goals:
+ Support for all types of orientaions of display
+ Support for multiple controllers
+ Support for both parallel and serial interface
+ Small RAM footprint
+ Fast execution on all CPUs in all configurations
+ Small code
It has taken a considerable amount of time to develop, optimize and
test the concept of this driver. It should pretty much cover most LCDs
using 15XX controllers; if you feel your configuration is not covered
by this driver, please get
in contact with us, preferably via email (support@segger.com).
*/
#define FLUSH() if (DataW_Dirty) Flush()
/* For XOR operations, the byte needs to be loaded in order to
perform the operation. We also have to make sure that bits which
have been previously modified are not forgotten.
This essentially means loading only the unmodified bits (for which
the bit in DATAW_Dirty is ==0) and leave the other ones unchanged.
*/
#define LOADDATA() \
if (!DataR_Valid) { \
ReadData(); \
DataW_Cache &= DataW_Dirty; \
DataW_Cache |= DataR_Cache&(~DataW_Dirty); \
}
#if LCD_CACHE
#define ReadData() DataR_Cache = *pCacheByte; DataR_Valid= 0xff;
#else
static void ReadData(void) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -