//--------------------------------------------------------------------------- // Check to see if there is a short on the 1-Wire bus. Used to stop // communication with the DS2490 while the short is in effect to not // overrun the buffers. // // '*present' - flag set (1) if device presence detected // '*vpp' - flag set (1) if Vpp programming voltage detected // // Returns: TRUE - DS2490 1-Wire is NOT shorted // FALSE - Could not detect DS2490 or 1-Wire shorted // SMALLINT DS2490ShortCheck(usb_dev_handle *hDevice, SMALLINT *present, SMALLINT *vpp) { STATUS_PACKET status; uchar nResultRegisters; uchar i; // get the result registers (if any) if (!DS2490GetStatus(hDevice, &status, &nResultRegisters)) return FALSE; // get vpp present flag *vpp = ((status.StatusFlags & STATUSFLAGS_12VP) != 0); // Check for short if(status.CommBufferStatus != 0) { return FALSE; } else { // check for short for (i = 0; i < nResultRegisters; i++) { // check for SH bit (0x02), ignore 0xA5 if (status.CommResultCodes[i] & COMMCMDERRORRESULT_SH) { // short detected return FALSE; } } } // check for No 1-Wire device condition *present = TRUE; // loop through result registers for (i = 0; i < nResultRegisters; i++) { // only check for error conditions when the condition is not a ONEWIREDEVICEDETECT if (status.CommResultCodes[i] != ONEWIREDEVICEDETECT) { // check for NRS bit (0x01) if (status.CommResultCodes[i] & COMMCMDERRORRESULT_NRS) { // empty bus detected *present = FALSE; } } } return TRUE; }
//--------------------------------------------------------------------------- // Stop any on-going pulses // // Returns: TRUE - pulse stopped // FALSE - Could not stop pulse // SMALLINT DS2490HaltPulse(usb_dev_handle *hDevice) { STATUS_PACKET status; uchar nResultRegisters; SETUP_PACKET setup; SMALLINT ret; long limit; // set a time limit limit = msGettick() + 300; // loop until confirm pulse has ended or timeout do { // HalExecWhenIdle, Resume Execution to stop an infinite pulse // HalExecWhenIdle setup.RequestTypeReservedBits = 0x40; setup.Request = CONTROL_CMD; setup.Value = CTL_HALT_EXE_IDLE; setup.Index = 0x00; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(hDevice, setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure break; } // Resume Execution setup.RequestTypeReservedBits = 0x40; setup.Request = CONTROL_CMD; setup.Value = CTL_RESUME_EXE; setup.Index = 0x00; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(hDevice, setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure break; } // read the status to see if the pulse has been stopped if (!DS2490GetStatus(hDevice, &status, &nResultRegisters)) { // failure break; } else { // check the SPU flag if ((status.StatusFlags & STATUSFLAGS_SPUA) == 0) { // success // disable both pulse types setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_PULSE_EN; setup.Index = 0; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(hDevice, setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); return TRUE; } } } while (limit > msGettick()); return FALSE; }
//-------------------------------------------------------------------------- // 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; }