I connected two LPC5536-EVK boards for I3C communication, with one configured as the I3C Master and the other as the I3C Slave. If the Master’s specified read length exceeds the amount of data provided by the Slave, the Master gets stuck in the Read function I3C_MasterTransferBlocking. Based on the waveform, the signaling appears correct, so I believe the issue is on the Master side.
In my provided example, the Slave’s data is [0x01, 0x02], with a length of only 2 bytes. However, the Master specifies a read length of 3. Therefore, at the end of the 2nd byte, the Slave returns the T-Bit as 0 to indicate the end of the message.
Test Steps:
(1) Reset slave board
(2) Reset master board
For the definition of the T-Bit, please refer to MIPI I3C Basic Specification v1.1.1.
Section 5.1.2.3.4, Ninth Bit of SDR Target Returned (Read) Data as End-of-Data
In I2C, Read from Target has the issue that only the Controller ends the Read, so the Target has no ability to control the amount of data it returns. In I3C SDR, by contrast, the Target controls the number of data Words it returns; but it also allows the I3C Controller to abort the Read prematurely when necessary.
...
Solved! Go to Solution.
Hi @bell_huang
I have tested it.
You are right.
And i checked the this I3C_MasterReceive function.
/* Check RX data */
if ((0UL != rxSize) && (0UL != (base->MDATACTRL & I3C_MDATACTRL_RXCOUNT_MASK)))
{
*buf++ = (uint8_t)(base->MRDATAB & I3C_MRDATAB_VALUE_MASK);
rxSize--;
if ((flags & (uint32_t)kI3C_TransferDisableRxTermFlag) == 0UL)
{
if ((!isRxAutoTerm) && (rxSize == 1U))
{
base->MCTRL |= I3C_MCTRL_RDTERM(1U);
}
}
}
It reads data depend on the data size.
And i tested the i3c interrupt demo, it support this feature.
I set dataSize to 50.
And it never hang.
You can try it.
BR
Harry
Hi @bell_huang
I have tested it.
You are right.
And i checked the this I3C_MasterReceive function.
/* Check RX data */
if ((0UL != rxSize) && (0UL != (base->MDATACTRL & I3C_MDATACTRL_RXCOUNT_MASK)))
{
*buf++ = (uint8_t)(base->MRDATAB & I3C_MRDATAB_VALUE_MASK);
rxSize--;
if ((flags & (uint32_t)kI3C_TransferDisableRxTermFlag) == 0UL)
{
if ((!isRxAutoTerm) && (rxSize == 1U))
{
base->MCTRL |= I3C_MCTRL_RDTERM(1U);
}
}
}
It reads data depend on the data size.
And i tested the i3c interrupt demo, it support this feature.
I set dataSize to 50.
And it never hang.
You can try it.
BR
Harry
I tried switching to I3C_MasterTransferNonBlocking. Although it does not hang, the user has no way of knowing how many bytes the Slave actually provided. In the example I shared, it needs to return information such as transferred count = 2.
In your test with the lpcxpresso55s36_i3c_interrupt_b2b_transfer_master example, even though you changed dataSize to 50, the code still prints a fixed 32 bytes afterward, which happens to match the Slave’s provided transferred count.
In practical applications, such as the case I mentioned in another post about IBI with Pending Read Notification , after the IBI occurs and a Private Read is performed, the Slave’s transferred count is unpredictable and can vary. When the Master calls the read transfer function with a large buffer, the transfer function needs to return the actual transferred count.
Although the user cannot determine how many bytes were actually transferred by I3C_MasterTransferNonBlocking, it seems to be sufficient for my application.