From: John Tsiombikas Date: Tue, 23 Jul 2019 16:38:24 +0000 (+0300) Subject: initial commit X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=rpipulser;a=commitdiff_plain;h=e49ca3664591e457ffd8938ac4ecafd2f87e015b initial commit --- e49ca3664591e457ffd8938ac4ecafd2f87e015b diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9d9159f --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +obj = pulser.o +bin = pulser + +CFLAGS = -pedantic -Wall -g + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff --git a/pulser.c b/pulser.c new file mode 100644 index 0000000..6362d67 --- /dev/null +++ b/pulser.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include +#include + +#define IOBASEADDR 0x3f000000 +#define IOSIZE 16777216 + +#define IOREGADDR(x) ((x) | IOBASEADDR) + +#define REG_GPFSEL0 *((volatile uint32_t*)IOREGADDR(0x200000)) +#define REG_GPFSEL1 *((volatile uint32_t*)IOREGADDR(0x200004)) +#define REG_GPFSEL2 *((volatile uint32_t*)IOREGADDR(0x200008)) +#define REG_GPSET0 *((volatile uint32_t*)IOREGADDR(0x20001c)) +#define REG_GPSET1 *((volatile uint32_t*)IOREGADDR(0x200020)) +#define REG_GPCLR0 *((volatile uint32_t*)IOREGADDR(0x200028)) +#define REG_GPCLR1 *((volatile uint32_t*)IOREGADDR(0x20002c)) + +#define FSEL_OUT(x) (1 << (((x) % 10) * 3)) + +void print_usage(const char *argv0); + +int npulses = 1; +int freqhz = 1; +int duty = 128; /* duty cycle 0-255 */ +int pin = 24; + +int main(int argc, char **argv) +{ + int i, fd; + void *ptr; + long ontime, offtime; + + for(i=1; i= 256) { + fprintf(stderr, "-d must be followed by the duty cycle: 1-255\n"); + return 1; + } + break; + + case 'h': + print_usage(argv[0]); + return 0; + + default: + fprintf(stderr, "invalid option: %s\n", argv[i]); + print_usage(argv[0]); + return 1; + } + } else { + fprintf(stderr, "invalid option: %s\n", argv[i]); + print_usage(argv[0]); + return 1; + } + } else { + fprintf(stderr, "unexpected argument: %s\n", argv[i]); + print_usage(argv[0]); + return 1; + } + } + + + if((fd = open("/dev/mem", O_RDWR)) == -1) { + perror("failed to open /dev/mem"); + return 1; + } + if((ptr = mmap((void*)IOBASEADDR, IOSIZE, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, fd, IOBASEADDR)) == (void*)-1) { + perror("failed to map IO space"); + return 1; + } + assert(ptr == (void*)IOBASEADDR); + + ontime = duty * 1000000 / (freqhz * 256); + offtime = 1000000 / freqhz - ontime; + + printf("%d pulses, %d hz, %d/256 duty cycle\n", npulses, freqhz, duty); + printf("timing: %ldus on, %ldus off\n", ontime, offtime); + + REG_GPCLR0 = 1 << pin; + if(pin < 10) { + REG_GPFSEL0 |= FSEL_OUT(pin); + } else if(pin < 20) { + REG_GPFSEL1 |= FSEL_OUT(pin); + } else if(pin < 30) { + REG_GPFSEL2 |= FSEL_OUT(pin); + } + + for(i=0; i