Project

General

Profile

Download (6.78 KB) Statistics
| Branch: | Tag: | Revision:
1
#ifdef WINDOWS
2

    
3
#include <stdio.h>
4
#include "serial.h"
5

    
6
static void printErr(const char* text, int err)
7
{
8
	char errorBuf[256];
9
	char* buf = errorBuf;
10
	size_t max = sizeof(errorBuf) - 1;
11
	memset(errorBuf, 0x00, sizeof(errorBuf));
12

    
13
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), LANG_NEUTRAL, buf, (DWORD)max, NULL);
14
	fprintf(stderr, "%s: %s\n", text, errorBuf);
15
	fflush(stderr);
16
}
17

    
18
HANDLE serialOpen(const char* dev)
19
{
20
	char str[64];
21
	HANDLE fd;
22
	int err;
23

    
24
	snprintf(str, sizeof(str), "\\\\.\\%s", dev);
25
	fd = CreateFileA(str, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
26
	if(fd == INVALID_HANDLE_VALUE) {
27
		err = GetLastError();
28
		if(err == ERROR_FILE_NOT_FOUND) {
29
			fprintf(stderr, "could not open %s: serial port does not exist\n", dev);
30
		} else {
31
			snprintf(str, sizeof(str), "could not open %s", dev);
32
			printErr(str, err);
33
		}
34
		goto failed;
35
	}
36

    
37
	if(serialSetBaudrate(fd, 115200) < 0)
38
		goto failed;
39

    
40
	return fd;
41

    
42
failed:
43
	if(fd != INVALID_HANDLE_VALUE)
44
		CloseHandle(fd);
45
	return INVALID_HANDLE_VALUE;
46
}
47

    
48
void serialClose(HANDLE fd)
49
{
50
	if(fd != INVALID_HANDLE_VALUE)
51
		CloseHandle(fd);
52
}
53

    
54
int serialSetBaudrate(HANDLE fd, int baudrate)
55
{
56
	DCB dcb;
57

    
58
	memset(&dcb, 0x00, sizeof(dcb));
59
	dcb.DCBlength = sizeof(dcb);
60
	if(!GetCommState(fd, &dcb)) {
61
		printErr("error getting serial port state", GetLastError());
62
		return -1;
63
	}
64
	dcb.BaudRate = baudrate;
65
	dcb.ByteSize = 8;
66
	dcb.StopBits = ONESTOPBIT;
67
	dcb.Parity = NOPARITY;
68
	dcb.fBinary = 1;
69
	dcb.fOutxCtsFlow = 0;
70
	dcb.fOutxDsrFlow = 0;
71
	dcb.fOutX = 0;
72
	dcb.fInX = 0;
73
	dcb.fNull = 0;
74
	dcb.fTXContinueOnXoff = 0;
75
	dcb.fDtrControl = DTR_CONTROL_DISABLE;
76
	dcb.fDsrSensitivity = 0;
77
	dcb.fRtsControl = RTS_CONTROL_DISABLE;
78
	if(!SetCommState(fd, &dcb)) {
79
		printErr("error setting serial port state", GetLastError());
80
		return -1;
81
	}
82

    
83
	return 0;
84
}
85

    
86
int serialPutC(HANDLE fd, uint8_t c)
87
{
88
	DWORD bytesWritten;
89

    
90
	if(!WriteFile(fd, &c, 1, &bytesWritten, NULL)) {
91
		printErr("error writing to serial port", GetLastError());
92
		return -1;
93
	}
94

    
95
	return 1;
96
}
97

    
98
int serialGetC(HANDLE fd, uint8_t* c, int timeout)
99
{
100
	COMMTIMEOUTS timeouts;
101
	unsigned long res;
102
	COMSTAT comStat;
103
	DWORD errors;
104

    
105
	if(!ClearCommError(fd, &errors, &comStat)) {
106
		printErr("could not reset comm errors", GetLastError());
107
		return -1;
108
	}
109

    
110
	if(!GetCommTimeouts(fd, &timeouts)) {
111
		printErr("error getting comm timeouts", GetLastError());
112
		return -1;
113
	}
114
	timeouts.ReadIntervalTimeout = timeout;
115
	timeouts.ReadTotalTimeoutConstant = timeout;
116
	timeouts.ReadTotalTimeoutMultiplier = 10;
117
	if(!SetCommTimeouts(fd, &timeouts)) {
118
		printErr("error setting comm timeouts", GetLastError());
119
		return -1;
120
	}
121

    
122
	if(!ReadFile(fd, c, 1, &res, NULL)) {
123
		printErr("error reading from serial port", GetLastError());
124
		return -1;
125
	}
126

    
127
	if(res != 1)
128
		return -1;
129

    
130
	return *c;
131
}
132

    
133
#else // #ifdef WINDOWS
134

    
135
#include <stdio.h>
136
#include <string.h>
137
#include <errno.h>
138
#include <unistd.h>
139
#include <fcntl.h>
140
#include <termios.h>
141
#include <poll.h>
142
#include "serial.h"
143

    
144
HANDLE serialOpen(const char* dev)
145
{
146
	HANDLE fd;
147

    
148
	if((fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
149
		fprintf(stderr, "could not open %s: %s\n", dev, strerror(errno));
150
		goto failed;
151
	}
152
	if(tcflush(fd, TCIOFLUSH) < 0) {
153
		fprintf(stderr, "tcflush() failed: %s\n", strerror(errno));
154
		goto failed;
155
	}
156
	if(serialSetBaudrate(fd, 115200) < 0)
157
		goto failed;
158

    
159
	return fd;
160

    
161
failed:
162
	if(fd >= 0)
163
		close(fd);
164
	return INVALID_HANDLE_VALUE;
165
}
166

    
167
void serialClose(HANDLE fd)
168
{
169
	if(fd != INVALID_HANDLE_VALUE)
170
		close(fd);
171
}
172

    
173
int serialSetBaudrate(HANDLE fd, int baudrate)
174
{
175
	struct termios tios;
176

    
177
	bzero(&tios, sizeof(tios));
178
	switch(baudrate) {
179
		case 230400:
180
			tios.c_cflag = B230400;
181
			break;
182

    
183
		case 460800:
184
			tios.c_cflag = B460800;
185
			break;
186

    
187
		case 921600:
188
			tios.c_cflag = B921600;
189
			break;
190

    
191
		default:
192
			tios.c_cflag = B115200;
193
			break;
194
	}
195
	tios.c_cflag |= CS8 | CLOCAL | CREAD;
196
	tios.c_iflag = IGNPAR;
197
	tios.c_oflag = 0;
198
	tios.c_lflag = ICANON;
199
	tios.c_cc[VMIN] = 1;
200
	cfmakeraw(&tios);
201

    
202
	if(tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
203
		fprintf(stderr, "tcsetattr() failed: %s\n", strerror(errno));
204
		return -1;
205
	}
206
	if(tcflush(fd, TCIOFLUSH) < 0) {
207
		fprintf(stderr, "tcflush() failed: %s\n", strerror(errno));
208
		return -1;
209
	}
210

    
211
	return 0;
212
}
213

    
214
int serialPutC(HANDLE fd, uint8_t c)
215
{
216
	if(write(fd, &c, sizeof(uint8_t)) != sizeof(uint8_t)) {
217
		if(errno == EAGAIN) {
218
			struct pollfd pollfd;
219
			int res;
220
			pollfd.fd = fd;
221
			pollfd.events = POLLOUT;
222
			pollfd.revents = 0;
223
			do {
224
				res = poll(&pollfd, 1, 250);
225
			} while((res < 0) && (errno == EINTR));
226
			if(res > 0) {
227
				if(write(fd, &c, sizeof(char)) != sizeof(char)) {
228
					fprintf(stderr, "write failed: %s\n", strerror(errno));
229
					return -1;
230
				} else {
231
					return 0;
232
				}
233
			} else if(res == 0) {
234
				fprintf(stderr, "write failed: %s\n", strerror(errno));
235
				return -1;
236
			} else {
237
				fprintf(stderr, "poll failed: %s\n", strerror(errno));
238
				return -1;
239
			}
240
		} else {
241
			fprintf(stderr, "write failed: %s\n", strerror(errno));
242
			return -1;
243
		}
244
	} else {
245
		return 0;
246
	}
247
}
248

    
249
int serialGetC(HANDLE fd, uint8_t* c, int timeout)
250
{
251
	struct pollfd pollfd;
252
	int res;
253

    
254
	pollfd.fd = fd;
255
	pollfd.events = POLLIN;
256
	pollfd.revents = 0;
257

    
258
	do {
259
		res = poll(&pollfd, 1, timeout);
260
	} while((res < 0) && (errno == EINTR));
261

    
262
	if(res > 0) {
263
		if(read(fd, c, sizeof(char)) != sizeof(char)) {
264
			fprintf(stderr, "read failed: %s\n", strerror(errno));
265
			return -1;
266
		} else {
267
			return 0;
268
		}
269
	} else if(res == 0) {
270
		// timeout
271
		return -1;
272
	}
273

    
274
	fprintf(stderr, "poll failed: %s\n", strerror(errno));
275
	return -1;
276
}
277

    
278
#endif // #ifdef WINDOWS
279

    
280
int serialPutS(HANDLE fd, const char* str)
281
{
282
	while(*str != '\0') {
283
		if(serialPutC(fd, *((uint8_t*)str)) < 0)
284
			return -1;
285
		str++;
286
	}
287
	return 0;
288
}
289

    
290
int serialGetS(HANDLE fd, char* str, int len, int timeout)
291
{
292
	int todo = len;
293
	uint64_t endTime = getTickCount() + timeout;
294

    
295
	while(todo > 0) {
296
		uint64_t now = getTickCount();
297

    
298
		if(now < endTime) {
299
			uint8_t c;
300
			if(serialGetC(fd, &c, endTime - now) < 0)
301
				return -1;
302
			*((uint8_t*)str) = c;
303
			str++;
304
			todo--;
305
		} else {
306
			break;
307
		}
308
	}
309

    
310
	return (todo > 0) ? -1 : 0;
311
}
312

    
313
int serialExpect(HANDLE fd, const char* str, int timeout)
314
{
315
	int todo = strlen(str);
316
	uint64_t endTime = getTickCount() + timeout;
317

    
318
	while(todo > 0) {
319
		uint64_t now = getTickCount();
320

    
321
		if(now < endTime) {
322
			uint8_t c;
323
			if(serialGetC(fd, &c, endTime - now) < 0)
324
				return -1;
325
			//fprintf(stderr, "{%c}", c);
326
			if(c == (uint8_t)(*str++)) {
327
				todo--;
328
				continue;
329
			} else {
330
				return -1;
331
			}
332
		} else {
333
			break;
334
		}
335
	}
336

    
337
	return (todo > 0) ? -1 : 0;
338
}
(2-2/5)
Add picture from clipboard (Maximum size: 48.8 MB)