graphlcd-base/glcddrivers/avrctl.c
author root@rika
Wed, 06 Feb 2008 17:37:50 +0000
changeset 5 37602e25a04a
parent 4 df6a40031aa5
child 10 9798f65f2f35
permissions -rw-r--r--
added picctl code
     1 /*
     2  * GraphLCD driver library
     3  *
     4  * avrctl.c  -  AVR controlled LCD driver class
     5  *
     6  * This file is released under the GNU General Public License. Refer
     7  * to the COPYING file distributed with this package.
     8  *
     9  * (c) 2005 Andreas Regel <andreas.regel AT powarman.de>
    10  */
    11 
    12 #include <stdint.h>
    13 #include <syslog.h>
    14 
    15 #include "common.h"
    16 #include "config.h"
    17 #include "port.h"
    18 #include "avrctl.h"
    19 
    20 
    21 namespace GLCD
    22 {
    23 
    24 /* command header:
    25 **  8 bits  sync byte (0xAA for sent commands, 0x55 for received commands)
    26 **  8 bits  command id
    27 ** 16 bits  command length (excluding header)
    28 */
    29 const unsigned char CMD_HDR_SYNC    = 0;
    30 const unsigned char CMD_HDR_COMMAND = 1;
    31 const unsigned char CMD_HDR_LENGTH  = 2;
    32 const unsigned char CMD_DATA_START  = 4;
    33 
    34 const unsigned char CMD_SYNC_SEND = 0xAA;
    35 const unsigned char CMD_SYNC_RECV = 0x55;
    36 
    37 const unsigned char CMD_SYS_SYNC = 0x00;
    38 const unsigned char CMD_SYS_ACK  = 0x01;
    39 
    40 const unsigned char CMD_DISP_CLEAR_SCREEN   = 0x10;
    41 const unsigned char CMD_DISP_SWITCH_SCREEN  = 0x11;
    42 const unsigned char CMD_DISP_SET_BRIGHTNESS = 0x12;
    43 const unsigned char CMD_DISP_SET_COL_DATA   = 0x13;
    44 const unsigned char CMD_DISP_SET_ROW_DATA   = 0x14;
    45 const unsigned char CMD_DISP_UPDATE         = 0x15;
    46 
    47 const int kBufferWidth  = 256;
    48 const int kBufferHeight = 128;
    49 
    50 
    51 cDriverAvrCtl::cDriverAvrCtl(cDriverConfig * config)
    52 :   config(config)
    53 {
    54     oldConfig = new cDriverConfig(*config);
    55 
    56     port = new cSerialPort();
    57 
    58     //width = config->width;
    59     //height = config->height;
    60     refreshCounter = 0;
    61 }
    62 
    63 cDriverAvrCtl::~cDriverAvrCtl()
    64 {
    65     delete port;
    66     delete oldConfig;
    67 }
    68 
    69 int cDriverAvrCtl::Init()
    70 {
    71     int x;
    72 
    73     width = config->width;
    74     if (width <= 0)
    75         width = 256;
    76     height = config->height;
    77     if (height <= 0)
    78         height = 128;
    79 
    80     for (unsigned int i = 0; i < config->options.size(); i++)
    81     {
    82         if (config->options[i].name == "")
    83         {
    84         }
    85     }
    86 
    87     // setup lcd array (wanted state)
    88     newLCD = new unsigned char*[kBufferWidth];
    89     if (newLCD)
    90     {
    91         for (x = 0; x < kBufferWidth; x++)
    92         {
    93             newLCD[x] = new unsigned char[(kBufferHeight + 7) / 8];
    94             memset(newLCD[x], 0, (kBufferHeight + 7) / 8);
    95         }
    96     }
    97     // setup lcd array (current state)
    98     oldLCD = new unsigned char*[kBufferWidth];
    99     if (oldLCD)
   100     {
   101         for (x = 0; x < kBufferWidth; x++)
   102         {
   103             oldLCD[x] = new unsigned char[(kBufferHeight + 7) / 8];
   104             memset(oldLCD[x], 0, (kBufferHeight + 7) / 8);
   105         }
   106     }
   107 
   108     if (config->device == "")
   109     {
   110         return -1;
   111     }
   112     if (port->Open(config->device.c_str()) != 0)
   113         return -1;
   114 
   115     *oldConfig = *config;
   116 
   117     // clear display
   118     Clear();
   119 
   120     syslog(LOG_INFO, "%s: AvrCtl initialized.\n", config->name.c_str());
   121     return 0;
   122 }
   123 
   124 int cDriverAvrCtl::DeInit()
   125 {
   126     int x;
   127     // free lcd array (wanted state)
   128     if (newLCD)
   129     {
   130         for (x = 0; x < kBufferWidth; x++)
   131         {
   132             delete[] newLCD[x];
   133         }
   134         delete[] newLCD;
   135     }
   136     // free lcd array (current state)
   137     if (oldLCD)
   138     {
   139         for (x = 0; x < kBufferWidth; x++)
   140         {
   141             delete[] oldLCD[x];
   142         }
   143         delete[] oldLCD;
   144     }
   145 
   146     if (port->Close() != 0)
   147         return -1;
   148     return 0;
   149 }
   150 
   151 int cDriverAvrCtl::CheckSetup()
   152 {
   153     if (config->device != oldConfig->device ||
   154         config->width != oldConfig->width ||
   155         config->height != oldConfig->height)
   156     {
   157         DeInit();
   158         Init();
   159         return 0;
   160     }
   161 
   162     if (config->upsideDown != oldConfig->upsideDown ||
   163         config->invert != oldConfig->invert)
   164     {
   165         oldConfig->upsideDown = config->upsideDown;
   166         oldConfig->invert = config->invert;
   167         return 1;
   168     }
   169     return 0;
   170 }
   171 
   172 void cDriverAvrCtl::Clear()
   173 {
   174     for (int x = 0; x < kBufferWidth; x++)
   175         memset(newLCD[x], 0, (kBufferHeight + 7) / 8);
   176 }
   177 
   178 void cDriverAvrCtl::Set8Pixels(int x, int y, unsigned char data)
   179 {
   180     if (x >= width || y >= height)
   181         return;
   182 
   183     if (!config->upsideDown)
   184     {
   185         int offset = 7 - (y % 8);
   186         for (int i = 0; i < 8; i++)
   187         {
   188             newLCD[x + i][y / 8] |= ((data >> (7 - i)) << offset) & (1 << offset);
   189         }
   190     }
   191     else
   192     {
   193         x = width - 1 - x;
   194         y = height - 1 - y;
   195         int offset = 7 - (y % 8);
   196         for (int i = 0; i < 8; i++)
   197         {
   198             newLCD[x - i][y / 8] |= ((data >> (7 - i)) << offset) & (1 << offset);
   199         }
   200     }
   201 }
   202 
   203 void cDriverAvrCtl::Refresh(bool refreshAll)
   204 {
   205     int x;
   206     int y;
   207     int i;
   208     int num = kBufferWidth / 2;
   209     unsigned char data[16*num];
   210 
   211     if (CheckSetup() == 1)
   212         refreshAll = true;
   213 
   214     if (config->refreshDisplay > 0)
   215     {
   216         refreshCounter = (refreshCounter + 1) % config->refreshDisplay;
   217         if (!refreshAll && !refreshCounter)
   218             refreshAll = true;
   219     }
   220 
   221     refreshAll = true;
   222     if (refreshAll)
   223     {
   224         for (x = 0; x < kBufferWidth; x += num)
   225         {
   226             for (i = 0; i < num; i++)
   227             {
   228                 for (y = 0; y < (kBufferHeight + 7) / 8; y++)
   229                 {
   230                     data[i * ((kBufferHeight + 7) / 8) + y] = (newLCD[x + i][y]) ^ (config->invert ? 0xff : 0x00);
   231                 }
   232                 memcpy(oldLCD[x + i], newLCD[x + i], (kBufferHeight + 7) / 8);
   233             }
   234             CmdDispSetColData(x, 0, 16 * num, data);
   235         }
   236         CmdDispUpdate();
   237         CmdDispSwitchScreen();
   238         // and reset RefreshCounter
   239         refreshCounter = 0;
   240     }
   241     else
   242     {
   243         // draw only the changed bytes
   244     }
   245 }
   246 
   247 void cDriverAvrCtl::SetBrightness(unsigned int percent)
   248 {
   249   CmdDispSetBrightness(percent);
   250 }
   251 
   252 int cDriverAvrCtl::WaitForAck(void)
   253 {
   254     uint8_t cmd[4];
   255     int len;
   256     int timeout = 10000;
   257 
   258     len = 0;
   259     while (len < 4 && timeout > 0)
   260     {
   261         len += port->ReadData(&cmd[len]);
   262         timeout--;
   263     }
   264     if (timeout == 0)
   265         return 0;
   266     return 1;
   267 }
   268 
   269 void cDriverAvrCtl::CmdSysSync(void)
   270 {
   271     uint8_t cmd[4];
   272 
   273     cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND;
   274     cmd[CMD_HDR_COMMAND] = CMD_SYS_SYNC;
   275     cmd[CMD_HDR_LENGTH] = 0;
   276     cmd[CMD_HDR_LENGTH+1] = 0;
   277 
   278     port->WriteData(cmd, 4);
   279     WaitForAck();
   280 }
   281 
   282 void cDriverAvrCtl::CmdDispClearScreen(void)
   283 {
   284     uint8_t cmd[4];
   285 
   286     cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND;
   287     cmd[CMD_HDR_COMMAND] = CMD_DISP_CLEAR_SCREEN;
   288     cmd[CMD_HDR_LENGTH] = 0;
   289     cmd[CMD_HDR_LENGTH+1] = 0;
   290 
   291     port->WriteData(cmd, 4);
   292     WaitForAck();
   293 }
   294 
   295 void cDriverAvrCtl::CmdDispSwitchScreen(void)
   296 {
   297     uint8_t cmd[4];
   298 
   299     cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND;
   300     cmd[CMD_HDR_COMMAND] = CMD_DISP_SWITCH_SCREEN;
   301     cmd[CMD_HDR_LENGTH] = 0;
   302     cmd[CMD_HDR_LENGTH+1] = 0;
   303 
   304     port->WriteData(cmd, 4);
   305     WaitForAck();
   306 }
   307 
   308 void cDriverAvrCtl::CmdDispSetBrightness(uint8_t percent)
   309 {
   310     uint8_t cmd[5];
   311 
   312     cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND;
   313     cmd[CMD_HDR_COMMAND] = CMD_DISP_SET_BRIGHTNESS;
   314     cmd[CMD_HDR_LENGTH] = 0;
   315     cmd[CMD_HDR_LENGTH+1] = 1;
   316     cmd[CMD_DATA_START] = percent;
   317 
   318     port->WriteData(cmd, 5);
   319     WaitForAck();
   320 }
   321 
   322 void cDriverAvrCtl::CmdDispSetColData(uint16_t column, uint16_t offset, uint16_t length, uint8_t * data)
   323 {
   324     uint8_t cmd[2560];
   325 
   326     cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND;
   327     cmd[CMD_HDR_COMMAND] = CMD_DISP_SET_COL_DATA;
   328     cmd[CMD_HDR_LENGTH] = (length + 6) >> 8;
   329     cmd[CMD_HDR_LENGTH+1] = (length + 6);
   330     cmd[CMD_DATA_START] = column >> 8;
   331     cmd[CMD_DATA_START+1] = column;
   332     cmd[CMD_DATA_START+2] = offset >> 8;
   333     cmd[CMD_DATA_START+3] = offset;
   334     cmd[CMD_DATA_START+4] = length >> 8;
   335     cmd[CMD_DATA_START+5] = length;
   336     memcpy(&cmd[CMD_DATA_START+6], data, length);
   337 
   338     port->WriteData(cmd, length+10);
   339     WaitForAck();
   340 }
   341 
   342 void cDriverAvrCtl::CmdDispUpdate(void)
   343 {
   344     uint8_t cmd[4];
   345 
   346     cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND;
   347     cmd[CMD_HDR_COMMAND] = CMD_DISP_UPDATE;
   348     cmd[CMD_HDR_LENGTH] = 0;
   349     cmd[CMD_HDR_LENGTH+1] = 0;
   350 
   351     port->WriteData(cmd, 4);
   352     WaitForAck();
   353 }
   354 
   355 }