//---------------------------------------------------------------------- // Perform a overdrive MATCH command to select the 1-Wire device with // the address in the ID data register. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE: If the device is present on the 1-Wire Net and // can do overdrive then the device is selected. // FALSE: Device is not present or not capable of overdrive. // // *Note: This function could be converted to send DS2480 // commands in one packet. // BYTE owOverdriveAccess(BYTE portnum) { BYTE sendpacket[8]; BYTE i, bad_echo = FALSE; owSetCurrentPort(portnum); // make sure normal level owLevel(owCurrentPortnum, MODE_NORMAL); // force to normal communication speed owSpeed(owCurrentPortnum, MODE_NORMAL); // call the 1-Wire Net reset function if(owTouchReset(owCurrentPortnum)) { // send the match command 0x69 if(owWriteByte(owCurrentPortnum, 0x69)) { // switch to overdrive communication speed owSpeed(owCurrentPortnum, MODE_OVERDRIVE); // create a buffer to use with block function // Serial Number for(i = 0; i < 8; i++) { sendpacket[i] = owNetCurrent.SerialNum[i]; } // send/recieve the transfer buffer if(owBlock(owCurrentPortnum, FALSE, sendpacket,8)) { // verify that the echo of the writes was correct for(i = 0; i < 8; i++) { if(sendpacket[i] != owNetCurrent.SerialNum[i]) { bad_echo = TRUE; } } // if echo ok then success if(!bad_echo) { return TRUE; } else { OWERROR(OWERROR_WRITE_VERIFY_FAILED); } } else { OWERROR(OWERROR_BLOCK_FAILED); } } else { OWERROR(OWERROR_WRITE_BYTE_FAILED); } } else { OWERROR(OWERROR_NO_DEVICES_ON_NET); } // failure, force back to normal communication speed owSpeed(owCurrentPortnum, MODE_NORMAL); return FALSE; }
//-------------------------------------------------------------------------- // The 'owAccess' function resets the 1-Wire and sends a MATCH Serial // Number command followed by the current SerialNum code. After this // function is complete the 1-Wire device is ready to accept device-specific // commands. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE (1) : reset indicates present and device is ready // for commands. // FALSE (0): reset does not indicate presence or echos 'writes' // are not correct. // BYTE owAccess(BYTE portnum) { BYTE sendpacket[9]; BYTE i; owSetCurrentPort(portnum); // reset the 1-wire if(owTouchReset(owCurrentPortnum)) { // create a buffer to use with block function // match Serial Number command 0x55 sendpacket[0] = 0x55; // Serial Number for(i = 1; i < 9; i++) { sendpacket[i] = owNetCurrent.SerialNum[i-1]; } // send/recieve the transfer buffer if(owBlock(owCurrentPortnum, FALSE, sendpacket, 9)) { // verify that the echo of the writes was correct for(i = 1; i < 9; i++) { if(sendpacket[i] != owNetCurrent.SerialNum[i-1]) { return FALSE; } if(sendpacket[0] != 0x55) { OWERROR(OWERROR_WRITE_VERIFY_FAILED); return FALSE; } else { return TRUE; } } } else { OWERROR(OWERROR_BLOCK_FAILED); } } else { OWERROR(OWERROR_NO_DEVICES_ON_NET); } // reset or match echo failed return FALSE; }
//-------------------------------------------------------------------------- // The 'owAccess' function resets the 1-Wire and sends a MATCH Serial // Number command followed by the current SerialNum code. After this // function is complete the 1-Wire device is ready to accept device-specific // commands. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // // Returns: TRUE (1) : reset indicates present and device is ready // for commands. // FALSE (0): reset does not indicate presence or echos 'writes' // are not correct. // SMALLINT owAccess(int portnum) { uchar sendpacket[9]; uchar i; // reset the 1-wire if (owTouchReset(portnum)) { // create a buffer to use with block function // match Serial Number command 0x55 sendpacket[0] = 0x55; // Serial Number for (i = 1; i < 9; i++) sendpacket[i] = SerialNum[portnum][i-1]; // send/recieve the transfer buffer if (owBlock(portnum,FALSE,sendpacket,9)) { // verify that the echo of the writes was correct for (i = 1; i < 9; i++) if (sendpacket[i] != SerialNum[portnum][i-1]) return FALSE; if (sendpacket[0] != 0x55) { OWERROR(OWERROR_WRITE_VERIFY_FAILED); return FALSE; } else return TRUE; } else OWERROR(OWERROR_BLOCK_FAILED); } else OWERROR(OWERROR_NO_DEVICES_ON_NET); // reset or match echo failed return FALSE; }
//---------------------------------------------------------------------- // This is the Main routine for swtmain1c // int main(short argc, char **argv) { char msg[200]; uchar data[256]; int portnum = 0; int n=0; int addr = 0; int len; uchar es = 0x00; uchar address[2]; ushort i; uchar sn[8],state[3], reg[3], send_block[37]; uchar family[2][8]; int done=FALSE; int channel=0,send_cnt=0; SMALLINT alternate=TRUE, alt=FALSE; ushort lastcrc16; uchar latch, set; uchar check; // check for required port name if (argc != 2) { sprintf(msg,"1-Wire Net name required on command line!\n" " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" " "(Linux DS2480),\"1\" (Win32 TMEX)\n"); printf("%s",msg); return 0; } if((portnum = owAcquireEx(argv[1])) < 0) { printf("Did not Acquire port.\n",1); exit(1); } else { if(FindDevices(portnum,&family[0],0x1C,1)) { for(i=0;i<8;i++) sn[i] = family[0][i]; printf("device found: "); for(i=0;i<8;i++) printf("%02X ",sn[i]); printf("\n"); do { printf("PICK AN OPERATION:\n\n"); printf("(1) Read Channel state\n"); // Gives channel information printf("(2) Set Channel On/Off\n"); // Sets channel printf("(3) Read Channel Mask\n"); // Read Selection Mask printf("(4) Set Channel mask\n"); // Sets channel mask printf("(5) Read Channel Polarity\n"); // Read Polarity Selection printf("(6) Set Channel polarity\n"); // sets channel polarity printf("(7) Read Control/Status Register\n"); // Read Control/Status Reg printf("(8) Set Reset Mode On/Off\n"); // Set Reset Mode printf("(9) Clear Power on Reset\n"); // Clear Power on reset printf("(10) Get VCC state\n"); // Get VCC state printf("(11) Set OR conditional search\n"); // or condition search printf("(12) Set AND conditional search\n"); // and condition search printf("(13) Write Scratchpad\n"); // write scratchpad command printf("(14) Read Scratchpad\n"); // read scratchpad command printf("(15) Copy Scratchpad\n"); // copy scratchpad command printf("(16) Read Memory\n"); // read memory printf("(17) PIO access read with CRC confirmation\n"); // access read printf("(18) LED test\n"); // LED test printf("(19) QUIT\n"); scanf("%d",&n); if(n == 19) { n = 0; //used to finish off the loop done = TRUE; break; } switch(n) { case 1: // Channel Info printf("\nEnter the channel\n"); scanf("%d",&channel); if(readSwitch1C(portnum,&sn[0],&state[0])) { printf("The channel is "); if(getLatchState1C(channel,&state[0])) printf("on.\n"); else printf("off\n"); printf("The Level is "); if(getLevel1C(channel,&state[0])) printf("high.\n"); else printf("low.\n"); if(getSensedActivity1C(channel,&state[0])) printf("Activity was detected on the channel.\n\n"); else printf("No activity was detected on the channel.\n\n"); } else OWERROR_DUMP(stdout); break; case 2: // Sets channel printf("\nEnter the channel\n"); scanf("%d",&channel); printf("Turn channel off enter 0, on 1.\n"); scanf("%d",&set); if(setLatchState1C(portnum,&sn[0],channel,set)) { printf("Latch was set "); if(set) printf("on.\n"); else printf("off.\n"); } else OWERROR_DUMP(stdout); break; case 3: // Read Selection Mask printf("\nEnter the channel\n"); scanf("%d",&channel); if(readRegister1C(portnum,&sn[0],®[0])) { printf("register is %02X %02X %02X\n",reg[0],reg[1],reg[2]); printf("The Selection Mask for channel %d is ",channel); latch = (uchar) (0x01 << channel); if((reg[0] & latch) == latch) printf("set.\n\n"); else printf("not set.\n\n"); } else OWERROR_DUMP(stdout); break; case 4: // Sets channel mask printf("\nEnter the channel\n"); scanf("%d",&channel); printf("Turn channel mask off enter 0, on 1.\n"); scanf("%d",&set); if(setChannelMask1C(portnum,&sn[0],channel,set)) { printf("The mask for channel %d was set ",channel); if(set) printf("on.\n\n"); else printf("off.\n\n"); } else OWERROR_DUMP(stdout); break; case 5: // Read Polarity Selection printf("\nEnter the channel\n"); scanf("%d",&channel); printf("The Polarity for channel %d is ",channel); if(getChannelPolarity1C(portnum,&sn[0],channel)) printf("set.\n\n"); else printf("not set.\n\n"); break; case 6: // sets channel polarity printf("\nEnter the channel\n"); scanf("%d",&channel); printf("Turn channel polarity off enter 0, on 1.\n"); scanf("%d",&set); if(setChannelPolarity1C(portnum,&sn[0],channel,set)) { printf("The polarity for channel %d was set ",channel); if(set) printf("on.\n\n"); else printf("off.\n\n"); } else OWERROR_DUMP(stdout); break; case 7: // Read Control/Status Reg if(readRegister1C(portnum,&sn[0],®[0])) printf("The Constrol/Status register is as following in hex %02X\n\n", reg[2]); else OWERROR_DUMP(stdout); break; case 8: // Set Reset Mode printf("Turn reset mode off enter 0, on 1.\n"); scanf("%d",&set); if(setResetMode1C(portnum,&sn[0],set)) { printf("Reset Mode was turned "); if(set) printf("on.\n\n"); else printf("off.\n\n"); } else OWERROR_DUMP(stdout); break; case 9: // Clear Power on reset if(clearPowerOnReset1C(portnum,&sn[0])) printf("Power on reset was cleared.\n\n"); else OWERROR_DUMP(stdout); break; case 10: // Get VCC state if(readRegister1C(portnum,&sn[0],®[0])) { printf("VCC state register is %02X\n",reg[2]); if(getVCC1C(®[0])) printf("VCC is powered.\n\n"); else printf("VCC is grounded.\n\n"); } else OWERROR_DUMP(stdout); break; case 11: // or condition search if(orConditionalSearch1C(portnum,&sn[0])) printf("OR condition search was set.\n\n"); else OWERROR_DUMP(stdout); break; case 12: // and condition search if(andConditionalSearch1C(portnum,&sn[0])) printf("AND condition search was set.\n\n"); else OWERROR_DUMP(stdout); break; case 13: // write scratchpad printf("Enter the address to start writing: "); addr = getNumber(0, 550); if(menuSelect(&sn[0]) == MODE_TEXT) len = getData(data,MAX_LEN,MODE_TEXT); else len = getData(data,MAX_LEN,MODE_HEX); if(!writeScratch1C(portnum,&sn[0],addr,len,&data[0])) OWERROR_DUMP(stdout); break; case 14: // read scratchpad if(!readScratch1C(portnum,&sn[0],&len,&es,&address[0],&data[0])) { printf("error\n"); OWERROR_DUMP(stdout); } else { printf("Address bytes: %02X %02X\n",address[0],address[1]); printf("ES byte: %02X\n",es); printf("Length: %d\n",len); printf("Scratchpad data: "); for(i=0;i<len;i++) printf("%02X ",data[i]); printf("\n"); } break; case 15: // copy scratchpad if(!copyScratch1C(portnum,&sn[0])) { OWERROR_DUMP(stdout); } else { printf("Copy Scratchpad Complete.\n"); } break; case 16: // read memory printf("Enter the address to start reading: "); addr = getNumber(0, 550); printf("Enter the length you want to read: "); len = getNumber(0,256); if(!read1C(portnum,&sn[0],addr,len,&data[0])) { OWERROR_DUMP(stdout); } else { for(i=0;i<len;i++) printf("%02X ",data[i]); printf("\n"); } break; case 17: // and condition search if (!owTouchReset(portnum)) OWERROR_DUMP(stdout); if(!owWriteByte(portnum,0xCC)) printf("skip rom error.\n"); owWriteByte(portnum,0xF5); for(i=0;i<34;i++) send_block[send_cnt++] = 0xFF; if(!owBlock(portnum,FALSE,&send_block[0],send_cnt)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } setcrc16(portnum,0); lastcrc16 = docrc16(portnum,0xF5); for(i=0;i<34;i++) lastcrc16 = docrc16(portnum,send_block[i]); if(lastcrc16 != 0xB001) printf("CRC didn't match.\n"); printf("read data: "); for(i=0;i<34;i++) printf("%02X ",send_block[i]); printf("\n"); send_cnt = 0; for(i=0;i<34;i++) send_block[send_cnt++] = 0xFF; if(!owBlock(portnum,FALSE,&send_block[0],send_cnt)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } setcrc16(portnum,0); for(i=0;i<34;i++) lastcrc16 = docrc16(portnum,send_block[i]); if(lastcrc16 != 0xB001) printf("CRC2 didn't match.\n"); printf("read data2: "); for(i=0;i<34;i++) printf("%02X ",send_block[i]); printf("\n"); send_cnt = 0; for(i=0;i<34;i++) send_block[send_cnt++] = 0xFF; if(!owBlock(portnum,FALSE,&send_block[0],send_cnt)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } setcrc16(portnum,0); for(i=0;i<34;i++) lastcrc16 = docrc16(portnum,send_block[i]); if(lastcrc16 != 0xB001) printf("CRC3 didn't match.\n"); printf("read data3: "); for(i=0;i<34;i++) printf("%02X ",send_block[i]); printf("\n"); break; case 18: // LED test printf("\nEnter the channel to turn the LED on.\n"); scanf("%d",&channel); printf("Turn reset mode off enter 1, on 0.\n"); scanf("%d",&set); printf("Alternate on and off 0=No, 1=Yes.\n"); scanf("%d",&alternate); if (!owTouchReset(portnum)) OWERROR_DUMP(stdout); if(!owWriteByte(portnum,0xCC)) printf("skip rom error.\n"); owWriteByte(portnum,0x5A); for(i=0;i<256;i++) { if(channel == 0) { if(set == 0) { if(!alternate) { if(!owWriteByte(portnum,0xFE)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x01)) printf("write byte error.\n"); check = 0xFE; } else { if(alt) { if(!owWriteByte(portnum,0xFE)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x01)) printf("write byte error.\n"); check = 0xFE; alt = FALSE; } else { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; alt = TRUE; } } } else { if(!alternate) { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; } else { if(alt) { if(!owWriteByte(portnum,0xFE)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x01)) printf("write byte error.\n"); check = 0xFE; alt = FALSE; } else { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; alt = TRUE; } } } } else { if(set == 0) { if(!alternate) { if(!owWriteByte(portnum,0xFD)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x02)) printf("write byte error.\n"); check = 0xFD; } else { if(alt) { if(!owWriteByte(portnum,0xFD)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x02)) printf("write byte error.\n"); check = 0xFD; alt = FALSE; } else { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; alt = TRUE; } } } else { if(!alternate) { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; } else { if(alt) { if(!owWriteByte(portnum,0xFD)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x02)) printf("write byte error.\n"); check = 0xFD; alt = FALSE; } else { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; alt = TRUE; } } } } send_block[0] = (uchar)owReadByte(portnum); send_block[1] = (uchar)owReadByte(portnum); if((send_block[0] != 0xAA) && (send_block[1] != check)) printf("confirmation byte was %02X and read back was %02X\n", send_block[0],send_block[1]); } default: break; } }while(!done); } else printf("DS28E04 not found on One Wire Network\n"); owRelease(portnum); } return 1; }
//--------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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 program volatage available // FALSE program voltage not available // SMALLINT owHasProgramPulse(int portnum) { owTouchReset(portnum); return USBVpp[portnum]; }
//---------------------------------------------------------------------- // Family 0x10 Demo // void main(void) { int temp; int sign; BYTE i; //---------------------------------------- ADCON1 = 0x07; // PortB digital bTRD6 = 1; // RD6 = Serial Input bTRD7 = 0; // RD7 = Serial Output bLD7 = 1; printf("\nFamily 0x10 Demo\n%"); //////////////////////////////////////////////////////////// // Initialise the OneWire network (bus) // attempt to acquire the 1-Wire Nets if (!owAcquire(0, NULL)) { printf("Acquire failed.\n%"); while(1) ; } //////////////////////////////////////////////////////////// // Let's set the alarmtemps of all devices on the bus. // To demonstrate this, we write a low alarmtemp of 19 // and a high alarmtemp of 21 to all devices. // Finally we copy the alarmtemps to non-volatile EEPROM. printf("\nStart - Set AlarmTemperatures.\n%"); // Reset the devices owTouchReset(0); // Address all devices on the net owWriteByte(0, OW_SKIPROM); // Use the WriteScratchpad command to set AlarmTemps owWriteByte(0, OW_WRITESCRATCHPAD); owWriteByte(0, 19); // Valid RoomTemperature owWriteByte(0, 21); // 19 <= Temp < 21 printf("End - Set AlarmTemperatures.\n%"); // Set alarmtemps done // Copy the temps to EEPROM printf("\nStart - Write AlarmTemperatures to EEPROM.\n%"); // Reset the devices owTouchReset(0); // Address all devices on the net owWriteByte(0, OW_SKIPROM); // send the CopyScratchpad command to copy the AlarmTemps to EEPROM // If the bus supports Strong PullUp, we use it (because // there might be parasite powered devices on this bus). if(owHasPowerDelivery(0)) { printf("The bus has a Strong PullUp\n%"); owWriteBytePower(0, OW_COPYSCRATCHPAD); // Eeprom update takes 10 milliseconds max. 11ms is safer Wait(11); // turn off the strong pull-up owLevel(0, MODE_NORMAL); } else { printf("The bus has NO Strong PullUp\n%"); owWriteByte(0, OW_COPYSCRATCHPAD); // Eeprom update takes 10 milliseconds max. 11ms is safer Wait(11); } printf("End - Write AlarmTemperatures to EEPROM.\n%"); // Copy the temps to EEPROM done while(1) { //////////////////////////////////////////////////////////// // We do a temp conversion on all DS18S20's printf("\nStart - TemperatureConversions\n%"); // Reset the devices owTouchReset(0); // Address all devices on this net owWriteByte(0, OW_SKIPROM); // Send the convert command and start power delivery if available. // Note that we use a different way here to determine // Strong PullUp capability. if(owWriteBytePower(0, OW_CONVERTT)) { printf("We are using a Strong PullUp.\n%"); } else { printf("No Strong PullUp configured.\n%"); owWriteByte(0, OW_CONVERTT); } // Coversion takes 750 milliseconds max. 751ms is safer Wait(751); // turn off the 1-Wire Net strong pull-up owLevel(0, MODE_NORMAL); printf("End - TemperatureConversions\n%"); //////////////////////////////////////////////////////////// // We will now demonstrate an alarmsearch printf("\nStart - Find devices in alarmstate\n%"); // Find the devices with temp < 19 or temp >= 21 if(!owFirst(0, TRUE, TRUE)) { printf("No devices in AlarmState found.\n%"); } else { do { printf("Device in AlarmState found: 0x%02X%02X%02X%02X%02X%02X%02X%02X\n%", owNetCurrent.SerialNum[7], owNetCurrent.SerialNum[6], owNetCurrent.SerialNum[5], owNetCurrent.SerialNum[4], owNetCurrent.SerialNum[3], owNetCurrent.SerialNum[2], owNetCurrent.SerialNum[1], owNetCurrent.SerialNum[0]); } while(owNext(0, TRUE, TRUE)); } printf("End - Find devices in alarmstate\n%"); //////////////////////////////////////////////////////////// // We will now demonstrate a normal search. For // every device found, it's temperature is retrieved. printf("\nStart - Find devices and get their temperatures.\n%"); if(!owFirst(0, TRUE, FALSE)) { printf("No devices found.\n%"); } else { do { printf("Device found: 0x%02X%02X%02X%02X%02X%02X%02X%02X%", owNetCurrent.SerialNum[7], owNetCurrent.SerialNum[6], owNetCurrent.SerialNum[5], owNetCurrent.SerialNum[4], owNetCurrent.SerialNum[3], owNetCurrent.SerialNum[2], owNetCurrent.SerialNum[1], owNetCurrent.SerialNum[0]); // Init the crc setcrc8(0, 0); // Read the device's memory owWriteByte(0, OW_READSCRATCHPAD); for(i = 0; i < SCRATCHPAD_SIZE; i++) { ScratchPad[i] = owReadByte(0); docrc8(0, ScratchPad[i]); } // Check the CRC if(owNetCurrent.utilcrc8 != 0) { printf(", crc is NOT OK.\n%"); } else { // We don't want to use float's temp = ((int)ScratchPad[SCRATCHPAD_TEMPERATUREMSB] << 8) | (int)ScratchPad[SCRATCHPAD_TEMPERATURELSB]; if(temp < 0) { temp = -temp; sign = '-'; } else if(temp == 0) { sign = ' '; } else { sign = '+'; } printf(", Temperature is %c%d.%d degrees\n%", sign, (temp >> 1), (temp & 0x01) ? 5 : 0); } } while(owNext(0, TRUE, FALSE)); } printf("End - Find devices and get their temperatures.\n%"); //////////////////////////////////////////////////////////// Wait(1); // Just a convenient way to set a breakpoint } }
//------------------------------------------------------------------------- // Select the current device and attempt overdrive if possible. Usable // for both DS1963S and DS1961S. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Return: TRUE - device selected // FALSE - device not select // SMALLINT SelectSHA(int portnum) { int rt,cnt=0; #ifdef __MC68K__ // Used in when overdrive isn't...Used owVerify for overdrive rt = owAccess(portnum); #else //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP uchar ROM[8]; int i, mcnt; char msg[255]; owSerialNum(portnum,ROM, TRUE); mcnt = sprintf(msg,"\n Device select "); for (i = 0; i < 8; i++) mcnt += sprintf(msg + mcnt, "%02X",ROM[i]); mcnt += sprintf(msg + mcnt,"\n"); printf("%s",msg); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // loop to access the device and optionally do overdrive do { rt = owVerify(portnum,FALSE); // check not present if (rt != 1) { // if in overdrive, drop back if (in_overdrive[portnum&0x0FF]) { // set to normal speed if(MODE_NORMAL == owSpeed(portnum,MODE_NORMAL)) in_overdrive[portnum&0x0FF] = FALSE; } } // present but not in overdrive else if (!in_overdrive[portnum&0x0FF]) { // put all devices in overdrive if (owTouchReset(portnum)) { if (owWriteByte(portnum,0x3C)) { // set to overdrive speed if(MODE_OVERDRIVE == owSpeed(portnum,MODE_OVERDRIVE)) in_overdrive[portnum&0x0FF] = TRUE; } } rt = 0; } else break; } while ((rt != 1) && (cnt++ < 3)); #endif return rt; }
//---------------------------------------------------------------------- // Main AlarmSearch Test // void main(void) { BYTE portnum; //---------------------------------------- ADCON1 = 0x07; // PortB digital bTRD6 = 1; // RD6 = Serial Input bTRD7 = 0; // RD7 = Serial Output bLD7 = 1; printf("\nEnumeration (AlarmSearch) test\n%"); // Initialise the OneWire nets and the temperature devices for(portnum = 0; portnum < MAX_PORTNUM; portnum++) { // attempt to acquire the 1-Wire Nets if (!owAcquire(portnum,NULL)) { printf("Acquire failed for OneWire net %d.\n%", portnum); } else { // Reset the devices owTouchReset(portnum); // Address all devices on this net owWriteByte(portnum, OW_SKIPROM); // send the WriteScratchpad command to set AlarmTemps owWriteByte(portnum, OW_WRITESCRATCHPAD); owWriteByte(portnum, 19); // Valid RoomTemperature owWriteByte(portnum, 21); // 19 <= Temp < 21 } } while(1) { // Do a temp conversion on all DS18S20's on all nets simultanously for(portnum = 0; portnum < MAX_PORTNUM; portnum++) { // Reset the devices owTouchReset(portnum); // Address all devices on this net owWriteByte(portnum, OW_SKIPROM); // send the convert command and start power delivery if(!owWriteBytePower(portnum, OW_CONVERTT)) { printf("\nNo Strong PullUp on net %d. Trying without SPU.\n%", portnum); owWriteByte(portnum, OW_CONVERTT); } } // Conversion takes 750 milliseconds max. Safer is 751ms Wait(751); // turn off the 1-Wire Net strong pull-up for(portnum = 0; portnum < MAX_PORTNUM; portnum++) { owLevel(portnum, MODE_NORMAL); } for(portnum = 0; portnum < MAX_PORTNUM; portnum++) { // Find the device(s) in AlarmState printf("\nEnumeration for net %d.\n%", portnum); if(!owFirst(portnum, TRUE, TRUE)) { printf("No devices in AlarmState found on this net.\n%"); } else { do { printf("Device in AlarmState found: 0x%02X%02X%02X%02X%02X%02X%02X%02X\n%", owNetCurrent.SerialNum[7], owNetCurrent.SerialNum[6], owNetCurrent.SerialNum[5], owNetCurrent.SerialNum[4], owNetCurrent.SerialNum[3], owNetCurrent.SerialNum[2], owNetCurrent.SerialNum[1], owNetCurrent.SerialNum[0]); } while(owNext(portnum, TRUE, TRUE)); } } Wait(10); // Just a convenient way to set a breakpoint } }
//-------------------------------------------------------------------------- // 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) { uchar bit_test, search_direction, bit_number; uchar last_zero, serial_byte_number, next_result; uchar serial_byte_mask; uchar lastcrc8; // initialize for search bit_number = 1; last_zero = 0; serial_byte_number = 0; serial_byte_mask = 1; next_result = 0; setcrc8(portnum,0); // if the last call was not the last one if (!LastDevice[portnum]) { // 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)) { // printf("owTouchReset failed\r\n"); // reset the search LastDiscrepancy[portnum] = 0; LastFamilyDiscrepancy[portnum] = 0; OWERROR(OWERROR_NO_DEVICES_ON_NET); return FALSE; } } // If finding alarming devices issue a different command if (alarm_only) owWriteByte(portnum,0xEC); // issue the alarming search command else owWriteByte(portnum,0xF0); // issue the search command //pause before beginning the search //usDelay(100); // loop to do the search do { // read a bit and its compliment bit_test = owTouchBit(portnum,1) << 1; bit_test |= owTouchBit(portnum,1); // check for no devices on 1-wire if (bit_test == 3) break; else { // all devices coupled have 0 or 1 if (bit_test > 0) search_direction = !(bit_test & 0x01); // bit write value for search else { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (bit_number < LastDiscrepancy[portnum]) search_direction = ((SerialNum[portnum][serial_byte_number] & serial_byte_mask) > 0); else // if equal to last pick 1, if not then pick 0 search_direction = (bit_number == LastDiscrepancy[portnum]); // if 0 was picked then record its position in LastZero if (search_direction == 0) { last_zero = bit_number; // check for Last discrepancy in family if (last_zero < 9) LastFamilyDiscrepancy[portnum] = last_zero; } } // set or clear the bit in the SerialNum[portnum] byte serial_byte_number // with mask serial_byte_mask if (search_direction == 1) SerialNum[portnum][serial_byte_number] |= serial_byte_mask; else SerialNum[portnum][serial_byte_number] &= ~serial_byte_mask; // serial number search direction write bit owTouchBit(portnum,search_direction); // increment the byte counter bit_number // and shift the mask serial_byte_mask bit_number++; serial_byte_mask <<= 1; // if the mask is 0 then go to new SerialNum[portnum] byte serial_byte_number // and reset mask if (serial_byte_mask == 0) { // The below has been added to accomidate the valid CRC with the // possible changing serial number values of the DS28E04. if (((SerialNum[portnum][0] & 0x7F) == 0x1C) && (serial_byte_number == 1)) lastcrc8 = docrc8(portnum,0x7F); else lastcrc8 = docrc8(portnum,SerialNum[portnum][serial_byte_number]); // accumulate the CRC serial_byte_number++; serial_byte_mask = 1; } } } while(serial_byte_number < 8); // loop until through all SerialNum[portnum] bytes 0-7 // if the search was successful then if (!((bit_number < 65) || lastcrc8)) { // search successful so set LastDiscrepancy[portnum],LastDevice[portnum],next_result LastDiscrepancy[portnum] = last_zero; LastDevice[portnum] = (LastDiscrepancy[portnum] == 0); next_result = TRUE; } } // if no device found then reset counters so next 'next' will be // like a first if (!next_result || !SerialNum[portnum][0]) { LastDiscrepancy[portnum] = 0; LastDevice[portnum] = FALSE; LastFamilyDiscrepancy[portnum] = 0; next_result = FALSE; } return next_result; }
//-------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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. // BYTE owNext(BYTE portnum, BYTE do_reset, BYTE alarm_only) { BYTE bit_test, search_direction, bit_number; BYTE last_zero, serial_byte_number, next_result; BYTE serial_byte_mask; BYTE lastcrc8; owSetCurrentPort(portnum); // initialize for search bit_number = 1; last_zero = 0; serial_byte_number = 0; serial_byte_mask = 1; next_result = 0; setcrc8(portnum, 0); // if the last call was not the last one if(!owNetCurrent.LastDevice) { // 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(owCurrentPortnum)) { // reset the search owNetCurrent.LastDiscrepancy = 0; owNetCurrent.LastFamilyDiscrepancy = 0; OWERROR(OWERROR_NO_DEVICES_ON_NET); return FALSE; } } // If finding alarming devices issue a different command if(alarm_only) { owWriteByte(owCurrentPortnum, 0xEC); // issue the alarming search command } else { owWriteByte(owCurrentPortnum, 0xF0); // issue the search command } //pause before beginning the search //usDelay(100); // loop to do the search do { // read a bit and its compliment bit_test = owTouchBit(owCurrentPortnum, 1) << 1; bit_test |= owTouchBit(owCurrentPortnum, 1); // check for no devices on 1-wire if(bit_test == 3) { break; } // all devices coupled have 0 or 1 if(bit_test > 0) { search_direction = !(bit_test & 0x01); // bit write value for search } else { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if(bit_number < owNetCurrent.LastDiscrepancy) { search_direction = ((owNetCurrent.SerialNum[serial_byte_number] & serial_byte_mask) > 0); } else { // if equal to last pick 1, if not then pick 0 search_direction = (bit_number == owNetCurrent.LastDiscrepancy); } // if 0 was picked then record its position in LastZero if(search_direction == 0) { last_zero = bit_number; // check for Last discrepancy in family if(last_zero < 9) { owNetCurrent.LastFamilyDiscrepancy = last_zero; } } } // set or clear the bit in the SerialNum byte serial_byte_number // with mask serial_byte_mask if(search_direction == 1) { owNetCurrent.SerialNum[serial_byte_number] |= serial_byte_mask; } else { owNetCurrent.SerialNum[serial_byte_number] &= ~serial_byte_mask; } // serial number search direction write bit owTouchBit(owCurrentPortnum, search_direction); // increment the byte counter bit_number // and shift the mask serial_byte_mask bit_number++; serial_byte_mask <<= 1; // if the mask is 0 then go to new SerialNum byte serial_byte_number // and reset mask if(serial_byte_mask == 0) { lastcrc8 = docrc8(owCurrentPortnum, owNetCurrent.SerialNum[serial_byte_number]); // accumulate the CRC serial_byte_number++; serial_byte_mask = 1; } } while(serial_byte_number < 8); // loop until through all SerialNum bytes 0-7 // if the search was successful then if(!((bit_number < 65) || lastcrc8)) { // search successful so set LastDiscrepancy, LastDevice, next_result owNetCurrent.LastDiscrepancy = last_zero; if(last_zero == 0) { owNetCurrent.LastDevice = TRUE; } else { owNetCurrent.LastDevice = FALSE; } // owNetCurrent.LastDevice = (last_zero == 0); next_result = TRUE; } } // if no device found then reset counters so next 'next' will be // like a first if(!next_result || !owNetCurrent.SerialNum[0]) { owNetCurrent.LastDiscrepancy = 0; owNetCurrent.LastDevice = FALSE; owNetCurrent.LastFamilyDiscrepancy = 0; next_result = FALSE; } return next_result; }
//---------------------------------------------------------------------- // Use the script to perform a step and return. // int ThermoStep(int portnum, ThermoStateType *ThermoState, ThermoScript *StateScript, int *SubStep, int *Status, int *ErrorCount, char *msg) { short rslt; static int read_page_num, read_pages, write_addr, write_len; static uchar *read_buf, *write_buf; static uchar tbuf[5]; ErrorCount; // hush the compiler // do the current step switch (StateScript->Step) { // the operation is complete case ST_FINISH: sprintf(msg,"Operation complete"); *Status = STATUS_COMPLETE; break; // read the mission status page case ST_READ_STATUS: read_page_num = STATUS_PAGE; read_pages = 1; read_buf = ThermoState->MissStat.status_raw; sprintf(msg,"Ready to read status page %d", read_page_num); *Status = STATUS_STEP_COMPLETE; break; // set up to read the alarm registers case ST_READ_ALARM: read_page_num = 17; read_pages = 3; read_buf = ThermoState->AlarmData.alarm_raw; sprintf(msg,"Ready to read alarm pages %d to %d", read_page_num, read_page_num + read_pages - 1); *Status = STATUS_STEP_COMPLETE; break; // set up to read the histogram data case ST_READ_HIST: read_page_num = 64; read_pages = 4; read_buf = ThermoState->HistData.hist_raw; sprintf(msg,"Ready to read histogram pages %d to %d", read_page_num, read_page_num + read_pages - 1); *Status = STATUS_STEP_COMPLETE; break; // set up to read the log data case ST_READ_LOG: read_page_num = 128; read_pages = 64; read_buf = ThermoState->LogData.log_raw; sprintf(msg,"Ready to read log pages %d to %d", read_page_num, read_page_num + read_pages - 1); *Status = STATUS_STEP_COMPLETE; break; // read the specified pages case ST_READ_PAGES: // check for last page if (*SubStep == 0) // set the sub-step to the current page being read *SubStep = read_page_num; // read the status page rslt = ReadPages(portnum, read_page_num, read_pages, SubStep, read_buf); if (rslt == FALSE) { sprintf(msg,"Thermochron not on 1-Wire Net"); *Status = STATUS_INPROGRESS; } else { sprintf(msg,"Pages read from Thermochron"); *Status = STATUS_STEP_COMPLETE; } break; // setup the clear memory case ST_CLEAR_SETUP: // create a small buff to write to start the clear memory tbuf[0] = 0x40; write_buf = &tbuf[0]; write_len = 1; write_addr = 0x20E; sprintf(msg,"Write to setup clear memory"); *Status = STATUS_STEP_COMPLETE; break; // clear the memory case ST_CLEAR_MEM: // set the clear memory command (not check return because verify) owAccess(portnum); owWriteByte(portnum,0x3C); msDelay(3); owTouchReset(portnum); sprintf(msg,"Clear memory command sent"); *Status = STATUS_STEP_COMPLETE; break; // clear the memory case ST_CLEAR_VERIFY: // look at the memory clear bit if ((ThermoState->MissStat.status_raw[0x14] & 0x40) == 0x40) { sprintf(msg,"Memory is clear"); *Status = STATUS_STEP_COMPLETE; break; } else { sprintf(msg,"Memory did NOT clear"); *Status = STATUS_ERROR_TRANSIENT; break; } break; // setup write time, clock alarm, control, trips case ST_WRITE_TIME: // create the write buffer FormatMission(&ThermoState->MissStat); write_buf = &ThermoState->MissStat.status_raw[0x00]; write_len = 13; write_addr = 0x200; sprintf(msg,"Write time, clock alarm, and trips setup"); *Status = STATUS_STEP_COMPLETE; break; // write the control, mission delay and clear flags case ST_WRITE_CONTROL: write_buf = &ThermoState->MissStat.status_raw[0x0E]; write_len = 7; write_addr = 0x20E; sprintf(msg,"Write control, mission delay, clear flags setup"); *Status = STATUS_STEP_COMPLETE; break; case ST_WRITE_RATE: write_buf = &ThermoState->MissStat.status_raw[0x0D]; write_len = 1; write_addr = 0x20D; sprintf(msg,"Write sample rate setup"); *Status = STATUS_STEP_COMPLETE; break; // write the specified memory location case ST_WRITE_MEM: if (WriteMemory(portnum, write_buf, write_len, write_addr)) { sprintf(msg,"Memory written to Thermochron"); *Status = STATUS_STEP_COMPLETE; } else { sprintf(msg,"Thermochron not on 1-Wire Net"); *Status = STATUS_INPROGRESS; } default: break; } return *Status; }