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.

Interface TCA9539 with LM4F and TM4C123 MCU

Other Parts Discussed in Thread: TCA9539

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...