Subversion Repositories HomeAutomation

Rev

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