'=========================================================== ' ' Dallas 1-Wire Interface ' ' Copyright 2000 by Jon Hylands ' jon@huv.com http://www.huv.com ' '=========================================================== '----------------------------------------------------------- ' DallasBaseROMAddress is the starting address of ' where the ROM ids are stored in the BasicX-24 EEPROM ' as the result of doing a SearchROM. ' ' The structure one byte for the total number of devices, ' followed by 8 bytes for each device's ROM id. public const DallasBaseROMAddress as Long = &h7200 '----------------------------------------------------------- private const DallasReadROM as Byte = &h33 private const DallasMatchROM as Byte = &h55 private const DallasSkipROM as Byte = &hCC private const DallasSearchROM as Byte = &hF0 private lastROMArray (1 to 8) as Byte '----------------------------------------------------------- ' Reset_1Wire ' ' Reset the 1-wire bus by sending a 500 usec low pulse. ' Return true if any devices respond, false if there ' are no devices on the bus. public Function Reset_1Wire (ByVal busPin as Byte) as Boolean dim index as Integer dim busTransitions as Long dim pinValues (1 to 10) as Byte ' It is important for timing reasons that this function ' not be pre-empted... call LockTask call PutPin (busPin, bxInputTristate) call PutPin (busPin, bxOutputLow) ' Delay for ~500 usec - fake it with PulseOut on pin 0... call PulseOut (0, 0.0005, 0) ' Now let the pullup resistor do its thing... Call PutPin (busPin, bxInputTristate) ' Look for the presence pulse over a 300 usec period busTransitions = CountTransitions (busPin, 0.0003) call UnlockTask Reset_1Wire = (busTransitions > 0) End Function '----------------------------------------------------------- ' ReadROM_1Wire ' ' Read the 64-bit ROM value of the single device on ' the bus. If there is more than one device on the bus, ' this routine will end up giving a bad ROM id. public Sub ReadROM_1Wire (ByVal busPin as Byte, ByRef romArray() as Byte) dim index as Integer if not Reset_1Wire (busPin) then Exit Sub end if call PutByte_1Wire (busPin, DallasReadROM) for index = 1 to 8 romArray (index) = InByte_1Wire (busPin) next End Sub '----------------------------------------------------------- ' MatchROM_1Wire ' ' Select the device on the bus that has a ROM id matching ' the contents of romArray. public Sub MatchROM_1Wire (ByVal busPin as Byte, ByRef romArray() as Byte) dim index as Integer if not Reset_1Wire (busPin) then Exit Sub end if call PutByte_1Wire (busPin, DallasMatchROM) for index = 1 to 8 call PutByte_1Wire (busPin, romArray (index)) next End Sub '----------------------------------------------------------- ' SkipROM_1Wire ' ' Skip the whole device select thing -- this only works ' in general if there is only device on the bus public Sub SkipROM_1Wire (ByVal busPin as Byte) if not Reset_1Wire (busPin) then Exit Sub end if call PutByte_1Wire (busPin, DallasSkipROM) End Sub '----------------------------------------------------------- ' SearchROM_1Wire ' ' Find the 64 bit ROM id of each device connected ' to the bus. ' ' Store the ROM ids in EEPROM memory, starting at the address ' specified by the global constant DallasBaseROMAddress. ' ' Return the number of devices that were found. public Function SearchROM_1Wire (ByVal busPin as Byte) as Byte dim lastConflict as Byte, deviceIndex as Byte dim index as Integer lastConflict = 0 deviceIndex = 0 for index = 1 to 8 lastROMArray (index) = 0 next if not Reset_1Wire (busPin) then SearchROM_1Wire = 0 Exit Function end if ' Loop once per device do lastConflict = HandleSearch_1Wire (busPin, lastConflict, deviceIndex) deviceIndex = deviceIndex + 1 loop until lastConflict = 0 ' Finally, save the device count as the first byte in our ' EEPROM storage area call PersistentPoke (deviceIndex, CuInt (DallasBaseROMAddress)) SearchROM_1Wire = deviceIndex End Function '----------------------------------------------------------- ' HandleSearch_1Wire ' ' This is the actual search working routine private Function HandleSearch_1Wire (ByVal busPin as Byte, _ ByVal startIndex as Byte, _ ByVal deviceIndex as Byte) as Byte dim bitIndex as Byte, conflictIndex as Byte, value as Byte dim bitValue as Byte dim romArray (1 to 8) as Byte HandleSearch_1Wire = 0 if not Reset_1Wire (busPin) then Exit Function end if bitIndex = 0 conflictIndex = 0 call PutByte_1Wire (busPin, DallasSearchROM) ' Blast through the last rom, up to the point where we had the conflict if deviceIndex > 0 then do while bitIndex < startIndex value = In2Bits_1Wire (busPin) bitValue = GetBit (lastROMArray, bitIndex) call Put1Wire (busPin, bitValue) call PutBit (romArray, bitIndex, bitValue) bitIndex = bitIndex + 1 loop ' Okay, now we're there. This time select the ROM with bit one value = In2Bits_1Wire (busPin) call Put1Wire (busPin, 1) call PutBit (romArray, bitIndex, 1) bitIndex = bitIndex + 1 end if ' Now loop through the rest of the 64 bits, watching for conflicts do select case In2Bits_1Wire (busPin) ' case 00 -- devices with both bits, always select 0 case bx00000000 conflictIndex = bitIndex call PutBit (romArray, bitIndex, 0) ' case 01 -- all devices have one bit in this position case bx00000001 call PutBit (romArray, bitIndex, 1) ' case 10 -- all devices have zero bit in this position case bx00000010 call PutBit (romArray, bitIndex, 0) ' case 11 -- all devices have deselected themselves case bx00000011 Exit Function end select call Put1Wire (busPin, GetBit (romArray, bitIndex)) bitIndex = bitIndex + 1 loop until bitIndex = 64 ' Copy the ROM id to EEPROM, and then save it as the last accessed one call PutROMid_1Wire (deviceIndex, romArray) call BlockMove (8, MemAddress (romArray), MemAddress (lastROMArray)) HandleSearch_1Wire = conflictIndex End Function '----------------------------------------------------------- ' PutROMid_1Wire ' ' Copy the ROM id from the given RAM array to the ' location in EEPROM indexed by deviceIndex. public Sub PutROMid_1Wire (ByVal deviceIndex as Byte, ByRef romArray() as Byte) call PutEEPROM (DallasBaseROMAddress + 1 + CLng (deviceIndex * 8), romArray, 8) End Sub '----------------------------------------------------------- ' GetROMid_1Wire ' ' Copy the ROM id indexed by deviceIndex from EEPROM ' to the given RAM array. public Sub GetROMid_1Wire (ByVal deviceIndex as Byte, ByRef romArray() as Byte) call GetEEPROM (DallasBaseROMAddress + 1 + CLng (deviceIndex * 8), romArray, 8) End Sub '----------------------------------------------------------- ' GetDeviceCount_1Wire ' ' Return the number of devices found by the last ' invocation of SearchROM. public Function GetDeviceCount_1Wire () as Byte GetDeviceCount_1Wire = PersistentPeek (CuInt (DallasBaseROMAddress)) End Function '----------------------------------------------------------- ' InByte_1Wire ' ' Pull a byte off the bus from the selected device. public Function InByte_1Wire (ByVal busPin as Byte) as Byte dim index as Byte dim inputByte as Byte for index = 0 to 7 call PutBit (inputByte, index, Get1Wire (busPin)) next InByte_1Wire = inputByte End Function '----------------------------------------------------------- ' In2Bits_1Wire ' ' Pull two bits off the bus from the selected device. private Function In2Bits_1Wire (ByVal busPin as Byte) as Byte In2Bits_1Wire = 0 call PutBit (In2Bits_1Wire, 0, Get1Wire (busPin)) call PutBit (In2Bits_1Wire, 1, Get1Wire (busPin)) End Function '----------------------------------------------------------- ' PutByte_1Wire ' ' Output a byte to the selected device on the bus. public Sub PutByte_1Wire (ByVal busPin as Byte, ByVal outputByte as Byte) dim index as Byte for index = 0 to 7 call Put1Wire (busPin, GetBit (outputByte, index)) next End Sub