Browse Source

- breaking change: OneWireSlave::write has been renamed to OneWireSlave::beginWrite, to show it's asynchronous. A new function OneWireSlave::write has been introduced, which is synchronous (and can't be called from an interrupt handler)

- added code to make sure a client completion callback will always get called, even if it's because of a reset or an error
timer1
Youen Toupin 9 years ago
parent
commit
b92a13a59d
  1. 60
      OneWireSlave.cpp
  2. 15
      OneWireSlave.h

60
OneWireSlave.cpp

@ -57,6 +57,11 @@ short OneWireSlave::bufferPos_;
void(*OneWireSlave::receiveBytesCallback_)(bool error); void(*OneWireSlave::receiveBytesCallback_)(bool error);
void(*OneWireSlave::sendBytesCallback_)(bool error); void(*OneWireSlave::sendBytesCallback_)(bool error);
bool OneWireSlave::waitingSynchronousWriteToComplete_;
bool OneWireSlave::synchronousWriteError_;
bool OneWireSlave::sendingClientBytes_;
bool OneWireSlave::singleBit_; bool OneWireSlave::singleBit_;
bool OneWireSlave::singleBitRepeat_; bool OneWireSlave::singleBitRepeat_;
void(*OneWireSlave::singleBitSentCallback_)(bool error); void(*OneWireSlave::singleBitSentCallback_)(bool error);
@ -83,6 +88,7 @@ void OneWireSlave::begin(const byte* rom, byte pinNumber)
alarmedFlag_ = false; alarmedFlag_ = false;
clientReceiveBitCallback_ = 0; clientReceiveBitCallback_ = 0;
sendingClientBytes_ = false;
// log("Enabling 1-wire library") // log("Enabling 1-wire library")
@ -112,16 +118,56 @@ void OneWireSlave::end()
sei(); sei();
} }
void OneWireSlave::write(const byte* bytes, short numBytes, void(*complete)(bool error)) bool OneWireSlave::write(const byte* bytes, short numBytes)
{
// TODO: put the arduino to sleep between interrupts to save power?
waitingSynchronousWriteToComplete_ = true;
beginWrite(bytes, numBytes, &OneWireSlave::onSynchronousWriteComplete_);
while (waitingSynchronousWriteToComplete_)
delay(1);
return synchronousWriteError_;
}
void OneWireSlave::onSynchronousWriteComplete_(bool error)
{
synchronousWriteError_ = error;
waitingSynchronousWriteToComplete_ = false;
}
void OneWireSlave::beginWrite(const byte* bytes, short numBytes, void(*complete)(bool error))
{ {
cli(); cli();
endClientWrite_(true);
sendingClientBytes_ = true;
beginWriteBytes_(bytes, numBytes, complete == 0 ? noOpCallback_ : complete); beginWriteBytes_(bytes, numBytes, complete == 0 ? noOpCallback_ : complete);
sei(); sei();
} }
void OneWireSlave::endClientWrite_(bool error)
{
if (sendingClientBytes_)
{
sendingClientBytes_ = false;
if (sendBytesCallback_ != 0)
{
void(*callback)(bool error) = sendBytesCallback_;
sendBytesCallback_ = noOpCallback_;
callback(error);
}
}
else if (singleBitSentCallback_ != 0)
{
void(*callback)(bool) = singleBitSentCallback_;
singleBitSentCallback_ = 0;
callback(error);
}
}
void OneWireSlave::writeBit(bool value, bool repeat, void(*bitSent)(bool)) void OneWireSlave::writeBit(bool value, bool repeat, void(*bitSent)(bool))
{ {
cli(); cli();
endClientWrite_(true);
singleBit_ = value; singleBit_ = value;
singleBitRepeat_ = repeat; singleBitRepeat_ = repeat;
singleBitSentCallback_ = bitSent; singleBitSentCallback_ = bitSent;
@ -142,13 +188,15 @@ void OneWireSlave::onSingleBitSent_(bool error)
if (singleBitSentCallback_ != 0) if (singleBitSentCallback_ != 0)
{ {
singleBitSentCallback_(error); void(*callback)(bool) = singleBitSentCallback_;
singleBitSentCallback_ = 0;
callback(error);
} }
} }
void OneWireSlave::stopWrite() void OneWireSlave::stopWrite()
{ {
write(0, 0, 0); beginWrite(0, 0, 0);
} }
void OneWireSlave::alarmed(bool value) void OneWireSlave::alarmed(bool value)
@ -200,6 +248,9 @@ void OneWireSlave::onLeaveInterrupt_()
void OneWireSlave::error_(const char* message) void OneWireSlave::error_(const char* message)
{ {
beginWaitReset_(); beginWaitReset_();
endClientWrite_(true);
if (clientReceiveCallback_ != 0)
clientReceiveCallback_(RE_Error, 0);
} }
void OneWireSlave::pullLow_() void OneWireSlave::pullLow_()
@ -354,6 +405,7 @@ void OneWireSlave::waitReset_()
lastReset_ = now; lastReset_ = now;
pin_.detachInterrupt(); pin_.detachInterrupt();
setTimerEvent_(PresenceWaitDuration - (micros() - now), &OneWireSlave::beginPresence_); setTimerEvent_(PresenceWaitDuration - (micros() - now), &OneWireSlave::beginPresence_);
endClientWrite_(true);
if (clientReceiveCallback_ != 0) if (clientReceiveCallback_ != 0)
clientReceiveCallback_(RE_Reset, 0); clientReceiveCallback_(RE_Reset, 0);
} }
@ -565,6 +617,7 @@ void OneWireSlave::beginWriteBytes_(const byte* data, short numBytes, void(*comp
} }
else else
{ {
endClientWrite_(true);
beginReceiveBytes_(scratchpad_, 1, &OneWireSlave::notifyClientByteReceived_); beginReceiveBytes_(scratchpad_, 1, &OneWireSlave::notifyClientByteReceived_);
} }
} }
@ -588,6 +641,7 @@ void OneWireSlave::bitSent_(bool error)
if (bufferPos_ == bufferLength_) if (bufferPos_ == bufferLength_)
{ {
beginWaitReset_(); beginWaitReset_();
endClientWrite_(false);
sendBytesCallback_(false); sendBytesCallback_(false);
return; return;
} }

15
OneWireSlave.h

@ -26,8 +26,11 @@ public:
//! Sets (or replaces) a function to be called when a bit is received. The byte reception callback is called after that if the received bit was the last of a byte. The callback is executed from interrupts and should be as short as possible. Failure to return quickly can prevent the library from correctly reading the next bit. //! Sets (or replaces) a function to be called when a bit is received. The byte reception callback is called after that if the received bit was the last of a byte. The callback is executed from interrupts and should be as short as possible. Failure to return quickly can prevent the library from correctly reading the next bit.
void setReceiveBitCallback(void(*callback)(bool bit)) { clientReceiveBitCallback_ = callback; } void setReceiveBitCallback(void(*callback)(bool bit)) { clientReceiveBitCallback_ = callback; }
//! Enqueues the specified bytes in the send buffer. They will be sent in the background. The optional callback is used to notify when the bytes are sent, or if an error occured. Callbacks are executed from interrupts and should be as short as possible. If bytes is null or numBytes is 0, nothing is sent, which is equivalent to calling stopWrite. In any case, calling the write function will cancel the previous write operation if it didn't complete yet. //! Writes the specified bytes synchronously. This function blocks until the write operation has finished. Do not call from an interrupt handler! Returns true in case of success, false if an error occured.
void write(const byte* bytes, short numBytes, void(*complete)(bool error)); bool write(const byte* bytes, short numBytes);
//! Starts sending the specified bytes. They will be sent in the background, and the buffer must remain valid and unchanged until the write operation has finished or is cancelled. The optional callback is used to notify when the bytes are sent, or if an error occured. Callbacks are executed from interrupts and should be as short as possible. If bytes is null or numBytes is 0, nothing is sent, which is equivalent to calling stopWrite. In any case, calling the write function will cancel the previous write operation if it didn't complete yet.
void beginWrite(const byte* bytes, short numBytes, void(*complete)(bool error));
//! Sets a bit that will be sent next time the master asks for one. Optionnaly, the repeat parameter can be set to true to continue sending the same bit each time. In both cases, the send operation can be canceled by calling stopWrite. //! Sets a bit that will be sent next time the master asks for one. Optionnaly, the repeat parameter can be set to true to continue sending the same bit each time. In both cases, the send operation can be canceled by calling stopWrite.
void writeBit(bool value, bool repeat = false, void(*bitSent)(bool error) = 0); void writeBit(bool value, bool repeat = false, void(*bitSent)(bool error) = 0);
@ -71,6 +74,9 @@ private:
static void beginWriteBytes_(const byte* data, short numBytes, void(*complete)(bool error)); static void beginWriteBytes_(const byte* data, short numBytes, void(*complete)(bool error));
static void beginReceiveBytes_(byte* buffer, short numBytes, void(*complete)(bool error)); static void beginReceiveBytes_(byte* buffer, short numBytes, void(*complete)(bool error));
static void endClientWrite_(bool error);
static void onSynchronousWriteComplete_(bool error);
static void noOpCallback_(bool error); static void noOpCallback_(bool error);
static void matchRomBytesReceived_(bool error); static void matchRomBytesReceived_(bool error);
static void notifyClientByteReceived_(bool error); static void notifyClientByteReceived_(bool error);
@ -115,6 +121,11 @@ private:
static void(*receiveBytesCallback_)(bool error); static void(*receiveBytesCallback_)(bool error);
static void(*sendBytesCallback_)(bool error); static void(*sendBytesCallback_)(bool error);
static bool waitingSynchronousWriteToComplete_;
static bool synchronousWriteError_;
static bool sendingClientBytes_;
static bool singleBit_; static bool singleBit_;
static bool singleBitRepeat_; static bool singleBitRepeat_;
static void (*singleBitSentCallback_)(bool error); static void (*singleBitSentCallback_)(bool error);

Loading…
Cancel
Save