<?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>topic I2C Start Read/Write Bit in MCUXpresso General</title>
    <link>https://community.nxp.com/t5/MCUXpresso-General/I2C-Start-Read-Write-Bit/m-p/1315476#M4268</link>
    <description>&lt;P&gt;Greetings:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have become ensnared in an interesting I2C phenomenon which I hope one better versed in such things than I might be able to shed some light.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am using MCUXpresso IDE v11.3.0 [Build 5222] and the lpcxpresso55s16 SDK.&amp;nbsp; I am writing test code for our own hardware but the problematic code is drawn straight from the SDK sample project &lt;EM&gt;lpcxpresso55s16_i2c_polling_b2b_master&lt;/EM&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;First, I am trying to interface with a Vishay 6030 Ambient Light Sensor.&amp;nbsp; To read the sensor, I need to replicate the instructions outlined in Figure (1).&amp;nbsp; Note that you’ve got to send the shifted slave address, then the command code, then a second shifted slave address but this time with the read bit set, after which the slave should make two data bytes available:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dougpaulsen_0-1627590687443.png" style="width: 400px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/151243i02AF9FB482C0028E/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dougpaulsen_0-1627590687443.png" alt="dougpaulsen_0-1627590687443.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;Figure 1.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Next, the Figure (1) I2C sequence translates to the Figure (2) code snippet (which is shamelessly plagiarized from the SDK &lt;EM&gt;lpcxpresso55s16_i2c_polling_b2b_master&lt;/EM&gt; sample project):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;//send start and I2C bus slave byte and W bit…&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;g_tRetVal = I2C_MasterStart( FLEXCOMM5_PERIPHERAL, I2C_MASTER_SLAVE_ADDR_7BIT, &lt;EM&gt;kI2C_Write&lt;/EM&gt; );&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;&lt;STRONG&gt;if&lt;/STRONG&gt; ( g_tRetVal == &lt;EM&gt;kStatus_Success&lt;/EM&gt; )&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;{&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;//send Command code...&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(06)&amp;nbsp;&amp;nbsp; g_tRetVal = I2C_MasterWriteBlocking( FLEXCOMM5_PERIPHERAL, &amp;amp;(g_u8MasterBuffTX[ 0 ]), 1, &lt;EM&gt;kI2C_TransferNoStopFlag&lt;/EM&gt;);&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(07)&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;if&lt;/STRONG&gt; ( g_tRetVal == &lt;EM&gt;kStatus_Success&lt;/EM&gt; )&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(08)&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(09)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //send second start, I2C bus slave address byte, and R bit...&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(10)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_tRetVal = I2C_MasterRepeatedStart( FLEXCOMM5_PERIPHERAL, I2C_MASTER_SLAVE_ADDR_7BIT, &lt;EM&gt;kI2C_Read &lt;/EM&gt;);&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Figure 2.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Alas!&amp;nbsp; Running the Figure (2) code yields an “arbitration” error, so it’s haul-out-the-oscilloscope time to see what’s going down on the SDA and SCL lines.&amp;nbsp; The results are shown in Figure (3):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dougpaulsen_1-1627590687465.png" style="width: 400px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/151244i8581814B8CAF6742/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dougpaulsen_1-1627590687465.png" alt="dougpaulsen_1-1627590687465.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;Figure 3.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Interesting…!&amp;nbsp; Cross referencing the Figure (2) code with the Figure (3) oscilloscope trace, the following is happening (even before the arbitration error:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Fig (2) line 2 I2C start function call results in Fig. (3) as the first “Address -10”,&lt;/LI&gt;&lt;LI&gt;Fig (2) line 6 write blocking function call&amp;nbsp; results in Fig. (3) as the “Data – 04” (that’s the 6030 read command).&amp;nbsp; All’s well so far….&lt;/LI&gt;&lt;LI&gt;Fig (2) line 10 repeat start function call is shown in Fig (3) as the second “Address – 10”.&amp;nbsp; But…&lt;/LI&gt;&lt;LI&gt;Note that the line 10 repeat start function call, which clearly includes the enumeration “&lt;EM&gt;kI2C_Read&lt;/EM&gt;”, actually executes as a write (that is, bit0 is zero)!&amp;nbsp; From there on, the process collapses in chaos.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;How can this be?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Well first lets check out the kI2C read/write enum.&amp;nbsp; Indeed, the read and write values are distinct:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/*! @brief Direction of master and slave transfers. */&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;typedef enum _i2c_direction&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;{&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;EM&gt;kI2C_Write&lt;/EM&gt; = 0U, /*!&amp;lt; Master transmit. */&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;EM&gt;kI2C_Read&lt;/EM&gt;&amp;nbsp; = 1U&amp;nbsp; /*!&amp;lt; Master receive. */&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;} i2c_direction_t;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;Figure 4.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Next, how about the I2C_MasterRepeatedStart( ) function?&amp;nbsp; It turns out that the I2C_MasterRepeatedStart() just straight out calls the I2C_MasterStart() function so let’s look at that (see Fig (4) below):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/*!&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @brief Sends a REPEATED START on the I2C bus.&lt;/P&gt;&lt;P&gt;&amp;nbsp;*&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;param&lt;/U&gt; base I2C peripheral base pointer&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;param&lt;/U&gt; address 7-bit slave device address.&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;param&lt;/U&gt; direction Master transfer directions(transmit/receive).&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;retval&lt;/U&gt; kStatus_Success Successfully send the start signal.&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;retval&lt;/U&gt; kStatus_I2C_Busy Current bus is busy but not occupied by current I2C master.&lt;/P&gt;&lt;P&gt;&amp;nbsp;*/&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;static&lt;/STRONG&gt; &lt;STRONG&gt;inline&lt;/STRONG&gt; status_t &lt;STRONG&gt;I2C_MasterRepeatedStart&lt;/STRONG&gt;(I2C_Type *base, uint8_t address, i2c_direction_t direction)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;return&lt;/STRONG&gt; I2C_MasterStart(base, address, direction);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/*!&lt;/P&gt;&lt;P&gt;* brief Sends a START on the I2C bus.&lt;/P&gt;&lt;P&gt;*&lt;/P&gt;&lt;P&gt;* This function is used to initiate a new master mode transfer by sending the START signal.&lt;/P&gt;&lt;P&gt;* The slave address is sent following the I2C START signal.&lt;/P&gt;&lt;P&gt;*&lt;/P&gt;&lt;P&gt;* &lt;U&gt;param&lt;/U&gt; base I2C peripheral base pointer&lt;/P&gt;&lt;P&gt;* &lt;U&gt;param&lt;/U&gt; address 7-bit slave device address.&lt;/P&gt;&lt;P&gt;* &lt;U&gt;param&lt;/U&gt; direction Master transfer directions(transmit/receive).&lt;/P&gt;&lt;P&gt;* &lt;U&gt;retval&lt;/U&gt; kStatus_Success Successfully send the start signal.&lt;/P&gt;&lt;P&gt;* &lt;U&gt;retval&lt;/U&gt; kStatus_I2C_Busy Current bus is busy.&lt;/P&gt;&lt;P&gt;*/&lt;/P&gt;&lt;P&gt;(01) status_t &lt;STRONG&gt;I2C_MasterStart&lt;/STRONG&gt;(I2C_Type *base, uint8_t address, i2c_direction_t direction)&lt;/P&gt;&lt;P&gt;(02) {&lt;/P&gt;&lt;P&gt;(03) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32_t result;&lt;/P&gt;&lt;P&gt;(04) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = I2C_PendingStatusWait(base);&lt;/P&gt;&lt;P&gt;(05) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;if&lt;/STRONG&gt; (result == (uint32_t)&lt;EM&gt;kStatus_I2C_Timeout&lt;/EM&gt;)&lt;/P&gt;&lt;P&gt;(06) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/P&gt;&lt;P&gt;(07) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;return&lt;/STRONG&gt; &lt;EM&gt;kStatus_I2C_Timeout&lt;/EM&gt;;&lt;/P&gt;&lt;P&gt;(08) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/P&gt;&lt;P&gt;(09)&lt;/P&gt;&lt;P&gt;(10) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/* Write Address and RW bit to data register */&lt;/P&gt;&lt;P&gt;(11) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base-&amp;gt;MSTDAT = ((uint32_t)address &amp;lt;&amp;lt; 1) | ((uint32_t)direction &amp;amp; 1U);&lt;/P&gt;&lt;P&gt;(12) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/* Start the transfer */&lt;/P&gt;&lt;P&gt;(13) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTART_MASK;&lt;/P&gt;&lt;P&gt;(14)&lt;/P&gt;&lt;P&gt;(15) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;return&lt;/STRONG&gt; &lt;EM&gt;kStatus_Success&lt;/EM&gt;;&lt;/P&gt;&lt;P&gt;(16) }&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;Figure 5.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;To summarize Fig 2 line 10 calls I2C_MasterRepeatedStart() with parameter 3, the direction, as read (i.e., 1).&amp;nbsp; Function I2C_MasterRepeatedStart() calls function I2C_MasterStart() with its’ parameter 3 also as read (i.e., 1).&amp;nbsp; In function I2C_MasterStart() the direction parameter is or-ed with the shifted I2C address and written to the MSTDAT register (figure 5 line 11).&amp;nbsp; &amp;nbsp;&amp;nbsp;By the time the data hits the bus (Figure 3) the read/write bit is cleared to a write.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Weird!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Can anyone see a failing in the logic here?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for your thoughts,&lt;/P&gt;&lt;P&gt;doug&lt;/P&gt;</description>
    <pubDate>Thu, 29 Jul 2021 20:34:32 GMT</pubDate>
    <dc:creator>dougpaulsen</dc:creator>
    <dc:date>2021-07-29T20:34:32Z</dc:date>
    <item>
      <title>I2C Start Read/Write Bit</title>
      <link>https://community.nxp.com/t5/MCUXpresso-General/I2C-Start-Read-Write-Bit/m-p/1315476#M4268</link>
      <description>&lt;P&gt;Greetings:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have become ensnared in an interesting I2C phenomenon which I hope one better versed in such things than I might be able to shed some light.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am using MCUXpresso IDE v11.3.0 [Build 5222] and the lpcxpresso55s16 SDK.&amp;nbsp; I am writing test code for our own hardware but the problematic code is drawn straight from the SDK sample project &lt;EM&gt;lpcxpresso55s16_i2c_polling_b2b_master&lt;/EM&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;First, I am trying to interface with a Vishay 6030 Ambient Light Sensor.&amp;nbsp; To read the sensor, I need to replicate the instructions outlined in Figure (1).&amp;nbsp; Note that you’ve got to send the shifted slave address, then the command code, then a second shifted slave address but this time with the read bit set, after which the slave should make two data bytes available:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dougpaulsen_0-1627590687443.png" style="width: 400px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/151243i02AF9FB482C0028E/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dougpaulsen_0-1627590687443.png" alt="dougpaulsen_0-1627590687443.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;Figure 1.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Next, the Figure (1) I2C sequence translates to the Figure (2) code snippet (which is shamelessly plagiarized from the SDK &lt;EM&gt;lpcxpresso55s16_i2c_polling_b2b_master&lt;/EM&gt; sample project):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;//send start and I2C bus slave byte and W bit…&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;g_tRetVal = I2C_MasterStart( FLEXCOMM5_PERIPHERAL, I2C_MASTER_SLAVE_ADDR_7BIT, &lt;EM&gt;kI2C_Write&lt;/EM&gt; );&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;&lt;STRONG&gt;if&lt;/STRONG&gt; ( g_tRetVal == &lt;EM&gt;kStatus_Success&lt;/EM&gt; )&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;{&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;//send Command code...&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(06)&amp;nbsp;&amp;nbsp; g_tRetVal = I2C_MasterWriteBlocking( FLEXCOMM5_PERIPHERAL, &amp;amp;(g_u8MasterBuffTX[ 0 ]), 1, &lt;EM&gt;kI2C_TransferNoStopFlag&lt;/EM&gt;);&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(07)&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;if&lt;/STRONG&gt; ( g_tRetVal == &lt;EM&gt;kStatus_Success&lt;/EM&gt; )&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(08)&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(09)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //send second start, I2C bus slave address byte, and R bit...&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;(10)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_tRetVal = I2C_MasterRepeatedStart( FLEXCOMM5_PERIPHERAL, I2C_MASTER_SLAVE_ADDR_7BIT, &lt;EM&gt;kI2C_Read &lt;/EM&gt;);&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Figure 2.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Alas!&amp;nbsp; Running the Figure (2) code yields an “arbitration” error, so it’s haul-out-the-oscilloscope time to see what’s going down on the SDA and SCL lines.&amp;nbsp; The results are shown in Figure (3):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dougpaulsen_1-1627590687465.png" style="width: 400px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/151244i8581814B8CAF6742/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dougpaulsen_1-1627590687465.png" alt="dougpaulsen_1-1627590687465.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;Figure 3.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Interesting…!&amp;nbsp; Cross referencing the Figure (2) code with the Figure (3) oscilloscope trace, the following is happening (even before the arbitration error:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Fig (2) line 2 I2C start function call results in Fig. (3) as the first “Address -10”,&lt;/LI&gt;&lt;LI&gt;Fig (2) line 6 write blocking function call&amp;nbsp; results in Fig. (3) as the “Data – 04” (that’s the 6030 read command).&amp;nbsp; All’s well so far….&lt;/LI&gt;&lt;LI&gt;Fig (2) line 10 repeat start function call is shown in Fig (3) as the second “Address – 10”.&amp;nbsp; But…&lt;/LI&gt;&lt;LI&gt;Note that the line 10 repeat start function call, which clearly includes the enumeration “&lt;EM&gt;kI2C_Read&lt;/EM&gt;”, actually executes as a write (that is, bit0 is zero)!&amp;nbsp; From there on, the process collapses in chaos.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;How can this be?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Well first lets check out the kI2C read/write enum.&amp;nbsp; Indeed, the read and write values are distinct:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/*! @brief Direction of master and slave transfers. */&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;typedef enum _i2c_direction&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;{&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;EM&gt;kI2C_Write&lt;/EM&gt; = 0U, /*!&amp;lt; Master transmit. */&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;EM&gt;kI2C_Read&lt;/EM&gt;&amp;nbsp; = 1U&amp;nbsp; /*!&amp;lt; Master receive. */&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="2"&gt;} i2c_direction_t;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;Figure 4.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Next, how about the I2C_MasterRepeatedStart( ) function?&amp;nbsp; It turns out that the I2C_MasterRepeatedStart() just straight out calls the I2C_MasterStart() function so let’s look at that (see Fig (4) below):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/*!&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @brief Sends a REPEATED START on the I2C bus.&lt;/P&gt;&lt;P&gt;&amp;nbsp;*&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;param&lt;/U&gt; base I2C peripheral base pointer&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;param&lt;/U&gt; address 7-bit slave device address.&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;param&lt;/U&gt; direction Master transfer directions(transmit/receive).&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;retval&lt;/U&gt; kStatus_Success Successfully send the start signal.&lt;/P&gt;&lt;P&gt;&amp;nbsp;* @&lt;U&gt;retval&lt;/U&gt; kStatus_I2C_Busy Current bus is busy but not occupied by current I2C master.&lt;/P&gt;&lt;P&gt;&amp;nbsp;*/&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;static&lt;/STRONG&gt; &lt;STRONG&gt;inline&lt;/STRONG&gt; status_t &lt;STRONG&gt;I2C_MasterRepeatedStart&lt;/STRONG&gt;(I2C_Type *base, uint8_t address, i2c_direction_t direction)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;return&lt;/STRONG&gt; I2C_MasterStart(base, address, direction);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/*!&lt;/P&gt;&lt;P&gt;* brief Sends a START on the I2C bus.&lt;/P&gt;&lt;P&gt;*&lt;/P&gt;&lt;P&gt;* This function is used to initiate a new master mode transfer by sending the START signal.&lt;/P&gt;&lt;P&gt;* The slave address is sent following the I2C START signal.&lt;/P&gt;&lt;P&gt;*&lt;/P&gt;&lt;P&gt;* &lt;U&gt;param&lt;/U&gt; base I2C peripheral base pointer&lt;/P&gt;&lt;P&gt;* &lt;U&gt;param&lt;/U&gt; address 7-bit slave device address.&lt;/P&gt;&lt;P&gt;* &lt;U&gt;param&lt;/U&gt; direction Master transfer directions(transmit/receive).&lt;/P&gt;&lt;P&gt;* &lt;U&gt;retval&lt;/U&gt; kStatus_Success Successfully send the start signal.&lt;/P&gt;&lt;P&gt;* &lt;U&gt;retval&lt;/U&gt; kStatus_I2C_Busy Current bus is busy.&lt;/P&gt;&lt;P&gt;*/&lt;/P&gt;&lt;P&gt;(01) status_t &lt;STRONG&gt;I2C_MasterStart&lt;/STRONG&gt;(I2C_Type *base, uint8_t address, i2c_direction_t direction)&lt;/P&gt;&lt;P&gt;(02) {&lt;/P&gt;&lt;P&gt;(03) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32_t result;&lt;/P&gt;&lt;P&gt;(04) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = I2C_PendingStatusWait(base);&lt;/P&gt;&lt;P&gt;(05) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;if&lt;/STRONG&gt; (result == (uint32_t)&lt;EM&gt;kStatus_I2C_Timeout&lt;/EM&gt;)&lt;/P&gt;&lt;P&gt;(06) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/P&gt;&lt;P&gt;(07) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;return&lt;/STRONG&gt; &lt;EM&gt;kStatus_I2C_Timeout&lt;/EM&gt;;&lt;/P&gt;&lt;P&gt;(08) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/P&gt;&lt;P&gt;(09)&lt;/P&gt;&lt;P&gt;(10) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/* Write Address and RW bit to data register */&lt;/P&gt;&lt;P&gt;(11) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base-&amp;gt;MSTDAT = ((uint32_t)address &amp;lt;&amp;lt; 1) | ((uint32_t)direction &amp;amp; 1U);&lt;/P&gt;&lt;P&gt;(12) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/* Start the transfer */&lt;/P&gt;&lt;P&gt;(13) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTART_MASK;&lt;/P&gt;&lt;P&gt;(14)&lt;/P&gt;&lt;P&gt;(15) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;return&lt;/STRONG&gt; &lt;EM&gt;kStatus_Success&lt;/EM&gt;;&lt;/P&gt;&lt;P&gt;(16) }&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;Figure 5.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;To summarize Fig 2 line 10 calls I2C_MasterRepeatedStart() with parameter 3, the direction, as read (i.e., 1).&amp;nbsp; Function I2C_MasterRepeatedStart() calls function I2C_MasterStart() with its’ parameter 3 also as read (i.e., 1).&amp;nbsp; In function I2C_MasterStart() the direction parameter is or-ed with the shifted I2C address and written to the MSTDAT register (figure 5 line 11).&amp;nbsp; &amp;nbsp;&amp;nbsp;By the time the data hits the bus (Figure 3) the read/write bit is cleared to a write.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Weird!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Can anyone see a failing in the logic here?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for your thoughts,&lt;/P&gt;&lt;P&gt;doug&lt;/P&gt;</description>
      <pubDate>Thu, 29 Jul 2021 20:34:32 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-General/I2C-Start-Read-Write-Bit/m-p/1315476#M4268</guid>
      <dc:creator>dougpaulsen</dc:creator>
      <dc:date>2021-07-29T20:34:32Z</dc:date>
    </item>
    <item>
      <title>Re: I2C Start Read/Write Bit</title>
      <link>https://community.nxp.com/t5/MCUXpresso-General/I2C-Start-Read-Write-Bit/m-p/1316558#M4270</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Recommend you refer to the I2C_read_accel_value_transfer demo under SDK.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 02 Aug 2021 08:25:39 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-General/I2C-Start-Read-Write-Bit/m-p/1316558#M4270</guid>
      <dc:creator>Alice_Yang</dc:creator>
      <dc:date>2021-08-02T08:25:39Z</dc:date>
    </item>
  </channel>
</rss>

