summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2018-10-27 22:45:41 +0200
committerErich Eckner <git@eckner.net>2018-10-27 22:45:41 +0200
commit71e97ec2bc954e57b6955b3ec3fc49379116efc7 (patch)
tree6c257725c88bf2cbdd0912db750994fb9b2dddaf
parentfc5f0e6e60bcaed784c955b79d173cd6eb7f4305 (diff)
downloadanzeige-71e97ec2bc954e57b6955b3ec3fc49379116efc7.tar.xz
put scrolling into separate thread; activate minutely updates; cleanup
-rw-r--r--anzeige.c110
-rw-r--r--multiplexer.c61
-rw-r--r--multiplexer.h17
3 files changed, 128 insertions, 60 deletions
diff --git a/anzeige.c b/anzeige.c
index ed79b1c..7bc8980 100644
--- a/anzeige.c
+++ b/anzeige.c
@@ -9,6 +9,7 @@
#include <string.h>
#include <pthread.h>
#include <signal.h>
+#include <time.h>
#include "fonts.h"
#include "input_gadgets.h"
@@ -17,16 +18,14 @@
void drop_privileges();
void handle_signals(int signo);
-t_display_data display_data;
+t_scroll_data scroll_data;
int main(int argc, char **argv)
{
- pthread_t thread_id;
int ret_val;
- #define TEXT_BUFFER_LENGTH 256
+ #define TEXT_BUFFER_LENGTH SCROLL_BUF_LEN / 5
char *text_buffer;
char *text_buffer_end;
- t_scroll_buffer scroll_buffers[2];
// Set up gpi pointer for direct register access
ret_val = multiplexer_setup_root();
@@ -49,7 +48,7 @@ int main(int argc, char **argv)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
- sigaction (SIGTERM, &new_action, NULL);struct sigaction action;
+ sigaction (SIGTERM, &new_action, NULL);
/************************************************************************\
* You are about to change the GPIO settings of your computer. *
@@ -59,62 +58,67 @@ int main(int argc, char **argv)
\************************************************************************/
// configure the gpio pins and start the multiplexer thread
- thread_id = multiplexer_setup_non_root(&display_data);
-
- int i,j;
+ multiplexer_setup_scroll(&scroll_data);
text_buffer = malloc(TEXT_BUFFER_LENGTH);
if (text_buffer == NULL) {
- fprintf(stderr, "malloc failed to allocate 24 bytes\n");
+ fprintf(stderr, "malloc failed to allocate %d bytes\n", TEXT_BUFFER_LENGTH);
exit(EXIT_FAILURE);
}
- memset(text_buffer, 0, TEXT_BUFFER_LENGTH);
-
- text_buffer_end = text_buffer;
- text_buffer_end = gadgets_retrieve_weather_warnings(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end);
- if (text_buffer_end == NULL) {
- fprintf(stderr, "gadgets_retrieve_weather_warnings failed\n");
- free(text_buffer);
- return EXIT_FAILURE;
- }
- if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0)
- text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; ");
- text_buffer_end = gadgets_retrieve_current_temperature(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end);
- if (text_buffer_end == NULL) {
- fprintf(stderr, "gadgets_retrieve_current_temperature failed\n");
- free(text_buffer);
- return EXIT_FAILURE;
- }
- if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0)
- text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; ");
- text_buffer_end = gadgets_retrieve_weather_forecast(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end);
- if (text_buffer_end == NULL) {
- fprintf(stderr, "gadgets_retrieve_weather_forecast failed\n");
- free(text_buffer);
- return EXIT_FAILURE;
- }
- if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0)
- text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; ");
-
- scroll_buffers[0].scroll_len = render(text_buffer, TEXT_BUFFER_LENGTH, scroll_buffers[0].buf, sizeof(scroll_buffers[0].buf), 1);
-
- i=-40;
- while (display_data.keep_running) {
- usleep(100000);
- for (j=0; j<40; j++)
- if (i+j<0)
- display_data.buf[(display_data.should_buf+1)%3][j] = 0;
- else
- display_data.buf[(display_data.should_buf+1)%3][j] = scroll_buffers[0].buf[(i+j) % scroll_buffers[0].scroll_len];
- display_data.should_buf = (display_data.should_buf+1)%3;
- i++;
- i = i % scroll_buffers[0].scroll_len;
+ time_t next_update = 0;
+
+ int i=0;
+
+ while (scroll_data . keep_running) {
+ if ((time(NULL) >= next_update) && (scroll_data . update == 0)) {
+ next_update = time(NULL) + 60; // one minute ahead
+
+ memset(text_buffer, 0, TEXT_BUFFER_LENGTH);
+
+ text_buffer_end = text_buffer;
+
+ text_buffer_end = gadgets_retrieve_weather_warnings(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end);
+ if (text_buffer_end == NULL) {
+ fprintf(stderr, "gadgets_retrieve_weather_warnings failed\n");
+ free(text_buffer);
+ return EXIT_FAILURE;
+ }
+ if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0)
+ text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; ");
+ text_buffer_end = gadgets_retrieve_current_temperature(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end);
+ if (text_buffer_end == NULL) {
+ fprintf(stderr, "gadgets_retrieve_current_temperature failed\n");
+ free(text_buffer);
+ return EXIT_FAILURE;
+ }
+ if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0)
+ text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; ");
+ text_buffer_end = gadgets_retrieve_weather_forecast(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end);
+ if (text_buffer_end == NULL) {
+ fprintf(stderr, "gadgets_retrieve_weather_forecast failed\n");
+ free(text_buffer);
+ return EXIT_FAILURE;
+ }
+ if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0)
+ text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; ");
+
+ scroll_data . input_len =
+ render(
+ text_buffer,
+ text_buffer_end - text_buffer,
+ scroll_data . input,
+ sizeof(scroll_data . input),
+ 1
+ );
+ scroll_data . update = 1;
+ }
+
+ sleep(1);
}
free(text_buffer);
- display_data.keep_running = 0;
- pthread_join(thread_id, NULL);
+ pthread_join(scroll_data . thread_id, NULL);
return 0;
@@ -145,6 +149,6 @@ void handle_signals(int signo)
{
if ((signo == SIGINT) || (signo == SIGHUP) || (signo == SIGTERM)) {
fprintf(stderr, "stopping\n");
- display_data.keep_running = 0;
+ scroll_data . keep_running = 0;
}
}
diff --git a/multiplexer.c b/multiplexer.c
index c81864b..52c7af1 100644
--- a/multiplexer.c
+++ b/multiplexer.c
@@ -7,6 +7,7 @@
#include <unistd.h>
#include <string.h>
#include <pthread.h>
+#include <assert.h>
#include "multiplexer.h"
@@ -108,10 +109,54 @@ void *put_on_display(void *param)
return NULL;
} // put_on_display
-pthread_t multiplexer_setup_non_root(t_display_data *display_data)
+// scroll the text over the display
+void *scroll_it(void *param)
{
- pthread_t thread_id;
+ t_scroll_data *scroll_data = (t_scroll_data *) param;
+ t_scroll_buffer buf[3];
+ for (int i=0; i<3; i++)
+ memset(&buf[i], 0, sizeof(buf[i]));
+ t_display_data display_data;
+ multiplexer_setup_non_root(&display_data);
+ int is_buf = 0;
+ int column = 0;
+ while (scroll_data -> keep_running) {
+ if (scroll_data -> update) {
+ if ((buf[is_buf] . len != scroll_data -> input_len) || (memcmp(&buf[is_buf] . buf[buf[is_buf] . start], scroll_data -> input, scroll_data -> input_len) != 0)) {
+ is_buf = (is_buf + 1) % 2;
+ // copy the currently visible, old content
+ memcpy(buf[is_buf] . buf, &buf[(is_buf + 1) % 2] . buf[column + 1], 39);
+ buf[is_buf] . start = 39;
+ // set the length of the new content
+ buf[is_buf] . len = scroll_data -> input_len;
+ // copy the new content from input
+ for (int i=0; i<2; i++)
+ memcpy(
+ &buf[is_buf] . buf[39 + i * buf[is_buf] . len],
+ scroll_data -> input,
+ buf[is_buf] . len
+ );
+ column = 0;
+ }
+ // clear update flag
+ scroll_data -> update = 0;
+ }
+ for (int i=0; i<40; i++)
+ display_data . buf[(display_data . should_buf + 1) % 3][i] =
+ buf[is_buf] . buf[column + i];
+ display_data . should_buf = (display_data . should_buf + 1) % 3;
+ column++;
+ if (buf[is_buf] . len > 0)
+ while (column >= buf[is_buf] . start + buf[is_buf] . len)
+ column -= buf[is_buf] . len;
+ usleep(100000);
+ }
+ display_data . keep_running = 0;
+ pthread_join(display_data . thread_id, NULL);
+} // scroll_it
+void multiplexer_setup_non_root(t_display_data *display_data)
+{
#ifndef SKIP_GPIO
// must use INP_GPIO before we can use OUT_GPIO
INP_GPIO(SER_DAT_PIN);
@@ -130,6 +175,14 @@ pthread_t multiplexer_setup_non_root(t_display_data *display_data)
display_data -> is_buf = 0;
display_data -> should_buf = 0;
display_data -> keep_running = 1;
- pthread_create(&thread_id, NULL, put_on_display, display_data);
- return thread_id;
+ pthread_create(&display_data -> thread_id, NULL, put_on_display, display_data);
+ return;
} // multiplexer_setup_non_root
+
+void multiplexer_setup_scroll(t_scroll_data *scroll_data)
+{
+ scroll_data -> update = 0;
+ scroll_data -> keep_running = 1;
+ pthread_create(&scroll_data -> thread_id, NULL, scroll_it, scroll_data);
+ return;
+} // multiplexer_setup_scroll
diff --git a/multiplexer.h b/multiplexer.h
index 9c73632..d7f7aee 100644
--- a/multiplexer.h
+++ b/multiplexer.h
@@ -23,19 +23,29 @@
#define PAR_CLK_PIN 6
#define SENSE_PIN 5
+#define SCROLL_BUF_LEN 4096
+
int mem_fd;
void *gpio_map;
typedef struct {
char buf[3][40];
int should_buf, is_buf, keep_running;
+ pthread_t thread_id;
} t_display_data;
typedef struct {
- char buf[2048];
- int scroll_len;
+ char buf[SCROLL_BUF_LEN];
+ int start, len;
} t_scroll_buffer;
+typedef struct {
+ int update;
+ char input[(SCROLL_BUF_LEN - 39) / 2];
+ int input_len, keep_running;
+ pthread_t thread_id;
+} t_scroll_data;
+
// I/O access
volatile unsigned *gpio;
@@ -54,4 +64,5 @@ volatile unsigned *gpio;
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
int multiplexer_setup_root();
-pthread_t multiplexer_setup_non_root(t_display_data *display_data);
+void multiplexer_setup_non_root(t_display_data *display_data);
+void multiplexer_setup_scroll(t_scroll_data *scroll_data);