Skip to content

Added multi address slave #2403

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
35 changes: 35 additions & 0 deletions hardware/arduino/avr/libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Modified 2012 by Todd Krein ([email protected]) to implement repeated starts
Modified 2014 by Nicola Corna ([email protected])
Moved pullups enable from twi.c to Wire.cpp
Added multi address slave
*/

extern "C" {
Expand All @@ -27,6 +30,8 @@ extern "C" {
}

#include "Wire.h"
#include "Arduino.h" // for digitalWrite
#include "pins_arduino.h"

// Initialize Class Variables //////////////////////////////////////////////////

Expand Down Expand Up @@ -59,6 +64,10 @@ void TwoWire::begin(void)
txBufferIndex = 0;
txBufferLength = 0;

// activate internal pullups for twi.
digitalWrite(SDA, 1);
digitalWrite(SCL, 1);

twi_init();
}

Expand All @@ -75,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;
Expand Down
10 changes: 10 additions & 0 deletions hardware/arduino/avr/libraries/Wire/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Modified 2012 by Todd Krein ([email protected]) to implement repeated starts
Modified 2014 by Nicola Corna ([email protected])
Added multi address slave
*/

#ifndef TwoWire_h
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions hardware/arduino/avr/libraries/Wire/keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#######################################

begin KEYWORD2
slaveAddress KEYWORD2
setClock KEYWORD2
beginTransmission KEYWORD2
endTransmission KEYWORD2
Expand Down
69 changes: 59 additions & 10 deletions hardware/arduino/avr/libraries/Wire/utility/twi.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Modified 2012 by Todd Krein ([email protected]) to implement repeated starts
Modified 2014 by Nicola Corna ([email protected])
Moved pullups enable from twi.c to Wire.cpp
Updated deprecated include <compat/twi.c>
Added multi address slave
*/

#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <compat/twi.h>
#include "Arduino.h" // for digitalWrite
#include <util/twi.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
Expand All @@ -35,7 +38,6 @@
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#include "pins_arduino.h"
#include "twi.h"

static volatile uint8_t twi_state;
Expand All @@ -59,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
Expand All @@ -71,10 +77,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);
Expand All @@ -88,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
*/
Expand All @@ -102,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
Expand Down Expand Up @@ -443,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);
Expand Down Expand Up @@ -484,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
Expand Down
12 changes: 11 additions & 1 deletion hardware/arduino/avr/libraries/Wire/utility/twi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 ([email protected])
Added multi address slave
*/

#ifndef twi_h
#define twi_h

#include <inttypes.h>

#include <avr/io.h>

//#define ATMEGA8

#ifndef TWI_FREQ
Expand All @@ -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);
Expand Down