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.

TMS320F28335: I2C Slave (holding SDAA and SCLA low)

Part Number: TMS320F28335
Other Parts Discussed in Thread: C2000WARE, CONTROLSUITE,

Issue while setting up the MCU as an I2C slave.  What I'm seeing is that the moment the I set IRS=1 within I2CMDR, the SDA and SCK lines are getting pulled to ground.  I'd expect them to be pulled up to 3.3v, since the device is a slave, that isn't communicating.  Is there something special that needs to be done when setting up as slave that I may be missing?

The following are the steps I'm taking

set Eallow

Enable Internal pullups on the I2C lines (tried disabling, as well)

Set the Mux for SCLA & SDAA

Set ASYNCHRONOUS Qual for the pins

Enable Peripheral Clock

Restore Eallow

Reset the I2C module.

Set the I2C module clock

Set our own address

Reset and enable the TX FIFO

Reset and enable the RX FIFO

set the interrupt handler for I2CINT2A

Set the I2C interrupts - disabled using FIFO mode

Clear the status flags.

remove the reset (IRS=1) and place bus into IDLE mode

  • Christopher,

    You are correct that the I2C should come up out of reset in "idle" mode where it is not in control of the bus, especially if it is in slave mode. When you enable the I2C (setting IRS = 1), do any of the status bits or interrupt flags get set? Can you possibly share your I2C Configuration code?

    Please take a look at the I2C example in C2000ware. this provides the necessary configuration settings for I2C to operate. Though it is set up for a Master, the remainder of the configuration is equivalent.

    Thanks,
    Mark
  • /* Initialize the I2C Slave peripheral */
    void F28335_I2C_InitSlave( uint8_t slave_addr, /*Ftn_Ptr_I2C_tx_t tx_fifo_callback,*/ Ftn_Ptr_I2C_rx_t rx_fifo_callback )
    {
    // Enable the I2C peripheral I/O pins and I2C clock.
    uint16_t prevEALLOW = CPU_SetEALLOW();
    // GPIO_32_33 (GPIO32, GPIO33)
    // Set GPIO32 & GPIO33 to disable internal pull-ups
    // bits 0 & 1
    PTR_GPIO_B_CTRL_REG->GPxPUDew |= 0x00000003;
    // clear GPIO32 & GPIO33 to enable internal pull-ups
    //PTR_GPIO_B_CTRL_REG->GPxPUDew &= ~0x00000003;

    // Set GPIO32 & GPIO33 for SCLA and SDAA
    // bits 0-4 (two for each)
    PTR_GPIO_B_CTRL_REG->GPxMUX1ew &= ~0x0000000F;
    PTR_GPIO_B_CTRL_REG->GPxMUX1ew |= 0x00000005;

    // Set GPIO32 & GPIO33 to ASYNCHRONOUS Qualification
    // bits 0-4 (two for each)
    PTR_GPIO_B_CTRL_REG->GPxQSEL1ew |= 0x0000000F;

    // Enable the peripheral clock
    PCLKCR0ew |= I2CAENCLK;

    CPU_RestoreEALLOW(prevEALLOW);

    // Reset the I2C module.
    // Note: The reset must be held (IRS=0) until configuration is complete.
    I2CMDR = I2C_HOLD_RESET;

    // Set the I2C module clock.
    I2CPSC = 14;

    // Set clock high and low pulse widths.
    I2CCLKL = 7;
    I2CCLKH = 8;

    // Set our own address
    I2COAR = slave_addr;

    // Reset and enable the TX FIFO. Use its interrupt
    I2CFFTX = TXFFINTCLR;
    I2CFFTX = I2CFFEN /*| TXFFRST | TXFFIENA | TXFFIL_TRIP*/;

    // Reset and enable the RX FIFO.
    I2CFFRX = RXFFINTCLR;
    I2CFFRX = RXFFRST | RXFFIENA | RXFFIL_TRIP;

    // set the interrupt handler for I2CINT2A
    PIE::SetVector_NoOS(I2CINT2_VECTOR, I2CINT2_GROUP, I2CINT2_BIT, &F28335_I2C_FIFO_ISR );
    /*tx_callback = tx_fifo_callback;*/
    rx_callback = rx_fifo_callback;

    // Set the I2C interrupts - disabled using FIFO mode.
    I2CIER = 0;

    // Clear the status flags.
    I2CSTR = I2CSTR_CLEAR_FLAGS;

    // Finished, remove the reset (IRS=1) and place bus into IDLE mode.
    I2CMDR = I2C_BUS_IDLE;
  • The following is a screen capture prior to executing the last I2CMDR line

    The following is a screen cap after stepping over the I2CMDR line

  • It looks like you have the Digital Loopback enabled on the I2C (bit 6 of I2CMDR). Since you are connected to an external device, and a slave, this does not make sense. I don't believe that this is the root of your issue, but it will cause some problems later for sure.

    Can you try out the example in C2000Ware? you can just change the configuration to slave receiver in stead of master transmitter. You can compare your configuration to that example.

    -Mark
  • I2CMDR is set to 0x4020.  This has bits 14 and 05 (0 based) set.  These are the FREE bit and the IRS bit; which should be how to enable it.

    I went through the ControlSUITE.  for the 28335 I didn't see any I2C Slave examples, just master.  However, my initialization is pretty in-line with what was done in there, with exception that I didn't turn on the master bit.  I did notice that the controlSUITE does enable TX\RX FIFO after taking the I2c out of reset.  I wouldn't think that that would be the culprit though.

  • Christopher,

    Thanks, yeah that was a mistake on my part referring to bit 6...

    Can you possibly zip up and share your project? I have not ever heard of this happening before and this is a very old device, so I am going to say that this is likely related to something in your setup but would like to try this out myself.

    Do you have another device connected to the I2C bus? Are you using custom hardware?

    Thanks,
    Mark
  • Probably can't sure the zip, but the Init code is up there.  its right on enabling that the issue arises.  I have at times seen the slave transmitter bit show-up in the Status register, which is unexpected, considering it doesn't hit a breakpoint in the function that would have received data prior to setting this slave transmitter bit.  I'm starting to fear there are some issues with the chip when configured as a slave that are unknown.  Perhaps its a unique scenario that I'm encountering.

    The Master I2C is just another TMS320F28335 board.  One's a master, the other a slave.

  • Thanks for the additional info.

    I will try to carve out some time today or tomorrow to look into this on some HW.

    -Mark
  • Actually I see the issue with just connecting a scope to the slave, without the master even in the loop, yet.  When I put the master in the loop odd things started occurring, my guess is its due to the fact that the slave was pulling the lines low indefinitely.

  • Thanks. I wasn't able to get to this today either. hopefully by Monday I can get some hands-on testing

    -Mark
  • Hi Christopher,

    It has been a hectic week here. I will for sure have some testing done for tomorrow, I have the boards sitting next to me and some time to dig in.

    -Mark
  • Christopher,

    I have exactly replicated the pre/post IRS enable register settings on the bench and do not see the behavior that you are. Is there an external pullup on the line? What is the value of your pullup.
    When I force one of the lines to 0, I do see the Bus Busy bit get set. To me it looks like there might be something already pulling the line low.
    Can you perhaps share a scope image of the i2c signals when you set the IRS? configure another GPIO as a trigger and toggle it directly before you set IRS to 1. I am curious to see if other things may be going on on the trace.

    Have you done any other debug steps yourself?


    Thanks,
    Mark
  • Christopher,

    I whipped up a quick simple Master/slave external loopback example for F28379D, the C file is linked here: e2e.ti.com/.../2533996

    This code does Master TX, Master RX, Slave RX, and Slave TX. it is very simple, and does not use interrupts or error checking, but is a good base to start from.

    -Mark