|
|
@ -33,6 +33,7 @@ |
|
|
|
#include "logging.h" |
|
|
|
|
|
|
|
#define _LCD_DEBUG 1 |
|
|
|
#define _LCD_DUMMY 1 |
|
|
|
|
|
|
|
#define LCD_RESET_TIMEOUT_US 250000 /* 250ms */ |
|
|
|
#define LCD_RESET_RETRY_TIMEOUT 10 /* 10s */ |
|
|
@ -59,7 +60,9 @@ enum lcdstate { |
|
|
|
|
|
|
|
struct lcddev { |
|
|
|
int fd; |
|
|
|
#if (_LCD_DUMMY) |
|
|
|
struct event_fd *fakedevice_event; |
|
|
|
#endif /* (_LCD_DUMMY) */ |
|
|
|
struct termios oldtio; |
|
|
|
|
|
|
|
enum lcdstate state; |
|
|
@ -102,14 +105,17 @@ void lcd_close(struct lcddev *dev) |
|
|
|
dev->read_event = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
if (dev->fakedevice_event == NULL) { |
|
|
|
tcsetattr(dev->fd, TCSANOW, &dev->oldtio); |
|
|
|
|
|
|
|
} else { |
|
|
|
#if (_LCD_DUMMY) |
|
|
|
if (dev->fakedevice_event != NULL) { |
|
|
|
int fd = event_get_fd(dev->fakedevice_event); |
|
|
|
event_remove_fd(dev->fakedevice_event); |
|
|
|
dev->fakedevice_event = NULL; |
|
|
|
close(fd); |
|
|
|
|
|
|
|
} else |
|
|
|
#endif /* (_LCD_DUMMY) */ |
|
|
|
{ |
|
|
|
tcsetattr(dev->fd, TCSANOW, &dev->oldtio); |
|
|
|
} |
|
|
|
|
|
|
|
close(dev->fd); |
|
|
@ -120,7 +126,7 @@ static int lcd_open(struct lcddev *dev, const char *device) |
|
|
|
{ |
|
|
|
dev->fd = open(device, O_RDWR); |
|
|
|
if (dev->fd < 0) { |
|
|
|
log_print(LOG_ERROR, "failed to open '%s'", device); |
|
|
|
log_print(LOG_ERROR, "%s(): failed to open '%s'", __FUNCTION__, device); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
@ -138,7 +144,7 @@ static int lcd_open(struct lcddev *dev, const char *device) |
|
|
|
|
|
|
|
int err = tcsetattr(dev->fd, TCSAFLUSH, &newtio); |
|
|
|
if (err < 0) { |
|
|
|
log_print(LOG_ERROR, "failed to set termios"); |
|
|
|
log_print(LOG_ERROR, "%s(): failed to set termios", __FUNCTION__); |
|
|
|
close(dev->fd); |
|
|
|
return -1; |
|
|
|
} |
|
|
@ -146,6 +152,7 @@ static int lcd_open(struct lcddev *dev, const char *device) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
#if (_LCD_DUMMY) |
|
|
|
static int lcd_fakedevice_reply(int fd, void *privdata) |
|
|
|
{ |
|
|
|
struct lcddev *dev = (struct lcddev *)privdata; |
|
|
@ -169,8 +176,22 @@ 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"); |
|
|
|
if (socketpair(AF_LOCAL, SOCK_STREAM, 0 , fd) < 0) { |
|
|
|
log_print(LOG_ERROR, "%s(): socketpair() failed", __FUNCTION__); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
if (fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0) { |
|
|
|
log_print(LOG_ERROR, "%s(): fcntl(FD_CLOEXEC)", __FUNCTION__); |
|
|
|
close(fd[0]); |
|
|
|
close(fd[1]); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
if (fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0) { |
|
|
|
log_print(LOG_ERROR, "%s(): fcntl(FD_CLOEXEC)", __FUNCTION__); |
|
|
|
close(fd[0]); |
|
|
|
close(fd[1]); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
@ -178,19 +199,22 @@ static int lcd_fakedevice_open(struct lcddev *dev) |
|
|
|
dev->fakedevice_event = event_add_readfd(NULL, fd[1], lcd_fakedevice_reply, dev); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
#endif /* (_LCD_DUMMY) */ |
|
|
|
|
|
|
|
#if (_LCD_DEBUG > 1) |
|
|
|
static void lcd_dump(const char *prefix, int len, int size, const char *buf) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int pos = 0; |
|
|
|
char buf[256]; |
|
|
|
|
|
|
|
fprintf(stderr, "%s:[%d/%d]: ", prefix, len, size); |
|
|
|
for (i = 0; i < len; i++) |
|
|
|
fprintf(stderr, "0x%X ", (unsigned char)buf[i]); |
|
|
|
for (i = 0; i < len; i++) { |
|
|
|
pos += snprintf(buf, sizeof(buf) - pos, "0x%X ", (unsigned char)buf[i]); |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(stderr, "\n"); |
|
|
|
log_print(LOG_DEBUG, "%s:[%d/%d]: %s", prefix, len, size, buf); |
|
|
|
} |
|
|
|
#endif |
|
|
|
#endif /* (_LCD_DEBUG > 1) */ |
|
|
|
|
|
|
|
static int lcd_read(struct lcddev *dev, const char *buf, int len) |
|
|
|
{ |
|
|
@ -203,8 +227,8 @@ static int lcd_read(struct lcddev *dev, const char *buf, int len) |
|
|
|
cnt += retval; |
|
|
|
} |
|
|
|
#if (_LCD_DEBUG > 1) |
|
|
|
lcd_dump("lcd_read", cnt, len, buf); |
|
|
|
#endif |
|
|
|
lcd_dump(__FUNCTION__, cnt, len, buf); |
|
|
|
#endif /* (_LCD_DEBUG > 1) */ |
|
|
|
return (cnt != 0) ? cnt : retval; |
|
|
|
} |
|
|
|
|
|
|
@ -213,8 +237,8 @@ static int lcd_write(struct lcddev *dev, char *buf, int len) |
|
|
|
int retval = write(dev->fd, buf, len); |
|
|
|
|
|
|
|
#if (_LCD_DEBUG > 1) |
|
|
|
lcd_dump("lcd_write", retval, len, buf); |
|
|
|
#endif |
|
|
|
lcd_dump(__FUNCTION__, retval, len, buf); |
|
|
|
#endif /* (_LCD_DEBUG > 1) */ |
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
@ -243,8 +267,8 @@ static int lcd_reset_timeout_cb(void *privdata) |
|
|
|
void lcd_reset(struct lcddev *dev) |
|
|
|
{ |
|
|
|
#if (_LCD_DEBUG > 0) |
|
|
|
fprintf(stderr, "lcd_reset()\n"); |
|
|
|
#endif |
|
|
|
log_print(LOG_DEBUG, "%s()", __FUNCTION__); |
|
|
|
#endif /* (_LCD_DEBUG > 0) */ |
|
|
|
|
|
|
|
char cmd[] = A125_CMD_RESET; |
|
|
|
lcd_write(dev, cmd, sizeof(cmd)); |
|
|
@ -263,8 +287,8 @@ static int lcd_backlight(struct lcddev *dev, int mode) |
|
|
|
return -1; |
|
|
|
|
|
|
|
#if (_LCD_DEBUG > 0) |
|
|
|
fprintf(stderr, "lcd_backlight(%d)\n", mode); |
|
|
|
#endif |
|
|
|
log_print(LOG_DEBUG, "%s(%d)", __FUNCTION__, mode); |
|
|
|
#endif /* (_LCD_DEBUG > 0) */ |
|
|
|
|
|
|
|
if (dev->backlight_state != mode) { |
|
|
|
char cmd[] = A125_CMD_BACKLIGHT; |
|
|
@ -358,8 +382,8 @@ static int lcd_setline(struct lcddev *dev, int line, int len, const char *buf) |
|
|
|
cmd[20] = '\0'; |
|
|
|
|
|
|
|
#if (_LCD_DEBUG > 0) |
|
|
|
fprintf(stderr, "lcd_setline(%d, '%-16s')\n", line, cmd +4); |
|
|
|
#endif |
|
|
|
log_print(LOG_DEBUG, "%s(%d, '%-16s')", __FUNCTION__, line, cmd +4); |
|
|
|
#endif /* (_LCD_DEBUG > 0) */ |
|
|
|
|
|
|
|
lcd_write(dev, cmd, 20); |
|
|
|
return 0; |
|
|
@ -436,16 +460,19 @@ struct lcddev * lcd_init(const char *devicename, |
|
|
|
{ |
|
|
|
struct lcddev *dev = malloc(sizeof(struct lcddev)); |
|
|
|
if (dev == NULL) { |
|
|
|
log_print(LOG_ERROR, "lcd_init(): out of memory"); |
|
|
|
log_print(LOG_ERROR, "%s(): out of memory", __FUNCTION__); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
memset(dev, 0, sizeof(struct lcddev)); |
|
|
|
|
|
|
|
int retval; |
|
|
|
#if (_LCD_DUMMY) |
|
|
|
if (strncmp(devicename, "dummy", 5) == 0) { |
|
|
|
retval = lcd_fakedevice_open(dev); |
|
|
|
} else { |
|
|
|
} else |
|
|
|
#endif /* (_LCD_DUMMY) */ |
|
|
|
{ |
|
|
|
retval = lcd_open(dev, devicename); |
|
|
|
} |
|
|
|
|
|
|
|