Xmega Application Note


twi_slave_driver.c

Go to the documentation of this file.
00001 
00046 //_____ I N C L U D E S ____________________________________________________
00047 
00048 #include "twi_slave_driver.h"
00049 #include "clksys_driver.h"
00050 
00051 //_____ M A C R O S ________________________________________________________
00052 
00053 //_____ D E F I N I T I O N ________________________________________________
00054 
00055 extern uint8_t twic_status_reg;
00056 extern uint8_t twic_data_reg;
00057 
00058 extern uint8_t twi_data;
00059 
00068 void TWI_SlaveInitializeDriver(TWI_Slave_t *twi,
00069                                TWI_t *module,
00070                                void (*processDataFunction) (void))
00071 {
00072    twi->interface = module;
00073    twi->Process_Data = processDataFunction;
00074    twi->bytesReceived = 0;
00075    twi->bytesSent = 0;
00076    twi->status = TWIS_STATUS_READY;
00077    twi->result = TWIS_RESULT_UNKNOWN;
00078    twi->abort = false;
00079           
00080    CLKSYS_Enable( OSC_RC32MEN_bm );
00081    do {} while ( CLKSYS_IsReady( OSC_RC32MRDY_bm ) == 0 );
00082         
00083    /* 32MHz Internal RC*/
00084    CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc );
00085         
00086    CLKSYS_Disable( OSC_RC2MEN_bm | OSC_RC32KEN_bm );    
00087 }
00088 
00089 
00099 void TWI_SlaveInitializeModule(TWI_Slave_t *twi,
00100                                uint8_t address,
00101                                TWI_SLAVE_INTLVL_t intLevel)
00102 {
00103    twi->interface->SLAVE.CTRLA = intLevel |
00104                                  TWI_SLAVE_DIEN_bm |
00105                                  TWI_SLAVE_APIEN_bm |
00106                                  TWI_SLAVE_ENABLE_bm;
00107    twi->interface->SLAVE.ADDR = (address<<1);
00108 }
00109 
00116 void TWI_process(TWI_Slave_t *twi)
00117 {
00118    //static uint8_t sent_NACK = 0;      //!< Holds whether NACK has been transmitted
00119    uint8_t currentStatus;
00120    currentStatus = twic_status_reg;
00121 
00122    twi->interface->SLAVE.CTRLB &= ~TWI_SLAVE_ACKACT_bm; 
00123 
00124    /* If bus error. */
00125    if (currentStatus & TWI_SLAVE_BUSERR_bm) {
00126       twi->bytesReceived = 0;
00127       twi->bytesSent = 0;
00128       twi->result = TWIS_RESULT_BUS_ERROR;
00129       twi->status = TWIS_STATUS_READY;
00130    }
00131    else if (currentStatus & TWI_SLAVE_COLL_bm) {
00132       /* If transmit collision. */
00133       twi->bytesReceived = 0;
00134       twi->bytesSent = 0;
00135       twi->result = TWIS_RESULT_TRANSMIT_COLLISION;
00136       twi->status = TWIS_STATUS_READY;
00137    }
00138    else if ((currentStatus & TWI_SLAVE_APIF_bm) && (currentStatus & TWI_SLAVE_AP_bm)) {
00139       /* If address match. */
00140       TWI_SlaveAddressMatchHandler(twi);        
00141    }
00142    else if (currentStatus & TWI_SLAVE_APIF_bm) {
00143       /* If stop (only enabled through slave read transaction). */        
00144       TWI_SlaveStopHandler(twi);
00145    }
00146    else if (currentStatus & TWI_SLAVE_DIF_bm) {
00147       /* If data interrupt. */     
00148       TWI_SlaveDataHandler(twi);
00149    }
00150    else {
00151       /* If unexpected state. */
00152       TWI_SlaveTransactionFinished(twi, TWIS_RESULT_FAIL);
00153    }
00154 }
00155 
00162 static void TWI_SlaveAddressMatchHandler(TWI_Slave_t *twi)
00163 {
00164    twi->status = TWIS_STATUS_BUSY;
00165    twi->result = TWIS_RESULT_UNKNOWN;
00166 
00167    /* Disable stop interrupt. */
00168    uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00169    twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
00170 
00171    twi->bytesReceived = 0;
00172    twi->bytesSent = 0;
00173 
00174    //init second byte to write
00175    twic_data_reg = twi->sendData[0];    
00176 }
00177 
00182 static void TWI_SlaveStopHandler(TWI_Slave_t *twi)
00183 {
00184    /* Disable stop interrupt. */
00185    uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00186    twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
00187    uint8_t currentStatus = twi->interface->SLAVE.STATUS;
00188    twi->interface->SLAVE.STATUS = currentStatus | TWI_SLAVE_APIF_bm;
00189 
00190    TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
00191 }
00192 
00199 static void TWI_SlaveDataHandler(TWI_Slave_t *twi)
00200 {       
00201    if (twic_status_reg & TWI_SLAVE_DIR_bm) {
00202       TWI_SlaveWriteHandler(twi);               
00203    } else {
00204       TWI_SlaveReadHandler(twi);          
00205    }
00206 }
00207 
00214 static void TWI_SlaveReadHandler(TWI_Slave_t *twi)
00215 {
00216    /* Enable stop interrupt. */
00217    uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00218    twi->interface->SLAVE.CTRLA = currentCtrlA | TWI_SLAVE_PIEN_bm;
00219 
00220    /* If free space in buffer.*/
00221    if (twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE) {
00222       /* Fetch data */
00223       uint8_t data = twic_data_reg;
00224       twi->receivedData[twi->bytesReceived] = data;
00225       /* Process data. */
00226       twi->Process_Data();
00227       twi->bytesReceived++;
00228    } else {
00229       // We will ignore the overshooting packets.
00230    }
00231         
00232    /* buffer overflow next time*/
00233    if  (!(twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE)){
00234       twi->interface->SLAVE.CTRLB |= TWI_SLAVE_ACKACT_bm;
00235   }
00236 }
00237 
00238 
00245 static void TWI_SlaveWriteHandler(TWI_Slave_t *twi)
00246 {
00247    /* If NACK, slave write transaction finished. */
00248    if ((twi->bytesSent > 0) && (twic_status_reg & TWI_SLAVE_RXACK_bm)) {
00249       //init first byte to write
00250       twic_data_reg = twi->sendData[0];
00251       TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
00252    }
00253    /* If ACK, master expects more data. */
00254    else {
00255       if (twi->bytesSent < TWIS_SEND_BUFFER_SIZE) {
00256          twi->bytesSent++;
00257          uint8_t data = twi->sendData[twi->bytesSent];
00258          twic_data_reg = data;                  
00259       }
00260       else {
00261          /* If buffer overflow. */
00262          TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
00263       }
00264    }
00265 } 
00266  
00274 static void TWI_SlaveTransactionFinished(TWI_Slave_t *twi, uint8_t result)
00275 {
00276    twi->result = result;
00277    twi->status = TWIS_STATUS_READY;
00278 }
@DOC_TITLE@
Generated on Tue Jan 19 18:41:58 2010 for AVR1320: True 400kHz operation for TWI slave by doxygen 1.5.8