Browse Source

more robust reset detection, now purely implemented in interrupts, that allows the match rom algorithm to work even if our rom is not the first one

pull/5/head
Youen Toupin 10 years ago
parent
commit
55d1bbf127
  1. 141
      OneWireIO.ino

141
OneWireIO.ino

@ -34,7 +34,7 @@ enum OwStatus
}; };
OwStatus status; OwStatus status;
byte owROM[8] = { 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 }; byte owROM[8] = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 };
byte searchROMCurrentByte = 0; byte searchROMCurrentByte = 0;
byte searchROMCurrentBit = 0; byte searchROMCurrentBit = 0;
bool searchROMSendingInverse = false; bool searchROMSendingInverse = false;
@ -44,23 +44,23 @@ void owPullLow()
{ {
owPin.outputMode(); owPin.outputMode();
owPin.writeLow(); owPin.writeLow();
//owOutTestPin.writeLow(); owOutTestPin.writeLow();
} }
void owRelease() void owRelease()
{ {
owPin.inputMode(); owPin.inputMode();
//owOutTestPin.writeHigh(); owOutTestPin.writeHigh();
} }
void onEnterInterrupt() void onEnterInterrupt()
{ {
owOutTestPin.writeLow(); //owOutTestPin.writeLow();
} }
void onLeaveInterrupt() void onLeaveInterrupt()
{ {
owOutTestPin.writeHigh(); //owOutTestPin.writeHigh();
} }
volatile unsigned long resetStart = (unsigned long)-1; volatile unsigned long resetStart = (unsigned long)-1;
@ -83,7 +83,7 @@ void setup()
led.writeLow(); led.writeLow();
cli(); // disable interrupts cli(); // disable interrupts
attachInterrupt(InterruptNumber,onewireInterrupt,FALLING); attachInterrupt(InterruptNumber, owWaitResetInterrupt, CHANGE);
// set timer0 interrupt at 250KHz (actually depends on compare match register OCR0A) // set timer0 interrupt at 250KHz (actually depends on compare match register OCR0A)
// 4us between each tick // 4us between each tick
@ -98,18 +98,16 @@ void setup()
Serial.begin(9600); Serial.begin(9600);
} }
//int count = 0; int count = 0;
void loop() void loop()
{ {
//if ((count++) % 1000 == 0) if ((count++) % 1000 == 0)
// led.write(!led.read()); led.write(!led.read());
cli();//disable interrupts cli();//disable interrupts
SerialChannel::swap(); SerialChannel::swap();
sei();//enable interrupts sei();//enable interrupts
SerialChannel::flush(); SerialChannel::flush();
owHandleReset();
} }
void(*timerEvent)() = 0; void(*timerEvent)() = 0;
@ -138,56 +136,54 @@ void owClearError()
led.writeLow(); led.writeLow();
} }
void owHandleReset() void owWaitResetInterrupt()
{ {
unsigned long localResetStart = resetStart; onEnterInterrupt();
if (owPin.read()) bool state = owPin.read();
{ unsigned long now = micros();
resetStart = (unsigned long)-1; if (state)
}
else if (localResetStart != (unsigned long)-1)
{ {
unsigned long resetDuration = micros() - localResetStart; if (resetStart == (unsigned int)-1)
{
onLeaveInterrupt();
return;
}
unsigned long resetDuration = now - resetStart;
resetStart = (unsigned int)-1;
if (resetDuration >= ResetMinDuration) if (resetDuration >= ResetMinDuration)
{ {
// wait for master to release the pin (or timeout if the pin is pulled low for too long) if (resetDuration > ResetMaxDuration)
unsigned long now = micros();
while (!owPin.read())
{ {
if (resetStart != localResetStart) owError("Reset too long");
return; onLeaveInterrupt();
now = micros(); return;
if (now - localResetStart > ResetMaxDuration)
{
owError("Reset too long");
return;
}
} }
cli();
owClearError(); owClearError();
lastReset = now; lastReset = now;
status = OS_Presence; status = OS_Presence;
setTimerEvent(PresenceWaitDuration - (micros() - now), &beginPresence); setTimerEvent(PresenceWaitDuration - (micros() - now), &beginPresence);
sei();
} }
} }
} else
{
void onewireInterrupt() resetStart = now;
{ }
onEnterInterrupt();
onewireInterruptImpl();
onLeaveInterrupt(); onLeaveInterrupt();
} }
//bool debugState = false; //bool debugState = false;
volatile unsigned long lastInterrupt = 0; volatile unsigned long lastInterrupt = 0;
void onewireInterruptImpl(void) void owReceiveCommandInterrupt(void)
{ {
onEnterInterrupt();
unsigned long now = micros(); unsigned long now = micros();
if (now < lastInterrupt + 20) if (now < lastInterrupt + 20)
{
onLeaveInterrupt();
return; // don't react to our own actions return; // don't react to our own actions
}
lastInterrupt = now; lastInterrupt = now;
//debugState = !debugState; //debugState = !debugState;
@ -195,45 +191,41 @@ void onewireInterruptImpl(void)
//led.write(state); //led.write(state);
resetStart = now; bool bit = readBit();
/*if (bit)
debug.SC_APPEND_STR("received bit 1");
else
debug.SC_APPEND_STR("received bit 0");*/
switch (status) { receivingByte |= ((bit ? 1 : 0) << receivingBitPos);
case OS_WaitCommand: ++receivingBitPos;
{
bool bit = readBit();
/*if (bit)
debug.SC_APPEND_STR("received bit 1");
else
debug.SC_APPEND_STR("received bit 0");*/
receivingByte |= ((bit ? 1 : 0) << receivingBitPos); if (receivingBitPos == 8)
++receivingBitPos; {
byte receivedByte = receivingByte;
receivingBitPos = 0;
receivingByte = 0;
//debug.SC_APPEND_STR_INT("received byte", (long)receivedByte);
if (receivingBitPos == 8) if (status == OS_WaitCommand && receivedByte == 0xF0)
{ {
byte receivedByte = receivingByte; status = OS_SearchRom;
receivingBitPos = 0; searchROMReadingMasterResponseBit = false;
receivingByte = 0; searchROMSendingInverse = false;
//debug.SC_APPEND_STR_INT("received byte", (long)receivedByte); searchROMCurrentByte = 0;
searchROMCurrentBit = 0;
if (status == OS_WaitCommand && receivedByte == 0xF0) byte currentByte = owROM[searchROMCurrentByte];
{ searchRomNextBit = bitRead(currentByte, searchROMCurrentBit);
status = OS_SearchRom; searchRomNextBitToSend = searchROMSendingInverse ? !searchRomNextBit : searchRomNextBit;
searchROMReadingMasterResponseBit = false; //attachInterrupt(InterruptNumber, onewireInterruptSearchROM, FALLING);
searchROMSendingInverse = false; setTimerEvent(10, owSearchSendBit);
searchROMCurrentByte = 0; detachInterrupt(InterruptNumber);
searchROMCurrentBit = 0; onLeaveInterrupt();
byte currentByte = owROM[searchROMCurrentByte]; return;
searchRomNextBit = bitRead(currentByte, searchROMCurrentBit);
searchRomNextBitToSend = searchROMSendingInverse ? !searchRomNextBit : searchRomNextBit;
//attachInterrupt(InterruptNumber, onewireInterruptSearchROM, FALLING);
setTimerEvent(10, owSearchSendBit);
detachInterrupt(InterruptNumber);
return;
}
} }
} break;
} }
onLeaveInterrupt();
} }
bool ignoreNextFallingEdge = false; bool ignoreNextFallingEdge = false;
@ -311,7 +303,7 @@ void onewireInterruptSearchROM()
{ {
debug.SC_APPEND_STR("Master didn't send our bit, leaving ROM search"); debug.SC_APPEND_STR("Master didn't send our bit, leaving ROM search");
status = OS_WaitReset; status = OS_WaitReset;
attachInterrupt(InterruptNumber, onewireInterrupt, FALLING); attachInterrupt(InterruptNumber, owWaitResetInterrupt, CHANGE);
onLeaveInterrupt(); onLeaveInterrupt();
return; return;
} }
@ -330,7 +322,7 @@ void onewireInterruptSearchROM()
searchROMCurrentByte = 0; searchROMCurrentByte = 0;
status = OS_WaitReset; status = OS_WaitReset;
debug.SC_APPEND_STR("ROM sent entirely"); debug.SC_APPEND_STR("ROM sent entirely");
attachInterrupt(InterruptNumber, onewireInterrupt, FALLING); attachInterrupt(InterruptNumber, owWaitResetInterrupt, CHANGE);
onLeaveInterrupt(); onLeaveInterrupt();
return; return;
} }
@ -411,6 +403,7 @@ void endPresence()
debug.SC_APPEND_STR_TIME("endPresence", now); debug.SC_APPEND_STR_TIME("endPresence", now);
status = OS_WaitCommand; status = OS_WaitCommand;
attachInterrupt(InterruptNumber, owReceiveCommandInterrupt, FALLING);
receivingByte = 0; receivingByte = 0;
receivingBitPos = 0; receivingBitPos = 0;
bitStart = (unsigned long)-1; bitStart = (unsigned long)-1;

Loading…
Cancel
Save