LCD15XX.c
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:95k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/GUI
  4. *                        Universal graphic software for embedded applications
  5. *
  6. *                       (c) Copyright 2002, Micrium Inc., Weston, FL
  7. *                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
  8. *
  9. *              礐/GUI is protected by international copyright laws. Knowledge of the
  10. *              source code may not be used to write a similar product. This file may
  11. *              only be used in accordance with a license and should not be redistributed
  12. *              in any way. We appreciate your understanding and fairness.
  13. *
  14. ----------------------------------------------------------------------
  15. File        : LCD15XX.C
  16. Purpose     : Driver for LCDs using Seiko Epson SED15XX controllers     
  17.               The current version supports up to 4 LCD controllers in   
  18.               (almost) any hardware configuration. The following
  19.                derivatives are currently supported:
  20.                Epson SED1560
  21.                Epson SED1565  132*65  BW
  22.                Epson SED1566  132*49  BW   (untested due to lack of hardware)
  23.                Epson SED1567  132*33  BW   (untested due to lack of hardware)
  24.                Epson SED1568  132*55  BW   (untested due to lack of hardware)
  25.                Epson SED1569  132*53  BW   (untested due to lack of hardware)
  26.                Epson SED1575  132*200 BW
  27.                Samsung KS0108B
  28.                Hitachi HD61202
  29.                
  30.                Other Epson LCD controllers are very similar and could
  31.                be covered by this driver as well, but are not
  32.                currently supported.
  33. ----------------------------------------------------------------------
  34. Version-Date---Author-Explanation
  35. ----------------------------------------------------------------------
  36. 2.02e   020716 JE     a) Support for KS0108B & HD61202 added
  37. 2.02d   020715 JE     a) Reworked to work with 2 LCD-controllers
  38. 2.02c   020204 JE     a) Hardwareinterface routines renamed:
  39.                          ...DATA -> ...A1, ...CMD -> ...A0
  40. 2.02b   010706 JE     a) BUGFIXES: DrawBitLine1BPP_NoSwap
  41. 2.02a   010402 RS     a) LCD_GetDevCaps removed from driver
  42.                          (now LCD.c)
  43. 2.02    010329 JE     a) Completely revised, tested without mirror & swap
  44. 2.00    001107 RS     a) New driver interface V2.00 used
  45. 1.32.01 000321 RS     a) BUGFIX: LCD__ClearVRam: aCAdr set to LCD_SEGS_MAX-1
  46.                       b) BUGFIX: Flush: DataR_Cache = DataW_Cache inserted
  47.                JE     c) BUGFIX: ASSIGN_PIXEL_FAST now takes account 
  48.                          of LCD_DRAWMODE_XOR
  49.                       d) BUGFIX: DrawBitLine1BPP_NoSwap XORMODE now works
  50.                       e) BUGFIX: DrawBitLine1BPP_NoSwap clipping now works
  51.                       f) BUGFIX: FindByte: -LCD_FIRSTSEG0 removed
  52.                       g) BUGFIX: LCD_RefreshSection: -LCD_FIRSTSEG0 removed
  53.                       h) LCD_DrawBit now checks number of colors
  54. 1.32.00 990930 RS     a) LCD_Init now returns an int
  55.                       b) bit changed -> Bit in order to vaoid problems
  56.                          with IAR compilers
  57. 1.31.06 990926 RS     a) Code is generated now only if LCD_CONTROLLER
  58.                          is in the range of 1500 - 1599, allowing to
  59.  compile all LCD drivers with a project, making
  60.  the selection in the config file.
  61.   b) Config defaults added
  62. 1.31.05 990922 RS/BB  a) Number of Segments for 1575 changed from 168
  63.                          to 200. 200 is correct because the controller
  64.  has RAM for 200 segments, even thou just 168
  65.  segment lines
  66.   b) Transparency support for bitmaps in
  67.      DrawBitLine1BPP_Swap added
  68. 1.31.04 990810 RS     a) LCD__ClearVRam: Cut and paste error elimiated
  69.                          (Relevant only in 4 controller system)
  70.   b) Transparency problem in DrawBitLine1BPP_Swap
  71.      eliminated
  72.   c) CALCXY: LCD_FIRSTSEG had been subtracted,
  73.      but had already been subtracted before. Could
  74.  lead to a an offset in the memory area used as
  75.  video RAM if LCD_FIRSTSEG<x>  != 0.
  76.  Fixed.
  77.   d) FlushCache-routine simplified for easier
  78.      maintanance using a macro
  79.       e) Bugfix in FlushCache-routine --- untested
  80.      due to lack of hardware !
  81. 1.31.03 990720 RS     a) Compile problem in single-controller system
  82.                          (CurController) fixed
  83.                       b) GotoYPlus1(void) Prototype: Parameterlist:
  84.      () replaced by (void) to avoid comiler warning
  85. 1.31.02 990713 RS     a) All (global/static) variables are initialized in
  86.                          LCD_Init. This turned out to be necessary as not
  87.  all systems comply with ANSI-"C" and automatically
  88.  initialize these variables with 0.
  89. 1.31.01 990712 RS     a) Cache locking bug for systems with seg/Com lookup
  90.                          tables fixed. Cache writeout accelerated.
  91. 1.31.00 990712 RS     a) FindByte made leaner and converted to a macro
  92.                          for 2 controller systems, resulting in improved
  93.  performance
  94.   b) Internal DrawLine /DrawBitmap routines
  95.      improved for higher performance and better
  96.  readability
  97.   c) Inline versions of SetPixel/ClrPixel created, as
  98.      well as fast versions of ASSIGN_PIXEL
  99.  (again: for better performance !)
  100. 1.30.03 990709 RS     a) Structural changes leading to clearer
  101.                          structure and higher performance
  102.                    b) FindByte Optimization for 2-Controller system
  103.                c) Bugfix: One of the previous optimizations
  104.                  could lead to a duplicated byte in video memory
  105.                when LCD_DrawByte was called fo very
  106.              narrow bitmaps. Fixed.
  107. 1.30.02 990708 RS     a) ReadData optimized if all bytes are
  108.                          in Cache (macro, no switch statement)
  109. 1.30.01 990707 RS     a) Add. Optimization in FindByte
  110. 1.30.00 990707 RS     a) Various optimizations impemented, esp.
  111.                          if translation (lookup) table for COMs is
  112.                                           activated
  113. 1.21.02 990617 RS     a) Macro bug (created in 1.21.01) cleaned up
  114.                       b) Page 8 of all controllers cleared during
  115.                          init in order to make sure that the COMS
  116.                          signal can be used and the data for it is
  117.                          cleared to 0
  118.                       c) Problem with segment table fixed ...
  119.                          If used, the segments were moved by LCD_FIRSTSEG<X>
  120. 1.21.01 990615 RS     a) Some more macros generated in order to
  121.                          keep the driver easy to maintain
  122.                       b) Com-offset is now subtracted from Cache<X>
  123.                          index (in order to avoid potential bounds
  124.                          problem): e.g.:
  125.                          Cache0[Page][Col] --> Cache0[Page][Col-LCD_FIRSTSEG0]
  126. 1.21.00 990615 RS     a) When using segment/com lookup tables,
  127.                          the macro-values
  128.                          LCD_NUM_COMS0, LCD_NUM_COMS0
  129.                          LCD_NUM_COMS1, LCD_NUM_COMS1 (controller 1)
  130.                          Have to be defined.
  131.                          Add. configuration checking added.
  132. 1.20.02 990614 RS     a) LCD_Init did not clear VMem for 3. and 4.
  133.                          controller. Fixed.
  134.                          configuration switches eliminated
  135. 1.20.01 990614 RS     a) Problem with certain combination of
  136.                          configuration switches eliminated
  137. 1.20.00 990614 RS     a) Optional segment and com translation tables
  138.                          supported. This turned out to be necessary
  139.                          as with some LCDs the COM/SEG lines are
  140.                          completely mixed up. The translation tables
  141.                          have to be defined in a seperate file
  142.                          (sample supplied in LCDTable.c) in
  143.                          order to make sure that the code in this
  144.                          driver does not have to be changed.
  145. 1.10.00 990505 RS     a) Optional support for Cache locking added.
  146.                          It now requires the add. configuration switch
  147.                          LCD_SUPPORT_CACHECONTROL
  148. 1.04.00 990420 AW/RS  a) Support for 1560 added.
  149. 1.03.03 990322 RS     a) Bitmaps have not been properly cut off at the
  150.                          end of the clipping region. Fixed
  151.                       b) Clipping for horizontal/vert. lines
  152.                          implemented
  153. 1.03.02 990319 RS     a) When writing bitmaps in XOR-Mode, the LCD   
  154.                          cache was not automatically flushed.
  155.                          Fixed.
  156. 1.03.01 990319 RS     a) (Kuennemann) If multiple LCD-controllers had
  157.                          been used in a horizontal array (different
  158.                          SEG lines with SEG<X> > 0) the page
  159.                          calculation did not take the SEG<X> value
  160.                          into account. Fixed.
  161.                       b) (Kuennemann)
  162.                          LCD_Init(): VRAM of controller2/3 was not
  163.                          cleared in a 3 or 4 controller system.
  164.                          Fixed.
  165.                       c) LCD_SetInverse / LCD_ClrInverse:
  166.                          These routines did not write the command to
  167.                          all LCD-controllers, but only to the first
  168.                          one. Fixed.
  169. 1.03.00 990317 RS     a) XOR Mode implemented for all configurations
  170.                       b) DrawVLine accelerated
  171. 1.02.03 990218 RS     a) (Kuennemann) If multiple LCD-controllers had
  172.                          been used in a vertical array (different
  173.                          COM lines with COM<X> > 0) the page
  174.                          calculation did not take the COM<X> value
  175.                          into account. Fixed.
  176.                       b) Driver should now also work with 4
  177.                          controllers. However, this configuration is
  178.                          still untested. The #error is taken out.
  179. 1.02.02 990217 RS     a) LCD_GetVisPage, LCD_GetSelPage added
  180. 1.02.01 990216 RS     a) LCD_GetPixel implemented
  181.                       b) Support for GetDeviceCaps added
  182.                       c) Support for Drawmode can now be disabled via
  183.                          config switch
  184. 1.02.00 990212 RS     a) Include file string.h put back in in order to
  185.                       be able to completly reset the LCD, including
  186.                       clearing the cache
  187.                       b) LCD_Refresh implemented
  188.                       c) Support for physical bitmaps added
  189.                       d) Support for LCD_REVERSE added
  190.                       e) Support for Write-thru cache added
  191. 1.01.01 990203 RS     a) Include file string.h no longer needed,
  192.                       taken out
  193. 1.01.00 990203 RS     a) Cache no longer filled with 0 using memset
  194.                        (We trust the compiler to do the job for us.)
  195. 1.00.02 990202 RS     Support for up to 4 controllers implemented
  196. 1.00.01 990128 RS     Changes in header-configuration  as discussed
  197.                       with BB
  198. 1.00    990118 RS     First release for up to 2 LCD controllers *
  199. ----------------------------------------------------------------------
  200. Known problems or limitations with current version
  201. ----------------------------------------------------------------------
  202. Due to the change to interface version 2.0,
  203. The draw bitline routines has been temp. disabled
  204. The routines:
  205. LCD_L0_SetPixelIndex
  206. LCD_L0_XorPixel
  207. LCD_L0_GetPixelIndex
  208. need to be proberly implemented
  209. ----------------------------------------------------------------------
  210. Possible optimizations
  211. ----------------------------------------------------------------------
  212. ---------------------------END-OF-HEADER------------------------------
  213. */
  214. #include <string.h>             /* for memset */
  215. #include <stddef.h>           /* needed for definition of NULL */
  216. #include "LCD_Private.h"      /* private modul definitions & config */
  217. #include "GUI_Private.h"
  218. #include "GUIDebug.h"
  219. #include "LCD_0.h"            /* Defines for first display */
  220. #if   (   (LCD_CONTROLLER/100 ==    15) 
  221.        || (LCD_CONTROLLER     ==  0713) 
  222.        || (LCD_CONTROLLER     ==   108) 
  223.        || (LCD_CONTROLLER     == 61202) 
  224.       ) 
  225.       && (LCD_CONTROLLER/100 != 0x15E05 ) 
  226.       && (!defined(WIN32) | defined(LCD_SIMCONTROLLER))
  227. /*
  228.         *********************************************************
  229.         *                                                       *
  230.         *           Compiler specific settings                  *
  231.         *                                                       *
  232.         *********************************************************
  233. */
  234. #ifdef WIN32   /* Avoid warnings in MS-compiler */
  235.   #pragma warning(disable : 4244)  // warning C4244: '=' : conversion from 'long ' to 'unsigned char ', possible loss of data
  236.   #pragma warning(disable : 4761)  // warning C4761: integral size mismatch in argument; conversion supplied
  237.   #pragma warning(disable : 4305)  // warning C4305: '=' : truncation from 'const int ' to ...
  238. #endif
  239. #ifndef LCD_DISPLAY_INDEX
  240.   #define LCD_DISPLAY_INDEX 0
  241. #endif
  242. /*********************************************************************
  243. *
  244. *      Map hardware macros
  245. *
  246. **********************************************************************
  247. */
  248. /* mapping for multi-display configuration */
  249. #if (LCD_NUM_DISPLAYS > 1)
  250.   #if   (LCD_DISPLAY_INDEX == 0)     /* First display in a multi-display configuration */
  251.     #define LCD_WRITE_A0   LCD_WRITE_A0_0
  252.     #define LCD_WRITE_A1   LCD_WRITE_A1_0
  253.     #define LCD_WRITE_A0C1 LCD_WRITE_A0C1_0
  254.     #define LCD_WRITE_A1C1 LCD_WRITE_A1C1_0
  255.     #define LCD_WRITE_A0C2 LCD_WRITE_A0C2_0
  256.     #define LCD_WRITE_A1C2 LCD_WRITE_A1C2_0
  257.     #define LCD_WRITE_A0C3 LCD_WRITE_A0C3_0
  258.     #define LCD_WRITE_A1C3 LCD_WRITE_A1C3_0
  259.     #define LCD_READ_A0    LCD_READ_A0_0
  260.     #define LCD_READ_A0    LCD_READ_A0_0
  261.     #define LCD_READ_A0C1  LCD_READ_A0C1_0
  262.     #define LCD_READ_A0C1  LCD_READ_A0C1_0
  263.     #define LCD_READ_A0C2  LCD_READ_A0C2_0
  264.     #define LCD_READ_A0C2  LCD_READ_A0C2_0
  265.     #define LCD_READ_A0C3  LCD_READ_A0C3_0
  266.     #define LCD_READ_A0C3  LCD_READ_A0C3_0
  267.   #elif (LCD_DISPLAY_INDEX == 1)  /* Second display in a multi-display configuration */
  268.     #define LCD_WRITE_A0   LCD_WRITE_A0_1
  269.     #define LCD_WRITE_A1   LCD_WRITE_A1_1
  270.     #define LCD_WRITE_A0C1 LCD_WRITE_A0C1_1
  271.     #define LCD_WRITE_A1C1 LCD_WRITE_A1C1_1
  272.     #define LCD_WRITE_A0C2 LCD_WRITE_A0C2_1
  273.     #define LCD_WRITE_A1C2 LCD_WRITE_A1C2_1
  274.     #define LCD_WRITE_A0C3 LCD_WRITE_A0C3_1
  275.     #define LCD_WRITE_A1C3 LCD_WRITE_A1C3_1
  276.     #define LCD_READ_A0    LCD_READ_A0_1
  277.     #define LCD_READ_A0    LCD_READ_A0_1
  278.     #define LCD_READ_A0C1  LCD_READ_A0C1_1
  279.     #define LCD_READ_A0C1  LCD_READ_A0C1_1
  280.     #define LCD_READ_A0C2  LCD_READ_A0C2_1
  281.     #define LCD_READ_A0C2  LCD_READ_A0C2_1
  282.     #define LCD_READ_A0C3  LCD_READ_A0C3_1
  283.     #define LCD_READ_A0C3  LCD_READ_A0C3_1
  284.   #else
  285.     #error This many displays not yet supported !
  286.   #endif
  287. #endif
  288. /* Command definitions in dependence of selected LCD-controller */
  289. #if   (LCD_CONTROLLER/100 == 15) || (LCD_CONTROLLER     ==  0713)
  290.   #define SET_PAGE0(Page) LCD_WriteSingleCommand0(0xb0 + Page)
  291.   #define SET_CADR0(Col)  LCD_WriteDoubleCommand0(0x10 + (Col >> 4), 0x00 + (Col & 0xf))
  292.   #define CMD_LCD_ON      0xaf
  293.   #define CMD_LCD_OFF     0xae
  294.   #define WAIT0()
  295.   #define WAIT1()
  296.   #define WAIT2()
  297.   #define WAIT3()
  298. #elif (LCD_CONTROLLER ==  108) || (LCD_CONTROLLER == 61202)
  299.   static int _Status;
  300.   #define SET_PAGE0(Page) LCD_WriteSingleCommand0(0xb8 + Page);
  301.   #define SET_CADR0(Col)  LCD_WriteSingleCommand0(0x40 + Col);
  302.   #if (LCD_NUM_CONTROLLERS > 1)
  303.     #define SET_PAGE1(Page) LCD_WriteSingleCommand1(0xb8 + Page);
  304.     #define SET_CADR1(Col)  LCD_WriteSingleCommand1(0x40 + Col);
  305.   #endif
  306.   #define CMD_LCD_ON      0x3f
  307.   #define CMD_LCD_OFF     0x3e
  308.   #define WAIT0()         do { LCD_READ_A0(_Status); }   while (_Status & 0x80);
  309.   #define WAIT1()         do { LCD_READ_A0C1(_Status); } while (_Status & 0x80);
  310.   #define WAIT2()         do { LCD_READ_A0C2(_Status); } while (_Status & 0x80);
  311.   #define WAIT3()         do { LCD_READ_A0C3(_Status); } while (_Status & 0x80);
  312. #else
  313.   #error LCD-controller not supported!
  314. #endif
  315. #ifdef WIN32     /* SEGGER internal simulation */
  316.   void SIM_WriteA1C0(U8 Data);
  317.   void SIM_WriteA0C0(U8 cmd);
  318.   U8   SIM_ReadA0C0(void);
  319.   U8   SIM_ReadA1C0(void);
  320.   #define WRITE_DATA0(Data) SIM_WriteA1C0(Data) 
  321.   #define WRITE_CMD0(cmd)   SIM_WriteA0C0(cmd)
  322.   #define READ_DATA0(Data)  Data = SIM_ReadA1C0()
  323.   #define READ_CMD0(cmd)    cmd  = SIM_ReadA0C0()
  324.   #define INIT_CONTROLLER()
  325.   #if LCD_NUM_CONTROLLERS > 1
  326.     void SIM_WriteA1C1(U8 Data);
  327.     void SIM_WriteA0C1(U8 cmd);
  328.     U8   SIM_ReadA0C1(void);
  329.     U8   SIM_ReadA1C1(void);
  330.     #define WRITE_DATA1(Data) SIM_WriteA1C1(Data) 
  331.     #define WRITE_CMD1(cmd)   SIM_WriteA0C1(cmd)
  332.     #define READ_DATA1(Data)  Data = SIM_ReadA1C1()
  333.     #define READ_CMD1(cmd)    cmd  = SIM_ReadA0C1()
  334.   #endif
  335.   #if LCD_NUM_CONTROLLERS > 2
  336.     void SIM_WriteA1C2(U8 Data);
  337.     void SIM_WriteA0C2(U8 cmd);
  338.     U8   SIM_ReadA0C2(void);
  339.     U8   SIM_ReadA1C2(void);
  340.     #define WRITE_DATA2(Data) SIM_WriteA1C2(Data) 
  341.     #define WRITE_CMD2(cmd)   SIM_WriteA0C2(cmd)
  342.     #define READ_DATA2(Data)  Data = SIM_ReadA1C2()
  343.     #define READ_CMD2(cmd)    cmd  = SIM_ReadA0C2()
  344.   #endif
  345.   #if LCD_NUM_CONTROLLERS > 3
  346.     void SIM_WriteA1C3(U8 Data);
  347.     void SIM_WriteA0C3(U8 cmd);
  348.     U8   SIM_ReadA0C3(void);
  349.     U8   SIM_ReadA1C3(void);
  350.     #define WRITE_DATA3(Data) SIM_WriteA1C3(Data) 
  351.     #define WRITE_CMD3(cmd)   SIM_WriteA0C3(cmd)
  352.     #define READ_DATA3(Data)  Data = SIM_ReadA1C3()
  353.     #define READ_CMD3(cmd)    cmd  = SIM_ReadA0C3()
  354.   #endif
  355. #else
  356.   #define WRITE_CMD0(cmd)   WAIT0(); LCD_WRITE_A0(cmd)
  357.   #define WRITE_DATA0(Data) WAIT0(); LCD_WRITE_A1(Data)
  358.   #define READ_DATA0(Data)  WAIT0(); LCD_READ_A1(Data)
  359.   #define READ_CMD0(cmd)    WAIT0(); LCD_READ_A0(cmd)
  360.   #define INIT_CONTROLLER  LCD_INIT_CONTROLLER
  361.   #if LCD_NUM_CONTROLLERS > 1
  362.     #define WRITE_CMD1(cmd)   WAIT1(); LCD_WRITE_A0C1(cmd)
  363.     #define WRITE_DATA1(Data) WAIT1(); LCD_WRITE_A1C1(Data)
  364.     #define READ_DATA1(Data)  WAIT1(); LCD_READ_A1C1(Data)
  365.     #define READ_CMD1(cmd)    WAIT1(); LCD_READ_A0C1(cmd)
  366.   #endif
  367.   #if LCD_NUM_CONTROLLERS > 2
  368.     #define WRITE_CMD2(cmd)   WAIT(2); LCD_WRITE_A0C2(cmd)
  369.     #define WRITE_DATA2(Data) WAIT(2); LCD_WRITE_A1C2(Data)
  370.     #define READ_DATA2(Data)  WAIT(2); LCD_READ_A1C2(Data)
  371.     #define READ_CMD2(cmd)    WAIT(2); LCD_READ_A0C2(cmd)
  372.   #endif
  373.   #if LCD_NUM_CONTROLLERS > 3
  374.     #define WRITE_CMD3(cmd)   WAIT(3); LCD_WRITE_A0C3(cmd)
  375.     #define WRITE_DATA3(Data) WAIT(3); LCD_WRITE_A1C3(Data)
  376.     #define READ_DATA3(Data)  WAIT(3); LCD_READ_A1C3(Data)
  377.     #define READ_CMD3(cmd)    WAIT(3); LCD_READ_A0C3(cmd)
  378.   #endif
  379. #endif
  380. /*
  381.   ********************************************************************
  382.   *
  383.   *                  ID translation table
  384.   *
  385.   ********************************************************************
  386. This table contains 0, 1, 2, ... and serves as translation table for DDBs
  387. */
  388. #define INTS(Base)  Base+0,Base+1,Base+2,Base+3,Base+4,Base+5,   
  389.                     Base+6,Base+7,Base+8,Base+9,Base+10,Base+11, 
  390.                     Base+12,Base+13,Base+14,Base+15
  391. static const LCD_PIXELINDEX aID[] = {
  392.   INTS(0),
  393.   #if LCD_MAX_LOG_COLORS > 0x10
  394.     INTS(0x10),
  395.   #endif
  396.   #if LCD_MAX_LOG_COLORS > 0x20
  397.     INTS(0x20),
  398.     INTS(0x30),
  399.   #endif
  400.   #if LCD_MAX_LOG_COLORS > 0x40
  401.     INTS(0x40),
  402.     INTS(0x50),
  403.     INTS(0x60),
  404.     INTS(0x70),
  405.   #endif
  406.   #if LCD_MAX_LOG_COLORS > 0x80
  407.     INTS(0x80),
  408.     INTS(0x90),
  409.     INTS(0xa0),
  410.     INTS(0xb0),
  411.     INTS(0xc0),
  412.     INTS(0xd0),
  413.     INTS(0xe0),
  414.     INTS(0xf0)
  415.   #endif
  416. };
  417. /*
  418.   ********************************************************************
  419.   *                                                                  *
  420.   *                Defaults for config switches                      *
  421.   *                                                                  *
  422.   ********************************************************************
  423. */
  424. #ifndef LCD_CACHE
  425.   #define  LCD_CACHE (1)
  426. #endif
  427. #ifndef LCD_SUPPORT_REFRESH
  428.   #define  LCD_SUPPORT_REFRESH LCD_CACHE
  429. #endif
  430. #ifndef LCD_REVERSEMODE_SUPPORT
  431.   #define LCD_REVERSEMODE_SUPPORT (0)
  432. #endif
  433. #ifndef LCD_SUPPORT_VERIFY
  434.   #define LCD_SUPPORT_VERIFY (0)
  435. #endif
  436. /* Drivers supports anti-aliasing if active. */
  437. #ifndef LCD_SUPPORT_ANTIALIASING
  438.   #define LCD_SUPPORT_ANTIALIASING (0)
  439. #endif
  440. /* Switch for support of cache control (locking) */
  441. #ifndef  LCD_SUPPORT_CACHECONTROL
  442.   #define  LCD_SUPPORT_CACHECONTROL     (1)
  443. #endif
  444. /* Switch support for the LCD_CopyRect function of the driver */
  445. #ifndef  LCD_SUPPORT_COPYRECT
  446.   #define  LCD_SUPPORT_COPYRECT         (1)
  447. #endif
  448. /* If disabled, selected drawmode is ignored.
  449.    ==> XOR, REVERSE drawing not supported */
  450. #ifndef LCD_SUPPORT_DRAWMODE
  451.   #define LCD_SUPPORT_DRAWMODE          (1)
  452. #endif
  453. /* Switch support for the LCD_On, LCD_Off functions of the driver */
  454. #ifndef  LCD_SUPPORT_ONOFF
  455.   #define  LCD_SUPPORT_ONOFF            (1)
  456. #endif
  457. /* Switch for support of multiple pages.
  458.  Only available with certain LCD-controllers */
  459. #ifndef LCD_SUPPORT_PAGING
  460.   #define LCD_SUPPORT_PAGING            (0)
  461. #endif
  462. /* Switch for support of run-time inversion of display. */
  463. #ifndef LCD_SUPPORT_REVERSEMODE
  464.   #define LCD_SUPPORT_REVERSEMODE       (0)
  465. #endif
  466. /* Switch support for the LCD_SetOrg function of the driver */
  467. #ifndef LCD_SUPPORT_SETORG
  468.   #define LCD_SUPPORT_SETORG            (0)
  469. #endif
  470. /* Switch for support of refreshing video RAM. */
  471. #ifndef LCD_SUPPORT_REFRESH
  472.   #define LCD_SUPPORT_REFRESH           (0)
  473. #endif
  474. #ifndef LCD_SCHEDULE_CNT
  475.   #define LCD_SCHEDULE_CNT 0
  476. #endif
  477. #ifndef LCD_NUM_CONTROLLERS
  478.   #define LCD_NUM_CONTROLLERS (1)
  479. #endif
  480. #ifndef LCD_LOCK
  481.   #define LCD_LOCK()
  482. #endif
  483. #ifndef LCD_UNLOCK
  484.   #define LCD_UNLOCK()
  485. #endif
  486. #ifndef LCD_READABLE
  487.   #define LCD_READABLE (0)
  488. #endif
  489.   
  490. #ifndef LCD_CACHE_WRITETHRU  
  491.   #define LCD_CACHE_WRITETHRU (0)
  492. #endif
  493. #ifndef LCD_SUPPORT_RT_INVERSION  
  494.   #define LCD_SUPPORT_RT_INVERSION  (0)
  495. #endif
  496. #ifndef LCD_SUPPORT_CHECKINIT
  497.   #define LCD_SUPPORT_CHECKINIT (0)
  498. #endif
  499. /*
  500.   ********************************************************************
  501.   *                                                                  *
  502.   *                Explicit externals                                *
  503.   *                                                                  *
  504.   ********************************************************************
  505. */
  506. /* For compatibility with older configs, define defaults */
  507. #ifndef LCD_SUPPORT_COMTRANS
  508.   #define LCD_SUPPORT_COMTRANS 0
  509. #endif
  510. #ifndef LCD_SUPPORT_SEGTRANS
  511.   #define LCD_SUPPORT_SEGTRANS 0
  512. #endif
  513. #if LCD_SUPPORT_COMTRANS
  514.   extern U8 LCD__aLine2Com0[LCD_LASTCOM0-LCD_FIRSTCOM0+1];
  515.   #if (LCD_NUM_CONTROLLERS >1)
  516.     extern U8 LCD__aLine2Com1[LCD_LASTCOM1-LCD_FIRSTCOM1+1];
  517.   #endif
  518.   #if (LCD_NUM_CONTROLLERS >2)
  519.     extern U8 LCD__aLine2Com2[LCD_LASTCOM2-LCD_FIRSTCOM2+1];
  520.   #endif
  521.   #if (LCD_NUM_CONTROLLERS >3)
  522.     extern U8 LCD__aLine2Com3[LCD_LASTCOM3-LCD_FIRSTCOM3+1];
  523.   #endif
  524. #endif
  525. #if LCD_SUPPORT_SEGTRANS
  526.   extern U8 LCD__aRow2Seg0[LCD_LASTSEG0-LCD_FIRSTSEG0+1];
  527.   #if (LCD_NUM_CONTROLLERS >1)
  528.     extern U8 LCD__aRow2Seg1[LCD_LASTSEG1-LCD_FIRSTSEG1+1];
  529.   #endif
  530.   #if (LCD_NUM_CONTROLLERS >2)
  531.     extern U8 LCD__aRow2Seg2[LCD_LASTSEG2-LCD_FIRSTSEG2+1];
  532.   #endif
  533.   #if (LCD_NUM_CONTROLLERS >3)
  534.     extern U8 LCD__aRow2Seg3[LCD_LASTSEG3-LCD_FIRSTSEG3+1];
  535.   #endif
  536. #endif
  537. /*
  538.   ********************************************************************
  539.   *                                                                  *
  540.   *                Internal types                                    *
  541.   *                                                                  *
  542.   ********************************************************************
  543. */
  544. /*
  545.   ********************************************************************
  546.   *                                                                  *
  547.   *                SCHEDULING                                        *
  548.   *                                                                  *
  549.   ********************************************************************
  550. */
  551. #if LCD_SCHEDULE_CNT
  552.   static int ScheduleCntRem=LCD_SCHEDULE_CNT;
  553.   #define CHECK_SCHEDULE(PixelCnt)                              
  554.           if ((ScheduleCntRem-=(PixelCnt)) <=0) {               
  555.             ScheduleCntRem=LCD_SCHEDULE_CNT;                    
  556.             LCD_SCHEDULE();                                     
  557.           }
  558. #else
  559.   #define CHECK_SCHEDULE(PixelCnt)
  560. #endif
  561. /*
  562.   ********************************************************************
  563.   *                                                                  *
  564.   *                 Macro calculations                               *
  565.   *                                                                  *
  566.   ********************************************************************
  567. */
  568. /* To make life easier, assign physical x/y size */
  569. #if !LCD_SWAP_XY
  570.   #define LCD_XSIZE_P LCD_XSIZE
  571.   #define LCD_YSIZE_P LCD_YSIZE
  572. #else
  573.   #define LCD_XSIZE_P LCD_YSIZE
  574.   #define LCD_YSIZE_P LCD_XSIZE
  575. #endif
  576. /* Define number of available segments of controller */
  577. #if (LCD_CONTROLLER == 1560)
  578.   #define LCD_COMS_MAX 64
  579.   #define LCD_SEGS_MAX  102
  580. #elif (LCD_CONTROLLER == 1565)
  581.   #define LCD_COMS_MAX 65
  582.   #define LCD_SEGS_MAX  132
  583. #elif (LCD_CONTROLLER == 1566)
  584.   #define LCD_COMS_MAX 49
  585.   #define LCD_SEGS_MAX  132
  586. #elif (LCD_CONTROLLER == 1567)
  587.   #define LCD_COMS_MAX 33
  588.   #define LCD_SEGS_MAX  132
  589. #elif (LCD_CONTROLLER == 1568)
  590.   #define LCD_COMS_MAX 55
  591.   #define LCD_SEGS_MAX  132
  592. #elif (LCD_CONTROLLER == 1569)
  593.   #define LCD_COMS_MAX 53
  594.   #define LCD_SEGS_MAX  132
  595. #elif (LCD_CONTROLLER == 1575)
  596.   #define LCD_COMS_MAX 65
  597.   #define LCD_SEGS_MAX  200
  598. #elif (LCD_CONTROLLER == 0713)
  599.   #define LCD_COMS_MAX 65
  600.   #define LCD_SEGS_MAX  132
  601. #elif (LCD_CONTROLLER == 108)
  602.   #define LCD_COMS_MAX 64
  603.   #define LCD_SEGS_MAX 64
  604. #elif (LCD_CONTROLLER == 61202)
  605.   #define LCD_COMS_MAX 64
  606.   #define LCD_SEGS_MAX 64
  607. #else
  608.   #error Please define a controller to use !
  609. #endif
  610. /* Define number of used coms/segments per controller */
  611. #if !LCD_SUPPORT_SEGTRANS
  612.   #define LCD_NUM_SEGS0 (LCD_LASTSEG0-LCD_FIRSTSEG0+1)
  613. #else
  614.   #ifndef LCD_NUM_SEGS0
  615.     #error Please define LCD_NUM_SEGS0 in your configuratiuon file LCDConf.h
  616.   #endif
  617. #endif
  618. #if !LCD_SUPPORT_COMTRANS
  619.   #define LCD_NUM_COMS0 (LCD_LASTCOM0-LCD_FIRSTCOM0+1)
  620. #else
  621.   #ifndef LCD_NUM_COMS0
  622.     #error Please define LCD_NUM_COMS0 in your configuratiuon file LCDConf.h
  623.   #endif
  624. #endif
  625. #if (LCD_NUM_CONTROLLERS >1)
  626.   #if !LCD_SUPPORT_SEGTRANS
  627.     #define LCD_NUM_SEGS1 (LCD_LASTSEG1-LCD_FIRSTSEG1+1)
  628.   #else
  629.     #ifndef LCD_NUM_SEGS1
  630.       #error Please define LCD_NUM_SEGS1 in your configuratiuon file LCDConf.h
  631.     #endif
  632.   #endif
  633.   #if !LCD_SUPPORT_COMTRANS
  634.     #define LCD_NUM_COMS1 (LCD_LASTCOM1-LCD_FIRSTCOM1+1)
  635.   #else
  636.     #ifndef LCD_NUM_COMS1
  637.       #error Please define LCD_NUM_COMS1 in your configuratiuon file LCDConf.h
  638.     #endif
  639.   #endif
  640. #endif
  641. #if (LCD_NUM_CONTROLLERS >2)
  642.   #define LCD_NUM_SEGS2 (LCD_LASTSEG2-LCD_FIRSTSEG2+1)
  643.   #define LCD_NUM_COMS2 (LCD_LASTCOM2-LCD_FIRSTCOM2+1)
  644. #endif
  645. #if (LCD_NUM_CONTROLLERS >3)
  646.   #define LCD_NUM_SEGS3 (LCD_LASTSEG3-LCD_FIRSTSEG3+1)
  647.   #define LCD_NUM_COMS3 (LCD_LASTCOM3-LCD_FIRSTCOM3+1)
  648. #endif
  649. /* Define total number of used coms/segments */
  650. #if (LCD_NUM_CONTROLLERS ==1)
  651.   #define LCD_NUM_SEGS LCD_NUM_SEGS0
  652.   #define LCD_NUM_COMS LCD_NUM_COMS0
  653. #elif (LCD_NUM_CONTROLLERS ==2)
  654.   #define LCD_NUM_SEGS (LCD_NUM_SEGS0+LCD_NUM_SEGS1)
  655.   #define LCD_NUM_COMS (LCD_NUM_COMS0+LCD_NUM_COMS1)
  656. #elif (LCD_NUM_CONTROLLERS ==3)
  657.   #define LCD_NUM_SEGS (LCD_NUM_SEGS0+LCD_NUM_SEGS1+LCD_NUM_SEGS2)
  658.   #define LCD_NUM_COMS (LCD_NUM_COMS0+LCD_NUM_COMS1+LCD_NUM_COMS2)
  659. #elif (LCD_NUM_CONTROLLERS ==4)
  660.   #define LCD_NUM_SEGS (LCD_NUM_SEGS0+LCD_NUM_SEGS1+LCD_NUM_SEGS2+LCD_NUM_SEGS3)
  661.   #define LCD_NUM_COMS (LCD_NUM_COMS0+LCD_NUM_COMS1+LCD_NUM_COMS2+LCD_NUM_COMS3)
  662. #endif
  663. /* Calc. the first column to actually write to. This is not as
  664.    easy as it seems, because if we mirror X, the controller
  665.    uses different columns in video memory to store the data.
  666.    If you use lookup tables for segment lines, the offsets are 0
  667.    because the right values are in the table
  668. */
  669. #if LCD_SUPPORT_SEGTRANS==0
  670.   #if !LCD_MIRROR_X
  671.     #define LCD_SEGOFF0 LCD_FIRSTSEG0
  672.     #define LCD_SEGOFF1 (LCD_XORG1 - LCD_FIRSTSEG1)
  673.     #define LCD_SEGOFF2 (LCD_XORG2 - LCD_FIRSTSEG2)
  674.     #define LCD_SEGOFF3 (LCD_XORG3 - LCD_FIRSTSEG3)
  675.   #else
  676.     #define LCD_SEGOFF0 (LCD_SEGS_MAX-LCD_LASTSEG0-1)
  677.     #define LCD_SEGOFF1 (LCD_SEGS_MAX-LCD_LASTSEG1-1)
  678.     #define LCD_SEGOFF2 (LCD_SEGS_MAX-LCD_LASTSEG2-1)
  679.     #define LCD_SEGOFF3 (LCD_SEGS_MAX-LCD_LASTSEG3-1)
  680.   #endif
  681. #else
  682.     #define LCD_SEGOFF0 0
  683.     #define LCD_SEGOFF1 0
  684.     #define LCD_SEGOFF2 0
  685.     #define LCD_SEGOFF3 0
  686. #endif
  687. #if !LCD_REVERSE
  688.   #define  LCD_CMDNORMAL  0xa6
  689.   #define  LCD_CMDREVERSE 0xa7
  690. #else
  691.   #define  LCD_CMDNORMAL  0xa7
  692.   #define  LCD_CMDREVERSE 0xa6
  693. #endif
  694. /*
  695.   ********************************************************************
  696.   *                                                                  *
  697.   *            Configuration switch checking                         *
  698.   *                                                                  *
  699.   ********************************************************************
  700. Please be aware that not all configuration errors can be captured !
  701. */
  702. #if (LCD_SUPPORT_REFRESH && !LCD_CACHE)
  703.   #error Cache has to be enabled in order to support refresh !
  704. #endif
  705. #if (LCD_BITSPERPIXEL != 1)
  706.   #error This controller can handle only b/w displays
  707. #endif
  708. /* Check number of controllers */
  709. #if ((LCD_NUM_CONTROLLERS >4) || (LCD_NUM_CONTROLLERS <0))
  710.   #error "More than 4 controllers not supported !"
  711. #endif
  712. /* Check if number of segments / coms equals resolution */
  713. #if (LCD_NUM_SEGS < LCD_XSIZE_P)
  714.   #error Please check segment setup of controller 0 and X/YSIZE !!!
  715. #endif
  716. #if (LCD_NUM_COMS < LCD_YSIZE_P)
  717.   #error Please check com setup of controller 0 and X/YSIZE !!!
  718. #endif
  719. /*
  720.   ********************************************************************
  721.   *                                                                  *
  722.   *       Standard variables for driver                              *
  723.   *                                                                  *
  724.   ********************************************************************
  725. */
  726. #define BKCOLOR LCD_BKCOLORINDEX
  727. #define   COLOR LCD_COLORINDEX
  728. static LCD_RECT ClipRect;
  729. #if LCD_SUPPORT_VERIFY
  730.   static int ErrCnt;
  731.   static int ErrStat;
  732. #endif
  733. /*
  734.         *****************************************
  735.         *                                       *
  736.         *   Memory areas for caching (optional) *
  737.         *                                       *
  738.         *****************************************
  739. The cache stores only the bytes actually used in every controller.
  740. This is also the reason why different arrays are used for every
  741. controller.
  742. */
  743. #if LCD_CACHE
  744.   /* Handle controller #0 */
  745.   #define NUM_COMS0   (LCD_LASTCOM0-LCD_FIRSTCOM0+1)
  746.   #define NUM_PAGES0  ((NUM_COMS0+7)/8)
  747.   #define NUM_COLS0    (LCD_LASTSEG0-LCD_FIRSTSEG0+1)
  748.   static U8 Cache0[NUM_PAGES0][NUM_COLS0];
  749. /* Check configuration a bit to capture the worst mistakes ...  */
  750.   #if (NUM_COLS0<LCD_NUM_SEGS0)
  751.     #error Configuration error ! Please check LCD_LASTSEG0, LCD_FIRSTSEG0
  752.   #endif
  753.   #if (NUM_COMS0<LCD_NUM_COMS0)
  754.     #error Configuration error ! Please check LCD_LASTCOM0, LCD_FIRSTCOM0
  755.   #endif
  756.   /* Handle controller #1 */
  757.   #if (LCD_NUM_CONTROLLERS >1)
  758.     #define NUM_COMS1   (LCD_LASTCOM1-LCD_FIRSTCOM1+1)
  759.     #define NUM_PAGES1  ((NUM_COMS1+7)/8)
  760.     #define NUM_COLS1    (LCD_LASTSEG1-LCD_FIRSTSEG1+1)
  761.     static U8 Cache1[NUM_PAGES1][NUM_COLS1];
  762. /* Check configuration a bit to capture the worst mistakes ...  */
  763.     #if (NUM_COLS1<LCD_NUM_SEGS1)
  764.       #error Configuration error ! Please check LCD_LASTSEG1, LCD_FIRSTSEG1
  765.     #endif
  766.     #if (NUM_COMS1<LCD_NUM_COMS1)
  767.       #error Configuration error ! Please check LCD_LASTCOM1, LCD_FIRSTCOM1
  768.     #endif
  769.   #endif
  770.   /* Handle controller #2 */
  771.   #if (LCD_NUM_CONTROLLERS >2)
  772.     #define NUM_PAGES2  ((LCD_LASTCOM2-LCD_FIRSTCOM2+1+7)/8)
  773.     #define NUM_COLS2    (LCD_LASTSEG2-LCD_FIRSTSEG2+1)
  774.     static U8 Cache2[NUM_PAGES2][NUM_COLS2];
  775.   #endif
  776.   /* Handle controller #3 */
  777.   #if (LCD_NUM_CONTROLLERS >3)
  778.     #define NUM_PAGES3  ((LCD_LASTCOM3-LCD_FIRSTCOM3+1+7)/8)
  779.     #define NUM_COLS3    (LCD_LASTSEG3-LCD_FIRSTSEG3+1)
  780.     static U8 Cache3[NUM_PAGES3][NUM_COLS3];
  781.   #endif
  782. #endif
  783. /*
  784.   ********************************************************************
  785.   *                                                                  *
  786.   *                Write Cache variables                             *
  787.   *                                                                  *
  788.   ********************************************************************
  789. */
  790. #if  LCD_SUPPORT_CACHECONTROL
  791.   static char CacheStat   =0;     /* 0: No changes */
  792.   static char CacheLocked =0;     /* 0: Not locked */
  793.   static U8   aaCacheDirtyTag0[NUM_PAGES0][(NUM_COLS0+7)/8];
  794.   #if (LCD_NUM_CONTROLLERS >1)
  795.     static U8   aaCacheDirtyTag1[NUM_PAGES1][(NUM_COLS1+7)/8];
  796.   #endif
  797.   #if (LCD_NUM_CONTROLLERS >2)
  798.     static U8   aaCacheDirtyTag2[NUM_PAGES2][(NUM_COLS2+7)/8];
  799.   #endif
  800.   #if (LCD_NUM_CONTROLLERS >3)
  801.     static U8   aaCacheDirtyTag3[NUM_PAGES3][(NUM_COLS3+7)/8];
  802.   #endif
  803. #endif
  804. /*
  805.   ********************************************************************
  806.   *                                                                  *
  807.   *                  Hardware access, low level                      *
  808.   *                                                                  *
  809.   *           Write Command/Data, Reset                              *
  810.   *           Read  Command/data if possible (LCD readable)          *
  811.   *                                                                  *
  812.   ********************************************************************
  813.   The following routines are used for all access to the
  814.   LCD-controller(s).
  815. */
  816. /* This macro can be used to check how much time is used up
  817.    for management and how much for hardware access */
  818. #ifdef LCD_TESTSPEED
  819.   #undef  WRITE_DATA0
  820.   #undef  WRITE_CMD0
  821.   #undef  WRITE_DATA1
  822.   #undef  WRITE_CMD1
  823.   #define WRITE_DATA0(p0)
  824.   #define WRITE_CMD0(p0)
  825.   #define WRITE_DATA1(p0)
  826.   #define WRITE_CMD1(p0)
  827. #endif
  828.         /****************************************
  829.         *                                       *
  830.         *        Write Data                     *
  831.         *                                       *
  832.         ****************************************/
  833. static void LCD_WriteData0(char Data) {
  834.   LCD_LOCK();
  835.   WRITE_DATA0(Data);
  836.   LCD_UNLOCK();
  837. }
  838. #if (LCD_NUM_CONTROLLERS >1)
  839. static void LCD_WriteData1(char Data) {
  840.   LCD_LOCK();
  841.   WRITE_DATA1(Data);
  842.   LCD_UNLOCK();
  843. }
  844. #endif
  845. #if (LCD_NUM_CONTROLLERS >2)
  846. static void LCD_WriteData2(char Data) {
  847.   LCD_LOCK();
  848.   LCD_WRITEDATA2(Data);
  849.   LCD_UNLOCK();
  850. }
  851. #endif
  852. #if (LCD_NUM_CONTROLLERS >3)
  853. static void LCD_WriteData3(char Data) {
  854.   LCD_LOCK();
  855.   LCD_WRITEDATA3(Data);
  856.   LCD_UNLOCK();
  857. }
  858. #endif
  859.         /****************************************
  860.         *                                       *
  861.         *        Write single command           *
  862.         *                                       *
  863.         ****************************************/
  864. static void LCD_WriteSingleCommand0(char cmd) {
  865.   LCD_LOCK();
  866.   WRITE_CMD0(cmd);
  867.   LCD_UNLOCK();
  868. }
  869. #if (LCD_NUM_CONTROLLERS >1)
  870. static void LCD_WriteSingleCommand1(char cmd) {
  871.   LCD_LOCK();
  872.   WRITE_CMD1(cmd);
  873.   LCD_UNLOCK();
  874. }
  875. #endif
  876. #if (LCD_NUM_CONTROLLERS >2)
  877. static void LCD_WriteSingleCommand2(char cmd) {
  878.   LCD_LOCK();
  879.   LCD_WRITECMD2(cmd);
  880.   LCD_UNLOCK();
  881. }
  882. #endif
  883. #if (LCD_NUM_CONTROLLERS >3)
  884. static void LCD_WriteSingleCommand3(char cmd) {
  885.   LCD_LOCK();
  886.   LCD_WRITECMD3(cmd);
  887.   LCD_UNLOCK();
  888. }
  889. #endif
  890.         /****************************************
  891.         *                                       *
  892.         *        Write double command           *
  893.         *                                       *
  894.         ****************************************/
  895. static void LCD_WriteDoubleCommand0(char P1, char P2) {
  896.   LCD_LOCK();
  897.   WRITE_CMD0(P1);
  898.   WRITE_CMD0(P2);
  899.   LCD_UNLOCK();
  900. }
  901. #if (LCD_NUM_CONTROLLERS >1)
  902. static void LCD_WriteDoubleCommand1(char P1, char P2) {
  903.   LCD_LOCK();
  904.   WRITE_CMD1(P1);
  905.   WRITE_CMD1(P2);
  906.   LCD_UNLOCK();
  907. }
  908. #endif
  909. #if (LCD_NUM_CONTROLLERS >2)
  910. static void LCD_WriteDoubleCommand2(char P1, char P2) {
  911.   LCD_LOCK();
  912.   LCD_WRITECMD2(P1);
  913.   LCD_WRITECMD2(P2);
  914.   LCD_UNLOCK();
  915. }
  916. #endif
  917. #if (LCD_NUM_CONTROLLERS >3)
  918. static void LCD_WriteDoubleCommand3(char P1, char P2) {
  919.   LCD_LOCK();
  920.   LCD_WRITECMD3(P1);
  921.   LCD_WRITECMD3(P2);
  922.   LCD_UNLOCK();
  923. }
  924. #endif
  925.         /****************************************
  926.         *                                       *
  927.         *          Read data                    *
  928.         *                                       *
  929.         ****************************************/
  930. #if LCD_READABLE
  931. static U8 LCD_ReadData0(void) {
  932.   U8 r;
  933.   LCD_LOCK();
  934.   READ_DATA0(r);
  935.   LCD_UNLOCK();
  936.   return r;
  937. }
  938. #if (LCD_NUM_CONTROLLERS >1)
  939. static U8 LCD_ReadData1(void) {
  940.   U8 r;
  941.   LCD_LOCK();
  942.   READ_DATA1(r);
  943.   LCD_UNLOCK();
  944.   return r;
  945. }
  946. #endif
  947. #if (LCD_NUM_CONTROLLERS >2)
  948. static U8 LCD_ReadData2(void) {
  949.   U8 r;
  950.   LCD_LOCK();
  951.   READ_DATA2(r);
  952.   LCD_UNLOCK();
  953.   return r;
  954. }
  955. #endif
  956. #if (LCD_NUM_CONTROLLERS >3)
  957. static U8 LCD_ReadData3(void) {
  958.   U8 r;
  959.   LCD_LOCK();
  960.   READ_DATA3(r);
  961.   LCD_UNLOCK();
  962.   return r;
  963. }
  964. #endif
  965. #endif
  966.         /****************************************
  967.         *                                       *
  968.         *          Read command (status)        *
  969.         *                                       *
  970.         ****************************************/
  971. #if LCD_READABLE
  972. static U8 LCD_ReadCmd0(void) {
  973.   U8 r;
  974.   LCD_LOCK();
  975.   READ_CMD0(r);
  976.   LCD_UNLOCK();
  977.   return r;
  978. }
  979. #if (LCD_NUM_CONTROLLERS >1)
  980. static U8 LCD_ReadCmd1(void) {
  981.   U8 r;
  982.   LCD_LOCK();
  983.   READ_CMD1(r);
  984.   LCD_UNLOCK();
  985.   return r;
  986. }
  987. #endif
  988. #if (LCD_NUM_CONTROLLERS >2)
  989. static U8 LCD_ReadCmd2(void) {
  990.   U8 r;
  991.   LCD_LOCK();
  992.   READ_CMD2(r);
  993.   LCD_UNLOCK();
  994.   return r;
  995. }
  996. #endif
  997. #if (LCD_NUM_CONTROLLERS >3)
  998. static U8 LCD_ReadCmd3(void) {
  999.   U8 r;
  1000.   LCD_LOCK();
  1001.   READ_CMD3(r);
  1002.   LCD_UNLOCK();
  1003.   return r;
  1004. }
  1005. #endif
  1006. #endif
  1007. /*
  1008.         ****************************************
  1009.         *                                      *
  1010.         *     Write to  all controllers        *
  1011.         *                                      *
  1012.         ****************************************
  1013. Some commands should be written to all controllers at the same time.
  1014. (Commands used in the init-sequence, or display on/off).
  1015. With a multi-controller LCD it can come in handy to have a routine to
  1016. write to all of them at once.
  1017. */
  1018. #if (LCD_NUM_CONTROLLERS ==1)
  1019.   #define LCD_WriteSingleCommandAll LCD_WriteSingleCommand0
  1020. #else
  1021.   void LCD_WriteSingleCommandAll(char cmd) {
  1022.     LCD_WriteSingleCommand0(cmd);
  1023.     LCD_WriteSingleCommand1(cmd);
  1024.     #if (LCD_NUM_CONTROLLERS >2)
  1025.       LCD_WriteSingleCommand2(cmd);
  1026.     #endif
  1027.     #if (LCD_NUM_CONTROLLERS >3)
  1028.       LCD_WriteSingleCommand3(cmd);
  1029.     #endif
  1030.   }
  1031. #endif
  1032. /*
  1033.   ********************************************************************
  1034.   *                                                                  *
  1035.   *                  Hardware access, register level                 *
  1036.   *                                                                  *
  1037.   *           Write Page / Column                                    *
  1038.   *                                                                  *
  1039.   ********************************************************************
  1040.  The following routines are used for all access to the
  1041.  LCD-controller(s).
  1042. */
  1043. #if (LCD_NUM_CONTROLLERS > 1)
  1044.   static U8 CurController;    /* Currently selected controller. All
  1045.                                  hardware operations are executed on
  1046.                                  this particular controller. It is
  1047.                                  more efficient to have a global
  1048.                                  variable than to pass this value as
  1049.                                  parameter many times. And in a low 
  1050.                                  level driver as this one, the
  1051.                                  priority of efficiency is top of
  1052.                                  the list.  */
  1053. #endif
  1054. static U8* pCacheByte;
  1055. static U8 aPage[LCD_NUM_CONTROLLERS];   /* Current page of
  1056.                                            LCD controller(s) */
  1057. static U8 aCAdr[LCD_NUM_CONTROLLERS];   /* Current column adr
  1058.                                            of LCD controller(s) */
  1059. static U8 Page, Col;            /* Page / column of cache byte */
  1060. static U8 DataW_Dirty;          /* Set (1) bits are dirty */
  1061. static U8 DataW_Cache;          /* Data to be written
  1062.                                   (not all bits may be valid !) */
  1063. static U8 DataR_Valid;
  1064. static U8 DataR_Cache;
  1065. /* The coordinates of the cache byte. We save current X,Y as well
  1066.    as Y0/Y1 (min/max) in Y-direction. Note that on this level we
  1067.    always talk about physical coordinates ! */
  1068. static int DataCacheX=-1;   /* x-adr. of currently cached byte.
  1069.                                If it is <0 it is sure invalid ! */
  1070. static int DataCacheY;
  1071. static int DataCacheY0;
  1072. static int DataCacheY1;
  1073. #if LCD_SUPPORT_COMTRANS
  1074.   static int DataCacheYBit0;
  1075. #else
  1076.   #define DataCacheYBit0 DataCacheY0
  1077. #endif
  1078. /*
  1079.         *****************************************
  1080.         *                                       *
  1081.         *         Set Page routines             *
  1082.         *                                       *
  1083.         *****************************************
  1084. These routines set the page-register of their respective
  1085. LCD-controller. Note that page is not what you might imagine,
  1086. but is a section of the controllers internal video RAM.
  1087. For details, please refer to the datasheet.
  1088. */
  1089. static void SetPage0(void) {
  1090.   SET_PAGE0(Page);
  1091.   aPage[0] = Page;
  1092. }
  1093. #if (LCD_NUM_CONTROLLERS > 1)
  1094. static void SetPage1(void) {
  1095.   SET_PAGE1(Page);
  1096.   aPage[1] = Page;
  1097. }
  1098. #endif
  1099. #if (LCD_NUM_CONTROLLERS > 2)
  1100. static void SetPage2(void) {
  1101.   SET_PAGE2(Page);
  1102.   aPage[2] = Page;
  1103. }
  1104. #endif
  1105. #if (LCD_NUM_CONTROLLERS > 3)
  1106. static void SetPage3(void) {
  1107.   SET_PAGE3(Page);
  1108.   aPage[3] = Page;
  1109. }
  1110. #endif
  1111. /*
  1112.         *****************************************
  1113.         *                                       *
  1114.         *         Set column routines           *
  1115.         *                                       *
  1116.         *****************************************
  1117. */
  1118. static void SetCAdr0(void) {
  1119.   #if LCD_SEGOFF0
  1120.     U8 ColP = Col+LCD_SEGOFF0;
  1121.   #else
  1122.     #define ColP Col
  1123.   #endif
  1124.   SET_CADR0(ColP);
  1125.   aCAdr[0] = Col;
  1126.   #if !LCD_SEGOFF0
  1127.     #undef ColP
  1128.   #endif
  1129. }
  1130. #if (LCD_NUM_CONTROLLERS > 1)
  1131. static void SetCAdr1(void) {
  1132.   #if LCD_SEGOFF1
  1133.     U8 ColP = Col+LCD_SEGOFF1;
  1134.   #else
  1135.     #define ColP Col
  1136.   #endif
  1137.   SET_CADR1(ColP);
  1138.   aCAdr[1] = Col;
  1139.   #if !LCD_SEGOFF1
  1140.     #undef ColP
  1141.   #endif
  1142. }
  1143. #endif
  1144. #if (LCD_NUM_CONTROLLERS > 2)
  1145. static void SetCAdr2(void) {
  1146.   #if LCD_SEGOFF2
  1147.     U8 ColP = Col+LCD_SEGOFF2;
  1148.   #else
  1149.     #define ColP Col
  1150.   #endif
  1151.   SET_CADR2(ColP);
  1152.   aCAdr[2] = Col;
  1153.   #if !LCD_SEGOFF2
  1154.     #undef ColP
  1155.   #endif
  1156. }
  1157. #endif
  1158. #if (LCD_NUM_CONTROLLERS > 3)
  1159. static void SetCAdr3(void) {
  1160.   #if LCD_SEGOFF3
  1161.     U8 ColP = Col+LCD_SEGOFF3;
  1162.   #else
  1163.     #define ColP Col
  1164.   #endif
  1165.   SET_CADR3(ColP);
  1166.   aCAdr[3] = Col;
  1167.   #if !LCD_SEGOFF3
  1168.     #undef ColP
  1169.   #endif
  1170. }
  1171. #endif
  1172. /*
  1173.         *****************************************
  1174.         *                                       *
  1175.         *        Read video memory routines     *
  1176.         *                                       *
  1177.         *****************************************
  1178. */
  1179. #if !LCD_CACHE
  1180.   static U8 ReadVMem0() {
  1181.     if (Page !=aPage[0])
  1182.       SetPage0();
  1183.     if (Col != aCAdr[0])
  1184.       SetCAdr0();
  1185.     aCAdr[0]+=2;
  1186.     LCD_ReadData0(Data);        /* Dummy read */
  1187.     return LCD_ReadData0(Data);
  1188.   }
  1189. #else
  1190.   #define ReadVMem0() (*pCacheByte)
  1191. #endif
  1192. #if (LCD_NUM_CONTROLLERS > 1)
  1193.   #if !LCD_CACHE
  1194.     U8 ReadVMem1() {
  1195.       if (Page !=aPage[1])
  1196.         SetPage1();
  1197.       if (Col != aCAdr[1])
  1198.         SetCAdr1();
  1199.       aCAdr[1]+=2;
  1200.       LCD_ReadData1(Data);      /* Dummy read */
  1201.       return LCD_ReadData1(Data);
  1202.     }
  1203.   #else
  1204.     #define ReadVMem1() (*pCacheByte)
  1205.   #endif
  1206. #endif /* LCD_NUM_CONTROLLERS >1 */
  1207. #if (LCD_NUM_CONTROLLERS > 2)
  1208.   #if !LCD_CACHE
  1209.     U8 ReadVMem2() {
  1210.       if (Page !=aPage[2])
  1211.         SetPage2();
  1212.       if (Col != aCAdr[2])
  1213.         SetCAdr2();
  1214.       aCAdr[2]+=2;
  1215.       LCD_ReadData2(Data);      /* Dummy read */
  1216.       return LCD_ReadData2(Data);
  1217.     }
  1218.   #else
  1219.     #define ReadVMem2() (*pCacheByte)
  1220.   #endif
  1221. #endif
  1222. #if (LCD_NUM_CONTROLLERS > 3)
  1223.   #if !LCD_CACHE
  1224.     U8 ReadVMem3() {
  1225.       if (Page !=aPage[3])
  1226.         SetPage3();
  1227.       if (Col != aCAdr[3])
  1228.         SetCAdr3();
  1229.       aCAdr[3]+=2;
  1230.       LCD_ReadData3(Data);      /* Dummy read */
  1231.       return LCD_ReadData3(Data);
  1232.     }
  1233.   #else
  1234.     #define ReadVMem3() (*pCacheByte)
  1235.   #endif
  1236. #endif
  1237. /*
  1238.         *****************************************
  1239.         *                                       *
  1240.         *       Write video memory routines     *
  1241.         *                                       *
  1242.         *****************************************
  1243. */
  1244. #if  LCD_SUPPORT_CACHECONTROL
  1245.   #define CHECK_CACHE_LOCK(Con)                          
  1246.   if (CacheLocked) {                                     
  1247.     U8 ColOff = Col -LCD_FIRSTSEG##Con;                  
  1248.     U8 Bit = ColOff&7;                                   
  1249.     aaCacheDirtyTag##Con[Page][ColOff>>3] |= (1<<Bit);   
  1250.     CacheStat = 1;         /* Mark cache as dirty */     
  1251.     return;                                              
  1252.   }
  1253. #else
  1254.   #define CHECK_CACHE_LOCK(LCDCON)
  1255. #endif
  1256. #define WRITE_VMEM(Con)             
  1257.   CHECK_CACHE_LOCK(Con);            
  1258.   if (Page !=aPage[Con])            
  1259.     SetPage##Con();                 
  1260.   if (Col != aCAdr[Con])            
  1261.     SetCAdr##Con();                 
  1262.   LCD_LOCK();                       
  1263.   WRITE_DATA##Con(DataW_Cache);          
  1264.   LCD_UNLOCK();                     
  1265.   aCAdr[Con]++;
  1266. #if !LCD_CACHE_WRITETHRU
  1267.   #define RETURN_IF_WRITE_NOT_NEEDED(Con) 
  1268.     if ( *pCacheByte == DataW_Cache) 
  1269.       return;
  1270. #else
  1271.   #define RETURN_IF_WRITE_NOT_NEEDED(Con)
  1272. #endif
  1273. #if LCD_CACHE
  1274.   #define CHECK_VMEM_CACHE(Con) 
  1275.     RETURN_IF_WRITE_NOT_NEEDED(Con);                                
  1276.     *pCacheByte = DataW_Cache;
  1277. #else
  1278.   #define CHECK_VMEM_CACHE(Con)
  1279. #endif
  1280. static void WriteVMem0(void) {
  1281.   CHECK_VMEM_CACHE(0);
  1282.   WRITE_VMEM(0);
  1283. }
  1284. #if (LCD_NUM_CONTROLLERS > 1)
  1285. static void WriteVMem1(void) {
  1286.   CHECK_VMEM_CACHE(1);
  1287.   WRITE_VMEM(1);
  1288. }
  1289. #endif
  1290. #if (LCD_NUM_CONTROLLERS > 2)
  1291. static void WriteVMem2(void) {
  1292.   CHECK_VMEM_CACHE(2);
  1293.   WRITE_VMEM(2);
  1294. }
  1295. #endif
  1296. #if (LCD_NUM_CONTROLLERS > 3)
  1297. static void WriteVMem3(void) {
  1298.   CHECK_VMEM_CACHE(3);
  1299.   WRITE_VMEM(3);
  1300. }
  1301. #endif
  1302. /*
  1303.   ********************************************************************
  1304.   *                                                                  *
  1305.   *                Write Cache control                               *
  1306.   *                                                                  *
  1307.   ********************************************************************
  1308. In order to speed up access to the LCD and to avoid flickering, it
  1309. can be necessary to lock the write cache. This means that all drawing
  1310. commands do not affect the hardware it the cache is locked until
  1311. the flush (or unlock) command is given.
  1312. Note: The code could be shortened a bit by defining an add. macro
  1313.       for the code for every controller. This has not been done
  1314.       because it would make debugging even harder.
  1315.       (It is already hard enough)
  1316. */
  1317. #define CHECK_CACHE_BYTE_DIRTY(Controller,Bit)   
  1318.   if (Dirty&(1<<Bit)) {                          
  1319.     if (page !=aPage[Controller]) {              
  1320.       Page = page;                               
  1321.       SetPage##Controller();                     
  1322.     }                                            
  1323.     if (col+Bit != aCAdr[Controller]) {        
  1324.       Col = col+Bit;                             
  1325.       SetCAdr##Controller();                     
  1326.     }                                            
  1327.     LCD_WriteData##Controller(Cache##Controller[page][col+Bit]); 
  1328.     aCAdr[Controller]++;                         
  1329.   }
  1330.     
  1331. #define FLUSH_CACHE_X(Con)                                      
  1332.   for (page=0; page<NUM_PAGES##Con; page++) {
  1333.     for (col8=0; col8<(NUM_COLS##Con+7)/8; col8++) {
  1334.       U8 Dirty;
  1335.       if ((Dirty=aaCacheDirtyTag##Con[page][col8]) !=0) {
  1336.         int col   = col8<<3;
  1337.         aaCacheDirtyTag##Con[page][col8] =0;
  1338.         CHECK_CACHE_BYTE_DIRTY(Con,0);
  1339.         CHECK_CACHE_BYTE_DIRTY(Con,1);
  1340.         CHECK_CACHE_BYTE_DIRTY(Con,2);
  1341.         CHECK_CACHE_BYTE_DIRTY(Con,3);
  1342.         CHECK_CACHE_BYTE_DIRTY(Con,4);
  1343.         CHECK_CACHE_BYTE_DIRTY(Con,5);
  1344.         CHECK_CACHE_BYTE_DIRTY(Con,6);
  1345.         CHECK_CACHE_BYTE_DIRTY(Con,7);                          
  1346.       }                                                         
  1347.     }
  1348.   }
  1349. #if  LCD_SUPPORT_CACHECONTROL
  1350. static void FlushCache(void) {
  1351.   int page;
  1352.   int col8;     /* Column index, 1 inc skips 8 bytes */
  1353.   FLUSH_CACHE_X(0);
  1354.   #if (LCD_NUM_CONTROLLERS >1)
  1355.     FLUSH_CACHE_X(1);
  1356.   #endif
  1357.   #if (LCD_NUM_CONTROLLERS >2)
  1358.     FLUSH_CACHE_X(2);
  1359.   #endif
  1360.   #if (LCD_NUM_CONTROLLERS >3)
  1361.     FLUSH_CACHE_X(3);
  1362.   #endif
  1363. /* Important !!!
  1364.   We have to make sure that the byte-level cache is not level
  1365.   inconsistent because we have modified the Page/Col values. This
  1366.   is done by invalidating the x-position. */
  1367.   DataCacheX=-1;
  1368. }
  1369. U8 LCD_L0_ControlCache(U8 cmd) {
  1370.   switch (cmd) {
  1371.   case LCD_CC_LOCK:   /* Set Cache to lock state.*/
  1372.     CacheLocked =1;
  1373.     break;
  1374.   case LCD_CC_UNLOCK: /* Set Cache to unlock state ... must flush !*/
  1375.     CacheLocked =0;
  1376.   case LCD_CC_FLUSH:  /* Flush cache */
  1377.     if (CacheStat) {
  1378.       CacheStat =0;
  1379.       FlushCache();
  1380.     }
  1381.   }
  1382.   return CacheStat;
  1383. }
  1384. #endif
  1385. /*
  1386.   ********************************************************************
  1387.   *                                                                  *
  1388.   *                                                                  *
  1389.   *         Internal video memory management                         *
  1390.   *                                                                  *
  1391.   *                                                                  *
  1392.   ********************************************************************
  1393. This contains the internal video management of this driver, which is
  1394. the core of it. It has been designed with the following goals:
  1395. + Support for all types of orientaions of display
  1396. + Support for multiple controllers
  1397. + Support for both parallel and serial interface
  1398. + Small RAM footprint
  1399. + Fast execution on all CPUs in all configurations
  1400. + Small code
  1401. It has taken a considerable amount of time to develop, optimize and
  1402. test the concept of this driver. It should pretty much cover most LCDs
  1403. using 15XX controllers; if you feel your configuration is not covered
  1404. by this driver, please get
  1405. in contact with us, preferably via email (support@segger.com).
  1406. */
  1407. #define FLUSH() if (DataW_Dirty) Flush()
  1408. /* For XOR operations, the byte needs to be loaded in order to
  1409.    perform the operation. We also have to make sure that bits which
  1410.    have been previously modified are not forgotten.
  1411.    This essentially means loading only the unmodified bits (for which
  1412.    the bit in DATAW_Dirty is ==0) and leave the other ones unchanged.
  1413. */
  1414. #define LOADDATA()                               
  1415.   if (!DataR_Valid) {                            
  1416.     ReadData();                                  
  1417.     DataW_Cache &= DataW_Dirty;                  
  1418.     DataW_Cache |= DataR_Cache&(~DataW_Dirty);   
  1419.   }
  1420. #if LCD_CACHE
  1421.   #define ReadData() DataR_Cache = *pCacheByte; DataR_Valid= 0xff;
  1422. #else
  1423. static void ReadData(void) {
  1424.   DataR_Valid= 0xff;                    /* All bits are valid. */
  1425.   #if (LCD_NUM_CONTROLLERS == 1)
  1426.     DataR_Cache= ReadVMem0();
  1427.   #else
  1428.     switch (CurController) {
  1429.     case 0:
  1430.       DataR_Cache= ReadVMem0(); break;
  1431.     case 1:
  1432.       DataR_Cache= ReadVMem1(); break;
  1433.     #if (LCD_NUM_CONTROLLERS >2)
  1434.     case 2:
  1435.       DataR_Cache= ReadVMem2(); break;
  1436.     #endif
  1437.     #if (LCD_NUM_CONTROLLERS >3)
  1438.     case 3:
  1439.       DataR_Cache= ReadVMem3(); break;
  1440.     #endif
  1441.     }
  1442.   #endif    /* LCD_NUM_CONTROLLERS == 1 */
  1443. }
  1444. #endif
  1445. #if (LCD_NUM_CONTROLLERS > 1)
  1446. typedef void (tWriteVMem)(void);
  1447. tWriteVMem* aWriteVMemX[] = {
  1448.   WriteVMem0,WriteVMem1
  1449. #if (LCD_NUM_CONTROLLERS >2)
  1450.   ,WriteVMem2
  1451. #endif
  1452. #if (LCD_NUM_CONTROLLERS >3)
  1453.   ,WriteVMem3
  1454. #endif
  1455. }; 
  1456. #endif 
  1457. static void Flush(void) {
  1458.   /* Nothing to write ? Then we are done !*/
  1459.   if (DataW_Dirty==0)
  1460.     return;
  1461.   /* All bits are dirty ? Then write`em all, dont read !!*/
  1462.   if (DataW_Dirty!=0xff) {
  1463.     /* Only some are dirty ... We have to read the byte ! */
  1464.     if (!DataR_Valid) {
  1465.       ReadData();         /* Get current byte in our cache */
  1466.     }
  1467.     DataW_Cache &= DataW_Dirty;
  1468.     DataW_Cache |= DataR_Cache & (~DataW_Dirty);
  1469.   }
  1470.   DataR_Cache = DataW_Cache;
  1471. #if (LCD_NUM_CONTROLLERS == 1)
  1472.   WriteVMem0();
  1473. #else
  1474.   aWriteVMemX[CurController]();
  1475. #endif
  1476.   DataW_Dirty = 0;              /* No more bits to write */
  1477. }
  1478. /*
  1479.         *****************************************
  1480.         *                                       *
  1481.         *         Find Byte                     *
  1482.         *                                       *
  1483.         *****************************************
  1484. Due to the setup options reg. the area of the display which is covered
  1485. by one LCD-controller and the fact that different display controllers
  1486. can controll arbitrary areas of the display as defined in the
  1487. config-file, It can be a tricky job to find out which display
  1488. controller is concerned, where in the video memory of that particular
  1489. controller the byte is located and how many bits are left (i.e. what
  1490. the minimal and maximal physical y-position is).
  1491. Note that this job is a lot easier in a single controller system,
  1492. where the entire routine could be placed in a macro.
  1493. */
  1494. #if (LCD_SUPPORT_SEGTRANS==0)
  1495.   #define CALCCOL(Con) Col  = DataCacheX-LCD_XORG##Con
  1496. #else
  1497.   #define CALCCOL(Con) Col  = LCD__aRow2Seg##Con[DataCacheX-LCD_XORG##Con]
  1498. #endif
  1499. #if (LCD_SUPPORT_COMTRANS==0)
  1500.   #define CALCY(Con) 
  1501.     DataCacheY0 = DataCacheY &(~7);    
  1502.     DataCacheY1 = DataCacheY0+  7;     
  1503.     Page = (DataCacheY0-LCD_YORG##Con)>>3
  1504. #else
  1505.     #define CALCY(Con) 
  1506.     DataCacheY1 = DataCacheY0 = DataCacheY; 
  1507.     {                                       
  1508.       int Com = LCD__aLine2Com##Con[DataCacheY-LCD_YORG##Con]; 
  1509.       Page = Com>>3;                                   
  1510.       DataCacheYBit0 = DataCacheY-(Com&7);             
  1511.     }
  1512. #endif
  1513. #define IF_INLEFT(Con)   if (DataCacheX >= LCD_XORG##Con)
  1514. #define IF_INRIGHT(Con)  if (DataCacheX <= LCD_XORG##Con+LCD_NUM_SEGS##Con-1)
  1515. #define IF_INTOP(Con)    if (DataCacheY >= LCD_YORG##Con)
  1516. #define IF_INBOTTOM(Con) if (DataCacheY <= LCD_YORG##Con+LCD_NUM_COMS##Con-1)
  1517. #define IF_INAREA(Con)                                    
  1518.    IF_INRIGHT(Con)                                        
  1519.    IF_INLEFT(Con)                                         
  1520.    IF_INTOP(Con)                                          
  1521.    IF_INBOTTOM(Con)
  1522. #define CALCXY(Con) 
  1523.   CALCCOL(Con);      
  1524.   CALCY(Con);      
  1525.   pCacheByte = &Cache##Con[Page][Col];  
  1526.   CurController = Con;
  1527. /* This is an optimization for a single controller system */
  1528.   #if (LCD_NUM_CONTROLLERS == 1)
  1529. #define FindByte() 
  1530. CALCCOL(0); CALCY(0); pCacheByte = &Cache0[Page][Col];
  1531. /* CALCCOL(0); CALCY(0); pCacheByte = &Cache0[Page][Col-LCD_FIRSTSEG0];*/
  1532.   #endif
  1533. /* This is an optimization for a 2 controller system */
  1534. #if (LCD_NUM_CONTROLLERS == 2)
  1535.   #if (LCD_XORG0==LCD_XORG1)
  1536.     #undef IF_INAREA
  1537.     #if (LCD_YORG0 == LCD_YORG)
  1538.       #define IF_INAREA(Con) IF_INBOTTOM(Con)
  1539.     #else
  1540.       #define IF_INAREA(Con) IF_INTOP(Con)
  1541.     #endif
  1542. #define FindByte() IF_INAREA(0) { CALCXY(0); } else { CALCXY(1); }
  1543.   #endif
  1544. #endif
  1545. /* The actual routine ... */
  1546. #ifndef FindByte
  1547. static void FindByte(void) {
  1548.   #if (LCD_NUM_CONTROLLERS > 1)
  1549.   /* Check if controller 0 is concerned */
  1550.     IF_INAREA(0)
  1551.     {
  1552.       CALCXY(0);
  1553.       return;
  1554.     }
  1555.   /* Check if controller 1 is concerned, but only
  1556.      in a system with more than 2 controllers */
  1557.   #if (LCD_NUM_CONTROLLERS > 2)
  1558.     IF_INAREA(1)
  1559.   #endif
  1560.     {
  1561.       CALCXY(1);
  1562.       return;
  1563.     }
  1564.   /* Check if controller 2 is concerned */
  1565.     #if (LCD_NUM_CONTROLLERS > 3)
  1566.       #if (LCD_NUM_CONTROLLERS > 3)
  1567.       IF_INAREA(2)
  1568.       #endif
  1569.     {
  1570.       CALCXY(2);
  1571.       return;
  1572.     }
  1573.     #endif
  1574.   /* Check if controller 3 is concerned */
  1575.     #if (LCD_NUM_CONTROLLERS >3)
  1576.       #if (LCD_NUM_CONTROLLERS >4)
  1577.       IF_INAREA(3)
  1578.       #endif
  1579.     {
  1580.       CALCXY(3);
  1581.       return;
  1582.     }
  1583.     #endif
  1584.     /* This should never happen ! */
  1585.   #endif
  1586. }
  1587. #endif
  1588. /*
  1589.         *****************************************
  1590.         *                                       *
  1591.         *         Set new Position              *
  1592.         *                                       *
  1593.         *****************************************
  1594. */
  1595. static void Goto(void) {
  1596.   U8* pCacheByteTemp[2];
  1597.   U8  PageTemp[2];
  1598.   U8  ColTemp[2];
  1599.   #if (LCD_NUM_CONTROLLERS > 1)
  1600.     U8  CurControllerTemp[2];
  1601.   #endif
  1602.   DataR_Valid=0;       /* No info about what's in the data byte */
  1603.   if (DataW_Dirty == 0) {
  1604.     FindByte();
  1605.     return;
  1606.   }
  1607.   /* Save the current values because FindByte will overwrite them */
  1608.   pCacheByteTemp[0]        = pCacheByte;
  1609.   PageTemp[0]              = Page;
  1610.   ColTemp[0]               = Col;
  1611.   #if (LCD_NUM_CONTROLLERS > 1)
  1612.     CurControllerTemp[0]     = CurController;
  1613.   #endif
  1614.   FindByte();
  1615.   if (pCacheByteTemp[0] != pCacheByte) {
  1616.     /* Save the new values */
  1617.     pCacheByteTemp[1]        = pCacheByte;
  1618.     PageTemp[1]              = Page;
  1619.     ColTemp[1]               = Col;
  1620.     #if (LCD_NUM_CONTROLLERS > 1)
  1621.       CurControllerTemp[1] = CurController;
  1622.     #endif
  1623.     /* Restore the old values for writing */
  1624.     pCacheByte        = pCacheByteTemp[0];
  1625.     Page              = PageTemp[0];
  1626.     Col               = ColTemp[0];
  1627.     #if (LCD_NUM_CONTROLLERS > 1)
  1628.       CurController = CurControllerTemp[0];
  1629.     #endif
  1630.     Flush();
  1631.     /* Restore the new (current) values */
  1632.     pCacheByte        = pCacheByteTemp[1];
  1633.     Page              = PageTemp[1];
  1634.     Col               = ColTemp[1];
  1635.     DataR_Valid=0;       /* We have no more info about what's in the data byte */
  1636.     #if (LCD_NUM_CONTROLLERS > 1)
  1637.       CurController = CurControllerTemp[1];
  1638.     #endif
  1639.   }
  1640. }
  1641. /*
  1642.         *****************************************
  1643.         *                                       *
  1644.         *         Set X and Y- Position         *
  1645.         *                                       *
  1646.         *****************************************
  1647.    Check if we already have the right byte in the buffer.
  1648.    This works only if COM-Lines are straight, otherwise it is just
  1649.    a waste of CPU-time.
  1650. */
  1651. #if (LCD_SUPPORT_COMTRANS)
  1652.   #define GotoXY(x,y)                     
  1653.     DataCacheY = y;                                                      
  1654.     DataCacheX = x;                         
  1655.     Goto()
  1656. #else
  1657. static void GotoXY(int x, int y) {
  1658.   DataCacheY = y;                                                          
  1659.   if ((x == DataCacheX) &&                  
  1660.       (y >= DataCacheY0) &&     (y <= DataCacheY1))
  1661.   {
  1662.     return;                                 
  1663.   }                                         
  1664.   DataCacheX = x;                         
  1665.   Goto();
  1666. }
  1667. #endif
  1668. /*
  1669.         *****************************************
  1670.         *                                       *
  1671.         *         Set Y- Position               *
  1672.         *                                       *
  1673.         *****************************************
  1674. */
  1675. #if (!LCD_SUPPORT_COMTRANS)     /* Only used if COMs are straight ! */
  1676. static void GotoY(int y) {
  1677. /* Check if we already have the right byte in the buffer.
  1678.    This works only if COM-Lines are straight, otherwise it is just
  1679.    a waste of CPU-time.
  1680.  */
  1681.   DataCacheY = y;    
  1682.   if ((y >= DataCacheY0) && (y <= DataCacheY1))
  1683.     return;
  1684.   Goto();
  1685. }
  1686. #endif
  1687. #if (LCD_SUPPORT_COMTRANS)
  1688. #define GotoYPlus1()           
  1689.   DataCacheY++;                
  1690.         Goto()
  1691. #else
  1692. static void GotoYPlus1(void) {
  1693.   DataCacheY++;
  1694.   if ((DataCacheY >= DataCacheY0) && (DataCacheY <= DataCacheY1))
  1695.     return;
  1696.         Goto();
  1697. }
  1698. #endif
  1699. /*
  1700.   ********************************************************************
  1701.   *                                                                  *
  1702.   *                Drawing routines, internal                        *
  1703.   *                                                                  *
  1704.   ********************************************************************
  1705. */
  1706. static const U8 Bit2Mask[] = { 1,2,4,8,16,32,64,128 };
  1707. /*
  1708.         *****************************************
  1709.         *                                       *
  1710.         *           Xor pixel                   *
  1711.         *                                       *
  1712.         *****************************************
  1713. */
  1714. /*
  1715. static void XORPIXEL() {
  1716.   U8 HWMask;
  1717.   LOADDATA();
  1718.   HWMask = Bit2Mask[DataCacheY-DataCacheYBit0];
  1719.   DataW_Dirty |= HWMask;
  1720.   DataW_Cache ^= HWMask;
  1721. }
  1722. */
  1723. #define XORPIXEL() {                             
  1724.   U8 HWMask;
  1725.   LOADDATA(); /* For XOR operations, the byte needs to be loaded */ 
  1726.   HWMask = Bit2Mask[DataCacheY-DataCacheYBit0];
  1727.   DataW_Dirty |= HWMask;
  1728.   DataW_Cache ^= HWMask;
  1729. }
  1730. static void XorPixel(void) {
  1731.   XORPIXEL();
  1732. }
  1733. /*
  1734.         *****************************************
  1735.         *                                       *
  1736.         *     Set pixel, internal drawing       *
  1737.         *                                       *
  1738.         *****************************************
  1739. */
  1740. /*
  1741. static void SETPIXEL() {
  1742.   U8 HWMask;
  1743.   HWMask = Bit2Mask[DataCacheY-DataCacheYBit0];
  1744.   DataW_Dirty |= HWMask;
  1745.   DataW_Cache |= HWMask;
  1746. }
  1747. */
  1748. #define SETPIXEL() {                             
  1749.   U8 HWMask;  
  1750.   HWMask = Bit2Mask[DataCacheY-DataCacheYBit0];  
  1751.   DataW_Dirty |= HWMask;  
  1752.   DataW_Cache |= HWMask;  
  1753. }
  1754. static void SetPixel(void) {
  1755.   SETPIXEL();
  1756. }
  1757. /*
  1758.         *********************************************************
  1759.         *                                                       *
  1760.         *       LCD_L0_XorPixel                                 *
  1761.         *                                                       *
  1762.         *********************************************************
  1763. Purpose:  This routine is called by emWin. It writes 1 pixel into the
  1764.           display.
  1765. */
  1766. void LCD_L0_XorPixel(int x, int y) {
  1767.   GotoXY(x,y);
  1768.   LOADDATA();
  1769.   XORPIXEL();
  1770. }
  1771. /*
  1772.         *****************************************
  1773.         *                                       *
  1774.         *       Clear pixel                     *
  1775.         *                                       *
  1776.         *****************************************
  1777. */
  1778. /*
  1779. static void CLRPIXEL() {
  1780.   U8 HWMask;
  1781.   HWMask = Bit2Mask[DataCacheY-DataCacheYBit0];
  1782.   DataW_Dirty |=  HWMask;
  1783.   DataW_Cache &= ~HWMask;
  1784. }
  1785. */
  1786. #define CLRPIXEL() {                             
  1787.   U8 HWMask;      
  1788.   HWMask = Bit2Mask[DataCacheY-DataCacheYBit0]; 
  1789.   DataW_Dirty |=  HWMask;     
  1790.   DataW_Cache &= ~HWMask;     
  1791. }
  1792. static void ClrPixel(void) {
  1793.   CLRPIXEL();
  1794. }
  1795. /*
  1796.         *********************************************************
  1797.         *                                                       *
  1798.         *       LCD_L0_SetPixelIndex                            *
  1799.         *                                                       *
  1800.         *********************************************************
  1801. Purpose:  This routine is called by emWin. It writes 1 pixel into the
  1802.           display.
  1803. */
  1804. void LCD_L0_SetPixelIndex(int x, int y, int ColorIndex) {
  1805.   GotoXY(x,y);
  1806.   LOADDATA();
  1807.   if (ColorIndex) {
  1808.     SETPIXEL();
  1809.   } else {
  1810.     CLRPIXEL();
  1811.   }
  1812.   FLUSH();
  1813. }
  1814. unsigned int LCD_L0_GetPixelIndex(int x, int y) {
  1815.   unsigned int Result;
  1816.   GotoXY(x,y);
  1817.   LOADDATA();
  1818.   Result = DataR_Cache & (1<<(DataCacheY&7));
  1819.   if (Result)
  1820.     return 1;
  1821.   else
  1822.     return 0;
  1823. }
  1824. /*
  1825.         *****************************************
  1826.         *                                       *
  1827.         *       Assign pixel                    *
  1828.         *                                       *
  1829.         *****************************************
  1830. */
  1831. #define ASSIGN_PIXEL(c)          { if(c) { SetPixel(); } else ClrPixel();}
  1832. /*
  1833. static void ASSIGN_PIXEL_FAST(U8 c)
  1834. {
  1835.   if(c) {
  1836.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1837.       XORPIXEL();
  1838.     } else {
  1839.       SETPIXEL();
  1840.     }
  1841.   } else {
  1842.     CLRPIXEL();
  1843.   }
  1844. }
  1845. */
  1846. #define ASSIGN_PIXEL_FAST(c) 
  1847.   if(c) { 
  1848.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) { 
  1849.       XORPIXEL(); 
  1850.     } else { 
  1851.       SETPIXEL(); 
  1852.     } 
  1853.   } else { 
  1854.     CLRPIXEL(); 
  1855.   } 
  1856. }
  1857. #define ASSIGN_PIXEL_REV(c)      { if(c) { ClrPixel(); } else SetPixel();}
  1858. #define ASSIGN_PIXEL_REV_FAST(c) { if(c) { CLRPIXEL(); } else SETPIXEL();}
  1859. /*
  1860.   ********************************************************************
  1861.   *                                                                  *
  1862.   *           Line drawing routines, internal                        *
  1863.   *                                                                  *
  1864.   ********************************************************************
  1865. There are 2 line drawing routines for horizontal and vertical
  1866. line drawing. Due to the organization of the controllers video ram,
  1867. one of them (the vertical line draw routine) is a lot faster,
  1868. since it cam write up to 8 pixels at a time. This routine is therefor
  1869. used internally for filling of rectangles.
  1870. */
  1871. #if (!LCD_SUPPORT_COMTRANS)
  1872.   static const U8 aMaskStart[8] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 };
  1873.   static const U8 aMaskEnd  [8] = { 0xff, 0x7f, 0x3f, 0x1f, 0xf,  0x7,  0x3,  0x1 };
  1874. #endif
  1875. static void DrawVLinePhys  (int x, int y0,  int y1) {
  1876. #if (!LCD_SUPPORT_COMTRANS)
  1877.   int yByte = y0 &(~7);
  1878.   U8  Mask = aMaskStart[y0-yByte];
  1879.   if (yByte+7 > y1) {   /* do we have to cut off the end ? */
  1880.     Mask &= aMaskEnd[yByte+7-y1];
  1881.   }
  1882.   CHECK_SCHEDULE(y1-y0+1);
  1883.   GotoXY(x,y0);
  1884.   if ((GUI_Context.DrawMode & LCD_DRAWMODE_XOR) ==0) {
  1885.     if(COLOR) {   /* Set Line */
  1886.       /* Draw first byte */
  1887.       DataW_Dirty |= Mask;
  1888.       DataW_Cache |= Mask;
  1889.       /* Draw middle bytes */
  1890.       yByte+=8;
  1891.       for (; yByte+7 <= y1; yByte+=8) {
  1892.         GotoY(yByte);
  1893.         DataW_Dirty = 0xff;
  1894.         DataW_Cache = 0xff;
  1895.       }
  1896.       /* Draw last (incomplete) byte */
  1897.       if (yByte <= y1) {
  1898.         GotoY(yByte);
  1899.         Mask = aMaskEnd[yByte-y1+7];
  1900.         DataW_Dirty |= Mask;
  1901.         DataW_Cache |= Mask;   
  1902.       }
  1903.     } else {      /* Clear Line */
  1904.       /* Draw first byte */
  1905.       DataW_Dirty |=  Mask;
  1906.       DataW_Cache &= ~Mask;
  1907.       /* Draw middle bytes */
  1908.       yByte+=8;
  1909.       for (; yByte+7 <= y1; yByte+=8) {
  1910.         GotoY(yByte);
  1911.         DataW_Dirty = 0xff;
  1912.         DataW_Cache = 0;
  1913.       }
  1914.       /* Draw last (incomplete) byte */
  1915.       if (yByte <= y1) {
  1916.         GotoY(yByte);
  1917.         Mask = aMaskEnd[yByte-y1+7];
  1918.         DataW_Dirty |=  Mask;
  1919.         DataW_Cache &= ~Mask;   
  1920.       }
  1921.     }
  1922.   } else { /* Xor Line */
  1923.     LOADDATA();
  1924.     /* Draw first byte */
  1925.     DataW_Dirty |= Mask;
  1926.     DataW_Cache ^= Mask;
  1927.     /* Draw middle bytes */
  1928.     yByte+=8;
  1929.     for (; yByte+7 <= y1; yByte+=8) {
  1930.       GotoY(yByte);
  1931.       LOADDATA();           /* for xor, data needs to be in cache */
  1932.       DataW_Dirty  = 0xff;
  1933.       DataW_Cache ^= 0xff;
  1934.     }
  1935.     /* Draw last (incomplete) byte */
  1936.     if (yByte <= y1) {
  1937.       GotoY(yByte);
  1938.       LOADDATA();           /* for xor, data needs to be in cache */
  1939.       Mask = aMaskEnd[yByte-y1+7];
  1940.       DataW_Dirty |= Mask;
  1941.       DataW_Cache ^= Mask;   
  1942.     }
  1943.   }
  1944. #else
  1945.   int NumPixels = y1-y0+1;
  1946.   if (NumPixels<=0)
  1947.     return;
  1948.   CHECK_SCHEDULE(NumPixels);
  1949.   GotoXY(x,y0);
  1950.   if ((GUI_Context.DrawMode & LCD_DRAWMODE_XOR) ==0) {
  1951.     if(COLOR) {   /* Set Line */
  1952.       for (; --NumPixels; ) {
  1953.         SETPIXEL();
  1954.         GotoYPlus1();
  1955.       }
  1956.       SetPixel();
  1957.     } else {      /* Clear Line */
  1958.       for (; --NumPixels; ) {
  1959.         CLRPIXEL();
  1960.         GotoYPlus1();
  1961.       }
  1962.       ClrPixel();
  1963.     }
  1964.   } else { /* Xor Line */
  1965.       for (; --NumPixels; ) {
  1966.       XorPixel();
  1967.       GotoYPlus1();
  1968.     }
  1969.     XorPixel();
  1970.   }
  1971. #endif
  1972. }
  1973. /*
  1974.         *****************************************
  1975.         *                                       *
  1976.         *       Draw horizontal line            *
  1977.         *                                       *
  1978.         *****************************************
  1979. Due to the organisation of the RAM of the LCD-controller, this is the
  1980. slow routine. It is not used by the driver unless there is no
  1981. other choice; for this reason it is not very important to try to
  1982. squeeze the last CPU-bus cycle out of it.
  1983. */
  1984. static void DrawHLinePhys  (int x0, int y,  int x1) {
  1985.   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  1986.     for ( ;x0 <= x1; x0++) {
  1987.       GotoXY(x0,y);
  1988.       XorPixel();
  1989.     }
  1990.   } else {
  1991.     if(COLOR) {
  1992.       for ( ;x0 <= x1; x0++) {
  1993.         GotoXY(x0,y);
  1994.         SetPixel();
  1995.       }
  1996.     } else {
  1997.       for ( ;x0 <= x1; x0++) {
  1998.         GotoXY(x0,y);
  1999.         ClrPixel();
  2000.       }
  2001.     }
  2002.   }
  2003. }
  2004. /*
  2005.   ********************************************************************
  2006.   *                                                                  *
  2007.   *                Drawing routines, public                          *
  2008.   *                                                                  *
  2009.   ********************************************************************
  2010. */
  2011. /*
  2012.         *****************************************
  2013.         *                                       *
  2014.         *       LCD_DrawPixel                   *
  2015.         *                                       *
  2016.         *****************************************
  2017. Purpose:  This routine is called by the upper layers of emWin.
  2018.           It writes 1 pixel into the display.
  2019. */
  2020. void LCD_L0_DrawPixel(int x, int y) {
  2021.   #if !LCD_SWAP_XY
  2022.     #define xP x
  2023.     #define yP y
  2024.   #else
  2025.     #define xP y
  2026.     #define yP x
  2027.   #endif
  2028.   GotoXY(xP,yP);
  2029.   ASSIGN_PIXEL_FAST(COLOR);
  2030.   FLUSH();
  2031. }
  2032. /*
  2033.         ****************************************
  2034.         *                                      *
  2035.         *     LCD_DrawHLine                    *
  2036.         *                                      *
  2037.         ****************************************
  2038. */
  2039. void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  2040.   #if !LCD_SWAP_XY
  2041.     DrawHLinePhys(x0, y, x1);
  2042.   #else
  2043.     DrawVLinePhys(y,x0, x1);
  2044.   #endif
  2045.   FLUSH();
  2046. }
  2047. /*
  2048.         ****************************************
  2049.         *                                      *
  2050.         *     LCD_DrawVLine                    *
  2051.         *                                      *
  2052.         ****************************************
  2053. */
  2054. void LCD_L0_DrawVLine  (int x, int y0,  int y1) {
  2055.   #if !LCD_SWAP_XY
  2056.     DrawVLinePhys(x,y0,y1);
  2057.   #else
  2058.     DrawHLinePhys(y0,x,y1);
  2059.   #endif
  2060.   FLUSH();
  2061. }
  2062. /*
  2063.         *****************************************
  2064.         *                                       *
  2065.         *          LCD_DrawRect                 *
  2066.         *                                       *
  2067.         *****************************************
  2068. */
  2069. void LCD_L0_FillRect(int x0, int y0, int x1, int y1) {
  2070. /* Now map logical to physical coordinates.
  2071.   Phys. and log. coordinates are identical unless x and y are swapped,
  2072.   in which case we simply assign x to y and vice versa.
  2073. */
  2074.   #if !LCD_SWAP_XY
  2075.      #define x0P x0
  2076.      #define y0P y0
  2077.      #define x1P x1
  2078.      #define y1P y1
  2079.   #else
  2080.      #define x0P y0
  2081.      #define y0P x0
  2082.      #define x1P y1
  2083.      #define y1P x1
  2084.   #endif
  2085.   for (; x0P <= x1P; x0P++) {
  2086.     DrawVLinePhys (x0P, y0P, y1P);
  2087.   }
  2088.   FLUSH();
  2089. }
  2090. /*
  2091.   ***************************************************************
  2092.   *                                                             *
  2093.   *            Internal bitmap routines                         *
  2094.   *                                                             *
  2095.   ***************************************************************
  2096. */
  2097. /*
  2098.     *********************************************
  2099.     *                                           *
  2100.     *      Draw Bitmap 1 BPP optimized          *
  2101.     *                                           *
  2102.     *********************************************
  2103. There are 2 versions of this routine, depending on if the display
  2104. is turned (X<-->Y swapped) or not.
  2105. */
  2106. #if !LCD_SWAP_XY
  2107. static void  DrawBitLine1BPP_NoSwap(
  2108.              int x, int y
  2109.              ,U8 const*pData
  2110.              ,int size
  2111.              ,const LCD_PIXELINDEX*pTrans
  2112.               ,int BytesPerLine
  2113.               ,U8 Mask)
  2114. {
  2115. /*
  2116. // Check if there is something left to draw
  2117. */
  2118.   GotoXY(x,y);
  2119.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR | LCD_DRAWMODE_REV)) {
  2120.   case LCD_DRAWMODE_NORMAL:
  2121.   case LCD_DRAWMODE_REV:
  2122.     for (; size>0; size--, pData+=BytesPerLine) {
  2123.       if(*pData & Mask) {
  2124.         if (*(pTrans+1)) { SETPIXEL(); }
  2125.         else             { CLRPIXEL(); }
  2126.       } else {
  2127.         if (*(pTrans  )) { SETPIXEL(); }
  2128.         else             { CLRPIXEL(); }
  2129.       }
  2130.       GotoYPlus1();
  2131.     }
  2132.     break;
  2133.   case LCD_DRAWMODE_XOR:
  2134.     for (; size>=1; size--, pData+=BytesPerLine) {
  2135.       if (*pData & Mask) { XORPIXEL(); }
  2136.       GotoYPlus1();
  2137.     }
  2138.     break;
  2139.   case LCD_DRAWMODE_TRANS:
  2140.     if (*(pTrans+1)) {  /* foreground positiv */
  2141.       for (; size>0; size--, pData+=BytesPerLine) {
  2142.         if(*pData & Mask) { SETPIXEL(); }
  2143.         GotoYPlus1();
  2144.       }
  2145.     } else {
  2146.       for (; size>0; size--, pData+=BytesPerLine) {
  2147.         if(*pData & Mask) { CLRPIXEL(); }
  2148.         GotoYPlus1();
  2149.       }
  2150.     }
  2151.     break;
  2152.   }
  2153. }
  2154. #else
  2155. static void  DrawBitLine1BPP_Swap(
  2156.              int x, int y
  2157.              ,U8 const*pData
  2158.              ,int size
  2159.              ,const U8*pTrans
  2160.              ,int BitNo)
  2161. {
  2162.   U8 Mask = 0x80>>(BitNo&7);
  2163.   pData += (BitNo>>3);
  2164. /*
  2165. // Check if there is something left to draw
  2166. */
  2167.   if (size <=0)
  2168.     return;
  2169.   GotoXY(x,y);
  2170.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
  2171.   case 0:
  2172.     if (*(pTrans+1)) {  /* foreground positiv */
  2173.       for (; size>1; size--) {
  2174.         ASSIGN_PIXEL_FAST(*pData & Mask);
  2175.         GotoYPlus1();
  2176.         if ((Mask >>=1)==0) {
  2177.           Mask =0x80;
  2178.           pData++;
  2179.         }
  2180.       }
  2181.       ASSIGN_PIXEL(*pData & Mask);
  2182.     } else {
  2183.       for (; size>1; size--) {
  2184.         ASSIGN_PIXEL_REV_FAST(*pData & Mask);
  2185.         GotoYPlus1();
  2186.         if ((Mask >>=1)==0) {
  2187.            Mask =0x80;
  2188.           pData++;
  2189.         }
  2190.       }
  2191.       ASSIGN_PIXEL_REV(*pData & Mask);
  2192.     }
  2193.     break;
  2194.   case LCD_DRAWMODE_TRANS:
  2195.     if (*(pTrans+1)) {  /* foreground positiv */
  2196.       for (; size>1; size--) {
  2197.         if(*pData & Mask) { SETPIXEL(); }
  2198.         GotoYPlus1();
  2199.         if ((Mask >>=1)==0) {
  2200.           Mask =0x80;
  2201.           pData++;
  2202.         }
  2203.       }
  2204.       ASSIGN_PIXEL(*pData & Mask);
  2205.     } else {
  2206.       for (; size>1; size--) {
  2207.         if(*pData & Mask) { CLRPIXEL(); }
  2208.         GotoYPlus1();
  2209.         if ((Mask >>=1)==0) {
  2210.            Mask =0x80;
  2211.           pData++;
  2212.         }
  2213.       }
  2214.       ASSIGN_PIXEL_REV(*pData & Mask);
  2215.     }
  2216.     break;
  2217.   case LCD_DRAWMODE_XOR:
  2218.     /* todo bugfix */
  2219.     for (; size>1; size--,y++) {
  2220.       if (*pData & Mask)
  2221.         XorPixel();
  2222.       GotoYPlus1();
  2223.       if ((Mask >>=1)==0) {
  2224.         Mask =0x80;
  2225.         pData++;
  2226.       }
  2227.     }
  2228.     if (*pData & Mask)
  2229.       XorPixel();
  2230.     break;
  2231.   }
  2232. }
  2233. #endif
  2234. /*
  2235.     *********************************************
  2236.     *                                           *
  2237.     *      Draw Bitmap 2 BPP                    *
  2238.     *                                           *
  2239.     *********************************************
  2240. */
  2241. #if (LCD_MAX_LOG_COLORS > 2)
  2242. static void  DrawBitLine2BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  2243.   LCD_PIXELINDEX pixel;
  2244. /*
  2245.         Jump to right entry point
  2246. */
  2247.   pixel = *p;
  2248.   if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) switch (Diff&3) {
  2249.   case 0:
  2250.     goto WriteTBit0;
  2251.   case 1:
  2252.     goto WriteTBit1;
  2253.   case 2:
  2254.     goto WriteTBit2;
  2255.   default:
  2256.     goto WriteTBit3;
  2257.   } else switch (Diff&3) {
  2258.   case 0:
  2259.     goto WriteBit0;
  2260.   case 1:
  2261.     goto WriteBit1;
  2262.   case 2:
  2263.     goto WriteBit2;
  2264.   default:
  2265.     goto WriteBit3;
  2266.   }
  2267. /*
  2268.         Write without transparency
  2269. */
  2270. WriteBit0:
  2271.   LCD_L0_SetPixelIndex(x+0, y, *(pTrans+(pixel>>6)));
  2272.   if (!--xsize)
  2273.     return;
  2274. WriteBit1:
  2275.   LCD_L0_SetPixelIndex(x+1, y, *(pTrans+(3&(pixel>>4))));
  2276.   if (!--xsize)
  2277.     return;
  2278. WriteBit2:
  2279.   LCD_L0_SetPixelIndex(x+2, y, *(pTrans+(3&(pixel>>2))));
  2280.   if (!--xsize)
  2281.     return;
  2282. WriteBit3:
  2283.   LCD_L0_SetPixelIndex(x+3, y, *(pTrans+(3&(pixel))));
  2284.   if (!--xsize)
  2285.     return;
  2286.   pixel = *(++p);
  2287.   x+=4;
  2288.   goto WriteBit0;
  2289. /*
  2290.         Write with transparency
  2291. */
  2292. WriteTBit0:
  2293.   if (pixel&(3<<6))
  2294.     LCD_L0_SetPixelIndex(x+0, y, *(pTrans+(pixel>>6)));
  2295.   if (!--xsize)
  2296.     return;
  2297. WriteTBit1:
  2298.   if (pixel&(3<<4))
  2299.     LCD_L0_SetPixelIndex(x+1, y, *(pTrans+(3&(pixel>>4))));
  2300.   if (!--xsize)
  2301.     return;
  2302. WriteTBit2:
  2303.   if (pixel&(3<<2))
  2304.     LCD_L0_SetPixelIndex(x+2, y, *(pTrans+(3&(pixel>>2))));
  2305.   if (!--xsize)
  2306.     return;
  2307. WriteTBit3:
  2308.   if (pixel&(3<<0))
  2309.     LCD_L0_SetPixelIndex(x+3, y, *(pTrans+(3&(pixel))));
  2310.   if (!--xsize)
  2311.     return;
  2312.   pixel = *(++p);
  2313.   x+=4;
  2314.   goto WriteTBit0;
  2315. }
  2316. #endif
  2317. /*
  2318.     *********************************************
  2319.     *                                           *
  2320.     *      Draw Bitmap 4 BPP                    *
  2321.     *                                           *
  2322.     *********************************************
  2323. */
  2324. #if (LCD_MAX_LOG_COLORS > 4)
  2325. static void  DrawBitLine4BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  2326.   LCD_PIXELINDEX pixel;
  2327. /*
  2328.         Jump to right entry point
  2329. */
  2330.   pixel = *p;
  2331.   if (GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) {
  2332.     if ((Diff&1) ==0)
  2333.       goto WriteTBit0;
  2334.     goto WriteTBit1;
  2335.   } else {
  2336.     if ((Diff&1) ==0)
  2337.       goto WriteBit0;
  2338.     goto WriteBit1;
  2339.   }
  2340. /*
  2341.         Write without transparency
  2342. */
  2343. WriteBit0:
  2344.   LCD_L0_SetPixelIndex(x+0, y, *(pTrans+(pixel>>4)));
  2345.   if (!--xsize)
  2346.     return;
  2347. WriteBit1:
  2348.   LCD_L0_SetPixelIndex(x+1, y, *(pTrans+(pixel&0xf)));
  2349.   if (!--xsize)
  2350.     return;
  2351.   x+=2;
  2352.   pixel = *(++p);
  2353.   goto WriteBit0;
  2354. /*
  2355.         Write with transparency
  2356. */
  2357. WriteTBit0:
  2358.   if (pixel>>4)
  2359.     LCD_L0_SetPixelIndex(x+0, y, *(pTrans+(pixel>>4)));
  2360.   if (!--xsize)
  2361.     return;
  2362. WriteTBit1:
  2363.   if (pixel&0xf)
  2364.     LCD_L0_SetPixelIndex(x+1, y, *(pTrans+(pixel&0xf)));
  2365.   if (!--xsize)
  2366.     return;
  2367.   x+=2;
  2368.   pixel = *(++p);
  2369.   goto WriteTBit0;
  2370. }
  2371. #endif
  2372. /*
  2373.     *********************************************
  2374.     *                                           *
  2375.     *      Draw Bitmap 8 BPP  (256 colors)      *
  2376.     *                                           *
  2377.     *********************************************
  2378. */
  2379. #if (LCD_MAX_LOG_COLORS > 16)
  2380. static void  DrawBitLine8BPP(int x, int y, U8 const*p, int xsize, const LCD_PIXELINDEX*pTrans) {
  2381.   LCD_PIXELINDEX pixel;
  2382.   if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS)==0) {
  2383.     while (xsize > 0) {
  2384.       pixel = *p;
  2385.       LCD_L0_SetPixelIndex(x+0, y, *(pTrans+pixel));
  2386.       xsize--;
  2387.       x++;
  2388.       p++;
  2389.     }
  2390.   } else {   /* Handle transparent bitmap */
  2391.     while (xsize > 0) {
  2392.       pixel = *p;
  2393.       if (pixel)
  2394.         LCD_L0_SetPixelIndex(x+0, y, *(pTrans+pixel));
  2395.       xsize--;
  2396.       x++;
  2397.       p++;
  2398.     }
  2399.   }
  2400. }
  2401. #endif
  2402. /*
  2403.     ******************************************************************
  2404.     *                                                                *
  2405.     *             Universal draw Bitmap routine                      *
  2406.     *                                                                *
  2407.     ******************************************************************
  2408. */
  2409. void LCD_L0_DrawBitmap   (int x0, int y0,
  2410.                        int xsize, int ysize,
  2411.                        int BitsPerPixel, 
  2412.                        int BytesPerLine,
  2413.                        const U8* pData, int Diff,
  2414.                        const LCD_PIXELINDEX* pTrans)
  2415. {
  2416.   int i;
  2417.   /* Use aID for bitmaps without palette */
  2418.   if (!pTrans) {
  2419.     pTrans = aID;
  2420.   }
  2421.   /*
  2422.      Use DrawBitLineXBPP
  2423.   */
  2424.   #if !LCD_SWAP_XY
  2425.     switch (BitsPerPixel) {
  2426.     case 1:
  2427.       xsize+=Diff&7;
  2428.       for (i=Diff; i<xsize; i++) {
  2429.         DrawBitLine1BPP_NoSwap(x0+i, y0,
  2430.                                pData+(i>>3),
  2431.                                ysize,
  2432.                                pTrans,
  2433.                                BytesPerLine,
  2434.                                0x80>>(i&7));
  2435.       }
  2436.       break;
  2437.       #if (LCD_MAX_LOG_COLORS > 2)
  2438.         case 2:
  2439.           for (i=0; i<ysize; i++) {
  2440.             DrawBitLine2BPP(x0, i+y0, pData, Diff, xsize, pTrans);
  2441.             pData += BytesPerLine;
  2442.           }
  2443.           break;
  2444.       #endif
  2445.       #if (LCD_MAX_LOG_COLORS > 4)
  2446.         case 4:
  2447.           for (i=0; i<ysize; i++) {
  2448.             DrawBitLine4BPP(x0, i+y0, pData, Diff, xsize, pTrans);
  2449.             pData += BytesPerLine;
  2450.           }
  2451.           break;
  2452.       #endif
  2453.       #if (LCD_MAX_LOG_COLORS > 16)
  2454.         case 8:
  2455.           for (i=0; i<ysize; i++) {
  2456.             DrawBitLine8BPP(x0, i+y0, pData, xsize, pTrans);
  2457.             pData += BytesPerLine;
  2458.           }
  2459.           break;
  2460.       #endif
  2461.     }
  2462.   #else
  2463.     switch (BitsPerPixel) {
  2464.     case 1:
  2465.       for (i=0; i<ysize; i++) {
  2466.         DrawBitLine1BPP_NoSwap(x0+i, y0,
  2467.                                pData+(i>>3),
  2468.                                ysize,
  2469.                                pTrans,
  2470.                                BytesPerLine,
  2471.                                0x80>>(i&7));
  2472.         pData += BytesPerLine;
  2473.       }
  2474.       break;
  2475.     }
  2476.   #endif
  2477.   FLUSH();
  2478. }
  2479. /*
  2480.         *********************************************************
  2481.         *                                                       *
  2482.         *       LCD_L0_SetOrg                                   *
  2483.         *                                                       *
  2484.         *********************************************************
  2485. Purpose: 
  2486.   Sets the original position of the virtual display.
  2487.   Has no function at this point with this driver,
  2488.   because the 15XX uses built-in memory as video memory.
  2489.   This memory is just big enough to store the info needed
  2490.   for the max. display resolution supported.
  2491. */
  2492. #if LCD_SUPPORT_SETORG
  2493. int OrgX, OrgY;
  2494. void LCD_L0_SetOrg(int x, int y) {
  2495.   OrgX = x;
  2496.   OrgY = y;
  2497. }
  2498. #endif
  2499. /*
  2500.         *********************************************************
  2501.         *                                                       *
  2502.         *       Support for dynamic inversion of LCD            *
  2503.         *                                                       *
  2504.         *********************************************************
  2505. */
  2506. #if LCD_SUPPORT_RT_INVERSION
  2507. void LCD_SetInverse   (void) {
  2508.   LCD_WriteSingleCommandAll(LCD_CMDREVERSE);  
  2509. }
  2510. /* This function is always available, it can not be eliminated
  2511.    by means of a configuration switch ! */
  2512. void LCD_ClrInverse   (void) {
  2513.   LCD_WriteSingleCommandAll(LCD_CMDNORMAL);  
  2514. }
  2515. #endif
  2516. /*
  2517.   ********************************************************************
  2518.   *                                                                  *
  2519.   *                       Refresh the Display                        *
  2520.   *                                                                  *
  2521.   ********************************************************************
  2522. */
  2523. /*
  2524.         *************************************************
  2525.         *                                               *
  2526.         *           Refresh display partially           *
  2527.         *                                               *
  2528.         *************************************************
  2529. */
  2530. #if LCD_SUPPORT_REFRESH
  2531. static U8 RefreshPage;
  2532. static void LCD_RefreshSection(void) {
  2533.   U8 OldPage = Page;
  2534.   U8 OldCol  = Col;
  2535.   U8* pData;
  2536.   Page = RefreshPage++;
  2537.   SetPage0();
  2538.   Col=0;
  2539.   SetCAdr0();
  2540.   pData = &Cache0[Page][Col];
  2541.   for (; Col<=LCD_NUM_SEGS0; Col++) {
  2542.     LCD_WriteData0(*pData++);
  2543.   }
  2544.   Page = OldPage;
  2545.   Col  = OldCol;
  2546.   if (RefreshPage >= NUM_PAGES0) {
  2547.     RefreshPage=0;
  2548.   }
  2549. }
  2550. /*
  2551.         *************************************************
  2552.         *                                               *
  2553.         *           Refresh entire display              *
  2554.         *                                               *
  2555.         *************************************************
  2556. */
  2557. void LCD_L0_Refresh(void) {
  2558.   int i;
  2559.   for (i=0; i<NUM_PAGES0; i++) {
  2560.     LCD_RefreshSection();
  2561.   }
  2562. }
  2563. #endif
  2564. /*
  2565.         *********************************************************
  2566.         *                                                       *
  2567.         *           Support for verification                    *
  2568.         *                                                       *
  2569.         *********************************************************
  2570. */
  2571. #if LCD_SUPPORT_VERIFY
  2572. static int ErrCnt;
  2573. static int ErrStat;
  2574. int  LCD_GetErrStat(void) {
  2575.   return ErrStat;
  2576. }
  2577. void LCD_ClrErrStat(void) {
  2578.   ErrStat = ErrCnt=0;
  2579. }
  2580. int  LCD_GetErrCnt (void) {
  2581.   return ErrCnt;
  2582. }
  2583. #endif  
  2584. /*
  2585.         *********************************************************
  2586.         *                                                       *
  2587.         *       LCD_On                                          *
  2588.         *       LCD_Off                                         *
  2589.         *                                                       *
  2590.         *********************************************************
  2591. */
  2592. #if LCD_SUPPORT_CHECKINIT
  2593.   static char IsOn;           /* Only needed for init check ! */
  2594. #endif
  2595. void LCD_On           (void) {
  2596.   LCD_WriteSingleCommandAll(CMD_LCD_ON);  
  2597.   #if LCD_SUPPORT_CHECKINIT
  2598.     IsOn =1;
  2599.   #endif
  2600. }
  2601. void LCD_Off          (void) {
  2602.   LCD_WriteSingleCommandAll(CMD_LCD_OFF);  
  2603.   #if LCD_SUPPORT_CHECKINIT
  2604.     IsOn =0;
  2605.   #endif
  2606. }
  2607. /*
  2608.         *********************************************************
  2609.         *                                                       *
  2610.         *       Support for different pages                     *
  2611.         *                                                       *
  2612.         *********************************************************
  2613. */
  2614. #if LCD_SUPPORT_PAGING
  2615. static U8 VisPage;
  2616. static U8 SelPage;
  2617. static int    XAdd;
  2618. int LCD_SelPage  (int Page) {
  2619.   int r = SelPage;
  2620.   SelPage = Page;
  2621.   XAdd = Page * LCD_XSIZE;
  2622.   return r;
  2623. }
  2624. int LCD_ShowPage (int Page) {
  2625.   int r = SelPage;
  2626.   SelPage = Page;
  2627. /* Update hardware */
  2628.   return r;
  2629. }
  2630. /* returns selected page */
  2631. int LCD_GetSelPage (void) {
  2632.   return SelPage;
  2633. }
  2634. /* returns visible page */
  2635. int LCD_GetVisPage (void) {
  2636.   return VisPage;
  2637. }
  2638. #endif
  2639. /*
  2640. *********************************************************
  2641. *
  2642. *       LCD_L0_ReInit : Re-Init the display
  2643. *
  2644. *********************************************************
  2645. ReInit contains all of the code that can be re-executed at any point without
  2646. changing or even disturbing what can be seen on the LCD.
  2647. Note that it is also used as a subroutine by LCD_Init().
  2648. */
  2649. #if LCD_MIRROR_X
  2650.   #define LCD_CMDSETADC 0xa1     /* ADC select: reverse  segment
  2651.                                     driver output (mirroring X) */
  2652. #else
  2653.   #define LCD_CMDSETADC 0xa0     /* ADC select: normal segment driver output */
  2654. #endif
  2655. #if LCD_MIRROR_Y
  2656.   #if LCD_CONTROLLER == 1560
  2657.     #error MIRROR_Y not supported for 1560 ! (Use LCD_INIT_CONTROLLER instead)
  2658.   #endif
  2659.   #define LCD_CMDCOMMODE  0xc8   /* Common mode : reverse output (mirroring Y) */
  2660. #else
  2661.   #define LCD_CMDCOMMODE  0xc0   /* Common mode : normal */
  2662. #endif
  2663. void  LCD_L0_ReInit(void) {
  2664.   int i;
  2665.   for (i=0; i<LCD_NUM_CONTROLLERS; i++) {
  2666.     aPage[i] = aCAdr[i] = 255;
  2667.   }
  2668.   INIT_CONTROLLER();                     /* macro defined in config */
  2669.   #if (LCD_CONTROLLER/100 == 15)
  2670.     LCD_WriteSingleCommandAll(LCD_CMDSETADC);      /* ADC select   */
  2671.     #if LCD_CONTROLLER != 1560                     /* This command is not available for the 1560 ! */
  2672.       LCD_WriteSingleCommandAll(LCD_CMDCOMMODE);   /* Set common mode */
  2673.     #endif
  2674.     LCD_WriteSingleCommandAll(LCD_FIRSTCOM0+0x40); /* Set start adress */
  2675.     LCD_WriteSingleCommandAll(0xA4);               /* Data Display Mode (not all on)  */
  2676.     LCD_WriteSingleCommandAll(LCD_CMDNORMAL);      /* Normal (Not reversed) mode  */
  2677.   #endif
  2678. }
  2679. static void LCD__ClearVRam(void) {
  2680.   for (Page=0; Page <=8; Page++) {
  2681.     SetPage0();
  2682.     #if (LCD_NUM_CONTROLLERS >1)
  2683.       SetPage1();
  2684.     #endif
  2685.     #if (LCD_NUM_CONTROLLERS >2)
  2686.       SetPage2();
  2687.     #endif
  2688.     #if (LCD_NUM_CONTROLLERS >3)
  2689.       SetPage3();
  2690.     #endif
  2691.     Col=0;
  2692.     SetCAdr0();
  2693.     #if (LCD_NUM_CONTROLLERS >1)
  2694.       SetCAdr1();
  2695.     #endif
  2696.     #if (LCD_NUM_CONTROLLERS >2)
  2697.       SetCAdr2();
  2698.     #endif
  2699.     #if (LCD_NUM_CONTROLLERS >3)
  2700.       SetCAdr3();
  2701.     #endif
  2702.     for (; Col<=LCD_SEGS_MAX; Col++) {
  2703.       LCD_WriteData0(0);
  2704.       #if (LCD_NUM_CONTROLLERS >1)
  2705.         LCD_WriteData1(0);
  2706.       #endif
  2707.       #if (LCD_NUM_CONTROLLERS >2)
  2708.         LCD_WriteData2(0);
  2709.       #endif
  2710.       #if (LCD_NUM_CONTROLLERS >3)
  2711.         LCD_WriteData3(0);
  2712.       #endif
  2713.     }
  2714.     memset (&aCAdr, LCD_SEGS_MAX-1, sizeof(aCAdr));    /* Invalidate register caches */
  2715.   }
  2716. }
  2717. /********************************************************
  2718. *
  2719. *       LCD_L0_SetOrg
  2720. *
  2721. *********************************************************
  2722. */
  2723. void LCD_L0_SetOrg(int x, int y) {
  2724.   LCD_USE_PARA(x);
  2725.   LCD_USE_PARA(y);
  2726. }
  2727. /*
  2728.         *********************************************************
  2729.         *                                                       *
  2730.         *       LCD_Init : Init the display                     *
  2731.         *                                                       *
  2732.         *********************************************************
  2733. */
  2734. #define ZEROINIT(var) memset(&var,0,sizeof(var))
  2735. int  LCD_L0_Init(void) {
  2736. /* Initialize static variables */
  2737. /* Clear Cache (If a cache has been configured) */
  2738.   #if LCD_CACHE
  2739.     ZEROINIT(Cache0);
  2740.     #if (LCD_NUM_CONTROLLERS >1)
  2741.       ZEROINIT(Cache1);
  2742.     #endif
  2743.     #if (LCD_NUM_CONTROLLERS >2)
  2744.       ZEROINIT(Cache2);
  2745.     #endif
  2746.     #if (LCD_NUM_CONTROLLERS >3)
  2747.       ZEROINIT(Cache3);
  2748.     #endif
  2749.   #endif
  2750.   #if  LCD_SUPPORT_CACHECONTROL
  2751.     CacheStat   =0;     /* 0: No changes */
  2752.     CacheLocked =0;     /* 0: Not locked */
  2753.     ZEROINIT(aaCacheDirtyTag0);
  2754.     #if (LCD_NUM_CONTROLLERS >1)
  2755.       ZEROINIT(aaCacheDirtyTag1);
  2756.     #endif
  2757.     #if (LCD_NUM_CONTROLLERS >2)
  2758.       ZEROINIT(aaCacheDirtyTag2);
  2759.     #endif
  2760.     #if (LCD_NUM_CONTROLLERS >3)
  2761.       ZEROINIT(aaCacheDirtyTag3);
  2762.     #endif
  2763.   #endif
  2764.   memset (&aPage, 255, sizeof(aPage));    /* Invalidate register caches */
  2765.   memset (&aCAdr, 255, sizeof(aCAdr));    /* Invalidate register caches */
  2766.   DataCacheX=-1;         /* Invalidate byte level cache */
  2767.   #if LCD_SUPPORT_VERIFY
  2768.     ErrCnt =0;
  2769.     ErrStat=0;
  2770.   #endif
  2771.   LCD_Off();
  2772.   LCD_L0_ReInit();
  2773. #if 0 /* For LCD-Test */
  2774.   LCD__ClearVRam();
  2775.   for (Page=0; Page <=8; Page++) {
  2776.     int Bit;
  2777.     SetPage0();
  2778.         for (Bit=0; Bit<=7; Bit++) {
  2779.       int Data = ((2<<Bit)-1);
  2780.           for (Col=0, SetCAdr0(); Col<=LCD_SEGS_MAX; Col++) {
  2781.         LCD_WriteData0(Data);
  2782.           }
  2783.         }
  2784.   }
  2785.   for (Page=0; Page <=8; Page++) {
  2786.     int Bit;
  2787.     SetPage1();
  2788.         for (Bit=0; Bit<=7; Bit++) {
  2789.       int Data = ((2<<Bit)-1);
  2790.           for (Col=0, SetCAdr1(); Col<=LCD_SEGS_MAX; Col++) {
  2791.         LCD_WriteData1(Data);
  2792.           }
  2793.         }
  2794.   }
  2795. #endif
  2796.   LCD__ClearVRam();
  2797.   LCD_On();
  2798.   return 0;
  2799. }
  2800. /*
  2801.         *********************************************************
  2802.         *                                                       *
  2803.         *                   LCD_L0_SetLUTEntry                     *
  2804.         *                                                       *
  2805.         *********************************************************
  2806.   This function is required, but has no functionality
  2807.   with 15XX controllers
  2808. */
  2809. void LCD_L0_SetLUTEntry(U8 Pos, LCD_COLOR color) {
  2810.   LCD_USE_PARA(Pos);
  2811.   LCD_USE_PARA(color);
  2812. }
  2813. /*
  2814.         *********************************************************
  2815.         *                                                       *
  2816.         *       LCD_L0_CheckInit                                   *
  2817.         *                                                       *
  2818.         *  Check if display controller(s) is/are still          *
  2819.         *  properly initialized                                 *
  2820.         *                                                       *
  2821.         *********************************************************
  2822. Return value:   0 => No error, init is O.K.
  2823. */
  2824. /* Create the mask to compare statuss with.
  2825.    The mask depends on the configuration.
  2826.    For details, refer to the manual page 8-49.
  2827. */
  2828. #if LCD_SUPPORT_CHECKINIT
  2829. int LCD_L0_CheckInit(void) {
  2830.   #if !LCD_READABLE
  2831.     return 0;           /* If LCD is not readable, there is
  2832.                            no way to check the configuration ! */
  2833.   #else
  2834.     /* Unfortunately, we can not read back the controller .
  2835.        The only thing that we can do is a status check.  */
  2836.     U8 Stat = LCD_ReadCmd0();
  2837.     /* Status of all controllers should be identical */
  2838.     #if (LCD_NUM_CONTROLLERS >1)
  2839.       if (Stat != LCD_ReadCmd1())
  2840.         return 1;
  2841.     #endif
  2842.     #if (LCD_NUM_CONTROLLERS >2)
  2843.       if (Stat != LCD_ReadCmd2())
  2844.         return 1;
  2845.     #endif
  2846.     #if (LCD_NUM_CONTROLLERS >3)
  2847.       if (Stat != LCD_ReadCmd3())
  2848.         return 1;
  2849.     #endif
  2850.     if (IsOn)
  2851.       Stat ^= (1<<5);   /* xor the on/off bit,
  2852.                           result should be 0 if O.K. */
  2853.     #if !LCD_MIRROR_X
  2854.       Stat ^= (1<<6);   /* xor the adc bit,
  2855.                           result should be 0 if O.K. */
  2856.     #endif
  2857.     return Stat;        /* will be 0 if all bits are O.K. */
  2858.   #endif
  2859. }
  2860. #endif
  2861. #else
  2862. void LCD15XX(void) { } /* avoid empty object files */
  2863. #endif /* (LCD_CONTROLLER/100 == 15) */
  2864. /* **************** END OF FILE ********************* */