I am trying to use the I3C peripheral on the FRDM-MCXA153 to communicate with an I2C target that requires clock stretching. I have added 10k pull-up resistors at R61 and R62 as instructed here https://community.nxp.com/t5/MCX-Microcontrollers/I3C-SDA-and-SCL-pin-configured-for-Pullup-Enabled-...). This does seem to get I2C communication started. The I2C target device ACKs its address, and I can successfully send a command to the device. The device then holds the clock low while preparing its response. However, when the target finally pulls SDA low to ACK that its response is ready and then releases SCL, the MCXA153 controller fails to resume clocking.
Is there a setting that is necessary to prevent this kind of timeout?
I am using the fsl_i3c driver. The write operation is performed by I3C_MasterTransferBlocking. That function calls I3C_MasterSend at line 1974 in order to send the command byte 0x08. Following the write to the controller data byte register, I3C_MasterWaitForComplete(base, false) is called (line 1558). This returns a result of 7903 (kStatus_I3C_WriteAbort). How do I get the controller to wait until the clock stretching is complete to check for the ACK?
For your reference, if I instead use the LPI2C peripheral to communicate with the same target, the ACK is properly processed following the clock stretching. Here is what successful communication looks like:
You can see that following the 0x08 write, and the long clock stretch, the controller resumes clocking in order to process the ACK (at approximately the +0.1ms marker). Since the ACK was received in this case, the controller continues to perform a successful two byte read operation.
Solved! Go to Solution.
Hi @aberger
Thanks for your information.
I am aligned with Design team, MCXA153 I3C doesn't support I2C stretch function.
MCXA156 I3C supports I2C stretch function.
BR
Hang
I have updated the i3c_polling_b2b_transfer_master demo to communicate with the I2C target device I am using (Texas Instruments BQ40Z80 Battery Pack manager). (The updated project is attached, with an updated README to describe the physical connections necessary. If you use git, you can compare the top of the main branch with the original commit to view differences).
In particular, I have configured the I3C SDA and SCL as open drain in pin_mux.c. Furthermore, note the differences in the masterConfig and the masterXfer.
+ // masterConfig.enableMaster = EXAMPLE_I2C_CTRL_MODE;
+ masterConfig.disableTimeout = true;
- masterConfig.enableOpenDrainStop = false;
+ masterConfig.enableOpenDrainStop = true;
+ masterConfig.hKeep = kI3C_MasterPassiveSDASCL;
- masterXfer.subaddress = 0x01;
- masterXfer.subaddressSize = 1;
+ masterXfer.subaddress = BMS_TEMP_CMD;
+ masterXfer.subaddressSize = BMS_CMD_LEN;
- masterXfer.dataSize = I3C_DATA_LENGTH - 1U;
+ masterXfer.dataSize = I3C_DATA_LENGTH;
+ masterXfer.ibiResponse = kI3C_IbiRespNack;
With the above changes to attempt Open Drain I2C communication (to allow clock stretching by the target), the communication looks like that from the original post:
The target device ACKs its address, so the controller sends the query temperature command (0x08). The target then attempts clock stretching, but when it finally pulls SDA low to ACK and releases the SCL, the controller fails to clock out the ACK. I3C_MasterTransferBlocking returns with a result of 7903 (kStatus_I3C_WriteAbort /*!< The slave device sent a NAK in response to a write. */)
I also tried to implement I3C_MCONFIG[MSTENA] = 0b11. According to the Reference Manual, this enables I2C Controller Mode to allow clock stretching. If you uncomment line 86 (masterConfig.enableMaster = EXAMPLE_I2C_CTRL_MODE;), the I3C peripheral should be configured in this mode. Note that the SDK fsl_i3c driver doesn't even include I2C Controller mode in the i3c_master_enable_t.
However, with MSTENA = 0b11, the communication fails even earlier. The controller actually fails to properly clock out the target address, which should be 0x0B + Write bit = 0b:0001_0110. Instead, only 7 bits are transferred: 0b000_1111.
It is beginning to appear that the I3C peripheral cannot support I2C communications with clock stretching. (Please see this article, which seems to imply the same: https://www.planetanalog.com/the-i3c-compatibility-with-i2c-and-clock-stretching/). If the I3C peripheral on the MCX A153 does not support I2C clock stretching, this would be a gross error of the Reference Manual.
Hi @aberger
I use two MCXA153s, one as the controller and the other as the target, and they communicate directly through I2C. My test examples are i3c_polling_b2b_transfer_master and i3c_polling_b2b_transfer_slave in the SDK.
The MCXA153 controller can resume clocking.
BR
Hang
Hi @HangZhang,
This is not helpful. There is no evidence of the slave doing any clock stretching in this example.
Furthermore, looking at the example code, there are several issues that make this example not relevant to my inquiry.
I3C0_SDA and I3C0_SCL are configured with Open Drain disabled. This will not permit clock stretching.
The i3c_master_config_t masterConfig is setup as follows:
enableMaster = kI3C_MasterOn = 1U; MSTENA should be = 3U for I2C Controller mode. This isn't even an enumerated option in i3c_master_enable_t!
hKeep = kI3C_MasterHighKeeperNone = 0U; HKEEP should be = 3U for Passive on SDA SCL for I2C clock stretching mode.
Hi @aberger
Thanks for your information.
I am aligned with Design team, MCXA153 I3C doesn't support I2C stretch function.
MCXA156 I3C supports I2C stretch function.
BR
Hang
Hi @HangZhang, Thank you for clarifying this point.
This is quite frustrating to learn, as the MCXA 153 Reference Manual mentions "clock stretching" 4 times in the I3C chapter:
pg 1195: Special mode for old-style I2C buses (no targets) with clock stretching.
pg 1216: SKEW > 0 when clock stretching feature is not required. SKEW = 0 when clock stretching feature is required.
pg 1217: If this field [HKEEP] is 11b, passive on SDA and SCL, can Hi-Z (high-impedance) both for bus free (Idle), and can Hi-Z SDA for hold. This is for I2C Clock Stretching mode, where both SCL and SDA are open drain.
pg 1218: Legacy I2C—if this field [MSTENA] is 11b, I2C Controller mode uses an open-drain clock (to allow clock stretching) and relies on passive pull-up resistors (PURs) on both SCL and SDA.
The MCXA 156 Reference Manual is nearly identical with one small exception: the mention of "no targets" is absent in discussion of the I3C Features and its use with old-style I2C buses
pg 1579: Special option in controller for old-style I2C buses with clock stretching.
Apparently that one small difference between the two manuals should be interpreted that I2C targets are not permitted to clock stretch when communicating with the MCXA 153 I3C peripheral.