I am using the Cypress FX3 with the latest SDK (1.3.3)
I am polling an I2C slave device for a reply to a command. The slave device will NAK its address until processing is complete and data is ready.
To do this, I call CyU3PI2cReceiveBytes periodically to try to read data. I use its return value as well as the return value of CyU3PI2cGetErrorCode to determine if the read was successful or if the slave NAKed its address.
I am monitoring the I2C bus with a Saleae logic analyzer.
As shown in the image, after the host finishes transmitting the 9th clock pulse, it fails to retake control of the data line to produce a valid stop condition.
The I2C specification requires all transactions to start with a start condition and end with either a restart or a stop condition.
In addition to this, the slave component we use is specifically sensitive to missing stop conditions. It’s unclear if it’s sensitive to missing stop conditions while ACKing its address, but without producing this stop condition, I can’t tell.
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
preamble.length = 1;
preamble.buffer = (device_address | 0x01); //address here is already left shifted.
preamble.ctrlMask = 0x0000;
CyU3PThreadSleep( 2 );
status = CyU3PI2cReceiveBytes( &preamble, buffer, count, 0 );
Please make preamble.ctrlMask = 0x0000 | (1<<8). This forces a stop condition after one byte of preamble.