예제 #1
0
파일: Wire.cpp 프로젝트: ykoh/bench
static inline bool TWI_WaitTransferComplete(Twi *_twi, uint32_t _timeout) {
	while (!TWI_TransferComplete(_twi)) {
		if (TWI_FailedAcknowledge(_twi))
			return false;
		if (--_timeout == 0)
			return false;
	}
	return true;
}
예제 #2
0
파일: twi.c 프로젝트: yunfei-ma/hprfs
/**
 * \brief Asynchronously reads data from a slave on the TWI bus. An optional
 * callback function is triggered when the transfer is complete.
 * \param pTwid  Pointer to a Twid instance.
 * \param address  TWI slave address.
 * \param iaddress  Optional slave internal address.
 * \param isize  Internal address size in bytes.
 * \param pData  Data buffer for storing received bytes.
 * \param num  Number of bytes to read.
 * \param pAsync  Asynchronous transfer descriptor.
 * \return 0 if the transfer has been started; otherwise returns a TWI error code.
 */
uint8_t TWID_Read(
    Twi *pTwi,
    uint8_t address,
    uint32_t iaddress,
    uint8_t isize,
    uint8_t *pData,
    uint32_t num)
{
    //Twi *pTwi;
    uint32_t timeout;

    assert( pTwi != NULL ) ;

    assert( (address & 0x80) == 0 ) ;
    assert( (iaddress & 0xFF000000) == 0 ) ;
    assert( isize < 4 ) ;

    /* Set STOP signal if only one byte is sent*/
    if (num == 1) {

        TWI_Stop(pTwi);
    }

    /* Synchronous transfer*/

    /* Start read*/
    TWI_StartRead(pTwi, address, iaddress, isize);

    /* Read all bytes, setting STOP before the last byte*/
    while (num > 0) {

        /* Last byte ?*/
        if (num == 1) {

            TWI_Stop(pTwi);
        }

        /* Wait for byte then read and store it*/
        timeout = 0;
        while( !TWI_ByteReceived(pTwi) && (++timeout<TWITIMEOUTMAX) );
        if (timeout == TWITIMEOUTMAX) {

            TRACE_ERROR("TWID Timeout BR\n\r");
        }
        *pData++ = TWI_ReadByte(pTwi);
        num--;
    }

    /* Wait for transfer to be complete */
    timeout = 0;
    while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
    if (timeout == TWITIMEOUTMAX) {
        TRACE_ERROR("TWID Timeout TC\n\r");
    }

    return 0;
}
예제 #3
0
파일: twi.c 프로젝트: yunfei-ma/hprfs
/**
 * \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;
}
예제 #4
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;
}
예제 #5
0
// i2c_eeprom_master_read/write are based on twid.c from atmels at91lib and
// adapted for better handling when there is no eeprom present.
// This handling is needed for the bricklet initialization
bool i2c_eeprom_master_read(Twi *twi,
                            const uint16_t internal_address,
                            char *data,
                            const uint16_t length) {
	uint32_t timeout;

	mutex_take(mutex_twi_bricklet, MUTEX_BLOCKING);

	// Start read
	TWI_StartRead(twi,
	              bricklet_eeprom_address,
	              internal_address,
	              I2C_EEPROM_INTERNAL_ADDRESS_BYTES);

	for(uint16_t i = 0; i < length; i++) {
		// If last Byte -> send STOP
		if(i == length-1) {
			TWI_Stop(twi);
		}

		uint32_t timeout = 0;
		// Wait until byte is received, otherwise return false
		while(!TWI_ByteReceived(twi) && (++timeout < I2C_EEPROM_TIMEOUT));

		if(timeout == I2C_EEPROM_TIMEOUT) {
			logieew("read timeout (nothing received)\n\r");
			mutex_give(mutex_twi_bricklet);
			return false;
		}

		data[i] = TWI_ReadByte(twi);
	}

	timeout = 0;
	// Wait for transfer to be complete
	while(!TWI_TransferComplete(twi) && (++timeout < I2C_EEPROM_TIMEOUT));
	if (timeout == I2C_EEPROM_TIMEOUT) {
		logieew("read timeout (transfer incomplete)\n\r");
		mutex_give(mutex_twi_bricklet);
		return false;
	}

	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
예제 #7
0
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;
}
예제 #8
0
unsigned char ReadAccelData(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 Reading
	TWI_StartRead(AT91C_BASE_TWI, ACCELADDR,iaddress,1);
	
	while (num > 0) {
		// Last byte
		if(num == 1) TWI_Stop(AT91C_BASE_TWI);
		
		// wait for byte then read and store it
		timeout = 0;
		while(!TWI_ByteReceived(AT91C_BASE_TWI) && (++timeout<TWITIMEOUTMAX)) nop();
		if(timeout == TWITIMEOUTMAX) return 2;
		*bytes++ = TWI_ReadByte(AT91C_BASE_TWI);
		num--;
	}
	
	return 0;
}
예제 #9
0
파일: twid.c 프로젝트: copterpilot/bricklib
/**
 * \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;
}
예제 #10
0
파일: twid.c 프로젝트: copterpilot/bricklib
/**
 * \brief Asynchronously reads data from a slave on the TWI bus. An optional
 * callback function is triggered when the transfer is complete.
 * \param pTwid  Pointer to a Twid instance.
 * \param address  TWI slave address.
 * \param iaddress  Optional slave internal address.
 * \param isize  Internal address size in bytes.
 * \param pData  Data buffer for storing received bytes.
 * \param num  Number of bytes to read.
 * \param pAsync  Asynchronous transfer descriptor.
 * \return 0 if the transfer has been started; otherwise returns a TWI error code.
 */
uint8_t TWID_Read(
    Twid *pTwid,
    uint8_t address,
    uint32_t iaddress,
    uint8_t isize,
    uint8_t *pData,
    uint32_t num,
    Async *pAsync)
{
    Twi *pTwi;
    AsyncTwi *pTransfer;
    uint32_t timeout;

    assert( pTwid != NULL ) ;
    pTwi = pTwid->pTwi;
    pTransfer = (AsyncTwi *) pTwid->pTransfer;

    assert( (address & 0x80) == 0 ) ;
    assert( (iaddress & 0xFF000000) == 0 ) ;
    assert( isize < 4 ) ;

    /* Check that no transfer is already pending*/
    if (pTransfer) {
        TRACE_ERROR("TWID_Read: A transfer is already pending\n\r");
        return TWID_ERROR_BUSY;
    }

    /* Set STOP signal if only one byte is sent*/
    if (num == 1) {

        TWI_Stop(pTwi);
    }

    /* 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 = 0;

        /* Enable read interrupt and start the transfer */
        TWI_EnableIt(pTwi, TWI_IER_RXRDY);
        TWI_StartRead(pTwi, address, iaddress, isize);
    }
    /* Synchronous transfer*/
    else {

        /* Start read*/
        TWI_StartRead(pTwi, address, iaddress, isize);

        /* Read all bytes, setting STOP before the last byte*/
        while (num > 0) {

            /* Last byte ?*/
            if (num == 1) {

                TWI_Stop(pTwi);
            }

            /* Wait for byte then read and store it*/
            timeout = 0;
            while( !TWI_ByteReceived(pTwi) && (++timeout<TWITIMEOUTMAX) ) {
            	if(pTwi->TWI_SR & TWI_SR_NACK) {
            		return 0;
            	}
            }
            if (timeout == TWITIMEOUTMAX) {
                TRACE_ERROR("TWID Timeout BR\n\r");
                *pData++ = 0;
            } else {
				*pData++ = TWI_ReadByte(pTwi);
            }
            num--;
        }

        /* Wait for transfer to be complete */
        timeout = 0;
        while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
        if (timeout == TWITIMEOUTMAX) {
            TRACE_ERROR("TWID Timeout TC\n\r");
        }
    }

    pTwi->TWI_SR;
    pTwi->TWI_RHR;

    return 0;
}
예제 #11
0
/**
 * \brief Asynchronously reads data from a slave on the TWI bus. An optional
 * callback function is triggered when the transfer is complete.
 * \param pTwid  Pointer to a Twid instance.
 * \param address  TWI slave address.
 * \param iaddress  Optional slave internal address.
 * \param isize  Internal address size in bytes.
 * \param pData  Data buffer for storing received bytes.
 * \param num  Number of bytes to read.
 * \param pAsync  Asynchronous transfer descriptor.
 * \return 0 if the transfer has been started; otherwise returns a TWI error code.
 */
uint8_t TWID_Read(
    Twid *pTwid,
    uint8_t address,
    uint32_t iaddress,
    uint8_t isize,
    uint8_t *pData,
    uint32_t num,
    Async *pAsync)
{
    Twi *pTwi;
    AsyncTwi *pTransfer;
    uint32_t timeout = 0;
    uint32_t i = 0;
    uint32_t status;

    assert( pTwid != NULL ) ;
    pTwi = pTwid->pTwi;
    pTransfer = (AsyncTwi *) pTwid->pTransfer;

    assert( (address & 0x80) == 0 ) ;
    assert( (iaddress & 0xFF000000) == 0 ) ;
    assert( isize < 4 ) ;

    /* Check that no transfer is already pending*/
    if (pTransfer) {

        TRACE_ERROR("TWID_Read: 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 = 0;

        /* Enable read interrupt and start the transfer */
        TWI_EnableIt(pTwi, TWI_IER_RXRDY);
        TWI_StartRead(pTwi, address, iaddress, isize);
    }
    /* Synchronous transfer*/
    else {

        /* Start read*/
        TWI_StartRead(pTwi, address, iaddress, isize);
        if (num != 1) 
        {
                status = TWI_GetStatus(pTwi);

                if(status & TWI_SR_NACK)
                    TRACE_ERROR("TWID NACK error\n\r");
                timeout = 0;
                while( ! (status & TWI_SR_RXRDY) && (++timeout<TWITIMEOUTMAX))
                {
                    status = TWI_GetStatus(pTwi);
                    //TRACE_ERROR("TWID status %x\n\r",TWI_GetStatus(pTwi));
                }

                pData[0] = TWI_ReadByte(pTwi);
                for( i = 1; i < num - 1; i++)
                {
                    status = TWI_GetStatus(pTwi);
                    if(status & TWI_SR_NACK)
                      TRACE_ERROR("TWID NACK error\n\r");
                    timeout = 0;
                    while( ! (status & TWI_SR_RXRDY) && (++timeout<TWITIMEOUTMAX))
                    {
                        status = TWI_GetStatus(pTwi);
                        //TRACE_ERROR("TWID status %x\n\r",TWI_GetStatus(pTwi));
                    }
                    pData[i] = TWI_ReadByte(pTwi);
                }
        }
        TWI_Stop(pTwi);
        status = TWI_GetStatus(pTwi);
        if(status & TWI_SR_NACK)
          TRACE_ERROR("TWID NACK error\n\r");
        timeout = 0;
        while( ! (status & TWI_SR_RXRDY)  && (++timeout<TWITIMEOUTMAX))
        {
            status = TWI_GetStatus(pTwi);
            //TRACE_ERROR("TWID status %x\n\r",TWI_GetStatus(pTwi));
        }

        pData[i] = TWI_ReadByte(pTwi);
        timeout = 0;
        status = TWI_GetStatus(pTwi);
        while( !(status & TWI_SR_TXCOMP) && (++timeout<TWITIMEOUTMAX))
        {
            status = TWI_GetStatus(pTwi);
            //TRACE_ERROR("TWID status %x\n\r",TWI_GetStatus(pTwi));
        }
#if 0
        /* Read all bytes, setting STOP before the last byte*/
        while (num > 0) {

            /* Last byte ?*/
            if (num == 1) {

                TWI_Stop(pTwi);
            }

            /* Wait for byte then read and store it*/
            timeout = 0;
            while( !TWI_ByteReceived(pTwi) && (++timeout<TWITIMEOUTMAX) );
            if (timeout == TWITIMEOUTMAX) {
                TRACE_ERROR("TWID Timeout BR\n\r");
            }
            *pData++ = TWI_ReadByte(pTwi);
            num--;
        }

        /* Wait for transfer to be complete */
        timeout = 0;
        while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
        if (timeout == TWITIMEOUTMAX) {
            TRACE_ERROR("TWID Timeout TC\n\r");
        }
#endif
    }

    return 0;
}
예제 #12
0
파일: twid.c 프로젝트: NissankaW/Mariokart3
//------------------------------------------------------------------------------
/// 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;
}
예제 #13
0
파일: twid.c 프로젝트: NissankaW/Mariokart3
//-----------------------------------------------------------------------------
/// Asynchronously reads data from a slave on the TWI bus. An optional
/// callback function is triggered when the transfer is complete.
/// Returns 0 if the transfer has been started; otherwise returns a TWI error
/// code.
/// \param pTwid  Pointer to a Twid instance.
/// \param address  TWI slave address.
/// \param iaddress  Optional slave internal address.
/// \param isize  Internal address size in bytes.
/// \param pData  Data buffer for storing received bytes.
/// \param num  Number of bytes to read.
/// \param pAsync  Asynchronous transfer descriptor.
//-----------------------------------------------------------------------------
unsigned char TWID_Read(
    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_Read()\n\r");
    SANITY_CHECK(pTwid);
    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("TWID_Read: A transfer is already pending\n\r");
        return TWID_ERROR_BUSY;
    }

    // Set STOP signal if only one byte is sent
    if (num == 1) {

        TWI_Stop(pTwi);
    }

    // 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 = 0;
        
        // Enable read interrupt and start the transfer
        TWI_EnableIt(pTwi, AT91C_TWI_RXRDY);
        TWI_StartRead(pTwi, address, iaddress, isize);
    }
    // Synchronous transfer
    else {

        // Start read
        TWI_StartRead(pTwi, address, iaddress, isize);

        // Read all bytes, setting STOP before the last byte
        while (num > 0) {

            // Last byte
            if (num == 1) {

                TWI_Stop(pTwi);
            }

            // Wait for byte then read and store it
            timeout = 0;
            while( !TWI_ByteReceived(pTwi) && (++timeout<TWITIMEOUTMAX) );
            if (timeout == TWITIMEOUTMAX) {
                TRACE_ERROR("TWID Timeout BR\n\r");
                return TWID_ERROR_TIMEOUT;
            }
            *pData++ = TWI_ReadByte(pTwi);
            num--;
        }

        // Wait for transfer to be complete
        timeout = 0;
        while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
        if (timeout == TWITIMEOUTMAX) {
            TRACE_ERROR("TWID Timeout TC\n\r");
            return TWID_ERROR_TIMEOUT;
        }
    }

    return 0;
}