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

Loading…
Cancel
Save