K32L2B3 I2C SCL appears to as push-pull instead of open-drain

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K32L2B3 I2C SCL appears to as push-pull instead of open-drain

Jump to solution
1,151 Views
aberger
Contributor V

I am using the FRDM-K32L2B3 as master to communicate with a target slave I2C device. The target device needs to be able to hold the SCL line low for clock stretching. However, it appears that the K32L2B3 SCL line is being driven as push-pull: both the rising and falling edges of the SCL waveform are fast, in contrast to the slow rising edges on the SDA line (which indicate weaker pull-up action).

scope_14.png

(SCL on yellow CH1, SDA on green CH2)

I have 10k resistors on both SCL and SDA. Below is the pin configuration.

const port_pin_config_t portc1_pin44_config = {/* Internal pull-up resistor is enabled */
kPORT_PullUp,
/* Slow slew rate is configured */
kPORT_SlowSlewRate,
/* Passive filter is disabled */
kPORT_PassiveFilterDisable,
/* Low drive strength is configured */
kPORT_LowDriveStrength,
/* Pin is configured as I2C1_SCL */
kPORT_MuxAlt2};
/* PORTC1 (pin 44) is configured as I2C1_SCL */
PORT_SetPinConfig(PORTC, 1U, &portc1_pin44_config);

const port_pin_config_t portc2_pin45_config = {/* Internal pull-up resistor is enabled */
kPORT_PullUp,
/* Slow slew rate is configured */
kPORT_SlowSlewRate,
/* Passive filter is disabled */
kPORT_PassiveFilterDisable,
/* Low drive strength is configured */
kPORT_LowDriveStrength,
/* Pin is configured as I2C1_SDA */
kPORT_MuxAlt2};
/* PORTC2 (pin 45) is configured as I2C1_SDA */
PORT_SetPinConfig(PORTC, 2U, &portc2_pin45_config);

 

The Reference Manual states "IIC signals are automatically enabled for open
drain when selected." However, my scope trace seems to show this is not the case. Am I missing an open-drain pin setting or I2C setting that permits slave clock stretching when the K32 is used as the I2C master?

0 Kudos
Reply
1 Solution
676 Views
aberger
Contributor V

I figured out the issue with pin 44. I am trying to use pin 44 as I2C1_SCL. A close look at the FRDM-K32L2B3 schematic shows that this pin is connected via 0 Ω resistor R24 to pin 31 of U7 (the on-board MK20DX128 that provides the OpenSDA interface for debugging the K32). 

I don't know what this connection is providing, as it doesn't appear necessary for debug or flashing of the target MCU. (It is also strangely labeled as off-sheet connector `PTC1_SDA`, even though it is not used as an SDA line).

Removing the 0 Ω resistor permits pin 44 to operate as an open-drain SCL for I2C1 as expected.

My apologies for the wild goose chase on this issue. However, it does seem that there should be some documentation regarding the connection of U4_44 (K32) to U7_31 (MK20), especially since pin 44 is explicitly wired to J4_12 (the Arduino Header).

View solution in original post

0 Kudos
Reply
10 Replies
1,126 Views
Joey_z
NXP Employee
NXP Employee

hi,aberger

Thank you for your interest in the FRDM-K32L2B3 product.I would like to provide service for you.

You can try to remove the 10k resistors on SCL, and then observe the waveform changes. When the resistors are removed, the rising and falling edges of the SCL waveform are weak, which means the pin is set to open-drain in the program. When the resistors are removed, both the rising and falling edges of the SCL waveform are fast, which means the pin may be set to push-pull.

Wish it helps you.

BR

Xu Zhang

0 Kudos
Reply
911 Views
aberger
Contributor V

Hi @Joey_z ,

I have the 10kΩ resistors installed at both R81 and R82. However, you can see a clear difference in the traces from my original post: slow pull-up action on SDA, but fast edges on SCL. This is despite the identical pin configurations for the two pins (pull up enabled). So I can already see that SDA has been successfully configured for open drain, but SCL has not.

Nevertheless, I t ried the test you suggested. Below is a comparison of the behavior with 10kΩ pull-up resistors in place, and with 10kΩ resistors removed. 

With 10k pull-up resistors

aberger_0-1726861407741.png

Without 10k pull-up resistors

aberger_1-1726861437180.png

Summary: the SDA edges are slower without the 10k resistors (as expected... the pull-up strength is now provided only by the internal 20kΩ - 50kΩ). However, the SCL edges remain fast. As you said, this implies that the pin is still configured for push-pull, even though "IIC signals are automatically enabled for open drain when selected" (according to the Reference Manual). 

In 36.1.1 I2C instantiation information, it states:

When the package pins associated with IIC have their mux select configured for IIC
operation, the pins (SCL and SDA) are driven either by true open drain or in a pseudo
open drain configuration. However, only pseudo open drain configuration is for KLx3
family.

What is "pseudo open drain"? Does that mean that the SDA behaves as open drain, but SCL is still driven push-pull? Is there any way to achieve true open drain operation for SCL as well on the K32? (Otherwise, target device clock stretching cannot be supported. This would also imply that SMBus 2.0 is not accurately supported).

Note: I see that the I2Cx_C2[SBRC] (Slave Baud Rate Control) bit might enable/disable clock stretching, but I believe this only applies to use of the K32 as an I2C slave. I wish to operate the K32 as I2C master. 

0 Kudos
Reply
842 Views
Joey_z
NXP Employee
NXP Employee

hi,aberger

I conducted some tests using the frdmk32l2b_i2c_polling_b2b_transfer_master demo in SDK.I configured the FRDM-K32L2B board as the I2C master to communicate with another board.The configuration and pin setting are as follows.

XuZhang_0-1727150150638.pngXuZhang_1-1727150163786.png

I have tested the signal of SCL, this letter is without pull-up resistor, you can see the information in the picture, and yours is different.

XuZhang_2-1727150513601.png

 

Hope it can help you.

BR

Xu Zhang

 

0 Kudos
Reply
825 Views
aberger
Contributor V

Hi @Joey_z 

That is helpful, thank you.

I was able to reproduce your result. I see open-drain behavior when I2C0 SCL is routed to PTB0 (pin 35).

I also see open-drain behavior on I2C1 SCL when it is routed to PTE1 (pin 2).

In the above two cases, I can successfully communicate with a target device that requires clock stretching.

However, I still see push-pull behavior on I2C1 SCL when routed to PTC1 (pin 44). Is there something different about this pin? Perhaps open-drain configuration is only available on specific pins? If that is the case, please point me to a table that describes which pins have open-drain configuration available to them.

Otherwise, maybe there is a hidden bit somewhere in the pin configuration that is responsible for the open-drain configuration? If so, please provide instructions for configuring a pin as open-drain.

Below I show scope traces for the 3 scenarios described above, along with the pin configuration for each. Note that the pin configurations generated by MCUXpresso Config Tools are identical.

1. Successful communication with I2C0 (open drain SCL)

aberger_0-1727219056160.png

/* PORTB0 (pin 35) is configured as I2C0_SCL */
PORT_SetPinMux(PORTB, 0U, kPORT_MuxAlt2);

PORTB->PCR[0] = ((PORTB->PCR[0] &
                  /* Mask bits to zero which are setting */
                  (~(PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK)))

                 /* Pull Enable: Internal pullup or pulldown resistor is enabled on the corresponding pin. */
                 | (uint32_t)(PORT_PCR_PE_MASK));

/* PORTB1 (pin 36) is configured as I2C0_SDA */
PORT_SetPinMux(PORTB, 1U, kPORT_MuxAlt2);

PORTB->PCR[1] = ((PORTB->PCR[1] &
                  /* Mask bits to zero which are setting */
                  (~(PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK)))

                 /* Pull Enable: Internal pullup or pulldown resistor is enabled on the corresponding pin. */
                 | (uint32_t)(PORT_PCR_PE_MASK));

 

2. Successful communication with I2C1 (open drain SCL)

aberger_1-1727219142864.png

/* PORTE0 (pin 1) is configured as I2C1_SDA */
PORT_SetPinMux(BOARD_I2C1_SDA_PORT, BOARD_I2C1_SDA_PIN, kPORT_MuxAlt6);

PORTE->PCR[0] = ((PORTE->PCR[0] &
                  /* Mask bits to zero which are setting */
                  (~(PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK)))

                 /* Pull Enable: Internal pullup or pulldown resistor is enabled on the corresponding pin. */
                 | (uint32_t)(PORT_PCR_PE_MASK));

/* PORTE1 (pin 2) is configured as I2C1_SCL */
PORT_SetPinMux(BOARD_I2C1_SCL_PORT, BOARD_I2C1_SCL_PIN, kPORT_MuxAlt6);

PORTE->PCR[1] = ((PORTE->PCR[1] &
                  /* Mask bits to zero which are setting */
                  (~(PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK)))

                 /* Pull Enable: Internal pullup or pulldown resistor is enabled on the corresponding pin. */
                 | (uint32_t)(PORT_PCR_PE_MASK));

 

3. Unsuccessful communication with I2C1 (push-pull SCL)

aberger_2-1727219224872.png

/* PORTC2 (pin 45) is configured as I2C1_SDA */
PORT_SetPinMux(PORTC, 2U, kPORT_MuxAlt2);

PORTC->PCR[2] = ((PORTC->PCR[2] &
                  /* Mask bits to zero which are setting */
                  (~(PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK)))

                 /* Pull Enable: Internal pullup or pulldown resistor is enabled on the corresponding pin. */
                 | (uint32_t)(PORT_PCR_PE_MASK));
                 
/* PORTC1 (pin 44) is configured as I2C1_SCL */
PORT_SetPinMux(PORTC, 1U, kPORT_MuxAlt2);

PORTC->PCR[1] = ((PORTC->PCR[1] &
                  /* Mask bits to zero which are setting */
                  (~(PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK)))

                 /* Pull Enable: Internal pullup or pulldown resistor is enabled on the corresponding pin. */
                 | (uint32_t)(PORT_PCR_PE_MASK));

  

0 Kudos
Reply
818 Views
aberger
Contributor V

Actually, I just found a table in the K32 L2B Data Sheet: 4.3 Pin Properties.

I summarize this table below for the pins I tested, all of which are marked as "N" for Open Drain.

64 LQFPOpen DrainObserved as Open Drain?
1NY (strong pull-up, fast rise)
2NY (weak pull-up, slow rise)
35NY (weak pull-up, slow rise)
36NY (weak pull-up, slow rise)
44NN
45NN

 

I see that "N" means "Disabled", with a footnote that reads "When I2C module is enabled and a pin is functional for I2C, this pin is (pseudo-) open drain enabled." So I've confirmed that all of the pins I tested should be configured for pseudo-open drain when routed as I2C. Why are these pins observed to behave differently? 

Tags (3)
0 Kudos
Reply
741 Views
Joey_z
NXP Employee
NXP Employee

Hi,aberger

 I have repeated your question and will get back to you as soon as possible.

BR

Xu Zhang

0 Kudos
Reply
677 Views
aberger
Contributor V

I figured out the issue with pin 44. I am trying to use pin 44 as I2C1_SCL. A close look at the FRDM-K32L2B3 schematic shows that this pin is connected via 0 Ω resistor R24 to pin 31 of U7 (the on-board MK20DX128 that provides the OpenSDA interface for debugging the K32). 

I don't know what this connection is providing, as it doesn't appear necessary for debug or flashing of the target MCU. (It is also strangely labeled as off-sheet connector `PTC1_SDA`, even though it is not used as an SDA line).

Removing the 0 Ω resistor permits pin 44 to operate as an open-drain SCL for I2C1 as expected.

My apologies for the wild goose chase on this issue. However, it does seem that there should be some documentation regarding the connection of U4_44 (K32) to U7_31 (MK20), especially since pin 44 is explicitly wired to J4_12 (the Arduino Header).

0 Kudos
Reply
648 Views
Joey_z
NXP Employee
NXP Employee

hi,aberger

I'm glad you solved the problem and appreciate you sharing the detailed solution. I'll contact the internal team and take care of it.

Wish you a happy life!

BR

Xu Zhang

0 Kudos
Reply
631 Views
aberger
Contributor V

Hi @Joey_z ,

Thanks. Can you clarify why the connection of the SCL line to the MK20 pin was causing that behavior?

0 Kudos
Reply
597 Views
Joey_z
NXP Employee
NXP Employee

hi,aberger

I suspect that the configuration of pin 44 (I2C1_SCL) on the K32L2B might be impacted by the PORT configuration of the MK20, because the MK20's PORT configuration could override the default I2C settings. You can use a multimeter to check if the PORT on the MK20 side has a pull-up.

BR

Xu Zhang

0 Kudos
Reply