diff options
author | Erich Eckner <git@eckner.net> | 2018-10-27 22:45:41 +0200 |
---|---|---|
committer | Erich Eckner <git@eckner.net> | 2018-10-27 22:45:41 +0200 |
commit | 71e97ec2bc954e57b6955b3ec3fc49379116efc7 (patch) | |
tree | 6c257725c88bf2cbdd0912db750994fb9b2dddaf | |
parent | fc5f0e6e60bcaed784c955b79d173cd6eb7f4305 (diff) | |
download | anzeige-71e97ec2bc954e57b6955b3ec3fc49379116efc7.tar.xz |
put scrolling into separate thread; activate minutely updates; cleanup
-rw-r--r-- | anzeige.c | 110 | ||||
-rw-r--r-- | multiplexer.c | 61 | ||||
-rw-r--r-- | multiplexer.h | 17 |
3 files changed, 128 insertions, 60 deletions
@@ -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); |