Files
motorBase/motorApp/CommSrc/gpibIO.c
T
2000-07-17 16:17:08 +00:00

166 lines
5.3 KiB
C

/* gpibIO.c - Routines for asynchronous EPICS GPIB I/O
*
* Author: Mark Rivers
* Date: October 30, 1997
*
* Modification Log:
* -----------------
* .01 30-Oct-1997 mlr Initial release
*
* These routines provide a simple interface to GPIB I/O. They hide the
* details of the driver. They are intended for use by applications which do
* simple synchronous reads and writes, and no control operations like Serial
* Poll.
*/
#include <stdlib.h>
#include <stdio.h>
#include <vxWorks.h>
#include <gpibIO.h>
#ifdef GPIB
#include <semLib.h>
#include <drvGpibInterface.h>
#endif
#define GPIB_SEND 0
#define GPIB_RECEIVE 1
#ifdef NODEBUG
#define Debug(l,f,v) ;
#else
#define Debug(l,f,v) { if(l<=gpibIODebug) printf(f,v); }
#endif
volatile int gpibIODebug = 0;
#ifdef GPIB
extern struct drvGpibEt drvGpib; /* entry points to driver functions */
#else
extern struct drvGpibSet drvGpib; /* entry points to driver functions */
#endif
struct gpibMessage {
struct dpvtGpibHead head;
int function;
int address;
int timeout;
int status;
int buff_len;
int terminator;
SEM_ID semID;
char *buffer;
};
static int gpibIOCallback(struct gpibMessage *gpibMessage);
struct gpibInfo *gpibIOInit(int link, int address)
{
struct gpibInfo *gpibInfo;
gpibInfo = (struct gpibInfo *) malloc(sizeof(struct gpibInfo));
gpibInfo->head.workStart = (int (*)()) gpibIOCallback;
gpibInfo->head.link = link;
gpibInfo->head.device = address;
gpibInfo->address = address;
gpibInfo->semID = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
#ifdef GPIB
gpibInfo->head.pibLink = (*(drvGpib.getLink))(link, address);
#else
(*(drvGpib.ioctl))(GPIB_IO, link, NULL, IBGENLINK, 0, NULL);
(*(drvGpib.ioctl))(GPIB_IO, link, NULL, IBGETLINK, 0, &gpibInfo->head.pibLink);
#endif
Debug(1, "gpibIOInit, address = %d\n", address);
return(gpibInfo);
}
int gpibIOSend(struct gpibInfo *info, char const *buffer, int buff_len, int timeout)
{
struct gpibMessage *gpibMessage;
int status;
gpibMessage = (struct gpibMessage *) malloc(sizeof(struct gpibMessage));
gpibMessage->address = info->address;
gpibMessage->buffer = (char *) buffer;
gpibMessage->buff_len = buff_len;
gpibMessage->timeout = timeout;
gpibMessage->function = GPIB_SEND;
gpibMessage->head = info->head;
gpibMessage->semID = info->semID;
Debug(2, "gpibIOSend, calling driver, buffer = %s\n", buffer);
(*(drvGpib.qGpibReq))(gpibMessage, IB_Q_LOW);
semTake(gpibMessage->semID, WAIT_FOREVER);
status = gpibMessage->status;
free(gpibMessage);
return (status);
}
int gpibIORecv(struct gpibInfo *info, char *buffer, int buff_len,
int terminator, int timeout)
{
struct gpibMessage *gpibMessage;
int status;
gpibMessage = (struct gpibMessage *) malloc(sizeof(struct gpibMessage));
gpibMessage->address = info->address;
gpibMessage->buffer = buffer;
gpibMessage->buff_len = buff_len;
gpibMessage->terminator = terminator;
gpibMessage->timeout = timeout;
gpibMessage->function = GPIB_RECEIVE;
gpibMessage->head = info->head;
gpibMessage->semID = info->semID;
Debug(2, "gpibIORecv, calling driver, address = %d\n", info->address);
(*(drvGpib.qGpibReq))(gpibMessage, IB_Q_LOW);
semTake(gpibMessage->semID, WAIT_FOREVER);
status = gpibMessage->status;
free(gpibMessage);
return (status);
}
static int gpibIOCallback(struct gpibMessage *gpibMessage)
{
int timeout;
int nrequest, nactual;
timeout = gpibMessage->timeout * sysClkRateGet() / 1000;
if (timeout < 1) timeout = 1;
switch(gpibMessage->function)
{
case GPIB_SEND:
Debug(2, "gpibIOCallback, GPIB_SEND, message=%s\n",
gpibMessage->buffer);
/* write the message to the GPIB listen address */
nrequest = gpibMessage->buff_len;
nactual =(*(drvGpib.writeIb))(gpibMessage->head.pibLink,
gpibMessage->address, gpibMessage->buffer,
nrequest, timeout);
if (nactual != nrequest) {
/* Something is wrong if we couldn't write everything */
Debug(1, "Error writing GPIB, requested length=%d\n", nrequest);
Debug(1, " actual length=%d\n", nactual);
}
gpibMessage->status = nactual;
semGive(gpibMessage->semID); /* gpibIOSend is waiting for this */
break;
case GPIB_RECEIVE:
/* Read a message from the GPIB listen address */
nrequest = gpibMessage->buff_len;
nactual = (*(drvGpib.readIbEos))(gpibMessage->head.pibLink,
gpibMessage->address, gpibMessage->buffer,
nrequest, timeout, gpibMessage->terminator);
/* Append a null terminator if there is room */
if (nactual < nrequest) gpibMessage->buffer[nactual]='\0';
Debug(2, "gpibIOCallback, GPIB_RECEIVE, message=%s\n",
gpibMessage->buffer);
Debug(2, "gpibIOCallback, GPIB_RECEIVE, nrequest=%d\n", nrequest);
Debug(2, "gpibIOCallback, GPIB_RECEIVE, nactual=%d\n", nactual);
gpibMessage->status = nactual;
semGive(gpibMessage->semID); /* gpibIORecv is waiting for this */
break;
}
return (0);
}