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. 81
      OneWireIO.ino

81
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();
if (state)
{ {
resetStart = (unsigned long)-1; if (resetStart == (unsigned int)-1)
}
else if (localResetStart != (unsigned long)-1)
{ {
unsigned long resetDuration = micros() - localResetStart; 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)
return;
now = micros();
if (now - localResetStart > ResetMaxDuration)
{ {
owError("Reset too long"); owError("Reset too long");
onLeaveInterrupt();
return; 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()
{ {
onEnterInterrupt(); resetStart = now;
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,11 +191,6 @@ void onewireInterruptImpl(void)
//led.write(state); //led.write(state);
resetStart = now;
switch (status) {
case OS_WaitCommand:
{
bool bit = readBit(); bool bit = readBit();
/*if (bit) /*if (bit)
debug.SC_APPEND_STR("received bit 1"); debug.SC_APPEND_STR("received bit 1");
@ -229,11 +220,12 @@ void onewireInterruptImpl(void)
//attachInterrupt(InterruptNumber, onewireInterruptSearchROM, FALLING); //attachInterrupt(InterruptNumber, onewireInterruptSearchROM, FALLING);
setTimerEvent(10, owSearchSendBit); setTimerEvent(10, owSearchSendBit);
detachInterrupt(InterruptNumber); detachInterrupt(InterruptNumber);
onLeaveInterrupt();
return; 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