Wire library support for TWI General Call
Squash and rebase of https://github.com/arduino/Arduino/pull/49
This commit is contained in:
parent
6c861d8c70
commit
ef4482afef
|
@ -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)
|
||||
{
|
||||
//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
|
||||
|
||||
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 //////////////////////////////////////////////////////
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
||||
//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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue