示例#1
0
/**
 * Reads out a single byte of data over the I2C
 * 
 * @return The received byte of data
 */
unsigned char I2C_ReceiveOneByte()
{
    I2CReceiverEnable(I2C1, TRUE);
    while (!I2CReceivedDataIsAvailable(I2C1));
    I2CReceiverEnable(I2C1, FALSE);

    return I2CGetByte(I2C1);
}
示例#2
0
文件: main.c 项目: conorpp/school
/*
 Reads a byte received from i2c channel (with no strings attached)
 */
BYTE readByte(I2C_MODULE i2c){

    I2CReceiverEnable(i2c, TRUE);               // enable receiving data
    while ( ! (I2CReceivedDataIsAvailable(i2c)));

    BYTE t;
    t = I2CGetByte(i2c);                        // grab byte

    I2CReceiverEnable(i2c, FALSE);              // put it back
    return t;
}
示例#3
0
//==============================================================================
int i2c_Rx( int Nack )
{
    I2C1CONbits.RCEN = 1;

    while( !I2C1STATbits.RBF );

    if (Nack == 1)
    {
        I2C1CONbits.ACKDT = 1;
        I2C1CONbits.ACKEN = 1;
    } else
    {
        I2C1CONbits.ACKDT = 0;
        I2C1CONbits.ACKEN = 1;
    }

    if(I2CReceiverEnable(EEPROM_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW)
    {
        putsUART1("Error: I2C Receive Overflow\n");
        return FALSE;
    }
    else
    {
        int x;
        while(!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS));
        x = I2CGetByte(EEPROM_I2C_BUS);

        while ( I2C1CONbits.ACKEN );

        return x;
    }
}
示例#4
0
/**
 *  @brief  Write to device using generic i2c protocol
 *  @param[in]  slave_addr - slave address
 *  @param[in]  reg_addr   - register address
 *  @param[in]  length     - number of bytes to read
 *  @param[in]  *data      - pointer to where register data is to be transfered
 *  @return     0 if sucessfull, 1 otherwise
 */
int i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data) {

	BYTE i=2;

	StartI2C1();								//Send the Start Bit
	IdleI2C1();
        if (MasterWriteI2C1(((slave_addr<<1)|(0x00))))
            return 1;
	IdleI2C1();
        if (MasterWriteI2C1(reg_addr))
            return 1;
	IdleI2C1();
        StartI2C1();                        //Send the Start Bit
        IdleI2C1();                         //Wait to complete
        if (MasterWriteI2C1(((slave_addr<<1)|(0x01))))
            return 1;
	IdleI2C1();
	I2CReceiverEnable ( I2C1, TRUE);

	for(i=0;i<length;i++) {
            data[i] = MasterReadI2C1();
		if(i<(length-1)) {
                    I2CAcknowledgeByte(MPU_I2C, TRUE);
                    IdleI2C1();
		}
		else {
                    I2CAcknowledgeByte(MPU_I2C, FALSE);
                    IdleI2C1();
		}
	}
        StopI2C1();								//Send the Stop condition
        IdleI2C1();								//Wait to complete

	return 0;
}
示例#5
0
int i2c_read(unsigned char addr, unsigned char reg, unsigned char length, unsigned char *data) {
    StartTransfer(FALSE);
    TransmitOneByte((addr<<1) & 0b11111110);
    TransmitOneByte(reg);
    
    StartTransfer(TRUE);
    TransmitOneByte((addr<<1) | 0b00000001);
    
    int i;
    for(i = 0; i < length; i++) {
        I2CReceiverEnable(I2C2, TRUE);
	while(!I2CReceivedDataIsAvailable(I2C2));
        if(i == length-1) {
            I2CAcknowledgeByte(I2C2, FALSE);
        } else {
            I2CAcknowledgeByte(I2C2, TRUE);
        }

        data[i] = I2CGetByte(I2C2);
        IdleI2C2();

    }
    StopTransfer();
    return 0;
}
示例#6
0
BYTE i2cRecieveByte(I2C_MODULE id, BOOL ack){
    I2CReceiverEnable(id, TRUE);
    while(!I2CReceivedDataIsAvailable(id));
    I2CAcknowledgeByte(id, ack);
    while(!I2CAcknowledgeHasCompleted(id)) ;
    BYTE result = I2CGetByte(id);
    return result;
}
示例#7
0
bool i2c_receive()
{
	state = I2C_STATE_RECEIVE;

	if (I2CReceiverEnable(I2C1, TRUE) != I2C_SUCCESS)
		return FALSE;

	if (!semaphore_take(bus_lock, PORT_MAX_DELAY))
		return FALSE;

	return TRUE;
}
示例#8
0
BOOL ReceiveOneByte(UINT8* data, BOOL ack)
{
	if(I2CReceiverEnable(LCD_I2C_BUS, TRUE)==I2C_SUCCESS)
	{
		while (!(I2CReceivedDataIsAvailable(LCD_I2C_BUS)));		
		*data = I2CGetByte(LCD_I2C_BUS);
		I2CAcknowledgeByte(LCD_I2C_BUS, ack);
		while (!(I2CAcknowledgeHasCompleted(LCD_I2C_BUS))); 
		return TRUE;
	}
	else 
	{
	return FALSE;
	}
}
示例#9
0
文件: I2C.c 项目: sdajani/sdp
int16_t I2C_getData(I2C_MODULE I2C_ID){
    BOOL Success = TRUE;

        // Enables the module to receive data from the I2C bus
    if(I2CReceiverEnable(I2C_ID, TRUE) == I2C_RECEIVE_OVERFLOW){
        #ifdef DEBUG
        printf("Error: I2C Receive Overflow\n");
        #endif
        Success = FALSE;
    }
    else{
    //wait until data is available
        while(!I2CReceivedDataIsAvailable(I2C_ID));
    //get a byte of data received from the I2C bus.
        return I2CGetByte(I2C_ID);
    }
    return Success;
}
static uint8_t ReceiveOneByte(I2C_MODULE i2c_id, bool ack)
{
    uint8_t data;
    
    // Enable I2C receive
    I2CReceiverEnable(i2c_id, TRUE);
    
    // Wait until 1-byte is fully received
    while (!I2CReceivedDataIsAvailable(i2c_id));
    
    // Save the byte received
    data = I2CGetByte(i2c_id);
    
    // Perform acknowledgement sequence
    I2CAcknowledgeByte(i2c_id, ack);
    
    // Wait until acknowledgement is successfully sent 
    while (!I2CAcknowledgeHasCompleted(i2c_id));
    
    return data;
}
示例#11
0
//------------------------------------------------------------------------------
// Function: I2C_ReadBlock
// Description: Read a block of bytes from the spacifed I2C slave address at the specified offset.
//              The offset address is one byte (8 bit offset only).
//              The return code is always 0.  There is no indication in case of error.
//------------------------------------------------------------------------------
BYTE I2C_ReadBlock(BYTE deviceID, BYTE offset, BYTE *buffer, WORD length)
{
    BYTE write_buffer[2] = {0x00};
    BYTE count =0;
    BOOL                Success = TRUE;

    write_buffer[0] = deviceID;
    write_buffer[1] = offset;

    // Start the transfer to write data to the EEPROM
    if(!StartTransfer(FALSE) )
    {
        while(1);
    }

    // Transmit all data
    count = 0;

    while( Success && (count < (2)) )
    {
        // Transmit a byte
        TransmitOneByte(write_buffer[count]);

            // Advance to the next byte
            count++;

            // Verify that the byte was acknowledged
            if(!I2CByteWasAcknowledged(OVM7690_I2C_BUS))
            {
                Success = FALSE;
            }
    }

    // Start the transfer to read data
    StartTransfer(TRUE);

   // Transmit the address with the READ bit set
   deviceID |= 0x01;

   TransmitOneByte(deviceID);

    // Verify that the byte was acknowledged
    if(!I2CByteWasAcknowledged(OVM7690_I2C_BUS))
    {
        Success = FALSE;
    }

    for(count=0;count<length;count++)
    {

    // Read the data from the desired address
    if(Success)
    {
        if(I2CReceiverEnable(OVM7690_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW)
        {
            Success = FALSE;
        }
        else
        {
//            while(!I2CReceivedDataIsAvailable(OVM7690_I2C_BUS));
            *buffer++ = I2CGetByte(OVM7690_I2C_BUS);
        }

    }
    }
    // End the transfer (stop here if an error occured)
    StopTransfer();

    return(0);
}
示例#12
0
int main(void)
{
    UINT8               i2cData[10];
    I2C_7_BIT_ADDRESS   SlaveAddress;
    int                 Index;
    int                 DataSz;
    UINT32              actualClock;
    BOOL                Acknowledged;
    BOOL                Success = TRUE;
    UINT8               i2cbyte;


    // Initialize debug messages (when supported)
    DBINIT();

    // Set the I2C baudrate
    actualClock = I2CSetFrequency(EEPROM_I2C_BUS, GetPeripheralClock(), I2C_CLOCK_FREQ);
    if ( abs(actualClock-I2C_CLOCK_FREQ) > I2C_CLOCK_FREQ/10 )
    {
        DBPRINTF("Error: I2C1 clock frequency (%u) error exceeds 10%%.\n", (unsigned)actualClock);
    }

    // Enable the I2C bus
    I2CEnable(EEPROM_I2C_BUS, TRUE);
    

    //
    // Send the data to EEPROM to program one location
    //

    // Initialize the data buffer
    I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_WRITE);
    i2cData[0] = SlaveAddress.byte;
    i2cData[1] = 0x05;              // EEPROM location to program (high address byte)
    i2cData[2] = 0x40;              // EEPROM location to program (low address byte)
    i2cData[3] = 0xAA;              // Data to write
    DataSz = 4;

    // Start the transfer to write data to the EEPROM
    if( !StartTransfer(FALSE) )
    {
        while(1);
    }

    // Transmit all data
    Index = 0;
    while( Success && (Index < DataSz) )
    {
        // Transmit a byte
        if (TransmitOneByte(i2cData[Index]))
        {
            // Advance to the next byte
            Index++;

            // Verify that the byte was acknowledged
            if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
            {
                DBPRINTF("Error: Sent byte was not acknowledged\n");
                Success = FALSE;
            }
        }
        else
        {
            Success = FALSE;
        }
    }

    // End the transfer (hang here if an error occured)
    StopTransfer();
    if(!Success)
    {
        while(1);
    }


    // Wait for EEPROM to complete write process, by polling the ack status.
    Acknowledged = FALSE;
    do
    {
        // Start the transfer to address the EEPROM
        if( !StartTransfer(FALSE) )
        {
            while(1);
        }
        
        // Transmit just the EEPROM's address
        if (TransmitOneByte(SlaveAddress.byte))
        {
            // Check to see if the byte was acknowledged
            Acknowledged = I2CByteWasAcknowledged(EEPROM_I2C_BUS);
        }
        else
        {
            Success = FALSE;
        }

        // End the transfer (stop here if an error occured)
        StopTransfer();
        if(!Success)
        {
            while(1);
        }

    } while (Acknowledged != TRUE);


    //
    // Read the data back from the EEPROM.
    //

    // Initialize the data buffer
    I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_WRITE);
    i2cData[0] = SlaveAddress.byte;
    i2cData[1] = 0x05;              // EEPROM location to read (high address byte)
    i2cData[2] = 0x40;              // EEPROM location to read (low address byte)
    DataSz = 3;
    
    // Start the transfer to read the EEPROM.
    if( !StartTransfer(FALSE) )
    {
        while(1);
    }
    
    // Address the EEPROM.
    Index = 0;
    while( Success & (Index < DataSz) )
    {
        // Transmit a byte
        if (TransmitOneByte(i2cData[Index]))
        {
            // Advance to the next byte
            Index++;
        }
        else
        {
            Success = FALSE;
        }

        // Verify that the byte was acknowledged
        if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
        {
            DBPRINTF("Error: Sent byte was not acknowledged\n");
            Success = FALSE;
        }
    }

    // Restart and send the EEPROM's internal address to switch to a read transfer
    if(Success)
    {
        // Send a Repeated Started condition
        if( !StartTransfer(TRUE) )
        {
            while(1);
        }

        // Transmit the address with the READ bit set
        I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_READ);
        if (TransmitOneByte(SlaveAddress.byte))
        {
            // Verify that the byte was acknowledged
            if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
            {
                DBPRINTF("Error: Sent byte was not acknowledged\n");
                Success = FALSE;
            }
        }
        else
        {
            Success = FALSE;
        }
    }

    // Read the data from the desired address
    if(Success)
    {
        if(I2CReceiverEnable(EEPROM_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW)
        {
            DBPRINTF("Error: I2C Receive Overflow\n");
            Success = FALSE;
        }
        else
        {
            while(!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS));
            i2cbyte = I2CGetByte(EEPROM_I2C_BUS);
        }

    }

    // End the transfer (stop here if an error occured)
    StopTransfer();
    if(!Success)
    {
        while(1);
    }


    // Validate the data read
    if( i2cbyte != 0xAA )
    {
        DBPRINTF("Error: Verify failed\n");
    }
    else
    {
        DBPRINTF("Success\n");
    }

    // Example complete
    while(1);
}
示例#13
0
void i2c_isr(uint8_t p) {
    I2CModule_t * mod;

    // Get a reference to the module structure
    switch (p) {
        case I2C2:
            mod = &I2C_2;
            break;
            
        default:
            return;
    }

    switch (mod->state) {
        case IDLE:
            break;

        case START:
            I2CStart(mod->moduleName);
            mod->state = ADDRESS;
            I2C_2.dataDirection = WRITING;
            break;

        case ADDRESS:
            switch (mod->dataDirection) {
                case READING:
                    I2CSendByte(mod->moduleName, mod->frame->address + 1);
                    mod->state = CHECK_ACK;
                    break;

                case WRITING:
                    I2CSendByte(mod->moduleName, mod->frame->address);
                    mod->state = CHECK_ACK;
                    break;
            }

            break;

        case CHECK_ACK:
            if (I2CByteWasAcknowledged(mod->moduleName) == True) {
                switch (mod->dataDirection) {
                    case READING:
                        mod->state = READ;
                        break;

                    case WRITING:
                        mod->state = WRITE;
                        break;
                }
            } else {
                mod->frame->success = False;
                mod->state = STOP;
            }

            i2c_isr(mod->moduleName);
            
            break;

        case RESTART:
            I2CRepeatStart(mod->moduleName);
            mod->dataDirection = READING;
            mod->state = ADDRESS;
            break;

        case READ_START:
            I2CReceiverEnable(mod->moduleName, TRUE);
            mod->state = READ;
            break;

        case READ:
            mod->frame->rx_buf[mod->frame->rx_buf_index++] = I2CGetByte(mod->moduleName);
                
            // If we need to read more bytes send an ACK
            if (mod->frame->rx_buf_index <= mod->frame->bytesToRead) {
                I2CAcknowledgeByte(mod->moduleName, True); // Send an ACK
                mod->state = READ_START; // Prepare for the next byte
            } else {
                I2CAcknowledgeByte(mod->moduleName, False); // Send a NACK
                mod->frame->success = True;
                mod->state = STOP; // Prepare for a stop condition
            }

            break;

        case WRITE:
            // If there are still bytes to send
            if (mod->frame->tx_buf_index < mod->frame->tx_buf_size) {
                I2CSendByte(mod->moduleName, mod->frame->tx_buf[mod->frame->tx_buf_index++]);
            } else {
                // If we need to read some bytes
                if (mod->frame->bytesToRead > 0) {
                    mod->state = RESTART; // Send a restart condition
                } else {
                    mod->frame->success = True;
                    mod->state = STOP; // Send a stop condition
                }

                i2c_isr(mod->moduleName); // Re-run this function to call stop/restart
                // TODO: Perhaps there is a better way to do this..!
            }
            break;

        case STOP:
            I2CStop(mod->moduleName);
            mod->frameToSend = False;
            mod->state = IDLE;

            // Tell the owner of the frame that it has complete or failed
            if (mod->frame->success == True) {
                mod->frame->callback();
            } else {
                mod->frame->error();
            }

            break;

        case BUSERROR:
            led12 = 1;
            // TODO: Something..!
            while(1); // Don't know what to do here yet..!
            break;
    }
}
示例#14
0
文件: mpu6050.cpp 项目: danhil/copter
BOOL MPU6050::readReg( UINT8 regAddress, UINT8 &data )
{
    // Variable declarations
    UINT8               i2cData[10];
    I2C_7_BIT_ADDRESS   SlaveAddress;
    int                 Index;
    int                 DataSz;
    BOOL                Acknowledged;
    BOOL                Success = TRUE;
    UINT8               i2cbyte;


    // Initialize the data buffer
    I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, this->deviceAddress, I2C_WRITE);
    i2cData[0] = SlaveAddress.byte;
    i2cData[1] = regAddress;                 // MPU6050 data address to read (0x75 = WHO_AM_I which contains 0x68)
    DataSz = 2;


    // Start the transfer
    if( !StartTransfer(FALSE) )
    {
        //while(1);
        Success = FALSE;

        sprintf( filename, "Error in #1 StartTransfer(): when reading address %u.\n", (unsigned)regAddress );
        putsUART1( filename );
    }

    // Address the device.
    Index = 0;
    while( Success & (Index < DataSz) )
    {
        // Transmit a byte
        if (TransmitOneByte(i2cData[Index]))
            Index++;
        else
        {
            Success = FALSE;

            sprintf( filename, "Error in #1 TransmitOneByte(): when reading address %u.\n", (unsigned)regAddress );
            putsUART1( filename );
        }
        // Verify that the byte was acknowledged
        if(!I2CByteWasAcknowledged( this->i2cBusId ))
        {
            //DBPRINTF("Error: Sent byte was not acknowledged\n");
            Success = FALSE;

            sprintf( filename, "Error in #1 I2CByteWasAcknowledged(): when reading address %u.\n", (unsigned)regAddress );
            putsUART1( filename );
        }
    }

    // Restart and send the device's internal address to switch to a read transfer
    if(Success)
    {
        // Send a Repeated Started condition
        if( !StartTransfer(TRUE) )
        {
            //while(1);
            Success = FALSE;

            sprintf( filename, "Error in #2 StartTransfer(): when reading address %u.\n", (unsigned)regAddress );
            putsUART1( filename );
        }

        // Transmit the address with the READ bit set
        I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, this->deviceAddress, I2C_READ);
        if (TransmitOneByte(SlaveAddress.byte))
        {
            // Verify that the byte was acknowledged
            if(!I2CByteWasAcknowledged( this->i2cBusId ))
            {
                //DBPRINTF("Error: Sent byte was not acknowledged\n");
                Success = FALSE;

                sprintf( filename, "Error in #2 I2CByteWasAcknowledged(): when reading address %u.\n", (unsigned)regAddress );
                putsUART1( filename );
            }
        }
        else
        {
            Success = FALSE;

            sprintf( filename, "Error in #2 TransmitOneByte(): when reading address %u.\n", (unsigned)regAddress );
            putsUART1( filename );
        }
    }

    //i2cbyte = 9;

    // Read the data from the desired address
    if(Success)
    {
        if(I2CReceiverEnable( this->i2cBusId , TRUE) == I2C_RECEIVE_OVERFLOW)
        {
            //DBPRINTF("Error: I2C Receive Overflow\n");
            Success = FALSE;

            sprintf( filename, "Error I2CReceiverEnable(): when reading address %u. I2C Receive Overflow.\n", (unsigned)regAddress );
            putsUART1( filename );
        }
        else
        {
            while(!I2CReceivedDataIsAvailable( this->i2cBusId ));
            i2cbyte = I2CGetByte( this->i2cBusId );
        }
    }

    // End the transfer
    StopTransfer();

    data = i2cbyte;

    if(!Success)
    {

        //mPORTBSetBits(BIT_2);
        //mPORTBClearBits(BIT_3);

        sprintf( filename, "Error in readReg(): when reading address %u.\n", (unsigned)regAddress );
        putsUART1( filename );
    }    

    return Success;
}
示例#15
0
文件: i2c_sw.c 项目: ctapang/v0_70b
//------------------------------------------------------------------------------
// Function: I2C_ReadBlock
// Description: Read a block of bytes from the spacifed I2C slave address at the specified offset.
//              The offset address is one byte (8 bit offset only).
//              The return code is always 0.  There is no indication in case of error.
//------------------------------------------------------------------------------
uint8_t I2C_ReadBlock(uint8_t deviceID, uint8_t offset, uint8_t *buffer, uint16_t length)
{
    uint8_t write_buffer[2] = {0x00};
    uint8_t count =0;
    bool Success = true;

    write_buffer[0] = deviceID;
    write_buffer[1] = offset;

    I2C1CONbits.ACKDT = 0;

    // Start the transfer to write data to the EEPROM
    if(!StartTransfer(false) )
    {
        return(1);
    }

   // Transmit the address with the READ bit set
   deviceID |= 0x01;

   TransmitOneByte(deviceID);
   
    // Verify that the byte was acknowledged
    if(!I2CByteWasAcknowledged(OVM7690_I2C_BUS))
    {
        Success = false;
        return(1);
    }

    for(count=0;count<length;count++)
    {

        // Read the data from the desired address
        if(I2CReceiverEnable(OVM7690_I2C_BUS, true) == I2C_RECEIVE_OVERFLOW)
        {
            Success = false;
            return(1);
        }
        else
        {
            while(!I2CReceivedDataIsAvailable(OVM7690_I2C_BUS));
            *buffer  = I2C1RCV;
            buffer++;

          if(count == (length-1))
          {
           // I2C1CONbits.ACKDT = 1;
            I2C1CONSET = 0x20;
          }

            I2C1CONbits.ACKEN = 1;		// initiate bus acknowledge sequence

            while(I2C1CONbits.ACKEN == 1);
        }

    }

    // End the transfer (stop here if an error occured)
    StopTransfer();

    return(0);
}
示例#16
0
/************************************************************************************************** 
  Function:
    BOOL I2CShared_ReadByte(const I2C_MODULE i2c, const UINT8 i2c_addr, const UINT8 i2c_register, UINT8 *const buffer)

  Author(s): 
    mkobit
  
  Summary: 
    Read a single byte from the (i2c) module from (i2c_register) and places it into (buffer)
  
  Description: 
    Waits until (i2c) bus is idle and then uses I2C protocol to start a transaction, write to the device and its register, restart with the read address
    and read the data. Sends a NACK at the end to stop the transmission and then stops the transaction
  
  Preconditions: 
    I2C module configured
  
  Parameters: 
    const I2C_MODULE i2c - I2C module to be used for this transaction
    const UINT8 i2c_write_addr - address of I2C device
    const UINT8 i2c_register - I2C register to read from
    UINT8 *const buffer - buffer to place read byte into
  
  Returns: 
    TRUE - read succesful
    FALSE - read unsuccessful
  
  Example: 
    <code>
    // example from accelerometer
    I2CShared_ReadByte(i2c, ACCEL_WRITE, ACCEL_READ, i2c_reg, buffer)
    </code>
  
  Conditions at Exit: 
    Buffer has byte of data in it read from (i2c)
    I2C bus idle
  
**************************************************************************************************/
BOOL I2CShared_ReadByte(const I2C_MODULE i2c, const UINT8 i2c_addr, const UINT8 i2c_register, UINT8 *const buffer) {
  int fault_count = 0;

  UINT8 i2c_write_addr = i2c_addr | I2C_WRITE;
  UINT8 i2c_read_addr = i2c_addr | I2C_READ;
  
  // START TRANSACTION
  if(!I2CShared_StartTransfer(i2c, FALSE)) {
    //printf("I2CShared_Read: Error, bus collision during transfer start to I2C=%d\n", i2c);
    return FALSE;
  }
    
  // SEND ADDRESS
  // Send write address for transaction, address is expected to already be formatted
  if (!I2CShared_TransmitOneByte(i2c, i2c_write_addr)) {
    //printf("I2CShared_Read: Error, could not send write address 0x%x to I2C=%d\n", (UINT8) i2c_write_addr, i2c);
    return FALSE;
  }
  
  // SEND INTERNAL REGISTER
  if (!I2CShared_TransmitOneByte(i2c, i2c_register)) {
    //printf("I2CShared_Read: Error, could not send i2c_register 0x%x to I2C=%d\n", (UINT8) i2c_register, i2c);
    return FALSE;
  }
  
  // SEND START AGAIN FOR READ
  // Send read address
  if(!I2CShared_StartTransfer(i2c, TRUE)) {
    //printf("I2CShared_Read: Error, bus collision during transfer start to I2C=%d\n", i2c);
    return FALSE;
  }

  if (!I2CShared_TransmitOneByte(i2c, i2c_read_addr)) {
    //printf("I2CShared_Read: Error, could not send i2c_address 0x%x to I2C=%d\n", i2c_read_addr, i2c);
    //I2CShared_StopTransfer(i2c);
    return FALSE;
  }
  
  // READ DATA BYTE
  // configure i2c module to receive
  if (I2CReceiverEnable(i2c, TRUE) != I2C_SUCCESS) {
    //printf("I2CShared_Read: Error, could not configure I2C=%d to be a receiver\n", i2c);
    return FALSE;
  }


  while (!I2CReceivedDataIsAvailable(i2c)) {// loop until data is ready to be read
    if (fault_count++ == TIMEOUT) {
      //printf("I2CShared_ReadByte: Timeout waiting for I2CReceivedDataIsAvailable\n");
      return FALSE;
    }
  }

  *buffer = I2CGetByte(i2c);
  I2CAcknowledgeByte(i2c, FALSE); // send nack on last byte
  fault_count = 0;
  while(!I2CAcknowledgeHasCompleted(i2c)) {
    if (fault_count++ == TIMEOUT) {
      //printf("I2CShared_ReadByte: Timeout waiting for I2CReceivedDataIsAvailable\n");
      return FALSE;
    }
  }
  I2CShared_StopTransfer(i2c);

  return TRUE;
}
示例#17
0
/************************************************************************************************** 
  Function:
    BOOL I2CShared_ReadMultipleBytes(const I2C_MODULE i2c, const UINT8 i2c_addr,
      const UINT8 i2c_register_start, const int nbytes, UINT8 *buffer)

  Author(s):
    mkobit

  Summary:
    Reads (nbytes) from the (i2c) module starting from (i2c_read_addr)  and places in (buffer)

  Description:
    Waits until (i2c) bus is idle and then uses I2C protocol to start a transaction, write to the device and its register, restart with the read address
    and read the data. Sends a NACK at the end to stop the transmission and then stops the transaction

  Preconditions:
    I2C module configured

  Parameters:
    const I2C_MODULE i2c - I2C module to be used for this transaction
    const UINT8 i2c_addr - address of I2C device
    const UINT8 i2c_register_start - I2C register to begin reading from
    const int nbytes - how many bytes to be read
    UINT8 *const buffer - buffer to place read bytes

  Returns:
    TRUE - reads were successful
    FALSE - at least 1 read was not successful

  Example:
    <code>
    // example from gyroscope, reading_rainbow buffer size 8
    I2CShared_ReadMultipleBytes(I2C_MODULE i2c, GYRO_WRITE, GYRO_READ, startReadI2CReg, nDataToRead, reading_rainbow)
    </code>

  Conditions at Exit:
    Buffer has n bytes of data in it read from (i2c)
    I2C bus idle

**************************************************************************************************/
BOOL I2CShared_ReadMultipleBytes(const I2C_MODULE i2c, const UINT8 i2c_addr, 
    const UINT8 i2c_register_start, const int nbytes, UINT8 *buffer) {
  int i;
  int fault_count = 0;
  UINT8 temp;
  
  UINT8 i2c_write_addr = i2c_addr | I2C_WRITE;
  UINT8 i2c_read_addr = i2c_addr | I2C_READ;

  // START TRANSACTION
  if(!I2CShared_StartTransfer(i2c, FALSE)) {
    //printf("I2CShared_ReadMultipleBytes: Error, bus collision during transfer start to I2C=%d\n", i2c);
    return FALSE;
  }
    
  // SEND ADDRESS
  if (!I2CShared_TransmitOneByte(i2c, i2c_write_addr)) {
    //printf("I2CShared_ReadMultipleBytes: Error, could not send i2c_address 0x%x to I2C=%d\n", i2c_write_addr, i2c);
    return FALSE;
  }
  
  // SEND INTERNAL REGISTER
  if (!I2CShared_TransmitOneByte(i2c, i2c_register_start)) {
    //printf("I2CShared_ReadMultipleBytes: Error, could not send i2c_register 0x%x to I2C=%d\n", (unsigned char) i2c_register_start, i2c);
    return FALSE;
  }
  
  // SEND START AGAIN FOR READ
  // Send read address
  if(!I2CShared_StartTransfer(i2c, TRUE)) {
    //printf("I2CShared_ReadMultipleBytes: Error, bus collision during transfer Restart to I2C=%d\n", i2c);
    return FALSE;
  }

  if (!I2CShared_TransmitOneByte(i2c, i2c_read_addr)) {
    //printf("I2CShared_ReadMultipleBytes: Error, could not send i2c_address 0x%x to I2C=%d\n", (unsigned char) i2c_read_addr, i2c);
    return FALSE;
  }
  
  // START READING
  // read all the data bytes and place them into the buffer
  for (i = 0; i < nbytes - 1; i++) {
    // configure i2c module to receive
    if (I2CReceiverEnable(i2c, TRUE) != I2C_SUCCESS) {
      //printf("I2CShared_ReadMultipleBytes: Error, could not configure I2C=%d to be a receiver\n", i2c);
      return FALSE;
    }

    fault_count = 0;
    while (!I2CReceivedDataIsAvailable(i2c)) {  // loop until data is ready to be read
      if (fault_count++ == TIMEOUT) {
        //printf("I2CShared_ReadMultipleBytes: Timeout waiting for I2CReceivedDataIsAvailable\n");
        return FALSE;
      }
    }

    // Read the byte from I2C
    temp = I2CGetByte(i2c);
    // Send ACK
    I2CAcknowledgeByte(i2c, TRUE);

    fault_count = 0;
    while(!I2CAcknowledgeHasCompleted(i2c)) {
      if (fault_count++ == TIMEOUT) {
        //printf("I2CShared_ReadMultipleBytes: Timeout waiting for I2CAcknowledgeHasCompleted\n");
        return FALSE;
      }
    }
    // place read data in buffer
    buffer[i] = temp;
    // END OF EACH READ
  }

  // Read last byte and send NACK
  if (I2CReceiverEnable(i2c, TRUE) != I2C_SUCCESS) {
    //printf("I2CShared_ReadMultipleBytes: Error, could not configure I2C=%d to be a receiver\n", i2c);
    return FALSE;
  }

  fault_count = 0;
  // Wait until data is ready to be read
  while (!I2CReceivedDataIsAvailable(i2c)) {
    if (fault_count++ == TIMEOUT) {
      //printf("I2CShared_ReadByte: Timeout waiting for I2CReceivedDataIsAvailable\n");
      return FALSE;
    }
  }

  // Get the data from the I2C
  temp = I2CGetByte(i2c);

  // Send NACK on last receive
  I2CAcknowledgeByte(i2c, FALSE);

  fault_count = 0;
  while(!I2CAcknowledgeHasCompleted(i2c)) {
    if (fault_count++ == TIMEOUT) {
      //printf("I2CShared_ReadByte: Timeout waiting for I2CAcknowledgeHasCompleted\n");
      return FALSE;
    }
  }

  // Place last data into buffer
  buffer[i] = temp;

  // Stop the transaction
  I2CShared_StopTransfer(i2c);
  return TRUE;
}
void* message_read(gestic_t *gestic, int *size)
{
    UINT8 RcvCount = 0;
    UINT8 writeIndex = 0;
    I2C_MODULE port = gestic->io.I2cPort;
    unsigned char *result = gestic->io.read_buffer;

    // Get TSLine
    if(gestic->io.device(GestICDev_TsLine_Get) == 1)
        result = NULL;

    if(result)
        gestic->io.device(GestICDev_TsLine_Assert);

    if(result && transfer_start(port, gestic->io.I2cSlaveAddr, 1))
        result = NULL;

    // Read the data from the desired address
    while(result) {
        UINT8 i2cbyte;

        /* Check for buffer overflow */
        if(I2CReceiverEnable(port, TRUE) == I2C_RECEIVE_OVERFLOW) {
            result = NULL;
            break;
        }

        while(!I2CReceivedDataIsAvailable(port));

        i2cbyte = I2CGetByte(gestic->io.I2cPort);
        result[writeIndex] = i2cbyte;
        writeIndex++;

        if(RcvCount == 0) {
            /* Set size if message fits into buffer */
            if(i2cbyte < sizeof(gestic->io.read_buffer))
                RcvCount = i2cbyte;
            else
                result = NULL;
        }

        /* In case of length == 0 or last byte (length == 1) send a NACK */
        if(RcvCount == 0 || RcvCount == 1)
            I2CAcknowledgeByte(port, FALSE);
        else
            I2CAcknowledgeByte(port, TRUE);

        while(!I2CAcknowledgeHasCompleted( gestic->io.I2cPort ));

        RcvCount--;
        if(RcvCount <= 0)
            break;
    }

    gestic->io.device(GestICDev_TsLine_Release);

    transfer_stop(gestic->io.I2cPort);
    
    if(result && size)
        *size = result[0];

    return result;
}