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;
|
uint8_t TwoWire::transmitting = 0;
|
||||||
void (*TwoWire::user_onRequest)(void);
|
void (*TwoWire::user_onRequest)(void);
|
||||||
void (*TwoWire::user_onReceive)(int);
|
void (*TwoWire::user_onReceive)(int);
|
||||||
|
void (*TwoWire::user_onGcallReceive)(int);
|
||||||
|
|
||||||
// Constructors ////////////////////////////////////////////////////////////////
|
// Constructors ////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -273,12 +274,22 @@ void TwoWire::flush(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// behind the scenes function that is called when data is received
|
// 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
|
// don't bother if user hasn't registered a callback
|
||||||
if(!user_onReceive){
|
if(!user_onReceive){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// don't bother if rx buffer is in use by a master requestFrom() op
|
// 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
|
// i know this drops data, but it allows for slight stupidity
|
||||||
// meaning, they may not have read all the master requestFrom() data yet
|
// 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
|
// set rx iterator vars
|
||||||
rxBufferIndex = 0;
|
rxBufferIndex = 0;
|
||||||
rxBufferLength = numBytes;
|
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);
|
user_onReceive(numBytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// behind the scenes function that is called when data is requested
|
// behind the scenes function that is called when data is requested
|
||||||
|
@ -312,16 +330,27 @@ void TwoWire::onRequestService(void)
|
||||||
user_onRequest();
|
user_onRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets function called on slave write
|
// sets function called when slave receives data from master at slave's address
|
||||||
void TwoWire::onReceive( void (*function)(int) )
|
void TwoWire::onReceive( void (*recFunction)(int) )
|
||||||
{
|
{
|
||||||
user_onReceive = function;
|
user_onReceive = recFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets function called on slave read
|
// sets function called when slave receives data from master at slaves address
|
||||||
void TwoWire::onRequest( void (*function)(void) )
|
// 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 //////////////////////////////////////////////////////
|
// Preinstantiate Objects //////////////////////////////////////////////////////
|
||||||
|
|
|
@ -45,8 +45,9 @@ class TwoWire : public Stream
|
||||||
static uint8_t transmitting;
|
static uint8_t transmitting;
|
||||||
static void (*user_onRequest)(void);
|
static void (*user_onRequest)(void);
|
||||||
static void (*user_onReceive)(int);
|
static void (*user_onReceive)(int);
|
||||||
|
static void (*user_onGcallReceive)(int);
|
||||||
static void onRequestService(void);
|
static void onRequestService(void);
|
||||||
static void onReceiveService(uint8_t*, int);
|
static void onReceiveService(uint8_t*, int,uint8_t);
|
||||||
public:
|
public:
|
||||||
TwoWire();
|
TwoWire();
|
||||||
void begin();
|
void begin();
|
||||||
|
@ -70,6 +71,7 @@ class TwoWire : public Stream
|
||||||
virtual int peek(void);
|
virtual int peek(void);
|
||||||
virtual void flush(void);
|
virtual void flush(void);
|
||||||
void onReceive( void (*)(int) );
|
void onReceive( void (*)(int) );
|
||||||
|
void onReceive( void (*)(int), void (*)(int) );
|
||||||
void onRequest( void (*)(void) );
|
void onRequest( void (*)(void) );
|
||||||
|
|
||||||
inline size_t write(unsigned long n) { return write((uint8_t)n); }
|
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 volatile uint8_t twi_inRepStart; // in the middle of a repeated start
|
||||||
|
|
||||||
static void (*twi_onSlaveTransmit)(void);
|
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 uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
|
||||||
static volatile uint8_t twi_masterBufferIndex;
|
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_rxBufferIndex;
|
||||||
|
|
||||||
static volatile uint8_t twi_error;
|
static volatile uint8_t twi_error;
|
||||||
|
static volatile uint8_t twi_gcall_data;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function twi_init
|
* Function twi_init
|
||||||
|
@ -114,8 +116,8 @@ void twi_disable(void)
|
||||||
*/
|
*/
|
||||||
void twi_setAddress(uint8_t address)
|
void twi_setAddress(uint8_t address)
|
||||||
{
|
{
|
||||||
// set twi slave address (skip over TWGCE bit)
|
// set twi slave address and leave TWGCE bit (LSB)
|
||||||
TWAR = address << 1;
|
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 */
|
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
|
* Function twi_readFrom
|
||||||
* Desc attempts to become twi bus master and read a
|
* 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
|
* Input function: callback function to use
|
||||||
* Output none
|
* Output none
|
||||||
*/
|
*/
|
||||||
void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) )
|
void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int, uint8_t) )
|
||||||
{
|
{
|
||||||
twi_onSlaveReceive = function;
|
twi_onSlaveReceive = function;
|
||||||
}
|
}
|
||||||
|
@ -481,10 +495,15 @@ ISR(TWI_vect)
|
||||||
twi_state = TWI_SRX;
|
twi_state = TWI_SRX;
|
||||||
// indicate that rx buffer can be overwritten and ack
|
// indicate that rx buffer can be overwritten and ack
|
||||||
twi_rxBufferIndex = 0;
|
twi_rxBufferIndex = 0;
|
||||||
|
|
||||||
|
//indicate that we have not received any gcall data
|
||||||
|
twi_gcall_data = 0;
|
||||||
|
|
||||||
twi_reply(1);
|
twi_reply(1);
|
||||||
break;
|
break;
|
||||||
case TW_SR_DATA_ACK: // data received, returned ack
|
|
||||||
case TW_SR_GCALL_DATA_ACK: // data received generally, 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 there is still room in the rx buffer
|
||||||
if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
|
if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
|
||||||
// put byte in buffer and ack
|
// put byte in buffer and ack
|
||||||
|
@ -503,7 +522,7 @@ ISR(TWI_vect)
|
||||||
twi_rxBuffer[twi_rxBufferIndex] = '\0';
|
twi_rxBuffer[twi_rxBufferIndex] = '\0';
|
||||||
}
|
}
|
||||||
// callback to user defined callback
|
// 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
|
// since we submit rx buffer to "wire" library, we can reset it
|
||||||
twi_rxBufferIndex = 0;
|
twi_rxBufferIndex = 0;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -41,11 +41,12 @@
|
||||||
void twi_init(void);
|
void twi_init(void);
|
||||||
void twi_disable(void);
|
void twi_disable(void);
|
||||||
void twi_setAddress(uint8_t);
|
void twi_setAddress(uint8_t);
|
||||||
|
void twi_enableGenCall(void);
|
||||||
void twi_setFrequency(uint32_t);
|
void twi_setFrequency(uint32_t);
|
||||||
uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_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_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
|
||||||
uint8_t twi_transmit(const 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_attachSlaveTxEvent( void (*)(void) );
|
||||||
void twi_reply(uint8_t);
|
void twi_reply(uint8_t);
|
||||||
void twi_stop(void);
|
void twi_stop(void);
|
||||||
|
|
Loading…
Reference in New Issue