annotate py/touch/touch.c @ 155:d03157c7ad60

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