Mercurial > templog
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/py/touch/touch.c Fri Dec 21 23:30:16 2012 +0800 @@ -0,0 +1,153 @@ +// +// How to access GPIO registers from C-code on the Raspberry-Pi +// Example program +// 15-January-2012 +// Dom and Gert +// + + +// Access from ARM Running Linux + +#define BCM2708_PERI_BASE 0x20000000 +#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ + + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dirent.h> +#include <fcntl.h> +#include <assert.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <unistd.h> + +#define PAGE_SIZE (4*1024) +#define BLOCK_SIZE (4*1024) + +int mem_fd; +char *gpio_mem, *gpio_map; +char *spi0_mem, *spi0_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 FSEL_OFFSET 0 // 0x0000 +#define SET_OFFSET 7 // 0x001c / 4 +#define CLR_OFFSET 10 // 0x0028 / 4 +#define PINLEVEL_OFFSET 13 // 0x0034 / 4 +#define EVENT_DETECT_OFFSET 16 // 0x0040 / 4 +#define RISING_ED_OFFSET 19 // 0x004c / 4 +#define FALLING_ED_OFFSET 22 // 0x0058 / 4 +#define HIGH_DETECT_OFFSET 25 // 0x0064 / 4 +#define LOW_DETECT_OFFSET 28 // 0x0070 / 4 +#define PULLUPDN_OFFSET 37 // 0x0094 / 4 +#define PULLUPDNCLK_OFFSET 38 // 0x0098 / 4 + + +#define GPIO_GET(g) ((*(gpio+PINLEVEL_OFFSET) & (1<<(g))) >> (g)) +#define GPIO_SET(g) (*(gpio+SET_OFFSET) = 1<<(g)) // sets bits which are 1 ignores bits which are 0 +#define GPIO_CLR(g) (*(gpio+CLR_OFFSET) = 1<<(g))// clears bits which are 1 ignores bits which are 0 + +#define TOUCH_IN 24 +#define TOUCH_OUT 25 + +void setup_io(); + +int main(int argc, char **argv) +{ + int g,rep; + + // Set up gpi pointer for direct register access + setup_io(); + + // Switch GPIO 7..11 to output mode + + /************************************************************************\ + * 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! * + \************************************************************************/ + + + INP_GPIO(TOUCH_IN); + INP_GPIO(TOUCH_OUT); + OUT_GPIO(TOUCH_OUT); + + int num = 1000; + int sum = 0; + + while (1) + { +int n; +sum = 0; + for (n = 0; n < num; n++) +{ + GPIO_CLR(TOUCH_OUT); + usleep(1000); + GPIO_SET(TOUCH_OUT); + while (GPIO_GET(TOUCH_IN) == 0) + { + sum++; + } + } + printf("total %f\n", (float)sum / num); +} + 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) { + printf("can't open /dev/mem \n"); + exit (-1); + } + + /* mmap GPIO */ + + // Allocate MAP block + if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) { + printf("allocation error \n"); + exit (-1); + } + + // Make sure pointer is on 4K boundary + if ((unsigned long)gpio_mem % PAGE_SIZE) + gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE); + + // Now map it + gpio_map = (unsigned char *)mmap( + (caddr_t)gpio_mem, + BLOCK_SIZE, + PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_FIXED, + mem_fd, + GPIO_BASE + ); + + if ((long)gpio_map < 0) { + printf("mmap error %d\n", (int)gpio_map); + exit (-1); + } + + // Always use volatile pointer! + gpio = (volatile unsigned *)gpio_map; + + +} // setup_io