1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#ifndef SKIP_GPIO
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#endif
#include <stdio.h>
#include <unistd.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
//
int 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");
return EXIT_FAILURE;
}
/* 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");
return EXIT_FAILURE;
}
// 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;
usleep(25);
GPIO_SET = 1<<SER_CLK_PIN;
usleep(25);
}
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;
usleep(250);
GPIO_SET = 1<<SER_CLK_PIN;
usleep(250);
#endif
}
#ifdef SKIP_GPIO
usleep(1000);
printf("\n");
#else
GPIO_SET = 1<<GATE_PIN; // Licht aus
usleep(250);
GPIO_CLR = 1<<PAR_CLK_PIN;
usleep(250);
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
|