source: npl/mediabox/lcdproc_edwin/src/server/drivers/hd44780.c @ c5c522c

gcc484ntopperl-5.22
Last change on this file since c5c522c was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 10.9 KB
Line 
1/* Driver module for Hitachi HD44780 based Optrex DMC-20481 LCD display
2 * The module is operated in it's 4 bit-mode to be connected to a single
3 * 8 bit-port
4 *
5 * Copyright (c) 1998 Richard Rognlie       GNU Public License 
6 *                    <rrognlie@gamerz.net>
7 *
8 * Large quantities of this code lifted (nearly verbatim) from
9 * the lcd4.c module of lcdtext.  Copyright (C) 1997 Matthias Prinke
10 * <m.prinke@trashcan.mcnet.de> and covered by GNU's GPL.
11 * In particular, this program is free software and comes WITHOUT
12 * ANY WARRANTY.
13 *
14 * Matthias stole (er, adapted) the code from the package lcdtime by
15 * Benjamin Tse (blt@mundil.cs.mu.oz.au), August/October 1995
16 * which uses the LCD-controller's 8 bit-mode.
17 * References: port.h             by <damianf@wpi.edu>
18 *             Data Sheet LTN211, Philips
19 *             Various FAQs and TXTs about Hitachi's LCD Controller HD44780 -
20 *                www.paranoia.com/~filipg is a good starting point  ???   
21 */
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <unistd.h>
26#include <termios.h>
27#include <fcntl.h>
28#include <string.h>
29#include <errno.h>
30#include <sys/perm.h>
31
32#include "../../shared/str.h"
33
34#include "lcd.h"
35#include "hd44780.h"
36#include "drv_base.h"
37
38
39lcd_logical_driver *HD44780;
40
41#define EN 64
42#define RW 32
43#define RS 16
44
45#ifndef LPTPORT
46unsigned int port = 0x378;
47#else
48unsigned int port = LPTPORT;
49#endif
50
51static int lcd_x=0;
52static int lcd_y=0;
53
54static void HD44780_linewrap(int on);
55static void HD44780_autoscroll(int on);
56
57static int lp;
58
59static void HD44780_senddata(unsigned char flags, unsigned char ch)
60{
61        unsigned char h = ch >> 4;
62        unsigned char l = ch & 15;
63
64        port_out(lp, 128 | EN | flags | h);     usleep(1); port_out(lp, 128 | flags | h);
65        port_out(lp, 128 | EN | flags | l);     usleep(1); port_out(lp, 128 | flags | l);
66}
67
68/////////////////////////////////////////////////////////////////
69// Opens com port and sets baud correctly...
70//
71int HD44780_init(lcd_logical_driver *driver, char *args)
72{
73   char *argv[64];
74   int argc;
75   int i;
76   
77   
78   HD44780 = driver;
79   
80
81   argc = get_args(argv, args, 64);
82
83   for(i=0; i<argc; i++)
84   {
85      //printf("Arg(%i): %s\n", i, argv[i]);
86      if(0 == strcmp(argv[i], "-p")  ||
87         0 == strcmp(argv[i], "--port"))
88      {
89         if(i + 1 > argc) {
90            fprintf(stderr, "HD44780_init: %s requires an argument\n",
91                    argv[i]);
92            return -1;
93         }
94         printf("Sorry, runtime lpt-port switching not yet implemented...\n");
95         //strcpy(device, argv[++i]);
96      }
97      else if(0 == strcmp(argv[i], "-c")  ||
98         0 == strcmp(argv[i], "--contrast"))
99      {
100         if(i + 1 > argc) {
101            fprintf(stderr, "HD44780_init: %s requires an argument\n",
102                    argv[i]);
103            return -1;
104         }
105         printf("Sorry, contrast changing not yet implemented...\n");
106         //contrast = atoi(argv[++i]);
107      }
108      else if(0 == strcmp(argv[i], "-h")  ||
109         0 == strcmp(argv[i], "--help"))
110      {
111         printf("LCDproc HD44780 driver\n"
112                "\t-p\t--port\tSelect the output device to use [0x%x]\n"
113                "\t-c\t--contrast\tSet the initial contrast [default]\n"
114                "\t-h\t--help\t\tShow this help information\n",
115                port);
116         return -1;
117      }
118      else
119      {
120         printf("Invalid parameter: %s\n", argv[i]);
121      }
122     
123   }
124   
125   
126   
127   // Set up io port correctly, and open it...
128        if ((ioperm(port,1,1)) == -1) {
129                fprintf(stderr, "HD44780_init: failed (%s)\n", strerror(errno));
130                return -1;
131        }
132
133        lp = port;
134
135        // init HD44780
136        port_out(lp, 128 | EN | 3);     usleep(1); port_out(lp, 128 | 3);               usleep(5000);
137        port_out(lp, 128 | EN | 3);     usleep(1); port_out(lp, 128 | 3);               usleep(150);
138        port_out(lp, 128 | EN | 3);     usleep(1); port_out(lp, 128 | 3);
139        // now in 8-bit mode...  set 4-bit mode
140        port_out(lp, 128 | EN | 2);     usleep(1); port_out(lp, 128 | 2);
141        // now in 4-bit mode...   set 2 line, small char mode
142        HD44780_senddata(0, 32 | 8);
143
144        //clear
145        HD44780_senddata(0, 1);
146        // set lcd on (4), cursor_on (2), and cursor_blink(1)
147        HD44780_senddata(0, 8 | 4 | 0 | 0);
148
149        // Set display-specific stuff..
150        //HD44780_linewrap(1);
151        //HD44780_autoscroll(1);
152
153        // Make sure the frame buffer is there... 
154        if (!HD44780->framebuf)
155                HD44780->framebuf = (unsigned char *) malloc(lcd.wid * lcd.hgt);
156
157        if (!HD44780->framebuf) {
158           //HD44780_close();
159                return -1;
160        }
161
162
163        // Set the functions the driver supports...
164
165        driver->clear =      (void *)-1;
166        driver->string =     (void *)-1;
167        driver->chr =        (void *)-1;
168        driver->vbar =       HD44780_vbar;
169        driver->init_vbar =  HD44780_init_vbar;
170        driver->hbar =       HD44780_hbar;
171        driver->init_hbar =  HD44780_init_hbar;
172        driver->num =        HD44780_num;
173        driver->init_num =   HD44780_init_num;
174       
175        driver->init =       HD44780_init;
176        driver->close =      (void *)-1;
177        driver->flush =      HD44780_flush;
178        driver->flush_box =  HD44780_flush_box;
179        driver->contrast =   HD44780_contrast;
180        driver->backlight =  HD44780_backlight;
181        driver->set_char =   HD44780_set_char;
182        driver->icon =       HD44780_icon;
183        driver->draw_frame = HD44780_draw_frame;
184
185        driver->getkey =     NULL;
186       
187        return lp;
188}
189
190
191
192/////////////////////////////////////////////////////////////////
193// Clean-up
194//
195/*
196void HD44780_close()
197{
198  drv_base_close();
199}
200*/
201
202static void HD44780_position(int x, int y)
203{
204        int val = x + (y%2) * 0x40;
205        if (y>=2) val += 20;
206
207        HD44780_senddata(0,128|val);
208
209        lcd_x = x;
210        lcd_y = y;
211}
212
213void HD44780_flush()
214{
215  HD44780_draw_frame(lcd.framebuf);
216}
217
218
219void HD44780_flush_box(int lft, int top, int rgt, int bot)
220{
221        int x,y;
222 
223//  printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot);
224
225        for (y=top; y<=bot; y++) {
226                HD44780_position(lft,y);
227
228                for (x=lft ; x<=rgt ; x++) {
229                        HD44780_senddata(RS,lcd.framebuf[(y*20)+x]);
230                }
231                //write(fd, lcd.framebuf[(y*20)+lft, rgt-lft+1]);
232        }
233
234}
235
236
237/////////////////////////////////////////////////////////////////
238// Changes screen contrast (0-255; 140 seems good)
239//
240int HD44780_contrast(int contrast)
241{
242  return 0;
243}
244
245/////////////////////////////////////////////////////////////////
246// Sets the backlight on or off -- can be done quickly for
247// an intermediate brightness...
248//
249void HD44780_backlight(int on)
250{
251}
252
253
254/////////////////////////////////////////////////////////////////
255// Toggle the built-in linewrapping feature
256//
257static void HD44780_linewrap(int on)
258{
259}
260
261/////////////////////////////////////////////////////////////////
262// Toggle the built-in automatic scrolling feature
263//
264static void HD44780_autoscroll(int on)
265{
266        HD44780_senddata(0,4 | on * 2);
267}
268
269
270/////////////////////////////////////////////////////////////////
271// Sets up for vertical bars.  Call before lcd.vbar()
272//
273void HD44780_init_vbar()
274{
275  char a[] = {
276    0,0,0,0,0,
277    0,0,0,0,0,
278    0,0,0,0,0,
279    0,0,0,0,0,
280    0,0,0,0,0,
281    0,0,0,0,0,
282    0,0,0,0,0,
283    1,1,1,1,1,
284  };
285  char b[] = {
286    0,0,0,0,0,
287    0,0,0,0,0,
288    0,0,0,0,0,
289    0,0,0,0,0,
290    0,0,0,0,0,
291    0,0,0,0,0,
292    1,1,1,1,1,
293    1,1,1,1,1,
294  };
295  char c[] = {
296    0,0,0,0,0,
297    0,0,0,0,0,
298    0,0,0,0,0,
299    0,0,0,0,0,
300    0,0,0,0,0,
301    1,1,1,1,1,
302    1,1,1,1,1,
303    1,1,1,1,1,
304  };
305  char d[] = {
306    0,0,0,0,0,
307    0,0,0,0,0,
308    0,0,0,0,0,
309    0,0,0,0,0,
310    1,1,1,1,1,
311    1,1,1,1,1,
312    1,1,1,1,1,
313    1,1,1,1,1,
314  };
315  char e[] = {
316    0,0,0,0,0,
317    0,0,0,0,0,
318    0,0,0,0,0,
319    1,1,1,1,1,
320    1,1,1,1,1,
321    1,1,1,1,1,
322    1,1,1,1,1,
323    1,1,1,1,1,
324  };
325  char f[] = {
326    0,0,0,0,0,
327    0,0,0,0,0,
328    1,1,1,1,1,
329    1,1,1,1,1,
330    1,1,1,1,1,
331    1,1,1,1,1,
332    1,1,1,1,1,
333    1,1,1,1,1,
334  };
335  char g[] = {
336    0,0,0,0,0,
337    1,1,1,1,1,
338    1,1,1,1,1,
339    1,1,1,1,1,
340    1,1,1,1,1,
341    1,1,1,1,1,
342    1,1,1,1,1,
343    1,1,1,1,1,
344  };
345
346  HD44780_set_char(1,a);
347  HD44780_set_char(2,b);
348  HD44780_set_char(3,c);
349  HD44780_set_char(4,d);
350  HD44780_set_char(5,e);
351  HD44780_set_char(6,f);
352  HD44780_set_char(7,g);
353 
354}
355
356/////////////////////////////////////////////////////////////////
357// Inits horizontal bars...
358//
359void HD44780_init_hbar()
360{
361
362  char a[] = {
363    1,0,0,0,0,
364    1,0,0,0,0,
365    1,0,0,0,0,
366    1,0,0,0,0,
367    1,0,0,0,0,
368    1,0,0,0,0,
369    1,0,0,0,0,
370    1,0,0,0,0,
371  };
372  char b[] = {
373    1,1,0,0,0,
374    1,1,0,0,0,
375    1,1,0,0,0,
376    1,1,0,0,0,
377    1,1,0,0,0,
378    1,1,0,0,0,
379    1,1,0,0,0,
380    1,1,0,0,0,
381  };
382  char c[] = {
383    1,1,1,0,0,
384    1,1,1,0,0,
385    1,1,1,0,0,
386    1,1,1,0,0,
387    1,1,1,0,0,
388    1,1,1,0,0,
389    1,1,1,0,0,
390    1,1,1,0,0,
391  };
392  char d[] = {
393    1,1,1,1,0,
394    1,1,1,1,0,
395    1,1,1,1,0,
396    1,1,1,1,0,
397    1,1,1,1,0,
398    1,1,1,1,0,
399    1,1,1,1,0,
400    1,1,1,1,0,
401  };
402
403  HD44780_set_char(1,a);
404  HD44780_set_char(2,b);
405  HD44780_set_char(3,c);
406  HD44780_set_char(4,d);
407
408}
409
410/////////////////////////////////////////////////////////////////
411// Draws a vertical bar...
412//
413void HD44780_vbar(int x, int len)
414{
415        char map[9] = {32, 1, 2, 3, 4, 5, 6, 7, 255 };
416
417        int y;
418        for(y=lcd.hgt; y > 0 && len>0; y--) {
419                if (len >= lcd.cellhgt)
420                        drv_base_chr(x, y, 255);
421                else
422                        drv_base_chr(x, y, map[len]);
423
424                len -= lcd.cellhgt;
425        }
426 
427}
428
429/////////////////////////////////////////////////////////////////
430// Draws a horizontal bar to the right.
431//
432void HD44780_hbar(int x, int y, int len)
433{
434        char map[6] = { 32, 1, 2, 3, 4, 255  };
435
436        for (; x<=lcd.wid && len>0; x++) {
437                if (len >= lcd.cellwid)
438                        drv_base_chr(x,y,255);
439                else
440                        drv_base_chr(x, y, map[len]);
441
442                len -= lcd.cellwid;
443
444        }
445}
446
447
448/////////////////////////////////////////////////////////////////
449// Sets up for big numbers.
450//
451void HD44780_init_num()
452{
453        char out[3];
454        sprintf(out, "%cn", 254);
455        //write(fd, out, 2);
456}
457
458
459/////////////////////////////////////////////////////////////////
460// Writes a big number.
461//
462void HD44780_num(int x, int num)
463{
464  char out[5];
465  sprintf(out, "%c#%c%c", 254, x, num);
466  //write(fd, out, 4);
467}
468
469
470/////////////////////////////////////////////////////////////////
471// Sets a custom character from 0-7...
472//
473// For input, values > 0 mean "on" and values <= 0 are "off".
474//
475// The input is just an array of characters...
476//
477void HD44780_set_char(int n, char *dat)
478{
479        int row, col;
480        int letter;
481
482        if(n < 0 || n > 7) return;
483        if(!dat) return;
484
485        HD44780_senddata(0, 64 | n*8);
486
487        for(row=0; row<lcd.cellhgt; row++) {
488                letter = 0;
489                for(col=0; col<lcd.cellwid; col++) {
490                        letter <<= 1;
491                        letter |= (dat[(row*lcd.cellwid) + col] > 0);
492                }
493                HD44780_senddata(RS, letter);
494        }
495
496}
497
498
499void HD44780_icon(int which, char dest)
500{
501  char icons[3][5*8] = {
502   {
503     1,1,1,1,1,  // Empty Heart
504     1,0,1,0,1,
505     0,0,0,0,0,
506     0,0,0,0,0,
507     0,0,0,0,0,
508     1,0,0,0,1,
509     1,1,0,1,1,
510     1,1,1,1,1,
511   },   
512
513   {
514     1,1,1,1,1,  // Filled Heart
515     1,0,1,0,1,
516     0,1,0,1,0,
517     0,1,1,1,0,
518     0,1,1,1,0,
519     1,0,1,0,1,
520     1,1,0,1,1,
521     1,1,1,1,1,
522   },
523   
524   {
525     0,0,0,0,0,  // Ellipsis
526     0,0,0,0,0,
527     0,0,0,0,0,
528     0,0,0,0,0,
529     0,0,0,0,0,
530     0,0,0,0,0,
531     0,0,0,0,0,
532     1,0,1,0,1,
533   },
534   
535  };
536
537   
538  HD44780_set_char(dest, &icons[which][0]);
539}
540
541
542/////////////////////////////////////////////////////////////
543// Blasts a single frame onscreen, to the lcd...
544//
545// Input is a character array, sized lcd.wid*lcd.hgt
546//
547void HD44780_draw_frame(char *dat)
548{
549        int x,y;
550
551        if (!dat) return;
552
553        for (y=0; y<=3; y++) {
554                HD44780_position(0,y);
555
556                for (x=0 ; x<=19 ; x++) {
557                        HD44780_senddata(RS,dat[(y*lcd.wid)+x]);
558                }
559        }
560
561}
562
Note: See TracBrowser for help on using the repository browser.