0
\$\begingroup\$

I am trying to communicate Kinetis K60 tower board with a Cypress IC CY8CMBR3116 cy8320 development board as slave IC. There are only two devices on the I2C bus. I am attaching a snapshot of the communication taking place on the I2C bus. enter image description here

The problem is that the acknowledgment is not low enough for the master to detect and even the stop condition is not correct. This is happening after sending the default address of 0X37 to the cypress IC.

Please tell me the reason for this output.

\$\endgroup\$
6
  • 4
    \$\begingroup\$ Are you doing your own I2C on the K60? It looks like the master is driving the SDA line push-pull instead of open-collector. Those intermediate levels look like a bus-fight where the master is driving high while the slave is driving low. \$\endgroup\$
    – DoxyLover
    May 17, 2017 at 10:13
  • 1
    \$\begingroup\$ No, we are using the onboard I2C peripheral on the Kinetis microcontroller K60DN512VMD10 on the tower board. \$\endgroup\$ May 17, 2017 at 10:25
  • 1
    \$\begingroup\$ The first transaction (address 37) by bus master looks like a corrupt ACK transaction at the end. Your bus master carries on regardless with a second transaction (which doesn't get a corrupt ACK, but gets no ACK. Does your code check for valid ACKs? \$\endgroup\$
    – glen_geek
    May 17, 2017 at 13:24
  • \$\begingroup\$ Have you tried a recommended I2C bus-clearing sequence well after both systems have powered up? \$\endgroup\$
    – glen_geek
    May 17, 2017 at 13:30
  • 1
    \$\begingroup\$ I'm not familiar with the Kinetis. In set up, do you need to manually set the pin mode to open-collector? \$\endgroup\$
    – DoxyLover
    May 17, 2017 at 16:12

1 Answer 1

0
\$\begingroup\$

TL;DR - Some or all of the problem(s) are in your code.

You didn't supply the relevant code, but the two problems that I see in that scope trace, are both code-related:

  • As DoxyLover pointed out, the trace clearly shows an intermediate voltage, caused by conflict between two devices driving that SDA signal in opposite directions for the I²C ACK cycle. Since the I²C slave is driving that signal low (as an ACK), then your Kinetis K60 MCU must be driving it high at the same time!

    As with many MCUs, when the internal I²C module is connected to actual external pins (e.g. via the internal pin multiplexer), those two pins must also be set to "open-drain" mode as a separate step in the configuration.

    In the NXP Reference Manual which I believe includes your specific K60 MCU (20MB pdf file), page 282 (section 11.6.1 Pin control) says:

    For example, if an I²C function is enabled on a pin, that does not override the pullup or open drain configuration for that pin.

    In other words, enabling I²C on a pin does not automatically set the pin to open-drain (nor does it change the current setting for the internal pullup).

    In this "I2C for Kinetis MCUs" document, page 23 has this question and answer:

    Q: Why is the low level signal on SDA or SCL not completely pulled down to 0 volts?
    A: For Kinetis MCUs, you may need to configure the I2C pins for open drain mode by setting the PORTx_PCR[ODE] bit. Another cause for this may be a poor ground connection between your master device and slave device.
    [my emphasis above]

    (Based on the scope trace, I doubt the ground connection is the cause of your problem.)

    As examples of setting open-drain mode in some I²C code, I found two random examples in Kinetis sample code here:

    #define I2C_0_PORT_CFG (PORT_PCR_MUX(I2C_0_PIN_AF) | PORT_PCR_ODE_MASK)

    and here:

    PORTB->PCR[0] = PORT_PCR_MUX(2) | PORT_PCR_ODE_MASK; PORTB->PCR[1] = PORT_PCR_MUX(2) | PORT_PCR_ODE_MASK;

  • As glen_geek has highlighted in earlier comments, it seems that your code continues with I²C communication even after the ACK cycle has the problem described above. Therefore you may have another code bug in this area.

\$\endgroup\$
10
  • \$\begingroup\$ Is it wired OR high or Hi/lo conflict . One could test with 10k pullup or pull down to determine Z of that mid-level voltage (ignore if code fixes it) \$\endgroup\$ May 17, 2017 at 21:30
  • \$\begingroup\$ @Tony - I don't know exactly what you mean by "wired OR high". I guess you are suggesting the pull-up resistor might be too strong (i.e. too low value), which could result in the typical 3mA I2C drivers being unable to pull the signal to ~0V - is that what you're asking? If so, looking at the scope trace I notice that the master can successfully pull-down the SDA signal to ~0 V when it is driving that signal alone, so the I2C pull-up resistor value does not seem too strong (low value). My vote, based on experience of debugging similar issues, is still on a "Hi/lo conflict" as I explained. \$\endgroup\$
    – SamGibson
    May 17, 2017 at 21:47
  • \$\begingroup\$ but if low level is say 100 Ohms and high level is passive 10k , I must misunderstand why ~3V \$\endgroup\$ May 17, 2017 at 21:59
  • \$\begingroup\$ Sorry @Tony, I don't understand your hypothesis. However if you have an alternative explanation which fits all parts of the scope trace (and the lack of confirmation from the OP of them setting open-drain mode), then perhaps writing it into an answer would help the OP, in case my hypothesis is wrong. \$\endgroup\$
    – SamGibson
    May 17, 2017 at 22:09
  • \$\begingroup\$ Vol=0.6V @6mA sink for good I2C chips or Ron=0.6V/6mA=100 Ohms and I2C is some pull-up R to Vdd then what is R to get mid-state V of 2V? while "1" looks like 3.3V and "0" looks like 0.3V , that's why I suggested adding another pull-up to test load current. If it has active 10k internal enabled to ground, that would explain the fault on driver. \$\endgroup\$ May 17, 2017 at 22:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.