2 * GraphLCD driver library
4 * avrctl.c - AVR controlled LCD driver class
6 * This file is released under the GNU General Public License. Refer
7 * to the COPYING file distributed with this package.
9 * (c) 2005 Andreas Regel <andreas.regel AT powarman.de>
25 ** 8 bits sync byte (0xAA for sent commands, 0x55 for received commands)
27 ** 16 bits command length (excluding header)
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;
34 const unsigned char CMD_SYNC_SEND = 0xAA;
35 const unsigned char CMD_SYNC_RECV = 0x55;
37 const unsigned char CMD_SYS_SYNC = 0x00;
38 const unsigned char CMD_SYS_ACK = 0x01;
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;
47 const int kBufferWidth = 256;
48 const int kBufferHeight = 128;
51 cDriverAvrCtl::cDriverAvrCtl(cDriverConfig * config)
54 oldConfig = new cDriverConfig(*config);
56 port = new cSerialPort();
58 //width = config->width;
59 //height = config->height;
63 cDriverAvrCtl::~cDriverAvrCtl()
69 int cDriverAvrCtl::Init()
73 width = config->width;
76 height = config->height;
80 for (unsigned int i = 0; i < config->options.size(); i++)
82 if (config->options[i].name == "")
87 // setup lcd array (wanted state)
88 newLCD = new unsigned char*[kBufferWidth];
91 for (x = 0; x < kBufferWidth; x++)
93 newLCD[x] = new unsigned char[(kBufferHeight + 7) / 8];
94 memset(newLCD[x], 0, (kBufferHeight + 7) / 8);
97 // setup lcd array (current state)
98 oldLCD = new unsigned char*[kBufferWidth];
101 for (x = 0; x < kBufferWidth; x++)
103 oldLCD[x] = new unsigned char[(kBufferHeight + 7) / 8];
104 memset(oldLCD[x], 0, (kBufferHeight + 7) / 8);
108 if (config->device == "")
112 if (port->Open(config->device.c_str()) != 0)
115 *oldConfig = *config;
120 syslog(LOG_INFO, "%s: AvrCtl initialized.\n", config->name.c_str());
124 int cDriverAvrCtl::DeInit()
127 // free lcd array (wanted state)
130 for (x = 0; x < kBufferWidth; x++)
136 // free lcd array (current state)
139 for (x = 0; x < kBufferWidth; x++)
146 if (port->Close() != 0)
151 int cDriverAvrCtl::CheckSetup()
153 if (config->device != oldConfig->device ||
154 config->width != oldConfig->width ||
155 config->height != oldConfig->height)
162 if (config->upsideDown != oldConfig->upsideDown ||
163 config->invert != oldConfig->invert)
165 oldConfig->upsideDown = config->upsideDown;
166 oldConfig->invert = config->invert;
172 void cDriverAvrCtl::Clear()
174 for (int x = 0; x < kBufferWidth; x++)
175 memset(newLCD[x], 0, (kBufferHeight + 7) / 8);
178 void cDriverAvrCtl::Set8Pixels(int x, int y, unsigned char data)
180 if (x >= width || y >= height)
183 if (!config->upsideDown)
185 int offset = 7 - (y % 8);
186 for (int i = 0; i < 8; i++)
188 newLCD[x + i][y / 8] |= ((data >> (7 - i)) << offset) & (1 << offset);
195 int offset = 7 - (y % 8);
196 for (int i = 0; i < 8; i++)
198 newLCD[x - i][y / 8] |= ((data >> (7 - i)) << offset) & (1 << offset);
203 void cDriverAvrCtl::Refresh(bool refreshAll)
208 int num = kBufferWidth / 2;
209 unsigned char data[16*num];
211 if (CheckSetup() == 1)
214 if (config->refreshDisplay > 0)
216 refreshCounter = (refreshCounter + 1) % config->refreshDisplay;
217 if (!refreshAll && !refreshCounter)
224 for (x = 0; x < kBufferWidth; x += num)
226 for (i = 0; i < num; i++)
228 for (y = 0; y < (kBufferHeight + 7) / 8; y++)
230 data[i * ((kBufferHeight + 7) / 8) + y] = (newLCD[x + i][y]) ^ (config->invert ? 0xff : 0x00);
232 memcpy(oldLCD[x + i], newLCD[x + i], (kBufferHeight + 7) / 8);
234 CmdDispSetColData(x, 0, 16 * num, data);
237 CmdDispSwitchScreen();
238 // and reset RefreshCounter
243 // draw only the changed bytes
247 void cDriverAvrCtl::SetBrightness(unsigned int percent)
249 CmdDispSetBrightness(percent);
252 int cDriverAvrCtl::WaitForAck(void)
259 while (len < 4 && timeout > 0)
261 len += port->ReadData(&cmd[len]);
269 void cDriverAvrCtl::CmdSysSync(void)
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;
278 port->WriteData(cmd, 4);
282 void cDriverAvrCtl::CmdDispClearScreen(void)
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;
291 port->WriteData(cmd, 4);
295 void cDriverAvrCtl::CmdDispSwitchScreen(void)
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;
304 port->WriteData(cmd, 4);
308 void cDriverAvrCtl::CmdDispSetBrightness(uint8_t percent)
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;
318 port->WriteData(cmd, 5);
322 void cDriverAvrCtl::CmdDispSetColData(uint16_t column, uint16_t offset, uint16_t length, uint8_t * data)
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);
338 port->WriteData(cmd, length+10);
342 void cDriverAvrCtl::CmdDispUpdate(void)
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;
351 port->WriteData(cmd, 4);