Skip to content

Commit 04bda59

Browse files
committed
2 parents 0d83c96 + 9a7f2be commit 04bda59

File tree

3 files changed

+58
-30
lines changed

3 files changed

+58
-30
lines changed

cores/arduino/SERCOM.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -415,14 +415,12 @@ void SERCOM::initSlaveWIRE( uint8_t ucAddress )
415415
// Set slave mode
416416
sercom->I2CS.CTRLA.bit.MODE = I2C_SLAVE_OPERATION ;
417417

418-
// Enable Quick Command
419-
sercom->I2CM.CTRLB.bit.QCEN = 1 ;
420-
421418
sercom->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits
422419
SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ; // 0x3FF all bits set
423420

424421
// Set the interrupt register
425-
sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_AMATCH | // Address Match
422+
sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_PREC | // Stop
423+
SERCOM_I2CS_INTENSET_AMATCH | // Address Match
426424
SERCOM_I2CS_INTENSET_DRDY ; // Data Ready
427425

428426
while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 )
@@ -455,23 +453,35 @@ void SERCOM::initMasterWIRE( uint32_t baudrate )
455453

456454
void SERCOM::prepareNackBitWIRE( void )
457455
{
458-
// Send a NACK
459-
sercom->I2CM.CTRLB.bit.ACKACT = 1;
456+
if(isMasterWIRE()) {
457+
// Send a NACK
458+
sercom->I2CM.CTRLB.bit.ACKACT = 1;
459+
} else {
460+
sercom->I2CS.CTRLB.bit.ACKACT = 1;
461+
}
460462
}
461463

462464
void SERCOM::prepareAckBitWIRE( void )
463465
{
464-
// Send an ACK
465-
sercom->I2CM.CTRLB.bit.ACKACT = 0;
466+
if(isMasterWIRE()) {
467+
// Send an ACK
468+
sercom->I2CM.CTRLB.bit.ACKACT = 0;
469+
} else {
470+
sercom->I2CS.CTRLB.bit.ACKACT = 0;
471+
}
466472
}
467473

468-
void SERCOM::prepareCommandBitsWire(SercomMasterCommandWire cmd)
474+
void SERCOM::prepareCommandBitsWire(uint8_t cmd)
469475
{
470-
sercom->I2CM.CTRLB.bit.CMD = cmd;
476+
if(isMasterWIRE()) {
477+
sercom->I2CM.CTRLB.bit.CMD = cmd;
471478

472-
while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
473-
{
474-
// Waiting for synchronization
479+
while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
480+
{
481+
// Waiting for synchronization
482+
}
483+
} else {
484+
sercom->I2CS.CTRLB.bit.CMD = cmd;
475485
}
476486
}
477487

cores/arduino/SERCOM.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class SERCOM
192192
void disableWIRE( void );
193193
void prepareNackBitWIRE( void ) ;
194194
void prepareAckBitWIRE( void ) ;
195-
void prepareCommandBitsWire(SercomMasterCommandWire cmd);
195+
void prepareCommandBitsWire(uint8_t cmd);
196196
bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag) ;
197197
bool sendDataMasterWIRE(uint8_t data) ;
198198
bool sendDataSlaveWIRE(uint8_t data) ;

libraries/Wire/Wire.cpp

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ void TwoWire::begin(uint8_t address) {
4747
//Slave mode
4848
sercom->initSlaveWIRE(address);
4949
sercom->enableWIRE();
50+
51+
pinPeripheral(_uc_pinSDA, g_APinDescription[_uc_pinSDA].ulPinType);
52+
pinPeripheral(_uc_pinSCL, g_APinDescription[_uc_pinSCL].ulPinType);
5053
}
5154

5255
void TwoWire::setClock(uint32_t baudrate) {
@@ -212,36 +215,51 @@ void TwoWire::onService(void)
212215
{
213216
if ( sercom->isSlaveWIRE() )
214217
{
215-
//Received data
216-
if(sercom->isDataReadyWIRE())
218+
if(sercom->isStopDetectedWIRE() ||
219+
(sercom->isAddressMatch() && sercom->isRestartDetectedWIRE() && !sercom->isMasterReadOperationWIRE())) //Stop or Restart detected
217220
{
218-
//Store data
219-
rxBuffer.store_char(sercom->readDataWIRE());
221+
sercom->prepareAckBitWIRE();
222+
sercom->prepareCommandBitsWire(0x03);
220223

221-
//Stop or Restart detected
222-
if(sercom->isStopDetectedWIRE() || sercom->isRestartDetectedWIRE())
224+
//Calling onReceiveCallback, if exists
225+
if(onReceiveCallback)
223226
{
224-
//Calling onReceiveCallback, if exists
225-
if(onReceiveCallback)
226-
{
227-
onReceiveCallback(available());
228-
}
227+
onReceiveCallback(available());
229228
}
229+
230+
rxBuffer.clear();
230231
}
231-
232-
//Address Match
233-
if(sercom->isAddressMatch())
232+
else if(sercom->isAddressMatch()) //Address Match
234233
{
235-
//Is a request ?
236-
if(sercom->isMasterReadOperationWIRE())
234+
sercom->prepareAckBitWIRE();
235+
sercom->prepareCommandBitsWire(0x03);
236+
237+
if(sercom->isMasterReadOperationWIRE()) //Is a request ?
237238
{
239+
// wait for data ready flag,
240+
// before calling request callback
241+
while(!sercom->isDataReadyWIRE());
242+
238243
//Calling onRequestCallback, if exists
239244
if(onRequestCallback)
240245
{
241246
onRequestCallback();
242247
}
243248
}
244249
}
250+
else if(sercom->isDataReadyWIRE()) //Received data
251+
{
252+
if (rxBuffer.isFull()) {
253+
sercom->prepareNackBitWIRE();
254+
} else {
255+
//Store data
256+
rxBuffer.store_char(sercom->readDataWIRE());
257+
258+
sercom->prepareAckBitWIRE();
259+
}
260+
261+
sercom->prepareCommandBitsWire(0x03);
262+
}
245263
}
246264
}
247265

0 commit comments

Comments
 (0)