Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

di194.c File Reference

Implementation of the DI-194 code, routines, etc. More...

#include "di194.h"
#include "di194-internal.h"

Go to the source code of this file.

Functions

int di_serial_close (const int COMM_FD)
 Simple wrapper to close the port.

int di_serial_init (const char *COMPORT_FILE)
 Open port and configure control lines, etc.

int min (const int A, const int B)
 Hardwired min fn.

void hex_print_byte (const uint8_t in_byte)
 Super-quick hack to hex-print a character, with ASCII if printable.

int di_stop (const int COMM_FD)
int di_start (const int COMM_FD)
int di_reset (const int COMM_FD)
int di_serial_num (const int COMM_FD, char *ser_buf)
int di_serial_read (const int COMM_FD, const uint8_t *buf, const int READ_LEN, const time_t TIMEOUT)
 Read with timeout from a file descriptor.

void di_cmd_print (const uint8_t *cmd, const int CMD_LEN)
 Debug routine to print a command to stderr.

bool is_reset_cmd (const uint8_t *cmd, const int CMD_LEN)
 Function to compare an input command to the reset command.

int di_daq_sync (const int COMM_FD)
 Function to re-sync with the incoming stream of samples.

int di_cmd_send (const int COMM_FD, const uint8_t *cmd, const int CMD_LEN)
 Send a command to the unit and get the reply.

int di_initialize (const int COMM_FD, int *num_bits)
 Function to init comms with a DI-194 once the port is setup.

int di_configure (const int COMM_FD)
 Program DI-194 for continuous DAQ.

char * di_byte_print (const uint8_t in_byte)
 Nasty hack to print a byte as bits.

int di_buf_validate (const daq_buf_t buf)
 Check that a buffer matches the expected structure.

int di_buf_decode (const daq_buf_t buf, daq_reading_t *result, const int NUM_BITS)
 Convert from raw data into float, raw and bit format.

int di_open (const char *COMPORT_FILE, int *num_bits)
 User-called routine to open the port, program DI194.

int di_close (const int COMM_FD)
 Shut down DI194.

int di_read (const int COMM_FD, daq_reading_t *data, const int NUM_BITS)
 User-called routine to read one data point. Or something like 1.

int di_read_single (const int COMM_FD, daq_reading_t *data, const int NUM_BITS)
 User-called routine to read one data point. Assumes unit stopped.


Variables

bool do_exit
 Global boolean set only by interrupt handler to indicate break.


Detailed Description

Implementation of the DI-194 code, routines, etc.

Simple code to read and program the Dataq DI-194, a $13 serial-port based DAQ card. It'll do 60Hz on its four analog input channels + 3 digital input bits.

This code started out as an undocumented file, here is the original attribution:

Author: Anthony Hanson and Mike Hage Date: April 1st, 2001

Many changes, cleanup and so forth on my part. I've basically rewritten the entire code, using the original to understand commands and parameters.

Author:
Paul Hubbard phubbard@computer.org
Date:
2/2002

Definition in file di194.c.


Function Documentation

int di_buf_decode const daq_buf_t    buf,
daq_reading_t   result,
const int    NUM_BITS
 

Convert from raw data into float, raw and bit format.

Function to decode a block of eight bytes encoded from a DATAQ DI-194 as explained in the app note, which should have been included with this file.

Expects 8-byte input buffer, zero terminated Data in 194 format (make some checks) Result buffer ready to fill

Returns Struct filled in, with bit set if OK, otherwise return non-zero

Notes Neither overly paranoid nor overly optimized.

Parameters:
buf  Buffer as read from the DI-194
result  Pointer to struct that we will fill with decoded data
NUM_BITS  8, 10 or 12, depending on hardware
Returns:
0 Success 1 Invalid buffer
Date:
3-3-02

Definition at line 841 of file di194.c.

References daq_reading_t::analog, daq_buf_t, di_buf_validate(), daq_reading_t::digital, hex_print_byte(), daq_reading_t::is_valid, and daq_reading_t::raw.

Referenced by di_read().

int di_buf_validate const daq_buf_t    buf
 

Check that a buffer matches the expected structure.

Function to check the first couple of bytes for the signature that should be there if they are a valid DI-194 reading. See the Dataq sheet for details; there are some bits hardwired to zero that we check for. Note that random data can easily confuse this into returning valid on bad data; this is _not_ robust.

Assumes Can check up the whole buffer Returns 0 if valid, nonzero if invalid

Parameters:
buf  Ptr to buffer that we are to check out
Returns:
0 Buffer is valid
Returns:
Non-zero Buffer is not valid, invalid LSB at index - 1 returned
Date:
3/13/01

Definition at line 793 of file di194.c.

References daq_buf_t.

Referenced by di_buf_decode(), and di_daq_sync().

char* di_byte_print const uint8_t    in_byte
 

Nasty hack to print a byte as bits.

Warning:
Uses a static buffer, so not threadsafe!
Parameters:
in_byte  Byte to print out
Returns:
char* != NULL Success; pointer to buffer to print
Returns:
NULL Error!
Date:
3/13/02

Definition at line 749 of file di194.c.

int di_close const int    COMM_FD
 

Shut down DI194.

Parameters:
COMM_FD  File descriptor of connected port
Returns:
0 Closed OK Non-zero An error occurred
Date:
4-12-02

Definition at line 1020 of file di194.c.

References di_serial_close().

Referenced by daq_loop(), main(), and user_loop().

void di_cmd_print const uint8_t *    cmd,
const int    CMD_LEN
 

Debug routine to print a command to stderr.

Parameters:
cmd  Pointer to the command to send
CMD_LEN  Length of command, in bytes

Definition at line 346 of file di194.c.

int di_cmd_send const int    COMM_FD,
const uint8_t *    cmd,
const int    CMD_LEN
 

Send a command to the unit and get the reply.

Function to send a command to the DI-194, and discard the echod response. The DI seems to echo the non-zero characters sent, but with some exceptions. Most annoying.

More exactly: it never echos the leading zero a rejected / unknown command echos 0xFF back arguments are echod verbatim unless the command is reset a reset command echos one extra byte back to the sender

All of this was determined experimentally and may therefore be wrong.

Parameters:
COMM_FD  File descriptor of the serial port
cmd  Pointer to command to send
CMD_LEN  Length of command, in bytes
Returns:
0 Success Non-zero An error occurred
Date:
3/2002

Definition at line 524 of file di194.c.

References di_serial_read(), and serial_timeout.

Referenced by di_configure(), di_initialize(), di_reset(), di_serial_num(), di_start(), and di_stop().

int di_configure const int    COMM_FD
 

Program DI-194 for continuous DAQ.

Note:
Currently hardwired for 240Hz on channel 1 + digital
If DI194_OLD_UNIT is defined, sends enable code from old source
Function to program the DI-194 for continuous sampling, for now it turns on all channels. This yields 60Hz, one can get to 240 by only sampling one channel. This is due to the 4800 baud transfer rate, and by the fact that the encryption table uses two bytes per analog sensor.

Assumes Port opened and init'd OK

Parameters:
COMM_FD  File descriptor of serial port
Returns:
0 Success- all programming seemed to work
Returns:
non-zero Error
Date:
3/6/02

Definition at line 699 of file di194.c.

References all_chan, di_cmd_send(), and dig_chan.

Referenced by di_open(), and user_loop().

int di_daq_sync const int    COMM_FD
 

Function to re-sync with the incoming stream of samples.

We may be off by up to seven bytes due to sync errors, so read two buffers' worth and look for the signature as spec'd in the DATAQ web page.

Kind of a hack until I grok more about the protocol.

Assumes DI-194 is streaming data to the given port

Parameters:
COMM_FD  File descriptor of the serial port
Returns:
0 Sync'd OK and next read should be valid Non-zero No sync, or other error occurred
Date:
3/13/02

Definition at line 439 of file di194.c.

References daq_buf_t, di_buf_validate(), di_serial_read(), and serial_timeout.

Referenced by daq_loop(), main(), and user_loop().

int di_initialize const int    COMM_FD,
int *    num_bits
 

Function to init comms with a DI-194 once the port is setup.

Does a reset, downloads the key, and requests the serial number from the unit - should make a good test.

Assumes Port open, 194 connected to same

Parameters:
COMM_FD  File descriptor of serial port
num_bits  Ptr to int that will hold the device precision
Returns:
0 Success Non-zero An error occurred
Date:
3/4/02

Definition at line 608 of file di194.c.

References di_cmd_send(), di_enable_key, di_serial_num(), di_stop(), key_cmd, odd_cmd, and SERIAL_NUM_LEN.

Referenced by di_open().

int di_open const char *    COMPORT_FILE,
int *    num_bits
 

User-called routine to open the port, program DI194.

Note:
Uses contents of "DI194_PORT" environment variable if set and COMPORT_FILE is null
Main. Open the port, init the card, do some daq.

To do: -p port parsing, will need for USB serial. getopt!

Parameters:
COMPORT_FILE  Path to device
num_bits  Ptr to storage location for device precision
Returns:
>0 All is good, return value is file descriptor <= 0 All is not good, no guarantees

Definition at line 946 of file di194.c.

References di_configure(), di_initialize(), and di_serial_init().

Referenced by daq_loop(), and main().

int di_read const int    COMM_FD,
daq_reading_t   data,
const int    NUM_BITS
 

User-called routine to read one data point. Or something like 1.

Warning:
Will block until data available
Assumes adequate buffering; does not re-sync
Date:
4-12-02
Parameters:
COMM_FD  File descriptor of ready port
data  Ptr to struct for returned data
NUM_BITS  8 or 10, depending on hardware
Returns:
0 Data is OK and read Non-zero An error occurred

Definition at line 1054 of file di194.c.

References daq_buf_t, di_buf_decode(), di_serial_read(), and serial_timeout.

Referenced by daq_loop(), di_read_single(), main(), and user_loop().

int di_read_single const int    COMM_FD,
daq_reading_t   data,
const int    NUM_BITS
 

User-called routine to read one data point. Assumes unit stopped.

Warning:
Will block until data available
Assumes adequate buffering; does not re-sync
Date:
5-19-02
Parameters:
COMM_FD  File descriptor of ready port
data  Ptr to struct for returned data
NUM_BITS  8 or 10, depending on hardware
Returns:
0 Data is OK and read Non-zero An error occurred

Definition at line 1111 of file di194.c.

References di_read(), di_start(), and di_stop().

Referenced by user_loop().

int di_reset const int    COMM_FD
 

Definition at line 227 of file di194.c.

References di_cmd_send(), and rst_cmd.

Referenced by user_loop().

int di_serial_close const int    COMM_FD
 

Simple wrapper to close the port.

... which releases the control lines and shuts down the DAQ.

Parameters:
COMM_FD  File descriptor of the opened serial port to be closed
Return values:
0  Completed OK
Non-zero  An error occurred
Date:
3/11/02
Note:
minor changes from original

Definition at line 50 of file di194.c.

Referenced by di_close().

int di_serial_init const char *    COMPORT_FILE
 

Open port and configure control lines, etc.

Function to open the serial port and set up the rather peculiar comms requirements of the DI-194: 4800 baud, N81 No flow control (?) Controlled by DTR?

Parameters:
COMPORT_FILE  Pointer to filename to open, not modified
Returns:
0 Operation successful Non-zero An error occurred
Date:
3/11/02
Note:
cleaning up original code, no substantial changes

Definition at line 82 of file di194.c.

References serial_timeout.

Referenced by di_open().

int di_serial_num const int    COMM_FD,
char *    ser_buf
 

Definition at line 232 of file di194.c.

References di_cmd_send(), di_serial_read(), SERIAL_NUM_LEN, serial_timeout, and sn_cmd.

Referenced by di_initialize(), and user_loop().

int di_serial_read const int    COMM_FD,
const uint8_t *    buf,
const int    READ_LEN,
const time_t    TIMEOUT
 

Read with timeout from a file descriptor.

Parameters:
COMM_FD  File descriptor of serial port in use
buf  Buffer to write data into
READ_LEN  Number of bytes to be read
TIMEOUT  Max wait, in seconds
Returns:
0 Success Non-zero An error occurred
Warning:
Not foolproof! Does not use select
Note:
Coarse granularity - integer seconds

Definition at line 288 of file di194.c.

Referenced by di_cmd_send(), di_daq_sync(), di_read(), and di_serial_num().

int di_start const int    COMM_FD
 

Definition at line 222 of file di194.c.

References di_cmd_send(), and start_cmd.

Referenced by daq_loop(), di_read_single(), main(), and user_loop().

int di_stop const int    COMM_FD
 

Definition at line 216 of file di194.c.

References di_cmd_send(), and stop_cmd.

Referenced by di_initialize(), di_read_single(), and user_loop().

void hex_print_byte const uint8_t    in_byte
 

Super-quick hack to hex-print a character, with ASCII if printable.

Note:
Strictly a debug aid.
Parameters:
in_byte  Character to be printed
Returns:
void

Definition at line 209 of file di194.c.

Referenced by di_buf_decode().

bool is_reset_cmd const uint8_t *    cmd,
const int    CMD_LEN
 

Function to compare an input command to the reset command.

Just an inline cleanup

Assumes CMD and len match

Returns true if matches rst_cmd, false otherwise or if NULL

Parameters:
cmd  Pointer to command in question
CMD_LEN  Length of command in question
Returns:
true cmd is a reset request false Not a reset request, or an error occurred
Date:
3/11/02

Definition at line 397 of file di194.c.

References rst_cmd.

int min const int    A,
const int    B
 

Hardwired min fn.

Here and I thought min(int, int) was part of C9X now. Hmm.

Parameters:
A  First value to be compared
B  Second value to be compared
Returns:
A A is <= B B B is <= A

Definition at line 193 of file di194.c.


Variable Documentation

bool do_exit
 

Global boolean set only by interrupt handler to indicate break.

Definition at line 30 of file di194.c.


Generated on Tue Feb 3 16:47:26 2004 for DI-194 driver by doxygen1.2.18