~benklop/+junk/lcdproc

« back to all changes in this revision

Viewing changes to server/drivers/CwLnx.c

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy Yoder (Launchpad)
  • Date: 2009-10-11 18:21:07 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20091011182107-twnkyhv1f63lzq3o
Tags: 0.5.3-0ubuntu1
* New upstream version 0.5.3 (LP: #432669)
* Merge source patches from 0.5.2-3 
  - LCDd.conf: Change driver path
  - clients/lcdproc/machine_Linux.c: Change ifdef
* Add clients/examples/lcdident.pl to debian files 
* Updated debian/rules:
  - Cleaned up whitespace
  - Changed config.guess/config.sub lines 
* Added a delay to server/drivers/imonlcd.c for slower models
* Added dependency on autotools-dev to fix launchpad build issue 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  This is the LCDproc driver for Cwlinux devices (http://www.cwlinux.com)
 
1
/** \file server/drivers/CwLnx.c
 
2
 *  LCDd \c CwLnx driver for CwLinux devices (http://www.cwlinux.com).
 
3
 */
2
4
 
3
 
    Applicable Data Sheets:
 
5
/* Applicable Data Sheets:
4
6
    - http://www.cwlinux.com/downloads/cw1602/cw1602-manual.pdf
5
7
    - http://www.cwlinux.com/downloads/lcd/cw12232-manual.pdf
6
8
 
7
9
        Copyright (C) 2002, Andrew Ip
8
10
                      2003, David Glaude
9
 
                      2006,7 Peter Marschall
 
11
                      2006,7,8 Peter Marschall
10
12
 
11
13
    This program is free software; you can redistribute it and/or modify
12
14
    it under the terms of the GNU General Public License as published by
84
86
} CGmode;
85
87
 
86
88
 
87
 
typedef struct driver_private_data {
 
89
/** private data for the \c CwLnx driver */
 
90
typedef struct CwLnx_private_data {
88
91
        int fd;
89
92
 
90
93
        int have_keypad;
122
125
static void CwLnx_linewrap(int fd, int on);
123
126
static void CwLnx_autoscroll(int fd, int on);
124
127
static void CwLnx_hidecursor(int fd);
 
128
static void CwLnx_set_char_unrestricted(Driver *drvthis, int n, unsigned char *dat);
125
129
 
126
130
 
127
131
#define LCD_CMD                 254
132
136
#define LCD_LIGHT_OFF           70
133
137
#define LCD_LIGHT_BRIGHTNESS    65
134
138
#define LCD_CLEAR               88
135
 
#define LCD_SET_INSERT          71
136
 
#define LCD_INIT_INSERT         72
 
139
#define LCD_SET_INSERT          71      /* go to X,Y */
 
140
#define LCD_INIT_INSERT         72      /* go to home */
137
141
#define LCD_SET_BAUD            57
138
142
#define LCD_ENABLE_WRAP         67
139
143
#define LCD_DISABLE_WRAP        68
140
144
#define LCD_SETCHAR             78
141
145
#define LCD_ENABLE_SCROLL       81
142
146
#define LCD_DISABLE_SCROLL      82
143
 
#define LCD_OFF_CURSOR          72
 
147
#define LCD_SOFT_RESET          86
 
148
#define LCD_OFF_CURSOR          72      /* is this correct? */
 
149
#define LCD_UNDERLINE_CURSOR_ON 74      /* set cursor on at X,Y */
 
150
#define LCD_UNDERLINE_CURSOR_OFF        75
 
151
#define LCD_MOVE_CURSOR_LEFT    76
 
152
#define LCD_MOVE_CURSOR_RIGHT   77
 
153
#define LCD_INVERSE_TEXT_ON     102
 
154
#define LCD_INVERSE_TEXT_OFF    103
144
155
 
145
156
#define LCD_PUT_PIXEL           112
146
157
#define LCD_CLEAR_PIXEL         113
147
158
 
148
159
#define DELAY                   2000    /* 2 milli sec */
149
 
#define UPDATE_DELAY            0       /* 1 imicro sec */
150
 
#define SETUP_DELAY             1       /* 2 micro sec */
151
 
 
152
 
 
 
160
#define UPDATE_DELAY            20000   /* 20 milliseconds */
 
161
#define SETUP_DELAY             20000   /* 20 milliseconds */
 
162
 
 
163
#define MOVE_COST               5       /* # bytes for most move-to ops */
153
164
 
154
165
static int Write_LCD(int fd, char *c, int size)
155
166
{
156
 
    int rc;
 
167
    int rc, wrote = 0;
157
168
    int retries = 30;
158
169
 
159
170
    do {
160
171
        rc = write(fd, c, size);
161
 
        if (rc == size)
 
172
        if (rc > 0) {
 
173
            c += rc;
 
174
            size -= rc;
 
175
            wrote += rc;
 
176
        } else if (rc == 0 || (rc < 0 && errno == EAGAIN)) { /* would have blocked */
 
177
            usleep(DELAY);
 
178
        } else {
162
179
            break;
163
 
        usleep(DELAY);
 
180
        }
 
181
    } while (size > 0 && --retries > 0);
164
182
        
165
 
    } while (--retries > 0);
166
 
 
167
 
    return rc;
 
183
    return wrote;
168
184
}
169
185
 
170
186
 
289
305
 
290
306
 
291
307
/* Hardware function */
292
 
static void Init_Port(fd)
 
308
static void Init_Port(int fd)
293
309
{
294
310
    /* Posix - set baudrate to 0 and back */
295
311
    struct termios tty, old;
392
408
static void
393
409
CwLnx_hidecursor(int fd)
394
410
{
395
 
        Disable_Cursor(fd);
 
411
    Disable_Cursor(fd);
 
412
}
 
413
 
 
414
 
 
415
/********************************************************************
 
416
 * Reset the display bios
 
417
 */
 
418
static void CwLnx_reboot(int fd)
 
419
{
 
420
    char cmd[] = { LCD_CMD, LCD_SOFT_RESET, LCD_CMD_END };
 
421
 
 
422
    Write_LCD(fd, cmd, 3);
 
423
    usleep(SETUP_DELAY);
 
424
    return;
396
425
}
397
426
 
398
427
 
410
439
MODULE_EXPORT int
411
440
CwLnx_init(Driver *drvthis)
412
441
{
413
 
    struct termios portset_save;
414
 
 
415
442
    char device[200] = DEFAULT_DEVICE;
416
443
    int speed = DEFAULT_SPEED;
417
444
    char size[200] = DEFAULT_SIZE;
449
476
 
450
477
    /* Read config file */
451
478
 
452
 
    /* Which model is it (1602 or 12232)? */
 
479
    /* Which model is it (1602, 12232 or 12832)? */
453
480
    tmp = drvthis->config_get_int(drvthis->name, "Model", 0, 12232);
454
481
    debug(RPT_INFO, "%s: Model (in config) is '%d'", __FUNCTION__, tmp);
455
 
    if ((tmp != 1602) && (tmp != 12232)) {
 
482
    if ((tmp != 1602) && (tmp != 12232) && (tmp != 12832)) {
456
483
        tmp = 12232;
457
 
        report(RPT_WARNING, "%s: Model must be 12232 or 1602; using default %d",
 
484
        report(RPT_WARNING, "%s: Model must be 12232, 12832 or 1602; using default %d",
458
485
                drvthis->name, tmp);
459
486
    }
460
487
    p->model = tmp;
470
497
        default_speed = DEFAULT_SPEED_12232;
471
498
        p->cellwidth = DEFAULT_CELL_WIDTH_12232;
472
499
        p->cellheight = DEFAULT_CELL_HEIGHT_12232;
 
500
    } else if (p->model == 12832) {
 
501
        default_size = DEFAULT_SIZE_12832;
 
502
        default_speed = DEFAULT_SPEED_12832;
 
503
        p->cellwidth = DEFAULT_CELL_WIDTH_12832;
 
504
        p->cellheight = DEFAULT_CELL_HEIGHT_12832;
473
505
    }
474
506
 
475
507
    /* Which device should be used */
576
608
    }
577
609
    report(RPT_INFO, "%s: opened display on %s", drvthis->name, device);
578
610
 
 
611
    /* 
 
612
       Since we don't know what speed the display is using when
 
613
       we first connect to it, configure the port for the speed
 
614
       we don't want to use, send a command to switch the display
 
615
       to the speed we want to use, and flush the command.
 
616
    */
 
617
 
579
618
    Init_Port(p->fd);
580
 
    tcgetattr(p->fd, &portset_save);
581
 
    speed = B19200;
582
 
    Setup_Port(p->fd, speed);
 
619
    if (speed == B9600) {
 
620
        Setup_Port(p->fd, B19200);
583
621
    Set_9600(p->fd); 
584
 
    close(p->fd);
585
 
 
586
 
    p->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
587
 
    if (p->fd == -1) {
588
 
        report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, device, strerror(errno));
589
 
        return -1;
 
622
    } else {
 
623
        Setup_Port(p->fd, B9600);
 
624
        Set_19200(p->fd);
590
625
    }
591
 
    report(RPT_INFO, "%s: opened display on %s", drvthis->name, device);
592
 
 
 
626
    tcdrain(p->fd);
 
627
    usleep(SETUP_DELAY);
593
628
    Init_Port(p->fd);
594
 
    speed = B9600; 
595
629
    Setup_Port(p->fd, speed);
 
630
 
596
631
    CwLnx_hidecursor(p->fd);
597
632
    CwLnx_linewrap(p->fd, 1);
598
633
    CwLnx_autoscroll(p->fd, 0);
712
747
    PrivateData *p = drvthis->private_data;
713
748
 
714
749
    int i, j;
715
 
    int move = 1;
 
750
    int iUpdate = 0, jUpdate = 0;
 
751
    unsigned char *firstUpdate = NULL, *lastUpdate = NULL;
716
752
 
717
753
    unsigned char *q = p->framebuf;
718
754
    unsigned char *r = p->backingstore;
720
756
    for (i = 0; i < p->height; i++) {
721
757
        for (j = 0; j < p->width; j++) {
722
758
            if ((*q == *r) && !((0 < *q) && (*q < 16))) {
723
 
                move = 1;
724
 
            }
725
 
            else {
726
 
                /* Draw characters that have changed, as well
727
 
                 * as custom characters.  We know not if a custom
728
 
                 * character has changed.  */ 
729
 
                if (move == 1) {
730
 
                    Set_Insert(p->fd, i, j);
731
 
                    move = 0;
732
 
                }
733
 
                Write_LCD(p->fd, (char *) q, 1);
 
759
                if (firstUpdate && q - lastUpdate > MOVE_COST) {
 
760
                    Set_Insert(p->fd, iUpdate, jUpdate);
 
761
                    Write_LCD(p->fd, (char *) firstUpdate,
 
762
                          lastUpdate - firstUpdate + 1);                
 
763
                    firstUpdate = lastUpdate = NULL;
 
764
                }
 
765
            } else {
 
766
                lastUpdate = q;
 
767
                if (!firstUpdate) {
 
768
                    firstUpdate = q;
 
769
                    iUpdate = i;
 
770
                    jUpdate = j;
 
771
                }
734
772
            }
735
773
            q++;
736
774
            r++; 
737
775
        }
738
776
    }
 
777
    if (firstUpdate) {
 
778
        Set_Insert(p->fd, iUpdate, jUpdate);
 
779
        Write_LCD(p->fd, (char *) firstUpdate,
 
780
                lastUpdate - firstUpdate + 1);
 
781
    }
 
782
 
739
783
    memcpy(p->backingstore, p->framebuf, p->width * p->height);
 
784
 
 
785
    if (p->backlight != p->saved_backlight ||
 
786
        p->brightness != p->saved_brightness) {
 
787
        if (!p->backlight) {
 
788
            Backlight_Brightness(p->fd, 1);
 
789
        } else {
 
790
            Backlight_Brightness(p->fd, 1 + p->brightness * 6 / 900); /* 90% and up is full brightness */
 
791
        }
 
792
        p->saved_backlight = p->backlight;
 
793
        p->saved_brightness = p->brightness;
 
794
    }
740
795
}
741
796
 
742
 
 
743
797
/**
744
798
 * Print a character on the screen at position (x,y).
745
799
 * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height).
904
958
        for (i = 1; i <= p->cellwidth; i++) {
905
959
            // fill pixel columns from left to right.
906
960
            memset(hBar, 0xFF & ~((1 << (p->cellwidth - i)) - 1), sizeof(hBar));
 
961
#if defined(SEAMLESS_HBARS)
 
962
            CwLnx_set_char_unrestricted(drvthis, i+1, hBar);
 
963
#else
907
964
            CwLnx_set_char(drvthis, i+1, hBar);
 
965
#endif
908
966
        }
909
967
    }
910
968
 
996
1054
            c = dat[row] & mask;
997
1055
            Write_LCD(p->fd, &c, 1);
998
1056
        }
999
 
    } else if (p->model == 12232) {     // the graphical model
 
1057
    } else if ((p->model == 12232) || (p->model == 12832)) {    // graphical models
1000
1058
        int col;
1001
1059
 
1002
1060
        for (col = p->cellwidth - 1; col >= 0; col--) {
1020
1078
}
1021
1079
 
1022
1080
 
 
1081
/*
 
1082
 * Identical to CwLnx_set_char, but it doesn't restrict the 12232 to
 
1083
 * using only 5 of its 6 columns.  Full 6-column mode is required
 
1084
 * for seamless H-bars.
 
1085
 */
 
1086
 
 
1087
#if defined(SEAMLESS_HBARS)
 
1088
static void
 
1089
CwLnx_set_char_unrestricted(Driver *drvthis, int n, unsigned char *dat)
 
1090
{
 
1091
    PrivateData *p = drvthis->private_data;
 
1092
 
 
1093
    char c;
 
1094
    int rc;
 
1095
 
 
1096
    if ((n <= 0) || (n > CwLnx_get_free_chars(drvthis)))
 
1097
        return;
 
1098
    if (!dat)
 
1099
        return;
 
1100
 
 
1101
    c = LCD_CMD;
 
1102
    rc = Write_LCD(p->fd, &c, 1);
 
1103
    c = LCD_SETCHAR;
 
1104
    rc = Write_LCD(p->fd, &c, 1);
 
1105
    c = (char) n;
 
1106
    rc = Write_LCD(p->fd, &c, 1);
 
1107
 
 
1108
    if (p->model == 1602) {     // the character model
 
1109
        unsigned char mask = (1 << p->cellwidth) - 1;
 
1110
        int row;
 
1111
 
 
1112
        for (row = 0; row < p->cellheight; row++) {
 
1113
            c = dat[row] & mask;
 
1114
            Write_LCD(p->fd, &c, 1);
 
1115
        }
 
1116
    } else if ((p->model == 12232) || (p->model == 12832)) {    // graphical models
 
1117
        int col;
 
1118
 
 
1119
        for (col = p->cellwidth - 1; col >= 0; col--) {
 
1120
            int letter = 0;
 
1121
            int row;
 
1122
 
 
1123
            for (row = p->cellheight - 1; row >= 0; row--) {
 
1124
                letter <<= 1;
 
1125
                letter |= ((dat[row] >> col) & 1);
 
1126
            }
 
1127
 
 
1128
            c = letter;
 
1129
 
 
1130
            Write_LCD(p->fd, &c, 1);
 
1131
        }
 
1132
    }
 
1133
 
 
1134
    c = LCD_CMD_END;
 
1135
    rc = Write_LCD(p->fd, &c, 1);
 
1136
}
 
1137
#endif
 
1138
 
 
1139
 
1023
1140
/**
1024
1141
 * Place an icon on the screen.
1025
1142
 * \param drvthis  Pointer to driver structure.
1026
1143
 * \param x        Horizontal character position (column).
1027
1144
 * \param y        Vertical character position (row).
1028
1145
 * \param icon     synbolic value representing the icon.
1029
 
 * \return  Information whether the icon is handled here or needs to be handled by the server core.
 
1146
 * \retval 0       Icon has been successfully defined/written.
 
1147
 * \retval <0      Server core shall define/write the icon.
1030
1148
 */
1031
1149
MODULE_EXPORT int 
1032
1150
CwLnx_icon(Driver *drvthis, int x, int y, int icon)
1267
1385
 
1268
1386
 
1269
1387
/**
1270
 
 * Get next key from the KeyRing.
 
1388
 * Get key from the device.
1271
1389
 * \param drvthis  Pointer to driver structure.
1272
 
 * \return  String representation of the key.
 
1390
 * \return         String representation of the key;
 
1391
 *                 \c NULL if nothing available / unmapped key.
1273
1392
 */
1274
1393
MODULE_EXPORT const char *
1275
1394
CwLnx_get_key(Driver *drvthis)