Subversion Repositories HomeAutomation

Rev

Rev 1004 | Rev 1019 | 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) {LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_RS);} else { LCD_CONTROL_PORT &= ~(1<<LCD_CONTROL_PIN_RS);};
  39.     if(RW) {LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_RW);} else { LCD_CONTROL_PORT &= ~(1<<LCD_CONTROL_PIN_RW);};
  40. }
  41.  
  42. void SetData(uint8_t Data){
  43.     if(Data&0x01) {LCD_DATA_PORT_DB0 |= (1<<LCD_DATA_PIN_DB0);} else { LCD_DATA_PORT_DB0 &= ~(1<<LCD_DATA_PIN_DB0);};
  44.     if(Data&0x02) {LCD_DATA_PORT_DB1 |= (1<<LCD_DATA_PIN_DB1);} else { LCD_DATA_PORT_DB1 &= ~(1<<LCD_DATA_PIN_DB1);};
  45.     if(Data&0x04) {LCD_DATA_PORT_DB2 |= (1<<LCD_DATA_PIN_DB2);} else { LCD_DATA_PORT_DB2 &= ~(1<<LCD_DATA_PIN_DB2);};
  46.     if(Data&0x08) {LCD_DATA_PORT_DB3 |= (1<<LCD_DATA_PIN_DB3);} else { LCD_DATA_PORT_DB3 &= ~(1<<LCD_DATA_PIN_DB3);};
  47.     if(Data&0x10) {LCD_DATA_PORT_DB4 |= (1<<LCD_DATA_PIN_DB4);} else { LCD_DATA_PORT_DB4 &= ~(1<<LCD_DATA_PIN_DB4);};
  48.     if(Data&0x20) {LCD_DATA_PORT_DB5 |= (1<<LCD_DATA_PIN_DB5);} else { LCD_DATA_PORT_DB5 &= ~(1<<LCD_DATA_PIN_DB5);};
  49.     if(Data&0x40) {LCD_DATA_PORT_DB6 |= (1<<LCD_DATA_PIN_DB6);} else { LCD_DATA_PORT_DB6 &= ~(1<<LCD_DATA_PIN_DB6);};
  50.     if(Data&0x80) {LCD_DATA_PORT_DB7 |= (1<<LCD_DATA_PIN_DB7);} else { LCD_DATA_PORT_DB7 &= ~(1<<LCD_DATA_PIN_DB7);};
  51. }
  52. uint8_t GetData(void){
  53.     uint8_t input = 0;
  54.     if (LCD_DATA_IN_DB0 & (1<<LCD_DATA_PIN_DB0)) {input += 1;}
  55.     if (LCD_DATA_IN_DB1 & (1<<LCD_DATA_PIN_DB1)) {input += 2;}
  56.     if (LCD_DATA_IN_DB2 & (1<<LCD_DATA_PIN_DB2)) {input += 4;}
  57.     if (LCD_DATA_IN_DB3 & (1<<LCD_DATA_PIN_DB3)) {input += 8;}
  58.     if (LCD_DATA_IN_DB4 & (1<<LCD_DATA_PIN_DB4)) {input += 16;}
  59.     if (LCD_DATA_IN_DB5 & (1<<LCD_DATA_PIN_DB5)) {input += 32;}
  60.     if (LCD_DATA_IN_DB6 & (1<<LCD_DATA_PIN_DB6)) {input += 64;}
  61.     if (LCD_DATA_IN_DB7 & (1<<LCD_DATA_PIN_DB7)) {input += 128;}
  62.     return input;
  63. }
  64.  
  65. void Disable(){
  66.     LCD_CONTROL_PORT &= ~(1<<LCD_CONTROL_PIN_E);
  67. }
  68.  
  69. void Delay(){
  70.     delay_us(1);
  71. }
  72.  
  73. void Enable(){
  74.     Delay();
  75.     LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_E);
  76.     Delay();
  77.     Disable();
  78.     Delay();
  79. }
  80.  
  81. void SetDirection(uint8_t dir){
  82.   if (dir == OUTPUT){
  83.     LCD_DATA_DDR_DB0 |= (1<<LCD_DATA_PIN_DB0);
  84.     LCD_DATA_DDR_DB1 |= (1<<LCD_DATA_PIN_DB1);
  85.     LCD_DATA_DDR_DB2 |= (1<<LCD_DATA_PIN_DB2);
  86.     LCD_DATA_DDR_DB3 |= (1<<LCD_DATA_PIN_DB3);
  87.     LCD_DATA_DDR_DB4 |= (1<<LCD_DATA_PIN_DB4);
  88.     LCD_DATA_DDR_DB5 |= (1<<LCD_DATA_PIN_DB5);
  89.     LCD_DATA_DDR_DB6 |= (1<<LCD_DATA_PIN_DB6);
  90.     LCD_DATA_DDR_DB7 |= (1<<LCD_DATA_PIN_DB7);
  91.   }else if (dir == INPUT){
  92.     LCD_DATA_DDR_DB0 &= ~(1<<LCD_DATA_PIN_DB0);
  93.     LCD_DATA_DDR_DB1 &= ~(1<<LCD_DATA_PIN_DB1);
  94.     LCD_DATA_DDR_DB2 &= ~(1<<LCD_DATA_PIN_DB2);
  95.     LCD_DATA_DDR_DB3 &= ~(1<<LCD_DATA_PIN_DB3);
  96.     LCD_DATA_DDR_DB4 &= ~(1<<LCD_DATA_PIN_DB4);
  97.     LCD_DATA_DDR_DB5 &= ~(1<<LCD_DATA_PIN_DB5);
  98.     LCD_DATA_DDR_DB6 &= ~(1<<LCD_DATA_PIN_DB6);
  99.     LCD_DATA_DDR_DB7 &= ~(1<<LCD_DATA_PIN_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.     LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_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.     LCD_CONTROL_PORT |= (1<<LCD_CONTROL_PIN_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.     LCD_CONTROL_DDR |= (1<<LCD_CONTROL_PIN_RS);
  185.     LCD_CONTROL_DDR |= (1<<LCD_CONTROL_PIN_RW);
  186.     LCD_CONTROL_DDR |= (1<<LCD_CONTROL_PIN_E);
  187.     LCD_CONTROL_DDR_CS |= (1<<LCD_CONTROL_PIN_CS1);
  188.     LCD_CONTROL_DDR_CS |= (1<<LCD_CONTROL_PIN_CS2);
  189.  
  190.     SetDirection(OUTPUT);
  191.     GrLcdState.color = GLCD_COLOR_BLACK;
  192.     LCD_CONTROL_PORT_CS |= (1<<LCD_CONTROL_PIN_CS2)|(1<<LCD_CONTROL_PIN_CS1);
  193.     Disable();
  194.     Delay();
  195.     //set display on
  196.     SetControls(0,0);
  197.     SetData(0x3F);
  198.     Enable();
  199.  
  200.     //set startaddress of the first row (set to row 0)
  201.     SetControls(0,0);
  202.     SetData(0xc0);
  203.     Enable();
  204.  
  205.     glcdClear();
  206. }
  207.  
  208. void glcdClear(){
  209.     LCD_CONTROL_PORT_CS |= (1<<LCD_CONTROL_PIN_CS2)|(1<<LCD_CONTROL_PIN_CS1);
  210.     Enable();
  211.     Delay();
  212.     Disable();
  213.  
  214.     uint8_t i;
  215.     uint8_t j;
  216.  
  217.     for(j = 0; j < 8; j++){
  218.         SetControls(0,0);
  219.         SetData(0xB8 + j);
  220.         Enable();
  221.  
  222.         SetControls(0,0);
  223.         SetData(0x40);
  224.         Enable();
  225.         for (i = 0; i < 64; i++){
  226.             SetControls(1,0);
  227.             if (GrLcdState.color == GLCD_COLOR_BLACK)
  228.               SetData(0x00);
  229.             else
  230.               SetData(0xff);
  231.             Enable();
  232.         }
  233.     }
  234.  
  235. }
  236.  
  237. void glcdSetXY(uint8_t x, uint8_t y){
  238.     GrLcdState.lcdXAddr = x;
  239.     GrLcdState.lcdYAddr = y;
  240.     GrLcdState.lcdYpage = y/8;
  241.  
  242.     //Vi b�rjar med X. Steg 1: V�lj r�tt chip:
  243.     if (x > 63){
  244.         LCD_CONTROL_PORT_CS |= (1<<LCD_CONTROL_PIN_CS2);
  245.         LCD_CONTROL_PORT_CS &= ~(1<<LCD_CONTROL_PIN_CS1);
  246.     } else {
  247.         LCD_CONTROL_PORT_CS |= (1<<LCD_CONTROL_PIN_CS1);
  248.         LCD_CONTROL_PORT_CS &= ~(1<<LCD_CONTROL_PIN_CS2);
  249.     }
  250.  
  251.     //Steg 2: S�tt r�tt x-adress p� det aktiva chippet
  252.     SetControls(0,0);
  253.     SetData(0x40 + x%64);
  254.     Enable();
  255.  
  256.     //Steg 3: S�tt r�tt y-adress p� det aktiva chippet
  257.     SetData(0xB8 + GrLcdState.lcdYpage);
  258.     Enable();
  259. }
  260.  
  261. void glcdWriteChar(char c, uint8_t color)
  262. {
  263.     uint8_t i = 0;
  264.     if (GrLcdState.lcdXAddr > (128-5))
  265.     {
  266.         glcdSetXY(0,GrLcdState.lcdYAddr + 8);
  267.     }
  268.  
  269.     for(i=0; i<5; i++)
  270.     {
  271.         glcdWriteData(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i]), color); //Borde snyggas till med pekare
  272.     }
  273.     glcdWriteData(0x00, color); //space between this and the next char
  274. }
  275.  
  276. void glcdPutStr(char *data, uint8_t color){
  277.     while (*data){
  278.         glcdWriteChar(*data, color);
  279.         data++;
  280.     }
  281. }
  282. void glcdWriteCharTransparent(char c, uint8_t color)
  283. {
  284.     uint8_t i = 0;
  285.     if (GrLcdState.lcdXAddr > (128-5))
  286.     {
  287.         glcdSetXY(0,GrLcdState.lcdYAddr + 8);
  288.     }
  289.  
  290.     for(i=0; i<5; i++)
  291.     {
  292.         glcdWriteDataTransparent(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i]), color); //Borde snyggas till med pekare
  293.     }
  294.     glcdWriteDataTransparent(0x00, color); //space between this and the next char
  295. }
  296.  
  297. void glcdPutStrTransparent(char *data, uint8_t color){
  298.     while (*data){
  299.         glcdWriteCharTransparent(*data, color);
  300.         data++;
  301.     }
  302. }
  303.  
  304. void glcdDrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color) {
  305.     uint8_t length, i, y, yAlt, xTmp, yTmp;
  306.     int16_t m;
  307.    
  308.     //
  309.     // vertical line
  310.     //
  311.     if(x1 == x2) {
  312.         // x1|y1 must be the upper point
  313.         if(y1 > y2) {
  314.             yTmp = y1;
  315.             y1 = y2;
  316.             y2 = yTmp;
  317.         }
  318.         glcdDrawVertLine(x1, y1, y2-y1, color);
  319.    
  320.     //
  321.     // horizontal line
  322.     //
  323.     } else if(y1 == y2) {  
  324.         // x1|y1 must be the left point
  325.         if(x1 > x2) {
  326.             xTmp = x1;
  327.             x1 = x2;
  328.             x2 = xTmp;
  329.         }
  330.         glcdDrawHoriLine(x1, y1, x2-x1, color);
  331.    
  332.     //
  333.     // schiefe line :)
  334.     //
  335.     } else {
  336.         // angle >= 45�
  337.         if((y2-y1) >= (x2-x1) || (y1-y2) >= (x2-x1)) {
  338.             // x1 must be smaller than x2
  339.             if(x1 > x2) {
  340.                 xTmp = x1;
  341.                 yTmp = y1;
  342.                 x1 = x2;
  343.                 y1 = y2;
  344.                 x2 = xTmp;
  345.                 y2 = yTmp;
  346.             }
  347.        
  348.             length = x2-x1;     // not really the length :)
  349.             m = ((y2-y1)*200)/length;
  350.             yAlt = y1;
  351.            
  352.             for(i=0; i<=length; i++) {
  353.                 y = ((m*i)/200)+y1;
  354.                
  355.                 if((m*i)%200 >= 100)
  356.                     y++;
  357.                 else if((m*i)%200 <= -100)
  358.                     y--;
  359.                
  360.                 glcdDrawLine(x1+i, yAlt, x1+i, y, color);
  361.                
  362.                 if(length <= (y2-y1) && y1 < y2)
  363.                     yAlt = y+1;
  364.                 else if(length <= (y1-y2) && y1 > y2)
  365.                     yAlt = y-1;
  366.                 else
  367.                     yAlt = y;
  368.             }
  369.        
  370.         // angle < 45�
  371.         } else {
  372.             // y1 must be smaller than y2
  373.             if(y1 > y2) {
  374.                 xTmp = x1;
  375.                 yTmp = y1;
  376.                 x1 = x2;
  377.                 y1 = y2;
  378.                 x2 = xTmp;
  379.                 y2 = yTmp;
  380.             }
  381.            
  382.             length = y2-y1;
  383.             m = ((x2-x1)*200)/length;
  384.             yAlt = x1;
  385.            
  386.             for(i=0; i<=length; i++) {
  387.                 y = ((m*i)/200)+x1;
  388.                
  389.                 if((m*i)%200 >= 100)
  390.                     y++;
  391.                 else if((m*i)%200 <= -100)
  392.                     y--;
  393.                
  394.                 glcdDrawLine(yAlt, y1+i, y, y1+i, color);
  395.                 if(length <= (x2-x1) && x1 < x2)
  396.                     yAlt = y+1;
  397.                 else if(length <= (x1-x2) && x1 > x2)
  398.                     yAlt = y-1;
  399.                 else
  400.                     yAlt = y;
  401.             }
  402.         }
  403.     }
  404. }
  405.  
  406. void glcdDrawRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color) {
  407.     glcdDrawHoriLine(x, y, width, color);               // top
  408.     glcdDrawHoriLine(x, y+height, width, color);        // bottom
  409.     glcdDrawVertLine(x, y, height, color);          // left
  410.     glcdDrawVertLine(x+width, y, height, color);        // right
  411. }
  412.  
  413.  
  414. void glcdFillRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color) {
  415.     uint8_t mask, pageOffset, h, i; //, data;
  416.     height++;
  417.    
  418.     pageOffset = y%8;
  419.     y -= pageOffset;
  420.     mask = 0xFF;
  421.     if(height < 8-pageOffset) {
  422.         mask >>= (8-height);
  423.         h = height;
  424.     } else {
  425.         h = 8-pageOffset;
  426.     }
  427.     mask <<= pageOffset;
  428.    
  429.     glcdSetXY(x, y);
  430.     for(i=0; i<=width; i++) {
  431.         glcdWriteDataTransparent(mask, color);
  432.     }
  433.    
  434.     while(h+8 <= height) {
  435.         h += 8;
  436.         y += 8;
  437.         glcdSetXY(x, y);
  438.        
  439.         for(i=0; i<=width; i++) {
  440.             glcdWriteData(0xff, color);
  441.         }
  442.     }
  443.    
  444.     if(h < height) {
  445.         mask = ~(0xFF << (height-h));
  446.         glcdSetXY(x, y+8);
  447.        
  448.         for(i=0; i<=width; i++) {
  449.             glcdWriteDataTransparent(mask, color);
  450.         }
  451.     }
  452. }
  453.  
  454. void glcdInvertRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
  455.     uint8_t mask, pageOffset, h, i, data, tmpData;
  456.     height++;
  457.    
  458.     pageOffset = y%8;
  459.     y -= pageOffset;
  460.     mask = 0xFF;
  461.     if(height < 8-pageOffset) {
  462.         mask >>= (8-height);
  463.         h = height;
  464.     } else {
  465.         h = 8-pageOffset;
  466.     }
  467.     mask <<= pageOffset;
  468.    
  469.     glcdSetXY(x, y);
  470.     for(i=0; i<=width; i++) {
  471.         data = glcdReadData(); //glcdReadData();
  472.         tmpData = ~data;
  473.         data = (tmpData & mask) | (data & ~mask);
  474.         glcdWriteData(data, GLCD_COLOR_SET);
  475.     }
  476.    
  477.     while(h+8 <= height) {
  478.         h += 8;
  479.         y += 8;
  480.         glcdSetXY(x, y);
  481.        
  482.         for(i=0; i<=width; i++) {
  483.             data = glcdReadData();
  484.             glcdWriteData(~data, GLCD_COLOR_SET);
  485.         }
  486.     }
  487.    
  488.     if(h < height) {
  489.         mask = ~(0xFF << (height-h));
  490.         glcdSetXY(x, y+8);
  491.        
  492.         for(i=0; i<=width; i++) {
  493.             data = glcdReadData(); //glcdReadData();
  494.             tmpData = ~data;
  495.             data = (tmpData & mask) | (data & ~mask);
  496.             glcdWriteData(data, GLCD_COLOR_SET);
  497.         }
  498.     }
  499. }
  500.  
  501. void glcdInvert(void) {
  502.     if(GrLcdState.color == GLCD_COLOR_BLACK)
  503.         GrLcdState.color = GLCD_COLOR_WHITE;
  504.     else
  505.         GrLcdState.color = GLCD_COLOR_BLACK;
  506.     glcdInvertRect(0,0,127,63);
  507. }
  508. void glcdSetDot(uint8_t x, uint8_t y, uint8_t color) {
  509.     glcdSetXY(x, y-y%8);                    // read data from display memory
  510.     glcdWriteDataTransparent(0x01 << (y%8), GLCD_COLOR_SET);
  511. }
  512.  
  513. void glcdDrawRoundRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t radius, uint8_t color) {
  514.     int16_t tSwitch, x1 = 0, y1 = radius;
  515.     tSwitch = 3 - 2 * radius;
  516.    
  517.     while (x1 <= y1) {
  518.         glcdSetDot(x+radius - x1, y+radius - y1, color);
  519.         glcdSetDot(x+radius - y1, y+radius - x1, color);
  520.  
  521.         glcdSetDot(x+width-radius + x1, y+radius - y1, color);
  522.         glcdSetDot(x+width-radius + y1, y+radius - x1, color);
  523.        
  524.         glcdSetDot(x+width-radius + x1, y+height-radius + y1, color);
  525.         glcdSetDot(x+width-radius + y1, y+height-radius + x1, color);
  526.  
  527.         glcdSetDot(x+radius - x1, y+height-radius + y1, color);
  528.         glcdSetDot(x+radius - y1, y+height-radius + x1, color);
  529.  
  530.         if (tSwitch < 0) {
  531.             tSwitch += (4 * x1 + 6);
  532.         } else {
  533.             tSwitch += (4 * (x1 - y1) + 10);
  534.             y1--;
  535.         }
  536.         x1++;
  537.     }
  538.        
  539.     glcdDrawHoriLine(x+radius, y, width-(2*radius), color);         // top
  540.     glcdDrawHoriLine(x+radius, y+height, width-(2*radius), color);  // bottom
  541.     glcdDrawVertLine(x, y+radius, height-(2*radius), color);            // left
  542.     glcdDrawVertLine(x+width, y+radius, height-(2*radius), color);  // right
  543. }
  544.