From 9b4e9fd3eda5760602dd28a14f78ccb830ed9076 Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Sun, 2 Nov 2014 12:53:28 +0100 Subject: [PATCH 1/3] Moved pullups enable from twi.c to Wire.cpp Now utility/twi.* is a pure AVR libc library, that can be used without Arduino --- hardware/arduino/avr/libraries/Wire/Wire.cpp | 8 ++++++++ hardware/arduino/avr/libraries/Wire/utility/twi.c | 9 +++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/hardware/arduino/avr/libraries/Wire/Wire.cpp b/hardware/arduino/avr/libraries/Wire/Wire.cpp index 553add78227..0802d6c7f2c 100644 --- a/hardware/arduino/avr/libraries/Wire/Wire.cpp +++ b/hardware/arduino/avr/libraries/Wire/Wire.cpp @@ -17,6 +17,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts + Modified 2014 by Nicola Corna (nicola@corna.info) + Moved pullups enable from twi.c to Wire.cpp */ extern "C" { @@ -27,6 +29,8 @@ extern "C" { } #include "Wire.h" +#include "Arduino.h" // for digitalWrite +#include "pins_arduino.h" // Initialize Class Variables ////////////////////////////////////////////////// @@ -59,6 +63,10 @@ void TwoWire::begin(void) txBufferIndex = 0; txBufferLength = 0; + // activate internal pullups for twi. + digitalWrite(SDA, 1); + digitalWrite(SCL, 1); + twi_init(); } diff --git a/hardware/arduino/avr/libraries/Wire/utility/twi.c b/hardware/arduino/avr/libraries/Wire/utility/twi.c index 201d7d1bbbf..c1ab68419fc 100644 --- a/hardware/arduino/avr/libraries/Wire/utility/twi.c +++ b/hardware/arduino/avr/libraries/Wire/utility/twi.c @@ -17,15 +17,17 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts + Modified 2014 by Nicola Corna (nicola@corna.info) + Moved pullups enable from twi.c to Wire.cpp */ #include #include +#include #include #include #include #include -#include "Arduino.h" // for digitalWrite #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) @@ -35,7 +37,6 @@ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif -#include "pins_arduino.h" #include "twi.h" static volatile uint8_t twi_state; @@ -71,10 +72,6 @@ void twi_init(void) twi_state = TWI_READY; twi_sendStop = true; // default value twi_inRepStart = false; - - // activate internal pullups for twi. - digitalWrite(SDA, 1); - digitalWrite(SCL, 1); // initialize twi prescaler and bit rate cbi(TWSR, TWPS0); From 0510efdebfc49a589adf3c36049c508bf8e091c0 Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Sun, 2 Nov 2014 14:25:41 +0100 Subject: [PATCH 2/3] Updated deprecated include As reported here https://lists.nongnu.org/archive/html/avr-libc-commit/2005-11/msg00009.html has been moved to in 2005 --- hardware/arduino/avr/libraries/Wire/utility/twi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hardware/arduino/avr/libraries/Wire/utility/twi.c b/hardware/arduino/avr/libraries/Wire/utility/twi.c index c1ab68419fc..cd8a134c923 100644 --- a/hardware/arduino/avr/libraries/Wire/utility/twi.c +++ b/hardware/arduino/avr/libraries/Wire/utility/twi.c @@ -19,6 +19,7 @@ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts Modified 2014 by Nicola Corna (nicola@corna.info) Moved pullups enable from twi.c to Wire.cpp + Updated deprecated include */ #include @@ -27,7 +28,7 @@ #include #include #include -#include +#include #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) From 9cb152b43122f84f11bd2fe156bf67d171d0d4a3 Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Sun, 2 Nov 2014 23:00:37 +0100 Subject: [PATCH 3/3] Added multi address slave Added begin and setAddressAndMask warnings if called with mask on a uC without mask support --- hardware/arduino/avr/libraries/Wire/Wire.cpp | 27 +++++++++ hardware/arduino/avr/libraries/Wire/Wire.h | 10 ++++ .../arduino/avr/libraries/Wire/keywords.txt | 1 + .../arduino/avr/libraries/Wire/utility/twi.c | 57 ++++++++++++++++++- .../arduino/avr/libraries/Wire/utility/twi.h | 12 +++- 5 files changed, 103 insertions(+), 4 deletions(-) diff --git a/hardware/arduino/avr/libraries/Wire/Wire.cpp b/hardware/arduino/avr/libraries/Wire/Wire.cpp index 0802d6c7f2c..af5295d387d 100644 --- a/hardware/arduino/avr/libraries/Wire/Wire.cpp +++ b/hardware/arduino/avr/libraries/Wire/Wire.cpp @@ -19,6 +19,7 @@ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts Modified 2014 by Nicola Corna (nicola@corna.info) Moved pullups enable from twi.c to Wire.cpp + Added multi address slave */ extern "C" { @@ -83,6 +84,32 @@ void TwoWire::begin(int address) begin((uint8_t)address); } +void TwoWire::begin(uint8_t address, uint8_t mask) +{ +#ifdef TWAMR + twi_setAddressAndMask(address, mask); +#else + twi_setAddress(address); //Just to show the function warning only once +#endif + twi_attachSlaveTxEvent(onRequestService); + twi_attachSlaveRxEvent(onReceiveService); + begin(); +} + +void TwoWire::begin(int address, int mask) +{ +#ifdef TWAMR + begin((uint8_t)address, (uint8_t)mask); +#else + begin((uint8_t)address); //Just to show the function warning only once +#endif +} + +uint8_t TwoWire::slaveAddress() +{ + return twi_slaveAddress(); +} + void TwoWire::setClock(uint32_t frequency) { TWBR = ((F_CPU / frequency) - 16) / 2; diff --git a/hardware/arduino/avr/libraries/Wire/Wire.h b/hardware/arduino/avr/libraries/Wire/Wire.h index 732bdc314e9..b5d10db44a6 100644 --- a/hardware/arduino/avr/libraries/Wire/Wire.h +++ b/hardware/arduino/avr/libraries/Wire/Wire.h @@ -17,6 +17,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts + Modified 2014 by Nicola Corna (nicola@corna.info) + Added multi address slave */ #ifndef TwoWire_h @@ -49,6 +51,14 @@ class TwoWire : public Stream void begin(); void begin(uint8_t); void begin(int); +#ifdef TWAMR + void begin(uint8_t, uint8_t); + void begin(int, int); +#else + void begin(uint8_t, uint8_t) __attribute__((warning("I2C address masking is unsupported on this microcontroller. Mask 0x00 will be used."))); + void begin(int, int) __attribute__((warning("I2C address masking is unsupported on this microcontroller. Mask 0x00 will be used."))); +#endif + uint8_t slaveAddress(); void setClock(uint32_t); void beginTransmission(uint8_t); void beginTransmission(int); diff --git a/hardware/arduino/avr/libraries/Wire/keywords.txt b/hardware/arduino/avr/libraries/Wire/keywords.txt index ff31475920a..3d1144381f2 100644 --- a/hardware/arduino/avr/libraries/Wire/keywords.txt +++ b/hardware/arduino/avr/libraries/Wire/keywords.txt @@ -11,6 +11,7 @@ ####################################### begin KEYWORD2 +slaveAddress KEYWORD2 setClock KEYWORD2 beginTransmission KEYWORD2 endTransmission KEYWORD2 diff --git a/hardware/arduino/avr/libraries/Wire/utility/twi.c b/hardware/arduino/avr/libraries/Wire/utility/twi.c index cd8a134c923..62775815a80 100644 --- a/hardware/arduino/avr/libraries/Wire/utility/twi.c +++ b/hardware/arduino/avr/libraries/Wire/utility/twi.c @@ -20,13 +20,13 @@ Modified 2014 by Nicola Corna (nicola@corna.info) Moved pullups enable from twi.c to Wire.cpp Updated deprecated include + Added multi address slave */ #include #include #include #include -#include #include #include @@ -61,6 +61,10 @@ static volatile uint8_t twi_rxBufferIndex; static volatile uint8_t twi_error; +#ifdef TWAMR +static volatile uint8_t twi_lastSlaveAddress; +#endif + /* * Function twi_init * Desc readys twi pins and sets twi bitrate @@ -86,11 +90,16 @@ void twi_init(void) // enable twi module, acks, and twi interrupt TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); + +#ifdef TWAMR + // initialize to 0 + twi_lastSlaveAddress = 0x00; +#endif } /* - * Function twi_slaveInit - * Desc sets slave address and enables interrupt + * Function twi_setAddress + * Desc set the slave address * Input none * Output none */ @@ -100,6 +109,40 @@ void twi_setAddress(uint8_t address) TWAR = address << 1; } +/* + * Function twi_setAddressAndMask + * Desc sets slave address and slave address mask + * Input address: slave address + * mask: slave address mask + * Output none + */ +void twi_setAddressAndMask(uint8_t address, uint8_t mask) +{ + // set twi slave address (skip over TWGCE bit) + TWAR = address << 1; +#ifdef TWAMR + //set twi slave address mask + TWAMR = mask << 1; +#endif +} + +/* + * Function twi_slaveAddress + * Desc return the last called slave address + * Input none + * Output the slave address + */ +uint8_t twi_slaveAddress(void) +{ + //If address masking is not supported, returns the only address + //supported (saved in TWAR) +#ifdef TWAMR + return twi_lastSlaveAddress; +#else + return TWAR >> 1; +#endif +} + /* * Function twi_readFrom * Desc attempts to become twi bus master and read a @@ -441,6 +484,10 @@ ISR(TWI_vect) case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack // enter slave receiver mode twi_state = TWI_SRX; +#ifdef TWAMR + // save the current TWDR (slave address) + twi_lastSlaveAddress = TWDR >> 1; +#endif // indicate that rx buffer can be overwritten and ack twi_rxBufferIndex = 0; twi_reply(1); @@ -482,6 +529,10 @@ ISR(TWI_vect) case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack // enter slave transmitter mode twi_state = TWI_STX; +#ifdef TWAMR + // save the current TWDR (slave address) + twi_lastSlaveAddress = TWDR >> 1; +#endif // ready the tx buffer index for iteration twi_txBufferIndex = 0; // set tx buffer length to be zero, to verify if user changes it diff --git a/hardware/arduino/avr/libraries/Wire/utility/twi.h b/hardware/arduino/avr/libraries/Wire/utility/twi.h index 6526593394e..a10fc755607 100644 --- a/hardware/arduino/avr/libraries/Wire/utility/twi.h +++ b/hardware/arduino/avr/libraries/Wire/utility/twi.h @@ -15,13 +15,17 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 2014 by Nicola Corna (nicola@corna.info) + Added multi address slave */ #ifndef twi_h #define twi_h #include - + #include + //#define ATMEGA8 #ifndef TWI_FREQ @@ -40,6 +44,12 @@ void twi_init(void); void twi_setAddress(uint8_t); +#ifdef TWAMR + void twi_setAddressAndMask(uint8_t, uint8_t); +#else + void twi_setAddressAndMask(uint8_t, uint8_t) __attribute__((warning("I2C address masking is unsupported on this microcontroller. Mask 0x00 will be used."))); +#endif + uint8_t twi_slaveAddress(void); uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); uint8_t twi_transmit(const uint8_t*, uint8_t);