root/branches/volker_dev/drv_picoLCD.c

Revision 771, 10.0 kB (checked in by michael, 23 months ago)

lots of compiler warnings removed, C++-style comments removed, changed struc initialisation from 'field:value' to '.field=value'

  • Property svn:keywords set to Id URL Rev
Line 
1/* $Id$
2 * $URL$
3 *
4 * driver for picoLCD displays from mini-box.com
5 *
6 * Copyright (C) 2005 Michael Reinelt <reinelt@eunet.at>
7 * Copyright (C) 2005, 2006, 2007 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
8 *
9 * Copyright (C) 2007 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_picoLCD
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 "widget.h"
57#include "widget_text.h"
58#include "widget_icon.h"
59#include "widget_bar.h"
60#include "drv.h"
61#include "drv_generic_text.h"
62#include "drv_generic_gpio.h"
63#include "drv_generic_keypad.h"
64
65
66
67#define picoLCD_VENDOR  0x04d8
68#define picoLCD_DEVICE  0x0002
69
70static char Name[] = "picoLCD";
71
72static unsigned int gpo = 0;
73
74static char *Buffer;
75static char *BufPtr;
76
77static usb_dev_handle *lcd;
78extern int usb_debug;
79
80
81
82/****************************************/
83/***  hardware dependant functions    ***/
84/****************************************/
85
86static int drv_pL_open(void)
87{
88    struct usb_bus *busses, *bus;
89    struct usb_device *dev;
90    char driver[1024];
91    char product[1024];
92    char manufacturer[1024];
93    char serialnumber[1024];
94    int ret;
95
96    lcd = NULL;
97
98    info("%s: scanning for picoLCD...", Name);
99
100    usb_debug = 0;
101
102    usb_init();
103    usb_find_busses();
104    usb_find_devices();
105    busses = usb_get_busses();
106
107    for (bus = busses; bus; bus = bus->next) {
108  for (dev = bus->devices; dev; dev = dev->next) {
109      if ((dev->descriptor.idVendor == picoLCD_VENDOR) && (dev->descriptor.idProduct == picoLCD_DEVICE)) {
110
111    info("%s: found picoLCD on bus %s device %s", Name, bus->dirname, dev->filename);
112
113    lcd = usb_open(dev);
114
115    ret = usb_get_driver_np(lcd, 0, driver, sizeof(driver));
116
117    if (ret == 0) {
118        info("%s: interface 0 already claimed by '%s'", Name, driver);
119        info("%s: attempting to detach driver...", Name);
120        if (usb_detach_kernel_driver_np(lcd, 0) < 0) {
121      error("%s: usb_detach_kernel_driver_np() failed!", Name);
122      return -1;
123        }
124    }
125
126    usb_set_configuration(lcd, 1);
127    usleep(100);
128
129    if (usb_claim_interface(lcd, 0) < 0) {
130        error("%s: usb_claim_interface() failed!", Name);
131        return -1;
132    }
133
134    usb_set_altinterface(lcd, 0);
135
136    usb_get_string_simple(lcd, dev->descriptor.iProduct, product, sizeof(product));
137    usb_get_string_simple(lcd, dev->descriptor.iManufacturer, manufacturer, sizeof(manufacturer));
138    usb_get_string_simple(lcd, dev->descriptor.iSerialNumber, serialnumber, sizeof(serialnumber));
139
140    info("%s: Manufacturer='%s' Product='%s' SerialNumber='%s'", Name, manufacturer, product, serialnumber);
141
142    return 0;
143      }
144  }
145    }
146    error("%s: could not find a picoLCD", Name);
147    return -1;
148}
149
150
151static int drv_pL_close(void)
152{
153    usb_release_interface(lcd, 0);
154    usb_close(lcd);
155
156    return 0;
157}
158
159
160static void drv_pL_send(unsigned char *data, int size)
161{
162    usb_interrupt_write(lcd, USB_ENDPOINT_OUT + 1, (char *) data, size, 1000);
163}
164
165
166static void drv_pL_clear(void)
167{
168    unsigned char cmd[1] = { 0x94 };  /* clear display */
169    drv_pL_send(cmd, 1);
170}
171
172static int drv_pL_contrast(int contrast)
173{
174    unsigned char cmd[2] = { 0x92 };  /* set contrast */
175
176    if (contrast < 0)
177  contrast = 0;
178    if (contrast > 255)
179  contrast = 255;
180
181    cmd[1] = contrast;
182    drv_pL_send(cmd, 2);
183
184    return contrast;
185}
186
187
188static int drv_pL_backlight(int backlight)
189{
190    unsigned char cmd[2] = { 0x91 };  /* set backlight */
191
192    if (backlight < 0)
193  backlight = 0;
194    if (backlight > 1)
195  backlight = 1;
196
197    cmd[1] = backlight;
198    drv_pL_send(cmd, 2);
199
200    return backlight;
201}
202
203static int drv_pL_gpo(int num, int val)
204{
205    unsigned char cmd[2] = { 0x81 };  /* set GPO */
206
207    if (num < 0)
208  num = 0;
209    if (num > 7)
210  num = 7;
211
212    if (val < 0)
213  val = 0;
214    if (val > 1)
215  val = 1;
216
217    /* set led bit to 1 or 0 */
218    if (val)
219  gpo |= 1 << num;
220    else
221  gpo &= ~(1 << num);
222
223    cmd[1] = gpo;
224    drv_pL_send(cmd, 2);
225
226    return val;
227}
228
229
230static void drv_pL_write(const int row, const int col, const char *data, int len)
231{
232    unsigned char cmd[64];
233    int i;
234
235    cmd[0] = 0x98;    /* goto/write */
236    cmd[1] = row;
237    cmd[2] = col;
238    cmd[3] = len;
239
240    i = 4;
241    while (len--) {
242  cmd[i++] = *data++;
243    }
244
245    drv_pL_send(cmd, i);
246}
247
248static void drv_pL_defchar(const int ascii, const unsigned char *matrix)
249{
250    unsigned char cmd[10] = { 0x9c }; /* define character */
251    int i;
252
253    cmd[1] = ascii;
254    for (i = 0; i < 8; i++) {
255  cmd[i + 2] = *matrix++ & 0x1f;
256    }
257
258    drv_pL_send(cmd, 10);
259}
260
261
262static int drv_pL_start(const char *section, const int quiet)
263{
264    int rows = -1, cols = -1;
265    int value;
266    char *s;
267
268    s = cfg_get(section, "Size", NULL);
269    if (s == NULL || *s == '\0') {
270  error("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
271  return -1;
272    }
273    if (sscanf(s, "%dx%d", &cols, &rows) != 2 || rows < 1 || cols < 1) {
274  error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source());
275  free(s);
276  return -1;
277    }
278
279    DROWS = rows;
280    DCOLS = cols;
281
282    if (drv_pL_open() < 0) {
283  return -1;
284    }
285
286    /* Init the command buffer */
287    Buffer = (char *) malloc(1024);
288    if (Buffer == NULL) {
289  error("%s: coommand buffer could not be allocated: malloc() failed", Name);
290  return -1;
291    }
292    BufPtr = Buffer;
293
294    if (cfg_number(section, "Contrast", 0, 0, 255, &value) > 0) {
295  info("Setting contrast to %d", value);
296  drv_pL_contrast(value);
297    }
298
299    if (cfg_number(section, "Backlight", 0, 0, 1, &value) > 0) {
300  info("Setting backlight to %d", value);
301  drv_pL_backlight(value);
302    }
303
304    drv_pL_clear();   /* clear display */
305
306    if (!quiet) {
307  char buffer[40];
308  qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
309  if (drv_generic_text_greet(buffer, "http://www.picolcd.com")) {
310      sleep(3);
311      drv_pL_clear();
312  }
313    }
314
315    return 0;
316}
317
318
319/****************************************/
320/***            plugins               ***/
321/****************************************/
322
323static void plugin_contrast(RESULT * result, RESULT * arg1)
324{
325    double contrast;
326
327    contrast = drv_pL_contrast(R2N(arg1));
328    SetResult(&result, R_NUMBER, &contrast);
329}
330
331static void plugin_backlight(RESULT * result, RESULT * arg1)
332{
333    double backlight;
334
335    backlight = drv_pL_backlight(R2N(arg1));
336    SetResult(&result, R_NUMBER, &backlight);
337}
338
339static void plugin_gpo(RESULT * result, RESULT * argv[])
340{
341    double gpo;
342    gpo = drv_pL_gpo(R2N(argv[0]), R2N(argv[1]));
343    SetResult(&result, R_NUMBER, &gpo);
344}
345
346
347/****************************************/
348/***        widget callbacks          ***/
349/****************************************/
350
351
352/* using drv_generic_text_draw(W) */
353/* using drv_generic_text_icon_draw(W) */
354/* using drv_generic_text_bar_draw(W) */
355
356
357/****************************************/
358/***        exported functions        ***/
359/****************************************/
360
361
362/* list models */
363int drv_pL_list(void)
364{
365    printf("generic");
366    return 0;
367}
368
369
370/* initialize driver & display */
371int drv_pL_init(const char *section, const int quiet)
372{
373    WIDGET_CLASS wc;
374    int ret;
375
376    info("%s: %s", Name, "$Rev$");
377
378    /* display preferences */
379    XRES = 5;     /* pixel width of one char  */
380    YRES = 8;     /* pixel height of one char  */
381    CHARS = 8;      /* number of user-defineable characters */
382    CHAR0 = 0;      /* ASCII of first user-defineable char */
383    GPOS = 8;
384    INVALIDATE = 1;
385    GOTO_COST = 2;    /* number of bytes a goto command requires */
386
387    /* real worker functions */
388    drv_generic_text_real_write = drv_pL_write;
389    drv_generic_text_real_defchar = drv_pL_defchar;
390    drv_generic_gpio_real_set = drv_pL_gpo;
391
392    /* start display */
393    if ((ret = drv_pL_start(section, quiet)) != 0)
394  return ret;
395
396    /* initialize generic text driver */
397    if ((ret = drv_generic_text_init(section, Name)) != 0)
398  return ret;
399
400    /* initialize generic icon driver */
401    if ((ret = drv_generic_text_icon_init()) != 0)
402  return ret;
403
404    /* initialize generic bar driver */
405    if ((ret = drv_generic_text_bar_init(0)) != 0)
406  return ret;
407
408    drv_generic_text_bar_add_segment(0, 0, 255, 32);
409
410    /* GPO's init */
411    if ((ret = drv_generic_gpio_init(section, Name)) != 0)
412  return ret;
413
414    /* register text widget */
415    wc = Widget_Text;
416    wc.draw = drv_generic_text_draw;
417    widget_register(&wc);
418
419    /* register icon widget */
420    wc = Widget_Icon;
421    wc.draw = drv_generic_text_icon_draw;
422    widget_register(&wc);
423
424    /* register bar widget */
425    wc = Widget_Bar;
426    wc.draw = drv_generic_text_bar_draw;
427    widget_register(&wc);
428
429    /* register plugins */
430    AddFunction("LCD::contrast", -1, plugin_contrast);
431    AddFunction("LCD::backlight", -1, plugin_backlight);
432    AddFunction("LCD::gpo", -1, plugin_gpo);
433
434    return 0;
435}
436
437
438/* close driver & display */
439int drv_pL_quit(const int quiet)
440{
441
442    info("%s: shutting down.", Name);
443
444    drv_generic_text_quit();
445
446    /* clear display */
447    drv_pL_clear();
448
449    /* say goodbye... */
450    if (!quiet) {
451  drv_generic_text_greet("goodbye!", NULL);
452    }
453
454    drv_pL_close();
455
456    if (Buffer) {
457  free(Buffer);
458  Buffer = NULL;
459  BufPtr = Buffer;
460    }
461
462    return (0);
463}
464
465
466DRIVER drv_picoLCD = {
467    .name = Name,
468    .list = drv_pL_list,
469    .init = drv_pL_init,
470    .quit = drv_pL_quit,
471};
Note: See TracBrowser for help on using the browser.