From a2949d505f977ab267ce28c4b02ad17a4088a4e1 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry <s.mistry@arduino.cc> Date: Wed, 18 Nov 2015 09:19:04 -0500 Subject: [PATCH] Wait for idle or bus owner state in startTransmissionWIRE instead of storing repeated start state. --- cores/arduino/SERCOM.cpp | 14 +++++++------- cores/arduino/SERCOM.h | 2 +- libraries/Wire/Wire.cpp | 6 ++---- libraries/Wire/Wire.h | 1 - 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index b45ecdc4..dacae227 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -476,17 +476,12 @@ void SERCOM::prepareCommandBitsWire(SercomMasterCommandWire cmd) } bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag) -{ - return startTransmissionWIRE(address, flag, false); -} - -bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag, bool repeatedStart) { // 7-bits address + 1-bits R/W address = (address << 0x1ul) | flag; - // Wait idle bus mode - while ( !repeatedStart && !isBusIdleWIRE()); + // Wait idle or owner bus mode + while ( !isBusIdleWIRE() && !isBusOwnerWIRE() ); // Send start and address sercom->I2CM.ADDR.bit.ADDR = address; @@ -580,6 +575,11 @@ bool SERCOM::isBusIdleWIRE( void ) return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE; } +bool SERCOM::isBusOwnerWIRE( void ) +{ + return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE; +} + bool SERCOM::isDataReadyWIRE( void ) { return sercom->I2CS.INTFLAG.bit.DRDY; diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h index 307f5a9c..26a437e8 100644 --- a/cores/arduino/SERCOM.h +++ b/cores/arduino/SERCOM.h @@ -194,12 +194,12 @@ class SERCOM void prepareAckBitWIRE( void ) ; void prepareCommandBitsWire(SercomMasterCommandWire cmd); bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag) ; - bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag, bool repeatedStart) ; bool sendDataMasterWIRE(uint8_t data) ; bool sendDataSlaveWIRE(uint8_t data) ; bool isMasterWIRE( void ) ; bool isSlaveWIRE( void ) ; bool isBusIdleWIRE( void ) ; + bool isBusOwnerWIRE( void ) ; bool isDataReadyWIRE( void ) ; bool isStopDetectedWIRE( void ) ; bool isRestartDetectedWIRE( void ) ; diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index c4747947..21d39f71 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -68,7 +68,7 @@ uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) size_t byteRead = 0; - if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG, repeatedStart)) + if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG)) { // Read first data rxBuffer.store_char(sercom->readDataWIRE()); @@ -83,7 +83,6 @@ uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) sercom->prepareNackBitWIRE(); // Prepare NACK to stop slave transmission //sercom->readDataWIRE(); // Clear data register to send NACK - repeatedStart = !stopBit; if (stopBit) { sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); // Send Stop @@ -117,7 +116,7 @@ uint8_t TwoWire::endTransmission(bool stopBit) transmissionBegun = false ; // Start I2C transmission - if ( !sercom->startTransmissionWIRE( txAddress, WIRE_WRITE_FLAG, repeatedStart ) ) + if ( !sercom->startTransmissionWIRE( txAddress, WIRE_WRITE_FLAG ) ) { sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); return 2 ; // Address error @@ -134,7 +133,6 @@ uint8_t TwoWire::endTransmission(bool stopBit) } } - repeatedStart = !stopBit; if (stopBit) { sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index bc2968ab..ab7ccae6 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -67,7 +67,6 @@ class TwoWire : public Stream uint8_t _uc_pinSCL; bool transmissionBegun; - bool repeatedStart; // RX Buffer RingBuffer rxBuffer; -- GitLab