Subversion Repositories HomeAutomation

Rev

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