| Xmega Application Note | |||||
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 }
Generated on Tue Jan 19 18:41:58 2010 for AVR1320: True 400kHz operation for TWI slave by 1.5.8
|