# HG changeset patch # User John Tsiombikas # Date 1456817916 0 # Node ID fbf9076c1984627743c3baa2c6d71b86fc977336 first raspberry pi gpio test (led blinker) diff -r 000000000000 -r fbf9076c1984 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Tue Mar 01 07:38:36 2016 +0000 @@ -0,0 +1,4 @@ +\.o$ +\.swp$ +\.d$ +test$ diff -r 000000000000 -r fbf9076c1984 gpiotest1/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpiotest1/Makefile Tue Mar 01 07:38:36 2016 +0000 @@ -0,0 +1,16 @@ +obj = test.o +bin = test + +vidcore_inc = -I/opt/vc/include \ + -I/opt/vc/include/interface/vcos/pthreads \ + -I/opt/vc/include/interface/vmcs_host/linux + +CFLAGS = -std=gnu99 -pedantic -Wall -g $(vidcore_inc) +LDFLAGS = -L/opt/vc/lib -lbcm_host + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 000000000000 -r fbf9076c1984 gpiotest1/test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpiotest1/test.c Tue Mar 01 07:38:36 2016 +0000 @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include "bcm_host.h" + +#define REG_GPFSEL_BASE 0x200000 +#define REG_GPSET_BASE 0x20001c +#define REG_GPCLR_BASE 0x200028 +#define REG_GPLEV_BASE 0x200034 + +#define FSEL_BITS 3 +#define FSEL_INPUT 0 +#define FSEL_OUTPUT 1 + +#define FSEL_SHIFT(i) (((i) % 10) * 3) +#define FSEL_MASK(i) (3 << FSEL_SHIFT(i)) + +#define REG(r) (volatile uint32_t*)((unsigned char*)iomem + (r)) + +void *iomem; +int quit; + +static inline void set_pin_func(int pin, int func); +static inline void set_pin_state(int pin, int s); +static inline int get_pin_state(int pin); +static void sighandler(int s); + +int main(void) +{ + int fd; + int i; + uint32_t io_addr, io_size; + + signal(SIGINT, sighandler); + signal(SIGQUIT, sighandler); + signal(SIGSEGV, sighandler); + signal(SIGILL, sighandler); + signal(SIGFPE, sighandler); + + io_addr = bcm_host_get_peripheral_address(); + io_size = bcm_host_get_peripheral_size(); + printf("I/O registers\n"); + printf(" addr: %x\n", io_addr); + printf(" size: %d\n", io_size); + + if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { + perror("failed to open /dev/mem"); + return 1; + } + if((iomem = mmap(0, io_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, io_addr)) == (void*)-1) { + perror("failed to map I/O registers range"); + return 1; + } + + /* configure GPIO pins 4 and 17 as outputs */ + set_pin_func(4, FSEL_OUTPUT); + set_pin_func(17, FSEL_OUTPUT); + + i = 0; + while(!quit) { + set_pin_state(4, i & 1); + set_pin_state(17, (~i) & 1); + ++i; + sleep(1); + } + + set_pin_state(4, 0); + set_pin_state(17, 0); + set_pin_func(4, FSEL_INPUT); + set_pin_func(17, FSEL_INPUT); + + munmap(iomem, io_size); + close(fd); + return 0; +} + +static inline void set_pin_func(int pin, int func) +{ + int reg_addr, val; + reg_addr = REG_GPFSEL_BASE + (pin / 10) * 4; + val = *REG(reg_addr); + *REG(reg_addr) = (val & FSEL_MASK(pin)) | (func << FSEL_SHIFT(pin)); +} + +static inline void set_pin_state(int pin, int s) +{ + int reg_addr; + int regidx = pin / 32; + int bit = pin % 32; + + if(s) { + reg_addr = REG_GPSET_BASE + regidx * 4; + *REG(reg_addr) |= 1 << bit; + } else { + reg_addr = REG_GPCLR_BASE + regidx * 4; + *REG(reg_addr) |= 1 << bit; + } +} + +static inline int get_pin_state(int pin) +{ + int reg_addr; + int regidx = pin / 32; + int bit = pin % 32; + + reg_addr = REG_GPLEV_BASE + regidx * 4; + return (*REG(reg_addr) >> bit) & 1; +} + +static void sighandler(int s) +{ + quit = 1; +}