From ccfc7db988fe2f61dd3f8734794fa9f69730f58d Mon Sep 17 00:00:00 2001 From: Dennis Ernst <95239117+DennisErnst@users.noreply.github.com> Date: Thu, 18 Jul 2024 12:43:41 -0700 Subject: [PATCH 1/3] Add files via upload --- cores/arduino/SERCOM.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index 9a75730fd..3a9191b1c 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -559,6 +559,12 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag while( !sercom->I2CM.INTFLAG.bit.MB ) { // Wait transmission complete + + // If certain errors occur, the MB bit may never be set (RFTM: SAMD21 sec:28.10.6; SAMD51 sec:36.10.7). + // There are additional errors that can occur (including BUSERR) that are rolled up in INTFLAG.ERROR + if (sercom->I2CM.INTFLAG.bit.ERROR) { + return false; + } } } else // Read mode @@ -566,8 +572,9 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag while( !sercom->I2CM.INTFLAG.bit.SB ) { // If the slave NACKS the address, the MB bit will be set. + // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register // In that case, send a stop condition and return false. - if (sercom->I2CM.INTFLAG.bit.MB) { + if (sercom->I2CM.INTFLAG.bit.ERROR || sercom->I2CM.INTFLAG.bit.MB) { sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition return false; } @@ -600,7 +607,8 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data) // If a bus error occurs, the MB bit may never be set. // Check the bus error bit and bail if it's set. - if (sercom->I2CM.STATUS.bit.BUSERR) { + // There are additional errors that can occur (including BUSERR) that are rolled up in INTFLAG.ERROR + if (sercom->I2CM.INTFLAG.bit.ERROR) { return false; } } @@ -704,6 +712,15 @@ uint8_t SERCOM::readDataWIRE( void ) while( sercom->I2CM.INTFLAG.bit.SB == 0 ) { // Waiting complete receive + // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register + // In that case, send a stop condition and return false. + // readDataWIRE should really be able to indicate an error (which would never be used + // because the readDataWIRE caller should have checked availableWIRE() first and timed it + // out if the data never showed up + if (sercom->I2CM.INTFLAG.bit.ERROR || sercom->I2CM.INTFLAG.bit.MB) { + sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition + return 0xFF; + } } return sercom->I2CM.DATA.bit.DATA ; From 6e5580d9b2de84c6be686459a2d3bd2b674f81b1 Mon Sep 17 00:00:00 2001 From: Dennis Ernst <95239117+DennisErnst@users.noreply.github.com> Date: Sun, 21 Jul 2024 10:50:03 -0700 Subject: [PATCH 2/3] Add files via upload --- cores/arduino/SERCOM.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index 3a9191b1c..c96171b05 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -561,7 +561,8 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag // Wait transmission complete // If certain errors occur, the MB bit may never be set (RFTM: SAMD21 sec:28.10.6; SAMD51 sec:36.10.7). - // There are additional errors that can occur (including BUSERR) that are rolled up in INTFLAG.ERROR + // The data transfer errors that can occur (including BUSERR) are all + // rolled up into INTFLAG.bit.ERROR from STATUS.reg if (sercom->I2CM.INTFLAG.bit.ERROR) { return false; } @@ -605,9 +606,10 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data) //Wait transmission successful while(!sercom->I2CM.INTFLAG.bit.MB) { - // If a bus error occurs, the MB bit may never be set. - // Check the bus error bit and bail if it's set. - // There are additional errors that can occur (including BUSERR) that are rolled up in INTFLAG.ERROR + // If a data transfer error occurs, the MB bit may never be set. + // Check the error bit and bail if it's set. + // The data transfer errors that can occur (including BUSERR) are all + // rolled up into INTFLAG.bit.ERROR from STATUS.reg if (sercom->I2CM.INTFLAG.bit.ERROR) { return false; } @@ -715,7 +717,7 @@ uint8_t SERCOM::readDataWIRE( void ) // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register // In that case, send a stop condition and return false. // readDataWIRE should really be able to indicate an error (which would never be used - // because the readDataWIRE caller should have checked availableWIRE() first and timed it + // because the readDataWIRE callers (in Wire.cpp) should have checked availableWIRE() first and timed it // out if the data never showed up if (sercom->I2CM.INTFLAG.bit.ERROR || sercom->I2CM.INTFLAG.bit.MB) { sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition From c8287a11c616ec4c39a8a4e6fdd7da5e2600a9c0 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Sep 2024 18:47:37 +0700 Subject: [PATCH 3/3] clean up format --- cores/arduino/SERCOM.cpp | 56 +++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index c96171b05..732393ebc 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -556,37 +556,35 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag // Address Transmitted if ( flag == WIRE_WRITE_FLAG ) // Write mode { - while( !sercom->I2CM.INTFLAG.bit.MB ) - { + while( !sercom->I2CM.INTFLAG.bit.MB ) { // Wait transmission complete - // If certain errors occur, the MB bit may never be set (RFTM: SAMD21 sec:28.10.6; SAMD51 sec:36.10.7). - // The data transfer errors that can occur (including BUSERR) are all - // rolled up into INTFLAG.bit.ERROR from STATUS.reg - if (sercom->I2CM.INTFLAG.bit.ERROR) { - return false; - } + // If certain errors occur, the MB bit may never be set (RFTM: SAMD21 sec:28.10.6; SAMD51 sec:36.10.7). + // The data transfer errors that can occur (including BUSERR) are all + // rolled up into INTFLAG.bit.ERROR from STATUS.reg + if (sercom->I2CM.INTFLAG.bit.ERROR) { + return false; + } } } else // Read mode { - while( !sercom->I2CM.INTFLAG.bit.SB ) - { - // If the slave NACKS the address, the MB bit will be set. - // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register - // In that case, send a stop condition and return false. - if (sercom->I2CM.INTFLAG.bit.ERROR || sercom->I2CM.INTFLAG.bit.MB) { - sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition - return false; - } + while( !sercom->I2CM.INTFLAG.bit.SB ) { // Wait transmission complete + + // If the slave NACKS the address, the MB bit will be set. + // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register + // In that case, send a stop condition and return false. + if (sercom->I2CM.INTFLAG.bit.MB || sercom->I2CM.INTFLAG.bit.ERROR) { + sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition + return false; + } } // Clean the 'Slave on Bus' flag, for further usage. //sercom->I2CM.INTFLAG.bit.SB = 0x1ul; } - //ACK received (0: ACK, 1: NACK) if(sercom->I2CM.STATUS.bit.RXNACK) { @@ -605,11 +603,10 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data) //Wait transmission successful while(!sercom->I2CM.INTFLAG.bit.MB) { - // If a data transfer error occurs, the MB bit may never be set. // Check the error bit and bail if it's set. // The data transfer errors that can occur (including BUSERR) are all - // rolled up into INTFLAG.bit.ERROR from STATUS.reg + // rolled up into INTFLAG.bit.ERROR from STATUS.reg if (sercom->I2CM.INTFLAG.bit.ERROR) { return false; } @@ -711,18 +708,17 @@ uint8_t SERCOM::readDataWIRE( void ) { if(isMasterWIRE()) { - while( sercom->I2CM.INTFLAG.bit.SB == 0 ) - { + while (sercom->I2CM.INTFLAG.bit.SB == 0) { // Waiting complete receive - // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register + // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register // In that case, send a stop condition and return false. - // readDataWIRE should really be able to indicate an error (which would never be used - // because the readDataWIRE callers (in Wire.cpp) should have checked availableWIRE() first and timed it - // out if the data never showed up - if (sercom->I2CM.INTFLAG.bit.ERROR || sercom->I2CM.INTFLAG.bit.MB) { - sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition - return 0xFF; - } + // readDataWIRE should really be able to indicate an error (which would never be used + // because the readDataWIRE callers (in Wire.cpp) should have checked availableWIRE() first and timed it + // out if the data never showed up + if (sercom->I2CM.INTFLAG.bit.MB || sercom->I2CM.INTFLAG.bit.ERROR) { + sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition + return 0xFF; + } } return sercom->I2CM.DATA.bit.DATA ;