~siretart/lcd4linux/debian

« back to all changes in this revision

Viewing changes to drv_Sample.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_Sample.c 975 2009-01-18 11:16:20Z michael $
 
2
 * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/drv_Sample.c $
 
3
 *
 
4
 * sample lcd4linux driver
 
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
 * This file is part of LCD4Linux.
 
10
 *
 
11
 * LCD4Linux is free software; you can redistribute it and/or modify
 
12
 * it under the terms of the GNU General Public License as published by
 
13
 * the Free Software Foundation; either version 2, or (at your option)
 
14
 * any later version.
 
15
 *
 
16
 * LCD4Linux is distributed in the hope that it will be useful,
 
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 * GNU General Public License for more details.
 
20
 *
 
21
 * You should have received a copy of the GNU General Public License
 
22
 * along with this program; if not, write to the Free Software
 
23
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
24
 *
 
25
 */
 
26
 
 
27
/* 
 
28
 *
 
29
 * exported fuctions:
 
30
 *
 
31
 * struct DRIVER drv_Sample
 
32
 *
 
33
 */
 
34
 
 
35
#include "config.h"
 
36
 
 
37
#include <stdlib.h>
 
38
#include <stdio.h>
 
39
#include <unistd.h>
 
40
#include <string.h>
 
41
#include <errno.h>
 
42
 
 
43
#include "debug.h"
 
44
#include "cfg.h"
 
45
#include "qprintf.h"
 
46
#include "udelay.h"
 
47
#include "plugin.h"
 
48
#include "widget.h"
 
49
#include "widget_text.h"
 
50
#include "widget_icon.h"
 
51
#include "widget_bar.h"
 
52
#include "drv.h"
 
53
 
 
54
/* text mode display? */
 
55
#include "drv_generic_text.h"
 
56
 
 
57
/* graphic display? */
 
58
#include "drv_generic_graphic.h"
 
59
 
 
60
/* GPO's? */
 
61
#include "drv_generic_gpio.h"
 
62
 
 
63
/* serial port? */
 
64
#include "drv_generic_serial.h"
 
65
 
 
66
/* parallel port? */
 
67
#include "drv_generic_parport.h"
 
68
 
 
69
/* i2c bus? */
 
70
#ifdef WITH_I2C
 
71
#include "drv_generic_i2c.h"
 
72
#endif
 
73
 
 
74
 
 
75
static char Name[] = "Sample";
 
76
 
 
77
 
 
78
/* for parallel port displays only */
 
79
/* use whatever lines you need */
 
80
static unsigned char SIGNAL_RS;
 
81
static unsigned char SIGNAL_EX;
 
82
 
 
83
 
 
84
 
 
85
/****************************************/
 
86
/***  hardware dependant functions    ***/
 
87
/****************************************/
 
88
 
 
89
/* low-level parallel port stuff */
 
90
/* example for sending one byte over the wire */
 
91
static void drv_Sample_bang(const unsigned int data)
 
92
{
 
93
    /* put data on DB1..DB8 */
 
94
    drv_generic_parport_data(data & 0xff);
 
95
 
 
96
    /* set/clear some signals */
 
97
    drv_generic_parport_control(SIGNAL_RS, SIGNAL_RS);
 
98
 
 
99
    /* data setup time (e.g. 200 ns) */
 
100
    ndelay(200);
 
101
 
 
102
    /* send byte */
 
103
    /* signal pulse width 500ns */
 
104
    drv_generic_parport_toggle(SIGNAL_EX, 1, 500);
 
105
 
 
106
    /* wait for command completion (e.g. 100 us) */
 
107
    udelay(100);
 
108
}
 
109
 
 
110
 
 
111
static int drv_Sample_open(const char *section)
 
112
{
 
113
    /* open serial port */
 
114
    /* don't mind about device, speed and stuff, this function will take care of */
 
115
 
 
116
    if (drv_generic_serial_open(section, Name, 0) < 0)
 
117
        return -1;
 
118
 
 
119
 
 
120
    /* opening the parallel port is a bit more tricky: */
 
121
    /* you have to do all the bit-banging yourself... */
 
122
 
 
123
    if (drv_generic_parport_open(section, Name) != 0) {
 
124
        error("%s: could not initialize parallel port!", Name);
 
125
        return -1;
 
126
    }
 
127
 
 
128
    /* read the wiring from config */
 
129
    if ((SIGNAL_EX = drv_generic_parport_wire_ctrl("EX", "STROBE")) == 0xff)
 
130
        return -1;
 
131
    if ((SIGNAL_RS = drv_generic_parport_wire_ctrl("RS", "INIT")) == 0xff)
 
132
        return -1;
 
133
 
 
134
    /* clear all signals */
 
135
    drv_generic_parport_control(SIGNAL_EX | SIGNAL_RS, 0);
 
136
 
 
137
    /* set direction: write */
 
138
    drv_generic_parport_direction(0);
 
139
 
 
140
    return 0;
 
141
}
 
142
 
 
143
 
 
144
static int drv_Sample_close(void)
 
145
{
 
146
    /* close whatever port you've opened */
 
147
    drv_generic_parport_close();
 
148
    drv_generic_serial_close();
 
149
 
 
150
    return 0;
 
151
}
 
152
 
 
153
 
 
154
/* dummy function that sends something to the display */
 
155
static void drv_Sample_send(const char *data, const unsigned int len)
 
156
{
 
157
    unsigned int i;
 
158
 
 
159
    /* send data to the serial port is easy... */
 
160
    drv_generic_serial_write(data, len);
 
161
 
 
162
    /* sending data to the parallel port is a bit more tricky... */
 
163
    for (i = 0; i < len; i++) {
 
164
        drv_Sample_bang(*data++);
 
165
    }
 
166
}
 
167
 
 
168
 
 
169
/* text mode displays only */
 
170
static void drv_Sample_clear(void)
 
171
{
 
172
    char cmd[1];
 
173
 
 
174
    /* do whatever is necessary to clear the display */
 
175
    /* assume 0x01 to be a 'clear display' command */
 
176
    cmd[0] = 0x01;
 
177
    drv_Sample_send(cmd, 1);
 
178
}
 
179
 
 
180
 
 
181
/* text mode displays only */
 
182
static void drv_Sample_write(const int row, const int col, const char *data, int len)
 
183
{
 
184
    char cmd[3];
 
185
 
 
186
    /* do the cursor positioning here */
 
187
    /* assume 0x02 to be a 'Goto' command */
 
188
    cmd[0] = 0x02;
 
189
    cmd[1] = row;
 
190
    cmd[2] = col;
 
191
    drv_Sample_send(cmd, 3);
 
192
 
 
193
    /* send string to the display */
 
194
    drv_Sample_send(data, len);
 
195
 
 
196
}
 
197
 
 
198
/* text mode displays only */
 
199
static void drv_Sample_defchar(const int ascii, const unsigned char *matrix)
 
200
{
 
201
    char cmd[10];
 
202
    int i;
 
203
 
 
204
    /* call the 'define character' function */
 
205
    /* assume 0x03 to be the 'defchar' command */
 
206
    cmd[0] = 0x03;
 
207
    cmd[1] = ascii;
 
208
 
 
209
    /* send bitmap to the display */
 
210
    for (i = 0; i < 8; i++) {
 
211
        cmd[i + 2] = *matrix++;
 
212
    }
 
213
    drv_Sample_send(cmd, 10);
 
214
}
 
215
 
 
216
 
 
217
/* for graphic displays only */
 
218
static void drv_Sample_blit(const int row, const int col, const int height, const int width)
 
219
{
 
220
    int r, c;
 
221
 
 
222
    for (r = row; r < row + height; r++) {
 
223
        for (c = col; c < col + width; c++) {
 
224
            /* drv_generic_graphic_black() returns 1 if pixel is black */
 
225
            /* drv_generic_graphic_gray() returns a gray value 0..255 */
 
226
            /* drv_generic_graphic_rgb() returns a RGB color */
 
227
            if (drv_generic_graphic_black(r, c)) {
 
228
                /* set bit */
 
229
            } else {
 
230
                /* clear bit */
 
231
            }
 
232
        }
 
233
    }
 
234
}
 
235
 
 
236
 
 
237
/* remove unless you have GPO's */
 
238
static int drv_Sample_GPO(const int num, const int val)
 
239
{
 
240
    char cmd[4];
 
241
 
 
242
    /* assume 0x42 to be the 'GPO' command */
 
243
    cmd[0] = 0x42;
 
244
    cmd[1] = num;
 
245
    cmd[2] = (val > 0) ? 1 : 0;
 
246
 
 
247
    drv_Sample_send(cmd, 3);
 
248
 
 
249
    return 0;
 
250
}
 
251
 
 
252
 
 
253
/* example function used in a plugin */
 
254
static int drv_Sample_contrast(int contrast)
 
255
{
 
256
    char cmd[2];
 
257
 
 
258
    /* adjust limits according to the display */
 
259
    if (contrast < 0)
 
260
        contrast = 0;
 
261
    if (contrast > 255)
 
262
        contrast = 255;
 
263
 
 
264
    /* call a 'contrast' function */
 
265
    /* assume 0x04 to be the 'set contrast' command */
 
266
    cmd[0] = 0x04;
 
267
    cmd[1] = contrast;
 
268
    drv_Sample_send(cmd, 2);
 
269
 
 
270
    return contrast;
 
271
}
 
272
 
 
273
 
 
274
/* start text mode display */
 
275
static int drv_Sample_start(const char *section)
 
276
{
 
277
    int contrast;
 
278
    int rows = -1, cols = -1;
 
279
    char *s;
 
280
    char cmd[1];
 
281
 
 
282
    s = cfg_get(section, "Size", NULL);
 
283
    if (s == NULL || *s == '\0') {
 
284
        error("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
 
285
        return -1;
 
286
    }
 
287
    if (sscanf(s, "%dx%d", &cols, &rows) != 2 || rows < 1 || cols < 1) {
 
288
        error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source());
 
289
        free(s);
 
290
        return -1;
 
291
    }
 
292
 
 
293
    DROWS = rows;
 
294
    DCOLS = cols;
 
295
 
 
296
    /* number of GPO's; remove if you don't have them */
 
297
    GPOS = 8;
 
298
 
 
299
    /* open communication with the display */
 
300
    if (drv_Sample_open(section) < 0) {
 
301
        return -1;
 
302
    }
 
303
 
 
304
    /* reset & initialize display */
 
305
    /* assume 0x00 to be a 'reset' command */
 
306
    cmd[0] = 0x00;
 
307
    drv_Sample_send(cmd, 0);
 
308
 
 
309
    if (cfg_number(section, "Contrast", 0, 0, 255, &contrast) > 0) {
 
310
        drv_Sample_contrast(contrast);
 
311
    }
 
312
 
 
313
    drv_Sample_clear();         /* clear display */
 
314
 
 
315
    return 0;
 
316
}
 
317
 
 
318
 
 
319
/* start graphic display */
 
320
static int drv_Sample_start2(const char *section)
 
321
{
 
322
    char *s;
 
323
    char cmd[1];
 
324
    int contrast;
 
325
 
 
326
    /* read display size from config */
 
327
    s = cfg_get(section, "Size", NULL);
 
328
    if (s == NULL || *s == '\0') {
 
329
        error("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
 
330
        return -1;
 
331
    }
 
332
 
 
333
    DROWS = -1;
 
334
    DCOLS = -1;
 
335
    if (sscanf(s, "%dx%d", &DCOLS, &DROWS) != 2 || DCOLS < 1 || DROWS < 1) {
 
336
        error("%s: bad Size '%s' from %s", Name, s, cfg_source());
 
337
        return -1;
 
338
    }
 
339
 
 
340
    s = cfg_get(section, "Font", "6x8");
 
341
    if (s == NULL || *s == '\0') {
 
342
        error("%s: no '%s.Font' entry from %s", Name, section, cfg_source());
 
343
        return -1;
 
344
    }
 
345
 
 
346
    XRES = -1;
 
347
    YRES = -1;
 
348
    if (sscanf(s, "%dx%d", &XRES, &YRES) != 2 || XRES < 1 || YRES < 1) {
 
349
        error("%s: bad Font '%s' from %s", Name, s, cfg_source());
 
350
        return -1;
 
351
    }
 
352
 
 
353
    /* Fixme: provider other fonts someday... */
 
354
    if (XRES != 6 && YRES != 8) {
 
355
        error("%s: bad Font '%s' from %s (only 6x8 at the moment)", Name, s, cfg_source());
 
356
        return -1;
 
357
    }
 
358
 
 
359
    /* you surely want to allocate a framebuffer or something... */
 
360
 
 
361
    /* open communication with the display */
 
362
    if (drv_Sample_open(section) < 0) {
 
363
        return -1;
 
364
    }
 
365
 
 
366
    /* reset & initialize display */
 
367
    /* assume 0x00 to be a 'reset' command */
 
368
    cmd[0] = 0x00;
 
369
    drv_Sample_send(cmd, 1);
 
370
 
 
371
    if (cfg_number(section, "Contrast", 0, 0, 255, &contrast) > 0) {
 
372
        drv_Sample_contrast(contrast);
 
373
    }
 
374
 
 
375
    return 0;
 
376
}
 
377
 
 
378
 
 
379
/****************************************/
 
380
/***            plugins               ***/
 
381
/****************************************/
 
382
 
 
383
static void plugin_contrast(RESULT * result, RESULT * arg1)
 
384
{
 
385
    double contrast;
 
386
 
 
387
    contrast = drv_Sample_contrast(R2N(arg1));
 
388
    SetResult(&result, R_NUMBER, &contrast);
 
389
}
 
390
 
 
391
 
 
392
/****************************************/
 
393
/***        widget callbacks          ***/
 
394
/****************************************/
 
395
 
 
396
 
 
397
/* using drv_generic_text_draw(W) */
 
398
/* using drv_generic_text_icon_draw(W) */
 
399
/* using drv_generic_text_bar_draw(W) */
 
400
/* using drv_generic_gpio_draw(W) */
 
401
 
 
402
 
 
403
/****************************************/
 
404
/***        exported functions        ***/
 
405
/****************************************/
 
406
 
 
407
 
 
408
/* list models */
 
409
int drv_Sample_list(void)
 
410
{
 
411
    printf("Sample driver");
 
412
    return 0;
 
413
}
 
414
 
 
415
 
 
416
/* initialize driver & display */
 
417
/* use this function for a text display */
 
418
int drv_Sample_init(const char *section, const int quiet)
 
419
{
 
420
    WIDGET_CLASS wc;
 
421
    int ret;
 
422
 
 
423
    info("%s: %s", Name, "$Rev: 975 $");
 
424
 
 
425
    /* display preferences */
 
426
    XRES = 5;                   /* pixel width of one char  */
 
427
    YRES = 8;                   /* pixel height of one char  */
 
428
    CHARS = 8;                  /* number of user-defineable characters */
 
429
    CHAR0 = 0;                  /* ASCII of first user-defineable char */
 
430
    GOTO_COST = 2;              /* number of bytes a goto command requires */
 
431
 
 
432
    /* real worker functions */
 
433
    drv_generic_text_real_write = drv_Sample_write;
 
434
    drv_generic_text_real_defchar = drv_Sample_defchar;
 
435
 
 
436
    /* remove unless you have GPO's */
 
437
    drv_generic_gpio_real_set = drv_Sample_GPO;
 
438
 
 
439
 
 
440
    /* start display */
 
441
    if ((ret = drv_Sample_start(section)) != 0)
 
442
        return ret;
 
443
 
 
444
    if (!quiet) {
 
445
        char buffer[40];
 
446
        qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
 
447
        if (drv_generic_text_greet(buffer, "www.bwct.de")) {
 
448
            sleep(3);
 
449
            drv_Sample_clear();
 
450
        }
 
451
    }
 
452
 
 
453
    /* initialize generic text driver */
 
454
    if ((ret = drv_generic_text_init(section, Name)) != 0)
 
455
        return ret;
 
456
 
 
457
    /* initialize generic icon driver */
 
458
    if ((ret = drv_generic_text_icon_init()) != 0)
 
459
        return ret;
 
460
 
 
461
    /* initialize generic bar driver */
 
462
    if ((ret = drv_generic_text_bar_init(0)) != 0)
 
463
        return ret;
 
464
 
 
465
    /* add fixed chars to the bar driver */
 
466
    drv_generic_text_bar_add_segment(0, 0, 255, 32);    /* ASCII  32 = blank */
 
467
 
 
468
 
 
469
    /* initialize generic GPIO driver */
 
470
    /* remove unless you have GPO's */
 
471
    if ((ret = drv_generic_gpio_init(section, Name)) != 0)
 
472
        return ret;
 
473
 
 
474
    /* register text widget */
 
475
    wc = Widget_Text;
 
476
    wc.draw = drv_generic_text_draw;
 
477
    widget_register(&wc);
 
478
 
 
479
    /* register icon widget */
 
480
    wc = Widget_Icon;
 
481
    wc.draw = drv_generic_text_icon_draw;
 
482
    widget_register(&wc);
 
483
 
 
484
    /* register bar widget */
 
485
    wc = Widget_Bar;
 
486
    wc.draw = drv_generic_text_bar_draw;
 
487
    widget_register(&wc);
 
488
 
 
489
    /* register plugins */
 
490
    AddFunction("LCD::contrast", 1, plugin_contrast);
 
491
 
 
492
    return 0;
 
493
}
 
494
 
 
495
 
 
496
/* initialize driver & display */
 
497
/* use this function for a graphic display */
 
498
int drv_Sample_init2(const char *section, const int quiet)
 
499
{
 
500
    int ret;
 
501
 
 
502
    /* real worker functions */
 
503
    drv_generic_graphic_real_blit = drv_Sample_blit;
 
504
 
 
505
    /* remove unless you have GPO's */
 
506
    drv_generic_gpio_real_set = drv_Sample_GPO;
 
507
 
 
508
    /* start display */
 
509
    if ((ret = drv_Sample_start2(section)) != 0)
 
510
        return ret;
 
511
 
 
512
    /* initialize generic graphic driver */
 
513
    if ((ret = drv_generic_graphic_init(section, Name)) != 0)
 
514
        return ret;
 
515
 
 
516
    if (!quiet) {
 
517
        char buffer[40];
 
518
        qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
 
519
        if (drv_generic_graphic_greet(buffer, NULL)) {
 
520
            sleep(3);
 
521
            drv_generic_graphic_clear();
 
522
        }
 
523
    }
 
524
 
 
525
    /* register plugins */
 
526
    AddFunction("LCD::contrast", 1, plugin_contrast);
 
527
 
 
528
    return 0;
 
529
}
 
530
 
 
531
 
 
532
 
 
533
/* close driver & display */
 
534
/* use this function for a text display */
 
535
int drv_Sample_quit(const int quiet)
 
536
{
 
537
 
 
538
    info("%s: shutting down.", Name);
 
539
 
 
540
    drv_generic_text_quit();
 
541
 
 
542
    /* remove unless you have GPO's */
 
543
    drv_generic_gpio_quit();
 
544
 
 
545
    /* clear display */
 
546
    drv_Sample_clear();
 
547
 
 
548
    /* say goodbye... */
 
549
    if (!quiet) {
 
550
        drv_generic_text_greet("goodbye!", NULL);
 
551
    }
 
552
 
 
553
    debug("closing connection");
 
554
    drv_Sample_close();
 
555
 
 
556
    return (0);
 
557
}
 
558
 
 
559
/* close driver & display */
 
560
/* use this function for a graphic display */
 
561
int drv_Sample_quit2(const int quiet)
 
562
{
 
563
 
 
564
    info("%s: shutting down.", Name);
 
565
 
 
566
    /* clear display */
 
567
    drv_generic_graphic_clear();
 
568
 
 
569
    /* remove unless you have GPO's */
 
570
    drv_generic_gpio_quit();
 
571
 
 
572
    /* say goodbye... */
 
573
    if (!quiet) {
 
574
        drv_generic_graphic_greet("goodbye!", NULL);
 
575
    }
 
576
 
 
577
    drv_generic_graphic_quit();
 
578
 
 
579
    debug("closing connection");
 
580
    drv_Sample_close();
 
581
 
 
582
    return (0);
 
583
}
 
584
 
 
585
 
 
586
/* use this one for a text display */
 
587
DRIVER drv_Sample = {
 
588
    .name = Name,
 
589
    .list = drv_Sample_list,
 
590
    .init = drv_Sample_init,
 
591
    .quit = drv_Sample_quit,
 
592
};
 
593
 
 
594
 
 
595
/* use this one for a graphic display */
 
596
DRIVER drv_Sample2 = {
 
597
    .name = Name,
 
598
    .list = drv_Sample_list,
 
599
    .init = drv_Sample_init2,
 
600
    .quit = drv_Sample_quit2,
 
601
};