/*! \brief TWI master read interrupt handler. * * This is the master read interrupt handler that takes care of * reading bytes from the TWI slave. * * \param twi The TWI_Master_t struct instance. */ static void TWI_MasterReadHandler() { /* Fetch data if bytes to be read. */ if (twi->bytesRead < TWIM_READ_BUFFER_SIZE) { uint8_t data = twi->interface->MASTER.DATA; twi->readData[twi->bytesRead] = data; twi->bytesRead++; } /* If buffer overflow, issue STOP and BUFFER_OVERFLOW condition. */ else { twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; TWI_MasterTransactionFinished(TWIM_RESULT_BUFFER_OVERFLOW); } /* Local variable used in if test to avoid compiler warning. */ uint8_t bytesToRead = twi->bytesToRead; /* If more bytes to read, issue ACK and start a byte read. */ if (twi->bytesRead < bytesToRead) { twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc; } /* If transaction finished, issue NACK and STOP condition. */ else { twi->interface->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc; TWI_MasterTransactionFinished(TWIM_RESULT_OK); } }
/*! \brief TWI master write interrupt handler. * * Handles TWI transactions (master write) and responses to (N)ACK. * * \param twi The TWI_Master_t struct instance. */ static void TWI_MasterWriteHandler() { /* Local variables used in if tests to avoid compiler warning. */ uint8_t bytesToWrite = twi->bytesToWrite; uint8_t bytesToRead = twi->bytesToRead; /* If NOT acknowledged (NACK) by slave cancel the transaction. */ if (twi->interface->MASTER.STATUS & TWI_MASTER_RXACK_bm) { twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; twi->result = TWIM_RESULT_NACK_RECEIVED; twi->status = TWIM_STATUS_READY; } /* If more bytes to write, send data. */ else if (twi->bytesWritten < bytesToWrite) { uint8_t data = twi->writeData[twi->bytesWritten]; twi->interface->MASTER.DATA = data; ++twi->bytesWritten; } /* If bytes to read, send repeated START condition + Address + * 'R/_W = 1' */ else if (twi->bytesRead < bytesToRead) { uint8_t readAddress = twi->address | 0x01; twi->interface->MASTER.ADDR = readAddress; } /* If transaction finished, send STOP condition and set RESULT OK. */ else { twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; TWI_MasterTransactionFinished(TWIM_RESULT_OK); } }
/*! \brief Common TWI master interrupt service routine. * * Check current status and calls the appropriate handler. * * \param twi The TWI_Master_t struct instance. */ static void TWI_MasterInterruptHandler() { uint8_t currentStatus = twi->interface->MASTER.STATUS; /* If arbitration lost or bus error. */ if ((currentStatus & TWI_MASTER_ARBLOST_bm) || (currentStatus & TWI_MASTER_BUSERR_bm)) { TWI_MasterArbitrationLostBusErrorHandler(); } /* If master write interrupt. */ else if (currentStatus & TWI_MASTER_WIF_bm) { TWI_MasterWriteHandler(); } /* If master read interrupt. */ else if (currentStatus & TWI_MASTER_RIF_bm) { TWI_MasterReadHandler(); } /* If unexpected state. */ else { TWI_MasterTransactionFinished(TWIM_RESULT_FAIL); } }
/*============================================================================ Name : TWI_MasterWriteHandler ------------------------------------------------------------------------------ Purpose : Handles TWI Input : n/a Output : n/a Notes : Called from TWI Interrupt routine ============================================================================*/ void TWI_MasterWriteHandler(void) { // Local variables used in if tests to avoid compiler warning. uint16_t bytesToWrite = twiMaster.bytesToWrite; //uint16_t bytesToRead = twiMaster.bytesToRead; // If NOT acknowledged (NACK) by slave cancel the transaction. if (twiMaster.interface->MASTER.STATUS & TWI_MASTER_RXACK_bm) { twiMaster.interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; twiMaster.result = TWIM_RESULT_NACK_RECEIVED; twiMaster.status = TWIM_STATUS_READY; } // If more bytes to write, send data. else if (twiMaster.bytesWritten <= bytesToWrite) { uint8_t data = TX_Buffer[twiMaster.bytesWritten]; twiMaster.interface->MASTER.DATA = data; ++twiMaster.bytesWritten; } // If transaction finished, send STOP condition and set RESULT OK. else { twiMaster.interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; TWI_MasterTransactionFinished(TWIM_RESULT_OK); } }
/*============================================================================ Name : TWI_MasterReadHandler ------------------------------------------------------------------------------ Purpose : Handles TWI Input : n/a Output : n/a Notes : Called from TWI Interrupt routine ============================================================================*/ void TWI_MasterReadHandler(void) { uint8_t FrameInProgress; uint8_t data = twiMaster.interface->MASTER.DATA; FrameInProgress = RxHandler(data); // If more bytes to read, issue ACK and start a byte read. if (FrameInProgress) { twiMaster.interface->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc; } else// If transaction finished, issue NACK and STOP condition. { twiMaster.interface->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc; TWI_MasterTransactionFinished(TWIM_RESULT_OK); } }
void WakeUpSensor(TWI_Master_t *twi, uint8_t address){ // If write command, send the START condition + Address + 'R/_W = 0' uint8_t writeAddress = twi->address & ~0x01; twi->interface->MASTER.ADDR = writeAddress; // If NOT acknowledged (NACK) by slave cancel the transaction. if (twi->interface->MASTER.STATUS & TWI_MASTER_RXACK_bm) { twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; twi->result = TWIM_RESULT_NACK_RECEIVED; twi->status = TWIM_STATUS_READY; } // If transaction finished, send STOP condition and set RESULT OK. else { twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; TWI_MasterTransactionFinished(twi, TWIM_RESULT_OK); } }