Skip to content

add support for I2C repeated start, tested with MB85RC256V #78

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions cores/arduino/SERCOM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,17 +485,19 @@ void SERCOM::prepareCommandBitsWire(uint8_t cmd)
}
}

bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag)
bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag, bool _repeatstart)
{
// 7-bits address + 1-bits R/W
address = (address << 0x1ul) | flag;

// Wait idle bus mode
while ( !isBusIdleWIRE() );
// Wait idle bus mode (except repeated start)
if (! _repeatstart) {
while ( !isBusIdleWIRE() );
}

// Send start and address
// Send start and address, in repeated start mode this will kick off the repstart too!
sercom->I2CM.ADDR.bit.ADDR = address;

// Address Transmitted
if ( flag == WIRE_WRITE_FLAG ) // Write mode
{
Expand Down
2 changes: 1 addition & 1 deletion cores/arduino/SERCOM.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class SERCOM
void prepareNackBitWIRE( void ) ;
void prepareAckBitWIRE( void ) ;
void prepareCommandBitsWire(uint8_t cmd);
bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag) ;
bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag, bool rs = false);
bool sendDataMasterWIRE(uint8_t data) ;
bool sendDataSlaveWIRE(uint8_t data) ;
bool isMasterWIRE( void ) ;
Expand Down
17 changes: 15 additions & 2 deletions libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ TwoWire::TwoWire(SERCOM * s, uint8_t pinSDA, uint8_t pinSCL)
this->_uc_pinSDA=pinSDA;
this->_uc_pinSCL=pinSCL;
transmissionBegun = false;
_repeatedstart = false;
}

void TwoWire::begin(void) {
Expand Down Expand Up @@ -71,7 +72,7 @@ uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit)

size_t byteRead = 0;

if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG))
if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG, _repeatedstart))
{
// Read first data
rxBuffer.store_char(sercom->readDataWIRE());
Expand Down Expand Up @@ -114,6 +115,13 @@ uint8_t TwoWire::endTransmission(bool stopBit)
{
transmissionBegun = false ;

SercomMasterCommandWire cmd;
if (stopBit) {
_repeatedstart = false;
} else {
_repeatedstart = true;
}

// Start I2C transmission
if ( !sercom->startTransmissionWIRE( txAddress, WIRE_WRITE_FLAG ) )
{
Expand All @@ -131,7 +139,12 @@ uint8_t TwoWire::endTransmission(bool stopBit)
return 3 ; // Nack or error
}
}
sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);

if (stopBit) {
sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
}
/* We dont actually send any command now, next time we try to do a read
it will automagically send a repeated start, see Table 27-12. Command Description */

return 0;
}
Expand Down
4 changes: 3 additions & 1 deletion libraries/Wire/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ class TwoWire : public Stream
using Print::write;

void onService(void);

private:
SERCOM * sercom;

uint8_t _uc_pinSDA;
uint8_t _uc_pinSCL;

bool transmissionBegun;

bool _repeatedstart;

// RX Buffer
RingBuffer rxBuffer;

Expand Down