added longer timeout in niGpibCmd() and fixed list traversal bug in the link task
This commit is contained in:
+42
-16
@@ -37,6 +37,8 @@
|
||||
* .02 12-03-91 jrw changed the setup of the ibLink and niLink structs
|
||||
* .03 01-21-92 jrw moved task parameters into task_params.h
|
||||
* .04 01-31-92 jrw added ibSrqLock code
|
||||
* .05 02-26-92 jrw changed pnode references in the link task's
|
||||
* busy-list checking, was an endless loop
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
@@ -60,7 +62,6 @@
|
||||
#define NIGPIB_IVEC_BASE 100 /* Vectored interrupts (2 used for each link) */
|
||||
#define NIGPIB_IRQ_LEVEL 5 /* IRQ level */
|
||||
/**************** end of stuff that does not belong here **********************/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <types.h>
|
||||
@@ -111,6 +112,8 @@ int ibSrqDebug = 0; /* Turns on ONLY srq related debug messages */
|
||||
int niIrqOneShot = 0; /* Used for a one shot peek at the DMAC */
|
||||
int ibSrqLock = 0; /* set to 1 to stop ALL srq checking & polling */
|
||||
|
||||
#define STD_ADDRESS_MODE D_SUP|D_S24 /* mode to use when DMAC accesses RAM */
|
||||
|
||||
static int defaultTimeout = 60; /* in 60ths, for GPIB timeouts */
|
||||
|
||||
static char init_called = 0; /* To insure that init is done first */
|
||||
@@ -184,6 +187,9 @@ struct niLink {
|
||||
char r_isr1;
|
||||
char r_isr2;
|
||||
int first_read;
|
||||
|
||||
unsigned long cmdSpins; /* total taskDelays while in niGpibCmd() */
|
||||
unsigned long maxSpins; /* most taskDelays in one call to niGpibCmd() */
|
||||
};
|
||||
|
||||
static struct niLink *pNiLink[NIGPIB_NUM_LINKS]; /* NULL if link not present */
|
||||
@@ -231,6 +237,8 @@ reportGpib()
|
||||
if (pNiLink[i])
|
||||
{
|
||||
printf("Link %d (address 0x%08.8X) present and initialized.\n", i, pNiLink[i]->ibregs);
|
||||
printf(" total niGpibCmd() taskDelay() calls = %lu\n", pNiLink[i]->cmdSpins);
|
||||
printf(" worst case delay in niGpibCmd() = %lu\n", pNiLink[i]->maxSpins);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -325,13 +333,15 @@ initGpib()
|
||||
ibLinkInit(&(pNiLink[i]->ibLink)); /* allocate the sems etc... */
|
||||
|
||||
pibregs->cfg2 = D_SFL; /* can't set all bits at same time */
|
||||
pibregs->cfg2 = D_SFL | D_SPAC | D_SC; /* put board in operating mode */
|
||||
pibregs->cfg2 = D_SFL | D_SC; /* put board in operating mode */
|
||||
|
||||
pNiLink[i]->ibregs = pibregs;
|
||||
pNiLink[i]->ioSem = semCreate();
|
||||
pNiLink[i]->watchDogId = wdCreate();
|
||||
pNiLink[i]->tmoLimit = defaultTimeout;
|
||||
pNiLink[i]->tmoFlag = 0;
|
||||
pNiLink[i]->cmdSpins = 0;
|
||||
pNiLink[i]->maxSpins = 0;
|
||||
|
||||
pNiLink[i]->cc_array.cc_ccb = 0; /* DMAC array chained structure */
|
||||
pNiLink[i]->cc_array.cc_ONE = 1;
|
||||
@@ -386,11 +396,12 @@ initGpib()
|
||||
pNiLink[i]->ibregs->ch1.dcr = D_CS|D_IACK|D_IPCL;
|
||||
pNiLink[i]->ibregs->ch0.dcr = D_CS|D_IACK|D_IPCL;
|
||||
pNiLink[i]->ibregs->ch1.scr = 0; /* no counting during DMA */
|
||||
pNiLink[i]->ibregs->ch1.mfc = D_SUP|D_S24;
|
||||
pNiLink[i]->ibregs->ch1.bfc = D_SUP|D_S24;
|
||||
pNiLink[i]->ibregs->ch0.scr = D_MCU; /* count up during DMA cycles */
|
||||
pNiLink[i]->ibregs->ch0.mfc = D_SUP|D_S24;
|
||||
|
||||
pNiLink[i]->ibregs->ch0.mfc = STD_ADDRESS_MODE;
|
||||
pNiLink[i]->ibregs->ch1.mfc = STD_ADDRESS_MODE;
|
||||
pNiLink[i]->ibregs->ch1.bfc = STD_ADDRESS_MODE;
|
||||
|
||||
|
||||
/* attach the interrupt handler routines */
|
||||
intConnect((NIGPIB_IVEC_BASE + i*2) * 4, niIrq, i);
|
||||
intConnect((NIGPIB_IVEC_BASE + 1 + (i*2)) * 4, niIrqError, i);
|
||||
@@ -585,6 +596,9 @@ int link;
|
||||
* be made to init the bus and enable the interface card.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define TOOLONG 100 /* how many times to try to send the same byte */
|
||||
#define IDELAY 1000 /* how long to busy wait while sending a byte */
|
||||
|
||||
static int
|
||||
niGpibCmd(link, buffer, length)
|
||||
int link;
|
||||
@@ -594,19 +608,21 @@ int length;
|
||||
int iDelay; /* how long to spin before doing a taskWait */
|
||||
int tooLong; /* how long should I tolerate waiting */
|
||||
int lenCtr;
|
||||
unsigned spins; /* how many taskDelay() calls made in this function */
|
||||
|
||||
lenCtr = length;
|
||||
spins = 0;
|
||||
|
||||
if (ibDebug)
|
||||
printf("niGpibCmd(%d, 0x%08.8X, %d): command string >%s<\n", link, buffer, length, buffer);
|
||||
|
||||
tooLong = 60; /* limit to wait for ctrlr's command buffer */
|
||||
tooLong = TOOLONG; /* limit to wait for ctrlr's command buffer */
|
||||
pNiLink[link]->ibregs->auxmr = AUX_TCA; /* take control of the bus */
|
||||
|
||||
while (lenCtr)
|
||||
{
|
||||
pNiLink[link]->r_isr2 &= ~HR_CO;
|
||||
iDelay = 100; /* wait till the ctlr is ready */
|
||||
iDelay = IDELAY; /* wait till the ctlr is ready */
|
||||
while (iDelay && (((pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2) & HR_CO) == 0))
|
||||
iDelay--;
|
||||
|
||||
@@ -614,41 +630,51 @@ int length;
|
||||
{
|
||||
pNiLink[link]->ibregs->cdor = *buffer++; /* output a byte */
|
||||
lenCtr--;
|
||||
tooLong = 60; /* reset the limit again */
|
||||
tooLong = TOOLONG; /* reset the limit again */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(tooLong--))
|
||||
{
|
||||
/* errMsg() */
|
||||
printf("niGpibCmd(%d, 0x%08.8X, %d): Timeout writing command >%s<\n", link, buffer, length, buffer);
|
||||
printf("niGpibCmd(%d, 0x%08.8X, %d): Timeout while writing command >%s<\n", link, buffer, length, buffer);
|
||||
pNiLink[link]->ibregs->auxmr = AUX_GTS;
|
||||
if (spins > pNiLink[link]->maxSpins)
|
||||
pNiLink[link]->maxSpins = spins;
|
||||
return(ERROR);
|
||||
}
|
||||
spins++;
|
||||
pNiLink[link]->cmdSpins++;
|
||||
taskDelay(1); /* ctlr is taking too long */
|
||||
}
|
||||
}
|
||||
tooLong = 60;
|
||||
tooLong = TOOLONG;
|
||||
while(tooLong--)
|
||||
{
|
||||
pNiLink[link]->r_isr2 &= ~HR_CO;
|
||||
iDelay = 100; /* wait till the ctlr is ready */
|
||||
iDelay = IDELAY; /* wait till the ctlr is ready */
|
||||
while (iDelay && (((pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2) & HR_CO) == 0))
|
||||
iDelay--;
|
||||
|
||||
|
||||
if(iDelay)
|
||||
{
|
||||
pNiLink[link]->ibregs->auxmr = AUX_GTS;
|
||||
if (spins > pNiLink[link]->maxSpins)
|
||||
pNiLink[link]->maxSpins = spins;
|
||||
return(length);
|
||||
}
|
||||
else
|
||||
{
|
||||
spins++;
|
||||
pNiLink[link]->cmdSpins++;
|
||||
taskDelay(1);
|
||||
}
|
||||
}
|
||||
/* errMsg() */
|
||||
printf("niGpibCmd(%d, 0x%08.8X, %d): Timeout after writing command >%s<\n", link, buffer, length, buffer);
|
||||
pNiLink[link]->ibregs->auxmr = AUX_GTS;
|
||||
if (spins > pNiLink[link]->maxSpins)
|
||||
pNiLink[link]->maxSpins = spins;
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
@@ -1336,7 +1362,7 @@ struct ibLink *plink; /* a reference to the link structures covered */
|
||||
if ((pnode = (struct dpvtGpibHead *)lstFirst(&(plink->hiPriList))) != NULL)
|
||||
{
|
||||
while (plink->deviceStatus[pnode->device] == BUSY)
|
||||
if ((pnode = (struct dpvtGpibHead *)lstNext(&(plink->hiPriList))) == NULL)
|
||||
if ((pnode = (struct dpvtGpibHead *)lstNext(pnode)) == NULL)
|
||||
break;
|
||||
}
|
||||
if (pnode != NULL)
|
||||
@@ -1358,7 +1384,7 @@ struct ibLink *plink; /* a reference to the link structures covered */
|
||||
if ((pnode = (struct dpvtGpibHead *)lstFirst(&(plink->loPriList))) != NULL)
|
||||
{
|
||||
while (plink->deviceStatus[pnode->device] == BUSY)
|
||||
if ((pnode = (struct dpvtGpibHead *)lstNext(&(plink->loPriList))) == NULL)
|
||||
if ((pnode = (struct dpvtGpibHead *)lstNext(pnode)) == NULL)
|
||||
break;
|
||||
}
|
||||
if (pnode != NULL)
|
||||
@@ -1581,7 +1607,7 @@ int device;
|
||||
int (*handler)(); /* handler function to invoke upon SRQ detection */
|
||||
caddr_t parm; /* so caller can have a parm passed back */
|
||||
{
|
||||
/*if(ibDebug || ibSrqDebug)*/
|
||||
if(ibDebug || ibSrqDebug)
|
||||
printf("registerSrqCallback(%08.8X, %d, 0x%08.8X, %08.8X)\n", pibLink, device, handler, parm);
|
||||
|
||||
pibLink->srqHandler[device] = handler;
|
||||
|
||||
Reference in New Issue
Block a user