diff --git a/i2c_test_attiny85/i2c_test_attiny85.componentinfo.xml b/i2c_test_attiny85/i2c_test_attiny85.componentinfo.xml
index 80c79cc..f38ac81 100755
--- a/i2c_test_attiny85/i2c_test_attiny85.componentinfo.xml
+++ b/i2c_test_attiny85/i2c_test_attiny85.componentinfo.xml
@@ -9,57 +9,57 @@
Atmel
- 1.2.0
- C:/Program Files (x86)\Atmel\Studio\7.0\Packs
+ 1.8.0
+ D:/Programs\Atmelstudio\7.0\Packs
- C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.2.118\include
+ D:/Programs\Atmelstudio\7.0\Packs\atmel\ATtiny_DFP\1.8.332\include\
include
C
- include
+ include/
- C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.2.118\include\avr\iotn85.h
+ D:/Programs\Atmelstudio\7.0\Packs\atmel\ATtiny_DFP\1.8.332\include\avr\iotn85.h
header
C
- RcYmivGpgsCGGCzeWAIjcA==
+ T0lnJZ6iliUJCzU7ZHCMPQ==
include/avr/iotn85.h
- C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.2.118\templates\main.c
+ D:/Programs\Atmelstudio\7.0\Packs\atmel\ATtiny_DFP\1.8.332\templates\main.c
template
source
C Exe
- GD1k8YYhulqRs6FD1B2Hog==
+ KjvOcFWd++tbnsEMfVPd/w==
templates/main.c
Main file (.c)
- C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.2.118\templates\main.cpp
+ D:/Programs\Atmelstudio\7.0\Packs\atmel\ATtiny_DFP\1.8.332\templates\main.cpp
template
source
C Exe
- YXFphlh0CtZJU+ebktABgQ==
+ mkKaE95TOoATsuBGv6jmxg==
templates/main.cpp
Main file (.cpp)
- C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.2.118\gcc\dev\attiny85
+ D:/Programs\Atmelstudio\7.0\Packs\atmel\ATtiny_DFP\1.8.332\gcc\dev\attiny85
libraryPrefix
GCC
@@ -71,8 +71,8 @@
ATtiny_DFP
- C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATtiny_DFP/1.2.118/Atmel.ATtiny_DFP.pdsc
- 1.2.118
+ D:/Programs/Atmelstudio/7.0/Packs/atmel/ATtiny_DFP/1.8.332/Atmel.ATtiny_DFP.pdsc
+ 1.8.332
true
ATtiny85
diff --git a/i2c_test_attiny85/i2c_test_attiny85.cproj b/i2c_test_attiny85/i2c_test_attiny85.cproj
index 59a26aa..758d011 100755
--- a/i2c_test_attiny85/i2c_test_attiny85.cproj
+++ b/i2c_test_attiny85/i2c_test_attiny85.cproj
@@ -28,15 +28,15 @@
0
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
com.atmel.avrdbg.tool.stk500
@@ -72,79 +72,79 @@
- -mmcu=attiny85 -B "%24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\gcc\dev\attiny85"
- True
- True
- True
- True
- False
- True
- True
-
-
- NDEBUG
-
-
-
-
- %24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\include
-
-
- Optimize for size (-Os)
- True
- True
- True
-
-
- libm
-
-
-
-
- %24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\include
-
-
-
+ -mmcu=attiny85 -B "%24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\gcc\dev\attiny85"
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ NDEBUG
+
+
+
+
+ %24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\include
+
+
+ Optimize for size (-Os)
+ True
+ True
+ True
+
+
+ libm
+
+
+
+
+ %24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\include
+
+
+
- -mmcu=attiny85 -B "%24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\gcc\dev\attiny85"
- True
- True
- True
- True
- False
- True
- True
-
-
- DEBUG
-
-
-
-
- %24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\include
-
-
- Optimize (-O1)
- True
- True
- Default (-g2)
- True
-
-
- libm
-
-
-
-
- %24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\include
-
-
- Default (-Wa,-g)
-
+ -mmcu=attiny85 -B "%24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\gcc\dev\attiny85"
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ DEBUG
+
+
+
+
+ %24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\include
+
+
+ Optimize (-O1)
+ True
+ True
+ Default (-g2)
+ True
+
+
+ libm
+
+
+
+
+ %24(PackRepoDir)\atmel\ATtiny_DFP\1.2.118\include
+
+
+ Default (-Wa,-g)
+
@@ -163,10 +163,10 @@
compile
-
+
compile
-
+
compile
diff --git a/i2c_test_attiny85/led_gen.c b/i2c_test_attiny85/led_gen.c
index 9e5e026..5c93e9e 100755
--- a/i2c_test_attiny85/led_gen.c
+++ b/i2c_test_attiny85/led_gen.c
@@ -11,16 +11,16 @@ void led1_init(void)
{
DDRB |= (1<
#include
@@ -21,7 +21,7 @@
#define NOTHING 0x54
#define ERROR 0xF0
#define VOLTMIN 1
-#define TIMING 100
+#define TIMING 5
void ADC_init(void);
void ADC_start_conversion(void);
diff --git a/i2c_test_attiny85/main.c b/i2c_test_attiny85/main.c
index 90e2d40..1ff17b4 100755
--- a/i2c_test_attiny85/main.c
+++ b/i2c_test_attiny85/main.c
@@ -15,7 +15,7 @@
#include "led_gen.h"
#include "led_receptor.h"
-#include "USI_TWI_Slave.h"
+#include "usiTwiSlave.h"
//#define F_CPU 1000000
#define NOM_CONSTRUC 0x08
#define NOM_CAPTEUR 0x10
@@ -35,44 +35,52 @@ volatile unsigned char recVal;
int main( void )
{
- unsigned char slaveAdress, cmd,i=0;
+ float test1,test2;
+ unsigned char cmd,i=0;
unsigned char nom_capteur[8]= {'T','u','r','k','i','s','h','Z'};
unsigned char sensor_type[8]= {'C','a','t','c','h','E','y','e'};
+ uint8_t slaveAdress;//data = 0x45;
slaveAdress = 0x01;
MCUCR |= (1<
+ #include
+#else
+ #include
+ #include
+#endif
+#include "USI_TWI_Slave.h"
+#include "led_receptor.h"
+
+/*! Static Variables
+ */
+
+static unsigned char TWI_slaveAddress;
+static volatile unsigned char USI_TWI_Overflow_State;
+
+
+/*! Local variables
+ */
+static uint8_t TWI_RxBuf[TWI_RX_BUFFER_SIZE];
+static volatile uint8_t TWI_RxHead;
+static volatile uint8_t TWI_RxTail;
+
+static uint8_t TWI_TxBuf[TWI_TX_BUFFER_SIZE];
+static volatile uint8_t TWI_TxHead;
+static volatile uint8_t TWI_TxTail;
+
+/*! \brief Flushes the TWI buffers
+ */
+void Flush_TWI_Buffers(void)
+{
+ TWI_RxTail = 0;
+ TWI_RxHead = 0;
+ TWI_TxTail = 0;
+ TWI_TxHead = 0;
+}
+
+//********** USI_TWI functions **********//
+
+/*! \brief
+ * Initialise USI for TWI Slave mode.
+ */
+void USI_TWI_Slave_Initialise( unsigned char TWI_ownAddress )
+{
+ Flush_TWI_Buffers();
+
+ TWI_slaveAddress = TWI_ownAddress;
+
+ PORT_USI |= (1<>1 ) == TWI_slaveAddress))
+ {
+ if ( USIDR & 0x01 ){ // R/W
+ USI_TWI_Overflow_State = USI_SLAVE_SEND_DATA; //Read => L'esclave doit envoyer une donn?e
+ }else{
+ USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA; //Write => L'esclave doit lire la demande
+ }
+ SET_USI_TO_SEND_ACK();
+ }
+ else
+ {
+ SET_USI_TO_TWI_START_CONDITION_MODE();
+ }
+ break;
+
+ // ----- Master write data mode ------
+ // Check reply and goto USI_SLAVE_SEND_DATA if OK, else reset USI.
+ case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:
+ if ( USIDR ) // If NACK, the master does not want more data.
+ {
+ SET_USI_TO_TWI_START_CONDITION_MODE();
+ return;
+ }
+ // From here we just drop straight into USI_SLAVE_SEND_DATA if the master sent an ACK
+
+ // Copy data from buffer to USIDR and set USI to shift byte. Next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA
+ case USI_SLAVE_SEND_DATA:
+
+ // Get data from Buffer
+ tmpTxTail = TWI_TxTail; // Not necessary, but prevents warnings
+ if ( TWI_TxHead != tmpTxTail )
+ {
+ TWI_TxTail = ( TWI_TxTail + 1 ) & TWI_TX_BUFFER_MASK;
+ USIDR = TWI_TxBuf[TWI_TxTail];
+ }
+ else // If the buffer is empty then:
+ {
+ SET_USI_TO_TWI_START_CONDITION_MODE();
+ return;
+ }
+ USI_TWI_Overflow_State = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;
+ SET_USI_TO_SEND_DATA();
+ break;
+
+ // Set USI to sample reply from master. Next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA
+ case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:
+ USI_TWI_Overflow_State = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA;
+ SET_USI_TO_READ_ACK();
+ break;
+
+ // ----- Master read data mode ------
+ // Set USI to sample data from master. Next USI_SLAVE_GET_DATA_AND_SEND_ACK.
+ case USI_SLAVE_REQUEST_DATA:
+ USI_TWI_Overflow_State = USI_SLAVE_GET_DATA_AND_SEND_ACK;
+ SET_USI_TO_READ_DATA();
+ break;
+
+ // Copy data from USIDR and send ACK. Next USI_SLAVE_REQUEST_DATA
+ case USI_SLAVE_GET_DATA_AND_SEND_ACK:
+ // Put data into Buffer
+ tmpUSIDR = USIDR; // Not necessary, but prevents warnings
+ TWI_RxHead = ( TWI_RxHead + 1 ) & TWI_RX_BUFFER_MASK;
+ TWI_RxBuf[TWI_RxHead] = tmpUSIDR;
+
+ USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA;
+ SET_USI_TO_SEND_ACK();
+ break;
+ }
+}
diff --git a/i2c_test_attiny85/old USI_TWI/USI_TWI_Slave.h b/i2c_test_attiny85/old USI_TWI/USI_TWI_Slave.h
new file mode 100755
index 0000000..b7cd2a1
--- /dev/null
+++ b/i2c_test_attiny85/old USI_TWI/USI_TWI_Slave.h
@@ -0,0 +1,203 @@
+// This file has been prepared for Doxygen automatic documentation generation.
+/*! \file ********************************************************************
+ *
+ * Atmel Corporation
+ *
+ * File : USI_TWI_Slave.h
+ * Compiler : IAR EWAAVR 4.11A
+ * Revision : $Revision: 6351 $
+ * Date : $Date: 2010-01-29 20:15:43 +0800 (Fri, 29 Jan 2010) $
+ * Updated by : $Author: hskinnemoen $
+ *
+ * Support mail : avr@atmel.com
+ *
+ * Supported devices : All device with USI module can be used.
+ * The example is written for the ATmega169, ATtiny26 & ATtiny2313
+ *
+ * AppNote : AVR312 - Using the USI module as a TWI slave
+ *
+ * Description : Header file for USI_TWI driver
+ *
+ *
+ *
+ ****************************************************************************/
+//********** Prototypes **********//
+#include
+#ifndef TWDR
+void USI_TWI_Slave_Initialise(unsigned char);
+void USI_TWI_Slave_Disable();
+void USI_TWI_Transmit_Byte(unsigned char);
+unsigned char USI_TWI_Receive_Byte(void);
+unsigned char USI_TWI_Peek_Receive_Byte(void);
+unsigned char USI_TWI_Data_In_Receive_Buffer(void);
+unsigned char USI_TWI_Space_In_Transmission_Buffer(void);
+unsigned char USI_TWI_Slave_Is_Active();
+
+void (*USI_TWI_On_Slave_Transmit)(void);
+void (*USI_TWI_On_Slave_Receive)(int);
+
+void Timer_Init(void);
+
+#define TRUE 1
+#define FALSE 0
+
+typedef unsigned char uint8_t;
+
+//////////////////////////////////////////////////////////////////
+///////////////// Driver Buffer Definitions //////////////////////
+//////////////////////////////////////////////////////////////////
+// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
+extern uint8_t TWI_Buffer[];
+
+#define TWI_RX_BUFFER_SIZE (16)
+
+#if (TWI_RX_BUFFER_SIZE & TWI_RX_BUFFER_MASK)
+#error TWI RX buffer size is not a power of 2
+#endif
+
+// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
+
+#define TWI_TX_BUFFER_SIZE (16)
+
+#if (TWI_TX_BUFFER_SIZE & TWI_TX_BUFFER_MASK)
+#error TWI TX buffer size is not a power of 2
+#endif
+
+#define TWI_BUFFER_SIZE (TWI_RX_BUFFER_SIZE + TWI_TX_BUFFER_SIZE)
+//////////////////////////////////////////////////////////////////
+
+#define USI_SLAVE_CHECK_ADDRESS (0x00)
+#define USI_SLAVE_SEND_DATA (0x01)
+#define USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA (0x02)
+#define USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA (0x03)
+#define USI_SLAVE_REQUEST_DATA (0x04)
+#define USI_SLAVE_GET_DATA_AND_SEND_ACK (0x05)
+
+//! Device dependent defines
+#if defined(__AT90tiny26__) | defined(__ATtiny26__)
+#define DDR_USI DDRB
+#define PORT_USI PORTB
+#define PIN_USI PINB
+#define PORT_USI_SDA PORTB0
+#define PORT_USI_SCL PORTB2
+#define PIN_USI_SDA PINB0
+#define PIN_USI_SCL PINB2
+#define USI_START_COND_INT USISIF
+#define USI_START_VECTOR USI_STRT_vect
+#define USI_OVERFLOW_VECTOR USI_OVF_vect
+#endif
+
+#if defined(__AT90Tiny2313__) | defined(__ATtiny2313__)
+#define DDR_USI DDRB
+#define PORT_USI PORTB
+#define PIN_USI PINB
+#define PORT_USI_SDA PORTB5
+#define PORT_USI_SCL PORTB7
+#define PIN_USI_SDA PINB5
+#define PIN_USI_SCL PINB7
+#define USI_START_COND_INT USISIF
+#define USI_START_VECTOR USI_STRT_vect
+#define USI_OVERFLOW_VECTOR USI_OVF_vect
+#endif
+
+#if defined( __AVR_ATtiny25__ ) | \
+defined( __AVR_ATtiny45__ ) | \
+defined( __AVR_ATtiny85__ )
+#define DDR_USI DDRB
+#define PORT_USI PORTB
+#define PIN_USI PINB
+#define PORT_USI_SDA PB0
+#define PORT_USI_SCL PB2
+#define PIN_USI_SDA PINB0
+#define PIN_USI_SCL PINB2
+#define USI_START_COND_INT USISIF
+#define USI_START_VECTOR USI_START_vect
+#define USI_OVERFLOW_VECTOR USI_OVF_vect
+#endif
+
+#if defined(__AT90Mega165__) | defined(__ATmega165__) | \
+defined(__ATmega325__) | defined(__ATmega3250__) | \
+defined(__ATmega645__) | defined(__ATmega6450__) | \
+defined(__ATmega329__) | defined(__ATmega3290__) | \
+defined(__ATmega649__) | defined(__ATmega6490__)
+#define DDR_USI DDRE
+#define PORT_USI PORTE
+#define PIN_USI PINE
+#define PORT_USI_SDA PORTE5
+#define PORT_USI_SCL PORTE4
+#define PIN_USI_SDA PINE5
+#define PIN_USI_SCL PINE4
+#define USI_START_COND_INT USISIF
+#define USI_START_VECTOR USI_START_vect
+#define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
+#endif
+
+//#if defined(__AT90Mega169__) | defined(__ATmega169__)
+#if defined(__AT90Mega169__) | defined(__AVR_ATmega169PA__)
+#define DDR_USI DDRE
+#define PORT_USI PORTE
+#define PIN_USI PINE
+#define PORT_USI_SDA PORTE5
+#define PORT_USI_SCL PORTE4
+#define PIN_USI_SDA PINE5
+#define PIN_USI_SCL PINE4
+#define USI_START_COND_INT USISIF
+#define USI_START_VECTOR USI_STRT_vect
+#define USI_OVERFLOW_VECTOR USI_OVF_vect
+#endif
+
+#define SET_USI_TO_SEND_ACK() \
+ { \
+ USIDR = 0; /* Prepare ACK */ \
+ DDR_USI |= (1 << PORT_USI_SDA); /* Set SDA as output */ \
+ USISR = (0 << USI_START_COND_INT) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) \
+ | /* Clear all flags, except Start Cond */ \
+ (0x0E << USICNT0); /* set USI counter to shift 1 bit. */ \
+ }
+
+#define SET_USI_TO_SEND_NACK() \
+ { \
+ DDR_USI &= ~(1 << PORT_USI_SDA); /* Set SDA as input, NACK is SDA high */ \
+ USISR = (0 << USI_START_COND_INT) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) \
+ | /* Clear all flags, except Start Cond */ \
+ (0x0E << USICNT0); /* set USI counter to shift 1 bit. */ \
+ }
+
+#define SET_USI_TO_READ_ACK() \
+ { \
+ DDR_USI &= ~(1 << PORT_USI_SDA); /* Set SDA as input */ \
+ USIDR = 0; /* Prepare ACK */ \
+ USISR = (0 << USI_START_COND_INT) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) \
+ | /* Clear all flags, except Start Cond */ \
+ (0x0E << USICNT0); /* set USI counter to shift 1 bit. */ \
+ }
+
+#define SET_USI_TO_TWI_START_CONDITION_MODE() \
+ { \
+ DDR_USI &= ~(1 << PORT_USI_SDA); /* Set SDA as input */ \
+ USICR = (1 << USISIE) | (0 << USIOIE) | /* Enable Start Condition Interrupt. Disable Overflow Interrupt.*/ \
+ (1 << USIWM1) | (0 << USIWM0) | /* Set USI in Two-wire mode. No USI Counter overflow hold. */ \
+ (1 << USICS1) | (0 << USICS0) | (0 << USICLK) \
+ | /* Shift Register Clock Source = External, positive edge */ \
+ (0 << USITC); \
+ USISR = (0 << USI_START_COND_INT) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) \
+ | /* Clear all flags, except Start Cond */ \
+ (0x0 << USICNT0); \
+ }
+
+#define SET_USI_TO_SEND_DATA() \
+ { \
+ DDR_USI |= (1 << PORT_USI_SDA); /* Set SDA as output */ \
+ USISR = (0 << USI_START_COND_INT) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) \
+ | /* Clear all flags, except Start Cond */ \
+ (0x0 << USICNT0); /* set USI to shift out 8 bits */ \
+ }
+
+#define SET_USI_TO_READ_DATA() \
+ { \
+ DDR_USI &= ~(1 << PORT_USI_SDA); /* Set SDA as input */ \
+ USISR = (0 << USI_START_COND_INT) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) \
+ | /* Clear all flags, except Start Cond */ \
+ (0x0 << USICNT0); /* set USI to shift out 8 bits */ \
+ }
+#endif
\ No newline at end of file
diff --git a/i2c_test_attiny85/usiTwiSlave.c b/i2c_test_attiny85/usiTwiSlave.c
new file mode 100755
index 0000000..216ae78
--- /dev/null
+++ b/i2c_test_attiny85/usiTwiSlave.c
@@ -0,0 +1,748 @@
+/********************************************************************************
+
+USI TWI Slave driver.
+
+Created by Donald R. Blake. donblake at worldnet.att.net
+Adapted by Jochen Toppe, jochen.toppe at jtoee.com
+
+---------------------------------------------------------------------------------
+
+Created from Atmel source files for Application Note AVR312: Using the USI Module
+as an I2C slave.
+
+This program is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+---------------------------------------------------------------------------------
+
+Change Activity:
+
+ Date Description
+ ------ -------------
+ 16 Mar 2007 Created.
+ 27 Mar 2007 Added support for ATtiny261, 461 and 861.
+ 26 Apr 2007 Fixed ACK of slave address on a read.
+ 04 Jul 2007 Fixed USISIF in ATtiny45 def
+ 12 Dev 2009 Added callback functions for data requests
+ 06 Feb 2016 Minor change to allow mutli-byte requestFrom() from master.
+ 10 Feb 2016 Simplied RX/TX buffer code and allowed use of full buffer.
+ 13 Feb 2016 Made USI_RECEIVE_CALLBACK() callback fully interrupt-driven
+ 12 Dec 2016 Added support for ATtiny167
+ 23 Dec 2017 Fixed repeated restart (which broke when making receive callback
+ interrupt-driven)
+
+********************************************************************************/
+
+
+/********************************************************************************
+ includes
+********************************************************************************/
+
+#include
+#include
+
+#include "usiTwiSlave.h"
+//#include "../common/util.h"
+
+
+/********************************************************************************
+ device dependent defines
+********************************************************************************/
+
+#if defined( __AVR_ATtiny167__ )
+# define DDR_USI DDRB
+# define PORT_USI PORTB
+# define PIN_USI PINB
+# define PORT_USI_SDA PB0
+# define PORT_USI_SCL PB2
+# define PIN_USI_SDA PINB0
+# define PIN_USI_SCL PINB2
+# define USI_START_COND_INT USISIF
+# define USI_START_VECTOR USI_START_vect
+# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
+#endif
+
+#if defined( __AVR_ATtiny2313__ )
+# define DDR_USI DDRB
+# define PORT_USI PORTB
+# define PIN_USI PINB
+# define PORT_USI_SDA PB5
+# define PORT_USI_SCL PB7
+# define PIN_USI_SDA PINB5
+# define PIN_USI_SCL PINB7
+# define USI_START_COND_INT USISIF
+# define USI_START_VECTOR USI_START_vect
+# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
+#endif
+
+#if defined(__AVR_ATtiny84__) | \
+ defined(__AVR_ATtiny44__)
+# define DDR_USI DDRA
+# define PORT_USI PORTA
+# define PIN_USI PINA
+# define PORT_USI_SDA PORTA6
+# define PORT_USI_SCL PORTA4
+# define PIN_USI_SDA PINA6
+# define PIN_USI_SCL PINA4
+# define USI_START_COND_INT USISIF
+# define USI_START_VECTOR USI_START_vect
+# define USI_OVERFLOW_VECTOR USI_OVF_vect
+#endif
+
+#if defined( __AVR_ATtiny25__ ) | \
+ defined( __AVR_ATtiny45__ ) | \
+ defined( __AVR_ATtiny85__ )
+# define DDR_USI DDRB
+# define PORT_USI PORTB
+# define PIN_USI PINB
+# define PORT_USI_SDA PB0
+# define PORT_USI_SCL PB2
+# define PIN_USI_SDA PINB0
+# define PIN_USI_SCL PINB2
+# define USI_START_COND_INT USISIF
+# define USI_START_VECTOR USI_START_vect
+# define USI_OVERFLOW_VECTOR USI_OVF_vect
+#endif
+
+#if defined( __AVR_ATtiny26__ )
+# define DDR_USI DDRB
+# define PORT_USI PORTB
+# define PIN_USI PINB
+# define PORT_USI_SDA PB0
+# define PORT_USI_SCL PB2
+# define PIN_USI_SDA PINB0
+# define PIN_USI_SCL PINB2
+# define USI_START_COND_INT USISIF
+# define USI_START_VECTOR USI_STRT_vect
+# define USI_OVERFLOW_VECTOR USI_OVF_vect
+#endif
+
+#if defined( __AVR_ATtiny261__ ) | \
+ defined( __AVR_ATtiny461__ ) | \
+ defined( __AVR_ATtiny861__ )
+# define DDR_USI DDRB
+# define PORT_USI PORTB
+# define PIN_USI PINB
+# define PORT_USI_SDA PB0
+# define PORT_USI_SCL PB2
+# define PIN_USI_SDA PINB0
+# define PIN_USI_SCL PINB2
+# define USI_START_COND_INT USISIF
+# define USI_START_VECTOR USI_START_vect
+# define USI_OVERFLOW_VECTOR USI_OVF_vect
+#endif
+
+#if defined( __AVR_ATmega165__ ) | \
+ defined( __AVR_ATmega325__ ) | \
+ defined( __AVR_ATmega3250__ ) | \
+ defined( __AVR_ATmega645__ ) | \
+ defined( __AVR_ATmega6450__ ) | \
+ defined( __AVR_ATmega329__ ) | \
+ defined( __AVR_ATmega3290__ )
+# define DDR_USI DDRE
+# define PORT_USI PORTE
+# define PIN_USI PINE
+# define PORT_USI_SDA PE5
+# define PORT_USI_SCL PE4
+# define PIN_USI_SDA PINE5
+# define PIN_USI_SCL PINE4
+# define USI_START_COND_INT USISIF
+# define USI_START_VECTOR USI_START_vect
+# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
+#endif
+
+#if defined( __AVR_ATmega169__ )
+# define DDR_USI DDRE
+# define PORT_USI PORTE
+# define PIN_USI PINE
+# define PORT_USI_SDA PE5
+# define PORT_USI_SCL PE4
+# define PIN_USI_SDA PINE5
+# define PIN_USI_SCL PINE4
+# define USI_START_COND_INT USISIF
+# define USI_START_VECTOR USI_START_vect
+# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
+#endif
+
+// These macros make the stop condition detection code more readable.
+#define USI_PINS_SCL_SDA ( ( 1 << PIN_USI_SDA ) | ( 1 << PIN_USI_SCL ) )
+#define USI_PINS_SDA ( 1 << PIN_USI_SDA )
+#define USI_PINS_SCL ( 1 << PIN_USI_SCL )
+
+/********************************************************************************
+
+ functions implemented as macros
+
+********************************************************************************/
+
+#define SET_USI_TO_SEND_ACK( ) \
+{ \
+ /* prepare ACK, ack is a zero */ \
+ USIDR = 0; \
+ /* set SDA as output */ \
+ DDR_USI |= ( 1 << PORT_USI_SDA ); \
+ /* clear all interrupt flags, except Start Cond */ \
+ USISR = \
+ ( 0 << USI_START_COND_INT ) | \
+ ( 1 << USIOIF ) | ( 1 << USIPF ) | \
+ ( 1 << USIDC )| \
+ /* set USI counter to shift 1 bit */ \
+ ( 0x0E << USICNT0 ); \
+}
+
+#define SET_USI_TO_READ_ACK( ) \
+{ \
+ /* set SDA as input */ \
+ DDR_USI &= ~( 1 << PORT_USI_SDA ); \
+ /* prepare ACK */ \
+ USIDR = 0; \
+ /* clear all interrupt flags, except Start Cond */ \
+ USISR = \
+ ( 0 << USI_START_COND_INT ) | \
+ ( 1 << USIOIF ) | \
+ ( 1 << USIPF ) | \
+ ( 1 << USIDC ) | \
+ /* set USI counter to shift 1 bit */ \
+ ( 0x0E << USICNT0 ); \
+}
+
+#define SET_USI_TO_TWI_START_CONDITION_MODE( ) \
+{ \
+ USICR = \
+ /* enable Start Condition Interrupt, disable Overflow Interrupt */ \
+ ( 1 << USISIE ) | ( 0 << USIOIE ) | \
+ /* set USI in Two-wire mode, no USI Counter overflow hold */ \
+ ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | \
+ /* Shift Register Clock Source = External, positive edge */ \
+ /* 4-Bit Counter Source = external, both edges */ \
+ ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | \
+ /* no toggle clock-port pin */ \
+ ( 0 << USITC ); \
+ USISR = \
+ /* clear all interrupt flags, except Start Cond */ \
+ ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \
+ ( 1 << USIDC ) | ( 0x0 << USICNT0 ); \
+}
+
+#define SET_USI_TO_SEND_DATA() \
+{ \
+ DDR_USI |= (1 << PORT_USI_SDA); /* Set SDA as output */ \
+ USISR = (0 << USI_START_COND_INT) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) \
+ | /* Clear all flags, except Start Cond */ \
+ (0x0 << USICNT0); /* set USI to shift out 8 bits */ \
+}
+
+#define SET_USI_TO_READ_DATA( ) \
+{ \
+ /* set SDA as input */ \
+ DDR_USI &= ~( 1 << PORT_USI_SDA ); \
+ /* clear all interrupt flags, except Start Cond */ \
+ USISR = \
+ ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | \
+ ( 1 << USIPF ) | ( 1 << USIDC ) | \
+ /* set USI to shift out 8 bits */ \
+ ( 0x0 << USICNT0 ); \
+}
+
+#define USI_RECEIVE_CALLBACK() \
+{ \
+ if (usi_onReceiverPtr) \
+ { \
+ if (usiTwiAmountDataInReceiveBuffer()) \
+ { \
+ usi_onReceiverPtr(usiTwiAmountDataInReceiveBuffer()); \
+ } \
+ } \
+}
+
+#define USI_REQUEST_CALLBACK() \
+{ \
+ if(usi_onRequestPtr) usi_onRequestPtr(); \
+}
+
+/********************************************************************************
+
+ typedef's
+
+********************************************************************************/
+
+typedef enum
+{
+ USI_SLAVE_CHECK_ADDRESS = 0x00,
+ USI_SLAVE_SEND_DATA = 0x01,
+ USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA = 0x02,
+ USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA = 0x03,
+ USI_SLAVE_REQUEST_DATA = 0x04,
+ USI_SLAVE_GET_DATA_AND_SEND_ACK = 0x05
+} overflowState_t;
+
+
+
+/********************************************************************************
+
+ local variables
+
+********************************************************************************/
+
+static uint8_t slaveAddress;
+static uint8_t sleep_enable_bit;
+static uint8_t in_transaction;
+static volatile overflowState_t overflowState;
+
+
+static uint8_t rxBuf[ TWI_RX_BUFFER_SIZE ];
+static volatile uint8_t rxHead;
+static volatile uint8_t rxTail;
+static volatile uint8_t rxCount;
+
+static uint8_t txBuf[ TWI_TX_BUFFER_SIZE ];
+static volatile uint8_t txHead;
+static volatile uint8_t txTail;
+static volatile uint8_t txCount;
+
+
+
+/********************************************************************************
+
+ local functions
+
+********************************************************************************/
+
+// flushes the TWI buffers
+
+static void flushTwiBuffers( void )
+{
+ rxTail = 0;
+ rxHead = 0;
+ rxCount = 0;
+ txTail = 0;
+ txHead = 0;
+ txCount = 0;
+} // end flushTwiBuffers
+
+
+
+/********************************************************************************
+
+ public functions
+
+********************************************************************************/
+
+// initialise USI for TWI slave mode
+
+void usiTwiSlaveInit( uint8_t ownAddress )
+{
+ // initialize the TX and RX buffers to empty
+ flushTwiBuffers( );
+
+ slaveAddress = ownAddress;
+
+ // In Two Wire mode (USIWM1, USIWM0 = 1X), the slave USI will pull SCL
+ // low when a start condition is detected or a counter overflow (only
+ // for USIWM1, USIWM0 = 11). This inserts a wait state. SCL is released
+ // by the ISRs (USI_START_vect and USI_OVERFLOW_vect).
+
+ // Set SCL and SDA as output
+ DDR_USI |= ( 1 << PORT_USI_SCL ) | ( 1 << PORT_USI_SDA );
+
+ // set SCL high
+ PORT_USI |= ( 1 << PORT_USI_SCL );
+
+ // set SDA high
+ PORT_USI |= ( 1 << PORT_USI_SDA );
+
+ // Set SDA as input
+ DDR_USI &= ~( 1 << PORT_USI_SDA );
+
+ USICR =
+ // enable Start Condition Interrupt
+ ( 1 << USISIE ) |
+ // disable Overflow Interrupt
+ ( 0 << USIOIE ) |
+ // set USI in Two-wire mode, no USI Counter overflow hold
+ ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |
+ // Shift Register Clock Source = external, positive edge
+ // 4-Bit Counter Source = external, both edges
+ ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
+ // no toggle clock-port pin
+ ( 0 << USITC );
+
+ // clear all interrupt flags and reset overflow counter
+
+ USISR = ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | ( 1 << USIDC );
+
+ // The 'in_transaction' variable remembers if the usiTwiSlave driver is in the middle of
+ // an i2c transaction. Initialize it to zero
+ in_transaction = 0;
+
+} // end usiTwiSlaveInit
+
+
+bool usiTwiDataInTransmitBuffer(void) //Fonction modif : affiche 255 constamment
+{ //Solution : creer une variable temporaire recuperant rxTail et la comparant avec rxHead
+
+ unsigned char tmpRxTail; // Creation d'une variable temporaire pour stocker rxTail au moment present
+ tmpRxTail = rxTail; // on recupere rxTail dans la variable temporaire
+ return ( rxHead != tmpRxTail ); // Renvoi 0 si aucune donnee n'est envoyee
+
+ // renvoi 0 mais perturbe la transmission
+ //return txCount;
+
+} // end usiTwiDataInTransmitBuffer
+
+
+// put data in the transmission buffer, wait if buffer is full
+
+void usiTwiTransmitByte( uint8_t data )
+{
+
+ // wait for free space in buffer
+ while ( txCount == TWI_TX_BUFFER_SIZE) ;
+
+ // store data in buffer
+ txBuf[ txHead ] = data;
+ txHead = ( txHead + 1 ) & TWI_TX_BUFFER_MASK;
+ txCount++;
+
+} // end usiTwiTransmitByte
+
+
+// return a byte from the receive buffer, wait if buffer is empty
+
+uint8_t usiTwiReceiveByte( void )
+{
+ uint8_t rtn_byte;
+
+ // wait for Rx data
+ while ( !rxCount );
+
+ rtn_byte = rxBuf [ rxTail ];
+ // calculate buffer index
+ rxTail = ( rxTail + 1 ) & TWI_RX_BUFFER_MASK;
+ rxCount--;
+
+ // return data from the buffer.
+ return rtn_byte;
+
+} // end usiTwiReceiveByte
+
+
+uint8_t usiTwiAmountDataInReceiveBuffer(void)
+{
+ return rxCount;
+}
+
+
+/********************************************************************************
+
+ USI Start Condition ISR
+
+********************************************************************************/
+
+ISR( USI_START_VECTOR )
+{
+ uint8_t usi_pins;
+ // http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__interrupts.html
+
+ // Notes about ISR. The compiler in the Arduino IDE handles some of the
+ // basic ISR plumbing (unless the "ISR_NAKED" attribute is applied).
+ // * The AVR processor resets the SREG.I bit when jumping into an ISR
+ // * The compiler automatically adds code to save SREG
+ // * < user's ISR code goes here >
+ // * The compiler automatically adds code to restore SREG
+ // * The compiler automatically uses the RETI instruction to return from the ISR.
+ // The RETI instruction enables interrupts after the return from ISR.
+ // The compiler behavior can be altered with attributes into the ISR declaration;
+ // however, the description above is the default.
+
+ // cli() call is not necessary. Processor disables interrupts when
+ // jumping to an ISR
+
+ // no need to save the SREG. The compiler does this automatically when using the
+ // ISR construct without modifying attributes.
+
+ if ( !in_transaction )
+ {
+ // remeber the sleep enable bit when entering the ISR
+ sleep_enable_bit = MCUCR & ( 1 << SE );
+
+ // clear the sleep enable bit to prevent the CPU from entering sleep mode while executing this ISR.
+ MCUCR &= ~( 1 << SE );
+ }
+
+ // set default starting conditions for new TWI package
+ overflowState = USI_SLAVE_CHECK_ADDRESS;
+
+ // set SDA as input
+ DDR_USI &= ~( 1 << PORT_USI_SDA );
+
+ // the start condition is that the master pulls SDA low.
+
+ // wait for SCL to go low to ensure the Start Condition has completed (the
+ // start detector will hold SCL low ) - if a Stop Condition arises then leave
+ // the interrupt to prevent waiting forever - don't use USISR to test for Stop
+ // Condition as in Application Note AVR312 because the Stop Condition Flag is
+ // going to be set from the last TWI sequence
+
+ // while SCL is high and SDA is low
+ while ( ( usi_pins = PIN_USI & USI_PINS_SCL_SDA ) == USI_PINS_SCL );
+
+ // if SDA line was low at SCL edge, then start condition occurred
+ if ( !( usi_pins & USI_PINS_SDA ) )
+ {
+ // a Stop Condition did not occur
+
+ // Execute callback if this is a repeated start
+ if (in_transaction)
+ {
+ USI_RECEIVE_CALLBACK();
+ }
+
+ USICR =
+ // keep Start Condition Interrupt enabled to detect RESTART
+ ( 1 << USISIE ) |
+ // enable Overflow Interrupt
+ ( 1 << USIOIE ) |
+ // set USI in Two-wire mode, hold SCL low on USI Counter overflow
+ ( 1 << USIWM1 ) | ( 1 << USIWM0 ) |
+ // Shift Register Clock Source = External, positive edge
+ // 4-Bit Counter Source = external, both edges
+ ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
+ // no toggle clock-port pin
+ ( 0 << USITC );
+
+ //remember that the USI is in a valid i2c transaction
+ in_transaction = 1;
+
+ }
+ else
+ {
+ // a Stop Condition did occur
+
+ USICR =
+ // enable Start Condition Interrupt
+ ( 1 << USISIE ) |
+ // disable Overflow Interrupt
+ ( 0 << USIOIE ) |
+ // set USI in Two-wire mode, no USI Counter overflow hold
+ ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |
+ // Shift Register Clock Source = external, positive edge
+ // 4-Bit Counter Source = external, both edges
+ ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
+ // no toggle clock-port pin
+ ( 0 << USITC );
+
+ //no longer in valid i2c transaction
+ in_transaction = 0;
+ // restore the sleep enable bit
+ MCUCR |= sleep_enable_bit;
+
+ } // end if
+
+ USISR =
+ // clear interrupt flags - resetting the Start Condition Flag will
+ // release SCL
+ ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) |
+ ( 1 << USIPF ) |( 1 << USIDC ) |
+ // set USI to sample 8 bits (count 16 external SCL pin toggles)
+ ( 0x0 << USICNT0);
+
+ // no need to restore the SREG. The compiler does this automatically when using the
+ // ISR construct without modifying attributes.
+
+ // The compiler automatically uses an RETI instruction to return when using the
+ // ISR construct without modifying attributes.
+
+} // end ISR( USI_START_VECTOR )
+
+
+
+/********************************************************************************
+
+ USI Overflow ISR
+
+Handles all the communication.
+
+Only disabled when waiting for a new Start Condition.
+
+********************************************************************************/
+
+ISR( USI_OVERFLOW_VECTOR )
+{
+ uint8_t finished;
+ uint8_t usi_pins;
+
+ // http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__interrupts.html
+
+ // Notes about ISR. The compiler in the Arduino IDE handles some of the
+ // basic ISR plumbing.
+ // * The AVR processor resets the SREG.I bit when jumping into an ISR
+ // * The compiler automatically adds code to save the SREG
+ // * < user's ISR code goes here >
+ // * The compiler automatically adds code to restore the SREG
+ // * The compiler automatically uses the RETI instruction to return from the ISR.
+ // The RETI insturction enables interrupts after the return from ISR.
+ // The compiler behavior can be altered with attributes into the ISR declaration;
+ // however, the description above is the default.
+
+ // cli() call is not necessary. Processor disables interrupts when
+ // jumping to an ISR
+
+ // no need to save the SREG. The compiler does this automatically when using the
+ // ISR construct without modifying attributes.
+
+ // The ISR is only ever entered because the ISR(USI_START_VECTOR) interrupt
+ // routine ran first. That routine saved the sleep mode and disabled sleep.
+
+ // Most of the time this routine exits, it has setup the USI to shift in/out bits
+ // and is expected to re-entered because of the USI overflow interrupt. Track whether or
+ // not the transaction is completely finished.
+ finished = 0;
+
+
+ switch ( overflowState )
+ {
+
+ // Address mode: check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK,
+ // else reset USI
+ case USI_SLAVE_CHECK_ADDRESS:
+ if ( ( USIDR == 0 ) || ( ( USIDR >> 1 ) == slaveAddress) )
+ {
+ if ( USIDR & 0x01 )
+ {
+ overflowState = USI_SLAVE_SEND_DATA;
+ }
+ else
+ {
+ overflowState = USI_SLAVE_REQUEST_DATA;
+ } // end if
+
+ // ack the start frame
+ // sets up the USI to pull SDA low and clock one bit (two edges)
+ SET_USI_TO_SEND_ACK( );
+ }
+ else
+ {
+ SET_USI_TO_TWI_START_CONDITION_MODE( );
+ finished = 1;
+ }
+ break;
+
+ // master-read / slave-send: check reply and goto USI_SLAVE_SEND_DATA if OK,
+ // else reset USI
+ case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:
+ // Execute request callback for each byte requested, as this is the intended
+ // behavior of this library
+ USI_REQUEST_CALLBACK();
+ if ( USIDR )
+ {
+ // if NACK, the master does not want more data
+ SET_USI_TO_TWI_START_CONDITION_MODE( );
+ finished = 1;
+ break;
+ }
+ // from here we just drop straight into USI_SLAVE_SEND_DATA if the
+ // master sent an ACK
+
+ // copy data from buffer to USIDR and set USI to shift byte
+ // next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA
+ case USI_SLAVE_SEND_DATA:
+ // Get data from Buffer
+ if ( txCount )
+ {
+ USIDR = txBuf[ txTail ];
+ txTail = ( txTail + 1 ) & TWI_TX_BUFFER_MASK;
+ txCount--;
+
+ overflowState = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;
+ SET_USI_TO_SEND_DATA( );
+ }
+ else
+ {
+ // the buffer is empty
+ SET_USI_TO_READ_ACK( ); // This might be neccessary sometimes see http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=805227#805227
+ SET_USI_TO_TWI_START_CONDITION_MODE( );
+ } // end if
+ break;
+
+ // set USI to sample reply from master
+ // next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA
+ case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:
+ overflowState = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA;
+ SET_USI_TO_READ_ACK( );
+ break;
+
+ // master-send / slave-receive: set USI to sample data from master, next
+ // USI_SLAVE_GET_DATA_AND_SEND_ACK
+ case USI_SLAVE_REQUEST_DATA:
+ overflowState = USI_SLAVE_GET_DATA_AND_SEND_ACK;
+ SET_USI_TO_READ_DATA( );
+
+ // with the SET_USI_TO_READ_DATA() macro call above, the USI has
+ // been setup to catch the next byte if the master sends one.
+ // while that's going on, look for a stop condition here which
+ // is when the SDA line goes high after the SCL line;
+
+ // wait until SCL goes high
+ while ( ! ( ( usi_pins = PIN_USI & USI_PINS_SCL_SDA ) & USI_PINS_SCL ) );
+
+ // if SDA line was high at SCL edge, then not a stop condition
+ if ( usi_pins & USI_PINS_SDA )
+ break;
+
+ // wait until SCL goes low or SDA goes high
+ while ( ( usi_pins = PIN_USI & USI_PINS_SCL_SDA ) == USI_PINS_SCL );
+
+ // if both SCL and SDA are high, then stop condition occurred
+ if ( usi_pins == USI_PINS_SCL_SDA )
+ {
+ USI_RECEIVE_CALLBACK();
+ SET_USI_TO_TWI_START_CONDITION_MODE( );
+ finished = 1;
+ }
+
+ break;
+
+ // copy data from USIDR and send ACK
+ // next USI_SLAVE_REQUEST_DATA
+ case USI_SLAVE_GET_DATA_AND_SEND_ACK:
+ // put data into buffer
+ // check buffer size
+ if ( rxCount < TWI_RX_BUFFER_SIZE )
+ {
+ rxBuf[ rxHead ] = USIDR;
+ rxHead = ( rxHead + 1 ) & TWI_RX_BUFFER_MASK;
+ rxCount++;
+ } else {
+ // overrun
+ // drop data
+ }
+ // next USI_SLAVE_REQUEST_DATA
+ overflowState = USI_SLAVE_REQUEST_DATA;
+ SET_USI_TO_SEND_ACK( );
+ break;
+
+ } // end switch
+
+ if (finished)
+ {
+ //no longer in valid i2c transaction
+ in_transaction = 0;
+ // restore the sleep enable bit
+ // note that this allows sleep -- it does not cause sleep
+ MCUCR |= sleep_enable_bit;
+ }
+
+ // no need to restore the SREG. The compiler does this automatically when using the
+ // ISR construct without modifying attributes.
+
+ // The compiler automatically uses an RETI instruction to return when using the
+ // ISR construct without modifying attributes.
+
+} // end ISR( USI_OVERFLOW_VECTOR )
diff --git a/i2c_test_attiny85/usiTwiSlave.h b/i2c_test_attiny85/usiTwiSlave.h
new file mode 100755
index 0000000..8a1cfaf
--- /dev/null
+++ b/i2c_test_attiny85/usiTwiSlave.h
@@ -0,0 +1,96 @@
+/********************************************************************************
+
+Header file for the USI TWI Slave driver.
+
+Created by Donald R. Blake
+donblake at worldnet.att.net
+
+---------------------------------------------------------------------------------
+
+Created from Atmel source files for Application Note AVR312: Using the USI Module
+as an I2C slave.
+
+This program is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+---------------------------------------------------------------------------------
+
+Change Activity:
+
+ Date Description
+ ------ -------------
+ 15 Mar 2007 Created.
+
+********************************************************************************/
+
+
+
+#ifndef _USI_TWI_SLAVE_H_
+#define _USI_TWI_SLAVE_H_
+
+
+
+/********************************************************************************
+
+ includes
+
+********************************************************************************/
+
+#include
+#include
+
+
+
+/********************************************************************************
+
+ prototypes
+
+********************************************************************************/
+
+void usiTwiSlaveInit( uint8_t );
+void usiTwiTransmitByte( uint8_t );
+uint8_t usiTwiReceiveByte( void );
+bool usiTwiDataInTransmitBuffer(void);
+uint8_t usiTwiAmountDataInReceiveBuffer(void);
+// on_XXX handler pointers
+void (*usi_onRequestPtr)(void);
+void (*usi_onReceiverPtr)(uint8_t);
+
+
+/********************************************************************************
+
+ driver buffer definitions
+
+********************************************************************************/
+
+// permitted RX buffer sizes: 1, 2, 4, 8, 16, 32, 64, 128 or 256
+
+#ifndef TWI_RX_BUFFER_SIZE
+#define TWI_RX_BUFFER_SIZE ( 16 )
+#endif
+#define TWI_RX_BUFFER_MASK ( TWI_RX_BUFFER_SIZE - 1 )
+
+#if ( TWI_RX_BUFFER_SIZE & TWI_RX_BUFFER_MASK )
+# error TWI RX buffer size is not a power of 2
+#endif
+
+// permitted TX buffer sizes: 1, 2, 4, 8, 16, 32, 64, 128 or 256
+
+#ifndef TWI_TX_BUFFER_SIZE
+#define TWI_TX_BUFFER_SIZE ( 1 )
+#endif
+#define TWI_TX_BUFFER_MASK ( TWI_TX_BUFFER_SIZE - 1 )
+
+#if ( TWI_TX_BUFFER_SIZE & TWI_TX_BUFFER_MASK )
+# error TWI TX buffer size is not a power of 2
+#endif
+
+
+
+#endif // ifndef _USI_TWI_SLAVE_H_