/* * 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 display_dirty=0; int screensaver; int brightness = 4; int offset = 0; char *fifo; char *pausemsg = NULL; 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(65) #define TIME_DIM TB_TO_SECS(90) #define TIME_OFF TB_TO_SECS(520) #define DEVICE "/dev/ttyUSB0" // 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 send_display_init(){ SEND_DISPLAY_INIT; SEND_CURSOR_OFF; SEND_DISPLAY_ON; SEND_MODE_OVERWRITE; } 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_display_init(); 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 (display_dirty) { printf("DEBUG: resetting display\n"); send_display_init(); display_dirty=0; } display_dim (4); if (pc == '\n') { display_write (&pc, 1); } if (c != '\n') { display_write (&c, 1); } pc = c; } close (pipe); } } void sighandler (int sig) { pthread_kill (thread1, 0); send_display_init(); SEND_DISPLAY_OFF; close (fd); if (fifo) { unlink (fifo); } exit (0); //signal(sig, sighandler); } void scrolltext(){ if (pausemsg){ char *message = calloc (LINELEN + 1, sizeof (char)); int spaces=0; if (offset (TIME_CLOCK + 10)) && (screensaver < TIME_OFF)) { display_dirty=1; scrolltext(); } //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; }