//--------------------------------------------------------------------------- // Attempt to acquire a 1-Wire net using a com port and a DS2480 based // adapter. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'port_zstr' - zero terminated port name. For this platform // use format COMX where X is the port number. // 'return_msg' - zero terminated return message. // // Returns: TRUE - success, COM port opened // int owAcquire(int portnum, char *port_zstr, char *return_msg) { int cnt=0; portname[portnum][0] = 0; // attempt to open the communications port if (OpenCOM(portnum,port_zstr)) cnt += sprintf(&return_msg[cnt],"%s opened\n",port_zstr); else { cnt += sprintf(&return_msg[cnt],"Could not open port %s," " aborting.\nClosing port %s.\n",port_zstr,port_zstr); return FALSE; } // detect DS2480 if (DS2480Detect(portnum)) cnt += sprintf(&return_msg[cnt],"DS2480-based adapter detected\n"); else { cnt += sprintf(&return_msg[cnt],"DS2480-based adapter not detected, aborting program\n"); cnt += sprintf(&return_msg[cnt],"Closing port %s.\n",port_zstr); CloseCOM(portnum); return FALSE; } // success sprintf(portname[portnum],"%s",port_zstr); return TRUE; }
//-------------------------------------------------------------------------- // Set the MicroLAN communucation speed. // // 'NewSpeed' - new speed defined as // MODE_NORMAL 0x00 // MODE_OVERDRIVE 0x01 // // Returns: current MicroLAN speed // int MLanSpeed(int NewSpeed) { uchar sendpacket[5]; short sendlen=0; int rt = FALSE; // check if change from current mode if (((NewSpeed == MODE_OVERDRIVE) && (USpeed != SPEEDSEL_OD)) || ((NewSpeed == MODE_NORMAL) && (USpeed != SPEEDSEL_FLEX))) { if (NewSpeed == MODE_OVERDRIVE) { // if overdrive then switch to 115200 baud if (DS2480ChangeBaud(PARMSET_57600) == PARMSET_57600) { USpeed = SPEEDSEL_OD; rt = TRUE; } } else if (NewSpeed == MODE_NORMAL) { // else normal so set to 9600 baud if (DS2480ChangeBaud(PARMSET_9600) == PARMSET_9600) { USpeed = SPEEDSEL_FLEX; rt = TRUE; } } // if baud rate is set correctly then change DS2480 speed if (rt) { // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // proceed to set the DS2480 communication speed sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed; // send the packet if (!WriteCOM(sendlen,sendpacket)) { rt = FALSE; // lost communication with DS2480 then reset DS2480Detect(); } } } // return the current speed return (USpeed == SPEEDSEL_OD) ? MODE_OVERDRIVE : MODE_NORMAL; }
//-------------------------------------------------------------------------- // 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 was provided to // OpenCOM to indicate the port number. // // Returns: TRUE successful // FALSE program voltage not available // SMALLINT owProgramPulse(int portnum) { uchar sendpacket[10],readbuffer[10]; uchar sendlen=0; // check if programming voltage available if (!ProgramAvailable[portnum]) return FALSE; // make sure normal level owLevel(portnum,MODE_NORMAL); // check if correct mode if (UMode[portnum] != MODSEL_COMMAND) { UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // set the SPUD time value sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us; // pulse command sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE; // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the 2 byte response if (ReadCOM(portnum,2,readbuffer) == 2) { // check response byte if (((readbuffer[0] | CMD_CONFIG) == (CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us)) && ((readbuffer[1] & 0xFC) == (0xFC & (CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE)))) return TRUE; } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occurred so re-sync with DS2480 DS2480Detect(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 was provided to // OpenCOM to indicate the port number. // // Returns: TRUE(1): presense pulse(s) detected, device(s) reset // FALSE(0): no presense pulses detected // // WARNING: This routine will not function correctly on some // Alarm reset types of the DS1994/DS1427/DS2404 with // Rev 1,2, and 3 of the DS2480/DS2480B. // SMALLINT owTouchReset(int portnum) { uchar readbuffer[10],sendpacket[10]; uchar sendlen=0; // make sure normal level owLevel(portnum,MODE_NORMAL); // check if correct mode if (UMode[portnum] != MODSEL_COMMAND) { UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_RESET | USpeed[portnum]); // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(portnum,1,readbuffer) == 1) { // make sure this byte looks like a reset byte if (((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) || ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE)) { // check if programming voltage available ProgramAvailable[portnum] = ((readbuffer[0] & 0x20) == 0x20); return TRUE; } else OWERROR(OWERROR_RESET_FAILED); } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occurred so re-sync with DS2480 DS2480Detect(portnum); return FALSE; }
//-------------------------------------------------------------------------- // This procedure creates a fixed 480 microseconds 12 volt pulse // on the MicroLAN for programming EPROM iButtons. // // Returns: TRUE successful // FALSE program voltage not available // int MLanProgramPulse(void) { uchar sendpacket[10],readbuffer[10]; short sendlen=0; // check if programming voltage available if (!ProgramAvailable) return FALSE; // make sure normal level MLanLevel(MODE_NORMAL); // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // set the SPUD time value sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us; // pulse command sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE; // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 2 byte response if (ReadCOM(2,readbuffer) == 2) { // check response byte if (((readbuffer[0] | CMD_CONFIG) == (CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us)) && ((readbuffer[1] & 0xFC) == (0xFC & (CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE)))) return TRUE; } } // an error occured so re-sync with DS2480 DS2480Detect(); return FALSE; }
//-------------------------------------------------------------------------- // Send 1 bit of communication to the 1-Wire Net and return the // result 1 bit read from the 1-Wire Net. The parameter 'sendbit' // least significant bit is used and the least significant bit // of the result is the return bit. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'sendbit' - the least significant bit is the bit to send // // Returns: 0: 0 bit read from sendbit // 1: 1 bit read from sendbit // SMALLINT owTouchBit(int portnum, SMALLINT sendbit) { uchar readbuffer[10],sendpacket[10]; uchar sendlen=0; // make sure normal level owLevel(portnum,MODE_NORMAL); // check if correct mode if (UMode[portnum] != MODSEL_COMMAND) { UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen] = (sendbit != 0) ? BITPOL_ONE : BITPOL_ZERO; sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | USpeed[portnum]; // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the response if (ReadCOM(portnum,1,readbuffer) == 1) { // interpret the response if (((readbuffer[0] & 0xE0) == 0x80) && ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE)) return 1; else return 0; } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occurred so re-sync with DS2480 DS2480Detect(portnum); return 0; }
//-------------------------------------------------------------------------- // Reset all of the devices on the MicroLAN and return the result. // // Returns: TRUE(1): presense pulse(s) detected, device(s) reset // FALSE(0): no presense pulses detected // // WARNING: This routine will not function correctly on some // Alarm reset types of the DS1994/DS1427/DS2404 with // Rev 1 and 2 of the DS2480. // int MLanTouchReset(void) { uchar readbuffer[10],sendpacket[10]; int sendlen=0; // make sure normal level MLanLevel(MODE_NORMAL); // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_RESET | USpeed); // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(1,readbuffer) == 1) { // make sure this byte looks like a reset byte if (((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) || ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE)) { // check if programming voltage available ProgramAvailable = ((readbuffer[0] & 0x20) == 0x20); return TRUE; } else return FALSE; } } // an error occured so re-sync with DS2480 DS2480Detect(); return FALSE; }
//-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and return the // result 8 bits read from the 1-Wire Net. The parameter 'sendbyte' // least significant 8 bits are used and the least significant 8 bits // of the result is the return byte. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: 8 bits read from sendbyte // SMALLINT owTouchByte(int portnum, SMALLINT sendbyte) { uchar readbuffer[10],sendpacket[10]; uchar sendlen=0; // make sure normal level owLevel(portnum,MODE_NORMAL); // check if correct mode if (UMode[portnum] != MODSEL_DATA) { UMode[portnum] = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // add the byte to send sendpacket[sendlen++] = (uchar)sendbyte; // check for duplication of data that looks like COMMAND mode if (sendbyte ==(SMALLINT)MODE_COMMAND) sendpacket[sendlen++] = (uchar)sendbyte; // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(portnum,1,readbuffer) == 1) { // return the response return (int)readbuffer[0]; } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occurred so re-sync with DS2480 DS2480Detect(portnum); return 0; }
//--------------------------------------------------------------------------- // Attempt to acquire a 1-Wire net using a com port and a DS2480 based // adapter. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'port_zstr' - zero terminated port name. For this platform // use format COMX where X is the port number. // // Returns: TRUE - success, COM port opened // // exportable functions defined in ownetu.c SMALLINT owAcquire(int portnum, char *port_zstr) { // attempt to open the communications port if (OpenCOM(portnum,port_zstr) < 0) { OWERROR(OWERROR_OPENCOM_FAILED); return FALSE; } // detect DS2480 if (!DS2480Detect(portnum)) { CloseCOM(portnum); //OWERROR(OWERROR_DS2480_NOT_DETECTED); return FALSE; } return TRUE; }
//-------------------------------------------------------------------------- // Send 1 bit of communication to the MicroLAN and return the // result 1 bit read from the MicroLAN. The parameter 'sendbit' // least significant bit is used and the least significant bit // of the result is the return bit. // // 'sendbit' - the least significant bit is the bit to send // // Returns: 0: 0 bit read from sendbit // 1: 1 bit read from sendbit // int MLanTouchBit(int sendbit) { uchar readbuffer[10],sendpacket[10]; int sendlen=0; // make sure normal level MLanLevel(MODE_NORMAL); // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen] = (sendbit != 0) ? BITPOL_ONE : BITPOL_ZERO; sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | USpeed; // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the response if (ReadCOM(1,readbuffer) == 1) { // interpret the response if (((readbuffer[0] & 0xE0) == 0x80) && ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE)) return 1; else return 0; } } // an error occured so re-sync with DS2480 DS2480Detect(); return 0; }
//-------------------------------------------------------------------------- // Send 8 bits of communication to the MicroLAN and return the // result 8 bits read from the MicroLAN. The parameter 'sendbyte' // least significant 8 bits are used and the least significant 8 bits // of the result is the return byte. // // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: 8 bytes read from sendbyte // int MLanTouchByte(int sendbyte) { uchar readbuffer[10],sendpacket[10]; int sendlen=0; // make sure normal level MLanLevel(MODE_NORMAL); // check if correct mode if (UMode != MODSEL_DATA) { UMode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // add the byte to send sendpacket[sendlen++] = (uchar)sendbyte; // check for duplication of data that looks like COMMAND mode if (sendbyte == MODE_COMMAND) sendpacket[sendlen++] = (uchar)sendbyte; // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(1,readbuffer) == 1) { // return the response return (int)readbuffer[0]; } } // an error occured so re-sync with DS2480 DS2480Detect(); return 0; }
//--------------------------------------------------------------------------- // Attempt to acquire a 1-Wire net using a com port and a DS2480 based // adapter. // // 'port_zstr' - zero terminated port name. For this platform // use format COMX where X is the port number. // // Returns: valid handle, or -1 if an error occurred // // exportable functions defined in ownetu.c // int owAcquireEx(char *port_zstr) { int portnum; // attempt to open the communications port if ((portnum = OpenCOMEx(port_zstr)) < 0) { OWERROR(OWERROR_OPENCOM_FAILED); return -1; } // detect DS2480 if (!DS2480Detect(portnum)) { CloseCOM(portnum); OWERROR(OWERROR_DS2480_NOT_DETECTED); return -1; } return portnum; }
//-------------------------------------------------------------------------- // Set the MicroLAN line level. The values for NewLevel are // as follows: // // 'NewLevel' - new level defined as // MODE_NORMAL 0x00 // MODE_STRONG5 0x02 // MODE_PROGRAM 0x04 // MODE_BREAK 0x08 (not supported) // // Returns: current MicroLAN level // int MLanLevel(int NewLevel) { uchar sendpacket[10],readbuffer[10]; short sendlen=0; short rt=FALSE; // check if need to change level if (NewLevel != ULevel) { // check if just putting back to normal if (NewLevel == MODE_NORMAL) { // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // stop pulse command sendpacket[sendlen++] = MODE_STOP_PULSE; // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(1,readbuffer) == 1) { // check response byte if ((readbuffer[0] & 0xE0) == 0xE0) { rt = TRUE; ULevel = MODE_NORMAL; } } } } // set new level else { // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // strong 5 volts if (NewLevel == MODE_STRONG5) { // set the SPUD time value sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite; // add the command to begin the pulse sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V; } // 12 volts else if (NewLevel == MODE_PROGRAM) { // check if programming voltage available if (!ProgramAvailable) return MODE_NORMAL; // set the PPD time value sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_infinite; // add the command to begin the pulse sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_12V; } // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response from setting time limit if (ReadCOM(1,readbuffer) == 1) { // check response byte if ((readbuffer[0] & 0x81) == 0) { ULevel = NewLevel; rt = TRUE; } } } } // if lost communication with DS2480 then reset if (rt != TRUE) DS2480Detect(); } // return the current level return ULevel; }
//-------------------------------------------------------------------------- // Set the 1-Wire Net communucation speed. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the 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) { uchar sendpacket[5]; uchar sendlen=0; uchar rt = FALSE; // check if change from current mode if (((new_speed == MODE_OVERDRIVE) && (USpeed[portnum] != SPEEDSEL_OD)) || ((new_speed == MODE_NORMAL) && (USpeed[portnum] != SPEEDSEL_FLEX))) { if (new_speed == MODE_OVERDRIVE) { // if overdrive then switch to 115200 baud if (DS2480ChangeBaud(portnum,PARMSET_115200) == PARMSET_115200) { USpeed[portnum] = SPEEDSEL_OD; rt = TRUE; } } else if (new_speed == MODE_NORMAL) { // else normal so set to 9600 baud if (DS2480ChangeBaud(portnum,PARMSET_9600) == PARMSET_9600) { USpeed[portnum] = SPEEDSEL_FLEX; rt = TRUE; } } // if baud rate is set correctly then change DS2480 speed if (rt) { // check if correct mode if (UMode[portnum] != MODSEL_COMMAND) { UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // proceed to set the DS2480 communication speed sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum]; // send the packet if (!WriteCOM(portnum,sendlen,sendpacket)) { OWERROR(OWERROR_WRITECOM_FAILED); rt = FALSE; // lost communication with DS2480 then reset DS2480Detect(portnum); } } } // return the current speed return (USpeed[portnum] == SPEEDSEL_OD) ? MODE_OVERDRIVE : MODE_NORMAL; }
//-------------------------------------------------------------------------- // 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; }