graphlcd-base/glcddrivers/sed1330.c
author root@rika
Wed, 06 Feb 2008 17:32:55 +0000
changeset 4 df6a40031aa5
permissions -rw-r--r--
added graphlcd-base
root@4
     1
/*
root@4
     2
 * GraphLCD driver library
root@4
     3
 *
root@4
     4
 * sed1330.c  -  SED1330 driver class
root@4
     5
 *
root@4
     6
 * based on: hd61830.c
root@4
     7
 *  (c) 2001-2004 Carsten Siebholz <c.siebholz AT t-online.de>
root@4
     8
 *
root@4
     9
 * changes for Seiko-Epson displays: Mar 2004
root@4
    10
 *  (c) 2004 Heinz Gressenberger <heinz.gressenberger AT stmk.gv.at>
root@4
    11
 *
root@4
    12
 * init sequence taken from Thomas Baumann's LCD-Test program
root@4
    13
 *
root@4
    14
 * This file is released under the GNU General Public License. Refer
root@4
    15
 * to the COPYING file distributed with this package.
root@4
    16
 *
root@4
    17
 * (c) 2003 Roland Praml <praml.roland AT t-online.de>
root@4
    18
 */
root@4
    19
root@4
    20
#include <syslog.h>
root@4
    21
#include <sys/time.h>
root@4
    22
root@4
    23
#include "common.h"
root@4
    24
#include "config.h"
root@4
    25
#include "port.h"
root@4
    26
#include "sed1330.h"
root@4
    27
root@4
    28
root@4
    29
namespace GLCD
root@4
    30
{
root@4
    31
root@4
    32
// SED1330 Commands
root@4
    33
root@4
    34
// Command Codes, Bytes for Param
root@4
    35
root@4
    36
#define C_SYSTEMSET  0x40
root@4
    37
#define C_SLEEPIN    0x53
root@4
    38
#define C_DISPON     0x59
root@4
    39
#define C_DISPOFF    0x58
root@4
    40
#define C_SCROLL     0x44
root@4
    41
#define C_CSRFORM    0x5D
root@4
    42
#define C_CGRAMADR   0x5C
root@4
    43
#define C_CSRDIR_R   0x4C
root@4
    44
#define C_CSRDIR_L   0x4D
root@4
    45
#define C_CSRDIR_U   0x4E
root@4
    46
#define C_CSRDIR_D   0x4F
root@4
    47
#define C_HDOTSCR    0x5A
root@4
    48
#define C_OVLAY      0x5B
root@4
    49
#define C_CSRW       0x46
root@4
    50
#define C_CSRR       0x47
root@4
    51
#define C_MWRITE     0x42
root@4
    52
#define C_MREAD      0x43
root@4
    53
root@4
    54
#define M0 0
root@4
    55
// 0-internal CG ROM, 1-external CG-ROM/RAM
root@4
    56
root@4
    57
#define M1 0
root@4
    58
// 0 - 32 char CG-RAM, 1 - 64 char
root@4
    59
root@4
    60
#define M2 0
root@4
    61
// 0 - 8x8, 1 - 8x16 matrix in CG-RAM/ROM
root@4
    62
root@4
    63
#define FX 8
root@4
    64
// character-with
root@4
    65
#define FY 8
root@4
    66
// character-height
root@4
    67
#define BPC 1
root@4
    68
// byte per character, 1 - FX<=8, 2 - FX=9..16
root@4
    69
root@4
    70
#define SAD1 0x0000
root@4
    71
// startadress first screen
root@4
    72
root@4
    73
root@4
    74
const int kInterface6800 = 0;
root@4
    75
const int kInterface8080 = 1;
root@4
    76
root@4
    77
const std::string kWiringOriginal = "Original";
root@4
    78
const std::string kWiringPowerLCD = "PowerLCD";
root@4
    79
const std::string kWiringLCDProc  = "LCDProc";
root@4
    80
const std::string kWiringTweakers = "Tweakers";
root@4
    81
const std::string kWiringYASEDW   = "YASEDW";
root@4
    82
root@4
    83
const unsigned char kOriginalA0HI = kInitHigh;
root@4
    84
const unsigned char kOriginalA0LO = kInitLow;
root@4
    85
const unsigned char kOriginalRDHI = kStrobeHigh;
root@4
    86
const unsigned char kOriginalRDLO = kStrobeLow;
root@4
    87
const unsigned char kOriginalWRHI = kAutoHigh;
root@4
    88
const unsigned char kOriginalWRLO = kAutoLow;
root@4
    89
const unsigned char kOriginalCSHI = kSelectHigh;
root@4
    90
const unsigned char kOriginalCSLO = kSelectLow;
root@4
    91
root@4
    92
const unsigned char kPowerLCDA0HI = kInitHigh;
root@4
    93
const unsigned char kPowerLCDA0LO = kInitLow;
root@4
    94
const unsigned char kPowerLCDRDHI = kSelectHigh;
root@4
    95
const unsigned char kPowerLCDRDLO = kSelectLow;
root@4
    96
const unsigned char kPowerLCDWRHI = kStrobeHigh;
root@4
    97
const unsigned char kPowerLCDWRLO = kStrobeLow;
root@4
    98
const unsigned char kPowerLCDCSHI = kAutoHigh;
root@4
    99
const unsigned char kPowerLCDCSLO = kAutoLow;
root@4
   100
root@4
   101
const unsigned char kLCDProcA0HI = kSelectHigh;
root@4
   102
const unsigned char kLCDProcA0LO = kSelectLow;
root@4
   103
const unsigned char kLCDProcRDHI = kInitHigh;
root@4
   104
const unsigned char kLCDProcRDLO = kInitLow;
root@4
   105
const unsigned char kLCDProcWRHI = kAutoHigh;
root@4
   106
const unsigned char kLCDProcWRLO = kAutoLow;
root@4
   107
const unsigned char kLCDProcCSHI = kStrobeHigh;
root@4
   108
const unsigned char kLCDProcCSLO = kStrobeLow;
root@4
   109
root@4
   110
const unsigned char kTweakersA0HI = kSelectHigh;
root@4
   111
const unsigned char kTweakersA0LO = kSelectLow;
root@4
   112
const unsigned char kTweakersRDHI = kAutoHigh;
root@4
   113
const unsigned char kTweakersRDLO = kAutoLow;
root@4
   114
const unsigned char kTweakersWRHI = kInitHigh;
root@4
   115
const unsigned char kTweakersWRLO = kInitLow;
root@4
   116
const unsigned char kTweakersCSHI = kStrobeHigh;
root@4
   117
const unsigned char kTweakersCSLO = kStrobeLow;
root@4
   118
root@4
   119
const unsigned char kYASEDWA0HI = kAutoHigh;
root@4
   120
const unsigned char kYASEDWA0LO = kAutoLow;
root@4
   121
const unsigned char kYASEDWRDHI = kInitHigh;
root@4
   122
const unsigned char kYASEDWRDLO = kInitLow;
root@4
   123
const unsigned char kYASEDWWRHI = kStrobeHigh;
root@4
   124
const unsigned char kYASEDWWRLO = kStrobeLow;
root@4
   125
const unsigned char kYASEDWCSHI = kSelectHigh;
root@4
   126
const unsigned char kYASEDWCSLO = kSelectLow;
root@4
   127
root@4
   128
root@4
   129
cDriverSED1330::cDriverSED1330(cDriverConfig * config)
root@4
   130
:   config(config)
root@4
   131
{
root@4
   132
    oldConfig = new cDriverConfig(*config);
root@4
   133
root@4
   134
    port = new cParallelPort();
root@4
   135
root@4
   136
    refreshCounter = 0;
root@4
   137
}
root@4
   138
root@4
   139
cDriverSED1330::~cDriverSED1330()
root@4
   140
{
root@4
   141
    delete port;
root@4
   142
    delete oldConfig;
root@4
   143
}
root@4
   144
root@4
   145
int cDriverSED1330::Init()
root@4
   146
{
root@4
   147
    int x;
root@4
   148
    struct timeval tv1, tv2;
root@4
   149
root@4
   150
    width = config->width;
root@4
   151
    if (width <= 0)
root@4
   152
        width = 320;
root@4
   153
    height = config->height;
root@4
   154
    if (height <= 0)
root@4
   155
        height = 240;
root@4
   156
root@4
   157
    // default values
root@4
   158
    oscillatorFrequency = 9600;
root@4
   159
    interface = kInterface6800;
root@4
   160
    A0HI = kOriginalA0HI;
root@4
   161
    A0LO = kOriginalA0LO;
root@4
   162
    RDHI = kOriginalRDHI;
root@4
   163
    RDLO = kOriginalRDLO;
root@4
   164
    WRHI = kOriginalWRHI;
root@4
   165
    WRLO = kOriginalWRLO;
root@4
   166
    CSHI = kOriginalCSHI;
root@4
   167
    CSLO = kOriginalCSLO;
root@4
   168
    ENHI = RDHI;
root@4
   169
    ENLO = RDLO;
root@4
   170
    RWHI = WRHI;
root@4
   171
    RWLO = WRLO;
root@4
   172
root@4
   173
    for (unsigned int i = 0; i < config->options.size(); i++)
root@4
   174
    {
root@4
   175
        if (config->options[i].name == "Wiring")
root@4
   176
        {
root@4
   177
            if (config->options[i].value == kWiringOriginal)
root@4
   178
            {
root@4
   179
                A0HI = kOriginalA0HI;
root@4
   180
                A0LO = kOriginalA0LO;
root@4
   181
                RDHI = kOriginalRDHI;
root@4
   182
                RDLO = kOriginalRDLO;
root@4
   183
                WRHI = kOriginalWRHI;
root@4
   184
                WRLO = kOriginalWRLO;
root@4
   185
                CSHI = kOriginalCSHI;
root@4
   186
                CSLO = kOriginalCSLO;
root@4
   187
            }
root@4
   188
            else if (config->options[i].value == kWiringPowerLCD)
root@4
   189
            {
root@4
   190
                A0HI = kPowerLCDA0HI;
root@4
   191
                A0LO = kPowerLCDA0LO;
root@4
   192
                RDHI = kPowerLCDRDHI;
root@4
   193
                RDLO = kPowerLCDRDLO;
root@4
   194
                WRHI = kPowerLCDWRHI;
root@4
   195
                WRLO = kPowerLCDWRLO;
root@4
   196
                CSHI = kPowerLCDCSHI;
root@4
   197
                CSLO = kPowerLCDCSLO;
root@4
   198
            }
root@4
   199
            else if (config->options[i].value == kWiringLCDProc)
root@4
   200
            {
root@4
   201
                A0HI = kLCDProcA0HI;
root@4
   202
                A0LO = kLCDProcA0LO;
root@4
   203
                RDHI = kLCDProcRDHI;
root@4
   204
                RDLO = kLCDProcRDLO;
root@4
   205
                WRHI = kLCDProcWRHI;
root@4
   206
                WRLO = kLCDProcWRLO;
root@4
   207
                CSHI = kLCDProcCSHI;
root@4
   208
                CSLO = kLCDProcCSLO;
root@4
   209
            }
root@4
   210
            else if (config->options[i].value == kWiringTweakers)
root@4
   211
            {
root@4
   212
                A0HI = kTweakersA0HI;
root@4
   213
                A0LO = kTweakersA0LO;
root@4
   214
                RDHI = kTweakersRDHI;
root@4
   215
                RDLO = kTweakersRDLO;
root@4
   216
                WRHI = kTweakersWRHI;
root@4
   217
                WRLO = kTweakersWRLO;
root@4
   218
                CSHI = kTweakersCSHI;
root@4
   219
                CSLO = kTweakersCSLO;
root@4
   220
            }
root@4
   221
            else if (config->options[i].value == kWiringYASEDW)
root@4
   222
            {
root@4
   223
                A0HI = kYASEDWA0HI;
root@4
   224
                A0LO = kYASEDWA0LO;
root@4
   225
                RDHI = kYASEDWRDHI;
root@4
   226
                RDLO = kYASEDWRDLO;
root@4
   227
                WRHI = kYASEDWWRHI;
root@4
   228
                WRLO = kYASEDWWRLO;
root@4
   229
                CSHI = kYASEDWCSHI;
root@4
   230
                CSLO = kYASEDWCSLO;
root@4
   231
            }
root@4
   232
            else
root@4
   233
            {
root@4
   234
                syslog(LOG_ERR, "%s error: wiring %s not supported, using default (Original)!\n",
root@4
   235
                       config->name.c_str(), config->options[i].value.c_str());
root@4
   236
            }
root@4
   237
            ENHI = RDHI;
root@4
   238
            ENLO = RDLO;
root@4
   239
            RWHI = WRHI;
root@4
   240
            RWLO = WRLO;
root@4
   241
        }
root@4
   242
        else if (config->options[i].name == "OscillatorFrequency")
root@4
   243
        {
root@4
   244
            int freq = atoi(config->options[i].value.c_str());
root@4
   245
            if (freq > 1000 && freq < 15000)
root@4
   246
                oscillatorFrequency = freq;
root@4
   247
            else
root@4
   248
                syslog(LOG_ERR, "%s error: oscillator frequency %d out of range, using default (%d)!\n",
root@4
   249
                       config->name.c_str(), freq, oscillatorFrequency);
root@4
   250
        }
root@4
   251
        if (config->options[i].name == "Interface")
root@4
   252
        {
root@4
   253
            if (config->options[i].value == "6800")
root@4
   254
                interface = kInterface6800;
root@4
   255
            else if (config->options[i].value == "8080")
root@4
   256
                interface = kInterface8080;
root@4
   257
            else
root@4
   258
                syslog(LOG_ERR, "%s error: interface %s not supported, using default (6800)!\n",
root@4
   259
                       config->name.c_str(), config->options[i].value.c_str());
root@4
   260
        }
root@4
   261
    }
root@4
   262
root@4
   263
    // setup lcd array (wanted state)
root@4
   264
    newLCD = new unsigned char *[(width + 7) / 8];
root@4
   265
    if (newLCD)
root@4
   266
    {
root@4
   267
        for (x = 0; x < (width + 7) / 8; x++)
root@4
   268
        {
root@4
   269
            newLCD[x] = new unsigned char[height];
root@4
   270
            memset(newLCD[x], 0, height);
root@4
   271
        }
root@4
   272
    }
root@4
   273
    // setup lcd array (current state)
root@4
   274
    oldLCD = new unsigned char *[(width + 7) / 8];
root@4
   275
    if (oldLCD)
root@4
   276
    {
root@4
   277
        for (x = 0; x < (width + 7) / 8; x++)
root@4
   278
        {
root@4
   279
            oldLCD[x] = new unsigned char[height];
root@4
   280
            memset(oldLCD[x], 0, height);
root@4
   281
        }
root@4
   282
    }
root@4
   283
root@4
   284
    if (config->device == "")
root@4
   285
    {
root@4
   286
        // use DirectIO
root@4
   287
        if (port->Open(config->port) != 0)
root@4
   288
            return -1;
root@4
   289
        uSleep(10);
root@4
   290
    }
root@4
   291
    else
root@4
   292
    {
root@4
   293
        // use ppdev
root@4
   294
        if (port->Open(config->device.c_str()) != 0)
root@4
   295
            return -1;
root@4
   296
    }
root@4
   297
root@4
   298
    if (nSleepInit() != 0)
root@4
   299
    {
root@4
   300
        syslog(LOG_DEBUG, "%s: INFO: cannot change wait parameters (cDriver::Init)\n", config->name.c_str());
root@4
   301
        useSleepInit = false;
root@4
   302
    }
root@4
   303
    else
root@4
   304
    {
root@4
   305
        useSleepInit = true;
root@4
   306
    }
root@4
   307
root@4
   308
    syslog(LOG_DEBUG, "%s: benchmark started.\n", config->name.c_str());
root@4
   309
    gettimeofday(&tv1, 0);
root@4
   310
    for (x = 0; x < 1000; x++)
root@4
   311
    {
root@4
   312
        port->WriteData(x % 0x100);
root@4
   313
    }
root@4
   314
    gettimeofday(&tv2, 0);
root@4
   315
    if (useSleepInit)
root@4
   316
        nSleepDeInit();
root@4
   317
    timeForPortCmdInNs = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec);
root@4
   318
    syslog(LOG_DEBUG, "%s: benchmark stopped. Time for Command: %ldns\n", config->name.c_str(), timeForPortCmdInNs);
root@4
   319
root@4
   320
    // initialize graphic mode
root@4
   321
    InitGraphic();
root@4
   322
root@4
   323
    *oldConfig = *config;
root@4
   324
root@4
   325
    // clear display
root@4
   326
    Clear();
root@4
   327
    // The SED1330 can have up to 64k memory. If there is less memory
root@4
   328
    // it will be overwritten twice or more times.
root@4
   329
    WriteCmd(C_MWRITE);
root@4
   330
    for (x = 0; x < 65536; x++)
root@4
   331
        WriteData(0x00);
root@4
   332
root@4
   333
    WriteCmd(C_CSRW);
root@4
   334
    WriteData(0x00); // initializing cursor adress, low byte
root@4
   335
    WriteData(0x00); // high byte
root@4
   336
root@4
   337
    port->Release();
root@4
   338
root@4
   339
    syslog(LOG_INFO, "%s: SED1330 initialized.\n", config->name.c_str());
root@4
   340
    return 0;
root@4
   341
}
root@4
   342
root@4
   343
int cDriverSED1330::DeInit()
root@4
   344
{
root@4
   345
    int x;
root@4
   346
root@4
   347
    // free lcd array (wanted state)
root@4
   348
    if (newLCD)
root@4
   349
    {
root@4
   350
        for (x = 0; x < (width + 7) / 8; x++)
root@4
   351
        {
root@4
   352
            delete[] newLCD[x];
root@4
   353
        }
root@4
   354
        delete[] newLCD;
root@4
   355
    }
root@4
   356
    // free lcd array (current state)
root@4
   357
    if (oldLCD)
root@4
   358
    {
root@4
   359
        for (x = 0; x < (width + 7) / 8; x++)
root@4
   360
        {
root@4
   361
            delete[] oldLCD[x];
root@4
   362
        }
root@4
   363
        delete[] oldLCD;
root@4
   364
    }
root@4
   365
root@4
   366
    if (port->Close() != 0)
root@4
   367
        return -1;
root@4
   368
    return 0;
root@4
   369
}
root@4
   370
root@4
   371
int cDriverSED1330::CheckSetup()
root@4
   372
{
root@4
   373
    if (config->device != oldConfig->device ||
root@4
   374
        config->port != oldConfig->port ||
root@4
   375
        config->width != oldConfig->width ||
root@4
   376
        config->height != oldConfig->height)
root@4
   377
    {
root@4
   378
        DeInit();
root@4
   379
        Init();
root@4
   380
        return 0;
root@4
   381
    }
root@4
   382
root@4
   383
    if (config->upsideDown != oldConfig->upsideDown ||
root@4
   384
        config->invert != oldConfig->invert)
root@4
   385
    {
root@4
   386
        oldConfig->upsideDown = config->upsideDown;
root@4
   387
        oldConfig->invert = config->invert;
root@4
   388
        return 1;
root@4
   389
    }
root@4
   390
    return 0;
root@4
   391
}
root@4
   392
root@4
   393
int cDriverSED1330::InitGraphic()
root@4
   394
{
root@4
   395
    // initialize setup with two graphic screens
root@4
   396
    // most parts taken from Thomas Baumann's LCD-Test program
root@4
   397
    int cr;
root@4
   398
    int memGraph;
root@4
   399
    int sad1l, sad1h, sad2l, sad2h;
root@4
   400
root@4
   401
    cr = (width / FX - 1) * BPC;
root@4
   402
    memGraph = ((cr + 1) * height);  // required memory for a graphic layer
root@4
   403
    sad1l = SAD1 & 0xFF;
root@4
   404
    sad1h = SAD1 >> 8 & 0xFF;
root@4
   405
    sad2l = ((SAD1 + memGraph) & 0xFF);
root@4
   406
    sad2h = ((SAD1 + memGraph) >> 8 & 0xFF);
root@4
   407
root@4
   408
    WriteCmd(C_SYSTEMSET);
root@4
   409
    WriteData(0x30 + M0 + (M1 << 1) + (M2 << 2));
root@4
   410
    WriteData(0x80 + (FX - 1));
root@4
   411
    WriteData(0x00 + (FY - 1));
root@4
   412
    WriteData(cr);   // C/R .. display adresses per line
root@4
   413
    WriteData((oscillatorFrequency * 1000 / (70 * height) - 1) / 9);  // TC/R .. , fFR=70Hz
root@4
   414
    WriteData(height - 1); // L/F .. display lines per screen
root@4
   415
    WriteData(cr + 1);   // adresses per virtual display line, low byte
root@4
   416
    WriteData(0x00);   // adresses per virtual display line, high byte
root@4
   417
    // currently we don't use virtual screens greater then the display,
root@4
   418
    // therefore the high byte should always be zero
root@4
   419
root@4
   420
    WriteCmd(C_SCROLL);
root@4
   421
    WriteData(sad1l);  // low-byte startadress first layer
root@4
   422
    WriteData(sad1h);  // high-byte startadress first layer
root@4
   423
    WriteData(height); // lines per screen
root@4
   424
    WriteData(sad2l);  // low-byte startadress second layer
root@4
   425
    WriteData(sad2h);  // high-byte startadress second layer
root@4
   426
    WriteData(height); // lines per screen
root@4
   427
    WriteData(0x00); // low-byte startadress third layer, not used
root@4
   428
    WriteData(0x00); // high-byte startadress third layer, not used
root@4
   429
    WriteData(0x00); // low-byte startadress fourth layer, not used
root@4
   430
    WriteData(0x00); // high-byte startadress fourth layer, not used
root@4
   431
root@4
   432
    WriteCmd(C_CSRFORM);
root@4
   433
    WriteData(0x00); // cursor with: 1 pixel
root@4
   434
    WriteData(0x86); // cursor height: 7 lines, block mode
root@4
   435
root@4
   436
    WriteCmd(C_CSRDIR_R);  // automatic cursor increment to the right
root@4
   437
root@4
   438
    WriteCmd(C_OVLAY);
root@4
   439
    WriteData(0x0C); // two layer composition with Priority-OR
root@4
   440
root@4
   441
    WriteCmd(C_HDOTSCR);
root@4
   442
    WriteData(0x00);
root@4
   443
root@4
   444
    WriteCmd(C_DISPON);  // display ON with
root@4
   445
    WriteData(0x04); // cursor OFF and first layer ON without flashing
root@4
   446
root@4
   447
    WriteCmd(C_CSRW);
root@4
   448
    WriteData(0x00); // initializing cursor adress, low byte
root@4
   449
    WriteData(0x00); // high byte
root@4
   450
root@4
   451
    return 0;
root@4
   452
}
root@4
   453
root@4
   454
void cDriverSED1330::WriteCmd(unsigned char cmd)
root@4
   455
{
root@4
   456
    //if (useSleepInit)
root@4
   457
    //    nSleepInit();
root@4
   458
root@4
   459
    if (interface == kInterface6800)
root@4
   460
    {
root@4
   461
        // set A0 high (instruction), RW low (write) and E low
root@4
   462
        port->WriteControl(A0HI | CSLO | RWLO | ENLO);
root@4
   463
        //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   464
        // Output the actual command
root@4
   465
        port->WriteData(cmd);
root@4
   466
        //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   467
        // set E high
root@4
   468
        port->WriteControl(A0HI | CSLO | RWLO | ENHI);
root@4
   469
        //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   470
        // set E low
root@4
   471
        port->WriteControl(A0HI | CSLO | RWLO | ENLO);
root@4
   472
        //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   473
    }
root@4
   474
    else
root@4
   475
    {
root@4
   476
        // set A0 high (instruction), CS low, RD and WR high
root@4
   477
        port->WriteControl(A0HI | CSLO | RDHI | WRHI);
root@4
   478
        //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   479
        // Output the actual command
root@4
   480
        port->WriteData(cmd);
root@4
   481
        //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   482
        // set WR low
root@4
   483
        port->WriteControl(A0HI | CSLO | RDHI | WRLO);
root@4
   484
        //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   485
        // set WR high
root@4
   486
        port->WriteControl(A0HI | CSLO | RDHI | WRHI);
root@4
   487
        //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   488
    }
root@4
   489
root@4
   490
    //if (useSleepInit)
root@4
   491
    //    nSleepDeInit();
root@4
   492
}
root@4
   493
root@4
   494
void cDriverSED1330::WriteData(unsigned char data)
root@4
   495
{
root@4
   496
    //if (useSleepInit)
root@4
   497
    //    nSleepInit();
root@4
   498
root@4
   499
    if (interface == kInterface6800)
root@4
   500
    {
root@4
   501
        // set A0 low (data), RW low (write) and E low
root@4
   502
        port->WriteControl(A0LO | CSLO | RWLO | ENLO);
root@4
   503
        //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   504
        // Output the actual data
root@4
   505
        port->WriteData(data);
root@4
   506
        //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   507
        // set E high
root@4
   508
        port->WriteControl(A0LO | CSLO | RWLO | ENHI);
root@4
   509
        //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   510
        // set E low
root@4
   511
        port->WriteControl(A0LO | CSLO | RWLO | ENLO);
root@4
   512
        //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   513
    }
root@4
   514
    else
root@4
   515
    {
root@4
   516
        // set A0 low (data), CS low, RD and WR high
root@4
   517
        port->WriteControl(A0LO | CSLO | RDHI | WRHI);
root@4
   518
        //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   519
        // Output the actual data
root@4
   520
        port->WriteData(data);
root@4
   521
        //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   522
        // set WR low
root@4
   523
        port->WriteControl(A0LO | CSLO | RDHI | WRLO);
root@4
   524
        //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   525
        // set WR high
root@4
   526
        port->WriteControl(A0LO | CSLO | RDHI | WRHI);
root@4
   527
        //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming);
root@4
   528
    }
root@4
   529
root@4
   530
    //if (useSleepInit)
root@4
   531
    //    nSleepDeInit();
root@4
   532
}
root@4
   533
root@4
   534
void cDriverSED1330::Clear()
root@4
   535
{
root@4
   536
    for (int x = 0; x < (width + 7) / 8; x++)
root@4
   537
        memset(newLCD[x], 0, height);
root@4
   538
}
root@4
   539
root@4
   540
void cDriverSED1330::Set8Pixels(int x, int y, unsigned char data)
root@4
   541
{
root@4
   542
    if (x >= width || y >= height)
root@4
   543
        return;
root@4
   544
root@4
   545
    if (!config->upsideDown)
root@4
   546
    {
root@4
   547
        // normal orientation
root@4
   548
        newLCD[x / 8][y] = newLCD[x / 8][y] | data;
root@4
   549
    }
root@4
   550
    else
root@4
   551
    {
root@4
   552
        // upside down orientation
root@4
   553
        x = width - 1 - x;
root@4
   554
        y = height - 1 - y;
root@4
   555
        newLCD[x / 8][y] = newLCD[x / 8][y] | ReverseBits(data);
root@4
   556
    }
root@4
   557
}
root@4
   558
root@4
   559
void cDriverSED1330::Refresh(bool refreshAll)
root@4
   560
{
root@4
   561
    int x;
root@4
   562
    int y;
root@4
   563
    int pos = SAD1;
root@4
   564
root@4
   565
    if (CheckSetup() > 0)
root@4
   566
        refreshAll = true;
root@4
   567
root@4
   568
    if (config->refreshDisplay > 0)
root@4
   569
    {
root@4
   570
        refreshCounter = (refreshCounter + 1) % config->refreshDisplay;
root@4
   571
        if (!refreshAll && !refreshCounter)
root@4
   572
            refreshAll = true;
root@4
   573
    }
root@4
   574
root@4
   575
    port->Claim();
root@4
   576
root@4
   577
    if (refreshAll)
root@4
   578
    {
root@4
   579
        // draw all
root@4
   580
        // set cursor to startadress
root@4
   581
        WriteCmd(C_CSRW);
root@4
   582
        WriteData(pos & 0xFF);
root@4
   583
        WriteData(pos >> 8);
root@4
   584
root@4
   585
        for (y = 0; y < height; y++)
root@4
   586
        {
root@4
   587
            for (x = 0; x < (width + 7) / 8; x++)
root@4
   588
            {
root@4
   589
                WriteCmd(C_MWRITE); // cursor increments automatically
root@4
   590
                WriteData(newLCD[x][y] ^ (config->invert ? 0xff : 0x00));
root@4
   591
                oldLCD[x][y] = newLCD[x][y];
root@4
   592
                pos++;
root@4
   593
            }
root@4
   594
        }
root@4
   595
        // and reset RefreshCounter
root@4
   596
        refreshCounter = 0;
root@4
   597
    }
root@4
   598
    else
root@4
   599
    {
root@4
   600
        // draw only the changed bytes
root@4
   601
        bool cs = false;
root@4
   602
        for (y = 0; y < height; y++)
root@4
   603
        {
root@4
   604
            for (x = 0; x < (width + 7) / 8; x++)
root@4
   605
            {
root@4
   606
                if (newLCD[x][y] != oldLCD[x][y])
root@4
   607
                {
root@4
   608
                    if (!cs)
root@4
   609
                    {
root@4
   610
                        WriteCmd(C_CSRW);
root@4
   611
                        WriteData(pos & 0xFF);
root@4
   612
                        WriteData(pos >> 8);
root@4
   613
                        WriteCmd(C_MWRITE);
root@4
   614
                        cs = true;
root@4
   615
                    }
root@4
   616
                    WriteData(newLCD[x][y] ^ (config->invert ? 0xff : 0x00));
root@4
   617
                    oldLCD[x][y] = newLCD[x][y];
root@4
   618
                }
root@4
   619
                else
root@4
   620
                {
root@4
   621
                    cs = false;
root@4
   622
                }
root@4
   623
                pos++;
root@4
   624
            }
root@4
   625
        }
root@4
   626
    }
root@4
   627
    port->Release();
root@4
   628
}
root@4
   629
root@4
   630
} // end of namespace