From 10ab31fa86dbf9875b5f6baa6ac59fefaaf86be3 Mon Sep 17 00:00:00 2001 From: andreas 'randy' weinberger Date: Sun, 21 Feb 2010 19:58:27 +0100 Subject: initial git upload, based on graphlcd-base-0.1.5 --- glcddrivers/gu126x64D-K610A4.c | 967 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 967 insertions(+) create mode 100644 glcddrivers/gu126x64D-K610A4.c (limited to 'glcddrivers/gu126x64D-K610A4.c') diff --git a/glcddrivers/gu126x64D-K610A4.c b/glcddrivers/gu126x64D-K610A4.c new file mode 100644 index 0000000..e927f49 --- /dev/null +++ b/glcddrivers/gu126x64D-K610A4.c @@ -0,0 +1,967 @@ +/* + * GraphLCD driver library + * + * gu126x64D-K610A4.c - 8-bit driver module for Noritake GU126x64D-K610A4 VFD + * displays. The VFD is operating in its 8 bit-mode + * connected to a single PC parallel port. + * + * based on: + * gu256x64-372 driver module for graphlcd + * (c) 2004 Andreas 'randy' Weinberger (randy AT smue.org) + * gu256x64-3900 driver module for graphlcd + * (c) 2004 Ralf Mueller (ralf AT bj-ig.de) + * gu140x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * ks0108 driver module for graphlcd + * (c) 2004 Andreas 'randy' Weinberger (randy AT smue.org) + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2007 Alexander Rieger (Alexander.Rieger AT inka.de) + */ + +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "gu126x64D-K610A4.h" +#include "port.h" + +namespace GLCD +{ +//----- commands to the display ----------------------------------------------- +static const unsigned char CMD_RUN_MACRO_01 = 0x01; // run macro 1 +static const unsigned char CMD_RUN_MACRO_02 = 0x02; // run macro 2 +static const unsigned char CMD_RUN_MACRO_03 = 0x03; // run macro 3 +static const unsigned char CMD_RUN_MACRO_04 = 0x04; // run macro 4 +static const unsigned char CMD_RUN_MACRO_05 = 0x05; // run macro 5 +static const unsigned char CMD_RUN_MACRO_06 = 0x06; // run macro 6 +static const unsigned char CMD_RUN_MACRO_07 = 0x07; // run macro 7 + +static const unsigned char CMD_CURSOR_POS = 0x10; // Set cursor position +static const unsigned char CMD_BOX_SET = 0x11; // Set area +static const unsigned char CMD_BOX_CLEAR = 0x12; // Clear area +static const unsigned char CMD_BOX_INVERT = 0x13; // Invert area +static const unsigned char CMD_RECT_SET = 0x14; // Set outline +static const unsigned char CMD_RECT_CLEAR = 0x15; // Clear outline + +static const unsigned char CMD_PIXEL_SET = 0x16; // Set pixel at current pos +static const unsigned char CMD_PIXEL_CLEAR = 0x17; // Clear pixel at current pos + +static const unsigned char CMD_GRAPHIC_WRITE = 0x18; // Write graphics data (args: len, data) +static const unsigned char CMD_RESET = 0x19; // Reset display +static const unsigned char CMD_WRITE_MODE = 0x1A; // Write mode +static const unsigned char CMD_INTRO = 0x1B; // Intro for other commands (see CMA_*) +static const unsigned char CMD_FONT_PROP_SML = 0x1C; // Select font: proportional mini +static const unsigned char CMD_FONT_FIX_MED = 0x1D; // Select font: fixed spaced 5x7 +static const unsigned char CMD_FONT_FIX_BIG = 0x1E; // Select font: fixed spaced 10x14 + +static const unsigned char CMA_MACROS_ERASE = 0x4D; // Erase Macros (usage: CMD_INTRO + this) +static const unsigned char CMA_EPROM_LOCK = 0x4C; // Lock EEPROM (usage: CMD_INTRO + this) +static const unsigned char CMA_EPROM_UNLOCK = 0x55; // Unlock EEPROM (usage: CMD_INTRO + this) + +static const unsigned char CMA_POWER_OFF = 0x46; // Power off (usage: CMD_INTRO + this) +static const unsigned char CMA_POWER_ON = 0x50; // Power on (usage: CMD_INTRO + this) + +//----- signal lines ---------------------------------------------------------- +static const unsigned char OUT_EN_HI = kAutoLow ; +static const unsigned char OUT_EN_LO = kAutoHigh; +static const unsigned char OUT_EN_MASK = OUT_EN_HI; + +static const unsigned char IN_MB_HI = 0x40; +static const unsigned char IN_MB_LO = 0x00; +static const unsigned char IN_MB_MASK = IN_MB_HI; + +//----- log flags ------------------------------------------------------------- +static const unsigned int LL_REFRESH_START = 0x0001; // 1 +static const unsigned int LL_REFRESH_END = 0x0002; // 2 +static const unsigned int LL_REFRESH_MED = 0x0004; // 4 +static const unsigned int LL_VFD_CMD = 0x0008; // 8 +static const unsigned int LL_MAX_WAIT = 0x0010; // 16 + +//----- mixed consts ---------------------------------------------------------- +static const long ADJUST_FACTOR = 100; // used to adjust timing + +//----------------------------------------------------------------------------- +cDriverGU126X64D_K610A4::cDriverGU126X64D_K610A4(cDriverConfig * config) + : port (0) + , config (config) + , oldConfig (0) + , myNumRows (0) + , myDrawMem (0) + , myVFDMem (0) + , myUseSleepInit (false) + , myPortDelayNS (0) + , myDelay125NS (0) + , myRefreshCounter (0) + , myClaimCounter (0) + , myDataPendingCounter(0) + , myLogFlags (0) +{ + oldConfig = new cDriverConfig(*config); +} // cDriverGU126X64D_K610A4::cDriverGU126X64D_K610A4() + +//----------------------------------------------------------------------------- +cDriverGU126X64D_K610A4::~cDriverGU126X64D_K610A4() +{ + delete oldConfig; +} // cDriverGU126X64D_K610A4::cDriverGU126X64D_K610A4() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::Init() +{ + width = config->width; + if (width <= 0 || width > 256) // don't allow unreasonable big sizes from config + { + width = 126; + } // if + + height = config->height; + if (height <= 0 || height > 256) // don't allow unreasonable big sizes from config + { + height = 64; + } // if + + //----- parse config ----- + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Debug") + { + myLogFlags = atoi(config->options[i].value.c_str()); + } // if + } // for + + myNumRows = ((height + 7) / 8); + port = new cParallelPort(); + + // setup drawing memory + myDrawMem = new unsigned char *[width]; + for (int x = 0; x < width; x++) + { + myDrawMem[x] = new unsigned char[myNumRows]; + memset(myDrawMem[x], 0, myNumRows); + } // for + + // setup vfd memory + myVFDMem = new unsigned char *[width]; + for (int x = 0; x < width; x++) + { + myVFDMem[x] = new unsigned char[myNumRows]; + memset(myVFDMem[x], 0, myNumRows); + } // for + + if (initParallelPort() < 0) + { + return -1; + } // if + + initDisplay(); + + *oldConfig = *config; + + // Set Display SetBrightness + SetBrightness(config->brightness); + + // clear display + Clear(); + clearVFDMem(); + + syslog( LOG_INFO, "%s: initialized (width: %d height: %d)" + , config->name.c_str(), width, height + ); + + return 0; +} // cDriverGU126X64D_K610A4::Init() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::DeInit() +{ + if (myVFDMem) + { + for (int x = 0; x < width; x++) + { + delete[] myVFDMem[x]; + } // for + delete[] myVFDMem; + myVFDMem = 0; + } // if + + if (myDrawMem) + { + for(int x = 0; x < width; x++) + { + delete[] myDrawMem[x]; + } // for + delete[] myDrawMem; + myDrawMem = 0; + } // if + + if (port) + { + // claim port to avoid msg when closing the port + port->Claim(); + if (port->Close() != 0) + { + return -1; + } // if + delete port; + port = 0; + } // if + + return 0; +} // cDriverGU126X64D_K610A4::DeInit() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::checkSetup() +{ + if ( config->device != oldConfig->device + || config->port != oldConfig->port + || config->width != oldConfig->width + || config->height != oldConfig->height + ) + { + DeInit(); + Init(); + return 0; + } // if + + if (config->brightness != oldConfig->brightness) + { + oldConfig->brightness = config->brightness; + SetBrightness(config->brightness); + } // if + + if ( config->upsideDown != oldConfig->upsideDown + || config->invert != oldConfig->invert + ) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + + return 1; + } // if + + return 0; +} // cDriverGU126X64D_K610A4::checkSetup() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::initParallelPort() +{ + struct timeval tv1, tv2; + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + { + syslog(LOG_ERR, "%s: unable to initialize gu256x64-3900!", config->name.c_str()); + return -1; + } // if + syslog(LOG_INFO, "%s: using direct IO!", config->name.c_str()); + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + { + syslog(LOG_ERR, "%s: unable to initialize gu256x64-3900!", config->name.c_str()); + return -1; + } // if + syslog(LOG_INFO, "%s: using ppdev!", config->name.c_str()); + } // if + + if (nSleepInit() != 0) + { + syslog(LOG_ERR, "%s: INFO: cannot change wait parameters Err: %s (cDriver::Init)", config->name.c_str(), strerror(errno)); + myUseSleepInit = false; + } + else + { + myUseSleepInit = true; + } // if + + //----- measure the time to write to the port ----- + syslog(LOG_DEBUG, "%s: benchmark started.", config->name.c_str()); + gettimeofday(&tv1, 0); + + const int aBenchCount = 1000; // don't change this! + for (int x = 0; x < aBenchCount; x++) + { + port->WriteData(x % 0x100); + } // for + + gettimeofday(&tv2, 0); + + // release the port, which was implicitely claimed by open + port->Release(); + + if (myUseSleepInit) nSleepDeInit(); + + myPortDelayNS = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); + + myDelay125NS = std::max(125 + (ADJUST_FACTOR * config->adjustTiming) - myPortDelayNS, 0L); + + syslog( LOG_DEBUG, "%s: benchmark stopped. Time for Port Command: %ldns, delay: %ldns" + , config->name.c_str(), myPortDelayNS, myDelay125NS + ); + + return 0; +} // cDriverGU126X64D_K610A4::initParallelPort() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::initDisplay() +{ + claimPort(); + cmdReset(); + releasePort(); +} // cDriverGU126X64D_K610A4::initDisplay() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::clearVFDMem() +{ + for (int x = 0; x < width; x++) + { + memset(myVFDMem[x], 0, myNumRows); + } // for +} // cDriverGU126X64D_K610A4::clearVFDMem() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::Clear() +{ + for (int x = 0; x < width; x++) + { + memset(myDrawMem[x], 0, myNumRows); + } // for +} // cDriverGU126X64D_K610A4::Clear() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::SetBrightness(unsigned int percent) +{ + claimPort(); + cmdSetBrightness(percent); + releasePort(); +} // cDriverGU126X64D_K610A4::SetBrightness() + +//----------------------------------------------------------------------------- +bool cDriverGU126X64D_K610A4::waitForStatus(unsigned char theMask, unsigned char theValue, int theMaxWait) +{ + theValue = theValue & theMask; + + int status = port->ReadStatus(); + + if ((status & theMask) != theValue) + { + // wait some time for MB go HI/LO but not forever + int i = 0; + for(i = 0; ((status & theMask) != theValue) && i < theMaxWait; i++) + { + status = port->ReadStatus(); + } // for + + if (isLogEnabled(LL_MAX_WAIT) && i >= theMaxWait) + { + syslog( LOG_INFO, "%s: slept for %5d times while waiting for MB = %d" + , config->name.c_str(), i, ((theMask & theValue) == 0 ? 0 : 1) + ); + } // + } // if + + return ((status & theMask) == theValue); +} // cDriverGU126X64D_K610A4::waitForStatus() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::writeParallel(unsigned char data) +{ + if (myUseSleepInit) nSleepInit(); + + waitForStatus(IN_MB_MASK, IN_MB_LO, 500); // wait for MB == LO + + port->WriteData(data); // write data + nSleep(myDelay125NS); // - sleep + + port->WriteControl(OUT_EN_LO & OUT_EN_MASK); // set ENABLE to LO + nSleep(myDelay125NS); // - sleep + + port->WriteControl(OUT_EN_HI & OUT_EN_MASK); // set ENABLE to HI + + waitForStatus(IN_MB_MASK, IN_MB_HI, 50); // wait for MB == HI + +// the other drivers don't do this neither +// if (myUseSleepInit) nSleepDeInit(); +} // cDriverGU126X64D_K610A4::writeParallel() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::write(unsigned char data) +{ + int b = 0; + + writeParallel(data); + ++b; + + // if data == 0x60 -> send 0x60 twice + // (0x60 switches to hex-mode) + if (data == 0x60) + { + writeParallel(data); + ++b; + } // if + + return b; +} // cDriverGU126X64D_K610A4::write() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::setPixel(int x, int y) +{ + if (!myDrawMem ) return; + if (x >= width || x < 0) return; + if (y >= height || y < 0) return; + + if (config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } // if + + unsigned char c = 0x80 >> (y % 8); + + myDrawMem[x][y/8] = myDrawMem[x][y/8] | c; +} // cDriverGU126X64D_K610A4::setPixel() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::Set8Pixels(int x, int y, unsigned char data) +{ + // x - pos isn't maybe align to 8 + x &= 0xFFF8; + + for (int n = 0; n < 8; ++n) + { + if ((data & (0x80 >> n)) != 0) // if bit is set + { + setPixel(x + n, y); + } // if + } // for +} // cDriverGU126X64D_K610A4::Set8Pixels() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::Refresh(bool refreshAll) +{ + // no mem present -> return + if (!myVFDMem || !myDrawMem) + { + return; + } // if + + // create log + if (isLogEnabled(LL_REFRESH_START)) + { + syslog( LOG_INFO, "%s: > Refresh() all = %d RefreshDisplay = %d RefreshCtr = %d Delay = %ld" + , config->name.c_str() + , refreshAll + , config->refreshDisplay + , myRefreshCounter + , myDelay125NS + ); + } // if + + // setup changed -> refresh all + if (checkSetup() > 0) + { + syslog(LOG_DEBUG, "%s: Refresh() checkSetup() returned != 0 -> refreshAll = true", config->name.c_str()); + refreshAll = true; + } // if + + // refresh-counter exceeded -> refresh all + if (!refreshAll && config->refreshDisplay != 0) + { + myRefreshCounter = (myRefreshCounter + 1) % config->refreshDisplay; + refreshAll = myRefreshCounter == 0; + + if (refreshAll && isLogEnabled(LL_REFRESH_START)) + { + syslog(LOG_DEBUG, "%s: Refresh() refresh-count reached -> refreshAll = true", config->name.c_str()); + } // if + } // if + + if (isLogEnabled(LL_REFRESH_START)) + { + syslog( LOG_INFO, "%s: Refresh() all = %d RefreshDisplay = %d RefreshCtr = %d Delay = %ld" + , config->name.c_str() + , refreshAll + , config->refreshDisplay + , myRefreshCounter + , myDelay125NS + ); + } // if + + // time for logs + struct timeval tv1, tv2; + gettimeofday(&tv1, 0); + + claimPort(); + + int chunk = 128; // displays with more than 128 pixels width are written in chunks + // note: this driver isn't really prepared to handle displays + // with other dimensions than 126x64 + int xb = 0; + int yb = 0; + long bc = 0; + + for (yb = 0; yb < myNumRows; ++yb) + { + int minX = width; + int maxX = 0; + + //----- if !refreshAll -> check modified bytes + if (!refreshAll) + { + for (xb = 0; xb < width; ++xb) + { + if (myVFDMem[xb][yb] != myDrawMem[xb][yb]) + { + minX = std::min(minX, xb); + maxX = std::max(maxX, xb); + } // if + } // for + } + else + { + minX = 0; + maxX = width - 1; + } // if + + // create log + if (isLogEnabled(LL_REFRESH_MED)) + { + if (minX <= maxX) + { + syslog( LOG_INFO, "%s: Row[%d] %3d - %3d : %3d" + , config->name.c_str(), yb + , minX, maxX + , maxX - minX + 1 + ); + } + else + { + syslog( LOG_INFO, "%s: Row[%d] --- - --- : ---" + , config->name.c_str(), yb + ); + } // if + } // if + + // perform refresh + if (minX <= maxX) + { + bc += cmdSetCursorPos(minX, yb * 8); + + for (xb = minX; xb <= maxX; ++xb) + { + if ((xb - minX) % chunk == 0) + { + bc += cmdGraphicWrite(std::min((maxX - xb + 1), chunk)); + } // if + + bc += cmdGraphicData(myDrawMem[xb][yb]); + myVFDMem[xb][yb] = myDrawMem[xb][yb]; + } // for + } // if + } // for + + releasePort(); + + // create log + if (isLogEnabled(LL_REFRESH_END)) + { + gettimeofday(&tv2, 0); + + long duration_ms = ((tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec)) + / 1000 /* us -> ms */ + ; + + syslog( LOG_INFO, "%s: < Refresh() all = %d took %3ld ms %5ld bytes = %5ld bytes/sec = %5ld ns/byte" + , config->name.c_str() + , refreshAll + , duration_ms + , bc + , duration_ms == 0 ? -1 : bc * 1000 / duration_ms + , bc == 0 ? -1 : duration_ms * 1000000 / bc + ); + } // if +} // cDriverGU126X64D_K610A4::Refresh() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdReset() +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 1B: CMD_RESET : 0x%02X ", int(CMD_RESET)); + } // if + + b += write(CMD_RESET); + + unsigned char aMode = 1 << 7 // data orientation : 0: horizontal, 1: vertical , default: 0 + | 0 << 6 // cursor movement : 0: horizontal, 1: vertical , default: 0 + | 0 << 5 // cursor direction : 0: forwards , 1: backwards, default: 0 + | 0 << 4 // underscore cursor: 0: off , 1: on , default: 0 + | 0 << 3 // underscore cursor: 0: static , 1: flash , default: 0 + | 0 << 2 // not in documentation + | 0 << 0 // pen type: 0: overwrite, 1: AND, 2: OR, 3: XOR , default: 0 + ; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 2B: CMD_WRITE_MODE : 0x%02X 0x%02X", int(CMD_RESET), int(aMode)); + } // if + + b += write(CMD_WRITE_MODE); + b += write(aMode); + + return b; +} // cDriverGU126X64D_K610A4::cmdReset() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdPower(bool fOn) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 2B: CMD_POWER : 0x%02X 0x%02X" + , int(CMD_INTRO), int(fOn ? CMA_POWER_ON : CMA_POWER_OFF) + ); + } // if + + b += write(CMD_INTRO); + b += write(fOn ? CMA_POWER_ON : CMA_POWER_OFF); + + return b; +} // cDriverGU126X64D_K610A4::cmdPower() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdLock(bool fLock) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 2B: CMD_LOCK : 0x%02X 0x%02X" + , int(CMD_INTRO), int(fLock ? CMA_EPROM_LOCK : CMA_EPROM_UNLOCK) + ); + } // if + + b += write(CMD_INTRO); + b += write(fLock ? CMA_EPROM_LOCK : CMA_EPROM_UNLOCK); + + return b; +} // cDriverGU126X64D_K610A4::cmdPower() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetCursorPos(unsigned char x, unsigned char y) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 3B: CMD_CURSOR_POS : 0x%02X 0x%02X 0x%02X (x = %3d, y = %3d)" + , int(CMD_CURSOR_POS), int(x), int(y), int(x), int(y) + ); + } // if + + b += write(CMD_CURSOR_POS); // cmd + b += write(x ); // xpos + b += write(y ); // ypos + + return b; +} // cDriverGU126X64D_K610A4::cmdSetCursorPos(); + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdGraphicWrite(unsigned char count) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 2B: CMD_GRAPHIC_WRITE: 0x%02X 0x%02X (%d bytes)" + , int(CMD_GRAPHIC_WRITE), int(count), int(count) + ); + } // if + + b += write(CMD_GRAPHIC_WRITE); // cmd + b += write(count ); // len + + myDataPendingCounter = count; + + return b; +} // cDriverGU126X64D_K610A4::cmdGraphicWrite() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdGraphicData(unsigned char data) +{ + int b = 0; + + myDataPendingCounter--; + if (myDataPendingCounter < 0) + { + syslog( LOG_WARNING, "%s error: more graphic data written than announced -> ignored" + , config->name.c_str() + ); + } + else + { + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 1B: CMD_GRAPHIC_DATA : 0x%02X (expecting another %d bytes)" + , int(data), myDataPendingCounter + ); + } // if + + b += write(data ^ (config->invert ? 0xFF : 0x00)); + } // if + + return b; +} // cDriverGU126X64D_K610A4::cmdGraphicData() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetBrightness(unsigned int percent) +{ + ensureNotInGraphics(); + int b = 0; + + unsigned char bright = 0; + if (percent >= 85) bright = 0xFF; + else if (percent >= 71) bright = 0xFE; + else if (percent >= 57) bright = 0xFD; + else if (percent >= 43) bright = 0xFC; + else if (percent >= 29) bright = 0xFB; + else if (percent >= 15) bright = 0xFA; + else if (percent >= 1) bright = 0xF9; + else bright = 0xF8; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 2B: CMD_INTRO : 0x%02X 0x%02X = set brightness" + , int(CMD_INTRO), int(bright) + ); + } // if + + b += write(CMD_INTRO); + b += write(bright); + + return b; +} // cDriverGU126X64D_K610A4::cmdSetBrightness() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetFont(FontType theFont) +{ + ensureNotInGraphics(); + int b = 0; + + unsigned char aCmd = 0; + switch (theFont) + { + case FONT_PROP_SML: aCmd = CMD_FONT_PROP_SML; break; + case FONT_FIX_BIG : aCmd = CMD_FONT_FIX_BIG ; break; + case FONT_FIX_MED : + default : aCmd = CMD_FONT_FIX_MED ; break; + } // switch + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 1B: CMD_SET_FONT : 0x%02X", int(aCmd)); + } // if + + b += write(aCmd); + + return b; +} // cDriverGU126X64D_K610A4::cmdSetFont() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdWriteText(const char *theText) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "-%2dB: WRITE_TEXT : '%s'", strlen(theText), theText); + } // if + + for (const char *p = theText; *p != '\0'; ++p) + { + b += write(*p); + } // for + + return b; +} // cDriverGU126X64D_K610A4::cmdWriteText() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdDrawRect(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 5B: CMD_SET_OUTLINE : 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X (x1 = %3d, y1 = %3d, x2 = %3d, y2 = %3d)" + , int(CMD_CURSOR_POS) + , int(x1), int(y1), int(x2), int(y2) + , int(x1), int(y1), int(x2), int(y2) + ); + } // if + + b += write(CMD_RECT_SET ); + b += write(x1 ); + b += write(y1 ); + b += write(x2 ); + b += write(y2 ); + + return b; +} // cDriverGU126X64D_K610A4::cmdDrawRect() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetMacro(unsigned char theMacroNum, unsigned char theCountBytes) +{ + if (theMacroNum > 7) + { + return 0; + } // if + + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 3B: CMD_INTRO : 0x%02X 0x%02X 0x%02X (define macro %d with length %d)" + , int(CMD_INTRO) + , int(theMacroNum), int(theCountBytes) + , int(theMacroNum), int(theCountBytes) + ); + } // if + + b += write(CMD_INTRO ); + b += write(theMacroNum ); + b += write(theCountBytes ); + + return b; +} // cDriverGU126X64D_K610A4::cmdSetMacro() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetPixel(bool fSet) +{ + int b = 0; + + if (fSet) + { + ensureNotInGraphics(); + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 1B: SET_PIXEL : 0x%02X", 0x16); + } // if + + b += write(CMD_PIXEL_SET); + } + else + { + b = cmdClrPixel(); + } // if + + return b; +} // cDriverGU126X64D_K610A4::cmdSetPixel() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdClrPixel() +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 1B: CLR_PIXEL : 0x%02X", 0x17); + } // if + + b += write(CMD_PIXEL_CLEAR); + + return b; +} // cDriverGU126X64D_K610A4::cmdClrPixel() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::ensureNotInGraphics() +{ + if (myClaimCounter <= 0) + { + syslog(LOG_ERR, "%s: ERROR: port not claimed (%d)", config->name.c_str(), myClaimCounter); + } // if + + if (myDataPendingCounter > 0) + { + syslog( LOG_WARNING, "%s error: expected another %d bytes graphic data, filling with 0x00" + , config->name.c_str(), myDataPendingCounter + ); + } // if + while (myDataPendingCounter > 0) + { + cmdGraphicData(0); + } // while +} // cDriverGU126X64D_K610A4::ensureNotInGraphics() + + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::claimPort() +{ + if (myClaimCounter == 0) + { + port->Claim(); + } // if + + myClaimCounter++; + + if (myClaimCounter > 1) + { + syslog( LOG_WARNING, "%s: port claimed more than once (%d)" + , config->name.c_str(), myClaimCounter + ); + } // if + +} // cDriverGU126X64D_K610A4::claimPort() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::releasePort() +{ + if (myClaimCounter == 1) + { + port->Release(); + } // if + + myClaimCounter--; + + if (myClaimCounter < 0) + { + syslog( LOG_WARNING, "%s: port released more often than claimed" + , config->name.c_str() + ); + myClaimCounter = 0; + } // if + +} // cDriverGU126X64D_K610A4::releasePort() + +//----------------------------------------------------------------------------- +bool cDriverGU126X64D_K610A4::isLogEnabled(int theLevel) const +{ + return (theLevel & myLogFlags) != 0; +} // cDriverGU126X64D_K610A4::isLogEnabled() + +//----------------------------------------------------------------------------- +} // end of namespace + -- cgit v1.2.3