On Nov 29, 2005, at 8:39 AM, Bruins, Stefan wrote: One thing I did not made clear in the previous email: the idea is that the device has to respond to the message.
Ahhh... O.K. a custom conversion routine is not adequate in this case.
My first idea was to use the GBIBREAD operation for that, but this type has only got a conversion routine for the reply. I had taken a look to the GPIBCVTIO type, but this is not a query->response construction.
Yes it is. GPIBCVTIO is completely general-purpose. Nick DiMonte's Tektronix oscilloscope support uses GPIBCVTIO. I've included some sections of his code.
Here's an example of a GPIBCVTIO routine which sends commands and gets replies. /* 180 : read ethernet name SI */ {&DSET_SI, GPIBCVTIO, IB_Q_HIGH, NULL, NULL, 0, 100, getEthernetName, 0, 0, NULL, NULL, NULL},
static int getEthernetName(struct gpibDpvt *pdpvt, int P1, int P2, char **P3) { struct stringinRecord *psi= (struct stringinRecord *) (pdpvt->precord);
asynOctet *pasynOctet = pdpvt->pasynOctet; void *asynOctetPvt = pdpvt->asynOctetPvt; int j; size_t ntrans; char cbuf[300]; char make[12], model[12]; char netName[40];
if ((pasynOctet->write(asynOctetPvt,pdpvt->pasynUser,"*IDN?", sizeof"*IDN?" - 1,&ntrans) != asynSuccess) || (pasynOctet->read(asynOctetPvt,pdpvt->pasynUser,cbuf, sizeof cbuf - 1,&ntrans,NULL) != asynSuccess)) { recGblSetSevr(psi, READ_ALARM, INVALID_ALARM); return -1; } cbuf[ntrans] = '\0'; /* Null-terminate reply message */ /* do the checks in cbuf and optionally send the "ETHERNET:NAME?" using the write/read commands like above */
if (( j = sscanf(cbuf, "%11[^,],%11[^,]", make, model)) != 2){ printf("Scope ERROR: Scope ID scanned %d, min 2 needed. ID string = \n %s \n" , j, cbuf); return -1; }
if(TDS3000Debug) { printf("cbuf = %s\n",cbuf); printf("make = %s\n",make); printf("model = %s\n",model); printf("model[8] = %c\n",model[8]); }
if ( model[8] == 'B' || strstr(cbuf,"TDS3EM") != NULL ){ /* has ethernet option */ if ((pasynOctet->write(asynOctetPvt,pdpvt->pasynUser,"ETHER:NAME?", sizeof"ETHER:NAME?" - 1,&ntrans) != asynSuccess) || (pasynOctet->read(asynOctetPvt,pdpvt->pasynUser,cbuf, sizeof cbuf - 1,&ntrans,NULL) != asynSuccess)) { recGblSetSevr(psi, READ_ALARM, INVALID_ALARM); return -1; } cbuf[ntrans] = '\0'; /* Null-terminate reply message */ sscanf(cbuf, "%39[^\n\r]",netName); } else { sscanf(cbuf, "%18[^\n\r]",netName); } strcpy(psi->val,netName);
return 0; }
Here's an example that handles binary data. The readArbitraryBlockProgramData routine is part of the ASYN package. Have a look at it to see how arbitraty 8-bit data can be transferred. /* 19 : read waveform : WF */ {&DSET_WF, GPIBCVTIO, IB_Q_LOW, "DAT:SOU CH1;:WAVFRM?", "%lf", 0, 32000, convertData, 0 ,0, NULL, NULL, NULL},
static int convertData(pdpvt, P1, P2, P3) struct gpibDpvt *pdpvt; int P1; int P2; char **P3; { double xIncr, xZero, yMult, yZero, yOff; int byte, bits, length, ptOff, width; char encode[20], binFmt[20], byteOr[20], idString[80], ptFmt[20], xUnit[20], yUnit[20]; int len, i; size_t ntrans; struct waveformRecord *pwf= (struct waveformRecord *) (pdpvt->precord); gpibCmd *pgpibCmd = gpibCmdGet(pdpvt); asynOctet *pasynOctet = pdpvt->pasynOctet; void *asynOctetPvt = pdpvt->asynOctetPvt;
if ((pasynOctet->write(asynOctetPvt,pdpvt->pasynUser,pgpibCmd->cmd, strlen(pgpibCmd->cmd),&ntrans) != asynSuccess) || (pdevSupportGpib->readArbitraryBlockProgramData(pdpvt) <= 0)) { recGblSetSevr(pwf, READ_ALARM, INVALID_ALARM); return -1; }
if (sscanf(pdpvt->msg, "%d;%d;%19[^;];%19[^;];%19[^;];%d;%79[^;];%19[^;];" "%lg;%d;%lg;%19[^;];%lg;%lg;%lg;%19[^;];#%1d%n", &byte, &bits, encode, binFmt, byteOr, &length, idString, ptFmt, &xIncr, &ptOff, &xZero, xUnit, &yMult, &yZero, &yOff, yUnit, &width, &i ) != 17) { recGblSetSevr(pwf, READ_ALARM, INVALID_ALARM); return -1; } if(TDS3000Debug) { printf("%p, index=%d\n", (unsigned char *)&pdpvt->msg[0],i); printf("byte- %d, bits- %d, encode- %s, binFmt- %s, byteOr- %s\n", byte, bits, encode, binFmt, byteOr); printf("length- %d, ptFmt- %s\n", length, ptFmt); printf("xIncr- %g\nptOff- %d\nxZero- %g\nyMult- %g\nyZero- %g\nyOff- %g\n" , xIncr, ptOff, xZero, yMult, yZero, yOff); } i += width; /* I should be pointing to the first data byte now */
/* Copy waveform data from response buffer to waveform record */ if(P1) { printf("%p, index=%d\n", (void *)&pdpvt->msg[0], i); printf("ptFmt - %s, length - %d\n", ptFmt, length); len = P1; /* if P1 is non-zero, use it as length */ } else { len = length; } memcpy((char *)pwf->bptr, (char *)&pdpvt->msg[i], len*byte); pwf->nord=len; return(0); }
-- Eric Norum <[email protected]> Advanced Photon Source Argonne National Laboratory (630) 252-4793
|