Subversion Repositories HomeAutomation

Rev

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