~siretart/lcd4linux/debian

« back to all changes in this revision

Viewing changes to drv_picoLCDGraphic.c

  • Committer: Reinhard Tartler
  • Date: 2011-04-27 17:24:15 UTC
  • mto: This revision was merged to the branch mainline in revision 750.
  • Revision ID: siretart@tauware.de-20110427172415-6n4aptmvmz0eztvm
Tags: upstream-0.11.0~svn1143
ImportĀ upstreamĀ versionĀ 0.11.0~svn1143

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: drv_picoLCDGraphic.c 1143 2011-02-12 22:46:19Z mzuther $
 
2
 * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/drv_picoLCDGraphic.c $
 
3
 *
 
4
 * driver for picoLCD Graphic(256x64) displays from mini-box.com
 
5
 *
 
6
 * Copyright (C) 2005 Michael Reinelt <michael@reinelt.co.at>
 
7
 * Copyright (C) 2005, 2006, 2007 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
 
8
 *
 
9
 * Copyright (C) 2009 Nicu Pavel, Mini-Box.com <npavel@mini-box.com>
 
10
 *
 
11
 * This file is part of LCD4Linux.
 
12
 *
 
13
 * LCD4Linux is free software; you can redistribute it and/or modify
 
14
 * it under the terms of the GNU General Public License as published by
 
15
 * the Free Software Foundation; either version 2, or (at your option)
 
16
 * any later version.
 
17
 *
 
18
 * LCD4Linux is distributed in the hope that it will be useful,
 
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
 * GNU General Public License for more details.
 
22
 *
 
23
 * You should have received a copy of the GNU General Public License
 
24
 * along with this program; if not, write to the Free Software
 
25
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
26
 *
 
27
 */
 
28
 
 
29
/* 
 
30
 *
 
31
 * exported fuctions:
 
32
 *
 
33
 * struct DRIVER drv_picoLCDGraphic
 
34
 *
 
35
 */
 
36
 
 
37
#include "config.h"
 
38
 
 
39
#include <stdlib.h>
 
40
#include <stdio.h>
 
41
#include <string.h>
 
42
#include <errno.h>
 
43
#include <unistd.h>
 
44
#include <termios.h>
 
45
#include <fcntl.h>
 
46
#include <sys/ioctl.h>
 
47
#include <sys/time.h>
 
48
 
 
49
#include <usb.h>
 
50
 
 
51
#include "debug.h"
 
52
#include "cfg.h"
 
53
#include "qprintf.h"
 
54
#include "udelay.h"
 
55
#include "plugin.h"
 
56
#include "timer.h"
 
57
#include "widget.h"
 
58
#include "widget_text.h"
 
59
#include "widget_icon.h"
 
60
#include "widget_bar.h"
 
61
#include "widget_keypad.h"
 
62
#include "drv.h"
 
63
#include "drv_generic_gpio.h"
 
64
#include "drv_generic_keypad.h"
 
65
#include "drv_generic_graphic.h"
 
66
 
 
67
 
 
68
 
 
69
#define picoLCD_VENDOR  0x04d8
 
70
#define picoLCD_DEVICE  0xc002
 
71
 
 
72
#define OUT_REPORT_LED_STATE            0x81
 
73
#define OUT_REPORT_LCD_BACKLIGHT        0x91
 
74
#define OUT_REPORT_LCD_CONTRAST         0x92
 
75
 
 
76
#define OUT_REPORT_CMD                  0x94
 
77
#define OUT_REPORT_DATA                 0x95
 
78
#define OUT_REPORT_CMD_DATA             0x96
 
79
 
 
80
#define SCREEN_H                        64
 
81
#define SCREEN_W                        256
 
82
 
 
83
 
 
84
#if 1
 
85
#define DEBUG(x) debug("%s(): %s", __FUNCTION__, x);
 
86
#else
 
87
#define DEBUG(x)
 
88
#endif
 
89
 
 
90
/* "dirty" marks the display to be redrawn from frame buffer */
 
91
static int dirty = 1;
 
92
 
 
93
/* timer for display redraw (set to zero for "direct updates") */
 
94
static int update = 0;
 
95
 
 
96
/* USB read timeout in ms (the picoLCD 256x64 times out on every read
 
97
        unless a key has been pressed!)  */
 
98
static int read_timeout = 0;
 
99
 
 
100
static char Name[] = "picoLCDGraphic";
 
101
static unsigned char *pLG_framebuffer;
 
102
 
 
103
/* used to display white text on black background or inverse */
 
104
unsigned char inverted = 0;
 
105
 
 
106
static unsigned int gpo = 0;
 
107
 
 
108
static char *Buffer;
 
109
static char *BufPtr;
 
110
 
 
111
static usb_dev_handle *lcd;
 
112
//extern int usb_debug;
 
113
int usb_debug;
 
114
 
 
115
 
 
116
/****************************************/
 
117
/***  hardware dependant functions    ***/
 
118
/****************************************/
 
119
 
 
120
static int drv_pLG_open(void)
 
121
{
 
122
    struct usb_bus *busses, *bus;
 
123
    struct usb_device *dev;
 
124
    char driver[1024];
 
125
    char product[1024];
 
126
    char manufacturer[1024];
 
127
    char serialnumber[1024];
 
128
    int ret;
 
129
 
 
130
    lcd = NULL;
 
131
 
 
132
    info("%s: scanning for picoLCD 256x64...", Name);
 
133
 
 
134
    usb_debug = 0;
 
135
 
 
136
    usb_init();
 
137
    usb_find_busses();
 
138
    usb_find_devices();
 
139
    busses = usb_get_busses();
 
140
 
 
141
    for (bus = busses; bus; bus = bus->next) {
 
142
        for (dev = bus->devices; dev; dev = dev->next) {
 
143
            if ((dev->descriptor.idVendor == picoLCD_VENDOR) && (dev->descriptor.idProduct == picoLCD_DEVICE)) {
 
144
 
 
145
                info("%s: found picoLCD on bus %s device %s", Name, bus->dirname, dev->filename);
 
146
 
 
147
                lcd = usb_open(dev);
 
148
 
 
149
                ret = usb_get_driver_np(lcd, 0, driver, sizeof(driver));
 
150
 
 
151
                if (ret == 0) {
 
152
                    info("%s: interface 0 already claimed by '%s'", Name, driver);
 
153
                    info("%s: attempting to detach driver...", Name);
 
154
                    if (usb_detach_kernel_driver_np(lcd, 0) < 0) {
 
155
                        error("%s: usb_detach_kernel_driver_np() failed!", Name);
 
156
                        return -1;
 
157
                    }
 
158
                }
 
159
 
 
160
                usb_set_configuration(lcd, 1);
 
161
                usleep(100);
 
162
 
 
163
                if (usb_claim_interface(lcd, 0) < 0) {
 
164
                    error("%s: usb_claim_interface() failed!", Name);
 
165
                    return -1;
 
166
                }
 
167
 
 
168
                usb_set_altinterface(lcd, 0);
 
169
 
 
170
                usb_get_string_simple(lcd, dev->descriptor.iProduct, product, sizeof(product));
 
171
                usb_get_string_simple(lcd, dev->descriptor.iManufacturer, manufacturer, sizeof(manufacturer));
 
172
                usb_get_string_simple(lcd, dev->descriptor.iSerialNumber, serialnumber, sizeof(serialnumber));
 
173
 
 
174
                info("%s: Manufacturer='%s' Product='%s' SerialNumber='%s'", Name, manufacturer, product, serialnumber);
 
175
 
 
176
                return 0;
 
177
            }
 
178
        }
 
179
    }
 
180
    error("%s: could not find a picoLCD", Name);
 
181
    return -1;
 
182
}
 
183
 
 
184
static int drv_pLG_read(unsigned char *data, int size)
 
185
{
 
186
    return usb_interrupt_read(lcd, USB_ENDPOINT_IN + 1, (char *) data, size, read_timeout);
 
187
}
 
188
 
 
189
 
 
190
static void drv_pLG_send(unsigned char *data, int size)
 
191
{
 
192
    int ret;
 
193
    ret = usb_interrupt_write(lcd, USB_ENDPOINT_OUT + 1, (char *) data, size, 1000);
 
194
    //fprintf(stderr, "%s written %d bytes\n", __FUNCTION__, ret);
 
195
}
 
196
 
 
197
static int drv_pLG_close(void)
 
198
{
 
199
    usb_release_interface(lcd, 0);
 
200
    usb_close(lcd);
 
201
 
 
202
    return 0;
 
203
}
 
204
 
 
205
static void drv_pLG_update_img()
 
206
{
 
207
    unsigned char cmd3[64] = { OUT_REPORT_CMD_DATA };   /* send command + data */
 
208
    unsigned char cmd4[64] = { OUT_REPORT_DATA };       /* send data only */
 
209
 
 
210
    int index, bit, x, y;
 
211
    unsigned char cs, line;
 
212
    unsigned char pixel;
 
213
 
 
214
    /* do not redraw display if frame buffer has not changed, unless
 
215
       "direct updates" have been requested (update is zero) */
 
216
    if ((!dirty) && (update > 0)) {
 
217
        debug("Skipping %s\n", __FUNCTION__);
 
218
        return;
 
219
    }
 
220
 
 
221
    debug("In %s\n", __FUNCTION__);
 
222
 
 
223
    for (cs = 0; cs < 4; cs++) {
 
224
        unsigned char chipsel = (cs << 2);      //chipselect
 
225
        for (line = 0; line < 8; line++) {
 
226
            //ha64_1.setHIDPkt(OUT_REPORT_CMD_DATA, 8+3+32, 8, chipsel, 0x02, 0x00, 0x00, 0xb8|j, 0x00, 0x00, 0x40);
 
227
            cmd3[0] = OUT_REPORT_CMD_DATA;
 
228
            cmd3[1] = chipsel;
 
229
            cmd3[2] = 0x02;
 
230
            cmd3[3] = 0x00;
 
231
            cmd3[4] = 0x00;
 
232
            cmd3[5] = 0xb8 | line;
 
233
            cmd3[6] = 0x00;
 
234
            cmd3[7] = 0x00;
 
235
            cmd3[8] = 0x40;
 
236
            cmd3[9] = 0x00;
 
237
            cmd3[10] = 0x00;
 
238
            cmd3[11] = 32;
 
239
 
 
240
            //ha64_2.setHIDPkt(OUT_REPORT_DATA, 4+32, 4, chipsel | 0x01, 0x00, 0x00, 32);
 
241
 
 
242
            cmd4[0] = OUT_REPORT_DATA;
 
243
            cmd4[1] = chipsel | 0x01;
 
244
            cmd4[2] = 0x00;
 
245
            cmd4[3] = 0x00;
 
246
            cmd4[4] = 32;
 
247
 
 
248
            for (index = 0; index < 32; index++) {
 
249
                pixel = 0x00;
 
250
 
 
251
                for (bit = 0; bit < 8; bit++) {
 
252
                    x = cs * 64 + index;
 
253
                    y = (line * 8 + bit + 0) % SCREEN_H;
 
254
 
 
255
                    if (pLG_framebuffer[y * 256 + x] ^ inverted)
 
256
                        pixel |= (1 << bit);
 
257
                }
 
258
                cmd3[12 + index] = pixel;
 
259
            }
 
260
 
 
261
            for (index = 32; index < 64; index++) {
 
262
                pixel = 0x00;
 
263
 
 
264
                for (bit = 0; bit < 8; bit++) {
 
265
                    x = cs * 64 + index;
 
266
                    y = (line * 8 + bit + 0) % SCREEN_H;
 
267
                    if (pLG_framebuffer[y * 256 + x] ^ inverted)
 
268
                        pixel |= (1 << bit);
 
269
                }
 
270
 
 
271
                cmd4[5 + (index - 32)] = pixel;
 
272
            }
 
273
 
 
274
            drv_pLG_send(cmd3, 44);
 
275
            drv_pLG_send(cmd4, 38);
 
276
        }
 
277
    }
 
278
 
 
279
    /* mark display as up-to-date */
 
280
    dirty = 0;
 
281
    //drv_pLG_clear();
 
282
}
 
283
 
 
284
 
 
285
#define _USBLCD_MAX_DATA_LEN          24
 
286
#define IN_REPORT_KEY_STATE           0x11
 
287
static void drv_pLG_update_keypad()
 
288
{
 
289
    static int pressed_key = 0;
 
290
 
 
291
    int ret;
 
292
    unsigned char read_packet[_USBLCD_MAX_DATA_LEN];
 
293
    ret = drv_pLG_read(read_packet, _USBLCD_MAX_DATA_LEN);
 
294
    if ((ret > 0) && (read_packet[0] == IN_REPORT_KEY_STATE)) {
 
295
        debug("picoLCD: pressed key= 0x%02x\n", read_packet[1]);
 
296
        int new_pressed_key = read_packet[1];
 
297
        if (pressed_key != new_pressed_key) {
 
298
            /* negative values mark a key release */
 
299
            drv_generic_keypad_press(-pressed_key);
 
300
            drv_generic_keypad_press(new_pressed_key);
 
301
            pressed_key = new_pressed_key;
 
302
        }
 
303
    }
 
304
}
 
305
 
 
306
 
 
307
/* for graphic displays only */
 
308
static void drv_pLG_blit(const int row, const int col, const int height, const int width)
 
309
{
 
310
    int r, c;
 
311
 
 
312
    //DEBUG(fprintf(stderr, "In %s called with row %d col %d height %d width %d\n", __FUNCTION__, row, col, height, width));
 
313
 
 
314
    for (r = row; r < row + height; r++) {
 
315
        for (c = col; c < col + width; c++) {
 
316
            pLG_framebuffer[r * 256 + c] = drv_generic_graphic_black(r, c);
 
317
            //fprintf(stderr, "%d", pLG_framebuffer[r * 256 + c]);
 
318
        }
 
319
        //fprintf(stderr, "\n");
 
320
    }
 
321
 
 
322
    /*
 
323
       for (r = 0; r < 64; r++) {
 
324
       for(c = 0; c < 256; c++) {
 
325
       fprintf(stderr, "%d", pLG_framebuffer[r * 256 + c]); 
 
326
       }
 
327
       fprintf(stderr, "\n");
 
328
       }
 
329
     */
 
330
 
 
331
    /* display needs to be redrawn from frame buffer */
 
332
    dirty = 1;
 
333
 
 
334
    /* if "direct updates" have been requested, redraw now */
 
335
    if (update <= 0)
 
336
        drv_pLG_update_img();
 
337
}
 
338
 
 
339
 
 
340
void drv_pLG_clear(void)
 
341
{
 
342
    unsigned char cmd[3] = { 0x93, 0x01, 0x00 };        /* init display */
 
343
    unsigned char cmd2[9] = { OUT_REPORT_CMD }; /* init display */
 
344
    unsigned char cmd3[64] = { OUT_REPORT_CMD_DATA };   /* clear screen */
 
345
    unsigned char cmd4[64] = { OUT_REPORT_CMD_DATA };   /* clear screen */
 
346
 
 
347
    int init, index;
 
348
    unsigned char cs, line;
 
349
 
 
350
 
 
351
    debug("In %s\n", __FUNCTION__);
 
352
    drv_pLG_send(cmd, 3);
 
353
 
 
354
    for (init = 0; init < 4; init++) {
 
355
        unsigned char cs = ((init << 2) & 0xFF);
 
356
 
 
357
        cmd2[0] = OUT_REPORT_CMD;
 
358
        cmd2[1] = cs;
 
359
        cmd2[2] = 0x02;
 
360
        cmd2[3] = 0x00;
 
361
        cmd2[4] = 0x64;
 
362
        cmd2[5] = 0x3F;
 
363
        cmd2[6] = 0x00;
 
364
        cmd2[7] = 0x64;
 
365
        cmd2[8] = 0xC0;
 
366
 
 
367
        drv_pLG_send(cmd2, 9);
 
368
    }
 
369
 
 
370
 
 
371
    for (cs = 0; cs < 4; cs++) {
 
372
        unsigned char chipsel = (cs << 2);      //chipselect
 
373
        for (line = 0; line < 8; line++) {
 
374
            //ha64_1.setHIDPkt(OUT_REPORT_CMD_DATA, 8+3+32, 8, cs, 0x02, 0x00, 0x00, 0xb8|j, 0x00, 0x00, 0x40);
 
375
            cmd3[0] = OUT_REPORT_CMD_DATA;
 
376
            cmd3[1] = chipsel;
 
377
            cmd3[2] = 0x02;
 
378
            cmd3[3] = 0x00;
 
379
            cmd3[4] = 0x00;
 
380
            cmd3[5] = 0xb8 | line;
 
381
            cmd3[6] = 0x00;
 
382
            cmd3[7] = 0x00;
 
383
            cmd3[8] = 0x40;
 
384
            cmd3[9] = 0x00;
 
385
            cmd3[10] = 0x00;
 
386
            cmd3[11] = 32;
 
387
 
 
388
            unsigned char temp = 0;
 
389
 
 
390
            for (index = 0; index < 32; index++) {
 
391
                cmd3[12 + index] = temp;
 
392
            }
 
393
 
 
394
            drv_pLG_send(cmd3, 64);
 
395
 
 
396
            //ha64_2.setHIDPkt(OUT_REPORT_DATA, 4+32, 4, cs | 0x01, 0x00, 0x00, 32);
 
397
 
 
398
            cmd4[0] = OUT_REPORT_DATA;
 
399
            cmd4[1] = chipsel | 0x01;
 
400
            cmd4[2] = 0x00;
 
401
            cmd4[3] = 0x00;
 
402
            cmd4[4] = 32;
 
403
 
 
404
            for (index = 32; index < 64; index++) {
 
405
                temp = 0x00;
 
406
                cmd4[5 + (index - 32)] = temp;
 
407
            }
 
408
            drv_pLG_send(cmd4, 64);
 
409
        }
 
410
    }
 
411
}
 
412
 
 
413
static int drv_pLG_contrast(int contrast)
 
414
{
 
415
    unsigned char cmd[2] = { 0x92 };    /* set contrast */
 
416
 
 
417
    if (contrast < 0)
 
418
        contrast = 0;
 
419
    if (contrast > 255)
 
420
        contrast = 255;
 
421
 
 
422
    cmd[1] = contrast;
 
423
    drv_pLG_send(cmd, 2);
 
424
 
 
425
    return contrast;
 
426
}
 
427
 
 
428
 
 
429
static int drv_pLG_backlight(int backlight)
 
430
{
 
431
    unsigned char cmd[2] = { 0x91 };    /* set backlight */
 
432
 
 
433
    if (backlight < 0)
 
434
        backlight = 0;
 
435
    if (backlight >= 1)
 
436
        backlight = 200;
 
437
 
 
438
    cmd[1] = backlight;
 
439
    drv_pLG_send(cmd, 2);
 
440
 
 
441
    return backlight;
 
442
}
 
443
 
 
444
static int drv_pLG_gpi( __attribute__ ((unused))
 
445
                       int num)
 
446
{
 
447
    int ret;
 
448
    unsigned char read_packet[_USBLCD_MAX_DATA_LEN];
 
449
    ret = drv_pLG_read(read_packet, _USBLCD_MAX_DATA_LEN);
 
450
    if ((ret > 0) && (read_packet[0] == IN_REPORT_KEY_STATE)) {
 
451
        debug("picoLCD: pressed key= 0x%02x\n", read_packet[1]);
 
452
        return read_packet[1];
 
453
    }
 
454
    return 0;
 
455
}
 
456
 
 
457
 
 
458
static int drv_pLG_gpo(int num, int val)
 
459
{
 
460
    unsigned char cmd[2] = { 0x81 };    /* set GPO */
 
461
 
 
462
    if (num < 0)
 
463
        num = 0;
 
464
    if (num > 7)
 
465
        num = 7;
 
466
 
 
467
    if (val < 0)
 
468
        val = 0;
 
469
    if (val > 1)
 
470
        val = 1;
 
471
 
 
472
    /* set led bit to 1 or 0 */
 
473
    if (val)
 
474
        gpo |= 1 << num;
 
475
    else
 
476
        gpo &= ~(1 << num);
 
477
 
 
478
    cmd[1] = gpo;
 
479
    drv_pLG_send(cmd, 2);
 
480
 
 
481
    return val;
 
482
}
 
483
 
 
484
static int drv_pLG_start(const char *section, const int quiet)
 
485
{
 
486
    int rows = -1, cols = -1;
 
487
    int value;
 
488
    char *s;
 
489
 
 
490
    /* set display redraw interval (set to zero for "direct updates") */
 
491
    cfg_number(section, "update", 200, 0, -1, &update);
 
492
 
 
493
    /* USB read timeout in ms (the picoLCD 256x64 times out on every
 
494
       read unless a key has been pressed!)  */
 
495
    cfg_number(section, "Timeout", 5, 1, 1000, &read_timeout);
 
496
 
 
497
    s = cfg_get(section, "Size", NULL);
 
498
    if (s == NULL || *s == '\0') {
 
499
        error("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
 
500
        return -1;
 
501
    }
 
502
    if (sscanf(s, "%dx%d", &cols, &rows) != 2 || rows < 1 || cols < 1) {
 
503
        error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source());
 
504
        free(s);
 
505
        return -1;
 
506
    }
 
507
 
 
508
    if (cfg_number(section, "Inverted", 0, 0, 1, &value) > 0) {
 
509
        info("Setting display inverted to %d", value);
 
510
        inverted = value;
 
511
    }
 
512
 
 
513
    DROWS = SCREEN_H;
 
514
    DCOLS = SCREEN_W;
 
515
 
 
516
    if (drv_pLG_open() < 0) {
 
517
        return -1;
 
518
    }
 
519
 
 
520
    /* Init the command buffer */
 
521
    Buffer = (char *) malloc(1024);
 
522
    if (Buffer == NULL) {
 
523
        error("%s: command buffer could not be allocated: malloc() failed", Name);
 
524
        return -1;
 
525
    }
 
526
    BufPtr = Buffer;
 
527
 
 
528
    /* Init framebuffer buffer */
 
529
    pLG_framebuffer = malloc(SCREEN_W * SCREEN_H * sizeof(unsigned char));
 
530
    if (!pLG_framebuffer)
 
531
        return -1;
 
532
 
 
533
    DEBUG("allocated");
 
534
    memset(pLG_framebuffer, 0, SCREEN_W * SCREEN_H);
 
535
    DEBUG("zeroed");
 
536
 
 
537
    if (cfg_number(section, "Contrast", 0, 0, 255, &value) > 0) {
 
538
        info("Setting contrast to %d", value);
 
539
        drv_pLG_contrast(value);
 
540
    }
 
541
 
 
542
    if (cfg_number(section, "Backlight", 0, 0, 1, &value) > 0) {
 
543
        info("Setting backlight to %d", value);
 
544
        drv_pLG_backlight(value);
 
545
    }
 
546
 
 
547
    drv_pLG_clear();            /* clear display */
 
548
 
 
549
    if (!quiet) {
 
550
        char buffer[40];
 
551
        qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, SCREEN_W, SCREEN_H);
 
552
        if (drv_generic_graphic_greet(buffer, "http://www.picolcd.com")) {
 
553
            sleep(3);
 
554
            drv_pLG_clear();
 
555
        }
 
556
    }
 
557
 
 
558
    /* setup a timer that regularly redraws the display from the frame
 
559
       buffer (unless "direct updates" have been requested */
 
560
    if (update > 0)
 
561
        timer_add(drv_pLG_update_img, NULL, update, 0);
 
562
 
 
563
    /* setup a timer that regularly checks the keypad for pressed or
 
564
       released keys */
 
565
    /* FIXME: make 100msec configurable */
 
566
    timer_add(drv_pLG_update_keypad, NULL, 100, 0);
 
567
 
 
568
    return 0;
 
569
}
 
570
 
 
571
 
 
572
/****************************************/
 
573
/***            plugins               ***/
 
574
/****************************************/
 
575
 
 
576
static void plugin_contrast(RESULT * result, RESULT * arg1)
 
577
{
 
578
    double contrast;
 
579
 
 
580
    contrast = drv_pLG_contrast(R2N(arg1));
 
581
    SetResult(&result, R_NUMBER, &contrast);
 
582
}
 
583
 
 
584
static void plugin_backlight(RESULT * result, RESULT * arg1)
 
585
{
 
586
    double backlight;
 
587
 
 
588
    backlight = drv_pLG_backlight(R2N(arg1));
 
589
    SetResult(&result, R_NUMBER, &backlight);
 
590
}
 
591
 
 
592
static void plugin_gpo(RESULT * result, RESULT * argv[])
 
593
{
 
594
    double gpo;
 
595
    gpo = drv_pLG_gpo(R2N(argv[0]), R2N(argv[1]));
 
596
    SetResult(&result, R_NUMBER, &gpo);
 
597
}
 
598
 
 
599
 
 
600
/****************************************/
 
601
/***        widget callbacks          ***/
 
602
/****************************************/
 
603
 
 
604
 
 
605
/* using drv_generic_text_draw(W) */
 
606
/* using drv_generic_text_icon_draw(W) */
 
607
/* using drv_generic_text_bar_draw(W) */
 
608
 
 
609
 
 
610
/****************************************/
 
611
/***        exported functions        ***/
 
612
/****************************************/
 
613
 
 
614
 
 
615
/* list models */
 
616
int drv_pLG_list(void)
 
617
{
 
618
    printf("picoLCD 256x64 Graphic LCD");
 
619
    return 0;
 
620
}
 
621
 
 
622
 
 
623
static int drv_pLG_keypad(const int num)
 
624
{
 
625
    int val;
 
626
    int new_num = num;
 
627
 
 
628
    if (new_num == 0)
 
629
        return 0;
 
630
    else if (new_num > 0)
 
631
        val = WIDGET_KEY_PRESSED;
 
632
    else {
 
633
        /* negative values mark a key release */
 
634
        new_num = -num;
 
635
        val = WIDGET_KEY_RELEASED;
 
636
    }
 
637
 
 
638
    switch (new_num) {
 
639
    case 1:
 
640
        val += WIDGET_KEY_CANCEL;
 
641
        break;
 
642
    case 2:
 
643
        val += WIDGET_KEY_LEFT;
 
644
        break;
 
645
    case 3:
 
646
        val += WIDGET_KEY_RIGHT;
 
647
        break;
 
648
    case 5:
 
649
        val += WIDGET_KEY_UP;
 
650
        break;
 
651
    case 6:
 
652
        val += WIDGET_KEY_CONFIRM;
 
653
        break;
 
654
    case 7:
 
655
        val += WIDGET_KEY_DOWN;
 
656
        break;
 
657
    default:
 
658
        error("%s: unknown keypad value %d", Name, num);
 
659
    }
 
660
 
 
661
    return val;
 
662
}
 
663
 
 
664
 
 
665
/* initialize driver & display */
 
666
int drv_pLG_init(const char *section, const int quiet)
 
667
{
 
668
    int ret;
 
669
 
 
670
    info("%s: %s", Name, "$Rev: 1143 $");
 
671
 
 
672
    info("PICOLCD Graphic initialization\n");
 
673
 
 
674
    /* display preferences */
 
675
    XRES = 6;                   /* pixel width of one char  */
 
676
    YRES = 8;                   /* pixel height of one char  */
 
677
    GPOS = 8;
 
678
    GPIS = 1;
 
679
    /* real worker functions */
 
680
    drv_generic_graphic_real_blit = drv_pLG_blit;
 
681
    drv_generic_keypad_real_press = drv_pLG_keypad;
 
682
    drv_generic_gpio_real_set = drv_pLG_gpo;
 
683
    drv_generic_gpio_real_get = drv_pLG_gpi;
 
684
 
 
685
 
 
686
    /* start display */
 
687
    if ((ret = drv_pLG_start(section, quiet)) != 0)
 
688
        return ret;
 
689
 
 
690
 
 
691
    /* initialize generic graphic driver */
 
692
    if ((ret = drv_generic_graphic_init(section, Name)) != 0)
 
693
        return ret;
 
694
 
 
695
 
 
696
    /* initialize generic key pad driver */
 
697
    if ((ret = drv_generic_keypad_init(section, Name)) != 0)
 
698
        return ret;
 
699
 
 
700
 
 
701
    /* GPO's init */
 
702
 
 
703
    if ((ret = drv_generic_gpio_init(section, Name)) != 0)
 
704
        return ret;
 
705
 
 
706
    /* register plugins */
 
707
 
 
708
    AddFunction("LCD::contrast", 1, plugin_contrast);
 
709
    AddFunction("LCD::backlight", 1, plugin_backlight);
 
710
    AddFunction("LCD::gpo", -1, plugin_gpo);
 
711
 
 
712
    return 0;
 
713
}
 
714
 
 
715
 
 
716
/* close driver & display */
 
717
int drv_pLG_quit(const int quiet)
 
718
{
 
719
 
 
720
    info("%s: shutting down.", Name);
 
721
 
 
722
    /* clear display */
 
723
    drv_pLG_clear();
 
724
 
 
725
    /* say goodbye... */
 
726
    if (!quiet) {
 
727
        drv_generic_graphic_greet("goodbye!", NULL);
 
728
    }
 
729
 
 
730
    drv_pLG_close();
 
731
 
 
732
    if (Buffer) {
 
733
        free(Buffer);
 
734
        BufPtr = NULL;
 
735
    }
 
736
 
 
737
    drv_generic_graphic_quit();
 
738
    drv_generic_keypad_quit();
 
739
 
 
740
    return (0);
 
741
}
 
742
 
 
743
 
 
744
DRIVER drv_picoLCDGraphic = {
 
745
    .name = Name,
 
746
    .list = drv_pLG_list,
 
747
    .init = drv_pLG_init,
 
748
    .quit = drv_pLG_quit,
 
749
};