Mercurial > templog
comparison py/touch/touch.c @ 454:dce9f7841696
rough touch sensor
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 21 Dec 2012 23:30:16 +0800 |
parents | |
children | bed65c321b46 |
comparison
equal
deleted
inserted
replaced
453:0af7b38a1847 | 454:dce9f7841696 |
---|---|
1 // | |
2 // How to access GPIO registers from C-code on the Raspberry-Pi | |
3 // Example program | |
4 // 15-January-2012 | |
5 // Dom and Gert | |
6 // | |
7 | |
8 | |
9 // Access from ARM Running Linux | |
10 | |
11 #define BCM2708_PERI_BASE 0x20000000 | |
12 #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ | |
13 | |
14 | |
15 #include <stdio.h> | |
16 #include <string.h> | |
17 #include <stdlib.h> | |
18 #include <dirent.h> | |
19 #include <fcntl.h> | |
20 #include <assert.h> | |
21 #include <sys/mman.h> | |
22 #include <sys/types.h> | |
23 #include <sys/stat.h> | |
24 | |
25 #include <unistd.h> | |
26 | |
27 #define PAGE_SIZE (4*1024) | |
28 #define BLOCK_SIZE (4*1024) | |
29 | |
30 int mem_fd; | |
31 char *gpio_mem, *gpio_map; | |
32 char *spi0_mem, *spi0_map; | |
33 | |
34 | |
35 // I/O access | |
36 volatile unsigned *gpio; | |
37 | |
38 | |
39 // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) | |
40 #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) | |
41 #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) | |
42 #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) | |
43 | |
44 #define FSEL_OFFSET 0 // 0x0000 | |
45 #define SET_OFFSET 7 // 0x001c / 4 | |
46 #define CLR_OFFSET 10 // 0x0028 / 4 | |
47 #define PINLEVEL_OFFSET 13 // 0x0034 / 4 | |
48 #define EVENT_DETECT_OFFSET 16 // 0x0040 / 4 | |
49 #define RISING_ED_OFFSET 19 // 0x004c / 4 | |
50 #define FALLING_ED_OFFSET 22 // 0x0058 / 4 | |
51 #define HIGH_DETECT_OFFSET 25 // 0x0064 / 4 | |
52 #define LOW_DETECT_OFFSET 28 // 0x0070 / 4 | |
53 #define PULLUPDN_OFFSET 37 // 0x0094 / 4 | |
54 #define PULLUPDNCLK_OFFSET 38 // 0x0098 / 4 | |
55 | |
56 | |
57 #define GPIO_GET(g) ((*(gpio+PINLEVEL_OFFSET) & (1<<(g))) >> (g)) | |
58 #define GPIO_SET(g) (*(gpio+SET_OFFSET) = 1<<(g)) // sets bits which are 1 ignores bits which are 0 | |
59 #define GPIO_CLR(g) (*(gpio+CLR_OFFSET) = 1<<(g))// clears bits which are 1 ignores bits which are 0 | |
60 | |
61 #define TOUCH_IN 24 | |
62 #define TOUCH_OUT 25 | |
63 | |
64 void setup_io(); | |
65 | |
66 int main(int argc, char **argv) | |
67 { | |
68 int g,rep; | |
69 | |
70 // Set up gpi pointer for direct register access | |
71 setup_io(); | |
72 | |
73 // Switch GPIO 7..11 to output mode | |
74 | |
75 /************************************************************************\ | |
76 * You are about to change the GPIO settings of your computer. * | |
77 * Mess this up and it will stop working! * | |
78 * It might be a good idea to 'sync' before running this program * | |
79 * so at least you still have your code changes written to the SD-card! * | |
80 \************************************************************************/ | |
81 | |
82 | |
83 INP_GPIO(TOUCH_IN); | |
84 INP_GPIO(TOUCH_OUT); | |
85 OUT_GPIO(TOUCH_OUT); | |
86 | |
87 int num = 1000; | |
88 int sum = 0; | |
89 | |
90 while (1) | |
91 { | |
92 int n; | |
93 sum = 0; | |
94 for (n = 0; n < num; n++) | |
95 { | |
96 GPIO_CLR(TOUCH_OUT); | |
97 usleep(1000); | |
98 GPIO_SET(TOUCH_OUT); | |
99 while (GPIO_GET(TOUCH_IN) == 0) | |
100 { | |
101 sum++; | |
102 } | |
103 } | |
104 printf("total %f\n", (float)sum / num); | |
105 } | |
106 return 0; | |
107 | |
108 } // main | |
109 | |
110 | |
111 // | |
112 // Set up a memory regions to access GPIO | |
113 // | |
114 void setup_io() | |
115 { | |
116 /* open /dev/mem */ | |
117 if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { | |
118 printf("can't open /dev/mem \n"); | |
119 exit (-1); | |
120 } | |
121 | |
122 /* mmap GPIO */ | |
123 | |
124 // Allocate MAP block | |
125 if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) { | |
126 printf("allocation error \n"); | |
127 exit (-1); | |
128 } | |
129 | |
130 // Make sure pointer is on 4K boundary | |
131 if ((unsigned long)gpio_mem % PAGE_SIZE) | |
132 gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE); | |
133 | |
134 // Now map it | |
135 gpio_map = (unsigned char *)mmap( | |
136 (caddr_t)gpio_mem, | |
137 BLOCK_SIZE, | |
138 PROT_READ|PROT_WRITE, | |
139 MAP_SHARED|MAP_FIXED, | |
140 mem_fd, | |
141 GPIO_BASE | |
142 ); | |
143 | |
144 if ((long)gpio_map < 0) { | |
145 printf("mmap error %d\n", (int)gpio_map); | |
146 exit (-1); | |
147 } | |
148 | |
149 // Always use volatile pointer! | |
150 gpio = (volatile unsigned *)gpio_map; | |
151 | |
152 | |
153 } // setup_io |