9 #define IOBASEADDR 0x3f000000
10 #define IOSIZE 16777216
12 #define IOREGADDR(x) ((x) | IOBASEADDR)
14 #define REG_GPFSEL0 *((volatile uint32_t*)IOREGADDR(0x200000))
15 #define REG_GPFSEL1 *((volatile uint32_t*)IOREGADDR(0x200004))
16 #define REG_GPFSEL2 *((volatile uint32_t*)IOREGADDR(0x200008))
17 #define REG_GPSET0 *((volatile uint32_t*)IOREGADDR(0x20001c))
18 #define REG_GPSET1 *((volatile uint32_t*)IOREGADDR(0x200020))
19 #define REG_GPCLR0 *((volatile uint32_t*)IOREGADDR(0x200028))
20 #define REG_GPCLR1 *((volatile uint32_t*)IOREGADDR(0x20002c))
22 #define FSEL_OUT(x) (1 << (((x) % 10) * 3))
24 void print_usage(const char *argv0);
28 int duty = 128; /* duty cycle 0-255 */
31 int main(int argc, char **argv)
37 for(i=1; i<argc; i++) {
38 if(argv[i][0] == '-') {
42 if(!argv[++i] || (npulses = atoi(argv[i])) < 1) {
43 fprintf(stderr, "-n must be followed by the number of pulses\n");
49 if(!argv[++i] || (freqhz = atoi(argv[i])) < 1) {
50 fprintf(stderr, "-f must be followed by the pulse frequency\n");
56 if(!argv[++i] || (duty = atoi(argv[i])) < 1 || duty >= 256) {
57 fprintf(stderr, "-d must be followed by the duty cycle: 1-255\n");
63 if(!argv[++i] || (pin = atoi(argv[i])) < 1 || pin >= 28) {
64 fprintf(stderr, "-p must be followed by a BCM pin number: 1-27\n");
74 fprintf(stderr, "invalid option: %s\n", argv[i]);
79 fprintf(stderr, "invalid option: %s\n", argv[i]);
84 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
91 if((fd = open("/dev/mem", O_RDWR)) == -1) {
92 perror("failed to open /dev/mem");
95 if((ptr = mmap((void*)IOBASEADDR, IOSIZE, PROT_READ | PROT_WRITE,
96 MAP_SHARED | MAP_FIXED, fd, IOBASEADDR)) == (void*)-1) {
97 perror("failed to map IO space");
100 assert(ptr == (void*)IOBASEADDR);
102 ontime = duty * 1000000 / (freqhz * 256);
103 offtime = 1000000 / freqhz - ontime;
105 printf("%d pulses, %d hz, %d/256 duty cycle\n", npulses, freqhz, duty);
106 printf("timing: %ldus on, %ldus off\n", ontime, offtime);
108 REG_GPCLR0 = 1 << pin;
110 REG_GPFSEL0 |= FSEL_OUT(pin);
111 } else if(pin < 20) {
112 REG_GPFSEL1 |= FSEL_OUT(pin);
113 } else if(pin < 30) {
114 REG_GPFSEL2 |= FSEL_OUT(pin);
117 for(i=0; i<npulses; i++) {
118 REG_GPSET0 = 1 << pin;
120 REG_GPCLR0 = 1 << pin;
124 REG_GPCLR0 = 1 << pin;
131 void print_usage(const char *argv0)
133 printf("Usage: %s [options]\n", argv0);
134 printf("Options:\n");
135 printf(" -n: number of pulses to emit (default: 1)\n");
136 printf(" -f: frequency of pulses in hz (default: 1)\n");
137 printf(" -d: duty cycle [1, 255] (default: 128)\n");
138 printf(" -p: BCM pin number [1, 27] (default: 24)\n");
139 printf(" -h: print usage and exit\n");