~siretart/lcd4linux/debian

« back to all changes in this revision

Viewing changes to drv_ula200.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_ula200.c 1126 2010-07-13 03:25:44Z michael $
 
2
 * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/drv_ula200.c $
 
3
 *
 
4
 * ULA200 driver for lcd4linux
 
5
 *
 
6
 * Copyright (C) 2008 Bernhard Walle <bernhard.walle@gmx.de>
 
7
 *
 
8
 * This file is part of LCD4Linux.
 
9
 *
 
10
 * LCD4Linux is free software; you can redistribute it and/or modify
 
11
 * it under the terms of the GNU General Public License as published by
 
12
 * the Free Software Foundation; either version 2, or (at your option)
 
13
 * any later version.
 
14
 *
 
15
 * LCD4Linux is distributed in the hope that it will be useful,
 
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 * GNU General Public License for more details.
 
19
 *
 
20
 * You should have received a copy of the GNU General Public License
 
21
 * along with this program; if not, write to the Free Software
 
22
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
23
 *
 
24
 */
 
25
 
 
26
/*
 
27
 * Driver for the ELV ULA200 USB device. The device can control one
 
28
 * HD44780 display up to 4x20 characters.
 
29
 *
 
30
 * Implemented functions:
 
31
 *   - displaying characters :-)
 
32
 *   - controlling the backlight
 
33
 *
 
34
 * Todo:
 
35
 *   - input buttons
 
36
 *
 
37
 * Configuration:
 
38
 *   - Size (XxY): size of the display (e.g. '20x4')
 
39
 *   - Backlight (0/1): initial state of the backlight
 
40
 *
 
41
 * Author:
 
42
 *   Bernhard Walle <bernhard.walle@gmx.de>
 
43
 *
 
44
 * exported fuctions:
 
45
 *   struct DRIVER drv_ula200
 
46
 *
 
47
 */
 
48
 
 
49
#include "config.h"
 
50
 
 
51
#include <stdlib.h>
 
52
#include <stdio.h>
 
53
#include <unistd.h>
 
54
#include <string.h>
 
55
#include <errno.h>
 
56
 
 
57
#include <ftdi.h>
 
58
 
 
59
#include "debug.h"
 
60
#include "cfg.h"
 
61
#include "qprintf.h"
 
62
#include "udelay.h"
 
63
#include "plugin.h"
 
64
#include "widget.h"
 
65
#include "widget_text.h"
 
66
#include "widget_icon.h"
 
67
#include "widget_bar.h"
 
68
#include "drv.h"
 
69
 
 
70
/* text mode display? */
 
71
#include "drv_generic_text.h"
 
72
 
 
73
/****************************************/
 
74
/***        Global variables          ***/
 
75
/****************************************/
 
76
 
 
77
static char Name[] = "ULA200";
 
78
static struct ftdi_context *Ftdi = NULL;
 
79
 
 
80
 
 
81
/****************************************/
 
82
/***        Constants                 ***/
 
83
/****************************************/
 
84
 
 
85
/* USB connection */
 
86
#define ULA200_VENDOR_ID        0x0403
 
87
#define ULA200_PRODUCT_ID       0xf06d
 
88
 
 
89
/* connection parameters */
 
90
#define ULA200_BAUDRATE         19200
 
91
#define ULA200_DATABITS         BITS_8
 
92
#define ULA200_STOPBITS         STOP_BIT_1
 
93
#define ULA200_PARITY           EVEN
 
94
 
 
95
/* character constants used for the communication */
 
96
#define ULA200_CH_STX           0x02
 
97
#define ULA200_CH_ETX           0x03
 
98
#define ULA200_CH_ENQ           0x05
 
99
#define ULA200_CH_ACK           0x06
 
100
#define ULA200_CH_NAK           0x15
 
101
#define ULA200_CH_DC2           0x12
 
102
#define ULA200_CH_DC3           0x13
 
103
 
 
104
/* commands used for the communication (names are German) */
 
105
#define ULA200_CMD_POSITION     'p'     /* 'position' */
 
106
#define ULA200_CMD_STRING       's'     /* 'string' */
 
107
#define ULA200_CMD_CLEAR        'l'     /* 'loeschen' */
 
108
#define ULA200_CMD_BACKLIGHT    'h'     /* 'hintergrund' */
 
109
#define ULA200_CMD_CHAR         'c'     /* 'character' */
 
110
 
 
111
/* raw register access */
 
112
#define ULA200_RS_DATA          0x00    /* data */
 
113
#define ULA200_RS_INSTR         0x01    /* instruction */
 
114
#define ULA200_SETCHAR          0x40    /* set user-defined character */
 
115
 
 
116
/* character sizes */
 
117
#define ULA200_CELLWIDTH        5
 
118
#define ULA200_CELLHEIGHT       8
 
119
 
 
120
/* internal implementation constants */
 
121
#define ULA200_BUFFER_LENGTH    1024
 
122
#define ULA200_MAXLEN           512
 
123
#define ULA200_MAX_REPEATS      20
 
124
 
 
125
/* define TRUE and FALSE for better code readability if not already defined */
 
126
#ifndef TRUE
 
127
#define TRUE 1
 
128
#endif
 
129
#ifndef FALSE
 
130
#define FALSE 0
 
131
#endif
 
132
 
 
133
 
 
134
/****************************************/
 
135
/***        Macros                    ***/
 
136
/****************************************/
 
137
 
 
138
#define ULA200_ERROR(msg, ...) \
 
139
        error("%s: In %s():%d: " msg, Name, \
 
140
            __FUNCTION__, __LINE__, ##__VA_ARGS__)
 
141
 
 
142
#define ULA200_INFO(msg, ...) \
 
143
        info("%s: " msg, Name, ##__VA_ARGS__)
 
144
 
 
145
#define ULA200_DEBUG(msg, ...) \
 
146
        debug("%s: In %s():%d: " msg, Name, \
 
147
            __FUNCTION__, __LINE__, ##__VA_ARGS__)
 
148
 
 
149
#define ULA200_TRACE() \
 
150
        debug("%s: Calling %s()", Name, __FUNCTION__)
 
151
 
 
152
 
 
153
/****************************************/
 
154
/***        Prototypes                ***/
 
155
/****************************************/
 
156
 
 
157
static int drv_ula200_ftdi_read_response(void);
 
158
static int drv_ula200_ftdi_usb_read(void);
 
159
static int drv_ula200_ftdi_write_command(const unsigned char *, int);
 
160
static int drv_ula200_backlight(int);
 
161
static int drv_ula200_close(void);
 
162
 
 
163
static void plugin_backlight(RESULT *, RESULT *);
 
164
 
 
165
/****************************************/
 
166
/***        Internal (helper) funcs   ***/
 
167
/****************************************/
 
168
 
 
169
/**
 
170
 * Write a command to the display. Adds the STX and ETX header/trailer.
 
171
 *
 
172
 * @param[in] data the data bytes
 
173
 * @param[in] length the number of bytes in data which are valid
 
174
 * @return 0 on success, negative value on error
 
175
 */
 
176
static int drv_ula200_ftdi_write_command(const unsigned char *data, int length)
 
177
{
 
178
    int i, err;
 
179
    int repeat_count = 0;
 
180
    int pos = 0;
 
181
    unsigned char buffer[ULA200_BUFFER_LENGTH];
 
182
 
 
183
    /* check for the maximum length */
 
184
    if (length > ULA200_MAXLEN) {
 
185
        return -EINVAL;
 
186
    }
 
187
 
 
188
    /* fill the array */
 
189
    buffer[pos++] = ULA200_CH_STX;
 
190
    for (i = 0; i < length; i++) {
 
191
        if (data[i] == ULA200_CH_STX) {
 
192
            buffer[pos++] = ULA200_CH_ENQ;
 
193
            buffer[pos++] = ULA200_CH_DC2;
 
194
        } else if (data[i] == ULA200_CH_ETX) {
 
195
            buffer[pos++] = ULA200_CH_ENQ;
 
196
            buffer[pos++] = ULA200_CH_DC3;
 
197
        } else if (data[i] == ULA200_CH_ENQ) {
 
198
            buffer[pos++] = ULA200_CH_ENQ;
 
199
            buffer[pos++] = ULA200_CH_NAK;
 
200
        } else {
 
201
            buffer[pos++] = data[i];
 
202
        }
 
203
    }
 
204
    buffer[pos++] = ULA200_CH_ETX;
 
205
 
 
206
    do {
 
207
        /* ULA200_DEBUG("ftdi_write_data(%p, %d)", buffer, pos); */
 
208
        err = ftdi_write_data(Ftdi, buffer, pos);
 
209
        if (err < 0) {
 
210
            ULA200_ERROR("ftdi_write_data() failed");
 
211
            return -1;
 
212
        }
 
213
    }
 
214
    while (!drv_ula200_ftdi_read_response() && (repeat_count++ < ULA200_MAX_REPEATS));
 
215
 
 
216
    return 0;
 
217
}
 
218
 
 
219
/**
 
220
 * Reads a character from USB.
 
221
 *
 
222
 * @return a positive value between 0 and 255 indicates the character that
 
223
 *         has been read successfully, -1 indicates an error
 
224
 */
 
225
static int drv_ula200_ftdi_usb_read(void)
 
226
{
 
227
    unsigned char buffer[1];
 
228
    int err;
 
229
 
 
230
    while ((err = ftdi_read_data(Ftdi, buffer, 1)) == 0);
 
231
    return err >= 0 ? buffer[0] : -1;
 
232
}
 
233
 
 
234
 
 
235
/**
 
236
 * Reads the response of the display. Currently, key input is ignored
 
237
 * and only ACK / NACK is read.
 
238
 *
 
239
 * @return TRUE on success (ACK), FALSE on failure (NACK)
 
240
 */
 
241
static int drv_ula200_ftdi_read_response(void)
 
242
{
 
243
    int result = FALSE;
 
244
    int answer_read = FALSE;
 
245
    int ret;
 
246
    int ch;
 
247
 
 
248
    while (!answer_read) {
 
249
        /* wait until STX */
 
250
        do {
 
251
            ret = drv_ula200_ftdi_usb_read();
 
252
            /* ULA200_DEBUG("STX drv_ula200_ftdi_usb_read = %d", ret); */
 
253
        } while ((ret != ULA200_CH_STX) && (ret > 0));
 
254
 
 
255
        if (ret < 0) {
 
256
            return FALSE;
 
257
        }
 
258
 
 
259
        /* read next char */
 
260
        ch = drv_ula200_ftdi_usb_read();
 
261
        /* ULA200_DEBUG("drv_ula200_ftdi_usb_read = %d", ch); */
 
262
 
 
263
        switch (ch) {
 
264
        case 't':
 
265
            ch = drv_ula200_ftdi_usb_read();
 
266
            /* ULA200_DEBUG("drv_ula200_ftdi_usb_read = %d", ch); */
 
267
            /* ignore currently */
 
268
            break;
 
269
 
 
270
        case ULA200_CH_ACK:
 
271
            answer_read = TRUE;
 
272
            result = TRUE;
 
273
            break;
 
274
 
 
275
        case ULA200_CH_NAK:
 
276
            answer_read = TRUE;
 
277
            result = FALSE;
 
278
            break;
 
279
 
 
280
        default:
 
281
            answer_read = TRUE;
 
282
            ULA200_ERROR("Read invalid answer");
 
283
        }
 
284
 
 
285
        /* wait until ETX */
 
286
        do {
 
287
            ret = drv_ula200_ftdi_usb_read();
 
288
            /* ULA200_DEBUG("ETX drv_ula200_ftdi_usb_read = %d", ret); */
 
289
        } while ((ret != ULA200_CH_ETX) && (ret > 0));
 
290
 
 
291
        if (ret < 0) {
 
292
            return FALSE;
 
293
        }
 
294
    }
 
295
 
 
296
    return result;
 
297
}
 
298
 
 
299
static int drv_ula200_ftdi_enable_raw_mode(void)
 
300
{
 
301
    unsigned char command[3];
 
302
 
 
303
    command[0] = 'R';
 
304
    command[1] = 'E';
 
305
    command[2] = '1';
 
306
    return drv_ula200_ftdi_write_command(command, 3);
 
307
}
 
308
 
 
309
 
 
310
/**
 
311
 * Writes raw data (access the HD44780 registers directly.
 
312
 *
 
313
 * @param[in] flags ULA200_RS_DATA or ULA200_RS_INSTR
 
314
 * @param[in] ch the real data
 
315
 * @return 0 on success, a negative value on error
 
316
 */
 
317
static int drv_ula200_ftdi_rawdata(unsigned char flags, unsigned char ch)
 
318
{
 
319
    unsigned char command[3];
 
320
    int err;
 
321
 
 
322
    command[0] = 'R';
 
323
    command[1] = flags == ULA200_RS_DATA ? '2' : '0';
 
324
    command[2] = ch;
 
325
    err = drv_ula200_ftdi_write_command(command, 3);
 
326
    if (err < 0) {
 
327
        ULA200_ERROR("ula200_ftdi_write_command() failed");
 
328
        return -1;
 
329
    }
 
330
 
 
331
    return 0;
 
332
}
 
333
 
 
334
/**
 
335
 * Sets the cursor position.
 
336
 *
 
337
 * @param[in] x the x coordinate of the position
 
338
 * @param[in] y the y coordinate of the position
 
339
 * @return 0 on success, a negative value on error
 
340
 */
 
341
static int drv_ula200_set_position(int x, int y)
 
342
{
 
343
    unsigned char command[3];
 
344
    int err;
 
345
 
 
346
    if (y >= 2) {
 
347
        y -= 2;
 
348
        x += DCOLS;             /* XXX: multiply by 2? */
 
349
    }
 
350
 
 
351
    command[0] = ULA200_CMD_POSITION;
 
352
    command[1] = x;
 
353
    command[2] = y;
 
354
    err = drv_ula200_ftdi_write_command(command, 3);
 
355
    if (err < 0) {
 
356
        ULA200_ERROR("ula200_ftdi_write_command() failed");
 
357
    }
 
358
 
 
359
    return err;
 
360
}
 
361
 
 
362
/**
 
363
 * Sends the text
 
364
 *
 
365
 * @param[in] data the data bytes
 
366
 * @param[in] len the number of valid bytes in @p data
 
367
 * @return 0 on success, a negative value on error
 
368
 */
 
369
static int drv_ula200_send_text(const unsigned char *data, int len)
 
370
{
 
371
    unsigned char buffer[ULA200_BUFFER_LENGTH];
 
372
    int err;
 
373
 
 
374
    if (len > ULA200_MAXLEN) {
 
375
        return -EINVAL;
 
376
    }
 
377
 
 
378
    buffer[0] = ULA200_CMD_STRING;
 
379
    buffer[1] = len;
 
380
    memcpy(buffer + 2, data, len);
 
381
    buffer[2 + len] = 0;        /* only necessary for the debug message */
 
382
 
 
383
    /* ULA200_DEBUG("Text: =%s= (%d)", buffer+2, len); */
 
384
 
 
385
    err = drv_ula200_ftdi_write_command(buffer, len + 2);
 
386
    if (err < 0) {
 
387
        ULA200_ERROR("ula200_ftdi_write_command() failed");
 
388
        return -1;
 
389
    }
 
390
 
 
391
    return 0;
 
392
}
 
393
 
 
394
/**
 
395
 * Sends one character.
 
396
 *
 
397
 * @param[in] ch the character to send
 
398
 * @return 0 on success, a negative value on error
 
399
 */
 
400
static int drv_ula200_send_char(char ch)
 
401
{
 
402
    unsigned char buffer[2];
 
403
    int err;
 
404
 
 
405
    buffer[0] = ULA200_CMD_CHAR;
 
406
    buffer[1] = ch;
 
407
 
 
408
    err = drv_ula200_ftdi_write_command(buffer, 2);
 
409
    if (err < 0) {
 
410
        ULA200_ERROR("ula200_ftdi_write_command() failed");
 
411
        return -1;
 
412
    }
 
413
 
 
414
    return 0;
 
415
}
 
416
 
 
417
/**
 
418
 * Opens the ULA200 display. Uses libftdi to initialise the USB communication to
 
419
 * the display.
 
420
 *
 
421
 @ @return a value less then zero on failure, 0 on success
 
422
 */
 
423
static int drv_ula200_open(void)
 
424
{
 
425
    int err;
 
426
 
 
427
    /* check if the device was already open */
 
428
    if (Ftdi != NULL) {
 
429
        ULA200_ERROR("open called although device was already open");
 
430
        drv_ula200_close();
 
431
    }
 
432
 
 
433
    /* get memory for the device descriptor */
 
434
    Ftdi = malloc(sizeof(struct ftdi_context));
 
435
    if (Ftdi == NULL) {
 
436
        ULA200_ERROR("Memory allocation failed");
 
437
        return -1;
 
438
    }
 
439
 
 
440
    /* open the ftdi library */
 
441
    ftdi_init(Ftdi);
 
442
    Ftdi->usb_write_timeout = 20;
 
443
    Ftdi->usb_read_timeout = 20;
 
444
 
 
445
    /* open the device */
 
446
    err = ftdi_usb_open(Ftdi, ULA200_VENDOR_ID, ULA200_PRODUCT_ID);
 
447
    if (err < 0) {
 
448
        ULA200_ERROR("ftdi_usb_open() failed");
 
449
        free(Ftdi);
 
450
        Ftdi = NULL;
 
451
        return -1;
 
452
    }
 
453
 
 
454
    /* set the baudrate */
 
455
    err = ftdi_set_baudrate(Ftdi, ULA200_BAUDRATE);
 
456
    if (err < 0) {
 
457
        ULA200_ERROR("ftdi_set_baudrate() failed");
 
458
        ftdi_usb_close(Ftdi);
 
459
        free(Ftdi);
 
460
        Ftdi = NULL;
 
461
        return -1;
 
462
    }
 
463
    /* set communication parameters */
 
464
    err = ftdi_set_line_property(Ftdi, ULA200_DATABITS, ULA200_STOPBITS, ULA200_PARITY);
 
465
    if (err < 0) {
 
466
        ULA200_ERROR("ftdi_set_line_property() failed");
 
467
        ftdi_usb_close(Ftdi);
 
468
        free(Ftdi);
 
469
        Ftdi = NULL;
 
470
        return -1;
 
471
    }
 
472
 
 
473
    return 0;
 
474
}
 
475
 
 
476
/**
 
477
 * Closes the display.
 
478
 *
 
479
 * @return 0 on success, a negative value on failure
 
480
 */
 
481
static int drv_ula200_close(void)
 
482
{
 
483
    ULA200_TRACE();
 
484
 
 
485
    ftdi_usb_purge_buffers(Ftdi);
 
486
    ftdi_usb_close(Ftdi);
 
487
    ftdi_deinit(Ftdi);
 
488
 
 
489
    free(Ftdi);
 
490
    Ftdi = NULL;
 
491
 
 
492
    return 0;
 
493
}
 
494
 
 
495
/**
 
496
 * Clears the contents of the display.
 
497
 *
 
498
 * @return 0 on success, a negative value on error
 
499
 */
 
500
static void drv_ula200_clear(void)
 
501
{
 
502
    unsigned const char command[] = { ULA200_CMD_CLEAR };
 
503
    int err;
 
504
 
 
505
    ULA200_TRACE();
 
506
 
 
507
    err = drv_ula200_ftdi_write_command(command, 1);
 
508
    if (err < 0) {
 
509
        ULA200_ERROR("ula200_ftdi_write_command() failed");
 
510
    }
 
511
}
 
512
 
 
513
/**
 
514
 * Writes data to the display.
 
515
 *
 
516
 * @param[in] row the row where the data should be written to
 
517
 * @param[in] col the column where the data should be written to
 
518
 * @param[in] data the data that should actually be written
 
519
 * @param[in] len the number of valid bytes in @p data
 
520
 */
 
521
static void drv_ula200_write(const int row, const int col, const char *data, int len)
 
522
{
 
523
    int ret;
 
524
 
 
525
    /* do the cursor positioning here */
 
526
    ret = drv_ula200_set_position(col, row);
 
527
    if (ret < 0) {
 
528
        ULA200_ERROR("drv_ula200_set_position() failed");
 
529
        return;
 
530
    }
 
531
 
 
532
    /* send string to the display */
 
533
    if (len == 1) {
 
534
        ret = drv_ula200_send_char(data[0]);
 
535
    } else {
 
536
        ret = drv_ula200_send_text((unsigned char *) data, len);
 
537
    }
 
538
    if (ret < 0) {
 
539
        ULA200_ERROR("drv_ula200_send_text() failed");
 
540
        return;
 
541
    }
 
542
}
 
543
 
 
544
/* text mode displays only */
 
545
static void drv_ula200_defchar(const int ascii, const unsigned char *matrix)
 
546
{
 
547
    int err, i;
 
548
 
 
549
    if (ascii >= 8) {
 
550
        ULA200_ERROR("Invalid value in drv_ula200_defchar");
 
551
        return;
 
552
    }
 
553
 
 
554
    /* Tell the HD44780 we will redefine char number 'ascii' */
 
555
    err = drv_ula200_ftdi_rawdata(ULA200_RS_INSTR, ULA200_SETCHAR | (ascii * 8));
 
556
    if (err < 0) {
 
557
        ULA200_ERROR("drv_ula200_ftdi_rawdata() failed");
 
558
        return;
 
559
    }
 
560
 
 
561
    /* Send the subsequent rows */
 
562
    for (i = 0; i < YRES; i++) {
 
563
        err = drv_ula200_ftdi_rawdata(ULA200_RS_DATA, *matrix++ & 0x1f);
 
564
        if (err < 0) {
 
565
            ULA200_ERROR("ula200_ftdi_rawdata() failed");
 
566
            return;
 
567
        }
 
568
    }
 
569
}
 
570
 
 
571
/**
 
572
 * Controls the backlight of the ULA200 display.
 
573
 *
 
574
 * @param[in] backlight a negative value if the backlight should be turned off,
 
575
 *            a positive value if it should be turned on
 
576
 * @return 0 on success, any other value on failure
 
577
 */
 
578
static int drv_ula200_backlight(int backlight)
 
579
{
 
580
    unsigned char cmd[2] = { ULA200_CMD_BACKLIGHT };
 
581
    int ret;
 
582
 
 
583
    if (backlight <= 0) {
 
584
        backlight = '0';
 
585
    } else {
 
586
        backlight = '1';
 
587
    }
 
588
 
 
589
    cmd[1] = backlight;
 
590
    ret = drv_ula200_ftdi_write_command(cmd, 2);
 
591
    if (ret < 0) {
 
592
        ULA200_ERROR("ula200_ftdi_write_command() failed");
 
593
    }
 
594
 
 
595
    return backlight == '1';
 
596
}
 
597
 
 
598
/**
 
599
 * Starts the display.
 
600
 *
 
601
 * @param[in] section the section of the configuration file
 
602
 * @return 0 on success, a negative value on failure
 
603
 */
 
604
static int drv_ula200_start(const char *section)
 
605
{
 
606
    int rows = -1, cols = -1;
 
607
    char *s;
 
608
    int backlight = 0;
 
609
    int err;
 
610
 
 
611
    s = cfg_get(section, "Size", NULL);
 
612
    if (s == NULL || *s == '\0') {
 
613
        ULA200_ERROR("No '%s.Size' entry from %s", section, cfg_source());
 
614
        return -1;
 
615
    }
 
616
    if (sscanf(s, "%dx%d", &cols, &rows) != 2 || rows < 1 || cols < 1) {
 
617
        ULA200_ERROR("Bad %s.Size '%s' from %s", section, s, cfg_source());
 
618
        free(s);
 
619
        return -1;
 
620
    }
 
621
 
 
622
    DROWS = rows;
 
623
    DCOLS = cols;
 
624
 
 
625
    /* open communication with the display */
 
626
    err = drv_ula200_open();
 
627
    if (err < 0) {
 
628
        return -1;
 
629
    }
 
630
 
 
631
    cfg_number(section, "Backlight", 0, 0, 1, &backlight);
 
632
    err = drv_ula200_backlight(backlight);
 
633
    if (err < 0) {
 
634
        ULA200_ERROR("drv_ula200_backlight() failed");
 
635
        return -1;
 
636
    }
 
637
 
 
638
    /* clear display */
 
639
    drv_ula200_clear();
 
640
 
 
641
    /* enable raw mode for defining own chars */
 
642
    drv_ula200_ftdi_enable_raw_mode();
 
643
 
 
644
    return 0;
 
645
}
 
646
 
 
647
/****************************************/
 
648
/***            plugins               ***/
 
649
/****************************************/
 
650
 
 
651
/**
 
652
 * Backlight plugin
 
653
 */
 
654
static void plugin_backlight(RESULT * result, RESULT * arg1)
 
655
{
 
656
    double backlight;
 
657
 
 
658
    backlight = drv_ula200_backlight(R2N(arg1));
 
659
    SetResult(&result, R_NUMBER, &backlight);
 
660
}
 
661
 
 
662
/****************************************/
 
663
/***        exported functions        ***/
 
664
/****************************************/
 
665
 
 
666
/**
 
667
 * list models
 
668
 *
 
669
 * @return 0 on success, a negative value on failure
 
670
 */
 
671
int drv_ula200_list(void)
 
672
{
 
673
    printf("ULA200");
 
674
    return 0;
 
675
}
 
676
 
 
677
/**
 
678
 * initialize driver & display
 
679
 *
 
680
 * @param[in] section the name of the section in the configuration file
 
681
 * @param[in] quiet TRUE on quiet mode
 
682
 * @return 0 on success, any negative error value on failure
 
683
 */
 
684
/* use this function for a text display */
 
685
int drv_ula200_init(const char *section, const int quiet)
 
686
{
 
687
    WIDGET_CLASS wc;
 
688
    int ret;
 
689
 
 
690
    ULA200_INFO("%s", "$Rev: 1126 $");
 
691
 
 
692
    /* display preferences */
 
693
    XRES = ULA200_CELLWIDTH;    /* pixel width of one char  */
 
694
    YRES = ULA200_CELLHEIGHT;   /* pixel height of one char  */
 
695
    CHARS = 7;                  /* number of user-defineable characters */
 
696
    CHAR0 = 1;                  /* ASCII of first user-defineable char */
 
697
    GOTO_COST = 4;              /* number of bytes a goto command requires */
 
698
 
 
699
    /* real worker functions */
 
700
    drv_generic_text_real_write = drv_ula200_write;
 
701
    drv_generic_text_real_defchar = drv_ula200_defchar;
 
702
 
 
703
    /* start display */
 
704
    if ((ret = drv_ula200_start(section)) != 0) {
 
705
        return ret;
 
706
    }
 
707
 
 
708
    if (!quiet) {
 
709
        char buffer[40];
 
710
        qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
 
711
        if (drv_generic_text_greet(buffer, "ULA 200")) {
 
712
            sleep(3);
 
713
            drv_ula200_clear();
 
714
        }
 
715
    }
 
716
 
 
717
    /* initialize generic text driver */
 
718
    if ((ret = drv_generic_text_init(section, Name)) != 0)
 
719
        return ret;
 
720
 
 
721
    /* initialize generic icon driver */
 
722
    if ((ret = drv_generic_text_icon_init()) != 0)
 
723
        return ret;
 
724
 
 
725
    /* initialize generic bar driver */
 
726
    if ((ret = drv_generic_text_bar_init(0)) != 0)
 
727
        return ret;
 
728
 
 
729
    /* add fixed chars to the bar driver */
 
730
    drv_generic_text_bar_add_segment(0, 0, 255, 32);    /* ASCII  32 = blank */
 
731
 
 
732
    /* register text widget */
 
733
    wc = Widget_Text;
 
734
    wc.draw = drv_generic_text_draw;
 
735
    widget_register(&wc);
 
736
 
 
737
    /* register icon widget */
 
738
    wc = Widget_Icon;
 
739
    wc.draw = drv_generic_text_icon_draw;
 
740
    widget_register(&wc);
 
741
 
 
742
    /* register bar widget */
 
743
    wc = Widget_Bar;
 
744
    wc.draw = drv_generic_text_bar_draw;
 
745
    widget_register(&wc);
 
746
 
 
747
    /* register plugins */
 
748
    AddFunction("LCD::backlight", -1, plugin_backlight);
 
749
 
 
750
    return 0;
 
751
}
 
752
 
 
753
/**
 
754
 * close driver & display
 
755
 *
 
756
 * @param[in] quiet TRUE on quiet mode
 
757
 * @return 0 on success, any negative error value on failure
 
758
 */
 
759
/* use this function for a text display */
 
760
int drv_ula200_quit(int quiet)
 
761
{
 
762
    ULA200_INFO("shutting down.");
 
763
 
 
764
    drv_generic_text_quit();
 
765
 
 
766
    /* turn backlight off */
 
767
    drv_ula200_backlight(0);
 
768
 
 
769
    /* clear display */
 
770
    drv_ula200_clear();
 
771
 
 
772
    /* say goodbye... */
 
773
    if (!quiet) {
 
774
        drv_generic_text_greet("goodbye!", NULL);
 
775
    }
 
776
 
 
777
    debug("closing connection");
 
778
    drv_ula200_close();
 
779
 
 
780
    return 0;
 
781
}
 
782
 
 
783
/* use this one for a text display */
 
784
DRIVER drv_ula200 = {
 
785
    .name = Name,
 
786
    .list = drv_ula200_list,
 
787
    .init = drv_ula200_init,
 
788
    .quit = drv_ula200_quit,
 
789
};
 
790
 
 
791
/* :indentSize=4:tabSize=8:noTabs=false: */