Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "act_ks0108.h"
  3.  
  4. static unsigned char Splash_left[] PROGMEM = {
  5. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//Line 1
  6. 0xff,0xff,0xff,0x3,0x7f,0x7f,0xbf,0xbf,0xdf,0x7,0xff,0xff,0xff,0x3f,0xbf,0xdf,0xdf,0xdf,0x3f,0xff,0xff,0xff,0x3f,0x3f,0xdf,0x9f,0x7f,0x7f,0xbf,0x9f,0x3f,0xff,0xff,0x7f,0xbf,0xdf,0xdf,0x9f,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xc7,0xf3,0xf,0xff,0xff,0xff,0x1f,0xff,0xff,0xff,0xff,0x3f,0xdf,0xff,0xef,0xef,0xef,0x40,0x5,0xf7,0xff,0xff,0x3f,0xbf,0xdf,0xdf,0xdf,0x3f,0xff,0xff,0xff,0x1f,0x7f,0xdf,0x9f,0x7f,0x7f,0x9f,0xdf,0x3f,0xff,0xff,0xbf,0xbf,0xdf,0xdf,0xdf,0x3f,0xff,0xff,0xef,0xef,0xef,0x40,0x5,0xf7,0xff,0x1d,0xff,0xff,0xff,0xff,0x3f,0xbf,0xdf,0xdf,0xdf,0x3f,0xff,0xff,0xff,0x1f,0xff,0x7f,0x9f,0xdf,0x3f,0xff,0xff,0xff,0xff,0xff,//Line 2
  7. 0xff,0xff,0xff,0xd0,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xe0,0xef,0xdf,0xdf,0xcf,0xe3,0xf8,0xff,0xff,0xff,0xc0,0xfe,0xff,0xff,0xe0,0xfa,0xff,0xff,0xe0,0xff,0xff,0xf8,0xe6,0xee,0xee,0xf6,0xf7,0xfb,0xff,0xff,0xef,0xf3,0xfc,0xfe,0xfe,0xfe,0xff,0xf0,0xff,0xff,0xf4,0xcf,0xdf,0xe7,0xfb,0xf0,0xe7,0xff,0xff,0xff,0xff,0xff,0xe0,0xff,0xff,0xe0,0xef,0xdf,0xdf,0xcf,0xe3,0xf8,0xff,0xff,0xff,0xc0,0xfe,0xff,0xff,0xe0,0xfa,0xff,0xff,0xe0,0xff,0xff,0xf3,0xeb,0xed,0xed,0xf5,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0xff,0xff,0xe0,0xff,0xff,0xff,0xf0,0xcf,0xdf,0xdf,0xcf,0xe3,0xf8,0xff,0xff,0xff,0xf4,0xf9,0xfe,0xff,0xff,0xe0,0xff,0xff,0xff,0xff,0xff,//Line 3
  8. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,//Line 4
  9. 0xff,0xff,0xff,0xff,0xff,0xdf,0xef,0xef,0xef,0x1f,0xff,0xff,0xf,0xff,0xff,0xff,0xff,0x3f,0xcf,0xff,0xff,0x1f,0x9f,0xef,0xcf,0x3f,0x3f,0xdf,0xcf,0x1f,0xff,0xff,0x40,0x2f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x5f,0xef,0xef,0xef,0xff,0xff,0x3f,0x1f,0x6f,0x6f,0xcf,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xcf,0xf3,0xfc,0xff,0xff,0xff,0x47,0xb7,0xf7,0xf7,0xf7,0x77,0x8f,0xff,0xff,0xf,0x7f,0x3f,0xdf,0xdf,0xff,0xff,0x7f,0x9f,0xdf,0xef,0xef,0xef,0x1f,0xff,0xff,0xff,0xff,0xdd,0x3f,0xff,0xff,0xff,0x3f,0x1f,0x6f,0x6f,0xcf,0x9f,0xff,0xff,0xfd,0x3,0x7f,0xbf,0xdf,0xef,0xff,0xff,0xf7,0xf7,0xf7,0xa0,0x2,0xfb,0xff,0xff,0xff,//Line 5
  10. 0xff,0xff,0xff,0xff,0xf9,0xf6,0xf6,0xfa,0xfa,0xf8,0xff,0xff,0xf8,0xe7,0xef,0xf3,0xfd,0xfc,0xf1,0xff,0xff,0xe0,0xff,0xff,0xff,0xf0,0xfd,0xff,0xff,0xf0,0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0xcf,0xc3,0xd3,0xe3,0xff,0xff,0xff,0xf7,0xe7,0xee,0xf6,0xf1,0xff,0xff,0xfc,0xf3,0xf7,0xf7,0xfb,0xfb,0xfd,0xff,0xff,0xff,0xcf,0xf3,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x5b,0xf9,0xfd,0xfe,0xff,0xff,0xff,0xf4,0xf8,0xff,0xff,0xff,0xff,0xff,0xf8,0xe7,0xef,0xef,0xe7,0xf1,0xfc,0xff,0xff,0xcf,0xbf,0xbf,0xc0,0xff,0xff,0xff,0xfc,0xfb,0xf7,0xf7,0xfb,0xfb,0xfd,0xff,0xff,0xf8,0xfd,0xfd,0xfb,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,//Line 6
  11. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//Line 7
  12. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0//Line 7
  13. };
  14.  
  15.  
  16.  
  17.  
  18. #define SOLID   0
  19. #define TRANSPARENT 1
  20. uint8_t color=GLCD_COLOR_BLACK;
  21. uint8_t Transparent=SOLID;
  22.  
  23. #if act_ks0108_USE_EXTERNAL_EEPROM==1
  24.  
  25.     void storeImage(uint8_t id, uint8_t size_x , uint8_t size_y);
  26.  
  27.     void saveImageFromScreen(uint8_t id, uint8_t size_x , uint8_t size_y);
  28.  
  29.     #define MEMORY_I2C_ADDR  0x57   // 64K EEPROM - allowed addresses are 0x50 to 0x57
  30.     #define MEMORY_ADDR_MSB  0      // start at base of memory. Next one is 0x01.
  31.     #define MEMORY_ADDR_LSB  0      // start on a page boundary. Next one is 0x80.
  32.     unsigned char messageBuf[MESSAGEBUF_SIZE];
  33. #endif
  34.  
  35.  
  36. void numtoascii( int16_t num, char **str );
  37. void signedtoascii(int16_t num, uint8_t decimalplace, char *string, uint8_t numberofdecimals);
  38. void unsignedtoascii(uint16_t num, uint8_t decimalplace, char *string, uint8_t numberofdecimals);
  39.  
  40. #if act_ks0108_USE_EXTERNAL_EEPROM==1
  41. //valid id is 1 to 255;
  42. void printImage(uint8_t id, uint8_t x_start, uint8_t y_start) {
  43.     if (id == 0 )
  44.         return;     //id=0 not allowed
  45.     uint16_t address = 0;
  46.     uint16_t buf_index = 0;
  47.     uint8_t index;
  48.     uint8_t size_x = 0;
  49.     uint8_t size_y = 0;
  50.     uint16_t max_picture_size;
  51.     index = (id>>5)&0x07;
  52.     //find starting adress of the requested data
  53.     switch (index) {
  54.         case 0:
  55.             address = (index)*1024;
  56.             max_picture_size = 1024;
  57.             break;
  58.         case 1:
  59.             address = 32768+(index)*512;
  60.             max_picture_size = 512;
  61.             break;
  62.         case 2:
  63.             address = 32768+32*512+(index)*256;
  64.             max_picture_size = 256;
  65.             break;
  66.         case 3:
  67.             address = 32768+32*512+32*256+(index)*128;
  68.             max_picture_size = 128;
  69.             break;
  70.         case 4:
  71.             address = 32768+32*512+32*256+32*128+(index)*64;
  72.             max_picture_size = 64;
  73.             break;
  74.         case 5:
  75.             address = 32768+32*512+32*256+32*128+32*64+(index)*32;
  76.             max_picture_size = 32;
  77.             break;
  78.         case 6:
  79.             address = 32768+32*512+32*256+32*128+32*64+32*32+(index)*16;
  80.             max_picture_size = 16;
  81.             break;
  82.         case 7:
  83.             address = 32768+32*512+32*256+32*128+32*64+32*32+32*16+(index)*16;
  84.             max_picture_size = 16;
  85.             break;
  86.     }
  87.     //Get size of picture (every picture has an 4 byte info-tag)
  88.     messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS); // Read/write bit doesn't matter here
  89.     messageBuf[1] = (uint8_t)(0);       // Starting address in memory
  90.     messageBuf[2] = (uint8_t)(((id&0xe0)>>5) & 0xff);           // Starting address in memory
  91.     TWI_Start_Random_Read( messageBuf, 129, 3 );    // Desired data length plus one (command byte).
  92.     // Could do other actions in here, then get data.
  93.     TWI_Read_Data_From_Buffer( messageBuf, 129 );
  94.     size_x = messageBuf[((id&0x1f)<<2)];
  95.     size_y = messageBuf[((id&0x1f)<<2)+1];
  96.     //more_data = messageBuf[((id&0x1f)<<2)+2];
  97.     //last_data = messageBuf[((id&0x1f)<<2)+3];
  98.  
  99.     // get data from eeprom
  100.     messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS); // Read/write bit doesn't matter here
  101.     messageBuf[1] = (uint8_t)((address >> 8) & 0xff);       // Starting address in memory
  102.     messageBuf[2] = (uint8_t)(address & 0xff);       // Starting address in memory
  103.     TWI_Start_Random_Read( messageBuf, 129, 3 );    // Desired data length plus one (command byte).
  104.     // Could do other actions in here, then get data.
  105.     TWI_Read_Data_From_Buffer( messageBuf, 129 );
  106.     uint8_t jy = 0;
  107.     uint8_t jx = 0;
  108.     buf_index = 0;
  109.     for (jy = 0; jy< size_y; jy+=8){
  110.         glcdSetXY(x_start,y_start+jy);
  111.         for (jx = 0; jx< size_x ; jx++){
  112.             if (buf_index>=128) {   //get new data if buffer empty
  113.                 address +=128;
  114.                 messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS); // Read/write bit doesn't matter here
  115.                 messageBuf[1] = (uint8_t)((address >> 8) & 0xff);       // Starting address in memory
  116.                 messageBuf[2] = (uint8_t)(address & 0xff);       // Starting address in memory
  117.                 TWI_Start_Random_Read( messageBuf, 129, 3 );    // Desired data length plus one (command byte).
  118.                 // Could do other actions in here, then get data.
  119.                 TWI_Read_Data_From_Buffer( messageBuf, 129 );
  120.                 buf_index=0;
  121.             }
  122.             glcdWriteData(messageBuf[buf_index+1], GLCD_COLOR_CLEAR);
  123.             buf_index++;
  124.         }
  125.     }
  126. }
  127. volatile uint8_t state;
  128. volatile uint8_t lastId = 255;
  129. #define IDLE    0
  130. #define RECEIVING_DATA 1
  131. void newImageData(StdCan_Msg_t *rxMsg) {
  132.     //State machine for storing new data
  133.     switch (state) {
  134.         case IDLE:
  135.             if (rxMsg->Header.Command == CAN_MODULE_CMD_KS0108_LCD_NEW_IMAGE)
  136.             {
  137.                 storeImage(rxMsg->Data[0],rxMsg->Data[1],rxMsg->Data[2]);
  138.                 state = RECEIVING_DATA;
  139.                 lastId = 255;
  140.                 //response message
  141.                 rxMsg->Length = 1;
  142.                 rxMsg->Header.Command = CAN_MODULE_CMD_KS0108_LCD_ACK;
  143.                 while (StdCan_Put(rxMsg) != StdCan_Ret_OK);  
  144.             }else {
  145.                 //error message
  146.                 rxMsg->Length = 0;
  147.                 rxMsg->Header.Command = CAN_MODULE_CMD_KS0108_LCD_ERROR;
  148.                 while (StdCan_Put(rxMsg) != StdCan_Ret_OK);  
  149.             }
  150.             break;
  151.         case RECEIVING_DATA:
  152.             if (rxMsg->Header.Command == CAN_MODULE_CMD_KS0108_LCD_IMAGE_DATA)
  153.             {
  154.                 if (rxMsg->Data[0] == (lastId+1)) {
  155.                     storeImage(rxMsg->Data[0],rxMsg->Data[1],rxMsg->Data[2]);
  156.                     state = RECEIVING_DATA;
  157.                     lastId++;
  158.  
  159.                     //FIXME: call function that handles the data
  160.  
  161.                     //response message
  162.                     rxMsg->Length = 1;
  163.                     rxMsg->Header.Command = CAN_MODULE_CMD_KS0108_LCD_ACK;
  164.                     while (StdCan_Put(rxMsg) != StdCan_Ret_OK);  
  165.                 } else {
  166.                     //wrong id
  167.                     rxMsg->Length = 1;
  168.                     rxMsg->Header.Command = CAN_MODULE_CMD_KS0108_LCD_DATA_ID_ERROR;
  169.                     rxMsg->Data[0] = (lastId+1);
  170.                     while (StdCan_Put(rxMsg) != StdCan_Ret_OK);  
  171.                 }
  172.             } else if (rxMsg->Header.Command == CAN_MODULE_CMD_KS0108_LCD_DATA_DONE) {
  173.                 //Call function to flush eeprom cache
  174.                 //FIXME
  175.                 state=IDLE;
  176.             } else {
  177.                 //error message
  178.                 rxMsg->Length = 0;
  179.                 rxMsg->Header.Command = CAN_MODULE_CMD_KS0108_LCD_ERROR;
  180.                 while (StdCan_Put(rxMsg) != StdCan_Ret_OK);  
  181.             }
  182.             break;
  183.     }
  184.  
  185. }
  186.  
  187.  
  188. //valid id is 1 to 255;
  189. void storeImage(uint8_t id, uint8_t size_x , uint8_t size_y) {
  190.     if (id == 0 )
  191.         return;     //id=0 not allowed
  192.     //uint16_t address = 0;
  193.     //uint16_t buf_index = 0;
  194.     uint8_t index;
  195.     //uint16_t max_picture_size;
  196.     index = (id>>5)&0x07;
  197.     //find starting adress of the requested data
  198.     //Get size of picture (every picture has an 4 byte info-tag)
  199.     messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS); // Read/write bit doesn't matter here
  200.     messageBuf[1] = (uint8_t)(0);       // Starting address in memory
  201.     messageBuf[2] = (uint8_t)(((id&0xe0)>>5) & 0xff);           // Starting address in memory
  202.     TWI_Start_Random_Read( messageBuf, 129, 3 );    // Desired data length plus one (command byte).
  203.     // Could do other actions in here, then get data.
  204.     TWI_Read_Data_From_Buffer( messageBuf, 129 );
  205.     messageBuf[((id&0x1f)<<2)+1] = size_x;
  206.     messageBuf[((id&0x1f)<<2)+2] = size_y;
  207.     //more_data = messageBuf[((id&0x1f)<<2)+2];
  208.     //last_data = messageBuf[((id&0x1f)<<2)+3];
  209.  
  210.     //move data in the buffer
  211.     for (index = 128; index > 0; index--) {
  212.         messageBuf[index+2] = messageBuf[index];
  213.     }
  214.     messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  215.     messageBuf[1] = (uint8_t)(0);       // Starting address in memory
  216.     messageBuf[2] = (uint8_t)(((id&0xe0)>>5) & 0xff);           // Starting address in memory
  217.     TWI_Start_Read_Write( messageBuf, 131 );
  218.     // Should wait for completion of EEPROM write cycle. Blinking the LED will do this.
  219.     while ( TWI_Transceiver_Busy() );    // Check for an error.
  220.  
  221.     //Now the info-tag is written, only to add data left
  222.  
  223.     //FIXME........ FIX!!!
  224.  
  225. }
  226.  
  227.  
  228. //valid id is 1 to 255;
  229. void saveImageFromScreen(uint8_t id, uint8_t size_x , uint8_t size_y) {
  230.     if (id == 0 )
  231.         return;     //id=0 not allowed
  232.     uint16_t max_picture_size;
  233.     uint8_t index;
  234.     uint8_t bufferIndex;
  235.     uint16_t address = 0;
  236.     index = (id>>5)&0x07;
  237.     //find starting adress of the requested data
  238.     switch (index) {
  239.         case 0:
  240.             address = (index)*1024;
  241.             max_picture_size = 1024;
  242.             break;
  243.         case 1:
  244.             address = 32768+(index)*512;
  245.             max_picture_size = 512;
  246.             break;
  247.         case 2:
  248.             address = 32768+32*512+(index)*256;
  249.             max_picture_size = 256;
  250.             break;
  251.         case 3:
  252.             address = 32768+32*512+32*256+(index)*128;
  253.             max_picture_size = 128;
  254.             break;
  255.         case 4:
  256.             address = 32768+32*512+32*256+32*128+(index)*64;
  257.             max_picture_size = 64;
  258.             break;
  259.         case 5:
  260.             address = 32768+32*512+32*256+32*128+32*64+(index)*32;
  261.             max_picture_size = 32;
  262.             break;
  263.         case 6:
  264.             address = 32768+32*512+32*256+32*128+32*64+32*32+(index)*16;
  265.             max_picture_size = 16;
  266.             break;
  267.         case 7:
  268.             address = 32768+32*512+32*256+32*128+32*64+32*32+32*16+(index)*16;
  269.             max_picture_size = 16;
  270.             break;
  271.     }
  272.     //Get size of picture (every picture has an 4 byte info-tag)
  273.     messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS); // Read/write bit doesn't matter here
  274.     messageBuf[1] = (uint8_t)(0);       // Starting address in memory
  275.     messageBuf[2] = (uint8_t)(((id&0xe0)>>5) & 0xff);           // Starting address in memory
  276.     TWI_Start_Random_Read( messageBuf, 129, 3 );    // Desired data length plus one (command byte).
  277.     // Could do other actions in here, then get data.
  278.     TWI_Read_Data_From_Buffer( messageBuf, 129 );
  279.     messageBuf[((id&0x1f)<<2)+1] = size_x;
  280.     messageBuf[((id&0x1f)<<2)+2] = size_y;
  281.  
  282.     //move data in the buffer
  283.     for (index = 128; index > 0; index--) {
  284.         messageBuf[index+2] = messageBuf[index];
  285.     }
  286.     messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  287.     messageBuf[1] = (uint8_t)(0);       // Starting address in memory
  288.     messageBuf[2] = (uint8_t)(((id&0xe0)>>5) & 0xff);           // Starting address in memory
  289.     TWI_Start_Read_Write( messageBuf, 131 );
  290.     // Should wait for completion of EEPROM write cycle. Blinking the LED will do this.
  291.     while ( TWI_Transceiver_Busy() );    // Check for an error.
  292.  
  293.     //Now the info-tag is written, only to add data left
  294.     uint8_t  h, i ;
  295.        
  296.  
  297.     messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  298.     messageBuf[1] = (uint8_t)((address >> 8) & 0xff);       // Starting address in memory
  299.     messageBuf[2] = (uint8_t)(address & 0xff);       // Starting address in memory
  300.     bufferIndex = 3;
  301.  
  302.     h = 0;
  303.     while(h+8 <= size_y) {
  304.         h += 8;
  305.         glcdSetXY(0, h);
  306.        
  307.         for(i=0; i<=size_x; i++) {
  308.             messageBuf[bufferIndex] = glcdReadData();
  309.             bufferIndex++;
  310.             if (bufferIndex >= 131) {
  311.                 TWI_Start_Read_Write( messageBuf, 131 );
  312.                 // Should wait for completion of EEPROM write cycle. Blinking the LED will do this.
  313.                 while ( TWI_Transceiver_Busy() );    // Check for an error.
  314.                 bufferIndex = 3;
  315.                 address+=128;
  316.                 messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  317.                 messageBuf[1] = (uint8_t)((address >> 8) & 0xff);       // Starting address in memory
  318.                 messageBuf[2] = (uint8_t)(address & 0xff);       // Starting address in memory
  319.             }
  320.         }
  321.     }
  322. }
  323. #endif
  324.  
  325. void act_ks0108_Init(void)
  326. {
  327.     /* Set up PWM controlling brightness */
  328. #if GRAPHICS_DRIVER==KS0108
  329.     TCCR0A |= (1<<COM0A1)|(1<<WGM01)|(1<<WGM00);
  330.     TCCR0B |= (1<<CS00);
  331.     OCR0A = act_ks0108_INITIAL_BACKLIGHT;
  332.     DDRD |= (1<<PD6);
  333. #endif
  334. #if GRAPHICS_DRIVER==DOTMATRIX
  335.     TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
  336.     TCCR0B |= (1<<CS00);
  337.     OCR0B = 0xff-act_ks0108_INITIAL_BACKLIGHT;
  338.     DDRD |= (1<<PD5);
  339.    
  340.     /* Start timer for row management */
  341.     Timer_SetTimeout(act_ks0108_DOTMATRIX_TIMER, 1, TimerTypeFreeRunning, &glcdRefresh);   
  342. #endif
  343.  
  344.  
  345. #if act_ks0108_USE_EXTERNAL_EEPROM==1
  346.     TWI_Master_Initialise();
  347.     uint8_t temp = 0;
  348.     /// Do initial write to EEPROM. Write cycle takes 5 msecs, so flashing the led will delay enough.
  349.     //
  350.    
  351.     messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  352.     messageBuf[1] = (((1024+128)>>8)&0xff);             // Starting address MSB
  353.     messageBuf[2] = ((1024+128)&0xff);              // Starting address LSB
  354.    
  355.     for (temp=0; temp<128; temp++)
  356.     {
  357.         messageBuf[temp+3] = 128-temp; 
  358.     }
  359.     TWI_Start_Read_Write( messageBuf, 131 );
  360.     // Should wait for completion of EEPROM write cycle. Blinking the LED will do this.
  361.     while ( TWI_Transceiver_Busy() );    // Check for an error.
  362.    
  363.     //delay 10ms
  364.     uint32_t temp2;
  365.     temp2 =Timer_GetTicks();
  366.     while (Timer_GetTicks() < temp2 + 10);
  367.  
  368.     #define TEMPID 0
  369.     uint16_t address = (TEMPID+1)*1024; //only addresses on page border is allowed
  370.     uint16_t ixa = 0;
  371.     uint8_t jxa = 0;
  372.     for (jxa = 0; jxa< 8; jxa++){
  373.         for (ixa = 0; ixa < 128; ixa++){
  374.             messageBuf[ixa+3] = (((uint8_t)pgm_read_byte((uint16_t)&Splash_left+ixa+jxa*128)) ^ 0xff);
  375.         }
  376.         messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  377.         messageBuf[1] = (uint8_t)((address >> 8) & 0xff);       // Starting address in memory
  378.         messageBuf[2] = (uint8_t)(address & 0xff);       // Starting address in memory
  379.         TWI_Start_Read_Write( messageBuf, 131 );
  380.         // Should wait for completion of EEPROM write cycle. Blinking the LED will do this.
  381.         while ( TWI_Transceiver_Busy() );    // Check for an error.
  382.         //delay 10ms
  383.         temp2 =Timer_GetTicks();
  384.         while (Timer_GetTicks() < temp2 + 10);
  385.         address += 128;
  386.     }
  387.  
  388.     address = (TEMPID+2)*1024;  //only addresses on page border is allowed
  389.     ixa = 0;
  390.     jxa = 0;
  391.     for (jxa = 0; jxa< 8; jxa++){
  392.         for (ixa = 0; ixa < 128; ixa++){
  393.             messageBuf[ixa+3] = (uint8_t)pgm_read_byte((uint16_t)&Splash_left+ixa+jxa*128);
  394.         }
  395.         messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  396.         messageBuf[1] = (uint8_t)((address >> 8) & 0xff);       // Starting address in memory
  397.         messageBuf[2] = (uint8_t)(address & 0xff);       // Starting address in memory
  398.         TWI_Start_Read_Write( messageBuf, 131 );
  399.         // Should wait for completion of EEPROM write cycle. Blinking the LED will do this.
  400.         while ( TWI_Transceiver_Busy() );    // Check for an error.
  401.         //delay 10ms
  402.         temp2 =Timer_GetTicks();
  403.         while (Timer_GetTicks() < temp2 + 10);
  404.         address += 128;
  405.     }
  406.     for (temp=0; temp<131; temp++)
  407.     {
  408.         messageBuf[temp] = 0;  
  409.     }
  410.  
  411. #endif
  412.  
  413.     glcdInit();
  414.  
  415. #if act_ks0108_USE_EXTERNAL_EEPROM==0
  416.     uint16_t ixa = 0;
  417.     uint8_t jxa = 0;
  418.     for (jxa = 0; jxa< 8; jxa++){
  419.         glcdSetXY(0,jxa*8);
  420.         for (ixa = 0; ixa < 128; ixa++){
  421.             glcdWriteData((uint8_t)pgm_read_byte((uint16_t)&Splash_left+ixa+jxa*128), GLCD_COLOR_CLEAR);
  422.         }
  423.     }
  424. #endif
  425.  
  426. #if act_ks0108_USE_EXTERNAL_EEPROM==1
  427.     printImage(1,0,0);
  428.     //delay 10ms
  429.     temp2 =Timer_GetTicks();
  430.     while (Timer_GetTicks() < temp2 + 5000);
  431.     printImage(0,0,0);
  432. #endif
  433.     //glcdSetXY(0,0);
  434.     //glcdPutStrTransparent("=_-[]_-=",GLCD_COLOR_SET);
  435.     //glcdSetXY(0,8);
  436.     //glcdPutStrTransparent("--------",GLCD_COLOR_SET);
  437.     //glcdSetXY(0,16);
  438.     //glcdPutStr("-_=[]=-_",GLCD_COLOR_SET);
  439.     //glcdDrawRect(32, 32, 40, 16, GLCD_COLOR_SET);
  440.     //glcdDrawLine(10, 10, 100, 60, GLCD_COLOR_SET);
  441.     //glcdFillRect(90, 10, 20, 20, GLCD_COLOR_SET);
  442.     //glcdInvertRect(28, 10, 20, 20);
  443.     //glcdInvert();
  444.     //glcdDrawRoundRect(85, 5, 30, 30, 5, GLCD_COLOR_SET);
  445.     //glcdDrawCircle(64, 32, 10, 1);
  446.     glcdSetXY(87,8);
  447.     glcdPutStrTransparent("Home-",GLCD_COLOR_SET);
  448.     glcdSetXY(80,16);
  449.     glcdPutStrTransparent("Automa-",GLCD_COLOR_SET);
  450.     glcdSetXY(91,24);
  451.     glcdPutStrTransparent("ion",GLCD_COLOR_SET);
  452.     //glcdDrawLine(10, 62, 50, 5, GLCD_COLOR_CLEAR);
  453.    
  454. }
  455.  
  456. void act_ks0108_Process(void)
  457. {
  458.     ///TODO: Stuff that needs doing is done here
  459. }
  460.  
  461. void act_ks0108_HandleMessage(StdCan_Msg_t *rxMsg)
  462. {
  463.     //StdCan_Msg_t txMsg;
  464.     uint8_t n = 0;
  465.  
  466.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
  467.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  468.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_KS0108 &&
  469.         rxMsg->Header.ModuleId == act_ks0108_ID)
  470.     {
  471.     switch (rxMsg->Header.Command)
  472.     {
  473.         case CAN_MODULE_CMD_KS0108_LCD_CLEAR:
  474.           if (rxMsg->Length == 1) {
  475.             glcdSetColor((0x80&rxMsg->Data[0])>>7);
  476.           }
  477.           glcdClear();
  478.           rxMsg->Data[0] = glcdGetColor()<<7;
  479.           StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  480.           rxMsg->Length = 1;
  481.           #if act_ks0108_USE_EXTERNAL_EEPROM==1
  482.               uint8_t temp = 0;
  483.               //    Read the data from Memory. Value of read/write bit doesn't matter.
  484.                 messageBuf[0] = (MEMORY_I2C_ADDR<<TWI_ADR_BITS); // Read/write bit doesn't matter here
  485.                 messageBuf[1] = MEMORY_ADDR_MSB;       // Starting address in memory
  486.                 messageBuf[2] = MEMORY_ADDR_LSB;       // Starting address in memory
  487.                 TWI_Start_Random_Read( messageBuf, 129, 3 );    // Desired data length plus one (command byte).
  488.                 // Could do other actions in here, then get data.
  489.                 temp = TWI_Read_Data_From_Buffer( messageBuf, 129 );
  490.               rxMsg->Length = 6;
  491.               rxMsg->Data[1] = temp;
  492.               rxMsg->Data[2] = messageBuf[0+3];
  493.               rxMsg->Data[3] = messageBuf[0+4];
  494.               rxMsg->Data[4] = messageBuf[0+5];
  495.               rxMsg->Data[5] = messageBuf[0+80];
  496.           #endif
  497.           while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  498.           break;
  499.         case CAN_MODULE_CMD_KS0108_LCD_INVERT:
  500.           if (rxMsg->Length == 1) {
  501.             if ((0x80&rxMsg->Data[0])>>7 != glcdGetColor())
  502.                 glcdInvert();
  503.           } else
  504.             glcdInvert();
  505.           rxMsg->Data[0] = glcdGetColor()<<7;
  506.           StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  507.           rxMsg->Length = 1;
  508.           while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  509.           break;
  510.         case CAN_MODULE_CMD_KS0108_LCD_CURSOR:
  511.           if (rxMsg->Length == 2) {
  512.             glcdSetXY((0x3f&rxMsg->Data[0])*6, rxMsg->Data[1]*8);
  513.             color = ((0x80&rxMsg->Data[2])>>7);
  514.             Transparent = ((0x40&rxMsg->Data[2])>>6);
  515.           }
  516.           rxMsg->Data[0] = glcdGetColor()<<7;
  517.           rxMsg->Data[0] = Transparent<<6;
  518.           rxMsg->Data[0] |= (0x3f & (glcdGetX()/6));
  519.           rxMsg->Data[1] |= ((glcdGetY()/8));
  520.           StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  521.           rxMsg->Length = 2;
  522.           while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  523.  
  524.           break;
  525.  
  526.         case CAN_MODULE_CMD_KS0108_LCD_TEXTAT:
  527.           glcdSetXY((0x3f&rxMsg->Data[0])*6, rxMsg->Data[1]*8);
  528.           for (n = 2; n < rxMsg->Length; n++)
  529.           {
  530.               if (((0x40&rxMsg->Data[0])>>6)== TRANSPARENT)
  531.                 glcdWriteCharTransparent((char)rxMsg->Data[n], (0x80&rxMsg->Data[0])>>7);
  532.               else
  533.                 glcdWriteChar((char)rxMsg->Data[n], (0x80&rxMsg->Data[0])>>7);
  534.           }
  535.         break;
  536.  
  537.         case CAN_MODULE_CMD_KS0108_LCD_TEXT:
  538.         for (n = 0; n < rxMsg->Length; n++)
  539.         {
  540.             if (Transparent == TRANSPARENT)
  541.                 glcdWriteCharTransparent((char)rxMsg->Data[n], color);
  542.             else
  543.                 glcdWriteChar((char)rxMsg->Data[n], color);
  544.         }
  545.         break;
  546.  
  547.         case CAN_MODULE_CMD_KS0108_LCD_BACKLIGHT:
  548.             if (rxMsg->Length > 0) {
  549.                 if ( rxMsg->Data[0] == 0) {
  550.                     TCCR0A &= ~(1<<COM0A0);
  551.                     TCCR0A &= ~(1<<COM0A1);
  552.                     PORTD &= ~(1<<PD6);
  553.                     OCR0A = rxMsg->Data[0];
  554.                 } else {
  555.                     TCCR0A |= (1<<COM0A1)|(1<<WGM01)|(1<<WGM00);
  556.                     OCR0A = rxMsg->Data[0];
  557.                 }
  558.  
  559.             }
  560.             StdCan_Msg_t txMsg;
  561.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  562.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  563.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_KS0108;
  564.             txMsg.Header.ModuleId = act_ks0108_ID;
  565.             txMsg.Header.Command = CAN_MODULE_CMD_KS0108_LCD_BACKLIGHT;
  566.             txMsg.Length = 1;
  567.             txMsg.Data[0] = OCR0A;
  568.             while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  569.         break;
  570.        
  571.         case CAN_MODULE_CMD_KS0108_LCD_DRAWRECT:
  572.           if ((0x40&rxMsg->Data[0])>>6)
  573.             glcdFillRect(rxMsg->Data[1], rxMsg->Data[2], rxMsg->Data[3], rxMsg->Data[4], (0x80&rxMsg->Data[0])>>7);
  574.           else
  575.             if (rxMsg->Data[5] == 0)
  576.                 glcdDrawRect(rxMsg->Data[1], rxMsg->Data[2], rxMsg->Data[3], rxMsg->Data[4], (0x80&rxMsg->Data[0])>>7);
  577.             else
  578.                 glcdDrawRoundRect(rxMsg->Data[1], rxMsg->Data[2], rxMsg->Data[3], rxMsg->Data[4], rxMsg->Data[5],(0x80&rxMsg->Data[0])>>7);
  579.           break;
  580.        
  581.         case CAN_MODULE_CMD_KS0108_LCD_DRAWLINE:
  582.           glcdDrawLine(rxMsg->Data[1], rxMsg->Data[2], rxMsg->Data[3], rxMsg->Data[4], (0x80&rxMsg->Data[0])>>7);
  583.           break;
  584.  
  585.         case CAN_MODULE_CMD_KS0108_LCD_DRAWCIRCLE:
  586.           glcdDrawCircle(rxMsg->Data[1], rxMsg->Data[2], rxMsg->Data[3], (0x80&rxMsg->Data[0])>>7);
  587.           break;
  588.    
  589.         case CAN_MODULE_CMD_KS0108_LCD_INVERTRECT:
  590.           glcdInvertRect(rxMsg->Data[0], rxMsg->Data[1], rxMsg->Data[2], rxMsg->Data[3]);
  591.           break;
  592.  
  593.         }
  594.     }
  595. /*
  596.     static uint8_t saer=0;
  597.     static uint8_t saer2=0;
  598.     saer++;
  599.     if (saer>10) {
  600.         saer2++;
  601.         uint8_t ixa = 0;
  602.         uint8_t jxa = 0;
  603.         for (jxa = 0; jxa< 8; jxa++){
  604.             glcdSetXY(0,jxa);
  605.             for (ixa = 0; ixa < 128; ixa++){
  606.                 glcdWriteData((uint8_t)pgm_read_byte((uint16_t)&Splash_left+ixa+jxa*128));
  607.             }
  608.         }
  609.         saer=0;
  610.         glcdSetXY(83,1);
  611.         glcdPutStr("Tycker ");
  612.         glcdSetXY(83,2);
  613.         glcdPutStr(" detta ");
  614.         glcdSetXY(83,3);
  615.         glcdPutStr("funkar!");
  616.         glcdSetXY(83,4);
  617.         char buffer[20];   
  618.         //numtoascii((int16_t)saer2 ,*buffer);
  619.         unsignedtoascii((int16_t)saer2,0,buffer,1);
  620.         glcdPutStr(buffer);
  621.     }
  622. */
  623. }
  624.  
  625. void act_ks0108_List(uint8_t ModuleSequenceNumber)
  626. {
  627.     StdCan_Msg_t txMsg;
  628.  
  629.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  630.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  631.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_KS0108;
  632.     txMsg.Header.ModuleId = act_ks0108_ID;
  633.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  634.     txMsg.Length = 6;
  635.  
  636.     uint32_t HwId=BIOS_GetHwId();
  637.     txMsg.Data[0] = HwId&0xff;
  638.     txMsg.Data[1] = (HwId>>8)&0xff;
  639.     txMsg.Data[2] = (HwId>>16)&0xff;
  640.     txMsg.Data[3] = (HwId>>24)&0xff;
  641.  
  642.     txMsg.Data[4] = NUMBER_OF_MODULES;
  643.     txMsg.Data[5] = ModuleSequenceNumber;
  644.  
  645.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  646. }
  647.  
  648. //� la pengi. Skall libbifieras.
  649.     void numtoascii( int16_t num, char **str ) {
  650.         if( num==0 ) return;
  651.         numtoascii( num/10, str );
  652.         **str = '0' + (num%10);
  653.         (*str)++;
  654.     }
  655.  
  656.     void signedtoascii(int16_t num, uint8_t decimalplace, char *string, uint8_t numberofdecimals){ //decimalplace is number of decimals
  657.         uint8_t i;
  658.  
  659.         if( num<0 ) {
  660.             *(string++) = '-';
  661.             num = -num;
  662.         }
  663.         numtoascii(num>>decimalplace, &string );
  664.         if(numberofdecimals!=0) *(string++) = '.';
  665.         for(i=0;i<numberofdecimals;i++) {
  666.             num %= 1<<decimalplace;
  667.             num *= 10;
  668.             *(string++) = '0' + (num>>decimalplace);
  669.         }
  670.         *(string++) = 0;
  671.     }
  672.  
  673.     void unsignedtoascii(uint16_t num, uint8_t decimalplace, char *string, uint8_t numberofdecimals){ //decimalplace is number of decimals
  674.         uint8_t i;
  675.         numtoascii(num>>decimalplace, &string );
  676.         if(numberofdecimals!=0) *(string++) = '.';
  677.         for(i=0;i<numberofdecimals;i++) {
  678.             num %= 1<<decimalplace;
  679.             num *= 10;
  680.             *(string++) = '0' + (num>>decimalplace);
  681.         }
  682.         *(string++) = 0;
  683.     }
  684.