コード例 #1
0
ファイル: OWnet.c プロジェクト: grodansparadis/vscp_firmware
//----------------------------------------------------------------------
// The function 'owVerify' verifies that the current device
// is in contact with the 1-Wire Net.
// Using the find alarm command 0xEC will verify that the device
// is in contact with the 1-Wire Net and is in an 'alarm' state.
//
// 'portnum'     - number 0 to MAX_PORTNUM-1.  This number is provided to
//                 indicate the symbolic port number.
// 'alarm_only'  - TRUE (1) the find alarm command 0xEC
//                 is sent instead of the normal search
//                 command 0xF0.
//
// Returns:   TRUE (1) : when the 1-Wire device was verified
//                       to be on the 1-Wire Net
//                       with alarm_only == FALSE
//                       or verified to be on the 1-Wire Net
//                       AND in an alarm state when
//                       alarm_only == TRUE.
//            FALSE (0): the 1-Wire device was not on the
//                       1-Wire Net or if alarm_only
//                       == TRUE, the device may be on the
//                       1-Wire Net but in a non-alarm state.
//
BYTE owVerify(BYTE portnum, BYTE alarm_only)
{
   BYTE i, sendlen = 0, goodbits = 0, cnt = 0, s, tst;
   BYTE sendpacket[50];

   owSetCurrentPort(portnum);
   
   // construct the search
   if(alarm_only) {
     sendpacket[sendlen++] = 0xEC; // issue the alarming search command
   } else {
     sendpacket[sendlen++] = 0xF0; // issue the search command
   }
   
   // set all bits at first
   for(i = 1; i <= 24; i++) {
     sendpacket[sendlen++] = 0xFF;
   }

   // now set or clear apropriate bits for search
   for(i = 0; i < 64; i++) {
     bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION, 0, i, &owNetCurrent.SerialNum[0]),(int)((i+1)*3-1),&sendpacket[1]);
   }
   
   // send/recieve the transfer buffer
   if(owBlock(owCurrentPortnum, TRUE, sendpacket, sendlen)) {
     // check results to see if it was a success
     for(i = 0; i < 192; i += 3) {
       tst = (bitacc(READ_FUNCTION, 0, i, &sendpacket[1]) << 1) |
              bitacc(READ_FUNCTION, 0, (int)(i+1), &sendpacket[1]);

       s = bitacc(READ_FUNCTION, 0, cnt++, &owNetCurrent.SerialNum[0]);

       if(tst == 0x03) {      // no device on line
         goodbits = 0;        // number of good bits set to zero
         break;               // quit
       }

       if(((s == 0x01) && (tst == 0x02)) ||
          ((s == 0x00) && (tst == 0x01))) {  // correct bit
         goodbits++;                       // count as a good bit
       }
     }

     // check too see if there were enough good bits to be successful
     if(goodbits >= 8) {
       return TRUE;
     }
   } else {
     OWERROR(OWERROR_BLOCK_FAILED);
   }

   // block fail or device not present
   return FALSE;
}
コード例 #2
0
ファイル: owfile.c プロジェクト: Derpybunneh/cpctelera
//--------------------------------------------------------------------------
// Format and Write a TMEX file. 
// Any previous files will be removed in the Format operation.
// The file length 'fllen' can be up to:
//     420  bytes for a DS1993   
//     1736 bytes for a DS1995
//     7084 bytes for a DS1996.
//
// 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
//              OpenCOM to indicate the port number.
// 'filename' - pointer to five byte filename to write where the
//              the first four bytes are the name and the fifth is
//              the extension (0 to 101 decimal).             
// 'buf'      - pointer to a buffer containing the file information to write.
//
// Supported devices: DS1993, DS1994, DS1995, DS1996
//
// Returns:  TRUE(1) success, device formated and file written
//           <0      failed to read the file (error code) 
//     
//
int owFormatWriteFile(int portnum, uchar *filename, int fllen, uchar *buf)
{
   uchar dummydir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, 0 },
      newdir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, ' ', ' ', ' ', ' ', 0, 1, 1, 0 },
      bmpg1[] = { 0x03,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x02 },
      bmpg2[] = { 0,0,0,0,0 }, pgbuf[32];   
   int i,numdirpgs,flpg,bmpg1len,bmpg2len,cntleft,pos,numpgs;

#if DEBUG_OW_FILE
   printf ("owFormatWriteFile: %s %d\n", filename, fllen);
#endif
   // calculate the number of pages needed to write the file
   numpgs = (fllen / 28) + ((fllen % 28) ? 1 : 0);
   
   // put the file in the newdirectory
   for(i = 0; i < 5; i++)
      newdir[i+7] = filename[i];
   newdir[13] = (uchar)numpgs;
   
   // set the directory pages for formatting device depending on the device type
   switch (SerialNum[portnum][0])  //jpe
   {
      case 0x06:  // DS1993
         // check for file too big
         if (numpgs > 15)
            return FILE_TOO_BIG;
         // set the bitmap in the directory page
         for (i = 0; i < numpgs; i++)
            bitacc(WRITE_FUNCTION,1,i+1,&newdir[3]);
         numdirpgs = 1;
         flpg = 1;   
         newdir[12] = (uchar)flpg;
         break;                               
      case 0x0A:  // DS1995
         // check for file too big
         if (numpgs > 62)
            return FILE_TOO_BIG;       
         // set to external bitmap file
         newdir[2] = 0; 
         // set the bitmap in the first (and only) bitmap page
         for (i = 0; i < numpgs; i++)
            bitacc(WRITE_FUNCTION,1,i+2,&bmpg1[0]);
         numdirpgs = 2;
         flpg = 2; 
         newdir[12] = (uchar)flpg; // startpage
         bmpg1len = 9;                          
         newdir[3] = 0; // remove local bitmap
         newdir[5] = 1; // bitmap start page
         newdir[6] = 1; // bitmap number of pages
         break;                               
      case 0x0C:  // DS1996 
         // check for file too big
         if (numpgs > 253)
            return FILE_TOO_BIG;
         // set to external bitmap file
         newdir[2] = 0; 
         // set the 3rd bitmap page in the bitmap
         bitacc(WRITE_FUNCTION,1,2,&bmpg1[0]);
         
         // set the bitmap in the first and second bitmap page
         for (i = 0; i < numpgs; i++)
         {
            if (i <= 221)
               bitacc(WRITE_FUNCTION,1,i+3,&bmpg1[0]);  
            else
               bitacc(WRITE_FUNCTION,1,i-221,&bmpg2[0]);  
         }   
         numdirpgs = 3;
         flpg = 3;   
         newdir[12] = (uchar)flpg; // startpage
         bmpg1len = 29;  
         bmpg2len = 5;  
         newdir[3] = 0; // remove local bitmap
         newdir[5] = 1; // bitmap start page
         newdir[6] = 2; // bitmap number of pages
         break;                               
      default:
         return WRONG_TYPE;
   }
   
   // write a dummy directory in page 0 in case we get interrupted
   if (!owWritePacketStd(portnum,0,dummydir,8,FALSE,FALSE))
      return WRITE_ERROR;
   
   // loop to write the file in contiguous pages start with flpg
   cntleft = fllen;  // count of bytes left to write  
   pos = 0; // current position in the buffer to write
   while (cntleft > 0)
   {
      // get a page of data to write
      for (i = 0; i < ((cntleft > 28) ? 28 : cntleft); i++)
         pgbuf[i] = buf[pos++];
                                    
      // adjust the bytes left
      cntleft -= i;
                                    
      // set the next page pointer   
      pgbuf[i] = (cntleft == 0) ? 0 : flpg+1;
      
      // write the page and check to result
      if (!owWritePacketStd(portnum,flpg,pgbuf,i+1,FALSE,FALSE))
         return WRITE_ERROR;
      
      // set the next page
      flpg++;      
   } 

   // now write the second bitmap page if needed
   if (numdirpgs == 3)
      if (!owWritePacketStd(portnum,2,bmpg2,bmpg2len,FALSE,FALSE))
         return WRITE_ERROR;

   // now write the first bitmap page if needed
   if (numdirpgs >= 2)
      if (!owWritePacketStd(portnum,1,bmpg1,bmpg1len,FALSE,FALSE))
         return WRITE_ERROR;
   
   // now write the directory page
   if (!owWritePacketStd(portnum,0,newdir,15,FALSE,FALSE))
      return WRITE_ERROR;
   
   // success file written
   return TRUE;
} 
コード例 #3
0
//--------------------------------------------------------------------------
// The 'OWSearch' function does a general search.  This function
// continues from the previos search state. The search state
// can be reset by using the 'OWFirst' function.
// This function contains one parameter 'alarm_only'.
// When 'alarm_only' is TRUE (1) the find alarm command
// 0xEC is sent instead of the normal search command 0xF0.
// Using the find alarm command 0xEC will limit the search to only
// 1-Wire devices that are in an 'alarm' state.
//
// Returns:   TRUE (1) : when a 1-Wire device was found and it's
//                       Serial Number placed in the global ROM
//            FALSE (0): when no new device was found.  Either the
//                       last search was the last device or there
//                       are no devices on the 1-Wire Net.
//
int DallasOneWire::OWSearch(void)
{
	DATA(F("OWSearch"));

	unsigned char last_zero,pos;
	unsigned char tmp_rom[8];
	unsigned char readbuffer[20],sendpacket[40];
	unsigned char i,sendlen=0;

	// if the last call was the last one
	if (LastDeviceFlag)
	{
		DATA(F("OWSearch: the last call was the last one"));
		// reset the search
		LastDiscrepancy = 0;
		LastDeviceFlag = FALSE;
		LastFamilyDiscrepancy = 0;
		return FALSE;
	}

	// reset the 1-wire
	// if there are no parts on 1-wire, return FALSE
	if (!OWReset())
	{
		DEBUG(F("OWSearch: there are no parts on 1-wire, return FALSE"));
		// reset the search
		LastDiscrepancy = 0;
		LastFamilyDiscrepancy = 0;
		return FALSE;
	}

	// build the command stream
	// call a function that may add the change mode command to the buff
	// check for correct mode
	if (UMode != MODSEL_DATA)
	{
		DATA(F("OWSearch: UMode != MODSEL_DATA"));
		UMode = MODSEL_DATA;
		sendpacket[sendlen++] = MODE_DATA;
	}

	// search command
	sendpacket[sendlen++] = 0xF0;

	// change back to command mode
	UMode = MODSEL_COMMAND;
	sendpacket[sendlen++] = MODE_COMMAND;

	// search mode on
	sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed);

	// change back to data mode
	UMode = MODSEL_DATA;
	sendpacket[sendlen++] = MODE_DATA;

	// set the temp Last Discrepancy to 0
	last_zero = 0;

	// add the 16 bytes of the search
	pos = sendlen;
	for (i = 0; i < 16; i++)
		sendpacket[sendlen++] = 0;

	// only modify bits if not the first search
	if (LastDiscrepancy != 0)
	{
		DATA(F("OWSearch: LastDiscrepancy != 0"));
		// set the bits in the added buffer
		for (i = 0; i < 64; i++)
		{
			// before last discrepancy
			if (i < (LastDiscrepancy - 1))
				bitacc(WRITE_FUNCTION,
						bitacc(READ_FUNCTION,0,i,&ROM_NO[0]),
						(short)(i * 2 + 1),
						&sendpacket[pos]);
			// at last discrepancy
			else if (i == (LastDiscrepancy - 1))
				bitacc(WRITE_FUNCTION,1,(short)(i * 2 + 1),
						&sendpacket[pos]);
			// after last discrepancy so leave zeros
		}
	}

	// change back to command mode
	UMode = MODSEL_COMMAND;
	sendpacket[sendlen++] = MODE_COMMAND;

	// search OFF command
	sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed);

	// flush the buffers
	flush();

	// send the packet
	if (WriteCOM(sendlen,sendpacket))
	{
		// read back the 1 byte response
		if (ReadCOM(17,readbuffer) == 17)
		{
			// interpret the bit stream
			for (i = 0; i < 64; i++)
			{
				// get the ROM bit
				bitacc(WRITE_FUNCTION,
						bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]),i,
						&tmp_rom[0]);
				// check LastDiscrepancy
				if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) &&
						(bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0))
				{
					last_zero = i + 1;
					// check LastFamilyDiscrepancy
					if (i < 8)
						LastFamilyDiscrepancy = i + 1;
				}
			}

			// do dowcrc
			crc8 = 0;
			for (i = 0; i < 8; i++)
				docrc8(tmp_rom[i]);

			// check results
			if ((crc8 != 0) || (LastDiscrepancy == 63) || (tmp_rom[0] == 0))
			{
				// error during search
				// reset the search
				LastDiscrepancy = 0;
				LastDeviceFlag = FALSE;
				LastFamilyDiscrepancy = 0;
				return FALSE;
			}
			// successful search
			else
			{
				// set the last discrepancy
				LastDiscrepancy = last_zero;

				// check for last device
				if (LastDiscrepancy == 0)
					LastDeviceFlag = TRUE;

				// copy the ROM to the buffer
				for (i = 0; i < 8; i++)
					ROM_NO[i] = tmp_rom[i];

				return TRUE;
			}
		}
	}

	WARNING(F("OWSearch: an error occured so re-sync with DS2480B"));
	// an error occured so re-sync with DS2480B
	DS2480B_Detect();

	// reset the search
	LastDiscrepancy = 0;
	LastDeviceFlag = FALSE;
	LastFamilyDiscrepancy = 0;

	return FALSE;
}
コード例 #4
0
ファイル: ownetu.c プロジェクト: BitMax/openitg
//--------------------------------------------------------------------------
// The 'owNext' function does a general search.  This function
// continues from the previos search state. The search state
// can be reset by using the 'owFirst' function.
// This function contains one parameter 'alarm_only'.
// When 'alarm_only' is TRUE (1) the find alarm command
// 0xEC is sent instead of the normal search command 0xF0.
// Using the find alarm command 0xEC will limit the search to only
// 1-Wire devices that are in an 'alarm' state.
//
// 'portnum'    - number 0 to MAX_PORTNUM-1.  This number was provided to
//                OpenCOM to indicate the port number.
// 'do_reset'   - TRUE (1) perform reset before search, FALSE (0) do not
//                perform reset before search.
// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
//                sent instead of the normal search command 0xF0
//
// Returns:   TRUE (1) : when a 1-Wire device was found and it's
//                       Serial Number placed in the global SerialNum
//            FALSE (0): when no new device was found.  Either the
//                       last search was the last device or there
//                       are no devices on the 1-Wire Net.
//
SMALLINT owNext(int portnum, SMALLINT do_reset, SMALLINT alarm_only)
{
   uchar last_zero,pos;
   uchar tmp_serial_num[8];
   uchar readbuffer[20],sendpacket[40];
   uchar i,sendlen=0;
   uchar lastcrc8;

   // if the last call was the last one
   if (LastDevice[portnum])
   {
      // reset the search
      LastDiscrepancy[portnum] = 0;
      LastDevice[portnum] = FALSE;
      LastFamilyDiscrepancy[portnum] = 0;
      return FALSE;
   }

   // check if reset first is requested
   if (do_reset)
   {
      // reset the 1-wire
      // if there are no parts on 1-wire, return FALSE
      if (!owTouchReset(portnum))
      {
         // reset the search
         LastDiscrepancy[portnum] = 0;
         LastFamilyDiscrepancy[portnum] = 0;
         OWERROR(OWERROR_NO_DEVICES_ON_NET);
         return FALSE;
      }
   }

   // build the command stream
   // call a function that may add the change mode command to the buff
   // check if correct mode
   if (UMode[portnum] != MODSEL_DATA)
   {
      UMode[portnum] = MODSEL_DATA;
      sendpacket[sendlen++] = MODE_DATA;
   }

   // search command
   if (alarm_only)
      sendpacket[sendlen++] = 0xEC; // issue the alarming search command
   else
      sendpacket[sendlen++] = 0xF0; // issue the search command

   // change back to command mode
   UMode[portnum] = MODSEL_COMMAND;
   sendpacket[sendlen++] = MODE_COMMAND;

   // search mode on
   sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed[portnum]);

   // change back to data mode
   UMode[portnum] = MODSEL_DATA;
   sendpacket[sendlen++] = MODE_DATA;

   // set the temp Last Descrep to none
   last_zero = 0;

   // add the 16 bytes of the search
   pos = sendlen;
   for (i = 0; i < 16; i++)
      sendpacket[sendlen++] = 0;

   // only modify bits if not the first search
   if (LastDiscrepancy[portnum] != 0)
   {
      // set the bits in the added buffer
      for (i = 0; i < 64; i++)
      {
         // before last discrepancy
         if (i < (LastDiscrepancy[portnum] - 1))
               bitacc(WRITE_FUNCTION,
                   bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]),
                   (short)(i * 2 + 1),
                   &sendpacket[pos]);
         // at last discrepancy
         else if (i == (LastDiscrepancy[portnum] - 1))
                bitacc(WRITE_FUNCTION,1,
                   (short)(i * 2 + 1),
                   &sendpacket[pos]);
         // after last discrepancy so leave zeros
      }
   }

   // change back to command mode
   UMode[portnum] = MODSEL_COMMAND;
   sendpacket[sendlen++] = MODE_COMMAND;

   // search OFF
   sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum]);

   // flush the buffers
   FlushCOM(portnum);

   // send the packet
   if (WriteCOM(portnum,sendlen,sendpacket))
   {
      // read back the 1 byte response
      if (ReadCOM(portnum,17,readbuffer) == 17)
      {
         // interpret the bit stream
         for (i = 0; i < 64; i++)
         {
            // get the SerialNum bit
            bitacc(WRITE_FUNCTION,
                   bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]),
                   i,
                   &tmp_serial_num[0]);
            // check LastDiscrepancy
            if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) &&
                (bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0))
            {
               last_zero = i + 1;
               // check LastFamilyDiscrepancy
               if (i < 8)
                  LastFamilyDiscrepancy[portnum] = i + 1;
            }
         }

         // do dowcrc
         setcrc8(portnum,0);
//         for (i = 0; i < 8; i++)
//            lastcrc8 = docrc8(portnum,tmp_serial_num[i]);
         // The above has been commented out for the DS28E04.  The
         // below has been added to accomidate the valid CRC with the
         // possible changing serial number values of the DS28E04.
         for (i = 0; i < 8; i++)
         {
            if (((tmp_serial_num[0] & 0x7F) == 0x1C) && (i == 1))
               lastcrc8 = docrc8(portnum,0x7F);
            else            
               lastcrc8 = docrc8(portnum,tmp_serial_num[i]);
         }


         // check results
         if ((lastcrc8 != 0) || (LastDiscrepancy[portnum] == 63) || (tmp_serial_num[0] == 0))
         {
            // error during search
            // reset the search
            LastDiscrepancy[portnum] = 0;
            LastDevice[portnum] = FALSE;
            LastFamilyDiscrepancy[portnum] = 0;
            OWERROR(OWERROR_SEARCH_ERROR);
            return FALSE;
         }
         // successful search
         else
         {
            // set the last discrepancy
            LastDiscrepancy[portnum] = last_zero;

            // check for last device 
            if (LastDiscrepancy[portnum] == 0)
               LastDevice[portnum] = TRUE;

            // copy the SerialNum to the buffer
            for (i = 0; i < 8; i++)
               SerialNum[portnum][i] = tmp_serial_num[i];

            // set the count
            return TRUE;
         }
      }
      else
         OWERROR(OWERROR_READCOM_FAILED);
   }
   else
      OWERROR(OWERROR_WRITECOM_FAILED);
   
   // an error occured so re-sync with DS2480
   DS2480Detect(portnum);

   // reset the search
   LastDiscrepancy[portnum] = 0;
   LastDevice[portnum] = FALSE;
   LastFamilyDiscrepancy[portnum] = 0;

   return FALSE;
}
コード例 #5
0
ファイル: usbwnet.c プロジェクト: AriZuu/OneWire
//--------------------------------------------------------------------------
// The 'owNext' function does a general search.  This function
// continues from the previos search state. The search state
// can be reset by using the 'owFirst' function.
// This function contains one parameter 'alarm_only'.
// When 'alarm_only' is TRUE (1) the find alarm command
// 0xEC is sent instead of the normal search command 0xF0.
// Using the find alarm command 0xEC will limit the search to only
// 1-Wire devices that are in an 'alarm' state.
//
// 'portnum'    - number 0 to MAX_PORTNUM-1.  This number is provided to
//                indicate the symbolic port number.
// 'do_reset'   - TRUE (1) perform reset before search, FALSE (0) do not
//                perform reset before search.
// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
//                sent instead of the normal search command 0xF0
//
// Returns:   TRUE (1) : when a 1-Wire device was found and it's
//                       Serial Number placed in the global SerialNum[portnum]
//            FALSE (0): when no new device was found.  Either the
//                       last search was the last device or there
//                       are no devices on the 1-Wire Net.
//
SMALLINT owNext(int portnum, SMALLINT do_reset, SMALLINT alarm_only)
{
   SETUP_PACKET setup;
   short rt=FALSE,i,ResetSearch=FALSE;
   BYTE rom_buf[16];
   BYTE ret_buf[16];
   WORD buf_len;
   uchar lastcrc8;
   WORD  nBytes = 8;
   ULONG nOutput = 0;
   long limit;
   STATUS_PACKET status;
   BYTE  nResult;

   // if the last call was the last one
   if (LastDevice[portnum])
   {
      // reset the search
      LastDiscrepancy[portnum] = 0;
      LastDevice[portnum] = FALSE;
      LastFamilyDiscrepancy[portnum] = 0;
      return FALSE;
   }

   // check if reset first is requested
   if (do_reset)
   {
      // reset the 1-wire
      // extra reset if last part was a DS1994/DS2404 (due to alarm)
      if ((SerialNum[portnum][0] & 0x7F) == 0x04)
         owTouchReset(portnum);
      // if there are no parts on 1-wire, return FALSE
      if (!owTouchReset(portnum))
      {
         // reset the search
         LastDiscrepancy[portnum] = 0;
         LastFamilyDiscrepancy[portnum] = 0;
         OWERROR(OWERROR_NO_DEVICES_ON_NET);
         return FALSE;
      }
   }

   // build the rom number to put to the USB chip
   for (i = 0; i < 8; i++)
      rom_buf[i] = SerialNum[portnum][i];

   // take into account LastDiscrepancy
   if (LastDiscrepancy[portnum] != 0xFF)
   {
      if (LastDiscrepancy[portnum] > 0)
         bitacc(WRITE_FUNCTION,1,(short)(LastDiscrepancy[portnum] - 1),rom_buf);

      for (i = LastDiscrepancy[portnum]; i < 64; i++)
         bitacc(WRITE_FUNCTION,0,i,rom_buf);
   }

   // put the ROM ID in EP2
   nBytes = 8;
   if (!DS2490Write(usbhnd[portnum], rom_buf, &nBytes))
   {
      AdapterRecover(portnum);
      return FALSE;
   }

   // setup for search command call
   setup.RequestTypeReservedBits = 0x40;
   setup.Request = COMM_CMD;
   setup.Value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; 
   // the number of devices to read (1) with the search command
   setup.Index = 0x0100 | (((alarm_only) ? 0xEC : 0xF0) & 0x00FF);  
   setup.Length = 0;
   setup.DataOut = FALSE;
   // call the driver
   if (!DeviceIoControl(usbhnd[portnum],
					    DS2490_IOCTL_VENDOR,
					    &setup,
					    sizeof(SETUP_PACKET),
					    NULL,
					    0,
					    &nOutput,
					    NULL))
   {
      // failure
      AdapterRecover(portnum);
      return FALSE;
   }

   // set a time limit
   limit = msGettick() + 200;
   // loop to wait on EP3 ready (device will go idle)   
   do
   {
      // read the status to see if the pulse has been stopped
      if (!DS2490GetStatus(usbhnd[portnum], &status, &nResult))
      {
         // failure
         break;
      }
      else
      {
	      // look for any fail conditions
	      for (i = 0; i < nResult; i++)
	      {
	        // only check for error conditions when the condition is not a ONEWIREDEVICEDETECT
	        if (status.CommResultCodes[i] != ONEWIREDEVICEDETECT)
	        {
               // failure
               break;
           }
         }
      }
   }
   while (((status.StatusFlags & STATUSFLAGS_IDLE) == 0) && 
          (limit > msGettick()));

   // check results of the waite for idel
   if ((status.StatusFlags & STATUSFLAGS_IDLE) == 0) 
   {
      AdapterRecover(portnum);
      return FALSE;
   }

   // check for data 
   if (status.ReadBufferStatus > 0)
   {
      // read the load 
      buf_len = 16;
	   if(!DS2490Read(usbhnd[portnum], ret_buf, &buf_len))
      {
         AdapterRecover(portnum);
		   return FALSE;
      }

      // success, get rom and desrepancy
      LastDevice[portnum] = (buf_len == 8); 
      // extract the ROM (and check crc)
      setcrc8(portnum,0);
      for (i = 0; i < 8; i++)
      {
         SerialNum[portnum][i] = ret_buf[i];
         lastcrc8 = docrc8(portnum,ret_buf[i]);
      }
      // crc OK and family code is not 0
      if (!lastcrc8 && SerialNum[portnum][0])
      {
         // loop through the descrepancy to get the pointers
         for (i = 0; i < 64; i++)
         {
            // if descrepancy
            if (bitacc(READ_FUNCTION,0,i,&ret_buf[8]) &&
                (bitacc(READ_FUNCTION,0,i,&ret_buf[0]) == 0))
            {
               LastDiscrepancy[portnum] = i + 1;  
            }
         }
         rt = TRUE;
      }
      else
      {
         ResetSearch = TRUE;
         rt = FALSE;
      }
   }

   // check if need to reset search
   if (ResetSearch)
   {
      LastDiscrepancy[portnum] = 0xFF;
      LastDevice[portnum] = FALSE;
      for (i = 0; i < 8; i++)
         SerialNum[portnum][i] = 0;
   }

   return rt;
}