-
Notifications
You must be signed in to change notification settings - Fork 1
/
gqgeiger.c
114 lines (86 loc) · 2.28 KB
/
gqgeiger.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "gqgeiger.h"
int gq_open(const char *device, speed_t baud) {
int fd = -1;
struct termios tio;
memset(&tio, 0, sizeof(struct termios));
tio.c_cflag = CS8 | CREAD | CLOCAL; // 8n1
tio.c_cc[VMIN] = 0;
tio.c_cc[VTIME] = 5;
if ((fd = open(device, O_RDWR)) != -1) {
if (cfsetspeed(&tio, baud) == 0) // usually 57600 or 115200 baud
if (tcsetattr(fd, TCSANOW, &tio) == 0)
// Turn off heartbeat,
if (gq_set_heartbeat_off(fd))
return fd;
// ... otherwise close device.
close(fd);
fd = -1;
}
return fd;
}
void gq_close(int device) {
close(device);
}
int gq_get_cpm(int device) {
const char cmd[] = "<GETCPM>>";
char buf[3] = { 0 };
if (gq_write(device, cmd) == (ssize_t) strlen(cmd))
gq_read(device, buf, 2);
// Mask out upper 2 bits as mentioned in GQ-RFC1201.
return (((unsigned char)buf[0] & 0x3f) << 8) | ((unsigned char)buf[1] & 0xff);
}
bool gq_set_heartbeat_off(int device) {
const char cmd[] = "<HEARTBEAT0>>";
if (gq_write(device, cmd) == (ssize_t) strlen(cmd))
return gq_flush(device);
return false;
}
bool gq_set_date(int device, int year, int month, int day) {
char y[] = "<SETDATEYY >>";
char m[] = "<SETDATEMM >>";
char d[] = "<SETDATEDD >>";
y[10] = year - 2000;
m[10] = month;
d[10] = day;
return gq_write_ack(device, y) && gq_write_ack(device, m) && gq_write_ack(device, d);
}
bool gq_set_time(int device, int hour, int minute, int second) {
char h[] = "<SETTIMEHH >>";
char m[] = "<SETTIMEMM >>";
char s[] = "<SETTIMESS >>";
h[10] = hour;
m[10] = minute;
s[10] = second;
return gq_write_ack(device, h) && gq_write_ack(device, m) && gq_write_ack(device, s);
}
bool gq_write_ack(int device, const char *cmd) {
char ch;
if (gq_write(device, cmd) == (ssize_t) strlen(cmd))
if (gq_read(device, &ch, 1) == 1 && ch == '\xAA')
return true;
return false;
}
int gq_write(int device, const char *cmd) {
return write(device, cmd, strlen(cmd));
}
int gq_read(int device, char *buf, unsigned int len) {
unsigned int n;
ssize_t rcvd = 0;
char *inp = &buf[0];
for (n = 0; n < len; n++) {
rcvd += read(device, inp, 1);
inp = &buf[rcvd];
if (rcvd >= len)
break;
}
return rcvd;
}
bool gq_flush(int device) {
int i;
char ch;
for (i = 0; i < 10; i++) {
if (read(device, &ch, 1) == 0)
return true;
}
return false;
}