summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile12
-rw-r--r--anzeige.c173
-rw-r--r--input_gadgets.c57
-rw-r--r--input_gadgets.h2
-rw-r--r--multiplexer.c128
-rw-r--r--multiplexer.h52
7 files changed, 258 insertions, 167 deletions
diff --git a/.gitignore b/.gitignore
index ff41870..7b72871 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
anzeige
+*.o
diff --git a/Makefile b/Makefile
index d2f3cb0..9ac123a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,13 @@
-anzeige: anzeige.c fonts.h
- gcc -o "$@" -Werror=implicit-function-declaration -lpthread "$<"
+CFLAGS="-Werror=implicit-function-declaration"
+
+anzeige: anzeige.c fonts.h input_gadgets.o multiplexer.o
+ gcc -o "$@" $(CFLAGS) -lpthread -lcurl $^
+
+input_gadgeds.o: input_gadgeds.c input_gadgeds.h
+ gcc -o "$@" $(CFLAGS) -c -lcurl "$<"
+
+multiplexer.o: multiplexer.c multiplexer.h
+ gcc -o "$@" $(CFLAGS) -c -lpthread "$<"
all: anzeige
diff --git a/anzeige.c b/anzeige.c
index b08d4d6..0e6713c 100644
--- a/anzeige.c
+++ b/anzeige.c
@@ -1,18 +1,3 @@
-//
-// How to access GPIO registers from C-code on the Raspberry-Pi
-// Example program
-// 15-January-2012
-// Dom and Gert
-// Revised: 15-Feb-2013
-
-#ifndef __arm__
-#define SKIP_GPIO
-#endif
-
-// Access from ARM Running Linux
-
-#define BCM2708_PERI_BASE 0x20000000
-#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#define _GNU_SOURCE
#include <stdio.h>
@@ -25,67 +10,25 @@
#include <pthread.h>
#include "fonts.h"
+#include "input_gadgets.h"
+#include "multiplexer.h"
-#define PAGE_SIZE (4*1024)
-#define BLOCK_SIZE (4*1024)
-
-#define SER_DAT_PIN 26
-#define SER_CLK_PIN 19
-#define GATE_PIN 13
-#define PAR_CLK_PIN 6
-#define SENSE_PIN 5
-
-int mem_fd;
-void *gpio_map;
-
-typedef struct {
- char buf[3][40];
- int should_buf, is_buf, keep_running;
-} t_display_data;
-
-// I/O access
-volatile unsigned *gpio;
-
-
-// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
-#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
-#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
-#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
-
-#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
-#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
-#define GPIO_ALTER(a) *(gpio+(a==0?10:7)) // alters (a==0: clear, else: set) bits which are 1 ignores bits which are 0
-
-#define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
-
-#define GPIO_PULL *(gpio+37) // Pull up/pull down
-#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
-
-void setup_io();
void drop_privileges();
-void *put_on_display(void *param);
-
-void printButton(int g)
-{
- if (GET_GPIO(g)) // !=0 <-> bit is 1 <- port is HIGH=3.3V
- printf("Button pressed!\n");
- else // port is LOW=0V
- printf("Button released!\n");
-}
int main(int argc, char **argv)
{
pthread_t thread_id;
t_display_data display_data;
-#ifndef SKIP_GPIO
// Set up gpi pointer for direct register access
- setup_io();
-#endif
+ multiplexer_setup_root();
// Drop root privileges
drop_privileges();
+ gadgets_retrieve_temperature();
+ return 0;
+
/************************************************************************\
* You are about to change the GPIO settings of your computer. *
* Mess this up and it will stop working! *
@@ -93,25 +36,8 @@ int main(int argc, char **argv)
* so at least you still have your code changes written to the SD-card! *
\************************************************************************/
-#ifndef SKIP_GPIO
- // must use INP_GPIO before we can use OUT_GPIO
- INP_GPIO(SER_DAT_PIN);
- OUT_GPIO(SER_DAT_PIN);
- INP_GPIO(SER_CLK_PIN);
- OUT_GPIO(SER_CLK_PIN);
- INP_GPIO(GATE_PIN);
- OUT_GPIO(GATE_PIN);
- INP_GPIO(PAR_CLK_PIN);
- OUT_GPIO(PAR_CLK_PIN);
- INP_GPIO(SENSE_PIN);
-#endif
-
- for (int i=0; i<3; i++)
- memset(display_data.buf[i],0,40);
- 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);
+ // configure the gpio pins and start the multiplexer thread
+ thread_id = multiplexer_setup_non_root(&display_data);
for (int i=0; i<20; i++) {
usleep(2500000);
@@ -127,41 +53,6 @@ int main(int argc, char **argv)
} // main
-
-//
-// Set up a memory regions to access GPIO
-//
-void setup_io()
-{
- /* open /dev/mem */
- if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
- perror("can't open /dev/mem");
- exit(-1);
- }
-
- /* mmap GPIO */
- gpio_map = mmap(
- NULL, //Any adddress in our space will do
- BLOCK_SIZE, //Map length
- PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
- MAP_SHARED, //Shared with other processes
- mem_fd, //File to map
- GPIO_BASE //Offset to GPIO peripheral
- );
-
- close(mem_fd); //No need to keep mem_fd open after mmap
-
- if (gpio_map == MAP_FAILED) {
- perror("mmap error");
- exit(-1);
- }
-
- // Always use volatile pointer!
- gpio = (volatile unsigned *)gpio_map;
-
-
-} // setup_io
-
//
// Drop (root) privileges
//
@@ -178,51 +69,3 @@ void drop_privileges()
exit(-1);
}
} // drop_root
-
-//
-// Shift the bits provided in content into the display
-//
-void *put_on_display(void *param)
-{
- t_display_data *display_data = param;
- int line, column;
-
- while (display_data -> keep_running) {
-
-#ifdef SKIP_GPIO
- usleep(100000);
- printf("=\n");
-#endif
- display_data -> is_buf = display_data -> should_buf;
- for (line=0; line<7; line++) {
-#ifdef SKIP_GPIO
- for (column=0; column<40; column++) {
- if ((*(display_data -> buf[display_data -> is_buf] + column)>>line) & 0x01)
- printf("X");
- else
- printf(".");
-#else
- GPIO_CLR = 1<<GATE_PIN; // Licht an
- for (column=0; column<8; column++) {
- GPIO_CLR = 1<<SER_CLK_PIN;
- GPIO_ALTER(column == line) = 1<<SER_DAT_PIN;
- GPIO_SET = 1<<SER_CLK_PIN;
- }
- for (column=39; column>=0; column--) {
- GPIO_CLR = 1<<SER_CLK_PIN;
- GPIO_ALTER((*(display_data -> buf[display_data -> is_buf] + column)>>line) & 0x01) = 1<<SER_DAT_PIN;
- GPIO_SET = 1<<SER_CLK_PIN;
-#endif
- }
- usleep(1000);
-#ifdef SKIP_GPIO
- printf("\n");
-#else
- GPIO_SET = 1<<GATE_PIN; // Licht aus
- GPIO_CLR = 1<<PAR_CLK_PIN;
- GPIO_SET = 1<<PAR_CLK_PIN;
-#endif
- }
- }
- return NULL;
-} // put_on_screen
diff --git a/input_gadgets.c b/input_gadgets.c
new file mode 100644
index 0000000..35dc766
--- /dev/null
+++ b/input_gadgets.c
@@ -0,0 +1,57 @@
+#include <string.h>
+#include <stdlib.h>
+#include <curl/curl.h>
+
+struct MemoryStruct {
+ char *memory;
+ size_t size;
+};
+
+static size_t
+WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
+{
+ size_t realsize = size * nmemb;
+ struct MemoryStruct *mem = (struct MemoryStruct *)userp;
+
+ char *ptr = realloc(mem->memory, mem->size + realsize + 1);
+ if(ptr == NULL) {
+ /* out of memory! */
+ printf("not enough memory (realloc returned NULL)\n");
+ return 0;
+ }
+
+ mem->memory = ptr;
+ memcpy(&(mem->memory[mem->size]), contents, realsize);
+ mem->size += realsize;
+ mem->memory[mem->size] = 0;
+
+ return realsize;
+}
+
+int gadgets_retrieve_temperature() {
+ CURL *curl_handle;
+ CURLcode res;
+ struct MemoryStruct chunk;
+
+ chunk.memory = malloc(1);
+ chunk.size = 0;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ curl_handle = curl_easy_init();
+ if (!curl_handle) {
+ perror("Failed to init curl");
+ return -1;
+ }
+ curl_easy_setopt(curl_handle, CURLOPT_URL, "https://wetter.mb.fh-jena.de/station/datenbank/php_giese/online.php");
+ curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
+ curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
+ res = curl_easy_perform(curl_handle);
+ if (res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
+ curl_easy_cleanup(curl_handle);
+ printf("%lu bytes retrieved\n", (unsigned long)chunk.size);
+ return 0;
+}
diff --git a/input_gadgets.h b/input_gadgets.h
new file mode 100644
index 0000000..11413a8
--- /dev/null
+++ b/input_gadgets.h
@@ -0,0 +1,2 @@
+
+void gadgets_retrieve_temperature();
diff --git a/multiplexer.c b/multiplexer.c
new file mode 100644
index 0000000..5f82ee5
--- /dev/null
+++ b/multiplexer.c
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "multiplexer.h"
+
+/** TODO
+void printButton(int g)
+{
+ if (GET_GPIO(g)) // !=0 <-> bit is 1 <- port is HIGH=3.3V
+ printf("Button pressed!\n");
+ else // port is LOW=0V
+ printf("Button released!\n");
+} **/
+
+
+//
+// Set up a memory regions to access GPIO
+//
+void multiplexer_setup_root()
+{
+#ifndef SKIP_GPIO
+ /* open /dev/mem */
+ if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
+ perror("can't open /dev/mem");
+ exit(-1);
+ }
+
+ /* mmap GPIO */
+ gpio_map = mmap(
+ NULL, //Any adddress in our space will do
+ BLOCK_SIZE, //Map length
+ PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
+ MAP_SHARED, //Shared with other processes
+ mem_fd, //File to map
+ GPIO_BASE //Offset to GPIO peripheral
+ );
+
+ close(mem_fd); //No need to keep mem_fd open after mmap
+
+ if (gpio_map == MAP_FAILED) {
+ perror("mmap error");
+ exit(-1);
+ }
+
+ // Always use volatile pointer!
+ gpio = (volatile unsigned *)gpio_map;
+#endif
+} // multiplexer_setup_root
+
+//
+// Shift the bits provided in content into the display
+//
+void *put_on_display(void *param)
+{
+ t_display_data *display_data = param;
+ int line, column;
+
+ while (display_data -> keep_running) {
+
+#ifdef SKIP_GPIO
+ usleep(100000);
+ printf("=\n");
+#endif
+ display_data -> is_buf = display_data -> should_buf;
+ for (line=0; line<7; line++) {
+#ifdef SKIP_GPIO
+ for (column=0; column<40; column++) {
+ if ((*(display_data -> buf[display_data -> is_buf] + column)>>line) & 0x01)
+ printf("X");
+ else
+ printf(".");
+#else
+ GPIO_CLR = 1<<GATE_PIN; // Licht an
+ for (column=0; column<8; column++) {
+ GPIO_CLR = 1<<SER_CLK_PIN;
+ GPIO_ALTER(column == line) = 1<<SER_DAT_PIN;
+ GPIO_SET = 1<<SER_CLK_PIN;
+ }
+ for (column=39; column>=0; column--) {
+ GPIO_CLR = 1<<SER_CLK_PIN;
+ GPIO_ALTER((*(display_data -> buf[display_data -> is_buf] + column)>>line) & 0x01) = 1<<SER_DAT_PIN;
+ GPIO_SET = 1<<SER_CLK_PIN;
+#endif
+ }
+ usleep(1000);
+#ifdef SKIP_GPIO
+ printf("\n");
+#else
+ GPIO_SET = 1<<GATE_PIN; // Licht aus
+ GPIO_CLR = 1<<PAR_CLK_PIN;
+ GPIO_SET = 1<<PAR_CLK_PIN;
+#endif
+ }
+ }
+ return NULL;
+} // put_on_display
+
+pthread_t multiplexer_setup_non_root(t_display_data *display_data)
+{
+ pthread_t thread_id;
+
+#ifndef SKIP_GPIO
+ // must use INP_GPIO before we can use OUT_GPIO
+ INP_GPIO(SER_DAT_PIN);
+ OUT_GPIO(SER_DAT_PIN);
+ INP_GPIO(SER_CLK_PIN);
+ OUT_GPIO(SER_CLK_PIN);
+ INP_GPIO(GATE_PIN);
+ OUT_GPIO(GATE_PIN);
+ INP_GPIO(PAR_CLK_PIN);
+ OUT_GPIO(PAR_CLK_PIN);
+ INP_GPIO(SENSE_PIN);
+#endif
+
+ for (int i=0; i<3; i++)
+ memset(display_data -> buf[i],0,40);
+ 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;
+} // multiplexer_setup_non_root
diff --git a/multiplexer.h b/multiplexer.h
new file mode 100644
index 0000000..806ef19
--- /dev/null
+++ b/multiplexer.h
@@ -0,0 +1,52 @@
+//
+// How to access GPIO registers from C-code on the Raspberry-Pi
+// Example program
+// 15-January-2012
+// Dom and Gert
+// Revised: 15-Feb-2013
+
+#ifndef __arm__
+#define SKIP_GPIO
+#endif
+
+// Access from ARM Running Linux
+
+#define BCM2708_PERI_BASE 0x20000000
+#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
+
+#define PAGE_SIZE (4*1024)
+#define BLOCK_SIZE (4*1024)
+
+#define SER_DAT_PIN 26
+#define SER_CLK_PIN 19
+#define GATE_PIN 13
+#define PAR_CLK_PIN 6
+#define SENSE_PIN 5
+
+int mem_fd;
+void *gpio_map;
+
+typedef struct {
+ char buf[3][40];
+ int should_buf, is_buf, keep_running;
+} t_display_data;
+
+// I/O access
+volatile unsigned *gpio;
+
+// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
+#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
+#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
+#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
+
+#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
+#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
+#define GPIO_ALTER(a) *(gpio+(a==0?10:7)) // alters (a==0: clear, else: set) bits which are 1 ignores bits which are 0
+
+#define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
+
+#define GPIO_PULL *(gpio+37) // Pull up/pull down
+#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
+
+void multiplexer_setup_root();
+pthread_t multiplexer_setup_non_root(t_display_data *display_data);