VOC Optimation
[owSlave2.git] / common / I2C / USI_TWI_Master.c
index 5e6dea8..d5f2596 100644 (file)
-/*****************************************************************************
-*
-* Atmel Corporation
-*
-* File              : USI_TWI_Master.c
-* Compiler          : AVRGCC Toolchain version 3.4.2
-* Revision          : $Revision: 992 $
-* Date              : $Date: 2013-11-07 $
-* Updated by        : $Author: Atmel $
-*
-* Support mail      : avr@atmel.com
-*
-* Supported devices : All device with USI module can be used.
-*                     The example is written for the ATmega169, ATtiny26 and ATtiny2313
-*
-* AppNote           : AVR310 - Using the USI module as a TWI Master
-*
-* Description       : This is an implementation of an TWI master using
-*                     the USI module as basis. The implementation assumes the AVR to
-*                     be the only TWI master in the system and can therefore not be
-*                     used in a multi-master system.
-* Usage             : Initialize the USI module by calling the USI_TWI_Master_Initialise() 
-*                     function. Hence messages/data are transceived on the bus using
-*                     the USI_TWI_Transceive() function. The transceive function 
-*                     returns a status byte, which can be used to evaluate the 
-*                     success of the transmission.
-*
-****************************************************************************/
-#define F_CPU 8000000UL
-#include <avr/io.h>
-#include "USI_TWI_Master.h"
-#include <util/delay.h>
-
-unsigned char USI_TWI_Master_Transfer( unsigned char );
-unsigned char USI_TWI_Master_Stop( void );
-
-union  USI_TWI_state
-{
-  unsigned char errorState;         // Can reuse the TWI_state for error states due to that it will not be need if there exists an error.
-  struct
-  {
-    unsigned char addressMode         : 1;
-    unsigned char masterWriteDataMode : 1;
-    unsigned char unused              : 6;
-  }; 
-}   USI_TWI_state;
-
-/*---------------------------------------------------------------
- USI TWI single master initialization function
----------------------------------------------------------------*/
-void USI_TWI_Master_Initialise( void )
-{
-  PORT_USI |= (1<<PIN_USI_SDA);           // Enable pullup on SDA, to set high as released state.
-  PORT_USI |= (1<<PIN_USI_SCL);           // Enable pullup on SCL, to set high as released state.
-  
-  DDR_USI  |= (1<<PIN_USI_SCL);           // Enable SCL as output.
-  DDR_USI  |= (1<<PIN_USI_SDA);           // Enable SDA as output.
-  
-  USIDR    =  0xFF;                       // Preload dataregister with "released level" data.
-  USICR    =  (0<<USISIE)|(0<<USIOIE)|                            // Disable Interrupts.
-              (1<<USIWM1)|(0<<USIWM0)|                            // Set USI in Two-wire mode.
-              (1<<USICS1)|(0<<USICS0)|(1<<USICLK)|                // Software stobe as counter clock source
-              (0<<USITC);
-  USISR   =   (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Clear flags,
-              (0x0<<USICNT0);                                     // and reset counter.
-}
-
-/*---------------------------------------------------------------
-Use this function to get hold of the error message from the last transmission
----------------------------------------------------------------*/
-unsigned char USI_TWI_Get_State_Info( void )
-{
-  return ( USI_TWI_state.errorState );                            // Return error state.
-}
-
-/*---------------------------------------------------------------
- USI Transmit and receive function. LSB of first byte in data 
- indicates if a read or write cycles is performed. If set a read
- operation is performed.
-
- Function generates (Repeated) Start Condition, sends address and
- R/W, Reads/Writes Data, and verifies/sends ACK.
- Success or error code is returned. Error codes are defined in 
- USI_TWI_Master.h
----------------------------------------------------------------*/
-unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize)
-{
-  unsigned char tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and
-                                 (0x0<<USICNT0);                                     // set USI to shift 8 bits i.e. count 16 clock edges.
-  unsigned char tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and
-                                 (0xE<<USICNT0);                                     // set USI to shift 1 bit i.e. count 2 clock edges.
-
-  USI_TWI_state.errorState = 0;
-  USI_TWI_state.addressMode = TRUE;
-
-#ifdef PARAM_VERIFICATION
-  if(msg > (unsigned char*)RAMEND)                 // Test if address is outside SRAM space
-  {
-    USI_TWI_state.errorState = USI_TWI_DATA_OUT_OF_BOUND;
-    return (FALSE);
-  }
-  if(msgSize <= 1)                                 // Test if the transmission buffer is empty
-  {
-    USI_TWI_state.errorState = USI_TWI_NO_DATA;
-    return (FALSE);
-  }
-#endif
-
-#ifdef NOISE_TESTING                                // Test if any unexpected conditions have arrived prior to this execution.
-  if( USISR & (1<<USISIF) )
-  {
-    USI_TWI_state.errorState = USI_TWI_UE_START_CON;
-    return (FALSE);
-  }
-  if( USISR & (1<<USIPF) )
-  {
-    USI_TWI_state.errorState = USI_TWI_UE_STOP_CON;
-    return (FALSE);
-  }
-  if( USISR & (1<<USIDC) )
-  {
-    USI_TWI_state.errorState = USI_TWI_UE_DATA_COL;
-    return (FALSE);
-  }
-#endif
-
-  if ( !(*msg & (1<<TWI_READ_BIT)) )                // The LSB in the address byte determines if is a masterRead or masterWrite operation.
-  {
-    USI_TWI_state.masterWriteDataMode = TRUE;
-  }
-
-/* Release SCL to ensure that (repeated) Start can be performed */
-  PORT_USI |= (1<<PIN_USI_SCL);                     // Release SCL.
-  while( !(PIN_USI & (1<<PIN_USI_SCL)) );          // Verify that SCL becomes high.
-#ifdef TWI_FAST_MODE
-  _delay_us( T4_TWI/4 );                         // Delay for T4TWI if TWI_FAST_MODE
-#else
-  _delay_us( T2_TWI/4 );                         // Delay for T2TWI if TWI_STANDARD_MODE
-#endif
-
-/* Generate Start Condition */
-  PORT_USI &= ~(1<<PIN_USI_SDA);                    // Force SDA LOW.
-  _delay_us( T4_TWI/4 );                         
-  PORT_USI &= ~(1<<PIN_USI_SCL);                    // Pull SCL LOW.
-  PORT_USI |= (1<<PIN_USI_SDA);                     // Release SDA.
-
-#ifdef SIGNAL_VERIFY
-  if( !(USISR & (1<<USISIF)) )
-  {
-    USI_TWI_state.errorState = USI_TWI_MISSING_START_CON;  
-    return (FALSE);
-  }
-#endif
-
-/*Write address and Read/Write data */
-  do
-  {
-    /* If masterWrite cycle (or inital address tranmission)*/
-    if (USI_TWI_state.addressMode || USI_TWI_state.masterWriteDataMode)
-    {
-      /* Write a byte */
-      PORT_USI &= ~(1<<PIN_USI_SCL);                // Pull SCL LOW.
-      USIDR     = *(msg++);                        // Setup data.
-      USI_TWI_Master_Transfer( tempUSISR_8bit );    // Send 8 bits on bus.
-      
-      /* Clock and verify (N)ACK from slave */
-      DDR_USI  &= ~(1<<PIN_USI_SDA);                // Enable SDA as input.
-      if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) ) 
-      {
-        if ( USI_TWI_state.addressMode )
-          USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
-        else
-          USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
-        return (FALSE);
-      }
-      USI_TWI_state.addressMode = FALSE;            // Only perform address transmission once.
-    }
-    /* Else masterRead cycle*/
-    else
-    {
-      /* Read a data byte */
-      DDR_USI   &= ~(1<<PIN_USI_SDA);               // Enable SDA as input.
-      *(msg++)  = USI_TWI_Master_Transfer( tempUSISR_8bit );
-
-      /* Prepare to generate ACK (or NACK in case of End Of Transmission) */
-      if( msgSize == 1)                            // If transmission of last byte was performed.
-      {
-        USIDR = 0xFF;                              // Load NACK to confirm End Of Transmission.
-      }
-      else
-      {
-        USIDR = 0x00;                              // Load ACK. Set data register bit 7 (output for SDA) low.
-      }
-      USI_TWI_Master_Transfer( tempUSISR_1bit );   // Generate ACK/NACK.
-    }
-  }while( --msgSize) ;                             // Until all data sent/received.
-  
-  USI_TWI_Master_Stop();                           // Send a STOP condition on the TWI bus.
-
-/* Transmission successfully completed*/
-  return (TRUE);
-}
-
-/*---------------------------------------------------------------
- Core function for shifting data in and out from the USI.
- Data to be sent has to be placed into the USIDR prior to calling
- this function. Data read, will be return'ed from the function.
----------------------------------------------------------------*/
-unsigned char USI_TWI_Master_Transfer( unsigned char temp )
-{
-  USISR = temp;                                     // Set USISR according to temp.
-                                                    // Prepare clocking.
-  temp  =  (0<<USISIE)|(0<<USIOIE)|                 // Interrupts disabled
-           (1<<USIWM1)|(0<<USIWM0)|                 // Set USI in Two-wire mode.
-           (1<<USICS1)|(0<<USICS0)|(1<<USICLK)|     // Software clock strobe as source.
-           (1<<USITC);                              // Toggle Clock Port.
-  do
-  {
-    _delay_us( T2_TWI/4 );              
-    USICR = temp;                          // Generate positve SCL edge.
-    while( !(PIN_USI & (1<<PIN_USI_SCL)) );// Wait for SCL to go high.
-    _delay_us( T4_TWI/4 );              
-    USICR = temp;                          // Generate negative SCL edge.
-  }while( !(USISR & (1<<USIOIF)) );        // Check for transfer complete.
-  
-  _delay_us( T2_TWI/4 );                
-  temp  = USIDR;                           // Read out data.
-  USIDR = 0xFF;                            // Release SDA.
-  DDR_USI |= (1<<PIN_USI_SDA);             // Enable SDA as output.
-
-  return temp;                             // Return the data from the USIDR
-}
-
-/*---------------------------------------------------------------
- Function for generating a TWI Stop Condition. Used to release 
- the TWI bus.
----------------------------------------------------------------*/
-unsigned char USI_TWI_Master_Stop( void )
-{
-  PORT_USI &= ~(1<<PIN_USI_SDA);           // Pull SDA low.
-  PORT_USI |= (1<<PIN_USI_SCL);            // Release SCL.
-  while( !(PIN_USI & (1<<PIN_USI_SCL)) );  // Wait for SCL to go high.
-  _delay_us( T4_TWI/4 );               
-  PORT_USI |= (1<<PIN_USI_SDA);            // Release SDA.
-  _delay_us( T2_TWI/4 );                
-  
-#ifdef SIGNAL_VERIFY
-  if( !(USISR & (1<<USIPF)) )
-  {
-    USI_TWI_state.errorState = USI_TWI_MISSING_STOP_CON;    
-    return (FALSE);
-  }
-#endif
-
-  return (TRUE);
-}
-
-
-
-unsigned char I2c_WriteByte(unsigned char msg) {
-  unsigned char tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and
-  (0x0<<USICNT0);                                     // set USI to shift 8 bits i.e. count 16 clock edges.
-  unsigned char tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and
-  (0xE<<USICNT0);                                     // set USI to shift 1 bit i.e. count 2 clock edges.
-
-       /* Write a byte */
-       PORT_USI &= ~(1<<PIN_USI_SCL);                // Pull SCL LOW.
-       USIDR     = msg;                        // Setup data.
-       USI_TWI_Master_Transfer( tempUSISR_8bit );    // Send 8 bits on bus.
-       /* Clock and verify (N)ACK from slave */
-       DDR_USI  &= ~(1<<PIN_USI_SDA);                // Enable SDA as input.
-       if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) ){
-               if ( USI_TWI_state.addressMode )
-                       USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
-               else
-                       USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
-               return 2;
-       }
-       return 0;
-}
-unsigned char I2c_ReadByte(unsigned char ack_mode) {
-  unsigned char tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and
-  (0x0<<USICNT0);                                     // set USI to shift 8 bits i.e. count 16 clock edges.
-  unsigned char tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and
-  (0xE<<USICNT0);                                     // set USI to shift 1 bit i.e. count 2 clock edges.
-       
-       /* Read a data byte */
-       DDR_USI   &= ~(1<<PIN_USI_SDA);               // Enable SDA as input.
-    unsigned char msg = USI_TWI_Master_Transfer( tempUSISR_8bit );
-
-    /* Prepare to generate ACK (or NACK in case of End Of Transmission) */
-    if( ack_mode == NO_ACK) {                           // If transmission of last byte was performed.
-               USIDR = 0xFF;                              // Load NACK to confirm End Of Transmission.
-    } else   {
-               USIDR = 0x00;                              // Load ACK. Set data register bit 7 (output for SDA) low.
-    }
-    USI_TWI_Master_Transfer( tempUSISR_1bit );   // Generate ACK/NACK.
-       return msg;
-}
-
-void I2c_StartCondition() {
-/* Release SCL to ensure that (repeated) Start can be performed */
-PORT_USI |= (1<<PIN_USI_SCL);                     // Release SCL.
-while( !(PIN_USI & (1<<PIN_USI_SCL)) );          // Verify that SCL becomes high.
-#ifdef TWI_FAST_MODE
-_delay_us( T4_TWI/4 );                         // Delay for T4TWI if TWI_FAST_MODE
-#else
-_delay_us( T2_TWI/4 );                         // Delay for T2TWI if TWI_STANDARD_MODE
-#endif
-
-/* Generate Start Condition */
-PORT_USI &= ~(1<<PIN_USI_SDA);                    // Force SDA LOW.
-_delay_us( T4_TWI/4 );
-PORT_USI &= ~(1<<PIN_USI_SCL);                    // Pull SCL LOW.
-PORT_USI |= (1<<PIN_USI_SDA);                     // Release SDA.
-       
-       
-}
-void I2c_StopCondition() {
-       USI_TWI_Master_Stop();
-}
+/*****************************************************************************\r
+*\r
+* Atmel Corporation\r
+*\r
+* File              : USI_TWI_Master.c\r
+* Compiler          : AVRGCC Toolchain version 3.4.2\r
+* Revision          : $Revision: 992 $\r
+* Date              : $Date: 2013-11-07 $\r
+* Updated by        : $Author: Atmel $\r
+*\r
+* Support mail      : avr@atmel.com\r
+*\r
+* Supported devices : All device with USI module can be used.\r
+*                     The example is written for the ATmega169, ATtiny26 and ATtiny2313\r
+*\r
+* AppNote           : AVR310 - Using the USI module as a TWI Master\r
+*\r
+* Description       : This is an implementation of an TWI master using\r
+*                     the USI module as basis. The implementation assumes the AVR to\r
+*                     be the only TWI master in the system and can therefore not be\r
+*                     used in a multi-master system.\r
+* Usage             : Initialize the USI module by calling the USI_TWI_Master_Initialise() \r
+*                     function. Hence messages/data are transceived on the bus using\r
+*                     the USI_TWI_Transceive() function. The transceive function \r
+*                     returns a status byte, which can be used to evaluate the \r
+*                     success of the transmission.\r
+*\r
+****************************************************************************/\r
+#define F_CPU 8000000UL\r
+#include <avr/io.h>\r
+#include "USI_TWI_Master.h"\r
+#include <util/delay.h>\r
+\r
+unsigned char USI_TWI_Master_Transfer( unsigned char );\r
+unsigned char USI_TWI_Master_Stop( void );\r
+\r
+union  USI_TWI_state\r
+{\r
+  unsigned char errorState;         // Can reuse the TWI_state for error states due to that it will not be need if there exists an error.\r
+  struct\r
+  {\r
+    unsigned char addressMode         : 1;\r
+    unsigned char masterWriteDataMode : 1;\r
+    unsigned char unused              : 6;\r
+  }; \r
+}   USI_TWI_state;\r
+\r
+/*---------------------------------------------------------------\r
+ USI TWI single master initialization function\r
+---------------------------------------------------------------*/\r
+void USI_TWI_Master_Initialise( void )\r
+{\r
+  PORT_USI |= (1<<PIN_USI_SDA);           // Enable pullup on SDA, to set high as released state.\r
+  PORT_USI |= (1<<PIN_USI_SCL);           // Enable pullup on SCL, to set high as released state.\r
+  \r
+  DDR_USI  |= (1<<PIN_USI_SCL);           // Enable SCL as output.\r
+  DDR_USI  |= (1<<PIN_USI_SDA);           // Enable SDA as output.\r
+  \r
+  USIDR    =  0xFF;                       // Preload dataregister with "released level" data.\r
+  USICR    =  (0<<USISIE)|(0<<USIOIE)|                            // Disable Interrupts.\r
+              (1<<USIWM1)|(0<<USIWM0)|                            // Set USI in Two-wire mode.\r
+              (1<<USICS1)|(0<<USICS0)|(1<<USICLK)|                // Software stobe as counter clock source\r
+              (0<<USITC);\r
+  USISR   =   (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Clear flags,\r
+              (0x0<<USICNT0);                                     // and reset counter.\r
+}\r
+\r
+/*---------------------------------------------------------------\r
+Use this function to get hold of the error message from the last transmission\r
+---------------------------------------------------------------*/\r
+unsigned char USI_TWI_Get_State_Info( void )\r
+{\r
+  return ( USI_TWI_state.errorState );                            // Return error state.\r
+}\r
+\r
+/*---------------------------------------------------------------\r
+ USI Transmit and receive function. LSB of first byte in data \r
+ indicates if a read or write cycles is performed. If set a read\r
+ operation is performed.\r
+\r
+ Function generates (Repeated) Start Condition, sends address and\r
+ R/W, Reads/Writes Data, and verifies/sends ACK.\r
\r
+ Success or error code is returned. Error codes are defined in \r
+ USI_TWI_Master.h\r
+---------------------------------------------------------------*/\r
+unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize)\r
+{\r
+  unsigned char tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and\r
+                                 (0x0<<USICNT0);                                     // set USI to shift 8 bits i.e. count 16 clock edges.\r
+  unsigned char tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and\r
+                                 (0xE<<USICNT0);                                     // set USI to shift 1 bit i.e. count 2 clock edges.\r
+\r
+  USI_TWI_state.errorState = 0;\r
+  USI_TWI_state.addressMode = TRUE;\r
+\r
+#ifdef PARAM_VERIFICATION\r
+  if(msg > (unsigned char*)RAMEND)                 // Test if address is outside SRAM space\r
+  {\r
+    USI_TWI_state.errorState = USI_TWI_DATA_OUT_OF_BOUND;\r
+    return (FALSE);\r
+  }\r
+  if(msgSize <= 1)                                 // Test if the transmission buffer is empty\r
+  {\r
+    USI_TWI_state.errorState = USI_TWI_NO_DATA;\r
+    return (FALSE);\r
+  }\r
+#endif\r
+\r
+#ifdef NOISE_TESTING                                // Test if any unexpected conditions have arrived prior to this execution.\r
+  if( USISR & (1<<USISIF) )\r
+  {\r
+    USI_TWI_state.errorState = USI_TWI_UE_START_CON;\r
+    return (FALSE);\r
+  }\r
+  if( USISR & (1<<USIPF) )\r
+  {\r
+    USI_TWI_state.errorState = USI_TWI_UE_STOP_CON;\r
+    return (FALSE);\r
+  }\r
+  if( USISR & (1<<USIDC) )\r
+  {\r
+    USI_TWI_state.errorState = USI_TWI_UE_DATA_COL;\r
+    return (FALSE);\r
+  }\r
+#endif\r
+\r
+  if ( !(*msg & (1<<TWI_READ_BIT)) )                // The LSB in the address byte determines if is a masterRead or masterWrite operation.\r
+  {\r
+    USI_TWI_state.masterWriteDataMode = TRUE;\r
+  }\r
+\r
+/* Release SCL to ensure that (repeated) Start can be performed */\r
+  PORT_USI |= (1<<PIN_USI_SCL);                     // Release SCL.\r
+  while( !(PIN_USI & (1<<PIN_USI_SCL)) );          // Verify that SCL becomes high.\r
+#ifdef TWI_FAST_MODE\r
+  _delay_us( T4_TWI/4 );                         // Delay for T4TWI if TWI_FAST_MODE\r
+#else\r
+  _delay_us( T2_TWI/4 );                         // Delay for T2TWI if TWI_STANDARD_MODE\r
+#endif\r
+\r
+/* Generate Start Condition */\r
+  PORT_USI &= ~(1<<PIN_USI_SDA);                    // Force SDA LOW.\r
+  _delay_us( T4_TWI/4 );                         \r
+  PORT_USI &= ~(1<<PIN_USI_SCL);                    // Pull SCL LOW.\r
+  PORT_USI |= (1<<PIN_USI_SDA);                     // Release SDA.\r
+\r
+#ifdef SIGNAL_VERIFY\r
+  if( !(USISR & (1<<USISIF)) )\r
+  {\r
+    USI_TWI_state.errorState = USI_TWI_MISSING_START_CON;  \r
+    return (FALSE);\r
+  }\r
+#endif\r
+\r
+/*Write address and Read/Write data */\r
+  do\r
+  {\r
+    /* If masterWrite cycle (or inital address tranmission)*/\r
+    if (USI_TWI_state.addressMode || USI_TWI_state.masterWriteDataMode)\r
+    {\r
+      /* Write a byte */\r
+      PORT_USI &= ~(1<<PIN_USI_SCL);                // Pull SCL LOW.\r
+      USIDR     = *(msg++);                        // Setup data.\r
+      USI_TWI_Master_Transfer( tempUSISR_8bit );    // Send 8 bits on bus.\r
+      \r
+      /* Clock and verify (N)ACK from slave */\r
+      DDR_USI  &= ~(1<<PIN_USI_SDA);                // Enable SDA as input.\r
+      if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) ) \r
+      {\r
+        if ( USI_TWI_state.addressMode )\r
+          USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;\r
+        else\r
+          USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;\r
+        return (FALSE);\r
+      }\r
+      USI_TWI_state.addressMode = FALSE;            // Only perform address transmission once.\r
+    }\r
+    /* Else masterRead cycle*/\r
+    else\r
+    {\r
+      /* Read a data byte */\r
+      DDR_USI   &= ~(1<<PIN_USI_SDA);               // Enable SDA as input.\r
+      *(msg++)  = USI_TWI_Master_Transfer( tempUSISR_8bit );\r
+\r
+      /* Prepare to generate ACK (or NACK in case of End Of Transmission) */\r
+      if( msgSize == 1)                            // If transmission of last byte was performed.\r
+      {\r
+        USIDR = 0xFF;                              // Load NACK to confirm End Of Transmission.\r
+      }\r
+      else\r
+      {\r
+        USIDR = 0x00;                              // Load ACK. Set data register bit 7 (output for SDA) low.\r
+      }\r
+      USI_TWI_Master_Transfer( tempUSISR_1bit );   // Generate ACK/NACK.\r
+    }\r
+  }while( --msgSize) ;                             // Until all data sent/received.\r
+  \r
+  USI_TWI_Master_Stop();                           // Send a STOP condition on the TWI bus.\r
+\r
+/* Transmission successfully completed*/\r
+  return (TRUE);\r
+}\r
+\r
+/*---------------------------------------------------------------\r
+ Core function for shifting data in and out from the USI.\r
+ Data to be sent has to be placed into the USIDR prior to calling\r
+ this function. Data read, will be return'ed from the function.\r
+---------------------------------------------------------------*/\r
+unsigned char USI_TWI_Master_Transfer( unsigned char temp )\r
+{\r
+  USISR = temp;                                     // Set USISR according to temp.\r
+                                                    // Prepare clocking.\r
+  temp  =  (0<<USISIE)|(0<<USIOIE)|                 // Interrupts disabled\r
+           (1<<USIWM1)|(0<<USIWM0)|                 // Set USI in Two-wire mode.\r
+           (1<<USICS1)|(0<<USICS0)|(1<<USICLK)|     // Software clock strobe as source.\r
+           (1<<USITC);                              // Toggle Clock Port.\r
+  do\r
+  {\r
+    _delay_us( T2_TWI/4 );              \r
+    USICR = temp;                          // Generate positve SCL edge.\r
+    while( !(PIN_USI & (1<<PIN_USI_SCL)) );// Wait for SCL to go high.\r
+    _delay_us( T4_TWI/4 );              \r
+    USICR = temp;                          // Generate negative SCL edge.\r
+  }while( !(USISR & (1<<USIOIF)) );        // Check for transfer complete.\r
+  \r
+  _delay_us( T2_TWI/4 );                \r
+  temp  = USIDR;                           // Read out data.\r
+  USIDR = 0xFF;                            // Release SDA.\r
+  DDR_USI |= (1<<PIN_USI_SDA);             // Enable SDA as output.\r
+\r
+  return temp;                             // Return the data from the USIDR\r
+}\r
+\r
+/*---------------------------------------------------------------\r
+ Function for generating a TWI Stop Condition. Used to release \r
+ the TWI bus.\r
+---------------------------------------------------------------*/\r
+unsigned char USI_TWI_Master_Stop( void )\r
+{\r
+  PORT_USI &= ~(1<<PIN_USI_SDA);           // Pull SDA low.\r
+  PORT_USI |= (1<<PIN_USI_SCL);            // Release SCL.\r
+  while( !(PIN_USI & (1<<PIN_USI_SCL)) );  // Wait for SCL to go high.\r
+  _delay_us( T4_TWI/4 );               \r
+  PORT_USI |= (1<<PIN_USI_SDA);            // Release SDA.\r
+  _delay_us( T2_TWI/4 );                \r
+  \r
+#ifdef SIGNAL_VERIFY\r
+  if( !(USISR & (1<<USIPF)) )\r
+  {\r
+    USI_TWI_state.errorState = USI_TWI_MISSING_STOP_CON;    \r
+    return (FALSE);\r
+  }\r
+#endif\r
+\r
+  return (TRUE);\r
+}\r
+\r
+\r
+\r
+unsigned char I2c_WriteByte(unsigned char msg) {\r
+  unsigned char tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and\r
+  (0x0<<USICNT0);                                     // set USI to shift 8 bits i.e. count 16 clock edges.\r
+  unsigned char tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and\r
+  (0xE<<USICNT0);                                     // set USI to shift 1 bit i.e. count 2 clock edges.\r
+\r
+       /* Write a byte */\r
+       PORT_USI &= ~(1<<PIN_USI_SCL);                // Pull SCL LOW.\r
+       USIDR     = msg;                        // Setup data.\r
+       USI_TWI_Master_Transfer( tempUSISR_8bit );    // Send 8 bits on bus.\r
+       /* Clock and verify (N)ACK from slave */\r
+       DDR_USI  &= ~(1<<PIN_USI_SDA);                // Enable SDA as input.\r
+       if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) ){\r
+               if ( USI_TWI_state.addressMode )\r
+                       USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;\r
+               else\r
+                       USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;\r
+               return 2;\r
+       }\r
+       return 0;\r
+}\r
+unsigned char I2c_ReadByte(unsigned char ack_mode) {\r
+  unsigned char tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and\r
+  (0x0<<USICNT0);                                     // set USI to shift 8 bits i.e. count 16 clock edges.\r
+  unsigned char tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and\r
+  (0xE<<USICNT0);                                     // set USI to shift 1 bit i.e. count 2 clock edges.\r
+       \r
+       /* Read a data byte */\r
+       DDR_USI   &= ~(1<<PIN_USI_SDA);               // Enable SDA as input.\r
+    unsigned char msg = USI_TWI_Master_Transfer( tempUSISR_8bit );\r
+\r
+    /* Prepare to generate ACK (or NACK in case of End Of Transmission) */\r
+    if( ack_mode == NO_ACK) {                           // If transmission of last byte was performed.\r
+               USIDR = 0xFF;                              // Load NACK to confirm End Of Transmission.\r
+    } else   {\r
+               USIDR = 0x00;                              // Load ACK. Set data register bit 7 (output for SDA) low.\r
+    }\r
+    USI_TWI_Master_Transfer( tempUSISR_1bit );   // Generate ACK/NACK.\r
+       return msg;\r
+}\r
+\r
+void I2c_StartCondition(void) {\r
+/* Release SCL to ensure that (repeated) Start can be performed */\r
+PORT_USI |= (1<<PIN_USI_SCL);                     // Release SCL.\r
+while( !(PIN_USI & (1<<PIN_USI_SCL)) );          // Verify that SCL becomes high.\r
+#ifdef TWI_FAST_MODE\r
+_delay_us( T4_TWI/4 );                         // Delay for T4TWI if TWI_FAST_MODE\r
+#else\r
+_delay_us( T2_TWI/4 );                         // Delay for T2TWI if TWI_STANDARD_MODE\r
+#endif\r
+\r
+/* Generate Start Condition */\r
+PORT_USI &= ~(1<<PIN_USI_SDA);                    // Force SDA LOW.\r
+_delay_us( T4_TWI/4 );\r
+PORT_USI &= ~(1<<PIN_USI_SCL);                    // Pull SCL LOW.\r
+PORT_USI |= (1<<PIN_USI_SDA);                     // Release SDA.\r
+       \r
+       \r
+}\r
+void I2c_StopCondition(void) {\r
+       USI_TWI_Master_Stop();\r
+}\r