diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index d2146f7..e4a42f5 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -42,6 +42,7 @@ uint8_t TwoWire::txBufferLength = 0; uint8_t TwoWire::transmitting = 0; void (*TwoWire::user_onRequest)(void); void (*TwoWire::user_onReceive)(int); +void (*TwoWire::user_onGcallReceive)(int); // Constructors //////////////////////////////////////////////////////////////// @@ -273,12 +274,22 @@ void TwoWire::flush(void) } // behind the scenes function that is called when data is received -void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) +void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes, uint8_t isGeneralCall) { - // don't bother if user hasn't registered a callback - if(!user_onReceive){ - return; - } + //check if general call or normal receive + if(isGeneralCall){ + // don't bother if user hasn't registered a general call callback + if(!user_onGcallReceive){ + return; + } + } + else{ + // don't bother if user hasn't registered a callback + if(!user_onReceive){ + return; + } + } + // don't bother if rx buffer is in use by a master requestFrom() op // i know this drops data, but it allows for slight stupidity // meaning, they may not have read all the master requestFrom() data yet @@ -293,8 +304,15 @@ void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) // set rx iterator vars rxBufferIndex = 0; rxBufferLength = numBytes; - // alert user program - user_onReceive(numBytes); + + if(isGeneralCall){ + // alert user's general call receive callback + user_onGcallReceive(numBytes); + } + else{ + // alert user's receive callback + user_onReceive(numBytes); + } } // behind the scenes function that is called when data is requested @@ -312,16 +330,27 @@ void TwoWire::onRequestService(void) user_onRequest(); } -// sets function called on slave write -void TwoWire::onReceive( void (*function)(int) ) +// sets function called when slave receives data from master at slave's address +void TwoWire::onReceive( void (*recFunction)(int) ) { - user_onReceive = function; + user_onReceive = recFunction; } -// sets function called on slave read -void TwoWire::onRequest( void (*function)(void) ) +// sets function called when slave receives data from master at slaves address +// and another function called when slave receives data from a general call +void TwoWire::onReceive( void (*recFunction)(int), void (*gcallRecFunction)(int) ) { - user_onRequest = function; + user_onReceive = recFunction; + user_onGcallReceive = gcallRecFunction; + + //enable general call addressing + twi_enableGenCall(); +} + +// sets function called when master requests data from slave +void TwoWire::onRequest( void (*reqFunction)(void) ) +{ + user_onRequest = reqFunction; } // Preinstantiate Objects ////////////////////////////////////////////////////// diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 702f37d..ae93ae4 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -45,8 +45,9 @@ class TwoWire : public Stream static uint8_t transmitting; static void (*user_onRequest)(void); static void (*user_onReceive)(int); + static void (*user_onGcallReceive)(int); static void onRequestService(void); - static void onReceiveService(uint8_t*, int); + static void onReceiveService(uint8_t*, int,uint8_t); public: TwoWire(); void begin(); @@ -70,6 +71,7 @@ class TwoWire : public Stream virtual int peek(void); virtual void flush(void); void onReceive( void (*)(int) ); + void onReceive( void (*)(int), void (*)(int) ); void onRequest( void (*)(void) ); inline size_t write(unsigned long n) { return write((uint8_t)n); } diff --git a/libraries/Wire/src/utility/twi.c b/libraries/Wire/src/utility/twi.c index 171af73..5abce9c 100644 --- a/libraries/Wire/src/utility/twi.c +++ b/libraries/Wire/src/utility/twi.c @@ -44,7 +44,7 @@ static volatile uint8_t twi_sendStop; // should the transaction end with a sto static volatile uint8_t twi_inRepStart; // in the middle of a repeated start static void (*twi_onSlaveTransmit)(void); -static void (*twi_onSlaveReceive)(uint8_t*, int); +static void (*twi_onSlaveReceive)(uint8_t*, int, uint8_t); static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; static volatile uint8_t twi_masterBufferIndex; @@ -58,6 +58,8 @@ static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; static volatile uint8_t twi_rxBufferIndex; static volatile uint8_t twi_error; +static volatile uint8_t twi_gcall_data; + /* * Function twi_init @@ -114,8 +116,8 @@ void twi_disable(void) */ void twi_setAddress(uint8_t address) { - // set twi slave address (skip over TWGCE bit) - TWAR = address << 1; + // set twi slave address and leave TWGCE bit (LSB) + TWAR = (address << TWA0) | ( TWAR & (1 << TWGCE) ) ; } /* @@ -134,6 +136,18 @@ void twi_setFrequency(uint32_t frequency) It is 72 for a 16mhz Wiring board with 100kHz TWI */ } +/* + * Function twi_enableGenCall + * Desc enables general call address for slave + * Input none + * Output none + */ +void twi_enableGenCall(void) +{ + // set TWGCE bit (LSB) and leave rest of address + TWAR |= 1 << TWGCE; +} + /* * Function twi_readFrom * Desc attempts to become twi bus master and read a @@ -328,7 +342,7 @@ uint8_t twi_transmit(const uint8_t* data, uint8_t length) * Input function: callback function to use * Output none */ -void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) +void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int, uint8_t) ) { twi_onSlaveReceive = function; } @@ -481,10 +495,15 @@ ISR(TWI_vect) twi_state = TWI_SRX; // indicate that rx buffer can be overwritten and ack twi_rxBufferIndex = 0; - twi_reply(1); + + //indicate that we have not received any gcall data + twi_gcall_data = 0; + + twi_reply(1); break; - case TW_SR_DATA_ACK: // data received, returned ack case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack + twi_gcall_data = 1; //indicate that we received some gcall data - need to send flag to receiver + case TW_SR_DATA_ACK: // data received, returned ack // if there is still room in the rx buffer if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ // put byte in buffer and ack @@ -503,7 +522,7 @@ ISR(TWI_vect) twi_rxBuffer[twi_rxBufferIndex] = '\0'; } // callback to user defined callback - twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); + twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex,twi_gcall_data); // since we submit rx buffer to "wire" library, we can reset it twi_rxBufferIndex = 0; break; diff --git a/libraries/Wire/src/utility/twi.h b/libraries/Wire/src/utility/twi.h index d27325e..5dc2326 100644 --- a/libraries/Wire/src/utility/twi.h +++ b/libraries/Wire/src/utility/twi.h @@ -41,11 +41,12 @@ void twi_init(void); void twi_disable(void); void twi_setAddress(uint8_t); + void twi_enableGenCall(void); void twi_setFrequency(uint32_t); 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); - void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); + void twi_attachSlaveRxEvent( void (*)(uint8_t*, int, uint8_t) ); void twi_attachSlaveTxEvent( void (*)(void) ); void twi_reply(uint8_t); void twi_stop(void);