This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BNO055 I2C TM4C123GXL

Hello,

I am currently working on I2C communications using TIVA TM4C123 and BNO055. I am having some issues reading data from BNO055, wondering if anyone can take a look at my read and  write functions to see what i am doing wrong. Thanks 

void InitI2C0(void)
{
    //enable I2C module 0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

    //reset module
    SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);

    //enable GPIO peripheral that contains I2C 0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    // Configure the pin muxing for I2C1 functions on port B2 and B3.
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);

    // Select the I2C function for these pins.
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

    // Enable and initialize the I2C0 master module.  Use the system clock for
    // the I2C0 module.  The last parameter sets the I2C data transfer rate.
    // If false the data rate is set to 100kbps and if true the data rate will
    // be set to 400kbps.
    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);

    //clear I2C FIFOs
    	HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000;
}

s8 bno_write(u8 dev_address, u8 reg_address, u8 *reg_data, u8 count)
{
	//specify that we want to communicate to device address with an intended write to bus
	I2CMasterSlaveAddrSet(I2C0_BASE, dev_address, false);

	//register to be read
	I2CMasterDataPut(I2C0_BASE, reg_address);

	//send control byte and register address byte to slave device
	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

	//wait for MCU to finish transaction
	while(I2CMasterBusy(I2C0_BASE));
	
	I2CMasterSlaveAddrSet(I2C0_BASE, dev_address, true);

	//specify data to be written to the above mentioned reg_data
	I2CMasterDataPut(I2C0_BASE, *reg_data);

	//wait while checking for MCU to complete the transaction
	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);

	//wait for MCU & device to complete transaction
	while(I2CMasterBusy(I2C0_BASE));	//more magic

	return I2CMasterErr(I2C0_BASE);

}

//read specified register on slave device
s8 bno_read(u8 dev_address, u8 reg_address, u8 *reg_data, u8 count)
{
	int x;
if(count==1){
	//specify that we want to communicate to device address with an intended write to bus
    I2CMasterSlaveAddrSet(I2C0_BASE, dev_address, false);

    //specify register to be read
    I2CMasterDataPut(I2C0_BASE, reg_address);

    //send control byte and register address byte to slave device
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));

    //specify that we are going to read from slave device
    I2CMasterSlaveAddrSet(I2C0_BASE, dev_address, true);

    //send control byte and read from the register from the MCU
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));
}

else{
	for(x=0; x < count ; x++)
	{
		//specify that we want to communicate to device address with an intended write to bus
	    I2CMasterSlaveAddrSet(I2C0_BASE, dev_address, false);

	    //specify register to be read
	    I2CMasterDataPut(I2C0_BASE, reg_address);

	    //send control byte and register address byte to slave device
	    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

	    //wait for MCU to finish transaction
	    while(I2CMasterBusy(I2C0_BASE));

	    //specify that we are going to read from slave device
	    I2CMasterSlaveAddrSet(I2C0_BASE, dev_address, true);

	    //send control byte and read from the register from the MCU
	    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

	    //wait for MCU to finish transaction
	    while(I2CMasterBusy(I2C0_BASE));

	    reg_address++;

	}

}
	return( I2CMasterDataGet(I2C0_BASE));
}

  • Hello Eric

    On the TM4C123 device, there is no FIFOCTL register.

    Secondly, during the read phase are you trying to perform a Write-Repeated Start-Read cycle to access the data?
  • Hello Amit

    I am using the BNO055 API from Bosch. I am trying to link my read and write functions to the API communication pointers. What i am trying to do with my read functions is read multiple bytes and store them in the data array that gets passed into the read function.  It has to be smart enough to save multiple bytes of data, starting at the register address and increment from there.

  • Hello Eric

    I see in the code that the function I2CMasterDataGet(I2C0_BASE) is being called only once. This will only read 1 byte of data. Also on the TM4C123x there is NO FIFO. So you have to read the data out into an array and then use the array for any further data processing. Your code does not do anything like that.
  • Greetings Amit,

    Once again your skill & commitment rescue posters - good that.

    Now, poster's code:

        //clear I2C FIFOs
            HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000;
    originated from somewhere.    Might this point to the need to better segregate TM4C129 code examples from TM4C123?   This situation may not be unique to (just) this poster...
  • Hello cb1

    The use of FIFOCTL is not even mentioned in the TM4C123x datasheet and that this register does not exist physically on the TM4C123x device family. Adding the register access to override everything else seems to be a discrepancy in the code (chances are someone else added the line) to meet the requirements of getting "all register data for a one time processing effort", which also seems to be incomplete with a single read of the data register.
  • Hi Amit,

    Might you confirm if Register "FIFOCTL" appears w/in TM4C129 MCU & is described w/in that MCU's manual?

    Similar issues befell (past) LM3S users when LX4F arrived. (early adopters "lusted for" new features w/in LX4F - which were NOT included on earlier LM3S - to their disappointment)

    Proper segregation of data - by MCU class - seems indicated...
  • Hello cb1

    Yes. And the I2C application note also makes explicit note of the same.
  • Amit Ashara said:
    the I2C application note also makes explicit note of the same.

    Yet - poster (completely) missed that!

    Bold notifications - in multiple (predictable) places - may serve to better prevent such client-user mistakes...

  • The arrays are created from within the API.
  • Hello Eric,

    But for the entire for loop there is only one I2CMasterDataGet. So if the "count" is more than 1, then it will try to read multiple bytes and return only a single byte. This is not a correct method. Are you using the count variable as 1 or more than 1?
  • Hello Amit,

    Yes i do see that it will only return a single byte, I will adjust my code. The read function "count" is always one but for the write function "count" can be more then one depending on the API function used.
  • Poster should be mindful that if he (borrowed) one "Register/Feature" from the 129 MCU - more (still) may be lurking...
  • Hello Eric

    In the read function, what is being done is a Write and Read operation with a STOP bit. Normally what I have seen is some devices require a Repeated Start and not a STOP condition. You would need to replace the condition

    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

    with

    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    The same applies for the more than 1 count and in this case you would need to read the data into an array.