MIMXRT685-EVK_How to generate the repeated start via "i3c_master_transfer_t".

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MIMXRT685-EVK_How to generate the repeated start via "i3c_master_transfer_t".

Jump to solution
3,116 Views
Jin_Tien
Contributor II

Hi everyone,

I have captured an I3C waveform as below picture:

IMG_5280.JPG

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: 

Jin_Tien_0-1679901583211.png

However, the [Repeated Start Bit] is not appeared in this waveform:

IMG_5282.JPG

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"?

0 Kudos
1 Solution
2,617 Views
kerryzhou
NXP TechSupport
NXP TechSupport

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

View solution in original post

0 Kudos
21 Replies
2,936 Views
kerryzhou
NXP TechSupport
NXP TechSupport

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

0 Kudos
2,929 Views
Jin_Tien
Contributor II

Hi @kerryzhou,

Thanks for your reply!

I've two more questions as below:

1. I was searching the MIPI_I3C_Spec, and I found the below command structure (Private RnW Transfer):

MIPI_I3C_Private RnW.JPG

So, does MCUXPRESSO IDE have function for this private RnW data transfer?

 

 

2. According to your reply, I should call function [I3C_MasterRepeatedStart] in function [I3C_MasterTransferBlocking] as below, right?

Untitled.png

But what should I actually write code to add only one [repeated start bit]?

Because the 3rd parameter of function [I3C_MasterRepeatedStart(base, transfer->busType, transfer->slaveAddress, kI3C_Read)] need to write the slaveAddress, and I don't need to re-send a slaveAddress here.

 

Can you provide some example to show how to modify here, thanks a millions times!

0 Kudos
2,921 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @Jin_Tien ,

1. I was searching the MIPI_I3C_Spec, and I found the below command structure (Private RnW Transfer):

=>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;
}

2. According to your reply, I should call function [I3C_MasterRepeatedStart] in function [I3C_MasterTransferBlocking] as below, right?

=> Yes

3.But what should I actually write code to add only one [repeated start bit]?

 

Because the 3rd parameter of function [I3C_MasterRepeatedStart(base, transfer->busType, transfer->slaveAddress, kI3C_Read)] need to write the slaveAddress, and I don't need to re-send a slaveAddress here.

=> From the RT600, you can see the start will send with address:

kerryzhou_0-1680078154701.png

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

 

 

0 Kudos
2,902 Views
Jin_Tien
Contributor II

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:

question_command_20230330.JPG

 

And below is my modified "I3C_MasterTransferBlocking", the full code of "I3C_MasterTransferBlocking" can refer to attached txt file:

question_20230330.JPG

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:

IMG_5317.JPG

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?

0 Kudos
2,881 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @Jin_Tien ,

    Please also upload your test project, I will find time to test it on my RT685-EVK board.

Best Regards,

Kerry

0 Kudos
2,879 Views
Jin_Tien
Contributor II

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

0 Kudos
2,876 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @Jin_Tien 

 Can you reproduce the issues on the MIMXRT685 directly?

 

Best Regards,

Kerry

0 Kudos
2,784 Views
Jin_Tien
Contributor II

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

0 Kudos
2,782 Views
Jin_Tien
Contributor II

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

0 Kudos
2,779 Views
kerryzhou
NXP TechSupport
NXP TechSupport

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

0 Kudos
2,769 Views
Jin_Tien
Contributor II

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

0 Kudos
2,733 Views
Jin_Tien
Contributor II

Hi @kerryzhou ,

By the way, may I request the complete register map profile of RT685?

RT600 Register.JPG

Have a nice day,

Jin Tien

0 Kudos
2,721 Views
kerryzhou
NXP TechSupport
NXP TechSupport

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:

kerryzhou_0-1680858284737.png

You can see, repeated start already occur!

Please note, flag have different define.

Wish it helps you!

Best Regards,

Kerry

 

 

0 Kudos
2,655 Views
Jin_Tien
Contributor II

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.

I3C_20230411.JPG

 

 

Another question, after we check your testing result, I have question for below wavefom:

Question of Sr.JPG

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

0 Kudos
2,645 Views
kerryzhou
NXP TechSupport
NXP TechSupport

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.

kerryzhou_0-1681201119801.png

Wish it helps you!

Best Regards,

Kerry

 

 

 

0 Kudos
2,628 Views
Jin_Tien
Contributor II

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:

S__32563510.jpg

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

0 Kudos
2,625 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @Jin_Tien ,

  This is our test result:

kerryzhou_0-1681275385886.png

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

 

0 Kudos
2,579 Views
Jin_Tien
Contributor II

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

0 Kudos
2,570 Views
kerryzhou
NXP TechSupport
NXP TechSupport

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

0 Kudos
2,478 Views
Jin_Tien
Contributor II

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:

issue_2nd command.jpg

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

0 Kudos