00001
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
00200 if (bytesToWrite > TWIM_WRITE_BUFFER_SIZE) {
00201 return false;
00202 }
00203 if (bytesToRead > TWIM_READ_BUFFER_SIZE) {
00204 return false;
00205 }
00206
00207
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
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
00226
00227
00228 if (twi->bytesToWrite > 0) {
00229 uint8_t writeAddress = twi->address & ~0x01;
00230 twi->interface->MASTER.ADDR = writeAddress;
00231 }
00232
00233
00234
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
00258 if ((currentStatus & TWI_MASTER_ARBLOST_bm) ||
00259 (currentStatus & TWI_MASTER_BUSERR_bm)) {
00260
00261 TWI_MasterArbitrationLostBusErrorHandler(twi);
00262 }
00263
00264
00265 else if (currentStatus & TWI_MASTER_WIF_bm) {
00266 TWI_MasterWriteHandler(twi);
00267 }
00268
00269
00270 else if (currentStatus & TWI_MASTER_RIF_bm) {
00271 TWI_MasterReadHandler(twi);
00272 }
00273
00274
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
00292 if (currentStatus & TWI_MASTER_BUSERR_bm) {
00293 twi->result = TWIM_RESULT_BUS_ERROR;
00294 }
00295
00296 else {
00297 twi->result = TWIM_RESULT_ARBITRATION_LOST;
00298 }
00299
00300
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
00316 uint8_t bytesToWrite = twi->bytesToWrite;
00317 uint8_t bytesToRead = twi->bytesToRead;
00318
00319
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
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
00334
00335
00336 else if (twi->bytesRead < bytesToRead) {
00337 uint8_t readAddress = twi->address | 0x01;
00338 twi->interface->MASTER.ADDR = readAddress;
00339 }
00340
00341
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
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
00366 else {
00367 twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
00368 TWI_MasterTransactionFinished(twi, TWIM_RESULT_BUFFER_OVERFLOW);
00369 }
00370
00371
00372 uint8_t bytesToRead = twi->bytesToRead;
00373
00374
00375 if (twi->bytesRead < bytesToRead) {
00376 twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
00377 }
00378
00379
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 }