//---------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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; }