-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgcode.cpp
168 lines (136 loc) · 3.86 KB
/
gcode.cpp
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// cheap hack to determine if building for raspberry pi
#ifdef __arm__
#include "gcode.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
fprintf(stderr, "Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= CLOCAL | CREAD;
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_lflag |= ICANON | ISIG; /* canonical input */
tty.c_lflag &= ~(ECHO | ECHOE | ECHONL | IEXTEN);
tty.c_iflag &= ~IGNCR; /* preserve carriage return */
tty.c_iflag &= ~INPCK;
tty.c_iflag &= ~(INLCR | ICRNL | IUCLC | IMAXBEL);
tty.c_iflag &= ~(IXON | IXOFF | IXANY); /* no SW flowcontrol */
tty.c_oflag &= ~OPOST;
tty.c_cc[VEOL] = 0;
tty.c_cc[VEOL2] = 0;
tty.c_cc[VEOF] = 0x04;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
fprintf(stderr, "Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
// Wait for input to become ready for read or timeout reached. If the file-descriptor
// becomes readable, returns number of milli-seconds left.
// Returns 0 on timeout (i.e. no millis left and nothing to be read).
// Returns -1 on error.
static int AwaitReadReady(int fd, int timeout_millis) {
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = timeout_millis * 1000;
FD_SET(fd, &read_fds);
int s = select(fd + 1, &read_fds, NULL, NULL, &tv);
if (s < 0)
return -1;
return tv.tv_usec / 1000;
}
int DiscardPendingInput(int fd, int timeout_ms, bool echo_received_data)
{
int total_bytes = 0;
char buf[128];
if (fd < 0)
return 0;
while (AwaitReadReady(fd, timeout_ms) > 0)
{
int r = read(fd, buf, sizeof(buf));
if (r < 0)
{
fprintf(stderr, "Error reading serial data", strerror(errno));
return -1;
}
total_bytes += r;
if (r > 0 && echo_received_data)
{
write(STDERR_FILENO, buf, r);
}
}
return total_bytes;
}
int gcode_open(const char *portname)
{
int fd;
// open the serial port to the CNC machine
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
fprintf(stderr, "Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
// baudrate 115200, 8 bits, no parity, 1 stop bit
set_interface_attribs(fd, B115200);
// If there is some initial chatter (like the grbl connect message), ignore it, until there is some time
// silence on the wire. That way, we only get OK responses to our requests.
DiscardPendingInput(fd, 3000, true);
return fd;
}
int gcode_write(int fd, const char *gcode)
{
int wlen, len;
char buf[256];
#ifdef _DEBUG
printf(gcode);
#endif
len = strlen(gcode);
wlen = write(fd, gcode, len);
if (wlen != len)
{
fprintf(stderr, "Error from write: %d, %s\n", wlen, strerror(errno));
return -1;
}
/* delay for output */
tcdrain(fd);
/* wait for "ok" response */
len = read(fd, buf, sizeof(buf) - 1);
if (len > 0)
{
buf[len] = 0;
if (!strncasecmp(buf, "ok", 2))
return 0;
fprintf(stderr, "Looking for 'ok' but got '%s'\n", buf);
}
else if (len < 0)
{
fprintf(stderr, "Error from read: %d: %s\n", len, strerror(errno));
}
else /* len == 0 */
{
fprintf(stderr, "Nothing read. EOF?\n");
}
return -1;
}
void gcode_close(int fd)
{
close(fd);
}
#endif