API
za_serial.c File Reference
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "za_serial.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
Include dependency graph for za_serial.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PRINT_ERROR(M)
 
#define PRINTF_ERROR(M, ...)
 
#define PRINT_SYSCALL_ERROR(M)
 
#define SYSCALL(F)
 

Functions

void za_set_verbose (int value)
 
int za_connect (z_port *port, const char *port_name)
 
int za_disconnect (z_port port)
 
int za_send (z_port port, const char *command, size_t sMaxSz)
 
int za_receive (z_port port, char *destination, int length)
 
int za_setbaud (z_port port, int baud)
 
int za_drain (z_port port)
 
static size_t copy_until_delim (char *destination, const char *source, const char delim, size_t destination_length)
 
static int decode_reply (struct za_reply *destination, const char *reply, size_t sMaxSz)
 
static int decode_alert (struct za_reply *destination, const char *reply, size_t sMaxSz)
 
static int decode_info (struct za_reply *destination, const char *reply, size_t sMaxSz)
 
int za_decode (struct za_reply *destination, const char *reply, size_t sMaxSz)
 

Variables

static int za_verbose = 1
 

Macro Definition Documentation

◆ PRINT_ERROR

#define PRINT_ERROR (   M)
Value:
do { if (za_verbose) { fprintf(stderr, "(%s: %d) " M\
"\n", __FILE__, __LINE__); } } while(0)
static int za_verbose
Definition: za_serial.c:16

Definition at line 35 of file za_serial.c.

◆ PRINT_SYSCALL_ERROR

#define PRINT_SYSCALL_ERROR (   M)
Value:
do { if (za_verbose) {\
fprintf(stderr, "(%s: %d) [ERROR] " M " failed: %s.\n",\
__FILE__, __LINE__, strerror(errno)); } } while(0)

Definition at line 40 of file za_serial.c.

◆ PRINTF_ERROR

#define PRINTF_ERROR (   M,
  ... 
)
Value:
do { if (za_verbose) { fprintf(stderr,\
"(%s: %d) " M "\n", __FILE__, __LINE__, __VA_ARGS__); } } while(0)

Definition at line 37 of file za_serial.c.

◆ SYSCALL

#define SYSCALL (   F)
Value:
do { if ((F) < 0) { PRINT_SYSCALL_ERROR(#F);\
return Z_ERROR_SYSTEM_ERROR; } } while(0)
@ Z_ERROR_SYSTEM_ERROR
Definition: z_common.h:67
#define PRINT_SYSCALL_ERROR(M)
Definition: za_serial.c:40

Definition at line 50 of file za_serial.c.

Function Documentation

◆ copy_until_delim()

static size_t copy_until_delim ( char *  destination,
const char *  source,
const char  delim,
size_t  destination_length 
)
static

Definition at line 263 of file za_serial.c.

Referenced by decode_alert(), decode_info(), and decode_reply().

◆ decode_alert()

static int decode_alert ( struct za_reply destination,
const char *  reply,
size_t  sMaxSz 
)
static

Definition at line 386 of file za_serial.c.

Referenced by za_decode().

◆ decode_info()

static int decode_info ( struct za_reply destination,
const char *  reply,
size_t  sMaxSz 
)
static

Definition at line 465 of file za_serial.c.

Referenced by za_decode().

◆ decode_reply()

static int decode_reply ( struct za_reply destination,
const char *  reply,
size_t  sMaxSz 
)
static

Definition at line 279 of file za_serial.c.

Referenced by za_decode().

◆ za_connect()

int za_connect ( z_port *  port,
const char *  port_name 
)

Connect to a serial port specified by port_name.

Configures the port to the ASCII protocol defaults (115200 baud, 8N1). If you have set your device to run at a different baud rate, use za_setbaud() to change it after connecting using this function.

On Linux the port name will likely be something like "/dev/ttyUSB0", on Windows "COM1", and on OS X and BSD systems "/dev/cu.usbserial-A4017CQX". It is important that OS X/BSD systems use the "callout" (cu.* or cua.*) port as opposed to the "dial in" ports with names starting with tty.*, which will not work with Zaber devices.

If you are re-using a z_port, make sure to use za_disconnect() to disconnect the old port before overwriting it with a new one.

Parameters
[out]porta pointer to a z_port to be written-over with the newly-connected port.
[in]port_namea string containing the name of the port to be opened.
Returns
Z_SUCCESS on success, Z_ERROR_NULL_PARAMETER if port or port_name is NULL, or Z_ERROR_SYSTEM_ERROR in case of system error.

Definition at line 53 of file za_serial.c.

Referenced by MagAOX::app::zaberLowLevel::connect(), and main().

◆ za_decode()

int za_decode ( struct za_reply destination,
const char *  reply,
size_t  sMaxSz 
)

Build a za_reply struct from a string pointed-to by reply.

The za_reply struct can then be used to gain easier access to the parts of an ASCII reply.

Parameters
[out]destinationa pointer to a za_reply struct to be populated with the data found in reply.
[in]replya pointer to a string containing a full reply from a Zaber device, as specified by the ASCII protocol manual.
Returns
Z_SUCCESS on success, Z_ERROR_NULL_PARAMETER if destination or reply is NULL, or Z_ERROR_COULD_NOT_DECODE if the reply is malformed.

Definition at line 539 of file za_serial.c.

Referenced by MagAOX::app::zaberStage< parentT >::getResponse(), poll_until_idle(), and MagAOX::app::zaberStage< parentT >::sendCommand().

◆ za_disconnect()

int za_disconnect ( z_port  port)

Gracefully closes a connection.

Parameters
[in]portthe port to be disconnected.
Returns
Z_SUCCESS on success, Z_ERROR_SYSTEM_ERROR in case of system error.

Definition at line 99 of file za_serial.c.

Referenced by MagAOX::app::zaberLowLevel::connect(), main(), and MagAOX::app::zaberLowLevel::onPowerOff().

◆ za_drain()

int za_drain ( z_port  port)

Flushes all input received but not yet read, and attempts to drain all input that would be incoming.

This function is intended to be used when many commands have been sent without reading any responses, and there is a need to read a response from a certain command. In other words, call this function before sending a command whose response you would like to read if you have not been consistently reading the responses to previous commands.

This function will always take at least 100ms to complete, as it tries to read input until it is certain no more is arriving by waiting 100ms before deciding there is no more input incoming. Do not use it for time-sensitive operations, or in any kind of "chatty" setup, eg. multiple devices daisy-chained together with move tracking enabled. In such a setup, the only reliable way to retrieve reply data is to always follow calls to za_send() with calls to za_receive().

Parameters
[in]portthe port to drain.
Returns
Z_SUCCESS on success, or Z_ERROR_SYSTEM_ERROR in case of system error.

Definition at line 235 of file za_serial.c.

Referenced by MagAOX::app::zaberLowLevel::connect().

◆ za_receive()

int za_receive ( z_port  port,
char *  destination,
int  length 
)

Reads a message from the serial port.

Blocks while reading until it encounters a newline character or its timeout has elapsed.

Note: It is recommended that your destination buffer be 256B long. This is long enough to hold any reply from a Zaber device using the ASCII protocol.

Note that this function will simply read the first message on the input buffer, whatever it may be. If you have sent many commands without receiving their corresponding replies, sorting them all out may be a real headache. Note also that the input buffer is finite, and allowing it to fill up will result in undefined behaviour. Try to receive responses to every command you send, or use za_drain() when necessary.

Passing NULL for destination and 0 for length will read a single reply, discarding it as it is read. This is useful for keeping your commands and replies straight without using zb_drain() when you don't care about the contents of most of the replies.

Parameters
[in]portthe port to receive a message from.
[out]destinationa pointer to which to write the reply read.
[in]lengththe length of the buffer pointed to by destination.
Returns
the number of bytes read, Z_ERROR_SYSTEM_ERROR in case of system error, or Z_ERROR_BUFFER_TOO_SMALL if length is insufficient to store the reply.

Definition at line 151 of file za_serial.c.

Referenced by MagAOX::app::zaberLowLevel::connect(), main(), poll_until_idle(), and MagAOX::app::zaberStage< parentT >::sendCommand().

◆ za_send()

int za_send ( z_port  port,
const char *  command,
size_t  sMaxSz 
)

Sends a command to a serial port.

Automatically adds a '/' to begin the command and a '\n' to end it if these characters are omitted from command.

Parameters
[in]portthe port to which to send the command.
[in]commanda string containing the command to be sent.
Returns
the number of bytes written, Z_ERROR_NULL_PARAMETER if command is NULL, or Z_ERROR_SYSTEM_ERROR in case of system error.

Definition at line 112 of file za_serial.c.

Referenced by MagAOX::app::zaberLowLevel::connect(), main(), poll_until_idle(), and MagAOX::app::zaberStage< parentT >::sendCommand().

◆ za_set_verbose()

void za_set_verbose ( int  value)

Sets whether errors and extra info are reported to stderr.

Set value to 0 to disable all output. Additionally, you can compile this library with the macro NDEBUG defined, which will disable all output and skip checks to "verbose" altogether in the compiled code.

Parameters
[in]valuewhether or not the program should output error messages and info to stderr.

Definition at line 18 of file za_serial.c.

◆ za_setbaud()

int za_setbaud ( z_port  port,
int  baud 
)

Changes the baud rate of both input and output.

This function is unlikely to be necessary for typical use, as za_connect() already sets the baud rate to 115200, the recommended rate for the ASCII protocol.

Note: za_setbaud() flushes both input and output buffers to ensure a "clean slate" after the baud rate has been changed.

Also note that this sets the baud rate at which the program tries to talk to the device. It does not change the baud rate of the device itself. See the ASCII Protocol Manual for info on how to change the device's baud rate.

Valid baid rates are 9600, 19200, 38400, 57600, and 115200.

Parameters
[in]portthe port to change.
[in]baudthe new desired baud rate.
Returns
Z_SUCCESS on success, Z_ERROR_INVALID_BAUDRATE if the baud rate is not one specified above, or Z_ERROR_SYSTEM_ERROR in case of system error.

Definition at line 200 of file za_serial.c.

Variable Documentation

◆ za_verbose

int za_verbose = 1
static

Definition at line 16 of file za_serial.c.

Referenced by za_set_verbose().