diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index 2cfb172aa2b4dfc7ccf9075342bc40031f1c978c..08297882d75e365685dff72dca9d2957565f86c2 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -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 ) @@ -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; } } diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h index fbd27e624f96041d56357ed7e02dad1189f9f7d9..974cebd7c22de9dc0c242fe556c459eaa025e15a 100644 --- a/cores/arduino/SERCOM.h +++ b/cores/arduino/SERCOM.h @@ -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) ; diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 31e0a1d8a2d2a42648b88da717e2f049055a7aec..273b03e7458b9ccbee18b871b04685a8b4c7349a 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -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() { @@ -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()) { @@ -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(); + } } }