Hi everyone,
I have captured an I3C waveform as below picture:
The byte reading in this waveform as below:
Start, 0x7E (address, Write), [Repeated Start Bit], 0x31, .... , Stop
And I wish to reproduce the below I3C waveform via function "i3c_master_transfer_t".
The function I wrote as below:
However, the [Repeated Start Bit] is not appeared in this waveform:
In this case, I have a question wish to have brainstorm with you:
Can I add a [Repeated Start Bit] between "Slave address bit" and "Sub Address bit"?
解決済! 解決策の投稿を見る。
Hello @Jin_Tien ,
Thanks for your updated information.
To your new questions, could you please help to create the new case, then we can spend more time for the testing.
Normally, Write is used for write the code, Read, just sendout the clock, then the data is from slave side.
So, your read following data, should not from Write master side, should from slave.
If you think it still from the master, please help to create the new case, and let me know, and also attach your test code.
Best Regards,
kerry
Hi @Jin_Tien ,
Just take the SDK I3C code as an example:
\SDK_2_12_0_MIMXRT685-AUD-EVK\boards\mimxrt685audevk\driver_examples\i3c\polling_b2b_transfer\master\iar
/* subAddress = 0x01, data = g_master_rxBuff - read from slave.
start + slaveaddress(w) + subAddress + repeated start + slaveaddress(r) + rx data buffer + stop */
masterXfer.slaveAddress = I3C_MASTER_SLAVE_ADDR_7BIT;
masterXfer.direction = kI3C_Read;
masterXfer.busType = kI3C_TypeI2C;
masterXfer.subaddress = (uint32_t)deviceAddress;
masterXfer.subaddressSize = 1;
masterXfer.data = g_master_rxBuff;
masterXfer.dataSize = I3C_DATA_LENGTH - 1U;
masterXfer.flags = kI3C_TransferDefaultFlag;
result = I3C_MasterTransferBlocking(EXAMPLE_MASTER, &masterXfer);
if (result != kStatus_Success)
{
return -1;
}
You can see, the sequence is:
start + slaveaddress(w) + subAddress + repeated start + slaveaddress(r) + rx data buffer + stop
So, between the "Slave address bit" and "Sub Address bit", really no repeated start.
But in the following slaveaddress(r), it contains the repeated start.
If you want to add the repeated start between "Slave address bit" and "Sub Address bit", you need to modify the I3C_MasterTransferBlocking driver.
I3C_MasterRepeatedStart(base, transfer->busType, transfer->slaveAddress, kI3C_Read)
The above code will used to generate the repeated start.
Wish it helps you!
Best Regards,
Kerry
Hi @kerryzhou,
Thanks for your reply!
I've two more questions as below:
Can you provide some example to show how to modify here, thanks a millions times!
Hi @Jin_Tien ,
=>Do you need to use the private RnW Transfer?
I think you can write a new API like the I3C_MasterTransferBlocking for the private RnW transfer.
As I know, we didn't Add the private transfer API.
This is the I3C_MasterRepeatedStart, for the parameter, it should like this:
base, transfer->busType, transfer->slaveAddress, direction which is defined in :
masterXfer.slaveAddress = 0x30U;
masterXfer.data = g_master_rxBuff;
masterXfer.dataSize = I3C_DATA_LENGTH - 1U;
masterXfer.direction = kI3C_Read;
masterXfer.busType = kI3C_TypeI3CSdr;
masterXfer.flags = kI3C_TransferDefaultFlag;
masterXfer.ibiResponse = kI3C_IbiRespAckMandatory;
status_t I3C_MasterRepeatedStart(I3C_Type *base, i3c_bus_type_t type, uint8_t address, i3c_direction_t dir)
{
uint32_t mctrlVal;
/* Clear all flags. */
I3C_MasterClearStatusFlags(base, (uint32_t)kMasterClearFlags);
/* Issue start command. */
mctrlVal = base->MCTRL;
mctrlVal &= ~(I3C_MCTRL_TYPE_MASK | I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_DIR_MASK | I3C_MCTRL_ADDR_MASK |
I3C_MCTRL_RDTERM_MASK);
mctrlVal |= I3C_MCTRL_TYPE(type) | I3C_MCTRL_REQUEST(kI3C_RequestEmitStartAddr) | I3C_MCTRL_DIR(dir) |
I3C_MCTRL_ADDR(address);
base->MCTRL = mctrlVal;
return kStatus_Success;
}
=> Yes
3.But what should I actually write code to add only one [repeated start bit]?
=> From the RT600, you can see the start will send with address:
So, I think, maybe you can write your own code instead of the SDK API, let the 7E as the address, then no data, then repeat start +address.
Wish it helps you!
Best Regards,
Kerry
Hi @kerryzhou
Really thanks for your advise.
However, I still have more following issue wish to discuss with you.
Below is my main command to send I3C_Write command:
And below is my modified "I3C_MasterTransferBlocking", the full code of "I3C_MasterTransferBlocking" can refer to attached txt file:
What I trying to do is adding a Stop Bit, and the command will generate a Start Bit when sending SubAddress Byte.
And here's the waveform I got:
In this waveform, I have few questions that troubled me:
Q1. The Slave Address I wrote is 0x7E, but what I sent in this waveform is 0x40.
Also, the first byte only have 8 bits, the Ack bit is missing.
Q2. The Bit mark by left cursor (white line) is the "Stop Bit", right?
Q3. The Bit mark by right cursor (white line) is the "Re-Start Bit", right?
PS(Why I ask Q2 and Q3 is because the SDA seems not transient when SCL is High)
Q4. The SubAddress byte seem no problem, but the following data byte didn't send out.
The command just end when finish the SubAddress byte.
Do you have any advises for above issues?
Hi @Jin_Tien ,
Please also upload your test project, I will find time to test it on my RT685-EVK board.
Best Regards,
Kerry
Hi @kerryzhou ,
Do you mean which device is under testing now?
The DUT is made by our customer, and it's not a products on the market.
Is it possible that use the common I3C device, then use the "Private RnW transfer" to communicate?
Have a nice day,
Jin Tien
Hi @kerryzhou ,
Unfortunately, I can't reproduce this waveform without device.
The waveform will stop after slave address is sent.
So, could you use your device to reproduce the Private RnW transfer?
Or could you provide a modified code, and I can test in my side then update the result to you.
Have a nice day,
Jin Tien
Hi @kerryzhou ,
Could we hold a meeting to discuss about this issue?
It can help to align our current status and next action, thanks!
Have a nice day,
Jin Tien
Hi @Jin_Tien ,
Please keep patient, I will help you to check internally, whether RT685 can support Private RnW transfer or not.
BTW, which detail I3C slave you are using now? your custom board or a module?
Best Regards,
Kerry
Hi @kerryzhou ,
Sorry that make you misunderstanding, I just afraid that we have information gap.
I will wait until you confirm the capability of RT685.
For your question, the I3C slave we are tested is provided from our client.
It's a module with I3C bus, and needs to communicate via Private RnW transfer structure.
Have a nice day,
Jin Tien
Hi @kerryzhou ,
By the way, may I request the complete register map profile of RT685?
Have a nice day,
Jin Tien
Hi @Jin_Tien ,
Thanks for your patient!
Good news to you, the RT685 can support the private transfer, and we also don't need to modify the API, just when call the API, use the different flag and settings.
Please check the following code in master:
/* Reset dynamic address before DAA */
memset(&masterXfer, 0, sizeof(masterXfer));
masterXfer.slaveAddress = 0x7EU; /* Broadcast address */
masterXfer.subaddress = 0x06U; /* CCC command RSTDAA */
masterXfer.subaddressSize = 0U;
masterXfer.direction = kI3C_Write;
masterXfer.busType = kI3C_TypeI3CSdr;
masterXfer.flags = kI3C_TransferNoStopFlag;
masterXfer.ibiResponse = kI3C_IbiRespAckMandatory;
result = I3C_MasterTransferBlocking(EXAMPLE_MASTER, &masterXfer);
if (kStatus_Success != result)
{
return result;
}
memset(&masterXfer, 0, sizeof(masterXfer));
masterXfer.slaveAddress = slaveAddr;
masterXfer.data = g_master_txBuff;
masterXfer.dataSize = I3C_DATA_LENGTH;
masterXfer.direction = kI3C_Write;
masterXfer.busType = kI3C_TypeI3CSdr;
masterXfer.flags = kI3C_TransferDefaultFlag;
masterXfer.ibiResponse = kI3C_IbiRespAckMandatory;
result = I3C_MasterTransferBlocking(EXAMPLE_MASTER, &masterXfer);
if (result != kStatus_Success)
{
return -1;
}
This is the test result:
You can see, repeated start already occur!
Please note, flag have different define.
Wish it helps you!
Best Regards,
Kerry
Hi @kerryzhou ,
I've tried the code you provide, and modify as below:
void i3c_Arm_ReadDieID_WriteID0(void)
{
i3c_master_transfer_t masterXfer;
uint8_t i3c_data_temp[12] = {0xCE, 0xFA, 0x01, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00};
status_t result;
memset(&masterXfer, 0, sizeof(masterXfer));
masterXfer.slaveAddress = 0x7EU; /* Use Broadcast address to access slave*/
masterXfer.subaddress = 0x30U; /* Reg address */
masterXfer.subaddressSize = 0U;
masterXfer.direction = kI3C_Write;
masterXfer.busType = kI3C_TypeI3CSdr;
masterXfer.flags = kI3C_TransferNoStopFlag;
masterXfer.ibiResponse = kI3C_IbiRespAckMandatory;
result = I3C_MasterTransferBlocking(EXAMPLE_MASTER, &masterXfer);
if (kStatus_Success != result)
{
return result;
}
memset(&masterXfer, 0, sizeof(masterXfer));
masterXfer.slaveAddress = 0x7EU;
masterXfer.data = &i3c_data_temp;
masterXfer.dataSize = 12;
masterXfer.direction = kI3C_Write;
masterXfer.busType = kI3C_TypeI3CSdr;
masterXfer.flags = kI3C_TransferDefaultFlag;
masterXfer.ibiResponse = kI3C_IbiRespAckMandatory;
result = I3C_MasterTransferBlocking(EXAMPLE_MASTER, &masterXfer);
if (result != kStatus_Success)
{
return -1;
PRINTF("\r\n i3c_Arm_ReadDieID_WriteID0 Failed\r\n");
}
}
In above coding, 0x7E is slave address; 0x30 is our register address.
However, we saw two issue with this coding:
1. The waveform still no "Repeated Start Bit" between 0x7E(slave address byte) and 0x30(register address byte).
2. The decode value of waveform is 0x7E > 0xCE > 0xFA > ... , it shows that 0x30 (register address byte) is missing.
Another question, after we check your testing result, I have question for below wavefom:
Cond1. Please check the Red Mark in below pic., if the first bit is "Repeated Start", then after 8 bit data is register address which is 0x60, not 0x30 we want.
However, the 9th bit is missing.
Cond2. Please check the Yellow Mark in below pic., if the first 8 bit is register address which is 0x30. And the 9th bit is parity bit which is 0 also.
However, the Repeated Start is still non-exist.
Can you verify which condition is correct for this waveform, and answer the following question?
Have a nice day,
Jin Tien
Hi @Jin_Tien ,
Your code is wrong:
masterXfer.slaveAddress = 0x7EU; /* Use Broadcast address to access slave*/
masterXfer.subaddress = 0x30U; /* Reg address */
masterXfer.subaddressSize = 0U;
masterXfer.direction = kI3C_Write;
masterXfer.busType = kI3C_TypeI3CSdr;
masterXfer.flags = kI3C_TransferNoStopFlag;
masterXfer.ibiResponse = kI3C_IbiRespAckMandatory;
result = I3C_MasterTransferBlocking(EXAMPLE_MASTER, &masterXfer);
if (kStatus_Success != result)
{
return result;
}
The above 0X30 is not used, if you want to sendout 0X30, use the next frame:
masterXfer.slaveAddress = 0x30U;
masterXfer.data = &i3c_data_temp;
masterXfer.dataSize = 12;
masterXfer.direction = kI3C_Write;
masterXfer.busType = kI3C_TypeI3CSdr;
masterXfer.flags = kI3C_TransferDefaultFlag;
masterXfer.ibiResponse = kI3C_IbiRespAckMandatory;
result = I3C_MasterTransferBlocking(EXAMPLE_MASTER, &masterXfer);
if (result != kStatus_Success)
{
return -1;
PRINTF("\r\n i3c_Arm_ReadDieID_WriteID0 Failed\r\n");
}
}
The wave which I give you contains the repeated start, just as your picture mentioned.
Wish it helps you!
Best Regards,
Kerry
Hi @kerryzhou ,
I re-try the code you provide yesterday, but test result is still unexpected.
The code I modified as attached file: "Private RnW function test_Jin Tien_20230412_1030"
And it's output waveform as below:
Seems the 0x7E didn't send correctly, it becomes the 0x70.
And the 9th data bit is NACK because of the incorrect 0x7E.
Do you have any solution of this behavior?
Have a nice day,
Jin Tien
Hi @Jin_Tien ,
This is our test result:
We use two MIMXRT685-EVK to test it, one as the I3C master, another as slave, and the code is which I share with you, I attach it again:
Please check the following master code.
Wish it helps you!
Best Regards,
Kerry
Hi @kerryzhou ,
After directly copy your code, I can't upgrade directly because I don't have the "I3C_MasterGetDeviceListAfterDAA", may I ask which version SDK you are installed for this testing?
Also, if I keep the code "memset(&masterXfer, 0, sizeof(masterXfer));", the slave address will become 0x70, like previous failed waveform.
May I know the function of this code? And could I block this code?
Have a nice day,
Jin Tien
Hi @Jin_Tien ,
The project which I share with you is tested on two MIMXRT685-EVK, one is the master, one is the slave, the slave is just the SDK I3C slave code, totally no modification.
As we don't have your slave, so we use the RT685 as the slave.
If you have another RT685 board, you also can test it.
Best Regards,
kerry
Hi @kerryzhou ,
I have one good news and one bad news after testing.
For good news, I can create the same waveform as you tested in first command.
>> [Start+0x7E+Write+Ack, Sr+0x18+Write+Ack, 0xCE, 0xFA, ... following data byte] >> transfer success.
But for bad news, I have another issue as below:
In the 2nd waveform from SCOUT (original I3C Master), the byte after Sr bit is 0x18+Read.
However, the following data is still transfer from Master to Slave.
So, our new question is, does the RT685 able to "Write" data into Slave when the direction is set as "Read"?
Have a nice day,
Jin Tien