diff --git a/avr/libraries/Wire/src/Wire.cpp b/avr/libraries/Wire/src/Wire.cpp index 6c1e48c74..3dcdeb148 100755 --- a/avr/libraries/Wire/src/Wire.cpp +++ b/avr/libraries/Wire/src/Wire.cpp @@ -17,6 +17,7 @@ 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 2017 by Chuck Todd (ctodd@cableone.net) to correct Unconfigured Slave Mode reboot */ extern "C" { @@ -60,14 +61,16 @@ void TwoWire::begin(void) txBufferLength = 0; twi_init(); + twi_attachSlaveTxEvent(onRequestService); // default callback must exist + twi_attachSlaveRxEvent(onReceiveService); // default callback must exist } void TwoWire::begin(uint8_t address) { - twi_setAddress(address); + begin(); twi_attachSlaveTxEvent(onRequestService); twi_attachSlaveRxEvent(onReceiveService); - begin(); + twi_setAddress(address); } void TwoWire::begin(int address) @@ -80,9 +83,9 @@ void TwoWire::end(void) twi_disable(); } -void TwoWire::setClock(uint32_t frequency) +void TwoWire::setClock(uint32_t clock) { - TWBR = ((F_CPU / frequency) - 16) / 2; + twi_setFrequency(clock); } uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) diff --git a/avr/libraries/Wire/src/utility/twi.c b/avr/libraries/Wire/src/utility/twi.c index 8a674c654..6882a3d2c 100755 --- a/avr/libraries/Wire/src/utility/twi.c +++ b/avr/libraries/Wire/src/utility/twi.c @@ -118,6 +118,22 @@ void twi_setAddress(uint8_t address) TWAR = address << 1; } +/* + * Function twi_setFrequency + * Desc sets twi bit rate + * Input Clock frequency + * Output none + */ +void twi_setFrequency(uint32_t frequency) +{ + TWBR = ((F_CPU / frequency) - 16) / 2; + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) + note: TWBR should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ +} + /* * Function twi_readFrom * Desc attempts to become twi bus master and read a @@ -288,7 +304,7 @@ uint8_t twi_transmit(const uint8_t* data, uint8_t length) uint8_t i; // ensure data will fit into buffer - if(TWI_BUFFER_SIZE < length){ + if(TWI_BUFFER_SIZE < (twi_txBufferLength+length)){ return 1; } @@ -300,9 +316,10 @@ uint8_t twi_transmit(const uint8_t* data, uint8_t length) // set length and copy data into tx buffer twi_txBufferLength = length; for(i = 0; i < length; ++i){ - twi_txBuffer[i] = data[i]; + twi_txBuffer[twi_txBufferLength+i] = data[i]; } - + twi_txBufferLength += length; + return 0; } @@ -429,6 +446,7 @@ ISR(TWI_vect) case TW_MR_DATA_ACK: // data received, ack sent // put byte into buffer twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + __attribute__ ((fallthrough)); case TW_MR_SLA_ACK: // address sent, ack received // ack if more bytes are expected, otherwise nack if(twi_masterBufferIndex < twi_masterBufferLength){ @@ -515,6 +533,7 @@ ISR(TWI_vect) twi_txBuffer[0] = 0x00; } // transmit first byte from buffer, fall + __attribute__ ((fallthrough)); case TW_ST_DATA_ACK: // byte sent, ack returned // copy data to output register TWDR = twi_txBuffer[twi_txBufferIndex++]; @@ -542,4 +561,3 @@ ISR(TWI_vect) break; } } - diff --git a/avr/libraries/Wire/src/utility/twi.h b/avr/libraries/Wire/src/utility/twi.h index 62d97c068..b836d9f71 100755 --- a/avr/libraries/Wire/src/utility/twi.h +++ b/avr/libraries/Wire/src/utility/twi.h @@ -22,15 +22,12 @@ #include - //#define ATMEGA8 - #ifndef TWI_FREQ #define TWI_FREQ 100000L #endif #ifndef TWI_BUFFER_SIZE #define TWI_BUFFER_SIZE 32 - #define BUFFER_LENGTH TWI_BUFFER_SIZE // For backwards compatibility #endif #define TWI_READY 0 @@ -42,6 +39,7 @@ void twi_init(void); void twi_disable(void); void twi_setAddress(uint8_t); + 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); diff --git a/avr/libraries/Wire1/keywords.txt b/avr/libraries/Wire1/keywords.txt index 47ffd52d0..a5c1e7f75 100755 --- a/avr/libraries/Wire1/keywords.txt +++ b/avr/libraries/Wire1/keywords.txt @@ -22,7 +22,6 @@ onRequest KEYWORD2 # Instances (KEYWORD2) ####################################### -Wire KEYWORD2 Wire1 KEYWORD2 ####################################### diff --git a/avr/libraries/Wire1/src/Wire1.cpp b/avr/libraries/Wire1/src/Wire1.cpp index 74df6114c..41db40190 100755 --- a/avr/libraries/Wire1/src/Wire1.cpp +++ b/avr/libraries/Wire1/src/Wire1.cpp @@ -17,6 +17,7 @@ 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 2017 by Chuck Todd (ctodd@cableone.net) to correct Unconfigured Slave Mode reboot */ extern "C" { @@ -60,14 +61,16 @@ void TwoWire1::begin(void) txBufferLength = 0; twi_init1(); + twi_attachSlaveTxEvent1(onRequestService); // default callback must exist + twi_attachSlaveRxEvent1(onReceiveService); // default callback must exist } void TwoWire1::begin(uint8_t address) { - twi_setAddress1(address); + begin(); twi_attachSlaveTxEvent1(onRequestService); twi_attachSlaveRxEvent1(onReceiveService); - begin(); + twi_setAddress1(address); } void TwoWire1::begin(int address) @@ -80,9 +83,9 @@ void TwoWire1::end(void) twi_disable1(); } -void TwoWire1::setClock(uint32_t frequency) +void TwoWire1::setClock(uint32_t clock) { - TWBR1 = ((F_CPU / frequency) - 16) / 2; + twi_setFrequency1(clock); } uint8_t TwoWire1::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) diff --git a/avr/libraries/Wire1/src/utility/twi1.c b/avr/libraries/Wire1/src/utility/twi1.c index 8be7de815..4929ad627 100755 --- a/avr/libraries/Wire1/src/utility/twi1.c +++ b/avr/libraries/Wire1/src/utility/twi1.c @@ -90,7 +90,7 @@ void twi_init1(void) TWCR1 = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); } -/* +/* * Function twi_disable * Desc disables twi pins * Input none @@ -106,7 +106,7 @@ void twi_disable1(void) digitalWrite(SCL, 0); } -/* +/* * Function twi_slaveInit * Desc sets slave address and enables interrupt * Input none @@ -118,6 +118,22 @@ void twi_setAddress1(uint8_t address) TWAR1 = address << 1; } +/* + * Function twi_setFrequency + * Desc sets twi bit rate + * Input Clock frequency + * Output none + */ +void twi_setFrequency1(uint32_t frequency) +{ + TWBR = ((F_CPU / frequency) - 16) / 2; + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR1)) + note: TWBR1 should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ +} + /* * Function twi_readFrom * Desc attempts to become twi bus master and read a @@ -288,7 +304,7 @@ uint8_t twi_transmit1(const uint8_t* data, uint8_t length) uint8_t i; // ensure data will fit into buffer - if(TWI1_BUFFER_SIZE < length){ + if(TWI1_BUFFER_SIZE < (twi_txBufferLength+length)){ return 1; } @@ -300,8 +316,9 @@ uint8_t twi_transmit1(const uint8_t* data, uint8_t length) // set length and copy data into tx buffer twi_txBufferLength = length; for(i = 0; i < length; ++i){ - twi_txBuffer[i] = data[i]; + twi_txBuffer[twi_txBufferLength+i] = data[i]; } + twi_txBufferLength += length; return 0; } @@ -430,6 +447,7 @@ ISR(TWI1_vect) case TW_MR_DATA_ACK: // data received, ack sent // put byte into buffer twi_masterBuffer[twi_masterBufferIndex++] = TWDR1; + __attribute__ ((fallthrough)); case TW_MR_SLA_ACK: // address sent, ack received // ack if more bytes are expected, otherwise nack if(twi_masterBufferIndex < twi_masterBufferLength){ @@ -516,6 +534,7 @@ ISR(TWI1_vect) twi_txBuffer[0] = 0x00; } // transmit first byte from buffer, fall + __attribute__ ((fallthrough)); case TW_ST_DATA_ACK: // byte sent, ack returned // copy data to output register TWDR1 = twi_txBuffer[twi_txBufferIndex++]; diff --git a/avr/libraries/Wire1/src/utility/twi1.h b/avr/libraries/Wire1/src/utility/twi1.h index eabbea0be..a62709e35 100755 --- a/avr/libraries/Wire1/src/utility/twi1.h +++ b/avr/libraries/Wire1/src/utility/twi1.h @@ -22,15 +22,12 @@ #include - //#define ATMEGA8 - #ifndef TWI_FREQ #define TWI_FREQ 100000L #endif #ifndef TWI1_BUFFER_SIZE #define TWI1_BUFFER_SIZE 32 - #define BUFFER_LENGTH1 TWI1_BUFFER_SIZE // For backwards compatibility #endif #define TWI_READY 0 @@ -42,6 +39,7 @@ void twi_init1(void); void twi_disable1(void); void twi_setAddress1(uint8_t); + void twi_setFrequency1(uint32_t); uint8_t twi_readFrom1(uint8_t, uint8_t*, uint8_t, uint8_t); uint8_t twi_writeTo1(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); uint8_t twi_transmit1(const uint8_t*, uint8_t);