Browse Source

added background reset check (in case the master sends a reset while another operation had started)

timer1
Youen Toupin 10 years ago
parent
commit
300a6be90f
  1. 174
      OneWireSlave.cpp
  2. 4
      OneWireSlave.h

174
OneWireSlave.cpp

@ -179,82 +179,29 @@ void OneWireSlave::releaseBus_()
#endif
}
void OneWireSlave::beginWaitReset_()
void OneWireSlave::beginResetDetection_()
{
disableTimer_();
pin_.attachInterrupt(&OneWireSlave::waitReset_, CHANGE);
resetStart_ = (unsigned int)-1;
setTimerEvent_(ResetMinDuration - 50, &OneWireSlave::resetCheck_);
resetStart_ = micros() - 50;
}
void OneWireSlave::waitReset_()
{
onEnterInterrupt_();
bool state = pin_.read();
unsigned long now = micros();
if (state)
{
if (resetStart_ == (unsigned int)-1)
{
onLeaveInterrupt_();
return;
}
unsigned long resetDuration = now - resetStart_;
resetStart_ = (unsigned int)-1;
if (resetDuration >= ResetMinDuration)
{
if (resetDuration > ResetMaxDuration)
{
error_("Reset too long");
onLeaveInterrupt_();
return;
}
lastReset_ = now;
pin_.detachInterrupt();
setTimerEvent_(PresenceWaitDuration - (micros() - now), &OneWireSlave::beginPresence_);
}
}
else
{
resetStart_ = now;
}
onLeaveInterrupt_();
}
void OneWireSlave::beginPresence_()
void OneWireSlave::cancelResetDetection_()
{
unsigned long now = micros();
pullLow_();
setTimerEvent_(PresenceDuration, &OneWireSlave::endPresence_);
#ifdef DEBUG_LOG
debug.SC_APPEND_STR_TIME("reset", lastReset_);
debug.SC_APPEND_STR_TIME("beginPresence", now);
#endif
disableTimer_();
resetStart_ = (unsigned long)-1;
}
void OneWireSlave::endPresence_()
void OneWireSlave::resetCheck_()
{
unsigned long now = micros();
releaseBus_();
onEnterInterrupt_();
if (!pin_.read())
{
pin_.attachInterrupt(&OneWireSlave::waitReset_, CHANGE);
#ifdef DEBUG_LOG
debug.SC_APPEND_STR_TIME("endPresence", now);
debug.SC_APPEND_STR("Reset detected during another operation");
#endif
beginWaitCommand_();
}
void OneWireSlave::beginWaitCommand_()
{
receiveTarget_ = ReceiveCommand;
beginReceive_();
}
void OneWireSlave::beginReceive_()
{
receivingByte_ = 0;
receivingBitPos_ = 0;
beginReceiveBit_(&OneWireSlave::onBitReceived_);
}
onLeaveInterrupt_();
}
void OneWireSlave::beginReceiveBit_(void(*completeCallback)(bool bit, bool error))
@ -273,6 +220,22 @@ void OneWireSlave::receive_()
onLeaveInterrupt_();
}
void OneWireSlave::readBit_()
{
onEnterInterrupt_();
bool bit = pin_.read();
if (bit)
cancelResetDetection_();
else
beginResetDetection_();
receiveBitCallback_(bit, false);
//dbgOutput.writeLow();
//dbgOutput.writeHigh();
onLeaveInterrupt_();
}
void OneWireSlave::beginSendBit_(bool bit, void(*completeCallback)(bool error))
{
bitSentCallback_ = completeCallback;
@ -290,6 +253,7 @@ void OneWireSlave::sendBitOne_()
{
onEnterInterrupt_();
beginResetDetection_();
bitSentCallback_(false);
onLeaveInterrupt_();
@ -317,18 +281,84 @@ void OneWireSlave::endSendBitZero_()
onLeaveInterrupt_();
}
void OneWireSlave::readBit_()
void OneWireSlave::beginWaitReset_()
{
disableTimer_();
pin_.attachInterrupt(&OneWireSlave::waitReset_, CHANGE);
resetStart_ = (unsigned int)-1;
}
void OneWireSlave::waitReset_()
{
onEnterInterrupt_();
bool state = pin_.read();
unsigned long now = micros();
if (state)
{
if (resetStart_ == (unsigned int)-1)
{
onLeaveInterrupt_();
return;
}
bool bit = pin_.read();
receiveBitCallback_(bit, false);
//dbgOutput.writeLow();
//dbgOutput.writeHigh();
unsigned long resetDuration = now - resetStart_;
resetStart_ = (unsigned int)-1;
if (resetDuration >= ResetMinDuration)
{
if (resetDuration > ResetMaxDuration)
{
error_("Reset too long");
onLeaveInterrupt_();
return;
}
lastReset_ = now;
pin_.detachInterrupt();
setTimerEvent_(PresenceWaitDuration - (micros() - now), &OneWireSlave::beginPresence_);
}
}
else
{
resetStart_ = now;
}
onLeaveInterrupt_();
}
void OneWireSlave::beginPresence_()
{
unsigned long now = micros();
pullLow_();
setTimerEvent_(PresenceDuration, &OneWireSlave::endPresence_);
#ifdef DEBUG_LOG
debug.SC_APPEND_STR_TIME("reset", lastReset_);
debug.SC_APPEND_STR_TIME("beginPresence", now);
#endif
}
void OneWireSlave::endPresence_()
{
unsigned long now = micros();
releaseBus_();
#ifdef DEBUG_LOG
debug.SC_APPEND_STR_TIME("endPresence", now);
#endif
beginWaitCommand_();
}
void OneWireSlave::beginWaitCommand_()
{
receiveTarget_ = ReceiveCommand;
beginReceive_();
}
void OneWireSlave::beginReceive_()
{
receivingByte_ = 0;
receivingBitPos_ = 0;
beginReceiveBit_(&OneWireSlave::onBitReceived_);
}
void OneWireSlave::onBitReceived_(bool bit, bool error)
{
if (error)

4
OneWireSlave.h

@ -39,6 +39,9 @@ private:
static void beginReceiveBit_(void(*completeCallback)(bool bit, bool error));
static void beginSendBit_(bool bit, void(*completeCallback)(bool error));
static void beginResetDetection_();
static void cancelResetDetection_();
static void beginWaitReset_();
static void beginWaitCommand_();
static void beginReceive_();
@ -58,6 +61,7 @@ private:
static void sendBitOne_();
static void sendBitZero_();
static void endSendBitZero_();
static void resetCheck_();
private:
static byte rom_[8];

Loading…
Cancel
Save