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.

Determine if port is initialized for I2C

I'm trying to write an I2C device scanning utility that will look over all the I2C busses and see which addresses will acknowledge a write request. I have the code working on busses I know are properly initialized for I2C. What I'd like to do is take my I2CBusScan(uint8_t ui8PortNum); function and create a new function I2CAllBusScan(); that calls I2CBusScan(i=0; i<4; i++);

the issue I'm running into is that I'm not sure exactly how to determine if I've initialized an I2C port or not, without directly keeping track of initialized ports.

specifically trying to write a function

bool I2CBusEnabled(uint8_t ui8PortNum);

this function takes a number 0-3 and can access predefined I2C port data such as i2c_busses[ui8PortNum].i2cBase (i.e. i2c_busses[0].i2cBase == I2C0_BASE)

I've added my i2c_busses definitions at the end of the post

I could only find one 'get' function that helped

GPIODirModeGet(i2c_busses[ui8PortNum].gpioPortBase,i2c_busses[ui8PortNum].gpioPinSCL);

This appears to return 0 before the SCL pin is enabled and 2 after.

I imagine there is a register, or perhaps several, I could read and do bit comparisons on to determine the function.

something loosely along the lines of 

if (HWREG(I2C3_BASE) == 0xSOMEHEX) then ENABLED else DISABLED

I've been trying to read through gpio.c and i2c.c to get clues on which bits are being set while I'm initializing an I2C bus but I'm just not familiar enough with some of the concepts needed to figure out exactly what's going on in a function like GPIOPinConfigure when it writes

HWREG(ui32Base + GPIO_O_PCTL) = ((HWREG(ui32Base + GPIO_O_PCTL) & ~(0xf << ui32Shift)) | ((ui32PinConfig & 0xf) << ui32Shift));


 

#in header
typedef struct {
	uint32_t sysctlPeriphI2C;
	uint32_t sysctlPeriphGPIO;
	uint32_t gpioPinISCL;
	uint32_t gpioPinISDA;
	uint32_t gpioPortBase;
	uint32_t gpioPinSCL;
	uint32_t gpioPinSDA;
	uint32_t gpioI2CBase;
} i2c_bus;

#in source
const i2c_bus i2c_busses[4] = {
	// I2C Bus Mappings for the TM4C123G LaunchPad
	{SYSCTL_PERIPH_I2C0,
		SYSCTL_PERIPH_GPIOB,
		GPIO_PB2_I2C0SCL,
		GPIO_PB3_I2C0SDA,
		GPIO_PORTB_BASE,
		GPIO_PIN_2,
		GPIO_PIN_3,
		I2C0_BASE}, // I2C0
	{SYSCTL_PERIPH_I2C1,
		SYSCTL_PERIPH_GPIOA,
		GPIO_PA6_I2C1SCL,
		GPIO_PA7_I2C1SDA,
		GPIO_PORTA_BASE,
		GPIO_PIN_6,
		GPIO_PIN_7,
		I2C1_BASE}, // I2C1
	{SYSCTL_PERIPH_I2C2,
		SYSCTL_PERIPH_GPIOE,
		GPIO_PE4_I2C2SCL,
		GPIO_PE5_I2C2SDA,
		GPIO_PORTE_BASE,
		GPIO_PIN_4,
		GPIO_PIN_5,
		I2C2_BASE}, // I2C2
	{SYSCTL_PERIPH_I2C3,
		SYSCTL_PERIPH_GPIOD,
		GPIO_PD0_I2C3SCL,
		GPIO_PD1_I2C3SDA,
		GPIO_PORTD_BASE,
		GPIO_PIN_0,
		GPIO_PIN_1,
		I2C3_BASE} // I2C3
};

  • Hello Jamie,

    The Pin's as you would have read by now have muxed functions. To enable a GPIO to be used for peripheral requires two set of bit(s) to be set

    1. AFSEL which allows the function to be used either for GPIO or set of Peripherals

    2. PCTL which allows the function on the Pin to be used between different Peripherals.

    Regards

    Amit

  • While there is some value in, "knowing/confirming" that various I2C Modules have been initialized - could not that be more easily achieved via simple, manual, "Or'ing" into a reserved/safe SRAM location?  This could be the final code entry for each such I2C initialization.  (and could employ an assert to align each numbered I2C module with its masked SRAM target bit)

    Working often with multi-drop I2C - in varied, "ISM" applications - we find a far greater need to be the confirmation - (of both the presence and signaling capability) of each/every I2C device - "attached/resident to that I2C bus."

    Indeed initialization is important - but such, "Challenge/Response" method (described just above) has long been proven to be, "Gold Standard."   (i.e. provides far fuller, functional test - exercising I2C originator, remote and that specific, I2C circuit path/components.)