void TWI_WriteBytes(uint8_t SLA, uint8_t address ,uint8_t size, uint8_t* buffer) { TWI_Start(); TWI_Write_SLA(SLA); TWI_WriteByte(address); while (size--) TWI_WriteByte(*buffer++); TWI_Stop(); }
// // Originally, 'endTransmission' was an f(void) function. // It has been modified to take one parameter indicating // whether or not a STOP should be performed on the bus. // Calling endTransmission(false) allows a sketch to // perform a repeated start. // // WARNING: Nothing in the library keeps track of whether // the bus tenure has been properly ended with a STOP. It // is very possible to leave the bus in a hung state if // no call to endTransmission(true) is made. Some I2C // devices will behave oddly if they do not see a STOP. // uint8_t TwoWire::endTransmission(uint8_t sendStop) { uint8_t error = 0; // transmit buffer (blocking) TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]); if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT)) error = 2; // error, got NACK on address transmit if (error == 0) { uint16_t sent = 1; while (sent < txBufferLength) { TWI_WriteByte(twi, txBuffer[sent++]); if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT)) error = 3; // error, got NACK during data transmmit } } if (error == 0) { TWI_Stop(twi); if (!TWI_WaitTransferComplete(twi, XMIT_TIMEOUT)) error = 4; // error, finishing up } txBufferLength = 0; // empty buffer status = MASTER_IDLE; return error; }
void TWI1_IrqHandler(void) { unsigned int status = TWI_GetStatus(TWI_STACK); if(((status & TWI_SR_SVACC) == TWI_SR_SVACC) && (eeprom.acquire == 0)) { TWI_DisableIt(TWI_STACK, TWI_IER_SVACC); TWI_EnableIt(TWI_STACK, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK | TWI_IER_EOSACC | TWI_IER_SCL_WS); eeprom.acquire++; eeprom.page = 0; eeprom.offset = 0; } if(((status & TWI_SR_SVACC) == TWI_SR_SVACC) && ((status & TWI_SR_GACC) == 0) && ((status & TWI_SR_RXRDY) == TWI_SR_RXRDY)) { if(eeprom.acquire == 1) { // Acquire LSB address eeprom.page = (TWI_ReadByte(TWI_STACK) & 0xFF); eeprom.acquire++; } else if(eeprom.acquire == 2) { // Acquire MSB address eeprom.page |= (TWI_ReadByte(TWI_STACK) & 0xFF) << 8; eeprom.acquire++; } else { // Read one byte of data from master to slave device uint16_t addr = I2C_EEPROM_PAGE_SIZE*eeprom.page + eeprom.offset; i2c_eeprom_slave_set_memory(addr, TWI_ReadByte(TWI_STACK) & 0xFF); eeprom.offset++; } } else if(((status & TWI_SR_TXRDY) == TWI_SR_TXRDY) && ((status & TWI_SR_TXCOMP) == TWI_SR_TXCOMP) && ((status & TWI_SR_EOSACC) == TWI_SR_EOSACC)) { // End of transfer, end of slave access eeprom.offset = 0; eeprom.acquire = 0; eeprom.page = 0; TWI_EnableIt(TWI_STACK, TWI_IER_SVACC); TWI_DisableIt(TWI_STACK, TWI_IER_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK | TWI_IER_EOSACC | TWI_IER_SCL_WS); } else if(((status & TWI_SR_SVACC) == TWI_SR_SVACC) && ((status & TWI_SR_GACC) == 0) && (eeprom.acquire == 3) && ((status & TWI_SR_SVREAD) == TWI_SR_SVREAD) && ((status & TWI_SR_NACK) == 0)) { // Write one byte of data from slave to master device uint16_t addr = I2C_EEPROM_PAGE_SIZE*eeprom.page + eeprom.offset; TWI_WriteByte(TWI_STACK, i2c_eeprom_slave_get_memory(addr)); eeprom.offset++; } }
/** * @ Brief Starts illuminance measurement. * @ Parameter mode: measurement mode. * @ Retval None */ void BH1750_Start(uint8_t mode) { mode_ = mode; TWI_Start(); TWI_Write_SLA(BH1750_SLA); TWI_WriteByte(mode_); TWI_Stop(); }
//------------------------------------------------------------------------------ /// Interrupt handler for a TWI peripheral. Manages asynchronous transfer /// occuring on the bus. This function MUST be called by the interrupt service /// routine of the TWI peripheral if asynchronous read/write are needed. /// \param pTwid Pointer to a Twid instance. //------------------------------------------------------------------------------ void TWID_Handler(Twid *pTwid) { unsigned char status; AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer; AT91S_TWI *pTwi = pTwid->pTwi; SANITY_CHECK(pTwid); // Retrieve interrupt status status = TWI_GetMaskedStatus(pTwi); // Byte received if (TWI_STATUS_RXRDY(status)) { pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi); pTransfer->transferred++; // Transfer finished ? if (pTransfer->transferred == pTransfer->num) { TWI_DisableIt(pTwi, AT91C_TWI_RXRDY); TWI_EnableIt(pTwi, AT91C_TWI_TXCOMP); } // Last byte ? else if (pTransfer->transferred == (pTransfer->num - 1)) { TWI_Stop(pTwi); } } // Byte sent else if (TWI_STATUS_TXRDY(status)) { // Transfer finished ? if (pTransfer->transferred == pTransfer->num) { TWI_DisableIt(pTwi, AT91C_TWI_TXRDY); TWI_EnableIt(pTwi, AT91C_TWI_TXCOMP); TWI_SendSTOPCondition(pTwi); } // Bytes remaining else { TWI_WriteByte(pTwi, pTransfer->pData[pTransfer->transferred]); pTransfer->transferred++; } } // Transfer complete else if (TWI_STATUS_TXCOMP(status)) { TWI_DisableIt(pTwi, AT91C_TWI_TXCOMP); pTransfer->status = 0; if (pTransfer->callback) { pTransfer->callback((Async *) pTransfer); } pTwid->pTransfer = 0; } }
/** * @ Brief Switches the sensor to power down mode. * @ Parameter None. * @ Retval None */ void BH1750_PowerDown() { //BH1750_DVI_PORT &= ~(BH1750_Power_OFF << BH1750_DVI_PIN); state_ = BH1750_Power_OFF; TWI_Start(); TWI_Write_SLA(BH1750_SLA); TWI_WriteByte(BH1750_Power_OFF); TWI_Stop(); }
/** * @ Brief Switches the sensor to power on mode. * @ Parameter None. * @ Retval None */ void BH1750_PowerOn() { _delay_us(5); //BH1750_DVI_PORT |= BH1750_Power_ON << BH1750_DVI_PIN; state_ = BH1750_Power_ON; TWI_Start(); TWI_Write_SLA(BH1750_SLA); TWI_WriteByte(BH1750_Power_ON); TWI_Stop(); }
/** * @ Brief Resets the BH1750 data register. After that, switches * sensor to power down mode. * @ Parameter None. * @ Retval None. */ void BH1750_ResetDR() { if(state_ == BH1750_Power_OFF) BH1750_PowerOn(); TWI_Start(); TWI_Write_SLA(BH1750_SLA); TWI_WriteByte(BH1750_RESET); TWI_Stop(); BH1750_PowerDown(); }
/** * \brief Asynchronously sends data to a slave on the TWI bus. An optional callback * function is invoked whenever the transfer is complete. * \param pTwid Pointer to a Twid instance. * \param address TWI slave address. * \param iaddress Optional slave internal address. * \param isize Number of internal address bytes. * \param pData Data buffer for storing received bytes. * \param num Data buffer to send. * \param pAsync Asynchronous transfer descriptor. * \return 0 if the transfer has been started; otherwise returns a TWI error code. */ uint8_t TWID_Write( Twi *pTwi, uint8_t address, uint32_t iaddress, uint8_t isize, uint8_t *pData, uint32_t num) { //Twi *pTwi = pTwid->pTwi; uint32_t timeout; assert( pTwi != NULL ) ; assert( (address & 0x80) == 0 ) ; assert( (iaddress & 0xFF000000) == 0 ) ; assert( isize < 4 ) ; /* Synchronous transfer*/ // Start write TWI_StartWrite(pTwi, address, iaddress, isize, *pData++); num--; /* Send all bytes */ while (num > 0) { /* Wait before sending the next byte */ timeout = 0; while( !TWI_ByteSent(pTwi) && (++timeout<TWITIMEOUTMAX) ); if (timeout == TWITIMEOUTMAX) { TRACE_ERROR("TWID Timeout BS\n\r"); } TWI_WriteByte(pTwi, *pData++); num--; } /* Wait for actual end of transfer */ timeout = 0; /* Send a STOP condition */ TWI_SendSTOPCondition(pTwi); while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) ); if (timeout == TWITIMEOUTMAX) { TRACE_ERROR("TWID Timeout TC2\n\r"); } return 0; }
bool i2c_eeprom_master_write(Twi *twi, const uint16_t internal_address, const char *data, const uint16_t length) { uint32_t timeout; mutex_take(mutex_twi_bricklet, MUTEX_BLOCKING); // Start write TWI_StartWrite(twi, bricklet_eeprom_address, internal_address, I2C_EEPROM_INTERNAL_ADDRESS_BYTES, data[0]); for(uint16_t i = 1; i < length; i++) { timeout = 0; // Wait until byte is sent, otherwise return false while(!TWI_ByteSent(twi) && (++timeout < I2C_EEPROM_TIMEOUT)) {} if(timeout == I2C_EEPROM_TIMEOUT) { logieew("write timeout (nothing sent)\n\r"); mutex_give(mutex_twi_bricklet); return false; } TWI_WriteByte(twi, data[i]); } // Send STOP TWI_SendSTOPCondition(twi); timeout = 0; // Wait for transfer to be complete while(!TWI_TransferComplete(twi) && (++timeout < I2C_EEPROM_TIMEOUT)) {} if (timeout == I2C_EEPROM_TIMEOUT) { logieew("write timeout (transfer incomplete)\n\r"); mutex_give(mutex_twi_bricklet); return false; } // Wait at least 5ms between writes (see m24128-bw.pdf) SLEEP_MS(5); mutex_give(mutex_twi_bricklet); return true; }
/********************************************** * \brief * * * \return none */ result_t HalExpansionPortClass::writePcaPorts(uint32_t iRegister, uint8_t *pBuffer, uint32_t bufLength) { uint32_t bufCnt=bufLength; uint32_t breakOut_cnt=0; result_t retResult=SUCCESS; TWI_StartWrite(HW_ADDR_TWI_PCA9698,HW_PCA9698_TwiAddr, iRegister,HW_PCA9698_InternalAddrLen,*pBuffer); pBuffer++; bufCnt--; while(bufCnt >0) { //if no NACK and Byte sent, then transmit next one if (TWI_SR_NACK & TWI_GetStatus(HW_ADDR_TWI_PCA9698)) { dbgOut1(eDbgAll_errEvt,'B',"HalTwiPca Unexpected NACK ",bufCnt); retResult=FAIL; break; } if (!TWI_ByteSent(HW_ADDR_TWI_PCA9698)) { if (90000 < ++breakOut_cnt) { dbgOut1(eDbgAll_errEvt,'B',"HalTwiPca TWI_SR_TXRDY exceeded ",bufCnt); retResult=FAIL; break; //Out while } continue; } breakOut_cnt = 0; TWI_WriteByte(HW_ADDR_TWI_PCA9698,*pBuffer); pBuffer++; bufCnt--; } TWI_Stop(HW_ADDR_TWI_PCA9698); while (!TWI_TransferComplete(HW_ADDR_TWI_PCA9698)) { if (90000 < ++breakOut_cnt) { dbgOut(eDbgAll_errEvt,'B',"HalTwiPca TWI_SR_TXCOMP exceeded "); break; //Out while } } return retResult; }//portInit
void TWI_ReadBytes(uint8_t SLA, uint8_t address ,uint8_t size, uint8_t* buffer) { TWI_Start(); TWI_Write_SLA(SLA); TWI_WriteByte(address); TWI_RStart(); TWI_Write_SLA(SLA+1); //while (size--) *buffer++ = size ? TWI_ReadByte_ACK() : ( len ? ACK : NACK ); while(size--) { *buffer++ = size ? TWI_ReadByte_ACK() : TWI_ReadByte_NACK(); } /* for (uint8_t i=0; i<size-1; i++) { buffer[i] = TWI_ReadByte_ACK(); } buffer[size-1]=TWI_ReadByte_NACK(); */ }
// // Originally, 'endTransmission' was an f(void) function. // It has been modified to take one parameter indicating // whether or not a STOP should be performed on the bus. // Calling endTransmission(false) allows a sketch to // perform a repeated start. // // WARNING: Nothing in the library keeps track of whether // the bus tenure has been properly ended with a STOP. It // is very possible to leave the bus in a hung state if // no call to endTransmission(true) is made. Some I2C // devices will behave oddly if they do not see a STOP. // uint8_t TwoWire::endTransmission(uint8_t sendStop) { // transmit buffer (blocking) TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]); TWI_WaitByteSent(twi, XMIT_TIMEOUT); int sent = 1; while (sent < txBufferLength) { TWI_WriteByte(twi, txBuffer[sent++]); TWI_WaitByteSent(twi, XMIT_TIMEOUT); } TWI_Stop( twi); TWI_WaitTransferComplete(twi, XMIT_TIMEOUT); // empty buffer txBufferLength = 0; status = MASTER_IDLE; return sent; }
unsigned char WriteAccelData(unsigned int iaddress, char *bytes, unsigned int num) { unsigned int timeout; // wait for TWI bus to be ready while(!(TWI_TransferComplete(AT91C_BASE_TWI))) nop(); // Start Writing TWI_StartWrite(AT91C_BASE_TWI,ACCELADDR,iaddress,1,*bytes++); num--; while(num > 0){ // Wait before sending the next byte timeout = 0; while(!TWI_ByteSent(AT91C_BASE_TWI) && (++timeout<TWITIMEOUTMAX)) nop(); if(timeout == TWITIMEOUTMAX) return 1; TWI_WriteByte(AT91C_BASE_TWI, *bytes++); num--; } return 0; }
//----------------------------------------------------------------------------- /// Starts a write operation on the TWI to access the selected slave, then /// returns immediately. A byte of data must be provided to start the write; /// other bytes are written next. /// \param pTwi Pointer to an AT91S_TWI instance. /// \param address Address of slave to acccess on the bus. /// \param iaddress Optional slave internal address. /// \param isize Number of internal address bytes. /// \param byte First byte to send. //----------------------------------------------------------------------------- void TWI_StartWrite( AT91S_TWI *pTwi, unsigned char address, unsigned int iaddress, unsigned char isize, unsigned char byte) { trace_LOG(trace_DEBUG, "-D- TWI_StartWrite()\n\r"); SANITY_CHECK(pTwi); SANITY_CHECK((address & 0x80) == 0); SANITY_CHECK((iaddress & 0xFF000000) == 0); SANITY_CHECK(isize < 4); // Set slave address and number of internal address bytes pTwi->TWI_MMR = (isize << 8) | (address << 16); // Set internal address bytes pTwi->TWI_IADR = iaddress; // Write first byte to send TWI_WriteByte(pTwi, byte); }
/** * \brief Starts a write operation on the TWI to access the selected slave, then * returns immediately. A byte of data must be provided to start the write; * other bytes are written next. * after that to send the remaining bytes. * \param pTwi Pointer to an Twi instance. * \param address Address of slave to acccess on the bus. * \param iaddress Optional slave internal address. * \param isize Number of internal address bytes. * \param byte First byte to send. */ void TWI_StartWrite( Twi *pTwi, uint8_t address, uint32_t iaddress, uint8_t isize, uint8_t byte) { assert( pTwi != NULL ) ; assert( (address & 0x80) == 0 ) ; assert( (iaddress & 0xFF000000) == 0 ) ; assert( isize < 4 ) ; /* Set slave address and number of internal address bytes. */ pTwi->TWI_MMR = 0; pTwi->TWI_MMR = (isize << 8) | (address << 16); /* Set internal address bytes. */ pTwi->TWI_IADR = 0; pTwi->TWI_IADR = iaddress; /* Write first byte to send.*/ TWI_WriteByte(pTwi, byte); }
/** * \brief Asynchronously sends data to a slave on the TWI bus. An optional callback * function is invoked whenever the transfer is complete. * \param pTwid Pointer to a Twid instance. * \param address TWI slave address. * \param iaddress Optional slave internal address. * \param isize Number of internal address bytes. * \param pData Data buffer for storing received bytes. * \param num Data buffer to send. * \param pAsync Asynchronous transfer descriptor. * \return 0 if the transfer has been started; otherwise returns a TWI error code. */ uint8_t TWID_Write( Twid *pTwid, uint8_t address, uint32_t iaddress, uint8_t isize, uint8_t *pData, uint32_t num, Async *pAsync) { Twi *pTwi = pTwid->pTwi; AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer; uint32_t timeout; assert( pTwi != NULL ) ; assert( (address & 0x80) == 0 ) ; assert( (iaddress & 0xFF000000) == 0 ) ; assert( isize < 4 ) ; /* Check that no transfer is already pending */ if (pTransfer) { TRACE_ERROR("TWI_Write: A transfer is already pending\n\r"); return TWID_ERROR_BUSY; } /* Asynchronous transfer */ if (pAsync) { /* Update the transfer descriptor */ pTwid->pTransfer = pAsync; pTransfer = (AsyncTwi *) pAsync; pTransfer->status = ASYNC_STATUS_PENDING; pTransfer->pData = pData; pTransfer->num = num; pTransfer->transferred = 1; /* Enable write interrupt and start the transfer */ TWI_StartWrite(pTwi, address, iaddress, isize, *pData); TWI_EnableIt(pTwi, TWI_IER_TXRDY); } /* Synchronous transfer*/ else { // Start write TWI_StartWrite(pTwi, address, iaddress, isize, *pData++); num--; /* Send all bytes */ while (num > 0) { /* Wait before sending the next byte */ timeout = 0; while( !TWI_ByteSent(pTwi) && (++timeout<TWITIMEOUTMAX) ); if (timeout == TWITIMEOUTMAX) { TRACE_ERROR("TWID Timeout BS\n\r"); } TWI_WriteByte(pTwi, *pData++); num--; } /* Wait for actual end of transfer */ timeout = 0; /* Send a STOP condition */ TWI_SendSTOPCondition(pTwi); while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) ); if (timeout == TWITIMEOUTMAX) { TRACE_ERROR("TWID Timeout TC2\n\r"); } } return 0; }
void TwoWire::onService(void) { // Retrieve interrupt status uint32_t sr = TWI_GetStatus(twi); if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) { TWI_DisableIt(twi, TWI_IDR_SVACC); TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK | TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP); srvBufferLength = 0; srvBufferIndex = 0; // Detect if we should go into RECV or SEND status // SVREAD==1 means *master* reading -> SLAVE_SEND if (!TWI_STATUS_SVREAD(sr)) { status = SLAVE_RECV; } else { status = SLAVE_SEND; // Alert calling program to generate a response ASAP if (onRequestCallback) onRequestCallback(); else // create a default 1-byte response write((uint8_t) 0); } } if (status != SLAVE_IDLE) { if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) { if (status == SLAVE_RECV && onReceiveCallback) { // Copy data into rxBuffer // (allows to receive another packet while the // user program reads actual data) for (uint8_t i = 0; i < srvBufferLength; ++i) rxBuffer[i] = srvBuffer[i]; rxBufferIndex = 0; rxBufferLength = srvBufferLength; // Alert calling program onReceiveCallback( rxBufferLength); } // Transfer completed TWI_EnableIt(twi, TWI_SR_SVACC); TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK | TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP); status = SLAVE_IDLE; } } if (status == SLAVE_RECV) { if (TWI_STATUS_RXRDY(sr)) { if (srvBufferLength < BUFFER_LENGTH) srvBuffer[srvBufferLength++] = TWI_ReadByte(twi); } } if (status == SLAVE_SEND) { if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) { uint8_t c = 'x'; if (srvBufferIndex < srvBufferLength) c = srvBuffer[srvBufferIndex++]; TWI_WriteByte(twi, c); } } }
//------------------------------------------------------------------------------ /// Asynchronously sends data to a slave on the TWI bus. An optional callback /// function is invoked whenever the transfer is complete. /// \param pTwid Pointer to a Twid instance. /// \param address Slave address. /// \param iaddress Optional slave internal address. /// \param isize Number of internal address bytes. /// \param pData Data buffer to send. /// \param num Number of bytes to send. /// \param pAsync Pointer to an Asynchronous transfer descriptor. //------------------------------------------------------------------------------ unsigned char TWID_Write( Twid *pTwid, unsigned char address, unsigned int iaddress, unsigned char isize, unsigned char *pData, unsigned int num, Async *pAsync) { AT91S_TWI *pTwi = pTwid->pTwi; AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer; unsigned int timeout; //TRACE_DEBUG("TWID_Write()\n\r"); //TRACE_DEBUG("0x%X\n\r", pData[0]); SANITY_CHECK(pTwi); SANITY_CHECK((address & 0x80) == 0); SANITY_CHECK((iaddress & 0xFF000000) == 0); SANITY_CHECK(isize < 4); // Check that no transfer is already pending if (pTransfer) { TRACE_ERROR("TWI_Write: A transfer is already pending\n\r"); return TWID_ERROR_BUSY; } // Asynchronous transfer if (pAsync) { // Update the transfer descriptor pTwid->pTransfer = pAsync; pTransfer = (AsyncTwi *) pAsync; pTransfer->status = ASYNC_STATUS_PENDING; pTransfer->pData = pData; pTransfer->num = num; pTransfer->transferred = 1; // Enable write interrupt and start the transfer TWI_StartWrite(pTwi, address, iaddress, isize, *pData); TWI_EnableIt(pTwi, AT91C_TWI_TXRDY); } // Synchronous transfer else { // Start write TWI_StartWrite(pTwi, address, iaddress, isize, *pData++); num--; // Send all bytes while (num > 0) { // Wait before sending the next byte timeout = 0; while( !TWI_ByteSent(pTwi) && (++timeout<TWITIMEOUTMAX) ); if (timeout == TWITIMEOUTMAX) { TRACE_ERROR("TWID Timeout BS\n\r"); return TWID_ERROR_TIMEOUT; } TWI_WriteByte(pTwi, *pData++); num--; } // Wait for actual end of transfer timeout = 0; #ifdef TWI_V3XX // Send a STOP condition TWI_SendSTOPCondition(pTwi); #endif while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) ); if (timeout == TWITIMEOUTMAX) { TRACE_ERROR("TWID Timeout TC2\n\r"); return TWID_ERROR_TIMEOUT; } } return 0; }
/** * \brief Interrupt handler for a TWI peripheral. Manages asynchronous transfer * occuring on the bus. This function MUST be called by the interrupt service * routine of the TWI peripheral if asynchronous read/write are needed. * \param pTwid Pointer to a Twid instance. */ void TWID_Handler( Twid *pTwid ) { uint8_t status; AsyncTwi *pTransfer ; Twi *pTwi ; assert( pTwid != NULL ) ; pTransfer = (AsyncTwi*)pTwid->pTransfer ; assert( pTransfer != NULL ) ; pTwi = pTwid->pTwi ; assert( pTwi != NULL ) ; /* Retrieve interrupt status */ status = TWI_GetMaskedStatus(pTwi); /* Byte received */ if (TWI_STATUS_RXRDY(status)) { pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi); pTransfer->transferred++; /* check for transfer finish */ if (pTransfer->transferred == pTransfer->num) { TWI_DisableIt(pTwi, TWI_IDR_RXRDY); TWI_EnableIt(pTwi, TWI_IER_TXCOMP); } /* Last byte? */ else if (pTransfer->transferred == (pTransfer->num - 1)) { TWI_Stop(pTwi); } } /* Byte sent*/ else if (TWI_STATUS_TXRDY(status)) { /* Transfer finished ? */ if (pTransfer->transferred == pTransfer->num) { TWI_DisableIt(pTwi, TWI_IDR_TXRDY); TWI_EnableIt(pTwi, TWI_IER_TXCOMP); TWI_SendSTOPCondition(pTwi); } /* Bytes remaining */ else { TWI_WriteByte(pTwi, pTransfer->pData[pTransfer->transferred]); pTransfer->transferred++; } } /* Transfer complete*/ else if (TWI_STATUS_TXCOMP(status)) { TWI_DisableIt(pTwi, TWI_IDR_TXCOMP); pTransfer->status = 0; pTwid->pTransfer = 0; if (pTransfer->callback) { pTransfer->callback((Async *) pTransfer); } } }