Skip to content
Permalink
10ffa99fef
Go to file
 
 
Cannot retrieve contributors at this time
123 lines (104 sloc) 3.3 KB
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>
#include "clocks/clock_crow.h"
#include "device_crow.h"
#include "events.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
#define TEST_NULL_AND_FREE(p) \
if ((p) != NULL) { \
free(p); \
} else { \
fprintf(stderr, "error: double free in device_crow.c\n"); \
}
#define CROW_RETRIES 10
int dev_crow_init(void *self) {
struct dev_crow *d = (struct dev_crow *)self;
struct dev_common *base = (struct dev_common *)self;
d->fd = open(d->base.path, O_RDWR | O_NOCTTY | O_SYNC);
if (d->fd < 0) {
fprintf(stderr, "failed to open crow device: %s\n", d->base.path);
return -1;
}
tcgetattr(d->fd, &d->oldtio);
// d->newtio.c_cflag = CROW_BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
d->newtio.c_cflag = CROW_BAUDRATE | CS8 | CLOCAL | CREAD;
// d->newtio.c_iflag = IGNPAR | ICRNL;
d->newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
d->newtio.c_oflag = 0;
// d->newtio.c_lflag = ICANON;
d->newtio.c_lflag = 0;
d->newtio.c_cc[VMIN] = 0;
d->newtio.c_cc[VTIME] = 5;
tcflush(d->fd, TCIFLUSH);
tcsetattr(d->fd, TCSANOW, &d->newtio);
// check if modem is a crow
char s[256];
read(d->fd, s, 255); // clear buffer
write(d->fd, "^^i\n\0", 5);
usleep(1000);
int retry = 0;
while (retry < CROW_RETRIES) {
retry++;
memset(s, 0, sizeof(s));
read(d->fd, s, 255);
// fprintf(stderr,"crow init> %i %s",sizeof(s),s);
if (strstr(s, "^^identity") != NULL)
break;
}
if (retry >= CROW_RETRIES) {
fprintf(stderr, ">> ttyACM found, but not a crow\n");
return -1;
}
base->start = &dev_crow_start;
base->deinit = &dev_crow_deinit;
return 0;
}
static void handle_event(void *dev, uint8_t id) {
union event_data *ev = event_data_new(EVENT_CROW_EVENT);
ev->crow_event.dev = dev;
ev->crow_event.id = id;
event_post(ev);
struct dev_crow *d = (struct dev_crow *)dev;
if (strstr(d->line, "^^change(1,1)")) {
clock_crow_handle_clock();
}
}
void *dev_crow_start(void *self) {
struct dev_crow *di = (struct dev_crow *)self;
struct dev_common *base = (struct dev_common *)self;
uint8_t len;
while (1) {
len = read(di->fd, di->line, 255);
if (len > 0) {
di->line[len] = 0; // add null to end of string
if (len > 1) {
// fprintf(stderr,"crow> %s", di->line);
handle_event(self, base->id);
}
len = 0;
}
usleep(1000); // 1ms
}
return NULL;
}
void dev_crow_deinit(void *self) {
struct dev_crow *di = (struct dev_crow *)self;
tcsetattr(di->fd, TCSANOW, &di->oldtio);
}
void dev_crow_send(struct dev_crow *d, const char *line) {
char s[256];
strcpy(s, line);
strcat(s, "\n\0");
// fprintf(stderr,"crow_send: %s",line);
write(d->fd, s, strlen(s));
}
#pragma GCC diagnostic pop