root/branches/0.10.1/drv_LCDTerm.c

Revision 773, 6.6 kB (checked in by michael, 23 months ago)

backport 768:771 from trunk, version changed to 0.10.1-RC2

  • Property svn:keywords set to Id URL Rev
Line 
1/* $Id$
2 * $URL$
3 *
4 * driver for the LCDTerm serial-to-HD44780 adapter boards
5 * http://www.bobblick.com/techref/projects/lcdterm/lcdterm.html
6 *
7 * Copyright (C) 2005 Michael Reinelt <reinelt@eunet.at>
8 * Copyright (C) 2005 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
9 *
10 * This file is part of LCD4Linux.
11 *
12 * LCD4Linux is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * LCD4Linux is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 */
27
28/*
29 *
30 * exported fuctions:
31 *
32 * struct DRIVER drv_LCDTerm
33 *
34 */
35
36#include "config.h"
37
38#include <stdlib.h>
39#include <unistd.h>
40
41#include "debug.h"
42#include "cfg.h"
43#include "qprintf.h"
44#include "plugin.h"
45#include "widget.h"
46#include "widget_text.h"
47#include "widget_icon.h"
48#include "widget_bar.h"
49#include "drv.h"
50#include "drv_generic_text.h"
51#include "drv_generic_serial.h"
52
53#define LCD_CLEAR 0x03
54#define LCD_CMD   0x12
55#define LCD_DATA  0x14
56
57static char Name[] = "LCDTerm";
58
59
60/****************************************/
61/***  hardware dependant functions    ***/
62/****************************************/
63
64static void drv_LT_clear(void)
65{
66    char cmd[1];
67
68    cmd[0] = LCD_CLEAR;   /* clear display */
69    drv_generic_serial_write(cmd, 1); /* clear screen */
70}
71
72
73static int drv_LT_send(const char request, const char value)
74{
75    char buf[2];
76
77    buf[0] = request;
78    buf[1] = value;
79    drv_generic_serial_write(buf, 2);
80
81    return 0;
82}
83
84
85static void drv_LT_command(const char cmd)
86{
87    drv_LT_send(LCD_CMD, cmd);
88}
89
90
91static void drv_LT_write(const int row, const int col, const char *data, int len)
92{
93    int pos;
94
95    /* 16x4 Displays use a slightly different layout */
96    if (DCOLS == 16 && DROWS == 4) {
97  pos = (row % 2) * 64 + (row / 2) * 16 + col;
98    } else {
99  pos = (row % 2) * 64 + (row / 2) * 20 + col;
100    }
101
102    drv_LT_command(0x80 | pos);
103
104    while (len--) {
105  drv_LT_send(LCD_DATA, *data++);
106    }
107}
108
109static void drv_LT_defchar(const int ascii, const unsigned char *matrix)
110{
111    int i;
112
113    drv_LT_command(0x40 | 8 * ascii);
114
115    for (i = 0; i < 8; i++) {
116  drv_LT_send(LCD_DATA, *matrix++ & 0x1f);
117    }
118}
119
120
121static int drv_LT_start(const char *section, const int quiet)
122{
123    int rows = -1, cols = -1;
124    char *s;
125
126    if (drv_generic_serial_open(section, Name, 0) < 0)
127  return -1;
128
129    s = cfg_get(section, "Size", NULL);
130    if (s == NULL || *s == '\0') {
131  error("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
132  return -1;
133    }
134    if (sscanf(s, "%dx%d", &cols, &rows) != 2 || rows < 1 || cols < 1) {
135  error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source());
136  free(s);
137  return -1;
138    }
139
140    DROWS = rows;
141    DCOLS = cols;
142
143    /* initialize display */
144    drv_LT_command(0x29); /* 8 Bit mode, 1/16 duty cycle, 5x8 font */
145    drv_LT_command(0x08); /* Display off, cursor off, blink off */
146    drv_LT_command(0x0c); /* Display on, cursor off, blink off */
147    drv_LT_command(0x06); /* curser moves to right, no shift */
148
149    drv_LT_clear();   /* clear display */
150
151    if (!quiet) {
152  char buffer[40];
153  qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
154  if (drv_generic_text_greet(buffer, "www.bwct.de")) {
155      sleep(3);
156      drv_LT_clear();
157  }
158    }
159
160    return 0;
161}
162
163
164/****************************************/
165/***            plugins               ***/
166/****************************************/
167
168/* none */
169
170
171/****************************************/
172/***        widget callbacks          ***/
173/****************************************/
174
175
176/* using drv_generic_text_draw(W) */
177/* using drv_generic_text_icon_draw(W) */
178/* using drv_generic_text_bar_draw(W) */
179
180
181/****************************************/
182/***        exported functions        ***/
183/****************************************/
184
185
186/* list models */
187int drv_LT_list(void)
188{
189    printf("generic");
190    return 0;
191}
192
193
194/* initialize driver & display */
195int drv_LT_init(const char *section, const int quiet)
196{
197    WIDGET_CLASS wc;
198    int asc255bug;
199    int ret;
200
201    info("%s: %s", Name, "$Rev$");
202
203    /* display preferences */
204    XRES = 5;     /* pixel width of one char  */
205    YRES = 8;     /* pixel height of one char  */
206    CHARS = 8;      /* number of user-defineable characters */
207    CHAR0 = 0;      /* ASCII of first user-defineable char */
208
209    /* Fixme: */
210    GOTO_COST = 2;    /* number of bytes a goto command requires */
211
212    /* real worker functions */
213    drv_generic_text_real_write = drv_LT_write;
214    drv_generic_text_real_defchar = drv_LT_defchar;
215
216
217    /* start display */
218    if ((ret = drv_LT_start(section, quiet)) != 0)
219  return ret;
220
221    /* initialize generic text driver */
222    if ((ret = drv_generic_text_init(section, Name)) != 0)
223  return ret;
224
225    /* initialize generic icon driver */
226    if ((ret = drv_generic_text_icon_init()) != 0)
227  return ret;
228
229    /* initialize generic bar driver */
230    if ((ret = drv_generic_text_bar_init(0)) != 0)
231  return ret;
232
233    /* add fixed chars to the bar driver */
234    /* most displays have a full block on ascii 255, but some have kind of  */
235    /* an 'inverted P'. If you specify 'asc255bug 1 in the config, this */
236    /* char will not be used, but rendered by the bar driver */
237    cfg_number(section, "asc255bug", 0, 0, 1, &asc255bug);
238    drv_generic_text_bar_add_segment(0, 0, 255, 32);  /* ASCII  32 = blank */
239    if (!asc255bug)
240  drv_generic_text_bar_add_segment(255, 255, 255, 255); /* ASCII 255 = block */
241
242    /* register text widget */
243    wc = Widget_Text;
244    wc.draw = drv_generic_text_draw;
245    widget_register(&wc);
246
247    /* register icon widget */
248    wc = Widget_Icon;
249    wc.draw = drv_generic_text_icon_draw;
250    widget_register(&wc);
251
252    /* register bar widget */
253    wc = Widget_Bar;
254    wc.draw = drv_generic_text_bar_draw;
255    widget_register(&wc);
256
257    /* register plugins */
258    /* none */
259
260    return 0;
261}
262
263
264/* close driver & display */
265int drv_LT_quit(const int quiet)
266{
267
268    info("%s: shutting down.", Name);
269
270    drv_generic_text_quit();
271
272    /* clear display */
273    drv_LT_clear();
274
275    /* say goodbye... */
276    if (!quiet) {
277  drv_generic_text_greet("goodbye!", NULL);
278    }
279
280    drv_generic_serial_close();
281
282    return (0);
283}
284
285
286DRIVER drv_LCDTerm = {
287    .name = Name,
288    .list = drv_LT_list,
289    .init = drv_LT_init,
290    .quit = drv_LT_quit,
291};
Note: See TracBrowser for help on using the browser.