<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Kinetis Microcontrollers中的主题 Re: fsl_i2c I2C_MasterStop stuck in while loop</title>
    <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1705231#M65441</link>
    <description>&lt;P&gt;Is it possible that there is a bug in the &lt;FONT face="courier new,courier"&gt;I2C_MasterReadBlocking()&lt;/FONT&gt; code from the fsl_i2c.c driver (copied below with &lt;FONT face="courier new,courier"&gt;#ifdef'&lt;/FONT&gt;s removed)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;while (0U != (rxSize--))
    {
        if (rxSize == 0U)
        {
            if (0U == (flags &amp;amp; (uint32_t)kI2C_TransferNoStopFlag))
            {
                /* Issue STOP command before reading last byte. */
                result = I2C_MasterStop(base);
            }
            else
            {
                /* Change direction to Tx to avoid extra clocks. */
                base-&amp;gt;C1 |= I2C_C1_TX_MASK;
            }
        }

        /* Clear the IICIF flag. */
        base-&amp;gt;S = (uint8_t)kI2C_IntPendingFlag;

        /* Read from the data register. */
        *rxBuff++ = base-&amp;gt;D;

        if (rxSize == 1U)
        {
            /* Issue NACK on read. */
            base-&amp;gt;C1 |= I2C_C1_TXAK_MASK;
        }
    }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;You can see that the data register is read&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;before&lt;/EM&gt;&lt;SPAN&gt; the NACK is configured for the last byte (&lt;FONT face="courier new,courier"&gt;if(rxSize == 1U)&lt;/FONT&gt;). From the K64 Reference Manual, reading the data register is responsible for initiating clocking-out of the next byte:&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;In master receive mode, reading this register initiates receiving of the next byte of data.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Therefore, if an interrupt occurs before C1 is configured for NACK but after the data register is read, it's possible that the last byte is clocked out with C1 still configured for ACK.&lt;/P&gt;&lt;P&gt;By comparison, look at lines 159 and 160 of&amp;nbsp;&lt;A href="https://github.com/jwr/kinetis_i2c/blob/main/i2c.c," target="_blank" rel="noopener"&gt;https://github.com/jwr/kinetis_i2c/blob/main/i2c.c,&lt;/A&gt;&amp;nbsp;which inverts the order of the C1 configurating and the data register read.&lt;/P&gt;</description>
    <pubDate>Tue, 15 Aug 2023 22:45:33 GMT</pubDate>
    <dc:creator>aberger</dc:creator>
    <dc:date>2023-08-15T22:45:33Z</dc:date>
    <item>
      <title>fsl_i2c I2C_MasterStop stuck in while loop</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1703759#M65435</link>
      <description>&lt;P&gt;Intermittently, my fsl_i2c driver code is getting stuck in a forever while loop while trying to read bytes from an external I2C EEPROM chip.&lt;/P&gt;&lt;P&gt;I'm using the fsl_i2c driver for the MK64F and am trying to read 4 bytes via I2C read using &lt;FONT face="courier new,courier"&gt;I2C_MasterTransferBlocking()&lt;/FONT&gt;. At the end of reading the 4 bytes in &lt;FONT face="courier new,courier"&gt;I2C_MasterReadBlocking()&lt;/FONT&gt;, when (&lt;FONT face="courier new,courier"&gt;rxSize == 0U)&lt;/FONT&gt;, the driver code executes &lt;FONT face="courier new,courier"&gt;I2C_MasterStop()&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;This is supposed to issue a STOP command with the following:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;/* Issue the STOP command on the bus. */
base-&amp;gt;C1 &amp;amp;= ~(uint8_t)(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);&lt;/LI-CODE&gt;&lt;P&gt;However, the code then gets stuck in the while loop:&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;while(0U != (base-&amp;gt;S &amp;amp; (uint8_t)kI2C_BusBusyFlag)) 
{
}&lt;/LI-CODE&gt;&lt;P&gt;By my understanding the BUSY bit of &lt;FONT face="courier new,courier"&gt;base-&amp;gt;S&lt;/FONT&gt; should be cleared when a STOP signal is detected. Why did the &lt;FONT face="courier new,courier"&gt;base-&amp;gt;C1&lt;/FONT&gt; write fail to issue the STOP command?&lt;/P&gt;&lt;P&gt;It also appears that the NACK that is supposed to be issued after the 4th byte is read is not actually being issued:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;if (rxSize == 1U)
{
    base-&amp;gt;C1 |= I2C_C1_TXAK_MASK;
}&lt;/LI-CODE&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="aberger_0-1691795399005.png" style="width: 999px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/236140i17B8547A2A845D79/image-size/large?v=v2&amp;amp;px=999" role="button" title="aberger_0-1691795399005.png" alt="aberger_0-1691795399005.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;As mentioned at the top of the post, the I2C_MasterReadBlocking works most of the time (I can read out all of the 4096 bytes from this EEPROM many times before occasionally running into this issue).&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 11 Aug 2023 23:17:03 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1703759#M65435</guid>
      <dc:creator>aberger</dc:creator>
      <dc:date>2023-08-11T23:17:03Z</dc:date>
    </item>
    <item>
      <title>Re: fsl_i2c I2C_MasterStop stuck in while loop</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1705231#M65441</link>
      <description>&lt;P&gt;Is it possible that there is a bug in the &lt;FONT face="courier new,courier"&gt;I2C_MasterReadBlocking()&lt;/FONT&gt; code from the fsl_i2c.c driver (copied below with &lt;FONT face="courier new,courier"&gt;#ifdef'&lt;/FONT&gt;s removed)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;while (0U != (rxSize--))
    {
        if (rxSize == 0U)
        {
            if (0U == (flags &amp;amp; (uint32_t)kI2C_TransferNoStopFlag))
            {
                /* Issue STOP command before reading last byte. */
                result = I2C_MasterStop(base);
            }
            else
            {
                /* Change direction to Tx to avoid extra clocks. */
                base-&amp;gt;C1 |= I2C_C1_TX_MASK;
            }
        }

        /* Clear the IICIF flag. */
        base-&amp;gt;S = (uint8_t)kI2C_IntPendingFlag;

        /* Read from the data register. */
        *rxBuff++ = base-&amp;gt;D;

        if (rxSize == 1U)
        {
            /* Issue NACK on read. */
            base-&amp;gt;C1 |= I2C_C1_TXAK_MASK;
        }
    }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;You can see that the data register is read&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;before&lt;/EM&gt;&lt;SPAN&gt; the NACK is configured for the last byte (&lt;FONT face="courier new,courier"&gt;if(rxSize == 1U)&lt;/FONT&gt;). From the K64 Reference Manual, reading the data register is responsible for initiating clocking-out of the next byte:&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;In master receive mode, reading this register initiates receiving of the next byte of data.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Therefore, if an interrupt occurs before C1 is configured for NACK but after the data register is read, it's possible that the last byte is clocked out with C1 still configured for ACK.&lt;/P&gt;&lt;P&gt;By comparison, look at lines 159 and 160 of&amp;nbsp;&lt;A href="https://github.com/jwr/kinetis_i2c/blob/main/i2c.c," target="_blank" rel="noopener"&gt;https://github.com/jwr/kinetis_i2c/blob/main/i2c.c,&lt;/A&gt;&amp;nbsp;which inverts the order of the C1 configurating and the data register read.&lt;/P&gt;</description>
      <pubDate>Tue, 15 Aug 2023 22:45:33 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1705231#M65441</guid>
      <dc:creator>aberger</dc:creator>
      <dc:date>2023-08-15T22:45:33Z</dc:date>
    </item>
    <item>
      <title>Re: fsl_i2c I2C_MasterStop stuck in while loop</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1706074#M65443</link>
      <description>&lt;P&gt;Hello, my name is Pavel, and I will be supporting your case, could you tell me what examples from the SDK are you based on?&lt;/P&gt;
&lt;P&gt;Best regards,&lt;BR /&gt;Pavel&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 16 Aug 2023 23:09:02 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1706074#M65443</guid>
      <dc:creator>Pavel_Hernandez</dc:creator>
      <dc:date>2023-08-16T23:09:02Z</dc:date>
    </item>
    <item>
      <title>Re: fsl_i2c I2C_MasterStop stuck in while loop</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1706076#M65444</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/196430"&gt;@Pavel_Hernandez&lt;/a&gt;,&amp;nbsp;thanks for following up. I am using the fsl_i2c.c and fsl_i2c.h drivers included with SDK_2_7_0_TWR_K64F120M (Version 2.7.0 (303 2019-12-19)).&lt;/P&gt;&lt;P&gt;You could look at the i2c_polling_b2b_transfer_master example.&lt;/P&gt;</description>
      <pubDate>Wed, 16 Aug 2023 23:17:42 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1706076#M65444</guid>
      <dc:creator>aberger</dc:creator>
      <dc:date>2023-08-16T23:17:42Z</dc:date>
    </item>
    <item>
      <title>Re: fsl_i2c I2C_MasterStop stuck in while loop</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1707080#M65455</link>
      <description>&lt;P&gt;Hello, I´m using the SDK version 2.11 and the example works as expected.&lt;/P&gt;
&lt;P&gt;Best regards,&lt;BR /&gt;Pavel&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 18 Aug 2023 00:12:24 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1707080#M65455</guid>
      <dc:creator>Pavel_Hernandez</dc:creator>
      <dc:date>2023-08-18T00:12:24Z</dc:date>
    </item>
    <item>
      <title>Re: fsl_i2c I2C_MasterStop stuck in while loop</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1707218#M65456</link>
      <description>&lt;P&gt;I also have no trouble running the example as is. The issue I believe I am having is that, when using the I2C blocking code from the fsl driver in a system where there &lt;EM&gt;are&lt;/EM&gt; interrupts, a poorly timed interrupt can occur after the&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;/*Read from the data register. */
*rxBuff++ = base-&amp;gt;D&lt;/LI-CODE&gt;&lt;P&gt;but before the&lt;/P&gt;&lt;LI-CODE lang="c"&gt; /* Issue NACK on read. */
base-&amp;gt;C1 |= I2C_C1_TXAK_MASK;&lt;/LI-CODE&gt;&lt;P&gt;As a result, the C1 register is still configured for ACK when the I2C hardware begins clocking out the next byte (triggered by the data register read). That means that after what should be the final byte is clocked out, an ACK is issued, the &lt;FONT face="courier new,courier"&gt;I2C_MasterStop()&lt;/FONT&gt; is never actually able to issue the STOP command, and the bus gets stuck in the busy state indefinitely.&lt;/P&gt;&lt;P&gt;I found that in my system, inverting the order of these lines of code makes the I2C communication more reliable.&lt;/P&gt;</description>
      <pubDate>Fri, 18 Aug 2023 05:00:37 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1707218#M65456</guid>
      <dc:creator>aberger</dc:creator>
      <dc:date>2023-08-18T05:00:37Z</dc:date>
    </item>
    <item>
      <title>Re: fsl_i2c I2C_MasterStop stuck in while loop</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1708599#M65470</link>
      <description>&lt;P&gt;Hello, thanks for your information, unfortunately, the example blocking does not have the robustness to detect that kind of event, I suggest changing the I2C to the non-blocking mode to get a better performance.&lt;/P&gt;
&lt;P&gt;Best regards,&lt;BR /&gt;Pavel&lt;/P&gt;</description>
      <pubDate>Mon, 21 Aug 2023 21:41:53 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1708599#M65470</guid>
      <dc:creator>Pavel_Hernandez</dc:creator>
      <dc:date>2023-08-21T21:41:53Z</dc:date>
    </item>
    <item>
      <title>Re: fsl_i2c I2C_MasterStop stuck in while loop</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1709108#M65471</link>
      <description>Be wary of any code clearing flags via using "|=" (Read OR Write). NXP example code is full of them where assignment "=" is meant to be used to clear "Write 1 To Clear" (W1C) bits.&lt;BR /&gt;&lt;BR /&gt;The OR clears bits unintentionally and statuses get lost. Using |= creates hard to diagnose timing races when used with W1C bits.</description>
      <pubDate>Tue, 22 Aug 2023 12:27:06 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/fsl-i2c-I2C-MasterStop-stuck-in-while-loop/m-p/1709108#M65471</guid>
      <dc:creator>bobpaddock</dc:creator>
      <dc:date>2023-08-22T12:27:06Z</dc:date>
    </item>
  </channel>
</rss>

