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.

TM4C123GH6PM: TM4C123

Part Number: TM4C123GH6PM

Hello everyone, I have problem with I2C communication from my Lounchpad TM4C123gxl to proximity sensor ADPS9960. I init MCU, peripheral, and when try to read from sensor register I get 0xFF, When I try to read from Arduino board to the same sensor, code works good. So I am apparently doing something wrong and I don't know what. I connected pullups in SCL and SDA line, (10k. )Here is my I2C code : 

void main(void) {

	SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHZ);
	Configuration();

	while(1)
	{
           Read_Inputs();
	}
}

void I2C_Configuration()
{
	SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
	SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	GPIOPinConfigure(GPIO_PB2_I2C0SCL);
	GPIOPinConfigure(GPIO_PB3_I2C0SDA);
	GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
	GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
	I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
	HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000;
}

uint8_t I2CWriteDataByte(uint8_t slave_addr, uint8_t dev_reg, uint8_t data)
{
	I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);

	I2CMasterDataPut(I2C0_BASE, dev_reg);

	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

	while(I2CMasterBusy(I2C0_BASE));

	I2CMasterDataPut(I2C0_BASE, data);

	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);

	while ( I2CMasterBusy(I2C0_BASE) );

	return 1;
}

uint8_t I2CReadDataByte(uint8_t slave_addr, uint8_t slave_reg)
{
	I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);

	I2CMasterDataPut(I2C0_BASE, slave_reg);

	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

	while(I2CMasterBusy(I2C0_BASE));

	I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true);

	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

	while(I2CMasterBusy(I2C0_BASE));

	return(I2CMasterDataGet(I2C0_BASE));
}

  • I don't see the error in the snippets of code you provided. You choice of parameters for SysCtlClockSet() seems odd. What frequency were you trying to achieve? Have you looked at the I2C signals with a scope? I have attached an example that uses I2C0 as a master and loops to I2C2 as a slave. You have to connect the two ports and add pull-up resistors externally. Use "File", "Import", "Code Composer Studio -> CCS Projects" then "Select archive file" to import the project attached.

    /cfs-file/__key/communityserver-discussions-components-files/908/0131.I2C_5F00_master2slave.zip

  • Just as vendor's 'Bob' noted - that 'SysCtlClockSet()' is (beyond) odd - it is simply wrong!
    Here's why:  Poster's 'SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL' proves ILLEGAL!    It sets the System Clock to the FULL PLL Frequency - which of course - is improper!

    That error should be corrected first - and only then - as (long) noted here - 'Scope Monitoring' of EACH of the I2C lines should be presented.     I2C troubleshooting - minus those clear images - is laborious & needlessly inefficient.      (it (may) make sense to consider the 'effort/time demand' placed upon hapless helper crüe - when such (proper) scope caps - are withheld...)

    Note too - poster has presented the 'slave address' - in a form 'uncheckable'  (i.e. 'slave_addr') - to those here.     As the Slave Address undergoes a 'shift-left' (to accommodate the I2C's R/W bit) an incorrect 'Slave Address' rises 'high' upon the list of user mistakes...    And no one here - can detect and/or comment - upon user's choice of 'slave address' - when it is hidden!

  • Thank You both for quick answer, seems that lot of the things were wrong in my code while I was searching for one error I make new one. That was case with system clock.
    Seems that actually besides that I used wrong address, I used device ID instead of address provided from vendor. My mistake for not reading sensor datasheet thoroughly. Sorry for taking your time. Reagrds!
  • Thank you - note that it has, 'Long been observed' that 'Haste makes Waste' - and such proves overwhelmingly true - in our MCU field.

    Your smart enough to, 'Read, Understand & Comply' with the directives provided by (both) your MCU's I2C Data Section as well as - your sensor data.    Insure the use of external pull-up Rs - and keep the distance between 'Sensor and MCU' - as 'Short & Direct'  (i.e. under 0.5 meter) as possible.      (I2C was not intended as a 'distance capable' serial bus.)

    If a scope is 'not available' - it is possible to employ (efficient - low current) Leds - to monitor (each) of the two, I2C signal lines.    (you must (greatly) current limit those Leds - while preventing their presence - from 'excessively loading and/or intruding' - upon the I2C signal lines.)     (employing a voltage comparator or op-amp - to monitor each signal line - AND to use its (buffered) output to drive the LED - proves safest!)

    As always - slowest (serial device) communication speed is advised when starting.     (gives your implementation the 'best chance' of success!)

    Your sensor IS complex - should you encounter (on-going) difficulties - your use of the 'smallest capacity, I2C based EEprom, has long proven a superior means - to 'most quickly & easily' - build a pathway toward your 'I2C Success.'     (that's simply pure 'KISS' - which always dictates 'Simplicity FIRST (and ONLY LATER) after the 'basics' have been verified) - introduce the complex!    (your advanced sensor)