File : USI_TWI_Slave.c Compiler : IAR EWAAVR 4.11A Revision :
Support mail : avr@atmel.com
Supported devices : All device with USI module can be used.
AppNote : AVR312 - Using the USI module as a I2C slave
Description : Functions for USI_TWI_receiver and USI_TWI_transmitter.
Definition in file USI_TWI_Slave.c.
#include "config.h"
#include "USI_TWI_Slave.h"
Go to the source code of this file.
Functions | |
void | Flush_TWI_Buffers (void) |
Flushes the TWI buffers. | |
__interrupt void | USI_Counter_Overflow_ISR (void) |
USI counter overflow ISR Handels all the comunication. Is disabled only when waiting for new Start Condition. | |
__interrupt void | USI_Start_Condition_ISR (void) |
Usi start condition ISR Detects the USI_TWI Start Condition and intialises the USI for reception of the "TWI Address" packet. | |
unsigned char | USI_TWI_Data_In_Receive_Buffer (void) |
Check if there is data in the receive buffer. | |
unsigned char | USI_TWI_Receive_Byte (void) |
Returns a byte from the receive buffer. Waits if buffer is empty. | |
void | USI_TWI_Slave_Initialise (unsigned char TWI_ownAddress) |
Initialise USI for TWI Slave mode. | |
void | USI_TWI_Transmit_Byte (unsigned char byte_data) |
Puts data in the transmission buffer, Waits if buffer is full. | |
Variables | |
static uint8_t | TWI_RxBuf [TWI_RX_BUFFER_SIZE] |
static volatile uint8_t | TWI_RxHead |
static volatile uint8_t | TWI_RxTail |
static unsigned char | TWI_slaveAddress |
static uint8_t | TWI_TxBuf [TWI_TX_BUFFER_SIZE] |
static volatile uint8_t | TWI_TxHead |
static volatile uint8_t | TWI_TxTail |
static volatile unsigned char | USI_TWI_Overflow_State |
void Flush_TWI_Buffers | ( | void | ) |
Flushes the TWI buffers.
Definition at line 45 of file USI_TWI_Slave.c.
References TWI_RxHead, TWI_RxTail, TWI_TxHead, and TWI_TxTail.
Referenced by USI_TWI_Slave_Initialise().
00046 { 00047 TWI_RxTail = 0; 00048 TWI_RxHead = 0; 00049 TWI_TxTail = 0; 00050 TWI_TxHead = 0; 00051 }
__interrupt void USI_Counter_Overflow_ISR | ( | void | ) |
USI counter overflow ISR Handels all the comunication. Is disabled only when waiting for new Start Condition.
Definition at line 146 of file USI_TWI_Slave.c.
References SET_USI_TO_READ_ACK, SET_USI_TO_READ_DATA, SET_USI_TO_SEND_ACK, SET_USI_TO_SEND_DATA, SET_USI_TO_TWI_START_CONDITION_MODE, TWI_RX_BUFFER_MASK, TWI_RxBuf, TWI_RxHead, TWI_slaveAddress, TWI_TX_BUFFER_MASK, TWI_TxBuf, TWI_TxHead, TWI_TxTail, USI_SLAVE_CHECK_ADDRESS, USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA, USI_SLAVE_GET_DATA_AND_SEND_ACK, USI_SLAVE_REQUEST_DATA, USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA, USI_SLAVE_SEND_DATA, and USI_TWI_Overflow_State.
00148 { 00149 unsigned char tmpTxTail; // Temporary variables to store volatiles 00150 unsigned char tmpUSIDR; 00151 00152 00153 switch (USI_TWI_Overflow_State) 00154 { 00155 // ---------- Address mode ---------- 00156 // Check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK, else reset USI. 00157 case USI_SLAVE_CHECK_ADDRESS: 00158 if ((USIDR == 0) || (( USIDR>>1 ) == TWI_slaveAddress)) 00159 { 00160 if ( USIDR & 0x01 ) 00161 USI_TWI_Overflow_State = USI_SLAVE_SEND_DATA; 00162 else 00163 USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA; 00164 SET_USI_TO_SEND_ACK(); 00165 } 00166 else 00167 { 00168 SET_USI_TO_TWI_START_CONDITION_MODE(); 00169 } 00170 break; 00171 00172 // ----- Master write data mode ------ 00173 // Check reply and goto USI_SLAVE_SEND_DATA if OK, else reset USI. 00174 case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA: 00175 if ( USIDR ) // If NACK, the master does not want more data. 00176 { 00177 SET_USI_TO_TWI_START_CONDITION_MODE(); 00178 return; 00179 } 00180 // From here we just drop straight into USI_SLAVE_SEND_DATA if the master sent an ACK 00181 00182 // Copy data from buffer to USIDR and set USI to shift byte. Next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA 00183 case USI_SLAVE_SEND_DATA: 00184 00185 // Get data from Buffer 00186 tmpTxTail = TWI_TxTail; // Not necessary, but prevents warnings 00187 if ( TWI_TxHead != tmpTxTail ) 00188 { 00189 TWI_TxTail = ( TWI_TxTail + 1 ) & TWI_TX_BUFFER_MASK; 00190 USIDR = TWI_TxBuf[TWI_TxTail]; 00191 } 00192 else // If the buffer is empty then: 00193 { 00194 SET_USI_TO_TWI_START_CONDITION_MODE(); 00195 return; 00196 } 00197 USI_TWI_Overflow_State = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA; 00198 SET_USI_TO_SEND_DATA(); 00199 break; 00200 00201 // Set USI to sample reply from master. Next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA 00202 case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA: 00203 USI_TWI_Overflow_State = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA; 00204 SET_USI_TO_READ_ACK(); 00205 break; 00206 00207 // ----- Master read data mode ------ 00208 // Set USI to sample data from master. Next USI_SLAVE_GET_DATA_AND_SEND_ACK. 00209 case USI_SLAVE_REQUEST_DATA: 00210 USI_TWI_Overflow_State = USI_SLAVE_GET_DATA_AND_SEND_ACK; 00211 SET_USI_TO_READ_DATA(); 00212 break; 00213 00214 // Copy data from USIDR and send ACK. Next USI_SLAVE_REQUEST_DATA 00215 case USI_SLAVE_GET_DATA_AND_SEND_ACK: 00216 // Put data into Buffer 00217 tmpUSIDR = USIDR; // Not necessary, but prevents warnings 00218 TWI_RxHead = ( TWI_RxHead + 1 ) & TWI_RX_BUFFER_MASK; 00219 TWI_RxBuf[TWI_RxHead] = tmpUSIDR; 00220 00221 USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA; 00222 SET_USI_TO_SEND_ACK(); 00223 break; 00224 } 00225 }
__interrupt void USI_Start_Condition_ISR | ( | void | ) |
Usi start condition ISR Detects the USI_TWI Start Condition and intialises the USI for reception of the "TWI Address" packet.
Definition at line 119 of file USI_TWI_Slave.c.
References USI_SLAVE_CHECK_ADDRESS, and USI_TWI_Overflow_State.
00121 { 00122 unsigned char tmpUSISR; // Temporary variable to store volatile 00123 tmpUSISR = USISR; // Not necessary, but prevents warnings 00124 // Set default starting conditions for new TWI package 00125 USI_TWI_Overflow_State = USI_SLAVE_CHECK_ADDRESS; 00126 DDR_USI &= ~(1<<PORT_USI_SDA); // Set SDA as input 00127 while ( (PIN_USI & (1<<PORT_USI_SCL)) & !(tmpUSISR & (1<<USIPF)) ); // Wait for SCL to go low to ensure the "Start Condition" has completed. 00128 // If a Stop condition arises then leave the interrupt to prevent waiting forever. 00129 USICR = (1<<USISIE)|(1<<USIOIE)| // Enable Overflow and Start Condition Interrupt. (Keep StartCondInt to detect RESTART) 00130 (1<<USIWM1)|(1<<USIWM0)| // Set USI in Two-wire mode. 00131 (1<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = External, positive edge 00132 (0<<USITC); 00133 USISR = (1<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Clear flags 00134 (0x0<<USICNT0); // Set USI to sample 8 bits i.e. count 16 external pin toggles. 00135 }
unsigned char USI_TWI_Data_In_Receive_Buffer | ( | void | ) |
Check if there is data in the receive buffer.
Definition at line 104 of file USI_TWI_Slave.c.
References TWI_RxHead, and TWI_RxTail.
00105 { 00106 unsigned char tmpRxTail; // Temporary variable to store volatile 00107 tmpRxTail = TWI_RxTail; // Not necessary, but prevents warnings 00108 return ( TWI_RxHead != tmpRxTail ); // Return 0 (FALSE) if the receive buffer is empty. 00109 }
unsigned char USI_TWI_Receive_Byte | ( | void | ) |
Returns a byte from the receive buffer. Waits if buffer is empty.
Definition at line 91 of file USI_TWI_Slave.c.
References TWI_RX_BUFFER_MASK, TWI_RxBuf, TWI_RxHead, and TWI_RxTail.
00092 { 00093 unsigned char tmptail; 00094 unsigned char tmpRxTail; // Temporary variable to store volatile 00095 tmpRxTail = TWI_RxTail; // Not necessary, but prevents warnings 00096 while ( TWI_RxHead == tmpRxTail ); 00097 tmptail = ( TWI_RxTail + 1 ) & TWI_RX_BUFFER_MASK; // Calculate buffer index 00098 TWI_RxTail = tmptail; // Store new index 00099 return TWI_RxBuf[tmptail]; // Return data from the buffer. 00100 }
void USI_TWI_Slave_Initialise | ( | unsigned char | TWI_ownAddress | ) |
Initialise USI for TWI Slave mode.
Prototypes.
Definition at line 58 of file USI_TWI_Slave.c.
References Flush_TWI_Buffers(), and TWI_slaveAddress.
00059 { 00060 Flush_TWI_Buffers(); 00061 00062 TWI_slaveAddress = TWI_ownAddress; 00063 00064 PORT_USI |= (1<<PORT_USI_SCL); // Set SCL high 00065 PORT_USI |= (1<<PORT_USI_SDA); // Set SDA high 00066 DDR_USI |= (1<<PORT_USI_SCL); // Set SCL as output 00067 DDR_USI &= ~(1<<PORT_USI_SDA); // Set SDA as input 00068 USICR = (1<<USISIE)|(0<<USIOIE)| // Enable Start Condition Interrupt. Disable Overflow Interrupt. 00069 (1<<USIWM1)|(0<<USIWM0)| // Set USI in Two-wire mode. No USI Counter overflow prior 00070 // to first Start Condition (potentail failure) 00071 (1<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = External, positive edge 00072 (0<<USITC); 00073 USISR = 0xF0; // Clear all flags and reset overflow counter 00074 }
void USI_TWI_Transmit_Byte | ( | unsigned char | byte_data | ) |
Puts data in the transmission buffer, Waits if buffer is full.
Definition at line 79 of file USI_TWI_Slave.c.
References TWI_TX_BUFFER_MASK, TWI_TxBuf, TWI_TxHead, and TWI_TxTail.
00080 { 00081 unsigned char tmphead; 00082 00083 tmphead = ( TWI_TxHead + 1 ) & TWI_TX_BUFFER_MASK; // Calculate buffer index. 00084 while ( tmphead == TWI_TxTail ); // Wait for free space in buffer. 00085 TWI_TxBuf[tmphead] = byte_data; // Store data in buffer. 00086 TWI_TxHead = tmphead; // Store new index. 00087 }
Local variables
Definition at line 35 of file USI_TWI_Slave.c.
Referenced by USI_Counter_Overflow_ISR(), and USI_TWI_Receive_Byte().
volatile uint8_t TWI_RxHead [static] |
Definition at line 36 of file USI_TWI_Slave.c.
Referenced by Flush_TWI_Buffers(), USI_Counter_Overflow_ISR(), USI_TWI_Data_In_Receive_Buffer(), and USI_TWI_Receive_Byte().
volatile uint8_t TWI_RxTail [static] |
Definition at line 37 of file USI_TWI_Slave.c.
Referenced by Flush_TWI_Buffers(), USI_TWI_Data_In_Receive_Buffer(), and USI_TWI_Receive_Byte().
unsigned char TWI_slaveAddress [static] |
Static Variables
Definition at line 29 of file USI_TWI_Slave.c.
Referenced by USI_Counter_Overflow_ISR(), and USI_TWI_Slave_Initialise().
Definition at line 39 of file USI_TWI_Slave.c.
Referenced by USI_Counter_Overflow_ISR(), and USI_TWI_Transmit_Byte().
volatile uint8_t TWI_TxHead [static] |
Definition at line 40 of file USI_TWI_Slave.c.
Referenced by Flush_TWI_Buffers(), USI_Counter_Overflow_ISR(), and USI_TWI_Transmit_Byte().
volatile uint8_t TWI_TxTail [static] |
Definition at line 41 of file USI_TWI_Slave.c.
Referenced by Flush_TWI_Buffers(), USI_Counter_Overflow_ISR(), and USI_TWI_Transmit_Byte().
volatile unsigned char USI_TWI_Overflow_State [static] |
Definition at line 30 of file USI_TWI_Slave.c.
Referenced by USI_Counter_Overflow_ISR(), and USI_Start_Condition_ISR().