Commit | Line | Data |
---|---|---|
e23fe653 JM |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <string.h> | |
4 | ||
5 | #include <windows.h> | |
6 | #include <conio.h> | |
7 | ||
8 | #include "log.h" | |
9 | #include "serial.h" | |
10 | ||
11 | struct serial_port { | |
12 | HANDLE handle; | |
13 | }; | |
14 | ||
15 | port_t * serial_open(const char *name, int speed) | |
16 | { | |
17 | port_t *pt = NULL; | |
18 | HANDLE port = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, | |
19 | 0, NULL, OPEN_EXISTING, 0, NULL); | |
20 | ||
21 | if (port == INVALID_HANDLE_VALUE) return NULL; | |
22 | ||
23 | DCB settings; | |
24 | memset(&settings, 0, sizeof(settings)); | |
25 | settings.DCBlength = sizeof(settings); | |
26 | ||
27 | char seta[120]; | |
28 | snprintf(seta, sizeof(seta), "baud=%d data=8 parity=N stop=1 dtr=off rts=off", speed); | |
29 | if (!BuildCommDCBA(seta, &settings)) { | |
30 | loge("Invalid serial port settings"); | |
31 | CloseHandle(port); | |
32 | return NULL; | |
33 | } | |
34 | ||
35 | if (!SetCommState(port, &settings)) { | |
36 | loge("Unable to configure serial port"); | |
37 | CloseHandle(port); | |
38 | return NULL; | |
39 | } | |
40 | ||
41 | COMMTIMEOUTS tout; | |
42 | tout.ReadIntervalTimeout = MAXDWORD; | |
43 | tout.ReadTotalTimeoutMultiplier = MAXDWORD; | |
44 | tout.ReadTotalTimeoutConstant = 30000; | |
45 | tout.WriteTotalTimeoutMultiplier = 0; | |
46 | tout.WriteTotalTimeoutConstant = 0; | |
47 | ||
48 | if (!SetCommTimeouts(port, &tout)) { | |
49 | loge("Unable to set serial timeouts"); | |
50 | CloseHandle(port); | |
51 | return NULL; | |
52 | } | |
53 | ||
54 | pt = malloc(sizeof(port_t)); | |
55 | pt->handle = port; | |
56 | ||
57 | return pt; | |
58 | ||
59 | } | |
60 | ||
61 | void serial_close(port_t * pt) | |
62 | { | |
63 | if (pt == NULL) return; | |
64 | if (pt->handle == INVALID_HANDLE_VALUE) return; | |
65 | ||
66 | CloseHandle(pt->handle); | |
67 | pt->handle = INVALID_HANDLE_VALUE; | |
68 | ||
69 | return; | |
70 | } | |
71 | ||
72 | int serial_read(port_t * pt, unsigned char * buff, size_t len) | |
73 | { | |
74 | if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1; | |
75 | int count = 0; | |
76 | unsigned char * p = buff; | |
77 | int done = 0; | |
78 | ||
79 | /* read will block if no chars, will return whats there otherwise, | |
80 | * and will timeout after 30 seconds */ | |
81 | while (done < len) { | |
82 | if (!ReadFile(pt->handle, p, len-done, (LPDWORD)&count, NULL)) | |
83 | return -1; | |
84 | p += count; | |
85 | done += count; | |
86 | } | |
87 | ||
88 | return count; | |
89 | } | |
90 | ||
91 | int serial_write(port_t * pt, unsigned char * buff, size_t len) | |
92 | { | |
93 | if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1; | |
94 | ||
95 | int n; | |
96 | ||
97 | if (WriteFile(pt->handle, buff, len, (LPDWORD)&n, NULL)) | |
98 | return n; | |
99 | ||
100 | return 0; | |
101 | } | |
102 | ||
103 | int serial_break(port_t * pt, int set) | |
104 | { | |
105 | if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1; | |
106 | ||
107 | if (set) { | |
108 | SetCommBreak(pt->handle); | |
109 | } else { | |
110 | ClearCommBreak(pt->handle); | |
111 | } | |
112 | ||
113 | return 0; | |
114 | } | |
115 |