Xmega Application Note


twi_slave_driver.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00069 #include "twi_slave_driver.h"
00070 
00071 
00080 void TWI_SlaveInitializeDriver(TWI_Slave_t *twi,
00081                                TWI_t *module,
00082                                void (*processDataFunction) (void))
00083 {
00084         twi->interface = module;
00085         twi->Process_Data = processDataFunction;
00086         twi->bytesReceived = 0;
00087         twi->bytesSent = 0;
00088         twi->status = TWIS_STATUS_READY;
00089         twi->result = TWIS_RESULT_UNKNOWN;
00090         twi->abort = false;
00091 }
00092 
00093 
00103 void TWI_SlaveInitializeModule(TWI_Slave_t *twi,
00104                                uint8_t address,
00105                                TWI_SLAVE_INTLVL_t intLevel)
00106 {
00107         twi->interface->SLAVE.CTRLA = intLevel |
00108                                       TWI_SLAVE_DIEN_bm |
00109                                       TWI_SLAVE_APIEN_bm |
00110                                       TWI_SLAVE_ENABLE_bm;
00111         twi->interface->SLAVE.ADDR = (address<<1);
00112 }
00113 
00114 
00122 void TWI_SlaveInterruptHandler(TWI_Slave_t *twi)
00123 {
00124         uint8_t currentStatus = twi->interface->SLAVE.STATUS;
00125 
00126         /* If bus error. */
00127         if (currentStatus & TWI_SLAVE_BUSERR_bm) {
00128                 twi->bytesReceived = 0;
00129                 twi->bytesSent = 0;
00130                 twi->result = TWIS_RESULT_BUS_ERROR;
00131                 twi->status = TWIS_STATUS_READY;
00132         }
00133 
00134         /* If transmit collision. */
00135         else if (currentStatus & TWI_SLAVE_COLL_bm) {
00136                 twi->bytesReceived = 0;
00137                 twi->bytesSent = 0;
00138                 twi->result = TWIS_RESULT_TRANSMIT_COLLISION;
00139                 twi->status = TWIS_STATUS_READY;
00140         }
00141 
00142         /* If address match. */
00143         else if ((currentStatus & TWI_SLAVE_APIF_bm) &&
00144                 (currentStatus & TWI_SLAVE_AP_bm)) {
00145 
00146                 TWI_SlaveAddressMatchHandler(twi);
00147         }
00148 
00149         /* If stop (only enabled through slave read transaction). */
00150         else if (currentStatus & TWI_SLAVE_APIF_bm) {
00151                 TWI_SlaveStopHandler(twi);
00152         }
00153 
00154         /* If data interrupt. */
00155         else if (currentStatus & TWI_SLAVE_DIF_bm) {
00156                 TWI_SlaveDataHandler(twi);
00157         }
00158 
00159         /* If unexpected state. */
00160         else {
00161                 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_FAIL);
00162         }
00163 }
00164 
00171 void TWI_SlaveAddressMatchHandler(TWI_Slave_t *twi)
00172 {
00173         /* If application signalling need to abort (error occured). */
00174         if (twi->abort) {
00175                 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
00176                 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED);
00177                 twi->abort = false;
00178         } else {
00179                 twi->status = TWIS_STATUS_BUSY;
00180                 twi->result = TWIS_RESULT_UNKNOWN;
00181 
00182                 /* Disable stop interrupt. */
00183                 uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00184                 twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
00185 
00186                 twi->bytesReceived = 0;
00187                 twi->bytesSent = 0;
00188 
00189                 /* Send ACK, wait for data interrupt. */
00190                 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
00191         }
00192 }
00193 
00194 
00199 void TWI_SlaveStopHandler(TWI_Slave_t *twi)
00200 {
00201         /* Disable stop interrupt. */
00202         uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00203         twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
00204         
00205         /* Clear APIF, according to flowchart don't ACK or NACK */
00206         uint8_t currentStatus = twi->interface->SLAVE.STATUS;
00207         twi->interface->SLAVE.STATUS = currentStatus | TWI_SLAVE_APIF_bm;
00208 
00209         TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
00210 
00211 }
00212 
00213 
00220 void TWI_SlaveDataHandler(TWI_Slave_t *twi)
00221 {
00222         if (twi->interface->SLAVE.STATUS & TWI_SLAVE_DIR_bm) {
00223                 TWI_SlaveWriteHandler(twi);
00224         } else {
00225                 TWI_SlaveReadHandler(twi);
00226         }
00227 }
00228 
00229 
00236 void TWI_SlaveReadHandler(TWI_Slave_t *twi)
00237 {
00238         /* Enable stop interrupt. */
00239         uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00240         twi->interface->SLAVE.CTRLA = currentCtrlA | TWI_SLAVE_PIEN_bm;
00241 
00242         /* If free space in buffer. */
00243         if (twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE) {
00244                 /* Fetch data */
00245                 uint8_t data = twi->interface->SLAVE.DATA;
00246                 twi->receivedData[twi->bytesReceived] = data;
00247 
00248                 /* Process data. */
00249                 twi->Process_Data();
00250 
00251                 twi->bytesReceived++;
00252 
00253                 /* If application signalling need to abort (error occured),
00254                  * complete transaction and wait for next START. Otherwise
00255                  * send ACK and wait for data interrupt.
00256                  */
00257                 if (twi->abort) {
00258                         twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
00259                         TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED);
00260                         twi->abort = false;
00261                 } else {
00262                         twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
00263                 }
00264         }
00265         /* If buffer overflow, send NACK and wait for next START. Set
00266          * result buffer overflow.
00267          */
00268         else {
00269                 twi->interface->SLAVE.CTRLB = TWI_SLAVE_ACKACT_bm |
00270                                               TWI_SLAVE_CMD_COMPTRANS_gc;
00271                 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
00272         }
00273 }
00274 
00275 
00282 void TWI_SlaveWriteHandler(TWI_Slave_t *twi)
00283 {
00284         /* If NACK, slave write transaction finished. */
00285         if ((twi->bytesSent > 0) && (twi->interface->SLAVE.STATUS &
00286                                      TWI_SLAVE_RXACK_bm)) {
00287 
00288                 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
00289                 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
00290         }
00291         /* If ACK, master expects more data. */
00292         else {
00293                 if (twi->bytesSent < TWIS_SEND_BUFFER_SIZE) {
00294                         uint8_t data = twi->sendData[twi->bytesSent];
00295                         twi->interface->SLAVE.DATA = data;
00296                         twi->bytesSent++;
00297 
00298                         /* Send data, wait for data interrupt. */
00299                         twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
00300                 }
00301                 /* If buffer overflow. */
00302                 else {
00303                         twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
00304                         TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
00305                 }
00306         }
00307 }
00308 
00309 
00317 void TWI_SlaveTransactionFinished(TWI_Slave_t *twi, uint8_t result)
00318 {
00319         twi->result = result;
00320         twi->status = TWIS_STATUS_READY;
00321 }
@DOC_TITLE@
Generated on Tue Aug 11 12:42:12 2009 for AVR1308 Using the XMEGA TWI by doxygen 1.5.9