LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Under WinNT I lose a lot time between successive reads to hardware

I am running NT4.0 CVI 7.0/6.0.
 
I have a PC104/ISA bus card that requires some handshaking when asking for data. (It gives me 24bit analogue data)
ie.
1. send a Read command to card
2. read Status Register and check if data ready to read ie. wait for DataReady flag
3. read first data byte
4. keep reading Status Register until DataReady flag set
5. read second data byte
6. keep reading Status Register until  DataReady flag set
7. read third data byte.
 
I use the inp() outp() functions and have loaded the cvintdrv.sys and confirmed that it is running.
 
In the sequence above if I wait too long before reading a data byte (ie. longer than ~5mSec) the PC104 card returns a timeout error and the sequence must start again. 
 
Basically I get many errors inbetween valid data.  I am not sure if the inp()/outp() are really working or that it is a timing error.  There are some single byte reads that I can do and they seem to be valid - therefore I am inclined to say the inp()/outp() are okay and it is a timing error.
 
I used the window set priority before and after my card calls as indicated, but that does not seem to help me.
 
//========================================================
 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
   
    error = SD811_GetData (&data);
 
     SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
//========================================================
    
 
0 Kudos
Message 1 of 3
(2,892 Views)

Is the PC104 card running right off the ISA bus of your CPU?

I assume you are executing this in some sort of callback or polling loop and that all other application functions are blocked while you are doing the acquisition, or you have this in a separate thread.

Are you saying that when you do single byte reads, seconds apart, that the reads work ok?

After you read the first byte, do you know that the status register is cleared before the second byte becomes available?  If the PC104 card has not had time to clear the status register after your hardware read, you maybe trying to read the next data byte before it is available.  You might also want to look at how your PC104 hardware implements the status register.  You are reading it at a very fast rate while the PC104 card is also trying to updating it to Set and Clear the Data Ready flag.  Some ISA hardware can get blocked under these conditions when installed in a system with a CPU that runs faster than those available when the hardware was designed.

I

Message Edited by mvr on 06-23-2006 09:43 AM

0 Kudos
Message 2 of 3
(2,884 Views)
The code below are the routines given by the card manufacturer.  The SD811_GetData() is the routine for reading the 24 bit analogue data. The checking of the status registers is incorporated in the GetData() routine. So I think the sequence is okay, but perhaps the timing of it all is wrong.
 
The reason I am thinking that NT is going 'off' somewhere is that I do get some good data (50 bad to 1 good) , but only occaisionally. If I use exactly the same hardware, just swapped the HDD with one an windows95 on it. The same compiled code gives almost no errors reading the card (100 good to 1 bad).  So does win95 have less overheads and do the loops faster?
 
The setting of the thread priority I thought might have helped here as indicated above, but I dont see any real improvement.
 
The card manufacturer says there is a  ~5ms hardware timeout if the byte(s) are not read. These timeout errors are what are received on a 'bad' read.
 
int SD811_GetData(long *pData)
{
register int iIndex;
long *pWord;
char szBuffer[4];
char *pByte;
int ireturnValue=SD811_OK;

if(WaitForIBFClear() != SD811_OK)
   return(SD811_IBF_TIMEOUT);                //input buffer not full
outp(SD811_DATA,SD811_GETDATA);    //write command
   
if(WaitForIBFClear() != SD811_OK)   //wait for clear, SD811 has read command
     return(SD811_IBF_TIMEOUT);
for(iIndex=0; iIndex<3; iIndex++)
 {
   if(WaitForOBFSet() != SD811_OK)
      return(SD811_OBF_TIMEOUT);    //error=3
  szBuffer[iIndex]=inp(SD811_DATA);   //read data 3 times
  }
szBuffer[3]= 0;                     //pad 4th byte with zero
if(WaitForOBFSet() != SD811_OK)
  ireturnValue=(5);     //new value for no OBFSet waiting for SD811_OK
if(inp(SD811_DATA) != SD811_OK)
  ireturnValue=5; //(SD811_ERROR);
pByte=&szBuffer[0];
pWord=(long *)pByte;
*pData=*pWord;
return(ireturnValue);
}
 
int WaitForIBFClear(void)
{
time_t tStart;
int iIndex;
 
if((inp(SD811_CSR) & 0x01)==0)
   return(SD811_OK);
for(iIndex=0; iIndex<25000; iIndex++)
{
 if((inp(SD811_CSR)&0x01)==0)
    return(SD811_OK);
}
return(SD811_ERROR);
}
 
int WaitForOBFSet(void)
{
time_t tStart;
int iData;
int iIndex;
 
iData=inp(SD811_CSR);        //read CSR
if((iData&0x02)!=0)     //logical AND with h'02, if not 0 output buffer
   return(SD811_OK);     //full flag is up, return and read
else
{
 for (iIndex=0;iIndex<25000;iIndex++)
 {
  if((iData=inp(SD811_CSR) & 0x02) != 0)
    return(SD811_OK);
  }
 }
return(SD811_ERROR);
}
0 Kudos
Message 3 of 3
(2,870 Views)