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.

MSP432P401R: I2C not working after changing eUSCI_B pins via PMAP

Part Number: MSP432P401R

Due to some resource constraints, we have several distinct I2C buses that need to share an eUSCI_B peripheral. They do not need to be in use simultaneously so I expected it would be no problem:

1. Use the initial I2C bus setup

2. Assert UCSWRST=1 via I2C_disableModule

3. Reconfigure the pins (turn old pins SEL=0 via GPIO_setAsInputPin, set PMAP for new pins, turn new pins SEL=1 via GPIO_setAsPeripheralModuleFunctionInputPin)

4. Re-enable RX/TX interrupts with I2C_enableInterrupt

5. Call I2C_enableModule and use the alternate I2C bus

However, what I am seeing is that after I do these steps, when I start a transfer the eUSCI_B just toggles the SDA/SCL pins constantly until I reset the CPU, none of the normal interrupts fire. [Clarification: none of the normal/typical I2C interrupts like TX/RX for this UCB get triggered, normal systick and other stuff does proceed!] My logic analyzer shows it as just constant start conditions (not a "repeated start" just keeps dropping SDA low while SCL is high) and it never sends the target address.

After the code calls I2C_masterSendStart, would prevent the eUSCI_B from sending the address in I2CSA? Is there something more than UCSWRST that I need to set before adjusting which pins are used via PMAP?

  • This sounds suspiciously similar to this other case:

    e2e.ti.com/.../3370649

    In that thread, the user was trying to use the two different UCB3 pin pairs, switching between them using (only) the PSELs. But in that case and yours (a) the physical pins were switched after using the I2C and (b) the symptom was (usually) continuous Start conditions, as though the I2C bus monitor wasn't seeing the transitions.

    In the other thread, the user found a different way to do things, and I don't think the phenomenon was ever explained.

  • Thanks, that does ± match what I'm seeing. I'm working through the thread now and trying to figure out if there's a similar solution available in my case. Too bad this didn't make it's way into an official errata :-/

  • Fortunately on this board I have external control of the pullup on each I2C bus which made it a bit cleaner to workaround.

    I didn't test extensively but what it seemed like is:

    * if I switch the PMAP with both buses (i.e. both the "old" and the "new" sets of pins) left high, I get the square waves using I2C on the "new" set.

    * if I switch the PMAP with both buses left low, I just get a flatline using I2C on the "new" set. [Note that I didn't test this combination thoroughly — ymmv]

    * if I switch the PMAP with the "old" bus low, and the "new" bus high the I2C works on the new pins!

    So in terms of a more complete sequence here is a combination that works for me:

    1. Have I2C configured for "Bus A", which is pulled up

    2. Power down "Bus A" (starts draining through a chip that gets its power from the same rail as the I2C buss pull-ups)

    3. Power up "Bus B" (pulls up quickly)

    4. [in my case I wait ~250msecs here for "Bus A" to finish draining to near 0V, but ideally I would pull it down quickly via GPIO, or determine the "logical 0" cutoff point more aggressively…]

    5. I2C_disableModule on the shared eUSCI (UCSWRST=1)

    6. GPIO_setAsInputPin on the SDA and CLK pins of "Bus A" (SEL=0)

    7. Set up PMAP for the two "Bus B" pins

    8. GPIO_setAsPeripheralModuleFuntionInputPin on the two "Bus B" pins

    9. Re-enable interrupts with I2C_enableInterrupt

    10. I2C_enableModule (UCSWRST=0)

    At this point the eUSCI behaves normally but now talking with "Bus B" instead of "Bus A". Skipping step 2 causes the continuous square waves, and delaying step 3 might also get the eUSCI stuck but in a quieter way.