Wiblocks --- TWI

TWI/TWI.c

00001 
00002 
00003 
00004 
00005 
00006 
00007 #include <TWI.h>
00008 #include <avr/interrupt.h>
00009 #include <avr/io.h>
00010 
00011 #if defined(ARDUINO) && (ARDUINO >= 100)
00012 #include "Arduino.h"
00013 #else
00014 #include "WConstants.h"
00015 #include <inttypes.h>
00016 #endif
00017 
00018 static unsigned char twi_buf[ TWI_BUFFER_SIZE ]; // Transceiver buffer
00019 static unsigned char twi_msg_size;               // Number of bytes to be transmitted.
00020 static unsigned char twi_state = TWI_NO_STATE;   // State byte. Default set to TWI_NO_STATE.
00021 
00022 union twi_status_reg twi_status_reg = {0};       // TWI_statusReg is defined in TWI_Master.h
00023 
00028 unsigned char twi_busy_p( void ) {
00029   return ( TWCR & (1<<TWIE) ); 
00030 }
00031 
00041 
00042 unsigned char twi_get_state( void ) {
00043   while ( twi_busy_p() );             // Wait until TWI has completed the transmission.
00044   return ( twi_state );               // Return error state.
00045 }
00046 
00059 
00060 void twi_transmit( unsigned char *msg, unsigned char msg_size )
00061 {
00062   unsigned char temp;
00063 
00064   while ( twi_busy_p() );                      // Wait until TWI is ready for next transmission.
00065 
00066   twi_msg_size = msg_size;                     // Number of data to transmit.
00067   twi_buf[0]  = msg[0];                        // Store slave address with R/W setting.
00068   if (!( msg[0] & (TRUE<<TWI_READ_BIT) )) {    // If it is a write operation, then also copy data.
00069     for ( temp = 1; temp < msg_size; temp++ )
00070       twi_buf[ temp ] = msg[ temp ];
00071   }
00072   twi_status_reg.all = 0;      
00073   twi_state         = TWI_NO_STATE ;
00074   TWCR = (1<<TWEN)|                             // TWI Interface enabled.
00075          (1<<TWIE)|(1<<TWINT)|                  // Enable TWI Interupt and clear the flag.
00076          (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)|       // Initiate a START condition.
00077          (0<<TWWC);                             
00078 }
00079 
00087 
00088 void twi_resend( void )
00089 {
00090   while ( twi_busy_p() );                       // Wait until TWI is ready for next transmission.
00091   twi_status_reg.all = 0;      
00092   twi_state         = TWI_NO_STATE ;
00093   TWCR = (1<<TWEN)|                             // TWI Interface enabled.
00094          (1<<TWIE)|(1<<TWINT)|                  // Enable TWI Interupt and clear the flag.
00095          (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)|       // Initiate a START condition.
00096          (0<<TWWC);                             
00097 }
00098 
00111 
00112 unsigned char twi_get_data( unsigned char *msg, unsigned char msg_size )
00113 {
00114   unsigned char i;
00115 
00116   while ( twi_busy_p() );              // Wait until TWI is ready for next transmission.
00117 
00118   if( twi_status_reg.last_trans_ok ) { // Last transmission competed successfully.              
00119     for ( i=0; i<msg_size; i++ ) {     // Copy data from Transceiver buffer.
00120       msg[ i ] = twi_buf[ i ];
00121     }
00122   }
00123   return( twi_status_reg.last_trans_ok );                                   
00124 }
00125 
00132 
00133 ISR(TWI_vect) {
00134   static unsigned char twi_buf_ptr;
00135   switch (TWSR)
00136   {
00137     case TWI_START:                             // START has been transmitted  
00138     case TWI_REP_START:                         // Repeated START has been transmitted
00139       twi_buf_ptr = 0;                          // Set buffer pointer to the TWI Address location
00140     case TWI_MTX_ADR_ACK:                       // SLA+W has been tramsmitted and ACK received
00141     case TWI_MTX_DATA_ACK:                      // Data byte has been tramsmitted and ACK received
00142       if (twi_buf_ptr < twi_msg_size) {
00143         TWDR = twi_buf[twi_buf_ptr++];
00144         TWCR = (1<<TWEN)|                       // TWI Interface enabled
00145                (1<<TWIE)|(1<<TWINT)|            // Enable TWI Interupt and clear the flag to send byte
00146                (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| 
00147                (0<<TWWC);                         
00148       } else {                                  // Send STOP after last byte
00149          twi_status_reg.last_trans_ok = TRUE;    // Set status bits to completed successfully. 
00150          TWCR = (1<<TWEN)|                       // TWI Interface enabled
00151                 (0<<TWIE)|(1<<TWINT)|            // Disable TWI Interrupt and clear the flag
00152                 (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // Initiate a STOP condition.
00153                 (0<<TWWC);                       
00154       }
00155       break;
00156     case TWI_MRX_DATA_ACK:                      // Data byte has been received and ACK tramsmitted
00157       twi_buf[twi_buf_ptr++] = TWDR;
00158     case TWI_MRX_ADR_ACK:                       // SLA+R has been tramsmitted and ACK received
00159       if (twi_buf_ptr < (twi_msg_size-1) ) {    // Detect the last byte to NACK it.
00160         TWCR = (1<<TWEN)|                       // TWI Interface enabled
00161                (1<<TWIE)|(1<<TWINT)|            // Enable TWI Interupt and clear the flag to read next byte
00162                (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after reception
00163                (0<<TWWC);                        
00164       } else {                                  // Send NACK after next reception
00165         TWCR = (1<<TWEN)|                       // TWI Interface enabled
00166                (1<<TWIE)|(1<<TWINT)|            // Enable TWI Interupt and clear the flag to read next byte
00167                (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send NACK after reception
00168                (0<<TWWC);                        
00169       }    
00170       break; 
00171     case TWI_MRX_DATA_NACK:                     // Data byte has been received and NACK tramsmitted
00172       twi_buf[twi_buf_ptr] = TWDR;
00173       twi_status_reg.last_trans_ok = TRUE;      // Set status bits to completed successfully. 
00174       TWCR = (1<<TWEN)|                         // TWI Interface enabled
00175              (0<<TWIE)|(1<<TWINT)|              // Disable TWI Interrupt and clear the flag
00176              (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|   // Initiate a STOP condition.
00177              (0<<TWWC);                         
00178       break;      
00179     case TWI_ARB_LOST:                          // Arbitration lost
00180       TWCR = (1<<TWEN)|                         // TWI Interface enabled
00181              (1<<TWIE)|(1<<TWINT)|              // Enable TWI Interupt and clear the flag
00182              (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)|   // Initiate a (RE)START condition.
00183              (0<<TWWC);                         
00184       break;
00185     case TWI_MTX_ADR_NACK:      // SLA+W has been tramsmitted and NACK received
00186     case TWI_MRX_ADR_NACK:      // SLA+R has been tramsmitted and NACK received    
00187     case TWI_MTX_DATA_NACK:     // Data byte has been tramsmitted and NACK received
00188 //  case TWI_NO_STATE           // No relevant state information available; TWINT = “0”
00189     case TWI_BUS_ERROR:         // Bus error due to an illegal START or STOP condition
00190     default:     
00191       twi_state = TWSR;                                 // Store TWSR and automatically sets clears noErrors bit.
00192                                                         // Reset TWI Interface
00193       TWCR = (1<<TWEN)|                                 // Enable TWI-interface and release TWI pins
00194              (0<<TWIE)|(0<<TWINT)|                      // Disable Interupt
00195              (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|           // No Signal requests
00196              (0<<TWWC);                                 //
00197   }
00198 }
00199 
00200