/* * Copyright (C) 2011 Florian Streibelt * Licensed under GPL v3 or later * */ #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include /* POSIX terminal control definitions */ #include #include #include #include /* Posix 1003.1c threads */ #include #include int fd; int screensaver; int brightness = 4; char *fifo; pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; pthread_t thread1; int initport (int fd) { struct termios options; // Get the current options for the port... tcgetattr (fd, &options); // Set the baud rates to 9600... cfsetispeed (&options, B9600); cfsetospeed (&options, B9600); // Enable the receiver and set local mode... options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; // Set the new options for the port... tcsetattr (fd, TCSANOW, &options); return 1; } //reset the display to defaults char display_init[] = { 0x1b, 0x40 }; //show or hide the cursor char display_cursor_off[] = { 0x1f, 0x43, 0x0 }; char display_cursor_on[] = { 0x1f, 0x43, 0x1 }; // blink-command: // where the last value defines the blink rate, // with 0=always on, 255=always off char display_on[] = { 0x1f, 0x45, 0x0 }; char display_off[] = { 0x1f, 0x45, 0xff }; //Modes for new chars: char display_overwrite[] = { 0x1f, 0x01 }; char display_vscroll[] = { 0x1f, 0x02 }; char display_hscroll[] = { 0x1f, 0x03 }; //clear and cursor home char display_clear_screen[] = { 0x0c }; // activate timer display in lower right corner. // actual time has to be set via display_set_timer. char display_time[] = { 0x1f, 0x55 }; // configures hour and minutes of the internal clock and // displays the time in the lower right corner. // turns off when something gets written into the line. // two bytes have to follow with hour and minute char display_set_timer[] = { 0x1F, 0x54 }; // various commands for the display: // send a command sequence from the heap(!) {sizeof used} // only to be used within the macros presented below! #define DWC(c) display_write(c,sizeof(c)) //send a null terminated string: #define SEND_TEXT(t) display_write(t,strlen(t)) //various commands #define SEND_DISPLAY_INIT DWC(display_init) #define SEND_CURSOR_OFF DWC(display_cursor_off) #define SEND_CURSOR_ON DWC(display_cursor_on) #define SEND_DEFINE_TIMER DWC(display_set_timer) #define SEND_SHOW_TIMER DWC(display_time) #define SEND_MODE_OVERWRITE DWC(display_overwrite) #define SEND_MODE_VSCROLL DWC(display_vscroll) #define SEND_MODE_HSCROLL DWC(display_hscroll) #define SEND_DISPLAY_OFF DWC(display_off) #define SEND_DISPLAY_ON DWC(display_on) #define SEND_CLEAR DWC(display_clear_screen); // internal defines. #define TIME_BASE 200000 #define TB_TO_SECS(x) (x*1000000/TIME_BASE) #define TIME_CLOCK TB_TO_SECS(25) #define TIME_DIM TB_TO_SECS(90) #define TIME_OFF TB_TO_SECS(320) #define DEVICE "/dev/ttyUSB0" #define PAUSEMSG "Hallo, bitte melde Dich am Barcodereader an, um das Kassensystem zu benutzen *** " // chars per line in our display: #define LINELEN 20 void display_write (const void *buf, size_t count) { pthread_mutex_lock (&mutex1); write (fd, buf, count); pthread_mutex_unlock (&mutex1); } void display_putstring (char *s) { screensaver = 0; SEND_TEXT (s); } void showtime (void) { SEND_CURSOR_OFF; char c[5] = { 0x1F, 0x54, 0x00, 0x00 }; time_t timer; // Define the timer struct tm *tblock; // Define a structure for time block timer = time (NULL); tblock = localtime (&timer); c[2] = tblock->tm_hour; c[3] = tblock->tm_min; display_write (&c, 4); SEND_MODE_HSCROLL; char *msg = "Freitagsrunde 4!"; display_write (msg, strlen (msg)); } void display_dim (short i) { // return; if (i == brightness) { //printf ("display_dim: would not change brightness. abort.\n"); return; } if (i > 0 && i < 5) { int l = 0; char *d; if (brightness == 0) { SEND_CURSOR_OFF; // turn display on again SEND_DISPLAY_ON; SEND_MODE_OVERWRITE; char c[4] = { 0x1f, 0x58, 0x04, 0x00 }; l = 6; //c[5]=i; d = c; } else { //set brightness directly: char c[4] = { 0x1f, 0x58, 0x01, 0x00 }; l = 3; c[2] = i; d = c; //printf ("command mode: %x \n", c[2]); } display_write (d, l); brightness = i; } else if (i == 0) { //turn off SEND_DISPLAY_OFF; brightness = i; } } void * rthread (void *args) { int pipe; char pc = ' '; char c = ' '; while (1) { pipe = open ("/tmp/display", O_RDONLY); int r; while ((r = read (pipe, &c, 1)) > 0) { screensaver = 0; if (pc == '\n') { display_write (&pc, 1); } if (c != '\n') { display_write (&c, 1); } pc = c; display_dim (4); } close (pipe); } } void sighandler (int sig) { pthread_kill (thread1, 0); SEND_DISPLAY_INIT; SEND_MODE_OVERWRITE; SEND_CURSOR_OFF; SEND_DISPLAY_OFF; close (fd); if (fifo) { unlink (fifo); } exit (0); //signal(sig, sighandler); } int main (int argc, char **argv) { char *devnode; //TODO: arg parser! fifo = strdup ("/tmp/display"); if (argc != 2) { devnode = strdup (DEVICE); printf ("no device specified, using default %s\n", devnode); } else { devnode = strdup (argv[1]); } fd = open (devnode, O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror (devnode); return 1; } else { fcntl (fd, F_SETFL, 0); } initport (fd); //init display, set, vertical scroll, cursor off SEND_DISPLAY_INIT; SEND_MODE_OVERWRITE; SEND_CURSOR_OFF; pthread_create (&thread1, NULL, rthread, NULL); signal (SIGINT, sighandler); if (mkfifo (fifo, S_IRWXU | S_IRWXG | S_IRWXO)) { perror (fifo); if (errno != EEXIST && errno != ESPIPE) { return (1); } } //showtime(); display_putstring ("Display initialized "); display_putstring (fifo); sleep (3); screensaver = 0; while (1) { usleep (TIME_BASE); if (0 == (screensaver) % TB_TO_SECS (1)) { //one-second event comes HERE: printf ("debug: screensaver: %d time until clock: %d time until dim: %d time until off: %d\n", screensaver, TIME_CLOCK - screensaver, TIME_DIM - screensaver, TIME_OFF - screensaver); } //printf ("screensaver = %05d brightness: %d\n", screensaver, brightness); screensaver = (screensaver + 1) % TIME_CLOCK + TIME_OFF + TIME_DIM; if (screensaver == TIME_CLOCK) { showtime (); } if (screensaver == TIME_OFF) { display_dim (0); } //show a scroll text while the screensaver is active... if ((screensaver > (TIME_CLOCK + 10)) && (screensaver < TIME_OFF)) { char *message = calloc (LINELEN + 1, sizeof (char)); strncpy (message, PAUSEMSG + ((screensaver - TIME_CLOCK - 1) % strlen (PAUSEMSG)), LINELEN); int l = strlen (message); if (l < LINELEN) { message = strncat (message, PAUSEMSG, LINELEN - l); } SEND_TEXT ("\x0b"); SEND_TEXT (message); free (message); } //after some more seconds of inactivity dim display and finally turn off if ((screensaver > TIME_DIM) && (brightness > 1)) { //printf ("dimming\n"); display_dim (brightness - 1); } } //you'll never get here close (fd); return 0; }