raspi_tests
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gpiotest1/test.c Tue Mar 01 07:38:36 2016 +0000 1.3 @@ -0,0 +1,115 @@ 1.4 +#include <stdio.h> 1.5 +#include <signal.h> 1.6 +#include <unistd.h> 1.7 +#include <fcntl.h> 1.8 +#include <sys/mman.h> 1.9 +#include "bcm_host.h" 1.10 + 1.11 +#define REG_GPFSEL_BASE 0x200000 1.12 +#define REG_GPSET_BASE 0x20001c 1.13 +#define REG_GPCLR_BASE 0x200028 1.14 +#define REG_GPLEV_BASE 0x200034 1.15 + 1.16 +#define FSEL_BITS 3 1.17 +#define FSEL_INPUT 0 1.18 +#define FSEL_OUTPUT 1 1.19 + 1.20 +#define FSEL_SHIFT(i) (((i) % 10) * 3) 1.21 +#define FSEL_MASK(i) (3 << FSEL_SHIFT(i)) 1.22 + 1.23 +#define REG(r) (volatile uint32_t*)((unsigned char*)iomem + (r)) 1.24 + 1.25 +void *iomem; 1.26 +int quit; 1.27 + 1.28 +static inline void set_pin_func(int pin, int func); 1.29 +static inline void set_pin_state(int pin, int s); 1.30 +static inline int get_pin_state(int pin); 1.31 +static void sighandler(int s); 1.32 + 1.33 +int main(void) 1.34 +{ 1.35 + int fd; 1.36 + int i; 1.37 + uint32_t io_addr, io_size; 1.38 + 1.39 + signal(SIGINT, sighandler); 1.40 + signal(SIGQUIT, sighandler); 1.41 + signal(SIGSEGV, sighandler); 1.42 + signal(SIGILL, sighandler); 1.43 + signal(SIGFPE, sighandler); 1.44 + 1.45 + io_addr = bcm_host_get_peripheral_address(); 1.46 + io_size = bcm_host_get_peripheral_size(); 1.47 + printf("I/O registers\n"); 1.48 + printf(" addr: %x\n", io_addr); 1.49 + printf(" size: %d\n", io_size); 1.50 + 1.51 + if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { 1.52 + perror("failed to open /dev/mem"); 1.53 + return 1; 1.54 + } 1.55 + if((iomem = mmap(0, io_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, io_addr)) == (void*)-1) { 1.56 + perror("failed to map I/O registers range"); 1.57 + return 1; 1.58 + } 1.59 + 1.60 + /* configure GPIO pins 4 and 17 as outputs */ 1.61 + set_pin_func(4, FSEL_OUTPUT); 1.62 + set_pin_func(17, FSEL_OUTPUT); 1.63 + 1.64 + i = 0; 1.65 + while(!quit) { 1.66 + set_pin_state(4, i & 1); 1.67 + set_pin_state(17, (~i) & 1); 1.68 + ++i; 1.69 + sleep(1); 1.70 + } 1.71 + 1.72 + set_pin_state(4, 0); 1.73 + set_pin_state(17, 0); 1.74 + set_pin_func(4, FSEL_INPUT); 1.75 + set_pin_func(17, FSEL_INPUT); 1.76 + 1.77 + munmap(iomem, io_size); 1.78 + close(fd); 1.79 + return 0; 1.80 +} 1.81 + 1.82 +static inline void set_pin_func(int pin, int func) 1.83 +{ 1.84 + int reg_addr, val; 1.85 + reg_addr = REG_GPFSEL_BASE + (pin / 10) * 4; 1.86 + val = *REG(reg_addr); 1.87 + *REG(reg_addr) = (val & FSEL_MASK(pin)) | (func << FSEL_SHIFT(pin)); 1.88 +} 1.89 + 1.90 +static inline void set_pin_state(int pin, int s) 1.91 +{ 1.92 + int reg_addr; 1.93 + int regidx = pin / 32; 1.94 + int bit = pin % 32; 1.95 + 1.96 + if(s) { 1.97 + reg_addr = REG_GPSET_BASE + regidx * 4; 1.98 + *REG(reg_addr) |= 1 << bit; 1.99 + } else { 1.100 + reg_addr = REG_GPCLR_BASE + regidx * 4; 1.101 + *REG(reg_addr) |= 1 << bit; 1.102 + } 1.103 +} 1.104 + 1.105 +static inline int get_pin_state(int pin) 1.106 +{ 1.107 + int reg_addr; 1.108 + int regidx = pin / 32; 1.109 + int bit = pin % 32; 1.110 + 1.111 + reg_addr = REG_GPLEV_BASE + regidx * 4; 1.112 + return (*REG(reg_addr) >> bit) & 1; 1.113 +} 1.114 + 1.115 +static void sighandler(int s) 1.116 +{ 1.117 + quit = 1; 1.118 +}