Browse Source

attempt to implement search ROM algorithm (doesn't work at this time)

timer1
Youen Toupin 9 years ago
parent
commit
68f4fce878
  1. 177
      OneWireIO.ino

177
OneWireIO.ino

@ -15,6 +15,11 @@
#define BitZeroMinDuration 20 #define BitZeroMinDuration 20
#define BitZeroMaxDuration 75 #define BitZeroMaxDuration 75
#define SendBitDuration 30
const byte InvalidBit = (byte)-1;
const byte IncompleteBit = (byte)-2;
SerialChannel debug("debug"); SerialChannel debug("debug");
Pin owPin(OWPin); Pin owPin(OWPin);
@ -27,9 +32,16 @@ enum OwStatus
OS_Presence, OS_Presence,
OS_AfterPresence, OS_AfterPresence,
OS_WaitCommand, OS_WaitCommand,
OS_SearchRom,
}; };
OwStatus status; 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() void owPullLow()
{ {
owPin.outputMode(); owPin.outputMode();
@ -112,6 +124,7 @@ void owError(const char* message)
{ {
debug.append(message); debug.append(message);
led.writeHigh(); led.writeHigh();
status = OS_WaitReset;
} }
void owResetError() void owResetError()
@ -151,6 +164,7 @@ void onewireInterrupt(void)
status = OS_WaitCommand; status = OS_WaitCommand;
receivingByte = 0; receivingByte = 0;
receivingBitPos = 0; receivingBitPos = 0;
bitStart = (unsigned long)-1;
if (state) if (state)
{ {
@ -162,57 +176,154 @@ void onewireInterrupt(void)
// read bytes // read bytes
if (status == OS_WaitCommand) if (status == OS_WaitCommand)
{ {
if (!state) byte bit = interpretReceivedEdgeAsBit(state, now);
{ if (bit != IncompleteBit)
// master just pulled low, this is a bit start
//debug.SC_APPEND_STR_TIME("bit start", now);
bitStart = now;
}
else
{ {
if (bitStart == (unsigned long)-1) if (bit == InvalidBit)
return;
receivingByte |= (bit << receivingBitPos);
++receivingBitPos;
if (receivingBitPos == 8)
{ {
//owError("Invalid read sequence"); debug.SC_APPEND_STR_INT("received byte", (long)receivingByte);
//return;
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) receivingBitPos = 0;
bitStart = now; receivingByte = 0;
} }
}
}
// master released the line, we interpret it as a bit 1 or 0 depending on timing if (status == OS_SearchRom)
unsigned long bitLength = now - bitStart; {
bitStart = (unsigned long)-1; 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 searchROMReadingMasterResponseBit = false;
//debug.SC_APPEND_STR_TIME("received bit 1", now); if (bit == InvalidBit)
receivingByte |= (1 << receivingBitPos); return;
++receivingBitPos; 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 // master is pulling low, we must send our bit
//debug.SC_APPEND_STR_TIME("received bit 0", now); bool bitToSend = searchROMSendingInverse ? !currentBit : currentBit;
++receivingBitPos; 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 else
{ {
// this is not a valid bit debug.SC_APPEND_STR_TIME("Search ROM : seen rising edge", now);
owError("Invalid read timing");
return;
} }
}
}
}
if (receivingBitPos == 8) byte interpretReceivedEdgeAsBit(bool wireState, unsigned long now)
{ {
debug.SC_APPEND_STR_INT("received byte", (long)receivingByte); if (!wireState)
receivingBitPos = 0; {
receivingByte = 0; // 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() void beginPresence()
{ {
unsigned long now = micros(); unsigned long now = micros();

Loading…
Cancel
Save