//-------------------------------------------------------------------------- // Reset all of the devices on the 1-Wire Net and return the result. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE(1): presense pulse(s) detected, device(s) reset // FALSE(0): no presense pulses detected // SMALLINT owTouchResetUSB(int portnum) { SETUP_PACKET setup; SMALLINT present,vpp; SMALLINT ret = 0; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevelUSB(portnum, MODE_NORMAL); // construct command setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE; setup.Index = (USBSpeed[portnum] == MODE_OVERDRIVE) ? ONEWIREBUSSPEED_OVERDRIVE : ONEWIREBUSSPEED_FLEXIBLE; setup.Length = 0; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_RESET_FAILED); AdapterRecover(portnum); return FALSE; } else { // extra delay for alarming DS1994/DS2404 complience if ((FAMILY_CODE_04_ALARM_TOUCHRESET_COMPLIANCE) && (USBSpeed[portnum] != MODE_OVERDRIVE)) msDelay(5); // success, check for shorts if (DS2490ShortCheck(usb_dev_handle_list[portnum], &present,&vpp)) { USBVpp[portnum] = vpp; return present; } else { OWERROR(OWERROR_OW_SHORTED); // short occuring msDelay(300); AdapterRecover(portnum); return FALSE; } } }
//-------------------------------------------------------------------------- // Reset all of the devices on the 1-Wire Net and return the result. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE(1): presense pulse(s) detected, device(s) reset // FALSE(0): no presense pulses detected // SMALLINT owTouchReset(int portnum) { SETUP_PACKET setup; ULONG nOutput = 0; SMALLINT present,vpp; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevel(portnum, MODE_NORMAL); // construct command setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE; setup.Index = (USBSpeed[portnum] == MODE_OVERDRIVE) ? ONEWIREBUSSPEED_OVERDRIVE : ONEWIREBUSSPEED_FLEXIBLE; 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 OWERROR(OWERROR_RESET_FAILED); AdapterRecover(portnum); return FALSE; } else { // extra delay for alarming DS1994/DS2404 complience if ((FAMILY_CODE_04_ALARM_TOUCHRESET_COMPLIANCE) && (USBSpeed[portnum] != MODE_OVERDRIVE)) Sleep(5); // success, check for shorts if (DS2490ShortCheck(usbhnd[portnum], &present,&vpp)) { USBVpp[portnum] = vpp; return present; } else { OWERROR(OWERROR_OW_SHORTED); // short occuring msDelay(300); AdapterRecover(portnum); return FALSE; } } }
//-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and verify that the // 8 bits read from the 1-Wire Net is the same (write operation). // The parameter 'sendbyte' least significant 8 bits are used. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: TRUE: bytes written and echo was the same // FALSE: echo was not the same // SMALLINT owTouchByteUSB(int portnum, SMALLINT sendbyte) { SETUP_PACKET setup; ushort nBytes; uchar buf[2]; SMALLINT ret = 0; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevelUSB(portnum, MODE_NORMAL); // set to do touchbyte setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_BYTE_IO | COMM_IM; setup.Index = sendbyte & 0xFF; setup.Length = 0; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return 0; } else { // success, read the result nBytes = 1; if (DS2490Read(usb_dev_handle_list[portnum], buf, &nBytes)) return buf[0]; else { OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return 0; } } }
//-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and verify that the // 8 bits read from the 1-Wire Net is the same (write operation). // The parameter 'sendbyte' least significant 8 bits are used. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: TRUE: bytes written and echo was the same // FALSE: echo was not the same // SMALLINT owTouchByte(int portnum, SMALLINT sendbyte) { SETUP_PACKET setup; ULONG nOutput = 0; WORD nBytes; BYTE buf[2]; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevel(portnum, MODE_NORMAL); // set to do touchbyte setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_BYTE_IO | COMM_IM; setup.Index = sendbyte & 0xFF; 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 OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return 0; } else { // success, read the result nBytes = 1; if (DS2490Read(usbhnd[portnum], buf, &nBytes)) return buf[0]; else { OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return 0; } } }
//-------------------------------------------------------------------------- // Set the 1-Wire Net communucation speed. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'new_speed' - new speed defined as // MODE_NORMAL 0x00 // MODE_OVERDRIVE 0x01 // // Returns: current 1-Wire Net speed // SMALLINT owSpeed(int portnum, SMALLINT new_speed) { SETUP_PACKET setup; ULONG nOutput = 0; // set to change the speed setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_1WIRE_SPEED; setup.Index = ((new_speed == MODE_OVERDRIVE) ? ONEWIREBUSSPEED_OVERDRIVE : ONEWIREBUSSPEED_FLEXIBLE) & 0x00FF; setup.Length = 0x00; setup.DataOut = FALSE; // call the driver if (!DeviceIoControl(usbhnd[portnum], DS2490_IOCTL_VENDOR, &setup, sizeof(SETUP_PACKET), NULL, 0, &nOutput, NULL)) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return USBSpeed[portnum]; } else { // success, read the result USBSpeed[portnum] = new_speed; return new_speed; } }
//-------------------------------------------------------------------------- // Set the 1-Wire Net communucation speed. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'new_speed' - new speed defined as // MODE_NORMAL 0x00 // MODE_OVERDRIVE 0x01 // // Returns: current 1-Wire Net speed // SMALLINT owSpeedUSB(int portnum, SMALLINT new_speed) { SETUP_PACKET setup; SMALLINT ret = 0; // set to change the speed setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_1WIRE_SPEED; setup.Index = ((new_speed == MODE_OVERDRIVE) ? ONEWIREBUSSPEED_OVERDRIVE : ONEWIREBUSSPEED_FLEXIBLE) & 0x00FF; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return USBSpeed[portnum]; } else { // success, read the result USBSpeed[portnum] = new_speed; return new_speed; } }
//-------------------------------------------------------------------------- // This procedure creates a fixed 480 microseconds 12 volt pulse // on the 1-Wire Net for programming EPROM iButtons. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE successful // FALSE program voltage not available // SMALLINT owProgramPulseUSB(int portnum) { SETUP_PACKET setup; SMALLINT ret = 0; // check if Vpp available if (!USBVpp[portnum]) return FALSE; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevelUSB(portnum, MODE_NORMAL); // send the pulse (already enabled) setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_PULSE | COMM_IM | COMM_TYPE; setup.Index = 0; setup.Length = 0; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return FALSE; } else return TRUE; }
//-------------------------------------------------------------------------- // This procedure creates a fixed 480 microseconds 12 volt pulse // on the 1-Wire Net for programming EPROM iButtons. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE successful // FALSE program voltage not available // SMALLINT owProgramPulse(int portnum) { SETUP_PACKET setup; ULONG nOutput = 0; // check if Vpp available if (!USBVpp[portnum]) return FALSE; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevel(portnum, MODE_NORMAL); // send the pulse (already enabled) setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_PULSE | COMM_IM | COMM_TYPE; setup.Index = 0; 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 OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return FALSE; } else return TRUE; }
//--------------------------------------------------------------------------- // Attempt to acquire the specified 1-Wire net. // // 'port_zstr' - zero terminated port name. For this platform // use format 'DS2490-X' where X is the port number. // // Returns: port number or -1 if not successful in setting up the port. // int owAcquireEx(char *port_zstr) { int portnum = 0, portstringlength = 0, i = 0, ret = 0; int portnumfromstring; //character escape sequence //char portSubStr[] = "\\\\.\\DS2490-"; char portSubStr[] = "DS2490-"; char *retStr; char tempStr[4]; // initialize tempStr memset(&tempStr[0],0x00,4); // convert supplied string to uppercase for (i = 0;i < (int)strlen(port_zstr); i++) { port_zstr[i] = (char)toupper((char)port_zstr[i]); } // strip off portnumber from supplied string and put it in tempStr portstringlength = strlen(port_zstr) - strlen(&portSubStr[0]); // get port string length if ((portstringlength < 0) || (portstringlength > 3)) { // error portstring length can only be 3 characters (i.e., "0" to "999") OWERROR(OWERROR_PORTNUM_ERROR); return -1; } for (i=0;i<portstringlength;i++) // tempStr holds the "stripped" port number (as a string) { //tempStr[i] = port_zstr[i+11]; tempStr[i] = port_zstr[i + 7]; } // check the port string and grab the port number from it. retStr = strstr (port_zstr, &portSubStr[0]); // check for "DS2490-" if (retStr == NULL) { // error - owAcquire called with invalid port string OWERROR(OWERROR_PORTNUM_ERROR); return -1; } portnumfromstring = atoi(&tempStr[0]); if (portnumfromstring == 0) // port could be zero, so make an extra check befor failing { ret = memcmp(&tempStr[0],"0",1); if (ret != 0) { // error - portnum supplied is not numeric OWERROR(OWERROR_PORTNUM_ERROR); return -1; } } // set portnum to the one provided portnum = portnumfromstring; if(!usbhnd_init) // check to see the USB bus has been setup properly { // discover all DS2490s on USB bus... DS2490Discover(); usbhnd_init = 1; } // check to see if the portnumber is valid if ((usb_num_devices < portnum) || (portnum == 0)) { // error - Attempted to select invalid port number OWERROR(OWERROR_LIBUSB_NO_ADAPTER_FOUND); return -1; } // check to see if opening the device is valid if (usb_dev_handle_list[portnum] != NULL) { // error - USB Device already open OWERROR(OWERROR_LIBUSB_DEVICE_ALREADY_OPENED); return -1; } // open the device usb_dev_handle_list[portnum] = usb_open(usb_dev_list[portnum]); if (usb_dev_handle_list[portnum] == NULL) { // Failed to open usb device OWERROR(OWERROR_LIBUSB_OPEN_FAILED); return -1; } // set the configuration if (usb_set_configuration(usb_dev_handle_list[portnum], 1)) { // Failed to set configuration OWERROR(OWERROR_LIBUSB_SET_CONFIGURATION_ERROR); usb_close(usb_dev_handle_list[portnum]); // close handle return -1; } // claim the interface if (usb_claim_interface(usb_dev_handle_list[portnum], 0)) { // Failed to claim interface //printf("%s\n", usb_strerror()); OWERROR(OWERROR_LIBUSB_CLAIM_INTERFACE_ERROR); usb_close(usb_dev_handle_list[portnum]); // close handle return -1; } // set the alt interface if (usb_set_altinterface(usb_dev_handle_list[portnum], 3)) { // Failed to set altinterface //printf("%s\n", usb_strerror()); OWERROR(OWERROR_LIBUSB_SET_ALTINTERFACE_ERROR); usb_release_interface(usb_dev_handle_list[portnum], 0); // release interface usb_close(usb_dev_handle_list[portnum]); // close handle return -1; } // clear USB endpoints before doing anything with them. usb_clear_halt(usb_dev_handle_list[portnum], DS2490_EP3); usb_clear_halt(usb_dev_handle_list[portnum], DS2490_EP2); usb_clear_halt(usb_dev_handle_list[portnum], DS2490_EP1); // verify adapter is working if (!AdapterRecover(portnum)) { usb_release_interface(usb_dev_handle_list[portnum], 0); // release interface usb_close(usb_dev_handle_list[portnum]); // close handle return -1; } // reset the 1-Wire owTouchReset(portnum); return portnum; }
//-------------------------------------------------------------------------- // Read 1 bit of communication from the 1-Wire net and verify that the // response matches the 'applyPowerResponse' bit and apply power delivery // to the 1-Wire net. Note that some implementations may apply the power // first and then turn it off if the response is incorrect. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'applyPowerResponse' - 1 bit response to check, if correct then start // power delivery // // Returns: TRUE: bit written and response correct, strong pullup now on // FALSE: response incorrect // SMALLINT owReadBitPower(int portnum, SMALLINT applyPowerResponse) { SETUP_PACKET setup; ULONG nOutput = 0; WORD nBytes; BYTE buf[2]; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevel(portnum, MODE_NORMAL); // enable the strong pullup pulse setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_PULSE_EN; setup.Index = ENABLEPULSE_SPUE; setup.Length = 0x00; setup.DataOut = FALSE; // call the driver if (!DeviceIoControl(usbhnd[portnum], DS2490_IOCTL_VENDOR, &setup, sizeof(SETUP_PACKET), NULL, 0, &nOutput, NULL)) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return FALSE; } // set to do touchbit setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D; setup.Index = 0; 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 OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return FALSE; } else { // now strong pullup is enabled USBLevel[portnum] = MODE_STRONG5; // success, read the result nBytes = 1; if (DS2490Read(usbhnd[portnum], buf, &nBytes)) { // check response if (buf[0] != applyPowerResponse) { owLevel(portnum, MODE_NORMAL); return FALSE; } else return TRUE; } else { OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return FALSE; } } }
//-------------------------------------------------------------------------- // Set the 1-Wire Net line level. The values for new_level are // as follows: // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'new_level' - new level defined as // MODE_NORMAL 0x00 // MODE_STRONG5 0x02 // MODE_PROGRAM 0x04 (not supported in this version) // MODE_BREAK 0x08 (not supported in chip) // // Returns: current 1-Wire Net level // SMALLINT owLevel(int portnum, SMALLINT new_level) { SETUP_PACKET setup; ULONG nOutput = 0; // Turn off infinite strong pullup? if ((new_level == MODE_NORMAL) && (USBLevel[portnum] == MODE_STRONG5)) { if (DS2490HaltPulse(usbhnd[portnum])) USBLevel[portnum] = MODE_NORMAL; } // Turn on infinite strong5 pullup? else if ((new_level == MODE_STRONG5) && (USBLevel[portnum] == MODE_NORMAL)) { // assume duration set to infinite during setup of device // enable the pulse setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_PULSE_EN; setup.Index = ENABLEPULSE_SPUE; setup.Length = 0x00; setup.DataOut = FALSE; // call the driver if (!DeviceIoControl(usbhnd[portnum], DS2490_IOCTL_VENDOR, &setup, sizeof(SETUP_PACKET), NULL, 0, &nOutput, NULL)) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return USBLevel[portnum]; } // start the pulse setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_PULSE | COMM_IM; setup.Index = 0; 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 OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return USBLevel[portnum]; } else { // success, read the result USBLevel[portnum] = new_level; return new_level; } } // unsupported else if (new_level != USBLevel[portnum]) { OWERROR(OWERROR_FUNC_NOT_SUP); return USBLevel[portnum]; } // success, return the current level return USBLevel[portnum]; }
//-------------------------------------------------------------------------- // Read 1 bit of communication from the 1-Wire net and verify that the // response matches the 'applyPowerResponse' bit and apply power delivery // to the 1-Wire net. Note that some implementations may apply the power // first and then turn it off if the response is incorrect. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'applyPowerResponse' - 1 bit response to check, if correct then start // power delivery // // Returns: TRUE: bit written and response correct, strong pullup now on // FALSE: response incorrect // SMALLINT owReadBitPowerUSB(int portnum, SMALLINT applyPowerResponse) { SETUP_PACKET setup; ushort nBytes; uchar buf[2]; SMALLINT ret = 0; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevelUSB(portnum, MODE_NORMAL); // enable the strong pullup pulse setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_PULSE_EN; setup.Index = ENABLEPULSE_SPUE; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return FALSE; } // set to do touchbit setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D; setup.Index = 0; setup.Length = 0; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return FALSE; } else { // now strong pullup is enabled USBLevel[portnum] = MODE_STRONG5; // success, read the result nBytes = 1; if (DS2490Read(usb_dev_handle_list[portnum], buf, &nBytes)) { // check response if (buf[0] != applyPowerResponse) { owLevelUSB(portnum, MODE_NORMAL); return FALSE; } else return TRUE; } else { OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return FALSE; } } }
//-------------------------------------------------------------------------- // Set the 1-Wire Net line level. The values for new_level are // as follows: // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'new_level' - new level defined as // MODE_NORMAL 0x00 // MODE_STRONG5 0x02 // MODE_PROGRAM 0x04 (not supported in this version) // MODE_BREAK 0x08 (not supported in chip) // // Returns: current 1-Wire Net level // SMALLINT owLevelUSB(int portnum, SMALLINT new_level) { SETUP_PACKET setup; SMALLINT ret = 0; // Turn off infinite strong pullup? if ((new_level == MODE_NORMAL) && (USBLevel[portnum] == MODE_STRONG5)) { if (DS2490HaltPulse(usb_dev_handle_list[portnum])) USBLevel[portnum] = MODE_NORMAL; } // Turn on infinite strong5 pullup? else if ((new_level == MODE_STRONG5) && (USBLevel[portnum] == MODE_NORMAL)) { // assume duration set to infinite during setup of device // enable the pulse setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_PULSE_EN; setup.Index = ENABLEPULSE_SPUE; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return USBLevel[portnum]; } // start the pulse setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_PULSE | COMM_IM; setup.Index = 0; setup.Length = 0; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return USBLevel[portnum]; } else { // success, read the result USBLevel[portnum] = new_level; return new_level; } } // unsupported else if (new_level != USBLevel[portnum]) { OWERROR(OWERROR_FUNC_NOT_SUP); return USBLevel[portnum]; } // success, return the current level return USBLevel[portnum]; }
//-------------------------------------------------------------------------- // 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; }