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

This commit is contained in:
Youen Toupin 2015-04-25 12:19:31 +02:00
parent cf3f309ade
commit 55d1bbf127

View File

@ -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();
{
resetStart = (unsigned long)-1;
}
else if (localResetStart != (unsigned long)-1)
{
unsigned long resetDuration = micros() - localResetStart;
if (resetDuration >= ResetMinDuration)
{
// wait for master to release the pin (or timeout if the pin is pulled low for too long)
unsigned long now = micros(); unsigned long now = micros();
while (!owPin.read()) if (state)
{ {
if (resetStart != localResetStart) if (resetStart == (unsigned int)-1)
return;
now = micros();
if (now - localResetStart > ResetMaxDuration)
{ {
owError("Reset too long"); onLeaveInterrupt();
return;
}
unsigned long resetDuration = now - resetStart;
resetStart = (unsigned int)-1;
if (resetDuration >= ResetMinDuration)
{
if (resetDuration > ResetMaxDuration)
{
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() 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,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;