Browse Source

- breaking change: writeBit has been renamed to beginWriteBit to show it's asynchronous, and a new function writeBit has been introduced, which is synchronous and can't be called from an interrupt handler

- fixed possible bugs when a write operation is canceled and a timer interrupt is still registered
timer1
Youen Toupin 9 years ago
parent
commit
f068849a7d
  1. 31
      OneWireSlave.cpp
  2. 9
      OneWireSlave.h

31
OneWireSlave.cpp

@ -139,14 +139,17 @@ void OneWireSlave::onSynchronousWriteComplete_(bool error)
void OneWireSlave::beginWrite(const byte* bytes, short numBytes, void(*complete)(bool error)) void OneWireSlave::beginWrite(const byte* bytes, short numBytes, void(*complete)(bool error))
{ {
cli(); cli();
endClientWrite_(true); endWrite_(true);
sendingClientBytes_ = true; sendingClientBytes_ = true;
beginWriteBytes_(bytes, numBytes, complete == 0 ? noOpCallback_ : complete); beginWriteBytes_(bytes, numBytes, complete == 0 ? noOpCallback_ : complete);
sei(); sei();
} }
void OneWireSlave::endClientWrite_(bool error) void OneWireSlave::endWrite_(bool error, bool resetInterrupts)
{ {
if(resetInterrupts)
beginWaitReset_();
if (sendingClientBytes_) if (sendingClientBytes_)
{ {
sendingClientBytes_ = false; sendingClientBytes_ = false;
@ -165,10 +168,20 @@ void OneWireSlave::endClientWrite_(bool error)
} }
} }
void OneWireSlave::writeBit(bool value, bool repeat, void(*bitSent)(bool)) bool OneWireSlave::writeBit(bool value)
{
// TODO: put the arduino to sleep between interrupts to save power?
waitingSynchronousWriteToComplete_ = true;
beginWriteBit(value, false, &OneWireSlave::onSynchronousWriteComplete_);
while (waitingSynchronousWriteToComplete_)
delay(1);
return !synchronousWriteError_;
}
void OneWireSlave::beginWriteBit(bool value, bool repeat, void(*bitSent)(bool))
{ {
cli(); cli();
endClientWrite_(true); endWrite_(true);
singleBit_ = value; singleBit_ = value;
singleBitRepeat_ = repeat; singleBitRepeat_ = repeat;
@ -251,8 +264,7 @@ void OneWireSlave::error_(const char* message)
{ {
if (logCallback_ != 0) if (logCallback_ != 0)
logCallback_(message); logCallback_(message);
beginWaitReset_(); endWrite_(true);
endClientWrite_(true);
if (clientReceiveCallback_ != 0) if (clientReceiveCallback_ != 0)
clientReceiveCallback_(RE_Error, 0); clientReceiveCallback_(RE_Error, 0);
} }
@ -409,7 +421,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); endWrite_(true, false);
if (clientReceiveCallback_ != 0) if (clientReceiveCallback_ != 0)
clientReceiveCallback_(RE_Reset, 0); clientReceiveCallback_(RE_Reset, 0);
} }
@ -621,7 +633,7 @@ void OneWireSlave::beginWriteBytes_(const byte* data, short numBytes, void(*comp
} }
else else
{ {
endClientWrite_(true); endWrite_(true);
beginReceiveBytes_(scratchpad_, 1, &OneWireSlave::notifyClientByteReceived_); beginReceiveBytes_(scratchpad_, 1, &OneWireSlave::notifyClientByteReceived_);
} }
} }
@ -644,8 +656,7 @@ void OneWireSlave::bitSent_(bool error)
if (bufferPos_ == bufferLength_) if (bufferPos_ == bufferLength_)
{ {
beginWaitReset_(); endWrite_(false);
endClientWrite_(false);
sendBytesCallback_(false); sendBytesCallback_(false);
return; return;
} }

9
OneWireSlave.h

@ -29,14 +29,17 @@ public:
//! Sets (or replaces) a function to be called when the library has a message to log, if the functionality is enabled in OneWireSlave.cpp. This is for debugging purposes. //! Sets (or replaces) a function to be called when the library has a message to log, if the functionality is enabled in OneWireSlave.cpp. This is for debugging purposes.
void setLogCallback(void(*callback)(const char* message)) { logCallback_ = callback; } void setLogCallback(void(*callback)(const char* message)) { logCallback_ = callback; }
//! 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. //! 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 occurs.
bool write(const byte* bytes, short numBytes); 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. //! 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)); void beginWrite(const byte* bytes, short numBytes, void(*complete)(bool error));
//! Writes a single bit synchronously. This function blocks until the bit is sent. Do not call from an interrupt handler! Returns true in case of success, false if an error occurs.
bool writeBit(bool value);
//! 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 beginWriteBit(bool value, bool repeat = false, void(*bitSent)(bool error) = 0);
//! Cancels any pending write operation, started by writeBit or write. If this function is called before the master asked for a bit, then nothing is sent to the master. //! Cancels any pending write operation, started by writeBit or write. If this function is called before the master asked for a bit, then nothing is sent to the master.
void stopWrite(); void stopWrite();
@ -77,7 +80,7 @@ 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 endWrite_(bool error, bool resetInterrupts = true);
static void onSynchronousWriteComplete_(bool error); static void onSynchronousWriteComplete_(bool error);
static void noOpCallback_(bool error); static void noOpCallback_(bool error);

Loading…
Cancel
Save