#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <sched.h>
#include <inttypes.h>
#define PIN "132"
void init_pin() {
int fd = open("/sys/class/gpio/export",O_WRONLY);
char buf[16];
int len = sprintf(buf,"%s\n",PIN);
write(fd,buf,len);
close(fd);
fd = open("/sys/class/gpio/gpio" PIN "/direction",O_WRONLY);
write(fd,"out\n",4);
close(fd);
}
void deinit_pin() {
int fd = open("/sys/class/gpio/unexport",O_WRONLY);
char buf[16];
int len = sprintf(buf,"%s\n",PIN);
write(fd,buf,len);
close(fd);
}
int pin_fd;
void write_pin(uint8_t value) {
if (!pin_fd) {
pin_fd = open("/sys/class/gpio/gpio" PIN "/value",O_WRONLY);
}
char buf[16];
int len = sprintf(buf,"%d\n",value);
write(pin_fd,buf,len);
}
void init_sched() {
struct sched_param sp;
sp.sched_priority=99;
sched_setscheduler(0,SCHED_RR,&sp);
}
const int width=520000;
struct timespec next_step;
void send_array(const uint8_t values[],size_t len) {
if (next_step.tv_sec == 0) {
clock_gettime(CLOCK_REALTIME,&next_step);
}
uint8_t pin_value = 1;
for (int i=0; i<len; ++i) {
write_pin(pin_value);
pin_value = 1 - pin_value;
next_step.tv_nsec += width * values[i];
if (next_step.tv_nsec > 1000000000UL) {
next_step.tv_nsec -= 1000000000UL;
++next_step.tv_sec;
}
int rc = clock_nanosleep(CLOCK_REALTIME,
TIMER_ABSTIME,
&next_step,
NULL);
if (rc) {
printf("problems: %d\n",rc);
}
}
}
void my_sleep(uint8_t seconds) {
next_step.tv_sec += seconds;
int rc = clock_nanosleep(CLOCK_REALTIME,
TIMER_ABSTIME,
&next_step,
NULL);
if (rc) {
printf("problems: %d\n",rc);
}
}
const uint8_t prologue[] = {
1,1, 1,1, 1,1, 1,1, 1,1, 1,1,
2,3, 1,1, 2,2, 1,1, 1,1, 2,1,
1,1, 1,1, 1,2, 1,1, 1,1, 1,1,
1,1, 1,1,
};
const size_t prologueSize = sizeof(prologue) / sizeof(uint8_t);
const uint8_t epilogue[] = {
1,2, 2,2, 1,3,
};
const size_t epilogueSize = sizeof(epilogue) / sizeof(uint8_t);
const uint8_t onSignal[] = {
2,2, 1,1, 1,1, 1,1, 1,1, 2,1, 1,1,
};
const size_t onSize = sizeof(onSignal) / sizeof(uint8_t);
const uint8_t offSignal[] = {
1,1, 1,1, 1,1, 1,1, 1,1, 2,2, 2,1,
};
const size_t offSize = sizeof(offSignal) / sizeof(uint8_t);
void transmitSignal(const uint8_t signal[], size_t signalSize) {
send_array(prologue,prologueSize);
send_array(signal,signalSize);
send_array(epilogue,epilogueSize);
}
void sendTrain(const uint8_t signal[], size_t signalSize) {
transmitSignal(offSignal,offSize);
my_sleep(1);
transmitSignal(signal,signalSize);
my_sleep(2);
transmitSignal(offSignal,offSize);
}
int main(int argc,char **argv) {
if (argc != 2) {
fprintf(stderr,"thing 0/1\n");
return 1;
}
init_sched();
init_pin();
write_pin(0);
if (argv[1][0] == '1') {
sendTrain(onSignal,onSize);
}
else {
sendTrain(offSignal,offSize);
}
deinit_pin();
return 0;
}