25 int zb_encode(uint8_t *destination, uint8_t device_number,
26 uint8_t command_number, int32_t data)
29 uint32_t udata = (uint32_t)data;
31 if (destination == NULL)
36 destination[0] = device_number;
37 destination[1] = command_number;
39 for (i = 2; i < 6; i++)
41 destination[i] = (uint8_t)udata;
48 int zb_decode(int32_t *destination,
const uint8_t *reply)
53 if (destination == NULL)
58 for (i = 5; i > 1; i--)
64 if ((data & 0x80000000UL) == 0)
66 *destination = (int32_t)data;
70 *destination = -(int32_t)(UINT32_MAX - data) - 1;
81 #define PRINT_ERROR(M)
82 #define PRINT_SYSCALL_ERROR(M)
84 #define PRINT_ERROR(M) do { if (zb_verbose) { fprintf(stderr, "(%s: %d)" M\
85 "\n", __FILE__, __LINE__); } } while(0)
86 #define PRINT_SYSCALL_ERROR(M) do { if (zb_verbose) { fprintf(stderr,\
87 "(%s: %d) [ERROR] " M " failed with error code %d.\n",\
88 __FILE__, __LINE__, GetLastError()); } } while(0)
90 #define SYSCALL(F) do { if ((F) == 0) {\
91 PRINT_SYSCALL_ERROR(#F); return Z_ERROR_SYSTEM_ERROR; } } while (0)
93 int zb_connect(z_port *port,
const char *port_name)
96 COMMTIMEOUTS timeouts;
98 if (port_name == NULL)
104 *port = CreateFileA(port_name,
105 GENERIC_READ | GENERIC_WRITE,
111 if (*port == INVALID_HANDLE_VALUE)
117 SYSCALL(GetCommState(*port, &dcb));
118 dcb.DCBlength =
sizeof(DCB);
122 dcb.fOutxCtsFlow = FALSE;
123 dcb.fOutxDsrFlow = FALSE;
124 dcb.fDtrControl = DTR_CONTROL_DISABLE;
125 dcb.fDsrSensitivity = FALSE;
126 dcb.fTXContinueOnXoff = TRUE;
129 dcb.fErrorChar = FALSE;
131 dcb.fRtsControl = RTS_CONTROL_DISABLE;
132 dcb.fAbortOnError = FALSE;
137 dcb.Parity = NOPARITY;
138 dcb.StopBits = ONESTOPBIT;
139 SYSCALL(SetCommState(*port, &dcb));
141 timeouts.ReadIntervalTimeout = MAXDWORD;
142 timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
144 timeouts.WriteTotalTimeoutMultiplier = 0;
145 timeouts.WriteTotalTimeoutConstant = 100;
146 SYSCALL(SetCommTimeouts(*port, &timeouts));
157 int zb_send(z_port port,
const uint8_t *command)
167 SYSCALL(WriteFile(port, command, 6, &nbytes, NULL));
180 int zb_receive(z_port port, uint8_t *destination)
186 for (i = 0; i < 6; i++)
188 SYSCALL(ReadFile(port, &c, 1, &nread, NULL));
196 if (destination != NULL) destination[i] = c;
212 COMMTIMEOUTS timeouts;
214 SYSCALL(PurgeComm(port, PURGE_RXCLEAR));
215 SYSCALL(GetCommTimeouts(port, &timeouts));
216 old_timeout = timeouts.ReadTotalTimeoutConstant;
217 timeouts.ReadTotalTimeoutConstant = 100;
218 SYSCALL(SetCommTimeouts(port, &timeouts));
222 SYSCALL(ReadFile(port, &c, 1, &nread, NULL));
226 timeouts.ReadTotalTimeoutConstant = old_timeout;
227 SYSCALL(SetCommTimeouts(port, &timeouts));
234 COMMTIMEOUTS timeouts;
236 SYSCALL(GetCommTimeouts(port, &timeouts));
237 timeouts.ReadTotalTimeoutConstant = milliseconds;
238 SYSCALL(SetCommTimeouts(port, &timeouts));
243 #elif defined(__unix__) || defined(__APPLE__)
245 #include <sys/types.h>
246 #include <sys/stat.h>
257 #define PRINT_ERROR(M)
258 #define PRINT_SYSCALL_ERROR(M)
261 #define PRINT_ERROR(M) do { if (zb_verbose) { fprintf(stderr, "(%s: %d)" M\
262 "\n", __FILE__, __LINE__); } } while(0)
263 #define PRINT_SYSCALL_ERROR(M) do { if (zb_verbose) {\
264 fprintf(stderr, "(%s: %d) [ERROR] " M " failed: %s.\n",\
265 __FILE__, __LINE__, strerror(errno)); } } while(0)
273 #define SYSCALL(F) do { if ((F) < 0) { PRINT_SYSCALL_ERROR(#F);\
274 return Z_ERROR_SYSTEM_ERROR; } } while(0)
276 int zb_connect(z_port *port,
const char *port_name)
278 struct termios tio, orig_tio;
280 if (port == NULL || port_name == NULL)
282 PRINT_ERROR(
"[ERROR] port and port_name cannot be NULL.");
287 SYSCALL(*port = open(port_name, O_RDWR | O_NOCTTY));
288 SYSCALL(tcgetattr(*port, &orig_tio));
289 memcpy(&tio, &orig_tio,
sizeof(
struct termios));
292 tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR
293 | IGNCR | ICRNL | IXON);
294 tio.c_oflag &= ~OPOST;
295 tio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
296 tio.c_cflag &= ~(CSIZE | PARENB);
298 tio.c_cflag = CS8|CREAD|CLOCAL;
311 SYSCALL(cfsetospeed(&tio, B9600) & cfsetispeed(&tio, B9600));
313 while(memcmp(&orig_tio, &tio,
sizeof(
struct termios)) != 0)
315 SYSCALL(tcsetattr(*port, TCSAFLUSH, &tio));
316 SYSCALL(tcgetattr(*port, &orig_tio));
328 int zb_send(z_port port,
const uint8_t *command)
332 SYSCALL(nbytes = write(port, command, 6));
353 int zb_receive(z_port port, uint8_t *destination)
359 for (i = 0; i < 6; i++)
361 SYSCALL(nread = (
int) read(port, &c, 1));
369 if (destination != NULL) destination[i] = c;
387 SYSCALL(tcgetattr(port, &tio));
388 old_timeout = tio.c_cc[VTIME];
390 SYSCALL(tcsetattr(port, TCSANOW, &tio));
393 SYSCALL(tcflush(port, TCIFLUSH));
394 while(read(port, &c, 1) > 0);
397 tio.c_cc[VTIME] = old_timeout;
398 SYSCALL(tcsetattr(port, TCSANOW, &tio));
408 if (milliseconds % 100 != 0)
410 new_time = milliseconds / 100 + 1;
414 new_time = milliseconds / 100;
417 SYSCALL(tcgetattr(port, &tio));
418 tio.c_cc[VTIME] = new_time;
419 SYSCALL(tcsetattr(port, TCSANOW, &tio));
421 return new_time * 100;
GeneratorWrapper< T > value(T &&value)
#define PRINT_SYSCALL_ERROR(M)
int zb_decode(int32_t *destination, const uint8_t *reply)
int zb_encode(uint8_t *destination, uint8_t device_number, uint8_t command_number, int32_t data)
void zb_set_verbose(int value)
Provides a set of functions for interacting with Zaber devices in the binary protocol.
int zb_disconnect(z_port port)
int zb_send(z_port port, const uint8_t *command)
int zb_receive(z_port port, uint8_t *destination)
int zb_drain(z_port port)
int zb_set_timeout(z_port port, int milliseconds)
int zb_connect(z_port *port, const char *port_name)