1 /* This is the LCDproc driver for the vfd on the Aopen EA65, based on
2 the Crystal Fontz driver.
4 Copyright (C) 2004 ????
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */
20 /*Initial modification of CFontz driver by Kent Williams (c) 2005*/
21 /*some additions and updates by Karsten Festag (c) 2007*/
41 typedef struct driver_private_data
{
47 unsigned char *framebuf
;
50 // Vars for the server core
51 MODULE_EXPORT
char *api_version
= API_VERSION
;
52 MODULE_EXPORT
int stay_in_foreground
= 1;
53 MODULE_EXPORT
int supports_multiple
= 0;
54 MODULE_EXPORT
int does_input
= 0;
55 MODULE_EXPORT
int does_output
= 1;
56 MODULE_EXPORT
char *symbol_prefix
= "EA65_";
58 /////////////////////////////////////////////////////////////////
59 // Opens com port and sets baud correctly...
62 EA65_init (Driver
*drvthis
)
64 debug(RPT_INFO
, "EA65: init(%p)", drvthis
);
67 char device
[] = "/dev/ttyS1";
68 /*speed is fixed at 9600*/
71 /* Allocate and store private data */
73 p
= (PrivateData
*) malloc(sizeof(PrivateData
));
76 if (drvthis
->store_private_ptr(drvthis
, p
))
79 //// initialize private data
80 // Width and Height are fixed
83 // Make sure the frame buffer is there...
84 p
->framebuf
= (unsigned char *) malloc (p
->width
* p
->height
);
85 memset (p
->framebuf
, ' ', p
->width
* p
->height
);
88 // Which backlight brightness
89 p
->brightness
= drvthis
->config_get_int ( drvthis
->name
, "Brightness" , 0 , DEFAULT_BRIGHTNESS
);
90 if (0 <= p
->brightness
&& p
->brightness
<= 1000) {
91 if (p
->brightness
< 300) {
92 p
->brightness
= 0x00; // command char that turns button LEDs off
93 } else if (p
->brightness
>= 700 ) {
94 p
->brightness
= 0x01; // command char that turns button LEDs on full
96 p
->brightness
= 0x02; // command char that turns button LEDs on half
99 report (RPT_WARNING
, "EA65_init: Brightness must be between 0 and 1000. Using default value.\n");
100 p
->brightness
= DEFAULT_BRIGHTNESS
;
103 // Which backlight-off "brightness"
104 p
->offbrightness
= drvthis
->config_get_int ( drvthis
->name
, "OffBrightness" , 0 , DEFAULT_OFFBRIGHTNESS
);
105 if (0 <= p
->offbrightness
&& p
->offbrightness
<= 1000) {
106 if (p
->offbrightness
< 300) {
107 p
->offbrightness
= 0x00; // command char that turns button LEDs off
108 } else if (p
->offbrightness
>= 700) {
109 p
->offbrightness
= 0x01; // command char that turns button LEDs on full
111 p
->offbrightness
= 0x02; // command char that turns button LEDs on half
114 report (RPT_WARNING
, "EA65_init: OffBrightness must be between 0 and 1000. Using default value.\n");
115 p
->offbrightness
= DEFAULT_OFFBRIGHTNESS
;
118 // Set up io port correctly, and open it...
119 debug( RPT_DEBUG
, "EA65: Opening serial device: %s", device
);
120 struct termios portset
;
121 p
->fd
= open (device
, O_RDWR
| O_NOCTTY
| O_NDELAY
);
123 report (RPT_ERR
, "EA65_init: failed (%s)\n", strerror (errno
));
126 tcgetattr (p
->fd
, &portset
);
128 #ifdef HAVE_CFMAKERAW
130 cfmakeraw( &portset
);
133 portset
.c_iflag
&= ~( IGNBRK
| BRKINT
| PARMRK
| ISTRIP
134 | INLCR
| IGNCR
| ICRNL
| IXON
);
135 portset
.c_oflag
&= ~OPOST
;
136 portset
.c_lflag
&= ~( ECHO
| ECHONL
| ICANON
| ISIG
| IEXTEN
);
137 portset
.c_cflag
&= ~( CSIZE
| PARENB
| CRTSCTS
);
138 portset
.c_cflag
|= CS8
| CREAD
| CLOCAL
;
142 cfsetospeed (&portset
, speed
);
143 cfsetispeed (&portset
, B0
);
146 tcsetattr (p
->fd
, TCSANOW
, &portset
);
148 report (RPT_DEBUG
, "EA65_init: done\n");
153 /////////////////////////////////////////////////////////////////
157 EA65_close (Driver
*drvthis
)
159 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
163 if(p
->framebuf
) free (p
->framebuf
);
167 /////////////////////////////////////////////////////////////////
168 // Returns the display width
171 EA65_width (Driver
*drvthis
)
173 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
178 /////////////////////////////////////////////////////////////////
179 // Returns the display height
182 EA65_height (Driver
*drvthis
)
184 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
189 //////////////////////////////////////////////////////////////////
190 // Flushes all output to the lcd...
193 EA65_flush (Driver
*drvthis
)
197 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
199 // Need to check for and deal with unsupported chars or the display gets a little upset
200 for (i
=0; i
< p
->width
* p
->height
; i
++) {
201 if ( (p
->framebuf
[i
] >= 224 && p
->framebuf
[i
] <= 253) || // is a lowercase accented letter
202 (p
->framebuf
[i
] >= 97 && p
->framebuf
[i
] <= 122) ) { // is a lowercase letter
203 p
->framebuf
[i
] -= 32; // -> convert to upper case
205 if (p
->framebuf
[i
] >= 48 && p
->framebuf
[i
] <= 57) { } // is a number -> do nothing
206 else if (p
->framebuf
[i
] >= 65 && p
->framebuf
[i
] <= 90) { } // is a uppercase letter -> do nothing
207 else if (p
->framebuf
[i
] == 42 || p
->framebuf
[i
] == 43 ||
208 p
->framebuf
[i
] == 45 || p
->framebuf
[i
] == 47 ) { } // is +,-,/,* -> do nothing
209 // Now lets replace some accented characters with remotely similar looking ones
210 else if (p
->framebuf
[i
] == 223) p
->framebuf
[i
] = 83; // use an "S" instead of "ß"
211 else if (p
->framebuf
[i
] >= 192 && p
->framebuf
[i
] <= 197) // use an "A"
213 else if (p
->framebuf
[i
] >= 200 && p
->framebuf
[i
] <= 203) // use an "E"
215 else if (p
->framebuf
[i
] >= 204 && p
->framebuf
[i
] <= 207) // use an "I"
217 else if (p
->framebuf
[i
] >= 210 && p
->framebuf
[i
] <= 214) // use an "O"
219 else if (p
->framebuf
[i
] >= 217 && p
->framebuf
[i
] <= 220) // use an "U"
221 else p
->framebuf
[i
] = 32; // other characters replaced by a space
223 snprintf(out
, sizeof(out
), "%c%c%c%c%c", 0xa0, 0x00, 0x80, 0x8a, 0x8a);
224 write(p
->fd
, out
, 5);
225 write(p
->fd
, p
->framebuf
, p
->width
* p
->height
);
228 /////////////////////////////////////////////////////////////////
229 // Prints a character on the lcd display, at position (x,y). The
230 // upper-left is (1,1), and the lower right should be (9,1).
233 EA65_chr (Driver
*drvthis
, int x
, int y
, char c
)
235 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
240 //if (c < 32 && c >= 0)
243 // For V2 of the firmware to get the block to display right
244 //if (newfirmware && c==-1) {
248 p
->framebuf
[(y
* p
->width
) + x
] = c
;
251 /////////////////////////////////////////////////////////////////
252 // Sets the backlight on or off
255 EA65_backlight (Driver
*drvthis
, int on
)
257 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
261 snprintf (out
, sizeof(out
), "%c%c%c%c%c", 0xa0, 0x00, 0x50, 0x81, p
->brightness
);
263 snprintf (out
, sizeof(out
), "%c%c%c%c%c", 0xa0, 0x00, 0x50, 0x81, p
->offbrightness
);
265 write (p
->fd
, out
, 5);
268 /////////////////////////////////////////////////////////////////
269 // Clears the LCD screen
272 EA65_clear (Driver
*drvthis
)
274 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
276 memset (p
->framebuf
, ' ', p
->width
* p
->height
);
280 /////////////////////////////////////////////////////////////////
281 // Prints a string on the lcd display, at position (x,y). The
282 // upper-left is (1,1), and the lower right should be (9,1).
285 EA65_string (Driver
*drvthis
, int x
, int y
, const char string
[])
287 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
291 x
-= 1; // Convert 1-based coords to 0-based...
294 for (i
= 0; string
[i
]; i
++) {
296 // Check for buffer overflows...
297 if ((y
* p
->width
) + x
+ i
> (p
->width
* p
->height
))
299 p
->framebuf
[(y
* p
->width
) + x
+ i
] = string
[i
];
303 /////////////////////////////////////////////////////////////////
304 //// Turns the recording LED on or off as desired.
307 EA65_output (Driver
*drvthis
, int on
)
309 PrivateData
*p
= (PrivateData
*) drvthis
->private_data
;
313 snprintf (out
, sizeof(out
), "%c%c%c%c%c", 0xa0,0x00,0x32,0x81,0x01);
315 snprintf (out
, sizeof(out
), "%c%c%c%c%c", 0xa0,0x00,0x32,0x81,0x00);
317 write (p
->fd
, out
, 5);