/** * 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); }
/* 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; }
//============================================================================== 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; } }
/** * @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; }
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; }
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; }
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; }
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; } }
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; }
//------------------------------------------------------------------------------ // 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); }
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); }
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; } }
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; }
//------------------------------------------------------------------------------ // 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); }
/************************************************************************************************** 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; }
/************************************************************************************************** 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; }