raspi_tests

view gpiotest1/test.c @ 0:fbf9076c1984

first raspberry pi gpio test (led blinker)
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 01 Mar 2016 07:38:36 +0000
parents
children 7cdaa3a0df97
line source
1 #include <stdio.h>
2 #include <signal.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/mman.h>
6 #include "bcm_host.h"
8 #define REG_GPFSEL_BASE 0x200000
9 #define REG_GPSET_BASE 0x20001c
10 #define REG_GPCLR_BASE 0x200028
11 #define REG_GPLEV_BASE 0x200034
13 #define FSEL_BITS 3
14 #define FSEL_INPUT 0
15 #define FSEL_OUTPUT 1
17 #define FSEL_SHIFT(i) (((i) % 10) * 3)
18 #define FSEL_MASK(i) (3 << FSEL_SHIFT(i))
20 #define REG(r) (volatile uint32_t*)((unsigned char*)iomem + (r))
22 void *iomem;
23 int quit;
25 static inline void set_pin_func(int pin, int func);
26 static inline void set_pin_state(int pin, int s);
27 static inline int get_pin_state(int pin);
28 static void sighandler(int s);
30 int main(void)
31 {
32 int fd;
33 int i;
34 uint32_t io_addr, io_size;
36 signal(SIGINT, sighandler);
37 signal(SIGQUIT, sighandler);
38 signal(SIGSEGV, sighandler);
39 signal(SIGILL, sighandler);
40 signal(SIGFPE, sighandler);
42 io_addr = bcm_host_get_peripheral_address();
43 io_size = bcm_host_get_peripheral_size();
44 printf("I/O registers\n");
45 printf(" addr: %x\n", io_addr);
46 printf(" size: %d\n", io_size);
48 if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
49 perror("failed to open /dev/mem");
50 return 1;
51 }
52 if((iomem = mmap(0, io_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, io_addr)) == (void*)-1) {
53 perror("failed to map I/O registers range");
54 return 1;
55 }
57 /* configure GPIO pins 4 and 17 as outputs */
58 set_pin_func(4, FSEL_OUTPUT);
59 set_pin_func(17, FSEL_OUTPUT);
61 i = 0;
62 while(!quit) {
63 set_pin_state(4, i & 1);
64 set_pin_state(17, (~i) & 1);
65 ++i;
66 sleep(1);
67 }
69 set_pin_state(4, 0);
70 set_pin_state(17, 0);
71 set_pin_func(4, FSEL_INPUT);
72 set_pin_func(17, FSEL_INPUT);
74 munmap(iomem, io_size);
75 close(fd);
76 return 0;
77 }
79 static inline void set_pin_func(int pin, int func)
80 {
81 int reg_addr, val;
82 reg_addr = REG_GPFSEL_BASE + (pin / 10) * 4;
83 val = *REG(reg_addr);
84 *REG(reg_addr) = (val & FSEL_MASK(pin)) | (func << FSEL_SHIFT(pin));
85 }
87 static inline void set_pin_state(int pin, int s)
88 {
89 int reg_addr;
90 int regidx = pin / 32;
91 int bit = pin % 32;
93 if(s) {
94 reg_addr = REG_GPSET_BASE + regidx * 4;
95 *REG(reg_addr) |= 1 << bit;
96 } else {
97 reg_addr = REG_GPCLR_BASE + regidx * 4;
98 *REG(reg_addr) |= 1 << bit;
99 }
100 }
102 static inline int get_pin_state(int pin)
103 {
104 int reg_addr;
105 int regidx = pin / 32;
106 int bit = pin % 32;
108 reg_addr = REG_GPLEV_BASE + regidx * 4;
109 return (*REG(reg_addr) >> bit) & 1;
110 }
112 static void sighandler(int s)
113 {
114 quit = 1;
115 }