I'm running I3C on LPC5536-EVK and find out that GETMRL command doesn't seem to work for any of the sensors. This issue can be reproduced in Building an I3C Sensor Network Using LPC553x/LPC55S3x example.
To begin with the conclusion: if GETMRL reads 3 bytes, it gets stuck after reading two bytes. However, if GETMRL reads only 2 bytes, it does not get stuck.
SDK: SDK_2.16.000_LPCXpresso55S36
At the beginning, if we call the I3C_BusMasterGetDeviceInfo() function from fsl_component_i3c.h, the function will get stuck. The I3C_BusMasterGetDeviceInfo() function includes several commands, such as GETPID, GETBCR, GETDCR, GETMRL, and GETMWL.
To simplify things, we copied out the two functions I3C_BusMasterGetBCR (GETBCR) and I3C_BusMasterGetMaxReadLength (GETMRL) and tested them individually.
static status_t I3C_BusMasterGetBCR(i3c_device_t *master, i3c_device_information_t *info)
{
uint8_t bcr;
i3c_ccc_cmd_t getBCRCmd = {0};
status_t result = kStatus_Success;
getBCRCmd.isRead = true;
getBCRCmd.cmdId = I3C_BUS_CCC_GETBCR;
getBCRCmd.destAddr = info->dynamicAddr;
getBCRCmd.data = &bcr;
getBCRCmd.dataSize = 1U;
result = I3C_BusMasterSendCCC(master, &getBCRCmd);
info->bcr = bcr;
return result;
}
static status_t I3C_BusMasterGetMaxReadLength(i3c_device_t *master, i3c_device_information_t *info)
{
i3c_ccc_cmd_t getMRLCmd = {0};
status_t result = kStatus_Success;
getMRLCmd.isRead = true;
getMRLCmd.cmdId = I3C_BUS_CCC_GETMRL;
getMRLCmd.destAddr = info->dynamicAddr;
getMRLCmd.data = malloc(3U);
getMRLCmd.dataSize = 3U;
/*
* When the device does not have IBI payload GETMRL only returns 2
* bytes of data.
*/
if ((info->bcr & I3C_BUS_DEV_BCR_IBI_PAYLOAD_MASK) == 0U)
{
getMRLCmd.dataSize -= 1U;
}
result = I3C_BusMasterSendCCC(master, &getMRLCmd);
uint8_t *pData = getMRLCmd.data;
if ((info->bcr & I3C_BUS_DEV_BCR_IBI_PAYLOAD_MASK) != 0U)
{
info->maxIBILength = pData[2];
}
info->maxReadLength = (uint16_t)pData[0] << 8UL | (uint16_t)pData[1];
free(getMRLCmd.data);
return result;
}
Then we can reproduce the stuck issue by calling them:
i3c_device_information_t device_info;
memset(&device_info, 0, sizeof(device_info));
device_info.dynamicAddr = icm42688p_sensorAddr;
I3C_BusMasterGetBCR(&demo_masterDev, &device_info);
I3C_BusMasterGetMaxReadLength(&demo_masterDev, &device_info);
After checking the waveform, we found that it gets stuck at GETMRL. After reading the MRL LSB, the SCL line stops and doesn't move anymore.
In previous case, I3C_BusMasterGetBCR reads the BCR value of the ICM42688P as 39 (= b00100111), which indicates that it supports BCR[2] IBI Payload. As a result, The dataSize of GETMRL in I3C_BusMasterGetMaxReadLength is 3.
If we assume that it does not support BCR[2] IBI Payload, that is, do not call I3C_BusMasterGetBCR, then the dataSize of GETMRL in I3C_BusMasterGetMaxReadLength is 2.
i3c_device_information_t device_info;
memset(&device_info, 0, sizeof(device_info));
device_info.dynamicAddr = icm42688p_sensorAddr;
//I3C_BusMasterGetBCR(&demo_masterDev, &device_info);
I3C_BusMasterGetMaxReadLength(&demo_masterDev, &device_info);
Then we can see GETMRL workable, it no longer gets stuck.
In MIPI I3C Basic℠ v1.1.1 , 5.1.9.3.6 Set/Get Max Read Length (SETMRL/GETMRL), the 3rd byte is IBI Payload Size which is optional. That is, if the sensor support IBI Payload, GETMRL shall read 3 bytes. But in current SDK, it seems get stuck if we read 3 bytes.
解決済! 解決策の投稿を見る。
Hi @bell_huang
I am using the latest I3C driver file (MAKE_VERSION(2, 13, 1)), and when the data size is 3, it no longer locks up. After confirming with the SDK team, there is indeed an update. So you can test it.
Although there is no lock, the 3rd byte is not received. After analysis, it appears that the slave actively terminated the read operation. So you can try to another sensor or consult the sensor manufacturer for further assistance.
BR
Harry
Hi @bell_huang
In order to reproduce this issue quickly.
Can you share the i3c_master_read_sensor_icm42688p.c?
BR
Harry
Hi @Harry_Zhang ,
Can you reproduce with attached i3c_sensor_network.c ?
Hi @bell_huang
I am using the latest I3C driver file (MAKE_VERSION(2, 13, 1)), and when the data size is 3, it no longer locks up. After confirming with the SDK team, there is indeed an update. So you can test it.
Although there is no lock, the 3rd byte is not received. After analysis, it appears that the slave actively terminated the read operation. So you can try to another sensor or consult the sensor manufacturer for further assistance.
BR
Harry
Hi @Harry_Zhang ,
Thanks for your test. Can you share the link of latest I3C driver file (MAKE_VERSION(2, 13, 1))? I cannot find it out in MCUXpresso SDK Dashboard . There are only 25.03.00, 2.16.000, 2.15.000.
I test LSM6DST which is an another sensor that supports GETMRL 3 bytes. The original I3C driver doesn't lock.
In comparison, ICM42688P pulls low the T-bit of LSB byte to indicate the end of the data. It means that if the sensor doesn't support GETMRL 3 bytes and the original driver want to read 3 bytes, then it will be locked.
I think the best is: The GETMRL function returns fail/error status if the driver want to read 3 bytes and the sensor doesn't support 3 bytes (pull low the T-bit of LSB byte).
However, it is acceptable: The GETMRL function will not lock at least.
Hi @bell_huang
You can download the latest 25.03.00 SDK.
"I think the best is: The GETMRL function returns fail/error status if the driver want to read 3 bytes and the sensor doesn't support 3 bytes (pull low the T-bit of LSB byte)."
Thank you for your suggestion. I will report it to the SDK team. Hope to improve in the future.
BR
Harry
Thanks. I tested IDE v24.12.148 & SDK 25.03.00. The GETMRL no longer get stuck.
Test step:
(1) Import SDK example(s)... -> driver_examples -> i3c ->i3c_master_read_sensor_icm42688p
(2) Remove source/i3c_master_read_sensor_icm42688p.c
(3) Add attached i3c_sensor_network.c to source/i3c_sensor_network.c
Hi @Harry_Zhang ,
This issue can be reproduced in Building an I3C Sensor Network Using LPC553x/LPC55S3x example.