<?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>MCUXpresso SDKのトピックRe: LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag u</title>
    <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358365#M3397</link>
    <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;Frankly speaking, I am not clear about your question, how do you know that transfer function changes from read to write? As far as I know that only the address command has the LSB which presents the READ or WRITE command.&lt;/P&gt;
&lt;P&gt;For the I2C protocol, the receiver must drive the data pin to LOW as ACK signal at the end of each byte, if the ACK is not received by transmitter if I2C is master writing phase, the master will stop by releasing the SCL/SDA, and both the SCL and SDA will be high,&amp;nbsp; so the I2C will stop.&lt;/P&gt;
&lt;P&gt;BR&lt;/P&gt;
&lt;P&gt;XiangJun Rong&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 20 Oct 2021 06:34:08 GMT</pubDate>
    <dc:creator>xiangjun_rong</dc:creator>
    <dc:date>2021-10-20T06:34:08Z</dc:date>
    <item>
      <title>LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag used</title>
      <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1357590#M3393</link>
      <description>&lt;P&gt;Hi, I need to communicate between LPC54606 (master) and PCIe switch PI7C9X2G1224GP (slave) via I2C. There's defined a specific sequence for read and write internal registers that I tried to do using &lt;STRONG&gt;I2C_MasterTransferBlocking&lt;/STRONG&gt; API or &lt;STRONG&gt;I2C_MasterStart/I2C_MasterStop/I2C_MasterReadBlocking&lt;/STRONG&gt; but I have a problem that I2C communication doesn't complete and end with error without data readed back. Write data are acked but when 5 bytes should be read back I see for some reason a write instead of read even I use &lt;STRONG&gt;direction=kI2C_Read&lt;/STRONG&gt;, see code of my function below. When I experimented with params I found this behavior changes when I change flags on previous write from &lt;STRONG&gt;kI2C_TransferNoStopFlag&lt;/STRONG&gt; to &lt;STRONG&gt;kI2C_TransferDefaultFlag&lt;/STRONG&gt;. Then read is sent but slave doesn't return valid data, just five 0xFF bytes ending with arb.err. But according to slave protocol requirements I must not to use stop between so I need to make TransferNoStopFlag working.&lt;/P&gt;&lt;P&gt;Here's the sequence from slave datasheet:&lt;/P&gt;&lt;P&gt;Figure 7-4 SMBus Block Write to Set up Read, and Resulting Read that Returns CFG Register Value&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;START&lt;/STRONG&gt; | Slave Addr Wr | ACK | Cmd Code = BAh | ACK | Byte Count = 4 | ACK | Cmd Byte1 | ACK | Cmd Byte 2 | ACK | Cmd Byte 3 | ACK | Cmd Byte 4 | ACK | &lt;STRONG&gt;STOP&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;A Block Write to set up Read&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;START&lt;/STRONG&gt; | Slave Addr Wr | ACK | Cmd code = BDh | ACK | (no stop here) &lt;STRONG&gt;START&lt;/STRONG&gt; | Slave Adress Rd | ACK | Byte Count = 4 (from slave) | ACK | Data Byte 1 (from slave) | ACK | Data Byte 2 (from slave) | ACK | Data Byte 3 (from slave) | ACK | Data Byte 4 (from slave) | ACK | &lt;STRONG&gt;STOP&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;My code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;  i2c_master_transfer_t xfer;          // I2C master transfer structure for I2C_MasterTransferNonBlocking()
  uint8_t buffer[6];                   // I2C data buffer for transfer (read/write)
  status_t err;

  if ((I2C_GetStatusFlags(base)&amp;amp;kI2C_MasterPendingFlag)==0) // if master is busy for some unknown reason
    {                                  // restart the I2C master
    I2C_MasterEnable(base,false);      // otherwise it will hang in an endless loop
    I2C_MasterEnable(base,true);       // in SDK function I2C_PendingStatusWait()
    }
  buffer[0]=I2C_PCIESW_BLKWR;          // fill command code to Tx buffer, see page 56
  buffer[1]=4;                         // fill Byte count=4 to Tx buffer
  buffer[2]=0x04;                      // fill Command Byte1 to Tx buffer, bit2:0 - 3=write reg, 4=read reg, bit7:3 - reserved
  buffer[3]=0x00;                      // fill Command Byte2 to Tx buffer, bit3:0 - port_select4:1, bit7:4 - reserved
  buffer[4]=0xBC;                      // fill Command Byte3 to Tx buffer, bit7 - port_select0, bit6 - reserved, bit5:2 - Byte enable (0=not modif, 1=modif), bit1:0 - reg_addr11:10
  buffer[5]=0x3E;                      // fill Command Byte4 to Tx buffer, bit7:0 - reg_addr9:2 (reg_addr1:0 are always 0)
  memset(&amp;amp;xfer, 0, sizeof(xfer));
  xfer.slaveAddress=I2C_PCIESW_SLAVE_ADDR;
  xfer.direction=kI2C_Write;
  xfer.subaddress=0;
  xfer.subaddressSize=0;
  xfer.data=buffer;
  xfer.dataSize=6;
  xfer.flags=kI2C_TransferDefaultFlag;
  err=I2C_MasterTransferBlocking(base, &amp;amp;xfer);
  uart_printf("err1 %d\n", err);

	buffer[0]=I2C_PCIESW_BLKR;           // fill read back command code to Tx buffer
  xfer.dataSize=1;
//  xfer.flags=kI2C_TransferNoStopFlag;
  xfer.flags=kI2C_TransferDefaultFlag;
  err=I2C_MasterTransferBlocking(base, &amp;amp;xfer);
  uart_printf("err2 %d\n", err);

  memset(&amp;amp;buffer, 0, sizeof(buffer));
  memset(&amp;amp;xfer, 0, sizeof(xfer));
  xfer.slaveAddress=I2C_PCIESW_SLAVE_ADDR;
  xfer.direction=kI2C_Read;
  xfer.subaddress=0;
  xfer.subaddressSize=0;
  xfer.data=buffer;
  xfer.dataSize=5;
  xfer.flags=kI2C_TransferDefaultFlag;
  err=I2C_MasterTransferBlocking(base, &amp;amp;xfer);
  uart_printf("err3 %d\n", err);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Terminal log when flag used: kI2C_TransferNoStopFlag&lt;/P&gt;&lt;P&gt;err1 0&lt;BR /&gt;err2 0&lt;BR /&gt;err3 2609&lt;BR /&gt;00 00 00 00 00&lt;/P&gt;&lt;P&gt;Terminal log when flag used: kI2C_kI2C_TransferDefaultFlag&lt;/P&gt;&lt;P&gt;err1 0&lt;BR /&gt;err2 0&lt;BR /&gt;err3 2605&lt;BR /&gt;FF FF FF FF FF&lt;/P&gt;&lt;P&gt;In the attachment there are oscillograms with I2C analyser decoder that shows there's write address the last part of sequence while there should be read - why? Is it a bug in SDK API func?&lt;/P&gt;&lt;P&gt;The second osc shows sequence with right read but with unwanted stop that may cause read failed.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 19 Oct 2021 05:22:32 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1357590#M3393</guid>
      <dc:creator>MartinDQ</dc:creator>
      <dc:date>2021-10-19T05:22:32Z</dc:date>
    </item>
    <item>
      <title>Re: LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag u</title>
      <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1357766#M3395</link>
      <description>&lt;P&gt;Hi, Martin,&lt;/P&gt;
&lt;P&gt;I suggest you call the I2C state machine function to implement your I2C sequence such as:&lt;/P&gt;
&lt;P&gt;I2C slave address + W + multiple data + repeated Start + I2C slave address +RD+ multiple data&lt;/P&gt;
&lt;P&gt;I copy the api function, pls read them and consider how to call them based on your application:&lt;/P&gt;
&lt;P&gt;Hope it can help you&lt;/P&gt;
&lt;P&gt;BR&lt;/P&gt;
&lt;P&gt;Xiangjun Rong&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;/*!&lt;BR /&gt;* @brief Prepares the transfer state machine and fills in the command buffer.&lt;BR /&gt;* @param handle Master nonblocking driver handle.&lt;BR /&gt;*/&lt;BR /&gt;static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)&lt;BR /&gt;{&lt;BR /&gt;struct _i2c_master_transfer *transfer;&lt;/P&gt;
&lt;P&gt;handle-&amp;gt;transfer = *xfer;&lt;BR /&gt;transfer = &amp;amp;(handle-&amp;gt;transfer);&lt;/P&gt;
&lt;P&gt;handle-&amp;gt;transferCount = 0;&lt;BR /&gt;handle-&amp;gt;remainingBytes = transfer-&amp;gt;dataSize;&lt;BR /&gt;handle-&amp;gt;buf = (uint8_t *)transfer-&amp;gt;data;&lt;BR /&gt;handle-&amp;gt;remainingSubaddr = 0;&lt;/P&gt;
&lt;P&gt;if ((transfer-&amp;gt;flags &amp;amp; (uint32_t)kI2C_TransferNoStartFlag) != 0U)&lt;BR /&gt;{&lt;BR /&gt;/* Start condition shall be ommited, switch directly to next phase */&lt;BR /&gt;if (transfer-&amp;gt;dataSize == 0U)&lt;BR /&gt;{&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kStopState;&lt;BR /&gt;}&lt;BR /&gt;else if (handle-&amp;gt;transfer.direction == kI2C_Write)&lt;BR /&gt;{&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kTransmitDataState;&lt;BR /&gt;}&lt;BR /&gt;else if (handle-&amp;gt;transfer.direction == kI2C_Read)&lt;BR /&gt;{&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kReceiveDataBeginState;&lt;BR /&gt;}&lt;BR /&gt;else&lt;BR /&gt;{&lt;BR /&gt;return kStatus_I2C_InvalidParameter;&lt;BR /&gt;}&lt;BR /&gt;}&lt;BR /&gt;else&lt;BR /&gt;{&lt;BR /&gt;if (transfer-&amp;gt;subaddressSize != 0U)&lt;BR /&gt;{&lt;BR /&gt;int i;&lt;BR /&gt;uint32_t subaddress;&lt;/P&gt;
&lt;P&gt;if (transfer-&amp;gt;subaddressSize &amp;gt; sizeof(handle-&amp;gt;subaddrBuf))&lt;BR /&gt;{&lt;BR /&gt;return kStatus_I2C_InvalidParameter;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;/* Prepare subaddress transmit buffer, most significant byte is stored at the lowest address */&lt;BR /&gt;subaddress = xfer-&amp;gt;subaddress;&lt;BR /&gt;for (i = (int)xfer-&amp;gt;subaddressSize - 1; i &amp;gt;= 0; i--)&lt;BR /&gt;{&lt;BR /&gt;handle-&amp;gt;subaddrBuf[i] = (uint8_t)subaddress &amp;amp; 0xffU;&lt;BR /&gt;subaddress &amp;gt;&amp;gt;= 8;&lt;BR /&gt;}&lt;BR /&gt;handle-&amp;gt;remainingSubaddr = transfer-&amp;gt;subaddressSize;&lt;BR /&gt;}&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kStartState;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;return kStatus_Success;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;/*!&lt;BR /&gt;* @brief Execute states until FIFOs are exhausted.&lt;BR /&gt;* @param handle Master nonblocking driver handle.&lt;BR /&gt;* @param[out] isDone Set to true if the transfer has completed.&lt;BR /&gt;* @retval #kStatus_Success&lt;BR /&gt;* @retval #kStatus_I2C_ArbitrationLost&lt;BR /&gt;* @retval #kStatus_I2C_Nak&lt;BR /&gt;*/&lt;BR /&gt;static status_t I2C_RunTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone)&lt;BR /&gt;{&lt;BR /&gt;uint32_t status;&lt;BR /&gt;uint32_t master_state;&lt;BR /&gt;struct _i2c_master_transfer *transfer;&lt;BR /&gt;status_t err;&lt;/P&gt;
&lt;P&gt;transfer = &amp;amp;(handle-&amp;gt;transfer);&lt;BR /&gt;bool ignoreNak = ((handle-&amp;gt;state == (uint8_t)kStopState) &amp;amp;&amp;amp; (handle-&amp;gt;remainingBytes == 0U)) ||&lt;BR /&gt;((handle-&amp;gt;state == (uint8_t)kWaitForCompletionState) &amp;amp;&amp;amp; (handle-&amp;gt;remainingBytes == 0U));&lt;/P&gt;
&lt;P&gt;*isDone = false;&lt;/P&gt;
&lt;P&gt;status = I2C_GetStatusFlags(base);&lt;/P&gt;
&lt;P&gt;if ((status &amp;amp; I2C_STAT_MSTARBLOSS_MASK) != 0U)&lt;BR /&gt;{&lt;BR /&gt;I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK);&lt;BR /&gt;return kStatus_I2C_ArbitrationLost;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;if ((status &amp;amp; I2C_STAT_MSTSTSTPERR_MASK) != 0U)&lt;BR /&gt;{&lt;BR /&gt;I2C_MasterClearStatusFlags(base, I2C_STAT_MSTSTSTPERR_MASK);&lt;BR /&gt;return kStatus_I2C_StartStopError;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;if ((status &amp;amp; I2C_STAT_MSTPENDING_MASK) == 0U)&lt;BR /&gt;{&lt;BR /&gt;return kStatus_I2C_Busy;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;/* Get the state of the I2C module */&lt;BR /&gt;master_state = (status &amp;amp; I2C_STAT_MSTSTATE_MASK) &amp;gt;&amp;gt; I2C_STAT_MSTSTATE_SHIFT;&lt;/P&gt;
&lt;P&gt;if (((master_state == (uint32_t)I2C_STAT_MSTCODE_NACKADR) ||&lt;BR /&gt;(master_state == (uint32_t)I2C_STAT_MSTCODE_NACKDAT)) &amp;amp;&amp;amp;&lt;BR /&gt;(ignoreNak != true))&lt;BR /&gt;{&lt;BR /&gt;/* Slave NACKed last byte, issue stop and return error */&lt;BR /&gt;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kWaitForCompletionState;&lt;BR /&gt;return kStatus_I2C_Nak;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;err = kStatus_Success;&lt;BR /&gt;switch (handle-&amp;gt;state)&lt;BR /&gt;{&lt;BR /&gt;case (uint8_t)kStartState:&lt;BR /&gt;if (handle-&amp;gt;remainingSubaddr != 0U)&lt;BR /&gt;{&lt;BR /&gt;/* Subaddress takes precedence over the data transfer, direction is always "write" in this case */&lt;BR /&gt;base-&amp;gt;MSTDAT = (uint32_t)transfer-&amp;gt;slaveAddress &amp;lt;&amp;lt; 1U;&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kTransmitSubaddrState;&lt;BR /&gt;}&lt;BR /&gt;else if (transfer-&amp;gt;direction == kI2C_Write)&lt;BR /&gt;{&lt;BR /&gt;base-&amp;gt;MSTDAT = (uint32_t)transfer-&amp;gt;slaveAddress &amp;lt;&amp;lt; 1;&lt;BR /&gt;handle-&amp;gt;state = (handle-&amp;gt;remainingBytes != 0U) ? (uint8_t)kTransmitDataState : (uint8_t)kStopState;&lt;BR /&gt;}&lt;BR /&gt;else&lt;BR /&gt;{&lt;BR /&gt;base-&amp;gt;MSTDAT = ((uint32_t)transfer-&amp;gt;slaveAddress &amp;lt;&amp;lt; 1) | 1u;&lt;BR /&gt;handle-&amp;gt;state = (handle-&amp;gt;remainingBytes != 0U) ? (uint8_t)kReceiveDataState : (uint8_t)kStopState;&lt;BR /&gt;}&lt;BR /&gt;/* Send start condition */&lt;BR /&gt;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTART_MASK;&lt;BR /&gt;break;&lt;/P&gt;
&lt;P&gt;case (uint8_t)kTransmitSubaddrState:&lt;BR /&gt;if (master_state != (uint32_t)I2C_STAT_MSTCODE_TXREADY)&lt;BR /&gt;{&lt;BR /&gt;return kStatus_I2C_UnexpectedState;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;/* Most significant subaddress byte comes first */&lt;BR /&gt;base-&amp;gt;MSTDAT = handle-&amp;gt;subaddrBuf[handle-&amp;gt;transfer.subaddressSize - handle-&amp;gt;remainingSubaddr];&lt;BR /&gt;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;&lt;BR /&gt;if (--(handle-&amp;gt;remainingSubaddr) != 0U)&lt;BR /&gt;{&lt;BR /&gt;/* There are still subaddress bytes to be transmitted */&lt;BR /&gt;break;&lt;BR /&gt;}&lt;BR /&gt;if (handle-&amp;gt;remainingBytes != 0U)&lt;BR /&gt;{&lt;BR /&gt;/* There is data to be transferred, if there is write to read turnaround it is necessary to perform&lt;BR /&gt;* repeated start */&lt;BR /&gt;handle-&amp;gt;state = (transfer-&amp;gt;direction == kI2C_Read) ? (uint8_t)kStartState : (uint8_t)kTransmitDataState;&lt;BR /&gt;}&lt;BR /&gt;else&lt;BR /&gt;{&lt;BR /&gt;/* No more data, schedule stop condition */&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kStopState;&lt;BR /&gt;}&lt;BR /&gt;break;&lt;/P&gt;
&lt;P&gt;case (uint8_t)kTransmitDataState:&lt;BR /&gt;if (master_state != (uint32_t)I2C_STAT_MSTCODE_TXREADY)&lt;BR /&gt;{&lt;BR /&gt;return kStatus_I2C_UnexpectedState;&lt;BR /&gt;}&lt;BR /&gt;base-&amp;gt;MSTDAT = *(handle-&amp;gt;buf)++;&lt;BR /&gt;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;&lt;BR /&gt;if (--handle-&amp;gt;remainingBytes == 0U)&lt;BR /&gt;{&lt;BR /&gt;/* No more data, schedule stop condition */&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kStopState;&lt;BR /&gt;}&lt;BR /&gt;handle-&amp;gt;transferCount++;&lt;BR /&gt;break;&lt;/P&gt;
&lt;P&gt;case (uint8_t)kReceiveDataBeginState:&lt;BR /&gt;if (master_state != (uint32_t)I2C_STAT_MSTCODE_RXREADY)&lt;BR /&gt;{&lt;BR /&gt;return kStatus_I2C_UnexpectedState;&lt;BR /&gt;}&lt;BR /&gt;(void)base-&amp;gt;MSTDAT;&lt;BR /&gt;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kReceiveDataState;&lt;BR /&gt;break;&lt;/P&gt;
&lt;P&gt;case (uint8_t)kReceiveDataState:&lt;BR /&gt;if (master_state != (uint32_t)I2C_STAT_MSTCODE_RXREADY)&lt;BR /&gt;{&lt;BR /&gt;return kStatus_I2C_UnexpectedState;&lt;BR /&gt;}&lt;BR /&gt;*(handle-&amp;gt;buf)++ = (uint8_t)base-&amp;gt;MSTDAT;&lt;BR /&gt;if (--handle-&amp;gt;remainingBytes != 0U)&lt;BR /&gt;{&lt;BR /&gt;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;&lt;BR /&gt;}&lt;BR /&gt;else&lt;BR /&gt;{&lt;BR /&gt;/* No more data expected, issue NACK and STOP right away */&lt;BR /&gt;if (0U == (transfer-&amp;gt;flags &amp;amp; (uint32_t)kI2C_TransferNoStopFlag))&lt;BR /&gt;{&lt;BR /&gt;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;&lt;BR /&gt;}&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kWaitForCompletionState;&lt;BR /&gt;}&lt;BR /&gt;handle-&amp;gt;transferCount++;&lt;BR /&gt;break;&lt;/P&gt;
&lt;P&gt;case (uint8_t)kStopState:&lt;BR /&gt;if ((transfer-&amp;gt;flags &amp;amp; (uint32_t)kI2C_TransferNoStopFlag) != 0U)&lt;BR /&gt;{&lt;BR /&gt;/* Stop condition is omitted, we are done */&lt;BR /&gt;*isDone = true;&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kIdleState;&lt;BR /&gt;break;&lt;BR /&gt;}&lt;BR /&gt;/* Send stop condition */&lt;BR /&gt;base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kWaitForCompletionState;&lt;BR /&gt;break;&lt;/P&gt;
&lt;P&gt;case (uint8_t)kWaitForCompletionState:&lt;BR /&gt;*isDone = true;&lt;BR /&gt;handle-&amp;gt;state = (uint8_t)kIdleState;&lt;BR /&gt;break;&lt;/P&gt;
&lt;P&gt;case (uint8_t)kIdleState:&lt;BR /&gt;default:&lt;BR /&gt;/* State machine shall not be invoked again once it enters the idle state */&lt;BR /&gt;err = kStatus_I2C_UnexpectedState;&lt;BR /&gt;break;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;return err;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 19 Oct 2021 08:42:00 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1357766#M3395</guid>
      <dc:creator>xiangjun_rong</dc:creator>
      <dc:date>2021-10-19T08:42:00Z</dc:date>
    </item>
    <item>
      <title>Re: LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag u</title>
      <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358104#M3396</link>
      <description>&lt;P&gt;Thanks for reply.&lt;/P&gt;&lt;P&gt;Is it really needed to reimplement own version of state machine instead of using standard SDK API functions? I'm absolutely OK with blocking mode so I want to keep it simple for now.&lt;/P&gt;&lt;P&gt;Do you have some explanation why the hell the last read command is changed to write? I already tried code with functions I2C_MasterWriteBlocking,&amp;nbsp;I2C_MasterReadBlocking and I2C_MasterStart/I2C_MasterStop but with same result. I analyzed code of I2C_MasterStart that seems to be quite simple and I added a debug print of read back of MSTDAT register to see the value when starting with I2C address. And as expected when write i saw value 0x70 and when read I saw 0x71 but on the scope (analyzed also carefully bit by bit) I see the read turned to write. And this behavior depends on flag of previous call MasterWriteBlocking&lt;/P&gt;&lt;P&gt;if ((err=I2C_MasterWriteBlocking(base, &amp;amp;buffer, 1, kI2C_TransferDefaultFlag))!=kStatus_Success)&lt;/P&gt;&lt;P&gt;// if ((err=I2C_MasterWriteBlocking(base, &amp;amp;buffer, 1, kI2C_TransferNoStopFlag))!=kStatus_Success)&lt;/P&gt;&lt;P&gt;If I use TransferNoStopFlag then read become write, see osci attached.&lt;/P&gt;&lt;P&gt;Also please have a look at the end of SCK sequence (2nd osci) where you can see a low-level pulse that has extemely short width - less than regular SCK pulses - what does it mean?&lt;/P&gt;</description>
      <pubDate>Tue, 19 Oct 2021 20:55:50 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358104#M3396</guid>
      <dc:creator>MartinDQ</dc:creator>
      <dc:date>2021-10-19T20:55:50Z</dc:date>
    </item>
    <item>
      <title>Re: LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag u</title>
      <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358365#M3397</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;Frankly speaking, I am not clear about your question, how do you know that transfer function changes from read to write? As far as I know that only the address command has the LSB which presents the READ or WRITE command.&lt;/P&gt;
&lt;P&gt;For the I2C protocol, the receiver must drive the data pin to LOW as ACK signal at the end of each byte, if the ACK is not received by transmitter if I2C is master writing phase, the master will stop by releasing the SCL/SDA, and both the SCL and SDA will be high,&amp;nbsp; so the I2C will stop.&lt;/P&gt;
&lt;P&gt;BR&lt;/P&gt;
&lt;P&gt;XiangJun Rong&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 20 Oct 2021 06:34:08 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358365#M3397</guid>
      <dc:creator>xiangjun_rong</dc:creator>
      <dc:date>2021-10-20T06:34:08Z</dc:date>
    </item>
    <item>
      <title>Re: LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag u</title>
      <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358710#M3398</link>
      <description>&lt;P&gt;Yes, the read/write is detemined by LSB of I2S slave address. I called function I2C_MasterStart with parameter kI2C_Read:&lt;/P&gt;&lt;P&gt;I2C_MasterStart(base, I2C_PCIESW_SLAVE_ADDR, kI2C_Read)&lt;/P&gt;&lt;P&gt;but as you can see on oscillogram it was turned to write (LSB=0). I put inside of I2C_MasterStart a debug read back of MSTDAT and when called with kI2C_Read I correctly read 0x71 but on oscillogram I see that 0x70 was shifted out by master instead. This is what I wonder about. And this behavior depends on previous call of I2C_MasterWriteBlocking function and its flag parameter. When kI2C_TransferDefaultFlag is used then I2C_MasterStart(base, I2C_PCIESW_SLAVE_ADDR, kI2C_Read) works as expected (send 0x71) while if kI2C_TransferNoStopFlag is used then following I2C_MasterStart(base, I2C_PCIESW_SLAVE_ADDR, kI2C_Read) send 0x70.&lt;/P&gt;&lt;P&gt;Here's my alternative code that use MasterWrite/ReadBlocking and I2C_MasterStart&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 20 Oct 2021 14:16:44 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358710#M3398</guid>
      <dc:creator>MartinDQ</dc:creator>
      <dc:date>2021-10-20T14:16:44Z</dc:date>
    </item>
    <item>
      <title>Re: LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag u</title>
      <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358716#M3399</link>
      <description>&lt;LI-CODE lang="c"&gt;  uint8_t buffer[6];                   // data buffer for I2C transfer (read/write)
  status_t err;
	if ((I2C_GetStatusFlags(base)&amp;amp;kI2C_MasterPendingFlag)==0) // if master is busy for some unknown reason
	  {                                  // restart the I2C master
    I2C_MasterEnable(base,false);      // otherwise it will hang in an endless loop
    I2C_MasterEnable(base,true);       // in SDK function I2C_PendingStatusWait()
	  }
	if ((err=I2C_MasterStart(base, I2C_PCIESW_SLAVE_ADDR, kI2C_Write))!=kStatus_Success) // initiate new master mode transfer by sending the START signal, write mode
		return(-1000000-err);              // if I2C fail to start due to timeout state reset should be done but API function I2C_MasterReset() does nothing
    
	buffer[0]=I2C_PCIESW_BLKWR;          // fill command code to Tx buffer, see page 56
	buffer[1]=4;                         // fill Byte count=4 to Tx buffer
	buffer[2]=0x04;                      // fill Command Byte1 to Tx buffer, bit2:0 - 3=write reg, 4=read reg, bit7:3 - reserved
	buffer[3]=0x00;                      // fill Command Byte2 to Tx buffer, bit3:0 - port_select4:1, bit7:4 - reserved
	buffer[4]=0xBC;                      // fill Command Byte3 to Tx buffer, bit7 - port_select0, bit6 - reserved, bit5:2 - Byte enable (0=not modif, 1=modif), bit1:0 - reg_addr11:10
	buffer[5]=0x3E;                      // fill Command Byte4 to Tx buffer, bit7:0 - reg_addr9:2 (reg_addr1:0 are always 0)
  if ((err=I2C_MasterWriteBlocking(base, &amp;amp;buffer, 6, kI2C_TransferDefaultFlag))!=kStatus_Success) // write block (6 Bytes), kI2C_TransferDefaultFlag = transfer starts with a start signal, stops with a stop signal
	  {
	  I2C_MasterStop(base);              // if error occours, send STOP
		return(-2000000-err);              // and return immediatelly
    }

  if ((err=I2C_MasterStart(base, I2C_PCIESW_SLAVE_ADDR, kI2C_Write))!=kStatus_Success) // initiate new master mode transfer by sending the START signal, write mode
	  {
	  I2C_MasterStop(base);              // if error occours, send STOP
		return(-3000000-err);              // and return immediatelly
    }
    
	buffer[0]=I2C_PCIESW_BLKR;           // fill read back command code to Tx buffer
//  if ((err=I2C_MasterWriteBlocking(base, &amp;amp;buffer, 1, kI2C_TransferDefaultFlag))!=kStatus_Success) // write block (1 Byte), kI2C_TransferDefaultFlag = transfer starts with a start signal, stops with a stop signal
  if ((err=I2C_MasterWriteBlocking(base, &amp;amp;buffer, 1, kI2C_TransferNoStopFlag))!=kStatus_Success) // write block (1 Byte), kI2C_TransferDefaultFlag = transfer starts with a start signal, stops with a stop signal
	  {
	  I2C_MasterStop(base);              // if error occours, send STOP
		return(-4000000-err);              // and return immediatelly
    }
// here happens the address byte is transmitted with LSB=0 as write instead read as required i kI2C_TransferNoStopFlag is used before
	if ((err=I2C_MasterStart(base, I2C_PCIESW_SLAVE_ADDR, kI2C_Read))!=kStatus_Success) // initiate new master mode transfer by sending the START signal, read mode
	  {
	  I2C_MasterStop(base);              // if error occours, send STOP
		return(-5000000-err);              // and return immediatelly
    }
    
  if ((err=I2C_MasterReadBlocking(base, &amp;amp;buffer, 5, kI2C_TransferDefaultFlag))!=kStatus_Success) // read block (5 Bytes), kI2C_TransferDefaultFlag = transfer starts with a start signal, stops with a stop signal
  	{
// returns error kStatus_I2C_ArbitrationLost (2605)
		I2C_MasterStop(I2C_BP);            // if error occours, send STOP
		return(-6000000-err);              // and return immediatelly
    }
		
*/		
	uart_printf("%02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
  return(0);&lt;/LI-CODE&gt;</description>
      <pubDate>Wed, 20 Oct 2021 14:15:19 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358716#M3399</guid>
      <dc:creator>MartinDQ</dc:creator>
      <dc:date>2021-10-20T14:15:19Z</dc:date>
    </item>
    <item>
      <title>Re: LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag u</title>
      <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358951#M3400</link>
      <description>&lt;P&gt;At last I wrote the transfer function at register level without using SK API, just register names from header and still getting the same result, I'm lost...&lt;/P&gt;&lt;LI-CODE lang="c"&gt;  uint8_t buffer[6];                   // data buffer for I2C transfer (read/write)
  int i;
	
	buffer[0]=I2C_PCIESW_BLKWR;          // fill command code to Tx buffer, see page 56
	buffer[1]=4;                         // fill Byte count=4 to Tx buffer
	buffer[2]=0x04;                      // fill Command Byte1 to Tx buffer, bit2:0 - 3=write reg, 4=read reg, bit7:3 - reserved
	buffer[3]=0x00;                      // fill Command Byte2 to Tx buffer, bit3:0 - port_select4:1, bit7:4 - reserved
	buffer[4]=0xBC;                      // fill Command Byte3 to Tx buffer, bit7 - port_select0, bit6 - reserved, bit5:2 - Byte enable (0=not modif, 1=modif), bit1:0 - reg_addr11:10
	buffer[5]=0x3E;                      // fill Command Byte4 to Tx buffer, bit7:0 - reg_addr9:2 (reg_addr1:0 are always 0)
	
  // Master write 1 byte to slave. Address 0x23, Data 0xdd. Polling mode.
  base-&amp;gt;CFG = I2C_CFG_MSTEN_MASK;
  while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
	if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(0)) // I2C_STAT_MSTST_IDLE
		return(-1);
	
  base-&amp;gt;MSTDAT = (I2C_PCIESW_SLAVE_ADDR &amp;lt;&amp;lt; 1) | 0; // address and 0 for RWn bit
  base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTART_MASK; // send start
  while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
  if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(2)) // I2C_STAT_MSTST_TX
		return(-2);
	
	for (i=0; i&amp;lt;6; i++)
		{
		base-&amp;gt;MSTDAT = buffer[i]; // send data
		base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; // continue transaction
		while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
		if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(2)) // I2C_STAT_MSTST_TX
			{
			base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; // send stop
			while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
			if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(0)) // I2C_STAT_MSTST_IDLE
				return(-5);
			return(-3);
			}
		}
	
  base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; // send stop
  while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
  if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(0)) // I2C_STAT_MSTST_IDLE
		return(-4);

// part 2	
  base-&amp;gt;MSTDAT = (I2C_PCIESW_SLAVE_ADDR &amp;lt;&amp;lt; 1) | 0; // address and 0 for RWn bit
  base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTART_MASK; // send start
  while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
  if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(2)) // I2C_STAT_MSTST_TX
		return(-6);

  base-&amp;gt;MSTDAT = I2C_PCIESW_BLKR; // send data
  base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; // continue transaction
	while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
	if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(2)) // I2C_STAT_MSTST_TX
		{
		base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; // send stop
		while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
		if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(0)) // I2C_STAT_MSTST_IDLE
			return(-8);
		return(-7);
		}
	
// part 3
  base-&amp;gt;MSTDAT = (I2C_PCIESW_SLAVE_ADDR &amp;lt;&amp;lt; 1) | 1; // address and 1 for RWn bit
  base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTART_MASK; // send start
  while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
  if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(1)) // I2C_STAT_MSTST_RX
		return(-9);
	
	for (i=0; i&amp;lt;5; i++)
		{
  	buffer[i] = base-&amp;gt;MSTDAT; // read data
		base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; // continue transaction
		while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
		if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(1)) // I2C_STAT_MSTST_RX
			{
			base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; // send stop
			while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
			if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(0)) // I2C_STAT_MSTST_IDLE
				return(-11);
			return(-10);
			}
		}

  base-&amp;gt;MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; // send stop
  while(!(base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTPENDING_MASK));
  if((base-&amp;gt;STAT &amp;amp; I2C_STAT_MSTSTATE_MASK) != I2C_STAT_MSTSTATE(0)) // I2C_STAT_MSTST_IDLE
		return(-12);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 20 Oct 2021 21:23:51 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1358951#M3400</guid>
      <dc:creator>MartinDQ</dc:creator>
      <dc:date>2021-10-20T21:23:51Z</dc:date>
    </item>
    <item>
      <title>Re: LPC54606 I2C transfer function accidentally changes read to write when kI2C_TransferNoStopFlag u</title>
      <link>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1359690#M3401</link>
      <description>&lt;P&gt;After all I found that problem was on slave side.&lt;/P&gt;&lt;P&gt;The PCIe switch implements 2 different protocols SMbus and I2C (over the same physical interface/pins). I was trying to send commands according to SMbus packet spec. When I tried to send packet according to I2C spec (it's simpler, eg. doesn't contain length Byte so packet is shorter) it works and all bytes are ACKed as expected. Both read reg and write reg works now.&lt;/P&gt;&lt;P&gt;But I cannot find anywhere in &lt;SPAN class=""&gt;PI7C9X2G1224GP&lt;/SPAN&gt; datasheet how is it determined what kind of protocol is used (how slave switches between them), they just describe 2 different protocols and let user try which works, huh, that was the catch...&lt;/P&gt;&lt;P&gt;Here I'm getting a nice read of VID/PID from reg 0:&lt;/P&gt;</description>
      <pubDate>Thu, 21 Oct 2021 20:17:26 GMT</pubDate>
      <guid>https://community.nxp.com/t5/MCUXpresso-SDK/LPC54606-I2C-transfer-function-accidentally-changes-read-to/m-p/1359690#M3401</guid>
      <dc:creator>MartinDQ</dc:creator>
      <dc:date>2021-10-21T20:17:26Z</dc:date>
    </item>
  </channel>
</rss>

