Ejemplo n.º 1
0
void readEeprom(void){
    BOOL success = FALSE;
    int index;

    do {
        if(!I2C_startTransfer(THERMAL_I2C_ID, FALSE)){
            #ifdef DEBUG
            printf("FAILED initial transfer!\n");
            #endif
            break;
        }
        // Transmit the slave's address to notify it
        if (!I2C_sendData(THERMAL_I2C_ID,EEPROM_WRITE_ADDRESS))
            break;

        // Tranmit the read address module
        if(!I2C_sendData(THERMAL_I2C_ID,EEPROM_READ_COMMAND)){
            #ifdef DEBUG
            printf("Error: Sent byte was not acknowledged\n");
            #endif
            break;
        }

        // Send a Repeated Started condition
        if(!I2C_startTransfer(THERMAL_I2C_ID,TRUE)){
            #ifdef DEBUG
                printf("FAILED Repeated start!\n");
            #endif
            break;
        }
        // Transmit the address with the READ bit set
        if (!I2C_sendData(THERMAL_I2C_ID,EEPROM_READ_ADDRESS))
            break;

        // Read the I2C bus most significant byte and send an acknowledge bit
        for(index = 0; index <=0xFF; index++){
            eepromData[index] = I2C_getData(THERMAL_I2C_ID);
            if(index < 0xFF)
                I2CAcknowledgeByte(I2C1, TRUE);
            else
                I2CAcknowledgeByte(I2C1, FALSE);
            while(!I2CAcknowledgeHasCompleted(I2C1));
        }
        success = TRUE;
    } while(0);
    // Send the stop bit to finish the transfer
    I2C_stopTransfer(THERMAL_I2C_ID);
    if(!success){
        printf("Data transfer unsuccessful.\n");
        return;
    }
    // Stop transfer twice?
    I2C_stopTransfer(THERMAL_I2C_ID);
    int Index;
    for(Index = 0; Index <=255; Index++){
        while(!Serial_isTransmitEmpty());
        //printf("EEPROM %x / %d: %x\n", Index, Index, eepromData[Index]);
    }
     
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
void readPixelValue(void){
    int Index = 0;
    BOOL Success = TRUE;
    UINT8 pixelMSB, pixelLSB;
    if(!I2C_startTransfer(THERMAL_I2C_ID, FALSE)){
        printf("FAILED initial transfer!\n");
        Success = FALSE;
    }
// Transmit the slave's address to notify it
    if(!I2C_sendData(THERMAL_I2C_ID,CAMERA_WRITE_ADDRESS)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,CAMERA_READ_COMMAND)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x00)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x01)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x40)){
        Success = FALSE;
    }
    if(Success){
    // Send a Repeated Started condition
        if(!I2C_startTransfer(THERMAL_I2C_ID,TRUE)){
            printf("FAILED Repeated start!\n");
            Success = FALSE;
        }
    // Transmit the address with the READ bit set
        if (!I2C_sendData(THERMAL_I2C_ID,CAMERA_READ_ADDRESS)){
            Success = FALSE;
        }
    }
    if(Success){
    // Read the I2C bus most significan byte and send an acknowledge bit
        for(Index = 0; Index <=63; Index++){
            pixelLSB = I2C_getData(THERMAL_I2C_ID);
            I2CAcknowledgeByte(I2C1, TRUE);
            while(!I2CAcknowledgeHasCompleted(THERMAL_I2C_ID));
            pixelMSB = I2C_getData(THERMAL_I2C_ID);
            I2CAcknowledgeByte(I2C1, TRUE);
            while(!I2CAcknowledgeHasCompleted(THERMAL_I2C_ID));
            pixelData[Index] = (pixelMSB << 8) + pixelLSB;
            if(pixelData[Index] > 32767)
                pixelData[Index] = pixelData[Index] - 65536;
        }
    }
    I2C_stopTransfer(THERMAL_I2C_ID);
}
Ejemplo n.º 5
0
void readCPixelValue(void){
    BOOL Success = TRUE;
    UINT8 CPixelMSB, CPixelLSB;
    if(!I2C_startTransfer(THERMAL_I2C_ID, FALSE)){
        printf("FAILED initial transfer!\n");
        Success = FALSE;
    }
// Transmit the slave's address to notify it
    if(!I2C_sendData(THERMAL_I2C_ID,CAMERA_WRITE_ADDRESS)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,CAMERA_READ_COMMAND)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x91)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x00)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x01)){
        Success = FALSE;
    }
    if(Success){
    // Send a Repeated Started condition
        if(!I2C_startTransfer(THERMAL_I2C_ID,TRUE)){
            printf("FAILED Repeated start!\n");
            Success = FALSE;
        }
    // Transmit the address with the READ bit set
        if (!I2C_sendData(THERMAL_I2C_ID,CAMERA_READ_ADDRESS)){
            Success = FALSE;
        }
    }
    if(Success){
    // Read the I2C bus most significan byte and send an acknowledge bit
        CPixelLSB = I2C_getData(THERMAL_I2C_ID);
        I2CAcknowledgeByte(I2C1, TRUE);
        while(!I2CAcknowledgeHasCompleted(THERMAL_I2C_ID));
        CPixelMSB = I2C_getData(THERMAL_I2C_ID);
        I2CAcknowledgeByte(I2C1, TRUE);
        while(!I2CAcknowledgeHasCompleted(THERMAL_I2C_ID));
        CPixel = (CPixelMSB << 8) + CPixelLSB;
    }
    I2C_stopTransfer(THERMAL_I2C_ID);
    if(CPixel > 32767){
        CPixel = CPixel - 65536;
    }
}
Ejemplo n.º 6
0
void readChipTemp(void){
    BOOL Success = TRUE;
    UINT8 tempMSB, tempLSB;
    if(!I2C_startTransfer(THERMAL_I2C_ID, FALSE)){
        printf("FAILED initial transfer!\n");
        Success = FALSE;
    }
// Transmit the slave's address to notify it
    if(!I2C_sendData(THERMAL_I2C_ID,CAMERA_WRITE_ADDRESS)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,CAMERA_READ_COMMAND)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x90)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x00)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x01)){
        Success = FALSE;
    }
    if(Success){
    // Send a Repeated Started condition
        if(!I2C_startTransfer(THERMAL_I2C_ID,TRUE)){
            printf("FAILED Repeated start!\n");
            Success = FALSE;
        }
    // Transmit the address with the READ bit set
        if (!I2C_sendData(THERMAL_I2C_ID,CAMERA_READ_ADDRESS)){
            Success = FALSE;
        }
    }
    if(Success){
    // Read the I2C bus most significan byte and send an acknowledge bit
        tempLSB = I2C_getData(THERMAL_I2C_ID);
        I2CAcknowledgeByte(THERMAL_I2C_ID, TRUE);
        while(!I2CAcknowledgeHasCompleted(THERMAL_I2C_ID));
        tempMSB = I2C_getData(THERMAL_I2C_ID);
        I2CAcknowledgeByte(THERMAL_I2C_ID, TRUE);
        while(!I2CAcknowledgeHasCompleted(THERMAL_I2C_ID));
        }
    I2C_stopTransfer(THERMAL_I2C_ID);
        rawTemp = (tempMSB << 8) + tempLSB;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
void portableCommonNackI2C(I2cBusConnection* i2cBusConnection) {
    I2cBus* i2cBus = i2cBusConnection->i2cBus;
    if (i2cBus == NULL) {
        NotAckI2C1();
    }
    else {
        I2C_MODULE i2cModule = getI2C_MODULE(i2cBus->port);
        I2CAcknowledgeByte(i2cModule, false);
    }
}
Ejemplo n.º 9
0
bool i2c_acknowledge(bool ack)
{
	state = I2C_STATE_ACKNOWLEDGE;

	I2CAcknowledgeByte(I2C1, ack);

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

	return TRUE;
}
Ejemplo n.º 10
0
/*
 Reads a value from a ADXL345 register and returns it
 */
unsigned int accelReadReg(const Accel *a, int reg){
    int I2C = a->I2C;
    sendStart(I2C);                 // start transaction
    sendByte(I2C, a->write);        // write accel device
    sendByte(I2C, reg);             // specify device register
    repeatStart(I2C);
    sendByte(I2C, a->read);         // read accel device
    unsigned int d = readByte(I2C);          // grab data
    I2CAcknowledgeByte(I2C, 0);     // Send nack
    while(!I2CAcknowledgeHasCompleted(I2C));
    I2CStop(I2C);                   // end transaction
    return d;
}
Ejemplo n.º 11
0
void readConfigReg(void){
    BOOL Success = TRUE;
    UINT8 configMSB, configLSB;
    if(!I2C_startTransfer(THERMAL_I2C_ID, FALSE)){
        printf("FAILED initial transfer!\n");
        Success = FALSE;
    }
// Transmit the slave's address to notify it
    if(!I2C_sendData(THERMAL_I2C_ID,CAMERA_WRITE_ADDRESS)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,CAMERA_READ_COMMAND)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x92)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x00)){
        Success = FALSE;
    }
// Tranmit the read address module
    if(!I2C_sendData(THERMAL_I2C_ID,0x01)){
        Success = FALSE;
    }
    if(Success){
    // Send a Repeated Started condition
        if(!I2C_startTransfer(THERMAL_I2C_ID,TRUE)){
            printf("FAILED Repeated start!\n");
            Success = FALSE;
        }
    // Transmit the address with the READ bit set
        if (!I2C_sendData(THERMAL_I2C_ID,CAMERA_READ_ADDRESS)){
            Success = FALSE;
        }
    }
    if(Success){
    // Read the I2C bus most significan byte and send an acknowledge bit
        configLSB = I2C_getData(THERMAL_I2C_ID);
        I2CAcknowledgeByte(I2C1, TRUE);
        while(!I2CAcknowledgeHasCompleted(THERMAL_I2C_ID));
        configMSB = I2C_getData(THERMAL_I2C_ID);
        }
    I2C_stopTransfer(THERMAL_I2C_ID);
        //while(!IsTransmitEmpty());
        //printf("Config Data %x %x\n", configMSB, configLSB);
}
Ejemplo n.º 12
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;
	}
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
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;
    }
}
Ejemplo n.º 15
0
/**
 * Invokes an I2C acknowledge
 * 
 */
void I2C_Ack()
{
    I2CAcknowledgeByte(I2C1, TRUE);
    while (!I2CAcknowledgeHasCompleted(I2C1));
}
Ejemplo n.º 16
0
/**
 * Invokes an I2C no acknowledge
 * 
 */
void I2C_Nack()
{
    I2CAcknowledgeByte(I2C1, FALSE);
    while (!I2CAcknowledgeHasCompleted(I2C1));
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
Archivo: I2C.c Proyecto: sdajani/sdp
void I2C_acknowledgeRead(I2C_MODULE I2C_ID, BOOL ack) {
    I2CAcknowledgeByte(I2C_ID, ack);
}
Ejemplo n.º 19
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;
}