From 68f4fce8783561a892af47b68cb89bf992b75940 Mon Sep 17 00:00:00 2001 From: Youen Toupin Date: Fri, 24 Apr 2015 12:13:29 +0200 Subject: [PATCH] attempt to implement search ROM algorithm (doesn't work at this time) --- OneWireIO.ino | 177 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 144 insertions(+), 33 deletions(-) diff --git a/OneWireIO.ino b/OneWireIO.ino index 5540e80..4a54161 100644 --- a/OneWireIO.ino +++ b/OneWireIO.ino @@ -15,6 +15,11 @@ #define BitZeroMinDuration 20 #define BitZeroMaxDuration 75 +#define SendBitDuration 30 + +const byte InvalidBit = (byte)-1; +const byte IncompleteBit = (byte)-2; + SerialChannel debug("debug"); Pin owPin(OWPin); @@ -27,9 +32,16 @@ enum OwStatus OS_Presence, OS_AfterPresence, OS_WaitCommand, + OS_SearchRom, }; OwStatus status; +byte owROM[8] = { 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 }; +byte searchROMCurrentByte = 0; +byte searchROMCurrentBit = 0; +bool searchROMSendingInverse = false; +bool searchROMReadingMasterResponseBit = false; + void owPullLow() { owPin.outputMode(); @@ -112,6 +124,7 @@ void owError(const char* message) { debug.append(message); led.writeHigh(); + status = OS_WaitReset; } void owResetError() @@ -151,6 +164,7 @@ void onewireInterrupt(void) status = OS_WaitCommand; receivingByte = 0; receivingBitPos = 0; + bitStart = (unsigned long)-1; if (state) { @@ -162,57 +176,154 @@ void onewireInterrupt(void) // read bytes if (status == OS_WaitCommand) { - if (!state) - { - // master just pulled low, this is a bit start - //debug.SC_APPEND_STR_TIME("bit start", now); - bitStart = now; - } - else + byte bit = interpretReceivedEdgeAsBit(state, now); + if (bit != IncompleteBit) { - if (bitStart == (unsigned long)-1) + if (bit == InvalidBit) + return; + + receivingByte |= (bit << receivingBitPos); + ++receivingBitPos; + + if (receivingBitPos == 8) { - //owError("Invalid read sequence"); - //return; + debug.SC_APPEND_STR_INT("received byte", (long)receivingByte); + + if (status == OS_WaitCommand && receivingByte == 0xF0) + { + status = OS_SearchRom; + searchROMReadingMasterResponseBit = false; + searchROMSendingInverse = false; + searchROMCurrentByte = 0; + searchROMCurrentBit = 0; + return; + } - // we missed the falling edge, we emulate one here (this can happen if handling of rising edge interrupt takes too long) - bitStart = now; + receivingBitPos = 0; + receivingByte = 0; } + } + } - // master released the line, we interpret it as a bit 1 or 0 depending on timing - unsigned long bitLength = now - bitStart; - bitStart = (unsigned long)-1; + if (status == OS_SearchRom) + { + byte currentByte = owROM[searchROMCurrentByte]; + bool currentBit = bitRead(currentByte, searchROMCurrentBit); - if (bitLength < BitZeroMinDuration) + if (searchROMReadingMasterResponseBit) + { + byte bit = interpretReceivedEdgeAsBit(state, now); + if (bit != IncompleteBit) { - // received bit = 1 - //debug.SC_APPEND_STR_TIME("received bit 1", now); - receivingByte |= (1 << receivingBitPos); - ++receivingBitPos; + searchROMReadingMasterResponseBit = false; + if (bit == InvalidBit) + return; + if ((bit == 1) != currentBit) + { + debug.SC_APPEND_STR_TIME("Master didn't send our bit, leaving ROM search", now); + status = OS_WaitReset; + } } - else if (bitLength < BitZeroMaxDuration) + } + else + { + if (!state) { - // received bit = 0 - //debug.SC_APPEND_STR_TIME("received bit 0", now); - ++receivingBitPos; + // master is pulling low, we must send our bit + bool bitToSend = searchROMSendingInverse ? !currentBit : currentBit; + sendBit(bitToSend); + if (bitToSend) + debug.SC_APPEND_STR_TIME("Sent ROM search bit : 1", now); + else + debug.SC_APPEND_STR_TIME("Sent ROM search bit : 0", now); + + if (searchROMSendingInverse) + { + searchROMSendingInverse = false; + searchROMReadingMasterResponseBit = true; + } + else + { + searchROMSendingInverse = true; + } + + if (searchROMCurrentBit == 8) + { + ++searchROMCurrentByte; + searchROMCurrentBit = 0; + debug.SC_APPEND_STR_TIME("sent another ROM byte", now); + } + + if (searchROMCurrentByte == 8) + { + searchROMCurrentByte = 0; + status = OS_WaitReset; + debug.SC_APPEND_STR_TIME("ROM sent entirely", now); + } } else { - // this is not a valid bit - owError("Invalid read timing"); - return; + debug.SC_APPEND_STR_TIME("Search ROM : seen rising edge", now); } + } + } +} - if (receivingBitPos == 8) - { - debug.SC_APPEND_STR_INT("received byte", (long)receivingByte); - receivingBitPos = 0; - receivingByte = 0; - } +byte interpretReceivedEdgeAsBit(bool wireState, unsigned long now) +{ + if (!wireState) + { + // master just pulled low, this is a bit start + //debug.SC_APPEND_STR_TIME("bit start", now); + bitStart = now; + return IncompleteBit; + } + else + { + if (bitStart == (unsigned long)-1) + { + //owError("Invalid read sequence"); + //return InvalidBit; + + // we missed the falling edge, we emulate one here (this can happen if handling of rising edge interrupt takes too long) + bitStart = now; + } + + // master released the line, we interpret it as a bit 1 or 0 depending on timing + unsigned long bitLength = now - bitStart; + bitStart = (unsigned long)-1; + + if (bitLength < BitZeroMinDuration) + { + // received bit = 1 + //debug.SC_APPEND_STR_TIME("received bit 1", now); + return 1; + } + else if (bitLength < BitZeroMaxDuration) + { + // received bit = 0 + //debug.SC_APPEND_STR_TIME("received bit 0", now); + return 0; + } + else + { + // this is not a valid bit + owError("Invalid read timing"); + return InvalidBit; } } } +void sendBit(bool bit) +{ + if (!bit) + { + owPullLow(); + delayMicroseconds(SendBitDuration); + owRelease(); + } +} + void beginPresence() { unsigned long now = micros();