add fake-lcd

This commit is contained in:
Olaf Rempel 2011-04-25 13:26:34 +02:00
parent eea740593b
commit 341eafb18d
2 changed files with 54 additions and 13 deletions

63
lcd.c
View File

@ -3,6 +3,7 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
@ -13,7 +14,6 @@
#include "logging.h" #include "logging.h"
#define _LCD_DEBUG 1 #define _LCD_DEBUG 1
#define _LCD_FAKE 1
#define LCD_RESET_TIMEOUT_US 250000 /* 250ms */ #define LCD_RESET_TIMEOUT_US 250000 /* 250ms */
#define LCD_RESET_RETRY_TIMEOUT 10 /* 10s */ #define LCD_RESET_RETRY_TIMEOUT 10 /* 10s */
@ -40,6 +40,7 @@ enum lcdstate {
struct lcddev { struct lcddev {
int fd; int fd;
struct event_fd *fakedevice_event;
struct termios oldtio; struct termios oldtio;
enum lcdstate state; enum lcdstate state;
@ -62,7 +63,16 @@ struct lcddev {
void lcd_close(struct lcddev *dev) void lcd_close(struct lcddev *dev)
{ {
if (dev->fakedevice_event == NULL) {
tcsetattr(dev->fd, TCSANOW, &dev->oldtio); tcsetattr(dev->fd, TCSANOW, &dev->oldtio);
} else {
int fd = event_get_fd(dev->fakedevice_event);
event_remove_fd(dev->fakedevice_event);
dev->fakedevice_event = NULL;
close(fd);
}
close(dev->fd); close(dev->fd);
} }
@ -96,6 +106,39 @@ static int lcd_open(struct lcddev *dev, const char *device)
return 0; return 0;
} }
static int lcd_fakedevice_reply(int fd, void *privdata)
{
struct lcddev *dev = (struct lcddev *)privdata;
char buf[32];
if (read(fd, buf, sizeof(buf)) <= 0) {
dev->fakedevice_event = NULL;
return -1;
}
char reset_expect[] = A125_CMD_RESET;
if (memcmp(buf, reset_expect, sizeof(reset_expect)) == 0) {
char actinfo_cmd[] = A125_EVENT_ACTINFO;
write(fd, actinfo_cmd, sizeof(actinfo_cmd));
}
return 0;
}
static int lcd_fakedevice_open(struct lcddev *dev)
{
int fd[2];
if (socketpair(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0 , fd) < 0) {
log_print(LOG_ERROR, "socketpair() failed");
return -1;
}
dev->fd = fd[0];
dev->fakedevice_event = event_add_readfd(NULL, fd[1], lcd_fakedevice_reply, dev);
return 0;
}
#if (_LCD_DEBUG > 1) #if (_LCD_DEBUG > 1)
static void lcd_dump(const char *prefix, int len, int size, const char *buf) static void lcd_dump(const char *prefix, int len, int size, const char *buf)
{ {
@ -135,7 +178,6 @@ static int lcd_write(struct lcddev *dev, char *buf, int len)
return retval; return retval;
} }
#if (_LCD_FAKE == 0)
static int lcd_reset_retry_timeout_cb(void *privdata) static int lcd_reset_retry_timeout_cb(void *privdata)
{ {
struct lcddev *dev = (struct lcddev *)privdata; struct lcddev *dev = (struct lcddev *)privdata;
@ -157,7 +199,6 @@ static int lcd_reset_timeout_cb(void *privdata)
return -1; /* singleshot */ return -1; /* singleshot */
} }
#endif
void lcd_reset(struct lcddev *dev) void lcd_reset(struct lcddev *dev)
{ {
@ -170,17 +211,10 @@ void lcd_reset(struct lcddev *dev)
dev->backlight_state = -1; dev->backlight_state = -1;
#if (_LCD_FAKE == 0)
dev->state = LCD_STATE_INITIALIZING; dev->state = LCD_STATE_INITIALIZING;
struct timeval tv = { .tv_usec = LCD_RESET_TIMEOUT_US }; struct timeval tv = { .tv_usec = LCD_RESET_TIMEOUT_US };
dev->reset_timeout = event_add_timeout(&tv, lcd_reset_timeout_cb, dev); dev->reset_timeout = event_add_timeout(&tv, lcd_reset_timeout_cb, dev);
#else
dev->state = LCD_STATE_READY;
/* trigger application to set data */
dev->event_callback(dev, LCD_EVENT_INIT, dev->event_privdata);
#endif
} }
static int lcd_backlight(struct lcddev *dev, int mode) static int lcd_backlight(struct lcddev *dev, int mode)
@ -368,7 +402,14 @@ struct lcddev * lcd_init(const char *devicename,
memset(dev, 0, sizeof(struct lcddev)); memset(dev, 0, sizeof(struct lcddev));
if (lcd_open(dev, devicename) < 0) { int retval;
if (devicename != NULL) {
retval = lcd_open(dev, devicename);
} else {
retval = lcd_fakedevice_open(dev);
}
if (retval < 0) {
free(dev); free(dev);
return NULL; return NULL;
} }

View File

@ -186,7 +186,7 @@ int main(int argc, char *argv[])
log_print(LOG_EVERYTIME, PROGNAME" started (pid:%d)", getpid()); log_print(LOG_EVERYTIME, PROGNAME" started (pid:%d)", getpid());
while (1) { while (1) {
struct lcddev *dev = lcd_init(LCD_DEVICE, &button_callback, NULL); struct lcddev *dev = lcd_init(NULL /*LCD_DEVICE*/, &button_callback, NULL);
if (dev == NULL) if (dev == NULL)
break; break;