diff options
Diffstat (limited to 'anzeige.c')
-rw-r--r-- | anzeige.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/anzeige.c b/anzeige.c new file mode 100644 index 0000000..24d6011 --- /dev/null +++ b/anzeige.c @@ -0,0 +1,184 @@ +// +// How to access GPIO registers from C-code on the Raspberry-Pi +// Example program +// 15-January-2012 +// Dom and Gert +// Revised: 15-Feb-2013 + + +// Access from ARM Running Linux + +#define BCM2708_PERI_BASE 0x20000000 +#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ + + +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> +#include <errno.h> +#include <string.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; + +// 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(char *content); + +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) +{ + int rep; + + // Set up gpi pointer for direct register access +// setup_io(); + + // Drop root privileges + drop_privileges(); + + /************************************************************************\ + * You are about to change the GPIO settings of your computer. * + * Mess this up and it will stop working! * + * It might be a good idea to 'sync' before running this program * + * so at least you still have your code changes written to the SD-card! * + \************************************************************************/ + + // 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); + + put_on_display("0123456789abcdefghijklmnopqrstuvwxy"); + + return 0; + +} // 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 +// +void drop_privileges() +{ + /* Drop superuser privileges in correct order */ + + if (setgid(99) == -1) { + perror("can't drop group privileges"); + exit(-1); + } + if (setuid(99) == -1) { + perror("can't drop user privileges"); + exit(-1); + } +} // drop_root + +// +// Shift the bits provided in content into the display +// +void put_on_display(char *content) +{ + char *raw_output; + int line; + + raw_output = malloc(7*(5+1)); + if (raw_output == NULL) { + perror("malloc failed"); + exit(-1); + } + for (line=0; line<7; line++) { + raw_output[line*6] = 1<<line; + memmove(raw_output+1+6*line,content+5*line,5); + } + while (1); + for (line=0; line<7; line++) { + GPIO_CLR = 1<<GATE_PIN; // Licht an + for (int byte=0; byte<6; byte++) { + for (int bit=0; bit<8; bit++) { + GPIO_CLR = 1<<SER_CLK_PIN; + GPIO_ALTER((*(raw_output+6*line+byte)>>bit) & 0x01) = 1<<SER_DAT_PIN; + GPIO_SET = 1<<SER_CLK_PIN; + } + } + usleep(1000); + GPIO_SET = 1<<GATE_PIN; // Licht aus + GPIO_CLR = 1<<PAR_CLK_PIN; + GPIO_SET = 1<<PAR_CLK_PIN; + } + free(raw_output); +} // put_on_screen |