forked from danreilly/qnicll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqna_usb.c
136 lines (110 loc) · 2.77 KB
/
qna_usb.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "qna_usb.h"
#include <unistd.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include "qnicll.h"
#include "util.h"
#define IBUF_LEN (1024)
char ibuf[IBUF_LEN];
int fd;
qnicll_set_err_fn *my_set_errmsg_fn;
char umsg[1024];
#define RBUG(MSG) return (*my_set_errmsg_fn)(MSG, QNICLL_ERR_BUG);
#define DO(CALL) {int e=CALL; if (e) return e;}
static int set_attrib(int fd, int speed) {
struct termios tty;
if (tcgetattr(fd, &tty) < 0)
RBUG("tcgetattr");
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN | ECHOE | ECHOK | ECHONL | ECHOCTL );
tty.c_lflag |= ICANON;
tty.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
tty.c_cc[VEOL] = '>'; // end of line char
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = .01;
if (tcsetattr(fd, TCSANOW, &tty) != 0)
RBUG("Error from tcsetattr");
return 0;
}
int dbg=1;
int wr(char *str) {
size_t l;
ssize_t n;
l=strlen(str);
if (dbg) {
printf("qna_usb w: ");
util_print_all(str);
printf("\n");
}
n = write(fd, str, l);
if (n<0) RBUG("write failed");
if (n!=l) {
sprintf(umsg, "did not write %zd chars", l);
RBUG(umsg);
}
return 0;
}
int rd_ibuf(void) {
ssize_t sz;
if (dbg) {
printf("read\n");
printf("qna_usb r: ");
fsync(0);
}
sz =read(fd, ibuf, IBUF_LEN-1);
if (sz<0) RBUG("read from qna usb failed");
ibuf[(int)sz]=0;
if (dbg) {
util_print_all(ibuf);
printf("\n");
}
return 0;
}
int qna_usb_connect(char *devname, qnicll_set_err_fn *set_errmsg_fn) {
my_set_errmsg_fn = set_errmsg_fn;
fd=open(devname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd<0) {
sprintf(umsg, "cant open usb device %s", devname);
RBUG(umsg);
}
if (set_attrib(fd, 115200))
RBUG("cant set serial usb port attributes");
DO(wr("i\r"));
DO(rd_ibuf());
printf("got rsp %s\n", ibuf);
return 0;
}
int qna_usb_do_cmd(char *cmd, char *rsp, int rsp_len) {
ssize_t n;
int p_len;
char *p;
DO(wr(cmd));
DO(wr("\r"));
p = rsp;
p_len = rsp_len-1;
while(1) {
n = read(fd, p, 1023);
if (n<0) RBUG("read error");
p[n]=0;
if (strstr(p,">")) return 0;
p += n;
p_len -= n;
}
return 0;
}
int qna_usb_disconnect(void) {
close(fd);
}