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:
parent
cf3f309ade
commit
55d1bbf127
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();
|
||||||
|
if (state)
|
||||||
{
|
{
|
||||||
resetStart = (unsigned long)-1;
|
if (resetStart == (unsigned int)-1)
|
||||||
}
|
{
|
||||||
else if (localResetStart != (unsigned long)-1)
|
onLeaveInterrupt();
|
||||||
{
|
return;
|
||||||
unsigned long resetDuration = micros() - localResetStart;
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (receivingBitPos == 8)
|
||||||
{
|
{
|
||||||
bool bit = readBit();
|
byte receivedByte = receivingByte;
|
||||||
/*if (bit)
|
receivingBitPos = 0;
|
||||||
debug.SC_APPEND_STR("received bit 1");
|
receivingByte = 0;
|
||||||
else
|
//debug.SC_APPEND_STR_INT("received byte", (long)receivedByte);
|
||||||
debug.SC_APPEND_STR("received bit 0");*/
|
|
||||||
|
|
||||||
receivingByte |= ((bit ? 1 : 0) << receivingBitPos);
|
if (status == OS_WaitCommand && receivedByte == 0xF0)
|
||||||
++receivingBitPos;
|
|
||||||
|
|
||||||
if (receivingBitPos == 8)
|
|
||||||
{
|
{
|
||||||
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…
Reference in New Issue
Block a user