Xmega Application Note


twi_master_driver.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00069 #include "twi_master_driver.h"
00070 
00071 
00083 void TWI_MasterInit(TWI_Master_t *twi,
00084                     TWI_t *module,
00085                     TWI_MASTER_INTLVL_t intLevel,
00086                     uint8_t baudRateRegisterSetting)
00087 {
00088         twi->interface = module;
00089         twi->interface->MASTER.CTRLA = intLevel |
00090                                        TWI_MASTER_RIEN_bm |
00091                                        TWI_MASTER_WIEN_bm |
00092                                        TWI_MASTER_ENABLE_bm;
00093         twi->interface->MASTER.BAUD = baudRateRegisterSetting;
00094         twi->interface->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
00095 }
00096 
00097 
00110 TWI_MASTER_BUSSTATE_t TWI_MasterState(TWI_Master_t *twi)
00111 {
00112         TWI_MASTER_BUSSTATE_t twi_status;
00113         twi_status = (TWI_MASTER_BUSSTATE_t) (twi->interface->MASTER.STATUS &
00114                                               TWI_MASTER_BUSSTATE_gm);
00115         return twi_status;
00116 }
00117 
00118 
00129 bool TWI_MasterReady(TWI_Master_t *twi)
00130 {
00131         bool twi_status = (twi->status & TWIM_STATUS_READY);
00132         return twi_status;
00133 }
00134 
00135 
00148 bool TWI_MasterWrite(TWI_Master_t *twi,
00149                      uint8_t address,
00150                      uint8_t *writeData,
00151                      uint8_t bytesToWrite)
00152 {
00153         bool twi_status = TWI_MasterWriteRead(twi, address, writeData, bytesToWrite, 0);
00154         return twi_status;
00155 }
00156 
00157 
00169 bool TWI_MasterRead(TWI_Master_t *twi,
00170                     uint8_t address,
00171                     uint8_t bytesToRead)
00172 {
00173         bool twi_status = TWI_MasterWriteRead(twi, address, 0, 0, bytesToRead);
00174         return twi_status;
00175 }
00176 
00177 
00193 bool TWI_MasterWriteRead(TWI_Master_t *twi,
00194                          uint8_t address,
00195                          uint8_t *writeData,
00196                          uint8_t bytesToWrite,
00197                          uint8_t bytesToRead)
00198 {
00199         /*Parameter sanity check. */
00200         if (bytesToWrite > TWIM_WRITE_BUFFER_SIZE) {
00201                 return false;
00202         }
00203         if (bytesToRead > TWIM_READ_BUFFER_SIZE) {
00204                 return false;
00205         }
00206 
00207         /*Initiate transaction if bus is ready. */
00208         if (twi->status == TWIM_STATUS_READY) {
00209 
00210                 twi->status = TWIM_STATUS_BUSY;
00211                 twi->result = TWIM_RESULT_UNKNOWN;
00212 
00213                 twi->address = address<<1;
00214 
00215                 /* Fill write data buffer. */
00216                 for (uint8_t bufferIndex=0; bufferIndex < bytesToWrite; bufferIndex++) {
00217                         twi->writeData[bufferIndex] = writeData[bufferIndex];
00218                 }
00219 
00220                 twi->bytesToWrite = bytesToWrite;
00221                 twi->bytesToRead = bytesToRead;
00222                 twi->bytesWritten = 0;
00223                 twi->bytesRead = 0;
00224 
00225                 /* If write command, send the START condition + Address +
00226                  * 'R/_W = 0'
00227                  */
00228                 if (twi->bytesToWrite > 0) {
00229                         uint8_t writeAddress = twi->address & ~0x01;
00230                         twi->interface->MASTER.ADDR = writeAddress;
00231                 }
00232 
00233                 /* If read command, send the START condition + Address +
00234                  * 'R/_W = 1'
00235                  */
00236                 else if (twi->bytesToRead > 0) {
00237                         uint8_t readAddress = twi->address | 0x01;
00238                         twi->interface->MASTER.ADDR = readAddress;
00239                 }
00240                 return true;
00241         } else {
00242                 return false;
00243         }
00244 }
00245 
00246 
00253 void TWI_MasterInterruptHandler(TWI_Master_t *twi)
00254 {
00255         uint8_t currentStatus = twi->interface->MASTER.STATUS;
00256 
00257         /* If arbitration lost or bus error. */
00258         if ((currentStatus & TWI_MASTER_ARBLOST_bm) ||
00259             (currentStatus & TWI_MASTER_BUSERR_bm)) {
00260 
00261                 TWI_MasterArbitrationLostBusErrorHandler(twi);
00262         }
00263 
00264         /* If master write interrupt. */
00265         else if (currentStatus & TWI_MASTER_WIF_bm) {
00266                 TWI_MasterWriteHandler(twi);
00267         }
00268 
00269         /* If master read interrupt. */
00270         else if (currentStatus & TWI_MASTER_RIF_bm) {
00271                 TWI_MasterReadHandler(twi);
00272         }
00273 
00274         /* If unexpected state. */
00275         else {
00276                 TWI_MasterTransactionFinished(twi, TWIM_RESULT_FAIL);
00277         }
00278 }
00279 
00280 
00287 void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi)
00288 {
00289         uint8_t currentStatus = twi->interface->MASTER.STATUS;
00290 
00291         /* If bus error. */
00292         if (currentStatus & TWI_MASTER_BUSERR_bm) {
00293                 twi->result = TWIM_RESULT_BUS_ERROR;
00294         }
00295         /* If arbitration lost. */
00296         else {
00297                 twi->result = TWIM_RESULT_ARBITRATION_LOST;
00298         }
00299 
00300         /* Clear interrupt flag. */
00301         twi->interface->MASTER.STATUS = currentStatus | TWI_MASTER_ARBLOST_bm;
00302 
00303         twi->status = TWIM_STATUS_READY;
00304 }
00305 
00306 
00313 void TWI_MasterWriteHandler(TWI_Master_t *twi)
00314 {
00315         /* Local variables used in if tests to avoid compiler warning. */
00316         uint8_t bytesToWrite  = twi->bytesToWrite;
00317         uint8_t bytesToRead   = twi->bytesToRead;
00318 
00319         /* If NOT acknowledged (NACK) by slave cancel the transaction. */
00320         if (twi->interface->MASTER.STATUS & TWI_MASTER_RXACK_bm) {
00321                 twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
00322                 twi->result = TWIM_RESULT_NACK_RECEIVED;
00323                 twi->status = TWIM_STATUS_READY;
00324         }
00325 
00326         /* If more bytes to write, send data. */
00327         else if (twi->bytesWritten < bytesToWrite) {
00328                 uint8_t data = twi->writeData[twi->bytesWritten];
00329                 twi->interface->MASTER.DATA = data;
00330                 ++twi->bytesWritten;
00331         }
00332 
00333         /* If bytes to read, send repeated START condition + Address +
00334          * 'R/_W = 1'
00335          */
00336         else if (twi->bytesRead < bytesToRead) {
00337                 uint8_t readAddress = twi->address | 0x01;
00338                 twi->interface->MASTER.ADDR = readAddress;
00339         }
00340 
00341         /* If transaction finished, send STOP condition and set RESULT OK. */
00342         else {
00343                 twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
00344                 TWI_MasterTransactionFinished(twi, TWIM_RESULT_OK);
00345         }
00346 }
00347 
00348 
00356 void TWI_MasterReadHandler(TWI_Master_t *twi)
00357 {
00358         /* Fetch data if bytes to be read. */
00359         if (twi->bytesRead < TWIM_READ_BUFFER_SIZE) {
00360                 uint8_t data = twi->interface->MASTER.DATA;
00361                 twi->readData[twi->bytesRead] = data;
00362                 twi->bytesRead++;
00363         }
00364 
00365         /* If buffer overflow, issue STOP and BUFFER_OVERFLOW condition. */
00366         else {
00367                 twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
00368                 TWI_MasterTransactionFinished(twi, TWIM_RESULT_BUFFER_OVERFLOW);
00369         }
00370 
00371         /* Local variable used in if test to avoid compiler warning. */
00372         uint8_t bytesToRead = twi->bytesToRead;
00373 
00374         /* If more bytes to read, issue ACK and start a byte read. */
00375         if (twi->bytesRead < bytesToRead) {
00376                 twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
00377         }
00378 
00379         /* If transaction finished, issue NACK and STOP condition. */
00380         else {
00381                 twi->interface->MASTER.CTRLC = TWI_MASTER_ACKACT_bm |
00382                                                TWI_MASTER_CMD_STOP_gc;
00383                 TWI_MasterTransactionFinished(twi, TWIM_RESULT_OK);
00384         }
00385 }
00386 
00387 
00395 void TWI_MasterTransactionFinished(TWI_Master_t *twi, uint8_t result)
00396 {
00397         twi->result = result;
00398         twi->status = TWIM_STATUS_READY;
00399 }
@DOC_TITLE@
Generated on Tue Aug 11 12:42:12 2009 for AVR1308 Using the XMEGA TWI by doxygen 1.5.9