Hi,
I am interfacing the TCA9539 I2C based I/O Expander with LM4F120 and TM4C123 MCU. I would appreciate if you could share sample code using Stellarisware I2C APi to configure and use the I/O Expander.
Thanks for your time.
Regards,
Hemant
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.
Hi,
I am interfacing the TCA9539 I2C based I/O Expander with LM4F120 and TM4C123 MCU. I would appreciate if you could share sample code using Stellarisware I2C APi to configure and use the I/O Expander.
Thanks for your time.
Regards,
Hemant
Hello Hemant,
It would be better if you can start the thread with a code that you think will work, post it to the forum for others to review. With so many I2C slave device, the chance of someone using the exact same part, with TM4C/LM4F and seeing your post would be slim (I would happily retract my statement as I have been proven wrong at times).
The distinct advantage of doing so is others giving you valuable inputs that would help make your end application better and your code being a part of larger data base for others to use.
Regards
Amit
Hi Amit,
I am using the LM4F120 launchpad and TCA9539 I/O expander. The NTS0104PW level shifter is used between the two chips.
Here's my code...This is for LM4F120H5QR I@C initialization....
void i2c_init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinConfigure(GPIO_PB2_I2C0SCL);
GPIOPinConfigure(GPIO_PB3_I2C0SDA);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), false);
}
The following code should select and write the TCA9539...
void i2c_test(unsigned char ucSlaveAddr, tBoolean bReceive)
{
unsigned int a;
unsigned long t;
//
// Specify slave address
//
delay(10);
I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, ucSlaveAddr, bReceive);
//Select Configuration register 0
a=I2C_Config_Port0_RW;
delay(20);
//
// Place the character to be sent in the data register
//
I2CMasterDataPut(I2C0_MASTER_BASE, a);
//
// Initiate send of character from Master to Slave
//
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
//
delay(30);
t=I2CMasterErr(I2C0_MASTER_BASE);
while(I2CMasterBusBusy(I2C0_MASTER_BASE))
{
GPIOPinWrite(GPIO_PORTF_BASE,GREEN_LED,GREEN_LED);
}
//Set all I/O as output
delay(20);
a=0x00;
//I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, ucSlaveAddr, bReceive);
I2CMasterDataPut(I2C0_MASTER_BASE, a);
//
// Initiate send of character from Master to Slave
//
delay(30);
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
t=I2CMasterErr(I2C0_MASTER_BASE);
while(I2CMasterBusBusy(I2C0_MASTER_BASE))
{
t=I2CMasterErr(I2C0_MASTER_BASE);
GPIOPinWrite(GPIO_PORTF_BASE,BLUE_LED,BLUE_LED);
}
delay(50);
//Select Output port 0 Register
a=I2C_Output_Port0_RW;
I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, ucSlaveAddr, bReceive);
I2CMasterDataPut(I2C0_MASTER_BASE, a);
//
// Initiate send of character from Master to Slave
//
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
delay(30);
t=I2CMasterLineStateGet(I2C0_MASTER_BASE);
while(I2CMasterBusBusy(I2C0_MASTER_BASE))
{
GPIOPinWrite(GPIO_PORTF_BASE,RED_LED,RED_LED);
}
GPIOPinWrite(GPIO_PORTF_BASE,BLUE_LED|RED_LED|GREEN_LED,a);
// Set 4 LSB output pins high
a=0xF0;
delay(30);
//I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, ucSlaveAddr, bReceive);
I2CMasterDataPut(I2C0_MASTER_BASE, a);
//
// Initiate send of character from Master to Slave
//
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
delay(20);
t=I2CMasterLineStateGet(I2C0_MASTER_BASE);
while(I2CMasterBusBusy(I2C0_MASTER_BASE))
{
GPIOPinWrite(GPIO_PORTF_BASE,RED_LED,RED_LED);
}
GPIOPinWrite(GPIO_PORTF_BASE,BLUE_LED|RED_LED|GREEN_LED,a);
delay(50);
}
And this is the main function..
void main(void)
{
//****************************************************************
// set up system clock
//****************************************************************
SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|
SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
//i2c_init();
while(1)
{
i2c_test(EXP_0_Addr, EXP_WR); //EXP_0_Addr= 0x74, EXP_WR= 0x00.
}
}
This code does not make any changes on the TCA9539 Output port.
Hello Hemant,
Before commenting on the code, I want to make sure that you are using StellarisWare and not TivaWare?
Some basic points though irrespective of that
1. Why is i2c_init commented?
2. When sending the first byte "a", the function call for MCS
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
is not correct.
It must be
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
Regards
Amit
Hi Amit,
Sorry for the mistake. The I2C_init is not commented in my code. I was testing some other modules and had commented the I2C code.
And yes right now I am testing on the Stellariware LM4F.
Regards
Hello Hemant,
The Polling of Busy status of the I2C Master is not with API
I2CMasterBusBusy
But
I2CMasterBusy
The TCA9539 requires the bus transaction as SA+Command+Port0+Port1
In the code you have sent, the Command Byte is missing. Also when sending the command byte you must use I2C_MASTER_CMD_BURST_SEND_START and not the one posted earlier by me, Then send the two bytes for P0 with I2C_MASTER_CMD_BURST_SEND_CONT and when sending P1 I2C_MASTER_CMD_BURST_SEND_FINISH.
The TCA IO's are in Input Mode. So you need to first configure them as output for doing a data write.
After making the changes can you please post the updated code and if possible the snapshot of the I2C Physical lines from a scope or a logic analyzer
Regards
Amit
Amit,
Thanks for the response.
When I use the API I2CMasterBusy, it continuously gives Master Busy.
I will try the rest as you have suggested and get back to you. I would appreciate if you could share a sample code.
Regards
Hello Hemant,
I do not have a code for TCA9539, that I can readily share with you. You can refer to the master_slave_loopback.c in the following path for StellarisWare as a reference
C:\ti\stellarisware\examples\peripherals\i2c
Regards
Amit
While poster is using (lowly) LX4F his use of GPIOPinType() for both SCL & SDA is incorrect - is it not?
Instead, "GPIOPinTypeI2CSCL()" is more normal/customary for TM4C or predecessor LX4F. (No LM4Fs roam this planet...)
There may be more - this one jumped out - appears lost in the noise...