1
/* $Id: drv_Sample.c 773 2007-02-25 12:39:09Z michael $
2
* $URL: https://ssl.bulix.org/svn/lcd4linux/branches/0.10.1/drv_Sample.c $
4
* lcd4linux driver for EFN LED modules (manufacturer: COMFILE/South Korea)
5
* connected to the ethernet to serial converter EUG 100 (manufacturer ELV/
8
* Up to 256 EFN LED modules listen on a serial bus (9600 BAUD, 1 stop bit,
9
* no parity) and are controlled by a 3 byte protocol:
11
* Byte 2: <module address>
12
* Byte 3: <Ascii value of character to be diplayed>
13
* The module address of each EFN LED module is set hy solder bridges.
14
* The driver expects the EFN LED modules to be configured starting
15
* from address 1. The EFN LED module set to address 1 is the right
18
* The EUG 100 is an ethernet to seriell converter. The IP address
19
* can be set by dhcp. It listens on ports 1000 (data) and 1001
20
* (configuration). Data received on port 1000 is sent onto the serial bus,
21
* while data sent to configuration port sets format of the EUG 100's
23
* Due to a bug in the firmware, the transmission is interrupted if '\0' (0x00)
24
* is received on port 1000. Consequently, none of the EFN LED modules shall
25
* be set to address 0.
27
* Copyright (C) 2010 Tilman Glötzner <tilmanglotzner@hotmail.com>
29
* This file is part of LCD4Linux.
31
* LCD4Linux is free software; you can redistribute it and/or modify
32
* it under the terms of the GNU General Public License as published by
33
* the Free Software Foundation; either version 2, or (at your option)
36
* LCD4Linux is distributed in the hope that it will be useful,
37
* but WITHOUT ANY WARRANTY; without even the implied warranty of
38
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39
* GNU General Public License for more details.
41
* You should have received a copy of the GNU General Public License
42
* along with this program; if not, write to the Free Software
43
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
51
* struct DRIVER drv_EFN
63
#include <sys/types.h>
64
#include <sys/socket.h>
65
#include <netinet/in.h>
74
#include "widget_text.h"
75
#include "widget_icon.h"
76
#include "widget_bar.h"
79
/* text mode display */
80
#include "drv_generic_text.h"
84
static char Name[] = "EFN";
90
static void drv_EFN_clear(void);
92
/****************************************/
93
/*** hardware dependant functions ***/
94
/****************************************/
96
static int drv_EFN_open(const char *section)
98
int sockfd_conf, portno_conf, n;
99
struct sockaddr_in serv_addr;
100
struct sockaddr_in conf_addr;
101
struct hostent *server;
104
/* open tcp sockets to config port to EUG 100 t0 set serial parameter */
105
/* 9600 BAUD; no parity; 1 stop bit */
106
// socket to config EUG
107
portno_conf = Port + 1;
108
sockfd_conf = socket(AF_INET, SOCK_STREAM, 0);
109
if (sockfd_conf < 0) {
110
error("ERROR opening config socket");
113
// resolve DNS name of EFN server (= EUG 100)
114
server = gethostbyname(Host);
115
if (server == NULL) {
116
error("ERROR, no such host\n");
119
// socket addr for config socket
120
bzero((char *) &conf_addr, sizeof(struct sockaddr_in));
121
conf_addr.sin_family = AF_INET;
122
bcopy((char *) server->h_addr, (char *) &conf_addr.sin_addr.s_addr, server->h_length);
123
conf_addr.sin_port = htons(portno_conf);
125
// open config socket
126
if (connect(sockfd_conf, (struct sockaddr *) &conf_addr, sizeof(struct sockaddr_in)) < 0) {
127
error("ERROR connecting to config port");
130
// sent config message
138
n = write(sockfd_conf, buffer, 3);
140
error("ERROR writing to config socket");
148
DataSocket = socket(AF_INET, SOCK_STREAM, 0);
149
if (DataSocket < 0) {
150
error("ERROR opening data socket");
153
// socket addr for data socket
154
bzero((char *) &serv_addr, sizeof(struct sockaddr_in));
155
serv_addr.sin_family = AF_INET;
156
bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length);
157
serv_addr.sin_port = htons(Port);
159
if (connect(DataSocket, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr_in)) < 0) {
160
error("ERROR connecting to data socket");
167
static int drv_EFN_close(void)
169
/* close whatever port you've opened */
176
/* dummy function that sends something to the display */
177
static void drv_EFN_send(const char *data, const unsigned int len)
181
// transport command stirng to EUG 100
182
n = write(DataSocket, data, len);
185
error("%s:drv_EFN_send: Failed to write to data socket\n", Name);
189
printf("EFN_send: ");
192
printf("0x%02x ",data[i]);
199
/* text mode displays only */
200
static void drv_EFN_clear(void)
203
int max_char, max_cmd, k;
205
max_char = DROWS * DCOLS;
206
max_cmd = 3 * max_char; // each EFN module expects 3 bytes
208
if ((cmd = malloc(max_cmd)) == NULL) {
209
error("%s : Failed to allocate memory in drv_Sample_write\n", Name);
212
/* do whatever is necessary to clear the display */
213
for (k = 0; k < max_char; k++) {
214
cmd[(3 * k) + 0] = 0xff;
215
cmd[(3 * k) + 1] = k + 1;
216
cmd[(3 * k) + 2] = ' ';
218
drv_EFN_send(cmd, max_cmd);
219
drv_EFN_send(cmd, max_cmd);
226
/* text mode displays only */
227
static void drv_EFN_write(const int row, const int col, const char *data, int len)
230
int offset, i, k, max_char, max_cmd;
232
max_char = DROWS * DCOLS;
233
max_cmd = 3 * max_char; // each LED blocks expects a 3 byte sequence
236
if ((cmd = (char *) malloc(max_cmd)) == NULL) {
237
error("%s : Failed to allocate memory in drv_Sample_write\n", Name);
240
/* do the cursor positioning here */
242
offset = ((row) * DCOLS) + col;
244
for (i = max_char - offset, k = 0; ((i > 0) && (k < len)); i--, k++) {
245
cmd[(3 * k) + 0] = 0xff;
246
cmd[(3 * k) + 1] = i;
247
cmd[(3 * k) + 2] = data[k];
250
/* send string to the display twice (to make transmission
252
drv_EFN_send(cmd, 3 * (k));
253
drv_EFN_send(cmd, 3 * (k));
260
static void drv_EFN_defchar(const int ascii, const unsigned char *matrix)
262
error("%s:drv_EFN_defchar: Function not supported by EFN modules\n", Name);
265
/* start text mode display */
266
static int drv_EFN_start(const char *section)
268
int rows = -1, cols = -1;
271
s = cfg_get(section, "Host", NULL);
273
if (s == NULL || *s == '\0') {
274
error("%s: no '%s.Host' entry from %s", Name, section, cfg_source());
278
if (sscanf(s, "%s", &Host) != 1) {
279
error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source());
284
if (cfg_number(section, "Port", 1000, 0, 65535, &Port) < 0)
288
s = cfg_get(section, "Size", NULL);
289
if (s == NULL || *s == '\0') {
290
error("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
293
if (sscanf(s, "%dx%d", &cols, &rows) != 2 || rows < 1 || cols < 1) {
294
error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source());
302
/* open communication with the display */
303
if (drv_EFN_open(section) < 0) {
307
/* initialize display */
308
drv_EFN_clear(); /* clear display */
315
/****************************************/
317
/****************************************/
320
/****************************************/
321
/*** widget callbacks ***/
322
/****************************************/
327
/****************************************/
328
/*** exported functions ***/
329
/****************************************/
333
int drv_EFN_list(void)
335
printf("EFN LED modules + EUG100 Ethernet to serial convertor");
340
/* initialize driver & display */
341
/* use this function for a text display */
342
int drv_EFN_init(const char *section, const int quiet)
347
info("%s: %s", Name, "$Rev: 773 $");
349
/* display preferences */
351
/* real worker functions */
352
drv_generic_text_real_write = drv_EFN_write;
353
drv_generic_text_real_defchar = drv_EFN_defchar;
357
if ((ret = drv_EFN_start(section)) != 0)
362
qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
368
/* initialize generic text driver */
369
if ((ret = drv_generic_text_init(section, Name)) != 0)
373
/* register text widget */
375
wc.draw = drv_generic_text_draw;
376
widget_register(&wc);
384
/* close driver & display */
385
/* use this function for a text display */
386
int drv_EFN_quit(const int quiet)
389
info("%s: shutting down.", Name);
391
drv_generic_text_quit();
398
drv_generic_text_greet("goodbye!", NULL);
401
debug("closing connection");
407
/* close driver & display */
408
/* use this one for a text display */
411
.list = drv_EFN_list,
412
.init = drv_EFN_init,
413
.quit = drv_EFN_quit,