Skip to content

Instantly share code, notes, and snippets.

@aycabta
Created January 2, 2017 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aycabta/0f049955d23f0ca1815ef4c7b73fe985 to your computer and use it in GitHub Desktop.
Save aycabta/0f049955d23f0ca1815ef4c7b73fe985 to your computer and use it in GitHub Desktop.
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/gpio.h>
#define ONE_SECOND 1000000
int gpio_write(int fd, int pin, int value)
{
int ret;
struct gpio_req req;
req.gp_pin = pin;
req.gp_value = value;
ret = ioctl(fd, GPIOSET, &req);
if (ret < 0) {
perror("ioctl(GPIOSET)");
exit(2);
}
return ret;
}
void plus_usec(struct timeval *timeval, long usec)
{
timeval->tv_usec += usec;
while (timeval->tv_usec >= ONE_SECOND) {
timeval->tv_usec -= ONE_SECOND;
timeval->tv_sec += 1;
}
}
int after_now(struct timeval *timeval)
{
struct timeval now;
gettimeofday(&now, NULL);
if (now.tv_sec > timeval->tv_sec) {
return 1;
} else if (now.tv_sec == timeval->tv_sec && now.tv_usec > timeval->tv_usec) {
return 1;
}
return 0;
}
long angle_to_pulse_width(int angle)
{
if (angle < 0 || 180 < angle) {
perror("0 <= angle <= 180");
exit(3);
}
return 500 + ((int)(angle * 1900 / 180));
}
int main(int argc, char **argv)
{
int fd;
int on;
struct timeval end;
struct timeval next_cycle;
struct timeval next_pulse_end;
long cycle_usec;
long pulse_width_usec;
int angle;
fd = open("/dev/gpioc0", O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
angle = 0;
if (argc > 1) {
angle = atoi(argv[1]);
}
cycle_usec = 20 * 1000;
pulse_width_usec = angle_to_pulse_width(angle);
gettimeofday(&end, NULL);
plus_usec(&end, ONE_SECOND / 6);
gettimeofday(&next_cycle, NULL);
on = 0;
while (1) {
if (!on && after_now(&next_cycle)) {
next_pulse_end = next_cycle;
plus_usec(&next_pulse_end, pulse_width_usec);
plus_usec(&next_cycle, cycle_usec);
gpio_write(fd, 18, 1);
on = 1;
} else if (on && after_now(&next_pulse_end)) {
gpio_write(fd, 18, 0);
on = 0;
}
usleep(1);
if (after_now(&end)) {
break;
}
}
close(fd);
return 0;
}
all: freebsd_pwm
freebsd_pwm: freebsd_pwm.o
clang freebsd_pwm.o -o freebsd_pwm
freebsd_pwm.o: freebsd_pwm.c
clang -c freebsd_pwm.c
clean:
rm freebsd_pwm freebsd_pwm.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment