|
|
|
@ -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) |
|
|
|
|
{ |
|
|
|
@ -161,19 +175,115 @@ void onewireInterrupt(void)
|
|
|
|
|
|
|
|
|
|
// read bytes
|
|
|
|
|
if (status == OS_WaitCommand) |
|
|
|
|
{ |
|
|
|
|
byte bit = interpretReceivedEdgeAsBit(state, now); |
|
|
|
|
if (bit != IncompleteBit) |
|
|
|
|
{ |
|
|
|
|
if (bit == InvalidBit) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
receivingByte |= (bit << receivingBitPos); |
|
|
|
|
++receivingBitPos; |
|
|
|
|
|
|
|
|
|
if (receivingBitPos == 8) |
|
|
|
|
{ |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
receivingBitPos = 0; |
|
|
|
|
receivingByte = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (status == OS_SearchRom) |
|
|
|
|
{ |
|
|
|
|
byte currentByte = owROM[searchROMCurrentByte]; |
|
|
|
|
bool currentBit = bitRead(currentByte, searchROMCurrentBit); |
|
|
|
|
|
|
|
|
|
if (searchROMReadingMasterResponseBit) |
|
|
|
|
{ |
|
|
|
|
byte bit = interpretReceivedEdgeAsBit(state, now); |
|
|
|
|
if (bit != IncompleteBit) |
|
|
|
|
{ |
|
|
|
|
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 (!state) |
|
|
|
|
{ |
|
|
|
|
// 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 |
|
|
|
|
{ |
|
|
|
|
debug.SC_APPEND_STR_TIME("Search ROM : seen rising edge", now); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
//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; |
|
|
|
@ -187,29 +297,30 @@ void onewireInterrupt(void)
|
|
|
|
|
{ |
|
|
|
|
// received bit = 1
|
|
|
|
|
//debug.SC_APPEND_STR_TIME("received bit 1", now);
|
|
|
|
|
receivingByte |= (1 << receivingBitPos); |
|
|
|
|
++receivingBitPos; |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
else if (bitLength < BitZeroMaxDuration) |
|
|
|
|
{ |
|
|
|
|
// received bit = 0
|
|
|
|
|
//debug.SC_APPEND_STR_TIME("received bit 0", now);
|
|
|
|
|
++receivingBitPos; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
// this is not a valid bit
|
|
|
|
|
owError("Invalid read timing"); |
|
|
|
|
return; |
|
|
|
|
return InvalidBit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (receivingBitPos == 8) |
|
|
|
|
{ |
|
|
|
|
debug.SC_APPEND_STR_INT("received byte", (long)receivingByte); |
|
|
|
|
receivingBitPos = 0; |
|
|
|
|
receivingByte = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sendBit(bool bit) |
|
|
|
|
{ |
|
|
|
|
if (!bit) |
|
|
|
|
{ |
|
|
|
|
owPullLow(); |
|
|
|
|
delayMicroseconds(SendBitDuration); |
|
|
|
|
owRelease(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|