forked from ole00/afterburner
-
Notifications
You must be signed in to change notification settings - Fork 3
/
serial_port.h
170 lines (130 loc) · 4.82 KB
/
serial_port.h
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
169
#ifndef _SERIAL_PORT_H_
#define _SERIAL_PORT_H_
#ifdef _USE_WIN_API_
#include <windows.h>
#define SerialDeviceHandle HANDLE
#define DEFAULT_SERIAL_DEVICE_NAME "COM1"
#define INVALID_HANDLE INVALID_HANDLE_VALUE
// https://www.xanthium.in/Serial-Port-Programming-using-Win32-API
static inline SerialDeviceHandle serialDeviceOpen(char* deviceName) {
SerialDeviceHandle h;
h = CreateFile(
deviceName, //port name
GENERIC_READ | GENERIC_WRITE, //Read/Write
0, // No Sharing
NULL, // No Security
OPEN_EXISTING,// Open existing port only
0, // Non Overlapped I/O
NULL); // Null for Comm Devices
if (h != INVALID_HANDLE) {
BOOL result;
COMMTIMEOUTS timeouts = { 0 };
DCB dcbSerialParams = { 0 }; // Initializing DCB structure
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
result = GetCommState(h, &dcbSerialParams);
if (!result) {
return INVALID_HANDLE;
}
dcbSerialParams.BaudRate = CBR_38400; // Setting BaudRate = 38400
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT;// Setting StopBits = 1
dcbSerialParams.Parity = NOPARITY; // Setting Parity = None
result = SetCommState(h, &dcbSerialParams);
if (!result) {
return INVALID_HANDLE;
}
timeouts.ReadIntervalTimeout = 50; // in milliseconds
timeouts.ReadTotalTimeoutConstant = 50; // in milliseconds
timeouts.ReadTotalTimeoutMultiplier = 10; // in milliseconds
timeouts.WriteTotalTimeoutConstant = 50; // in milliseconds
timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds
result = SetCommTimeouts(h, &timeouts);
if (!result) {
return INVALID_HANDLE;
}
return h;
} else {
return INVALID_HANDLE;
}
}
void serialDeviceCheckName(char* name, int maxSize) {
int nameLen = strlen(name);
//convert comxx to COMxx
if (strncmp(name, "com", 3) == 0 && (nameLen > 3 && name[3] >= '0' && name[3] <= '9')) {
name[0] = 'C';
name[1] = 'O';
name[2] = 'M';
}
// convert COMxx and higher to \\\\.\\COMxx
if (strncmp(name, "COM", 3) == 0 && (nameLen > 4 && name[3] >= '0' && name[3] <= '9')) {
if (nameLen + 4 < maxSize) {
int i;
for (i = nameLen - 1; i >= 0; i--) {
name[ i + 4] = name[i];
}
name[0] = '\\';
name[1] = '\\';
name[2] = '.';
name[3] = '\\';
}
}
}
static inline void serialDeviceClose(SerialDeviceHandle deviceHandle) {
CloseHandle(deviceHandle);
}
static inline int serialDeviceWrite(SerialDeviceHandle deviceHandle, char* buffer, int bytesToWrite) {
DWORD written = 0;
WriteFile(deviceHandle, buffer, bytesToWrite, &written, NULL);
return (int) written;
}
static inline int serialDeviceRead(SerialDeviceHandle deviceHandle, char* buffer, int bytesToRead) {
DWORD read = 0;
ReadFile(deviceHandle, buffer, bytesToRead, &read, NULL);
return (int) read;
}
#else
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#define SerialDeviceHandle int
#define DEFAULT_SERIAL_DEVICE_NAME "/dev/ttyUSB0"
#define INVALID_HANDLE -1
static inline SerialDeviceHandle serialDeviceOpen(char* deviceName) {
SerialDeviceHandle h;
h = open(deviceName, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (h != INVALID_HANDLE) {
//set the serial port parameters
struct termios serial;
memset(&serial, 0, sizeof(struct termios));
cfsetispeed(&serial, B38400);
cfsetospeed(&serial, B38400);
serial.c_cflag |= CS8; // no parity, 1 stop bit
serial.c_cflag |= CREAD | CLOCAL;
if (0 != tcsetattr(h, TCSANOW, &serial)) {
close(h);
printf("Error: failed to set serial parameters %i, %s\n", errno, strerror(errno));
return INVALID_HANDLE;
}
//ensure no leftover bytes exist on the serial line
tcdrain(h);
tcflush(h, TCIOFLUSH); //flush both queues
return h;
} else {
return INVALID_HANDLE;
}
}
void serialDeviceCheckName(char* name, int maxSize) {
//nothing to check
}
static inline void serialDeviceClose(SerialDeviceHandle deviceHandle) {
close(deviceHandle);
}
static inline int serialDeviceWrite(SerialDeviceHandle deviceHandle, char* buffer, int bytesToWrite) {
return write(deviceHandle, buffer, bytesToWrite);
}
static inline int serialDeviceRead(SerialDeviceHandle deviceHandle, char* buffer, int bytesToRead) {
return read(deviceHandle, buffer, bytesToRead);
}
#endif
#endif /* _SERIAL_PORT_H_ */