Skip to content

Wire Slave #46

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

Merged
merged 3 commits into from
Nov 18, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Changes to get Wire slave receiver working
  • Loading branch information
sandeepmistry committed Sep 8, 2015
commit 4efe39eb4908109bdbd96e9c4f23894e7e5b4523
36 changes: 23 additions & 13 deletions cores/arduino/SERCOM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,14 +410,12 @@ void SERCOM::initSlaveWIRE( uint8_t ucAddress )
// Set slave mode
sercom->I2CS.CTRLA.bit.MODE = I2C_SLAVE_OPERATION ;

// Enable Quick Command
sercom->I2CM.CTRLB.bit.QCEN = 1 ;

sercom->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits
SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ; // 0x3FF all bits set

// Set the interrupt register
sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_AMATCH | // Address Match
sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_PREC | // Stop
SERCOM_I2CS_INTENSET_AMATCH | // Address Match
SERCOM_I2CS_INTENSET_DRDY ; // Data Ready

while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 )
Expand Down Expand Up @@ -450,23 +448,35 @@ void SERCOM::initMasterWIRE( uint32_t baudrate )

void SERCOM::prepareNackBitWIRE( void )
{
// Send a NACK
sercom->I2CM.CTRLB.bit.ACKACT = 1;
if(isMasterWIRE()) {
// Send a NACK
sercom->I2CM.CTRLB.bit.ACKACT = 1;
} else {
sercom->I2CS.CTRLB.bit.ACKACT = 1;
}
}

void SERCOM::prepareAckBitWIRE( void )
{
// Send an ACK
sercom->I2CM.CTRLB.bit.ACKACT = 0;
if(isMasterWIRE()) {
// Send an ACK
sercom->I2CM.CTRLB.bit.ACKACT = 0;
} else {
sercom->I2CS.CTRLB.bit.ACKACT = 0;
}
}

void SERCOM::prepareCommandBitsWire(SercomMasterCommandWire cmd)
void SERCOM::prepareCommandBitsWire(uint8_t cmd)
{
sercom->I2CM.CTRLB.bit.CMD = cmd;
if(isMasterWIRE()) {
sercom->I2CM.CTRLB.bit.CMD = cmd;

while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
{
// Waiting for synchronization
while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
{
// Waiting for synchronization
}
} else {
sercom->I2CS.CTRLB.bit.CMD = cmd;
}
}

Expand Down
2 changes: 1 addition & 1 deletion cores/arduino/SERCOM.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class SERCOM
void disableWIRE( void );
void prepareNackBitWIRE( void ) ;
void prepareAckBitWIRE( void ) ;
void prepareCommandBitsWire(SercomMasterCommandWire cmd);
void prepareCommandBitsWire(uint8_t cmd);
bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag) ;
bool sendDataMasterWIRE(uint8_t data) ;
bool sendDataSlaveWIRE(uint8_t data) ;
Expand Down
50 changes: 32 additions & 18 deletions libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ void TwoWire::begin(uint8_t address) {
//Slave mode
sercom->initSlaveWIRE(address);
sercom->enableWIRE();

pinPeripheral(_uc_pinSDA, g_APinDescription[_uc_pinSDA].ulPinType);
pinPeripheral(_uc_pinSCL, g_APinDescription[_uc_pinSCL].ulPinType);
}

void TwoWire::end() {
Expand Down Expand Up @@ -216,26 +219,11 @@ void TwoWire::onService(void)
{
if ( sercom->isSlaveWIRE() )
{
//Received data
if(sercom->isDataReadyWIRE())
if(sercom->isAddressMatch()) //Address Match
{
//Store data
rxBuffer.store_char(sercom->readDataWIRE());

//Stop or Restart detected
if(sercom->isStopDetectedWIRE() || sercom->isRestartDetectedWIRE())
{
//Calling onReceiveCallback, if exists
if(onReceiveCallback)
{
onReceiveCallback(available());
}
}
}
sercom->prepareAckBitWIRE();
sercom->prepareCommandBitsWire(0x03);

//Address Match
if(sercom->isAddressMatch())
{
//Is a request ?
if(sercom->isMasterReadOperationWIRE())
{
Expand All @@ -246,6 +234,32 @@ void TwoWire::onService(void)
}
}
}
else if(sercom->isDataReadyWIRE()) //Received data
{
if (rxBuffer.isFull()) {
sercom->prepareNackBitWIRE();
} else {
//Store data
rxBuffer.store_char(sercom->readDataWIRE());

sercom->prepareAckBitWIRE();
}

sercom->prepareCommandBitsWire(0x03);
}
else if(sercom->isStopDetectedWIRE() || sercom->isRestartDetectedWIRE()) //Stop or Restart detected
{
sercom->prepareAckBitWIRE();
sercom->prepareCommandBitsWire(0x03);

//Calling onReceiveCallback, if exists
if(onReceiveCallback)
{
onReceiveCallback(available());
}

rxBuffer.clear();
}
}
}

Expand Down