Subversion Repositories HomeAutomation

Rev

Rev 1041 | Rev 1087 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. #include "ks0108.h"
  2. //#include <avr/io.h>
  3. #include "font.h"
  4. //#include <avr\pgmspace.h>
  5. #include <avr/io.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8.  
  9. #include <avr/pgmspace.h>
  10.  
  11. //Some parts of the code is from proycon avrlib written by Pascal Stang:
  12. //*****************************************************************************
  13. //
  14. // File Name    : 'glcd.c'
  15. // Title        : Graphic LCD API functions
  16. // Author       : Pascal Stang - Copyright (C) 2002
  17. // Date         : 5/30/2002
  18. // Revised      : 5/30/2002
  19. // Version      : 0.5
  20. // Target MCU   : Atmel AVR
  21. // Editor Tabs  : 4
  22. //
  23. // NOTE: This code is currently below version 1.0, and therefore is considered
  24. // to be lacking in some functionality or documentation, or may not be fully
  25. // tested.  Nonetheless, you can expect most functions to work.
  26. //
  27. // This code is distributed under the GNU Public License
  28. //      which can be found at http://www.gnu.org/licenses/gpl.txt
  29. //
  30. //*****************************************************************************
  31.  
  32. #define OUTPUT  0
  33. #define INPUT   1
  34.  
  35. volatile GrLcdStateType GrLcdState;
  36.  
  37. void SetControls(uint8_t RS, uint8_t RW){
  38.     if(RS) {gpio_set_pin(LCD_CONTROL_RS);} else {gpio_clr_pin(LCD_CONTROL_RS);};
  39.     if(RW) {gpio_set_pin(LCD_CONTROL_RW);} else {gpio_clr_pin(LCD_CONTROL_RW);};
  40.    
  41.     //if(RS) {LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_RS);} else { LCD_CONTROL_PORT &= ~(1<<LCD_CONTROL_PIN_RS);};
  42.     //if(RW) {LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_RW);} else { LCD_CONTROL_PORT &= ~(1<<LCD_CONTROL_PIN_RW);};
  43. }
  44.  
  45. void SetData(uint8_t Data){
  46.     if(Data&0x01) {gpio_set_pin(LCD_DATA_DB0);} else {gpio_clr_pin(LCD_DATA_DB0);};
  47.     if(Data&0x02) {gpio_set_pin(LCD_DATA_DB1);} else {gpio_clr_pin(LCD_DATA_DB1);};
  48.     if(Data&0x04) {gpio_set_pin(LCD_DATA_DB2);} else {gpio_clr_pin(LCD_DATA_DB2);};
  49.     if(Data&0x08) {gpio_set_pin(LCD_DATA_DB3);} else {gpio_clr_pin(LCD_DATA_DB3);};
  50.     if(Data&0x10) {gpio_set_pin(LCD_DATA_DB4);} else {gpio_clr_pin(LCD_DATA_DB4);};
  51.     if(Data&0x20) {gpio_set_pin(LCD_DATA_DB5);} else {gpio_clr_pin(LCD_DATA_DB5);};
  52.     if(Data&0x40) {gpio_set_pin(LCD_DATA_DB6);} else {gpio_clr_pin(LCD_DATA_DB6);};
  53.     if(Data&0x80) {gpio_set_pin(LCD_DATA_DB7);} else {gpio_clr_pin(LCD_DATA_DB7);};
  54. /*    
  55.     if(Data&0x01) {LCD_DATA_PORT_DB0 |= (1<<LCD_DATA_PIN_DB0);} else { LCD_DATA_PORT_DB0 &= ~(1<<LCD_DATA_PIN_DB0);};
  56.     if(Data&0x02) {LCD_DATA_PORT_DB1 |= (1<<LCD_DATA_PIN_DB1);} else { LCD_DATA_PORT_DB1 &= ~(1<<LCD_DATA_PIN_DB1);};
  57.     if(Data&0x04) {LCD_DATA_PORT_DB2 |= (1<<LCD_DATA_PIN_DB2);} else { LCD_DATA_PORT_DB2 &= ~(1<<LCD_DATA_PIN_DB2);};
  58.     if(Data&0x08) {LCD_DATA_PORT_DB3 |= (1<<LCD_DATA_PIN_DB3);} else { LCD_DATA_PORT_DB3 &= ~(1<<LCD_DATA_PIN_DB3);};
  59.     if(Data&0x10) {LCD_DATA_PORT_DB4 |= (1<<LCD_DATA_PIN_DB4);} else { LCD_DATA_PORT_DB4 &= ~(1<<LCD_DATA_PIN_DB4);};
  60.     if(Data&0x20) {LCD_DATA_PORT_DB5 |= (1<<LCD_DATA_PIN_DB5);} else { LCD_DATA_PORT_DB5 &= ~(1<<LCD_DATA_PIN_DB5);};
  61.     if(Data&0x40) {LCD_DATA_PORT_DB6 |= (1<<LCD_DATA_PIN_DB6);} else { LCD_DATA_PORT_DB6 &= ~(1<<LCD_DATA_PIN_DB6);};
  62.     if(Data&0x80) {LCD_DATA_PORT_DB7 |= (1<<LCD_DATA_PIN_DB7);} else { LCD_DATA_PORT_DB7 &= ~(1<<LCD_DATA_PIN_DB7);};
  63. */
  64. }
  65. uint8_t GetData(void){
  66.     uint8_t input = 0;
  67.     if (gpio_get_state(LCD_DATA_DB0)) {input += 1;}
  68.     if (gpio_get_state(LCD_DATA_DB1)) {input += 2;}
  69.     if (gpio_get_state(LCD_DATA_DB2)) {input += 4;}
  70.     if (gpio_get_state(LCD_DATA_DB3)) {input += 8;}
  71.     if (gpio_get_state(LCD_DATA_DB4)) {input += 16;}
  72.     if (gpio_get_state(LCD_DATA_DB5)) {input += 32;}
  73.     if (gpio_get_state(LCD_DATA_DB6)) {input += 64;}
  74.     if (gpio_get_state(LCD_DATA_DB7)) {input += 128;}
  75. /*
  76.     if (LCD_DATA_IN_DB0 & (1<<LCD_DATA_PIN_DB0)) {input += 1;}
  77.     if (LCD_DATA_IN_DB1 & (1<<LCD_DATA_PIN_DB1)) {input += 2;}
  78.     if (LCD_DATA_IN_DB2 & (1<<LCD_DATA_PIN_DB2)) {input += 4;}
  79.     if (LCD_DATA_IN_DB3 & (1<<LCD_DATA_PIN_DB3)) {input += 8;}
  80.     if (LCD_DATA_IN_DB4 & (1<<LCD_DATA_PIN_DB4)) {input += 16;}
  81.     if (LCD_DATA_IN_DB5 & (1<<LCD_DATA_PIN_DB5)) {input += 32;}
  82.     if (LCD_DATA_IN_DB6 & (1<<LCD_DATA_PIN_DB6)) {input += 64;}
  83.     if (LCD_DATA_IN_DB7 & (1<<LCD_DATA_PIN_DB7)) {input += 128;}
  84. */
  85.     return input;
  86. }
  87.  
  88. void Disable(){
  89.     gpio_clr_pin(LCD_CONTROL_E);
  90.     //LCD_CONTROL_PORT &= ~(1<<LCD_CONTROL_PIN_E);
  91. }
  92.  
  93. void Delay(){
  94.     delay_us(1);
  95. }
  96.  
  97. void Enable(){
  98.     Delay();
  99.     gpio_set_pin(LCD_CONTROL_E);    //LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_E);
  100.     Delay();
  101.     Disable();
  102.     Delay();
  103. }
  104.  
  105. void SetDirection(uint8_t dir){
  106.   if (dir == OUTPUT){
  107.     gpio_set_out(LCD_DATA_DB0);
  108.     gpio_set_out(LCD_DATA_DB1);
  109.     gpio_set_out(LCD_DATA_DB2);
  110.     gpio_set_out(LCD_DATA_DB3);
  111.     gpio_set_out(LCD_DATA_DB4);
  112.     gpio_set_out(LCD_DATA_DB5);
  113.     gpio_set_out(LCD_DATA_DB6);
  114.     gpio_set_out(LCD_DATA_DB7);
  115. /*
  116.     LCD_DATA_DDR_DB0 |= (1<<LCD_DATA_PIN_DB0);
  117.     LCD_DATA_DDR_DB1 |= (1<<LCD_DATA_PIN_DB1);
  118.     LCD_DATA_DDR_DB2 |= (1<<LCD_DATA_PIN_DB2);
  119.     LCD_DATA_DDR_DB3 |= (1<<LCD_DATA_PIN_DB3);
  120.     LCD_DATA_DDR_DB4 |= (1<<LCD_DATA_PIN_DB4);
  121.     LCD_DATA_DDR_DB5 |= (1<<LCD_DATA_PIN_DB5);
  122.     LCD_DATA_DDR_DB6 |= (1<<LCD_DATA_PIN_DB6);
  123.     LCD_DATA_DDR_DB7 |= (1<<LCD_DATA_PIN_DB7);
  124. */
  125.   }else if (dir == INPUT){
  126.     gpio_set_in(LCD_DATA_DB0);
  127.     gpio_set_in(LCD_DATA_DB1);
  128.     gpio_set_in(LCD_DATA_DB2);
  129.     gpio_set_in(LCD_DATA_DB3);
  130.     gpio_set_in(LCD_DATA_DB4);
  131.     gpio_set_in(LCD_DATA_DB5);
  132.     gpio_set_in(LCD_DATA_DB6);
  133.     gpio_set_in(LCD_DATA_DB7);
  134. /*
  135.     LCD_DATA_DDR_DB0 &= ~(1<<LCD_DATA_PIN_DB0);
  136.     LCD_DATA_DDR_DB1 &= ~(1<<LCD_DATA_PIN_DB1);
  137.     LCD_DATA_DDR_DB2 &= ~(1<<LCD_DATA_PIN_DB2);
  138.     LCD_DATA_DDR_DB3 &= ~(1<<LCD_DATA_PIN_DB3);
  139.     LCD_DATA_DDR_DB4 &= ~(1<<LCD_DATA_PIN_DB4);
  140.     LCD_DATA_DDR_DB5 &= ~(1<<LCD_DATA_PIN_DB5);
  141.     LCD_DATA_DDR_DB6 &= ~(1<<LCD_DATA_PIN_DB6);
  142.     LCD_DATA_DDR_DB7 &= ~(1<<LCD_DATA_PIN_DB7);
  143. */
  144.   }
  145. }
  146. void glcdSetColor(uint8_t color){
  147.   GrLcdState.color=color;
  148. }
  149. uint8_t glcdGetColor(void){
  150.   return GrLcdState.color;
  151. }
  152. void glcdWriteData(uint8_t data, uint8_t color){
  153.     SetControls(1,0);
  154.     if (color == GLCD_COLOR_CLEAR)
  155.       data = ~data;
  156.     if (GrLcdState.color == GLCD_COLOR_BLACK)
  157.       SetData(data);
  158.     else
  159.       SetData(~data);
  160.     Enable();
  161.     GrLcdState.lcdXAddr++;
  162.  
  163.     if (GrLcdState.lcdXAddr > 63){
  164.         glcdSetXY(GrLcdState.lcdXAddr,GrLcdState.lcdYAddr);
  165.     }
  166.     if (GrLcdState.lcdXAddr > 128){
  167.         glcdSetXY(0,GrLcdState.lcdYAddr+8);
  168.     }
  169. }
  170. void glcdWriteDataTransparent(uint8_t inputdata, uint8_t color){
  171.     uint8_t data = 0;
  172.     SetDirection(INPUT);
  173.     SetControls(1,1);
  174.     Enable();   //dummy read
  175.     Delay();
  176.     gpio_set_pin(LCD_CONTROL_E);
  177.     //LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_E);
  178.     Delay();
  179.     if (GrLcdState.color == GLCD_COLOR_BLACK)
  180.       data = GetData();
  181.     else
  182.       data = ~GetData();
  183.     Disable();
  184.     Delay();
  185.     SetControls(1,0);
  186.     SetDirection(OUTPUT);
  187.     glcdSetXY(GrLcdState.lcdXAddr, GrLcdState.lcdYAddr);
  188.     SetControls(1,0);
  189.     if (color == GLCD_COLOR_CLEAR)
  190.       data = data&(~inputdata);
  191.     else
  192.       data = data|inputdata;
  193.     if (GrLcdState.color == GLCD_COLOR_BLACK)
  194.       SetData(data);
  195.     else
  196.       SetData(~data);
  197.     Enable();
  198.     GrLcdState.lcdXAddr++;
  199.  
  200.     if (GrLcdState.lcdXAddr > 63){
  201.         glcdSetXY(GrLcdState.lcdXAddr,GrLcdState.lcdYAddr);
  202.     }
  203.     if (GrLcdState.lcdXAddr > 128){
  204.         glcdSetXY(0,GrLcdState.lcdYAddr+8);
  205.     }
  206. }
  207.  
  208. uint8_t glcdReadData(void){
  209.     uint8_t data = 0;
  210.     SetDirection(INPUT);
  211.     SetControls(1,1);
  212.     Enable();   //dummy read
  213.     Delay();
  214.     gpio_set_pin(LCD_CONTROL_E);
  215.     //LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_E);
  216.     Delay();
  217.     if (GrLcdState.color == GLCD_COLOR_BLACK)
  218.       data = GetData();
  219.     else
  220.       data = ~GetData();
  221.     Disable();
  222.     Delay();
  223.     SetControls(1,0);
  224.     SetDirection(OUTPUT);
  225.     glcdSetXY(GrLcdState.lcdXAddr, GrLcdState.lcdYAddr);
  226.     return data;
  227. }
  228.  
  229. void glcdPowerOn(){
  230.     gpio_set_out(LCD_CONTROL_RS); //LCD_CONTROL_DDR |= (1<<LCD_CONTROL_PIN_RS);
  231.     gpio_set_out(LCD_CONTROL_RW); //LCD_CONTROL_DDR |= (1<<LCD_CONTROL_PIN_RW);
  232.     gpio_set_out(LCD_CONTROL_E); //LCD_CONTROL_DDR |= (1<<LCD_CONTROL_PIN_E);
  233.     gpio_set_out(LCD_CONTROL_CS1); //LCD_CONTROL_DDR_CS |= (1<<LCD_CONTROL_PIN_CS1);
  234.     gpio_set_out(LCD_CONTROL_CS2); //LCD_CONTROL_DDR_CS |= (1<<LCD_CONTROL_PIN_CS2);
  235.  
  236.     SetDirection(OUTPUT);
  237.     GrLcdState.color = GLCD_COLOR_WHITE;
  238.     gpio_set_pin(LCD_CONTROL_CS1);
  239.     gpio_set_pin(LCD_CONTROL_CS2);
  240. //LCD_CONTROL_PORT_CS |= (1<<LCD_CONTROL_PIN_CS2)|(1<<LCD_CONTROL_PIN_CS1);
  241.     Disable();
  242.     Delay();
  243.     //set display on
  244.     SetControls(0,0);
  245.     SetData(0x3F);
  246.     Enable();
  247.  
  248.     //set startaddress of the first row (set to row 0)
  249.     SetControls(0,0);
  250.     SetData(0xc0);
  251.     Enable();
  252.  
  253.     glcdClear();
  254. }
  255.  
  256. void glcdClear(){
  257.     gpio_set_pin(LCD_CONTROL_CS1);
  258.     gpio_set_pin(LCD_CONTROL_CS2);
  259. //LCD_CONTROL_PORT_CS |= (1<<LCD_CONTROL_PIN_CS2)|(1<<LCD_CONTROL_PIN_CS1);
  260.     Enable();
  261.     Delay();
  262.     Disable();
  263.  
  264.     uint8_t i;
  265.     uint8_t j;
  266.  
  267.     for(j = 0; j < 8; j++){
  268.         SetControls(0,0);
  269.         SetData(0xB8 + j);
  270.         Enable();
  271.  
  272.         SetControls(0,0);
  273.         SetData(0x40);
  274.         Enable();
  275.         for (i = 0; i < 64; i++){
  276.             SetControls(1,0);
  277.             if (GrLcdState.color == GLCD_COLOR_BLACK)
  278.               SetData(0x00);
  279.             else
  280.               SetData(0xff);
  281.             Enable();
  282.         }
  283.     }
  284.  
  285. }
  286.  
  287. void glcdSetXY(uint8_t x, uint8_t y){
  288.     GrLcdState.lcdXAddr = x;
  289.     GrLcdState.lcdYAddr = y;
  290.     GrLcdState.lcdYpage = y/8;
  291.  
  292.     //Vi b�rjar med X. Steg 1: V�lj r�tt chip:
  293.     if (x > 63){
  294.         gpio_set_pin(LCD_CONTROL_CS2);
  295.         gpio_clr_pin(LCD_CONTROL_CS1);
  296.         //LCD_CONTROL_PORT_CS |= (1<<LCD_CONTROL_PIN_CS2);
  297.         //LCD_CONTROL_PORT_CS &= ~(1<<LCD_CONTROL_PIN_CS1);
  298.     } else {
  299.         gpio_set_pin(LCD_CONTROL_CS1);
  300.         gpio_clr_pin(LCD_CONTROL_CS2);
  301.         //LCD_CONTROL_PORT_CS |= (1<<LCD_CONTROL_PIN_CS1);
  302.         //LCD_CONTROL_PORT_CS &= ~(1<<LCD_CONTROL_PIN_CS2);
  303.     }
  304.  
  305.     //Steg 2: S�tt r�tt x-adress p� det aktiva chippet
  306.     SetControls(0,0);
  307.     SetData(0x40 + x%64);
  308.     Enable();
  309.  
  310.     //Steg 3: S�tt r�tt y-adress p� det aktiva chippet
  311.     SetData(0xB8 + GrLcdState.lcdYpage);
  312.     Enable();
  313. }
  314. uint8_t glcdGetX(void){
  315.     return GrLcdState.lcdXAddr;
  316. }
  317. uint8_t glcdGetY(void){
  318.     return GrLcdState.lcdYAddr;
  319. }
  320.  
  321.  
  322. void glcdWriteChar(char c, uint8_t color)
  323. {
  324.     uint8_t i = 0;
  325.     if (GrLcdState.lcdXAddr > (128-5))
  326.     {
  327.         glcdSetXY(0,GrLcdState.lcdYAddr + 8);
  328.     }
  329.  
  330.     for(i=0; i<5; i++)
  331.     {
  332.         glcdWriteData(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i]), color); //Borde snyggas till med pekare
  333.     }
  334.     glcdWriteData(0x00, color); //space between this and the next char
  335. }
  336.  
  337. void glcdPutStr(char *data, uint8_t color){
  338.     while (*data){
  339.         glcdWriteChar(*data, color);
  340.         data++;
  341.     }
  342. }
  343. void glcdWriteCharTransparent(char c, uint8_t color)
  344. {
  345.     uint8_t i = 0;
  346.     if (GrLcdState.lcdXAddr > (128-5))
  347.     {
  348.         glcdSetXY(0,GrLcdState.lcdYAddr + 8);
  349.     }
  350.  
  351.     for(i=0; i<5; i++)
  352.     {
  353.         glcdWriteDataTransparent(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i]), color); //Borde snyggas till med pekare
  354.     }
  355.     glcdWriteDataTransparent(0x00, color); //space between this and the next char
  356. }
  357.  
  358. void glcdPutStrTransparent(char *data, uint8_t color){
  359.     while (*data){
  360.         glcdWriteCharTransparent(*data, color);
  361.         data++;
  362.     }
  363. }
  364.  
  365. void glcdDrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color) {
  366.     uint8_t length, i, y, yAlt, xTmp, yTmp;
  367.     int16_t m;
  368.    
  369.     //
  370.     // vertical line
  371.     //
  372.     if(x1 == x2) {
  373.         // x1|y1 must be the upper point
  374.         if(y1 > y2) {
  375.             yTmp = y1;
  376.             y1 = y2;
  377.             y2 = yTmp;
  378.         }
  379.         glcdDrawVertLine(x1, y1, y2-y1, color);
  380.    
  381.     //
  382.     // horizontal line
  383.     //
  384.     } else if(y1 == y2) {  
  385.         // x1|y1 must be the left point
  386.         if(x1 > x2) {
  387.             xTmp = x1;
  388.             x1 = x2;
  389.             x2 = xTmp;
  390.         }
  391.         glcdDrawHoriLine(x1, y1, x2-x1, color);
  392.    
  393.     //
  394.     // schiefe line :)
  395.     //
  396.     } else {
  397.         // angle >= 45�
  398.         if((y2-y1) >= (x2-x1) || (y1-y2) >= (x2-x1)) {
  399.             // x1 must be smaller than x2
  400.             if(x1 > x2) {
  401.                 xTmp = x1;
  402.                 yTmp = y1;
  403.                 x1 = x2;
  404.                 y1 = y2;
  405.                 x2 = xTmp;
  406.                 y2 = yTmp;
  407.             }
  408.        
  409.             length = x2-x1;     // not really the length :)
  410.             m = ((y2-y1)*200)/length;
  411.             yAlt = y1;
  412.            
  413.             for(i=0; i<=length; i++) {
  414.                 y = ((m*i)/200)+y1;
  415.                
  416.                 if((m*i)%200 >= 100)
  417.                     y++;
  418.                 else if((m*i)%200 <= -100)
  419.                     y--;
  420.                
  421.                 glcdDrawLine(x1+i, yAlt, x1+i, y, color);
  422.                
  423.                 if(length <= (y2-y1) && y1 < y2)
  424.                     yAlt = y+1;
  425.                 else if(length <= (y1-y2) && y1 > y2)
  426.                     yAlt = y-1;
  427.                 else
  428.                     yAlt = y;
  429.             }
  430.        
  431.         // angle < 45�
  432.         } else {
  433.             // y1 must be smaller than y2
  434.             if(y1 > y2) {
  435.                 xTmp = x1;
  436.                 yTmp = y1;
  437.                 x1 = x2;
  438.                 y1 = y2;
  439.                 x2 = xTmp;
  440.                 y2 = yTmp;
  441.             }
  442.            
  443.             length = y2-y1;
  444.             m = ((x2-x1)*200)/length;
  445.             yAlt = x1;
  446.            
  447.             for(i=0; i<=length; i++) {
  448.                 y = ((m*i)/200)+x1;
  449.                
  450.                 if((m*i)%200 >= 100)
  451.                     y++;
  452.                 else if((m*i)%200 <= -100)
  453.                     y--;
  454.                
  455.                 glcdDrawLine(yAlt, y1+i, y, y1+i, color);
  456.                 if(length <= (x2-x1) && x1 < x2)
  457.                     yAlt = y+1;
  458.                 else if(length <= (x1-x2) && x1 > x2)
  459.                     yAlt = y-1;
  460.                 else
  461.                     yAlt = y;
  462.             }
  463.         }
  464.     }
  465. }
  466.  
  467. void glcdDrawRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color) {
  468.     glcdDrawHoriLine(x, y, width, color);               // top
  469.     glcdDrawHoriLine(x, y+height, width, color);        // bottom
  470.     glcdDrawVertLine(x, y, height, color);          // left
  471.     glcdDrawVertLine(x+width, y, height, color);        // right
  472. }
  473.  
  474.  
  475. void glcdFillRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color) {
  476.     uint8_t mask, pageOffset, h, i; //, data;
  477.     height++;
  478.    
  479.     pageOffset = y%8;
  480.     y -= pageOffset;
  481.     mask = 0xFF;
  482.     if(height < 8-pageOffset) {
  483.         mask >>= (8-height);
  484.         h = height;
  485.     } else {
  486.         h = 8-pageOffset;
  487.     }
  488.     mask <<= pageOffset;
  489.    
  490.     glcdSetXY(x, y);
  491.     for(i=0; i<=width; i++) {
  492.         glcdWriteDataTransparent(mask, color);
  493.     }
  494.    
  495.     while(h+8 <= height) {
  496.         h += 8;
  497.         y += 8;
  498.         glcdSetXY(x, y);
  499.        
  500.         for(i=0; i<=width; i++) {
  501.             glcdWriteData(0xff, color);
  502.         }
  503.     }
  504.    
  505.     if(h < height) {
  506.         mask = ~(0xFF << (height-h));
  507.         glcdSetXY(x, y+8);
  508.        
  509.         for(i=0; i<=width; i++) {
  510.             glcdWriteDataTransparent(mask, color);
  511.         }
  512.     }
  513. }
  514.  
  515. void glcdInvertRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
  516.     uint8_t mask, pageOffset, h, i, data, tmpData;
  517.     height++;
  518.    
  519.     pageOffset = y%8;
  520.     y -= pageOffset;
  521.     mask = 0xFF;
  522.     if(height < 8-pageOffset) {
  523.         mask >>= (8-height);
  524.         h = height;
  525.     } else {
  526.         h = 8-pageOffset;
  527.     }
  528.     mask <<= pageOffset;
  529.    
  530.     glcdSetXY(x, y);
  531.     for(i=0; i<=width; i++) {
  532.         data = glcdReadData(); //glcdReadData();
  533.         tmpData = ~data;
  534.         data = (tmpData & mask) | (data & ~mask);
  535.         glcdWriteData(data, GLCD_COLOR_SET);
  536.     }
  537.    
  538.     while(h+8 <= height) {
  539.         h += 8;
  540.         y += 8;
  541.         glcdSetXY(x, y);
  542.        
  543.         for(i=0; i<=width; i++) {
  544.             data = glcdReadData();
  545.             glcdWriteData(~data, GLCD_COLOR_SET);
  546.         }
  547.     }
  548.    
  549.     if(h < height) {
  550.         mask = ~(0xFF << (height-h));
  551.         glcdSetXY(x, y+8);
  552.        
  553.         for(i=0; i<=width; i++) {
  554.             data = glcdReadData(); //glcdReadData();
  555.             tmpData = ~data;
  556.             data = (tmpData & mask) | (data & ~mask);
  557.             glcdWriteData(data, GLCD_COLOR_SET);
  558.         }
  559.     }
  560. }
  561.  
  562. void glcdInvert(void) {
  563.     if(GrLcdState.color == GLCD_COLOR_BLACK)
  564.         GrLcdState.color = GLCD_COLOR_WHITE;
  565.     else
  566.         GrLcdState.color = GLCD_COLOR_BLACK;
  567.     glcdInvertRect(0,0,127,63);
  568. }
  569. void glcdSetDot(uint8_t x, uint8_t y, uint8_t color) {
  570.     glcdSetXY(x, y-y%8);                    // read data from display memory
  571.     glcdWriteDataTransparent(0x01 << (y%8), GLCD_COLOR_SET);
  572. }
  573.  
  574. void glcdDrawRoundRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t radius, uint8_t color) {
  575.     int16_t tSwitch, x1 = 0, y1 = radius;
  576.     tSwitch = 3 - 2 * radius;
  577.    
  578.     while (x1 <= y1) {
  579.         glcdSetDot(x+radius - x1, y+radius - y1, color);
  580.         glcdSetDot(x+radius - y1, y+radius - x1, color);
  581.  
  582.         glcdSetDot(x+width-radius + x1, y+radius - y1, color);
  583.         glcdSetDot(x+width-radius + y1, y+radius - x1, color);
  584.        
  585.         glcdSetDot(x+width-radius + x1, y+height-radius + y1, color);
  586.         glcdSetDot(x+width-radius + y1, y+height-radius + x1, color);
  587.  
  588.         glcdSetDot(x+radius - x1, y+height-radius + y1, color);
  589.         glcdSetDot(x+radius - y1, y+height-radius + x1, color);
  590.  
  591.         if (tSwitch < 0) {
  592.             tSwitch += (4 * x1 + 6);
  593.         } else {
  594.             tSwitch += (4 * (x1 - y1) + 10);
  595.             y1--;
  596.         }
  597.         x1++;
  598.     }
  599.        
  600.     glcdDrawHoriLine(x+radius, y, width-(2*radius), color);         // top
  601.     glcdDrawHoriLine(x+radius, y+height, width-(2*radius), color);  // bottom
  602.     glcdDrawVertLine(x, y+radius, height-(2*radius), color);            // left
  603.     glcdDrawVertLine(x+width, y+radius, height-(2*radius), color);  // right
  604. }
  605.