raspi_tests

changeset 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
files .hgignore gpiotest1/Makefile gpiotest1/test.c
diffstat 3 files changed, 135 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Tue Mar 01 07:38:36 2016 +0000
     1.3 @@ -0,0 +1,4 @@
     1.4 +\.o$
     1.5 +\.swp$
     1.6 +\.d$
     1.7 +test$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/gpiotest1/Makefile	Tue Mar 01 07:38:36 2016 +0000
     2.3 @@ -0,0 +1,16 @@
     2.4 +obj = test.o
     2.5 +bin = test
     2.6 +
     2.7 +vidcore_inc = -I/opt/vc/include \
     2.8 +			  -I/opt/vc/include/interface/vcos/pthreads \
     2.9 +			  -I/opt/vc/include/interface/vmcs_host/linux
    2.10 +
    2.11 +CFLAGS = -std=gnu99 -pedantic -Wall -g $(vidcore_inc)
    2.12 +LDFLAGS = -L/opt/vc/lib -lbcm_host
    2.13 +
    2.14 +$(bin): $(obj)
    2.15 +	$(CC) -o $@ $(obj) $(LDFLAGS)
    2.16 +
    2.17 +.PHONY: clean
    2.18 +clean:
    2.19 +	rm -f $(obj) $(bin)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/gpiotest1/test.c	Tue Mar 01 07:38:36 2016 +0000
     3.3 @@ -0,0 +1,115 @@
     3.4 +#include <stdio.h>
     3.5 +#include <signal.h>
     3.6 +#include <unistd.h>
     3.7 +#include <fcntl.h>
     3.8 +#include <sys/mman.h>
     3.9 +#include "bcm_host.h"
    3.10 +
    3.11 +#define REG_GPFSEL_BASE	0x200000
    3.12 +#define REG_GPSET_BASE	0x20001c
    3.13 +#define REG_GPCLR_BASE	0x200028
    3.14 +#define REG_GPLEV_BASE	0x200034
    3.15 +
    3.16 +#define FSEL_BITS	3
    3.17 +#define FSEL_INPUT	0
    3.18 +#define FSEL_OUTPUT	1
    3.19 +
    3.20 +#define FSEL_SHIFT(i)	(((i) % 10) * 3)
    3.21 +#define FSEL_MASK(i)	(3 << FSEL_SHIFT(i))
    3.22 +
    3.23 +#define REG(r)	(volatile uint32_t*)((unsigned char*)iomem + (r))
    3.24 +
    3.25 +void *iomem;
    3.26 +int quit;
    3.27 +
    3.28 +static inline void set_pin_func(int pin, int func);
    3.29 +static inline void set_pin_state(int pin, int s);
    3.30 +static inline int get_pin_state(int pin);
    3.31 +static void sighandler(int s);
    3.32 +
    3.33 +int main(void)
    3.34 +{
    3.35 +	int fd;
    3.36 +	int i;
    3.37 +	uint32_t io_addr, io_size;
    3.38 +
    3.39 +	signal(SIGINT, sighandler);
    3.40 +	signal(SIGQUIT, sighandler);
    3.41 +	signal(SIGSEGV, sighandler);
    3.42 +	signal(SIGILL, sighandler);
    3.43 +	signal(SIGFPE, sighandler);
    3.44 +
    3.45 +	io_addr = bcm_host_get_peripheral_address();
    3.46 +	io_size = bcm_host_get_peripheral_size();
    3.47 +	printf("I/O registers\n");
    3.48 +	printf("  addr: %x\n", io_addr);
    3.49 +	printf("  size: %d\n", io_size);
    3.50 +
    3.51 +	if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
    3.52 +		perror("failed to open /dev/mem");
    3.53 +		return 1;
    3.54 +	}
    3.55 +	if((iomem = mmap(0, io_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, io_addr)) == (void*)-1) {
    3.56 +		perror("failed to map I/O registers range");
    3.57 +		return 1;
    3.58 +	}
    3.59 +
    3.60 +	/* configure GPIO pins 4 and 17 as outputs */
    3.61 +	set_pin_func(4, FSEL_OUTPUT);
    3.62 +	set_pin_func(17, FSEL_OUTPUT);
    3.63 +
    3.64 +	i = 0;
    3.65 +	while(!quit) {
    3.66 +		set_pin_state(4, i & 1);
    3.67 +		set_pin_state(17, (~i) & 1);
    3.68 +		++i;
    3.69 +		sleep(1);
    3.70 +	}
    3.71 +
    3.72 +	set_pin_state(4, 0);
    3.73 +	set_pin_state(17, 0);
    3.74 +	set_pin_func(4, FSEL_INPUT);
    3.75 +	set_pin_func(17, FSEL_INPUT);
    3.76 +
    3.77 +	munmap(iomem, io_size);
    3.78 +	close(fd);
    3.79 +	return 0;
    3.80 +}
    3.81 +
    3.82 +static inline void set_pin_func(int pin, int func)
    3.83 +{
    3.84 +	int reg_addr, val;
    3.85 +	reg_addr = REG_GPFSEL_BASE + (pin / 10) * 4;
    3.86 +	val = *REG(reg_addr);
    3.87 +	*REG(reg_addr) = (val & FSEL_MASK(pin)) | (func << FSEL_SHIFT(pin));
    3.88 +}
    3.89 +
    3.90 +static inline void set_pin_state(int pin, int s)
    3.91 +{
    3.92 +	int reg_addr;
    3.93 +	int regidx = pin / 32;
    3.94 +	int bit = pin % 32;
    3.95 +
    3.96 +	if(s) {
    3.97 +		reg_addr = REG_GPSET_BASE + regidx * 4;
    3.98 +		*REG(reg_addr) |= 1 << bit;
    3.99 +	} else {
   3.100 +		reg_addr = REG_GPCLR_BASE + regidx * 4;
   3.101 +		*REG(reg_addr) |= 1 << bit;
   3.102 +	}
   3.103 +}
   3.104 +
   3.105 +static inline int get_pin_state(int pin)
   3.106 +{
   3.107 +	int reg_addr;
   3.108 +	int regidx = pin / 32;
   3.109 +	int bit = pin % 32;
   3.110 +
   3.111 +	reg_addr = REG_GPLEV_BASE + regidx * 4;
   3.112 +	return (*REG(reg_addr) >> bit) & 1;
   3.113 +}
   3.114 +
   3.115 +static void sighandler(int s)
   3.116 +{
   3.117 +	quit = 1;
   3.118 +}