00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <string.h>
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023 #include <fcntl.h>
00024 #include <unistd.h>
00025 #ifdef _WIN32
00026 #include <windows.h>
00027 #else
00028 #include <glob.h>
00029 #include <termios.h>
00030 #endif
00031 #include <stdlib.h>
00032 #include <glib.h>
00033 #include "sigrok.h"
00034 #include "sigrok-internal.h"
00035
00036
00037 #ifdef _WIN32
00038 static HANDLE hdl;
00039 #endif
00040
00041 static const char *serial_port_glob[] = {
00042
00043 "/dev/ttyS*",
00044 "/dev/ttyUSB*",
00045 "/dev/ttyACM*",
00046
00047 "/dev/ttys*",
00048 "/dev/tty.USB-*",
00049 "/dev/tty.Modem-*",
00050 NULL,
00051 };
00052
00053 SR_PRIV GSList *list_serial_ports(void)
00054 {
00055 GSList *ports;
00056
00057 #ifdef _WIN32
00058
00059 ports = NULL;
00060 ports = g_slist_append(ports, g_strdup("COM1"));
00061 #else
00062 glob_t g;
00063 unsigned int i, j;
00064
00065 ports = NULL;
00066 for (i = 0; serial_port_glob[i]; i++) {
00067 if (glob(serial_port_glob[i], 0, NULL, &g))
00068 continue;
00069 for (j = 0; j < g.gl_pathc; j++)
00070 ports = g_slist_append(ports, g_strdup(g.gl_pathv[j]));
00071 globfree(&g);
00072 }
00073 #endif
00074
00075 return ports;
00076 }
00077
00078 SR_PRIV int serial_open(const char *pathname, int flags)
00079 {
00080 #ifdef _WIN32
00081
00082 hdl = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0,
00083 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
00084 if (hdl == INVALID_HANDLE_VALUE) {
00085
00086 }
00087 return 0;
00088 #else
00089 return open(pathname, flags);
00090 #endif
00091 }
00092
00093
00094
00095
00096
00097 SR_PRIV int serial_close(int fd)
00098 {
00099 #ifdef _WIN32
00100
00101 return (CloseHandle(hdl) == 0) ? -1 : 0;
00102 #else
00103
00104 return close(fd);
00105 #endif
00106 }
00107
00108
00109
00110
00111
00112 SR_PRIV int serial_flush(int fd)
00113 {
00114 #ifdef _WIN32
00115
00116 return (PurgeComm(hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0) ? -1 : 0;
00117 #else
00118
00119 return tcflush(fd, TCIOFLUSH);
00120 #endif
00121 }
00122
00123
00124
00125
00126
00127 SR_PRIV int serial_write(int fd, const void *buf, size_t count)
00128 {
00129 #ifdef _WIN32
00130 DWORD tmp = 0;
00131
00132
00133
00134 WriteFile(hdl, buf, count, &tmp, NULL);
00135 #else
00136
00137 return write(fd, buf, count);
00138 #endif
00139 }
00140
00141
00142
00143
00144
00145 SR_PRIV int serial_read(int fd, void *buf, size_t count)
00146 {
00147 #ifdef _WIN32
00148 DWORD tmp = 0;
00149
00150
00151
00152 return ReadFile(hdl, buf, count, &tmp, NULL);
00153 #else
00154
00155 return read(fd, buf, count);
00156 #endif
00157 }
00158
00159 SR_PRIV void *serial_backup_params(int fd)
00160 {
00161 #ifdef _WIN32
00162
00163 #else
00164 struct termios *term;
00165
00166
00167 if (!(term = g_try_malloc(sizeof(struct termios)))) {
00168 sr_err("serial: %s: term malloc failed", __func__);
00169 return NULL;
00170 }
00171
00172 tcgetattr(fd, term);
00173
00174 return term;
00175 #endif
00176 }
00177
00178 SR_PRIV void serial_restore_params(int fd, void *backup)
00179 {
00180 #ifdef _WIN32
00181
00182 #else
00183 tcsetattr(fd, TCSADRAIN, (struct termios *)backup);
00184 #endif
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 SR_PRIV int serial_set_params(int fd, int baudrate, int bits, int parity,
00194 int stopbits, int flowcontrol)
00195 {
00196 #ifdef _WIN32
00197 DCB dcb;
00198
00199 if (!GetCommState(hdl, &dcb)) {
00200
00201 return SR_ERR;
00202 }
00203
00204 switch (baudrate) {
00205
00206 case 115200:
00207 dcb.BaudRate = CBR_115200;
00208 break;
00209 case 57600:
00210 dcb.BaudRate = CBR_57600;
00211 break;
00212 case 38400:
00213 dcb.BaudRate = CBR_38400;
00214 break;
00215 case 19200:
00216 dcb.BaudRate = CBR_19200;
00217 break;
00218 case 9600:
00219 dcb.BaudRate = CBR_9600;
00220 break;
00221 default:
00222
00223 break;
00224 }
00225 dcb.ByteSize = bits;
00226 dcb.Parity = NOPARITY;
00227 dcb.StopBits = ONESTOPBIT;
00228
00229 if (!SetCommState(hdl, &dcb)) {
00230
00231 return SR_ERR;
00232 }
00233 #else
00234 struct termios term;
00235 speed_t baud;
00236
00237 switch (baudrate) {
00238 case 9600:
00239 baud = B9600;
00240 break;
00241 case 38400:
00242 baud = B38400;
00243 break;
00244 case 57600:
00245 baud = B57600;
00246 break;
00247 case 115200:
00248 baud = B115200;
00249 break;
00250 #ifndef __APPLE__
00251 case 460800:
00252 baud = B460800;
00253 break;
00254 #endif
00255 default:
00256 return SR_ERR;
00257 }
00258
00259 if (tcgetattr(fd, &term) < 0)
00260 return SR_ERR;
00261 if (cfsetispeed(&term, baud) < 0)
00262 return SR_ERR;
00263
00264 term.c_cflag &= ~CSIZE;
00265 switch (bits) {
00266 case 8:
00267 term.c_cflag |= CS8;
00268 break;
00269 case 7:
00270 term.c_cflag |= CS7;
00271 break;
00272 default:
00273 return SR_ERR;
00274 }
00275
00276 term.c_cflag &= ~CSTOPB;
00277 switch (stopbits) {
00278 case 1:
00279 break;
00280 case 2:
00281 term.c_cflag |= CSTOPB;
00282 default:
00283 return SR_ERR;
00284 }
00285
00286 term.c_cflag &= ~(IXON | IXOFF | CRTSCTS);
00287 switch (flowcontrol) {
00288 case 2:
00289 term.c_cflag |= IXON | IXOFF;
00290 break;
00291 case 1:
00292 term.c_cflag |= CRTSCTS;
00293 default:
00294 return SR_ERR;
00295 }
00296
00297 term.c_iflag &= ~IGNPAR;
00298 term.c_cflag &= ~(PARODD | PARENB);
00299 switch (parity) {
00300 case 0:
00301 term.c_iflag |= IGNPAR;
00302 break;
00303 case 1:
00304 term.c_cflag |= PARENB;
00305 break;
00306 case 2:
00307 term.c_cflag |= PARENB | PARODD;
00308 break;
00309 default:
00310 return SR_ERR;
00311 }
00312
00313 if (tcsetattr(fd, TCSADRAIN, &term) < 0)
00314 return SR_ERR;
00315 #endif
00316
00317 return SR_OK;
00318 }