How to add stop bit during CX3 I2C read timing sequence?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
ZhYu_4525096
Level 1
Level 1

Hi all

     I came across problem when use CX3 I2C communicate with slave device, here is details:

     register address and read bytes are 2 bytes

     1. read code by I2C:

CyU3PReturnStatus_t I2C_SensorRead(uint16_t regAddr, uint8_t count, uint8_t *buf)

{

    CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

    CyU3PI2cPreamble_t preamble;

    uint8_t cnt=0;

    for(cnt=0; cnt<3 ; cnt++)

    {

        preamble.buffer[1] = CY_U3P_GET_MSB (regAddr);

        preamble.buffer[2] = CY_U3P_GET_LSB (regAddr);

        preamble.buffer[3] = SENSOR_I2C_READ_ADDRESS; /* Slave address: Read operation */

        preamble.buffer[0] = SENSOR_I2C_WRITE_ADDRESS; /* Slave address: write operation */

        preamble.length = 4;

        preamble.ctrlMask = 0x0004;

        status = CyU3PI2cReceiveBytes (&preamble, buf, count,0);

        CyU3PThreadSleep(1);

        if (status == CY_U3P_SUCCESS)

        {

            break;

        }

//#ifdef SENSOR_DEBUG

        else

            CyU3PDebugPrint(4,"\r\nImageSensorSensorRead Failed addr=0x%x",regAddr);

//#endif

    }

    return status;

}

2. CX3 I2C read waveform captured by Logic Analyzier, I didn't get right register data

捕获2.PNG

3. Cause slave device demand a stop bit after register adress sended as below, so How to send the stop bit after the third byte, if set ctrlMask as 0x0404, only get stop bit, because API GUIDE said "If both bits are set for an index, then the stop condition takes priority", Anybody can tell me How to get below waveform, Thank you!

3.JPG

0 Likes
1 Solution

Hi Sridhar

     Thanks for your reply, YES, stop condition is mandatory, I had tried to set Start and Stop bit at the same bit(crtlMask as 0x0404), as the API guide said that stop bit take priority, There is only STOP condition followed by the third byte(NO Re-Start), show as below:

捕获1.PNG

Because I didn't find any Cypress read API which can afford the waveform, I had to combine two APIs to generate this, code and waveform as below, firstly send slave and register address by CyU3PI2cTransmitBytes, add a stop condition automatically. secondly send  slave address and receive two data bytes, and there is also start condition at beginning. although the waveform is what I want , But I don't make sure if It is the right way to use Cypress APIs, Please help to  confirm, Thank you !

捕获2.PNG

CyU3PReturnStatus_t I2C_SensorRead_Test(uint16_t regAddr, uint8_t count, uint8_t *buf)
{
    CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
    CyU3PI2cPreamble_t preamble;
    uint8_t cnt=0;

    for(cnt=0; cnt<3 ; cnt++)
    {
        preamble.buffer[1] = CY_U3P_GET_MSB (regAddr);
        preamble.buffer[2] = CY_U3P_GET_LSB (regAddr);
        preamble.buffer[0] = SENSOR_I2C_WRITE_ADDRESS; /* Slave address: write operation */
        preamble.length = 1;
        preamble.ctrlMask = 0x0000;

        status = CyU3PI2cTransmitBytes (&preamble, &(preamble.buffer[1]), 2, 0);
        //CyU3PThreadSleep(1);
        if (status != CY_U3P_SUCCESS)
        {
            CyU3PDebugPrint(4,"\r\nImageSensorSensorWrite Failed addr=0x%x",regAddr);
            return status;
        }

        //preamble.buffer[1] = CY_U3P_GET_MSB (regAddr);
        //preamble.buffer[2] = CY_U3P_GET_LSB (regAddr);
        //preamble.buffer[3] = SENSOR_I2C_READ_ADDRESS; /* Slave address: Read operation */
        //preamble.buffer[0] = SENSOR_I2C_WRITE_ADDRESS; /* Slave address: write operation */
        preamble.buffer[0] = SENSOR_I2C_READ_ADDRESS;
        preamble.length = 1;
        preamble.ctrlMask = 0x0000;

        status = CyU3PI2cReceiveBytes (&preamble, buf, count,0);
        CyU3PThreadSleep(1);
        if (status == CY_U3P_SUCCESS)
        {
            break;
        }
//#ifdef SENSOR_DEBUG
        else
            CyU3PDebugPrint(4,"\r\nImageSensorSensorRead Failed addr=0x%x",regAddr);
//#endif
    }
    return status;
}

View solution in original post

0 Likes
4 Replies
ZhYu_4525096
Level 1
Level 1

alamandaa_16​ Please help check the problem, Thanks

0 Likes
KandlaguntaR_36
Moderator
Moderator
Moderator
25 solutions authored 10 solutions authored 5 solutions authored

Hello,

Is Stop bit before re-start bit mandatory as per the I2C slave functionality?

Have you tried setting the same bit for Start and Stop condition? Please share the result of it.

Is it stop bit condition taking the priority?

Regards,

Sridhar

0 Likes

Hi Sridhar

     Thanks for your reply, YES, stop condition is mandatory, I had tried to set Start and Stop bit at the same bit(crtlMask as 0x0404), as the API guide said that stop bit take priority, There is only STOP condition followed by the third byte(NO Re-Start), show as below:

捕获1.PNG

Because I didn't find any Cypress read API which can afford the waveform, I had to combine two APIs to generate this, code and waveform as below, firstly send slave and register address by CyU3PI2cTransmitBytes, add a stop condition automatically. secondly send  slave address and receive two data bytes, and there is also start condition at beginning. although the waveform is what I want , But I don't make sure if It is the right way to use Cypress APIs, Please help to  confirm, Thank you !

捕获2.PNG

CyU3PReturnStatus_t I2C_SensorRead_Test(uint16_t regAddr, uint8_t count, uint8_t *buf)
{
    CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
    CyU3PI2cPreamble_t preamble;
    uint8_t cnt=0;

    for(cnt=0; cnt<3 ; cnt++)
    {
        preamble.buffer[1] = CY_U3P_GET_MSB (regAddr);
        preamble.buffer[2] = CY_U3P_GET_LSB (regAddr);
        preamble.buffer[0] = SENSOR_I2C_WRITE_ADDRESS; /* Slave address: write operation */
        preamble.length = 1;
        preamble.ctrlMask = 0x0000;

        status = CyU3PI2cTransmitBytes (&preamble, &(preamble.buffer[1]), 2, 0);
        //CyU3PThreadSleep(1);
        if (status != CY_U3P_SUCCESS)
        {
            CyU3PDebugPrint(4,"\r\nImageSensorSensorWrite Failed addr=0x%x",regAddr);
            return status;
        }

        //preamble.buffer[1] = CY_U3P_GET_MSB (regAddr);
        //preamble.buffer[2] = CY_U3P_GET_LSB (regAddr);
        //preamble.buffer[3] = SENSOR_I2C_READ_ADDRESS; /* Slave address: Read operation */
        //preamble.buffer[0] = SENSOR_I2C_WRITE_ADDRESS; /* Slave address: write operation */
        preamble.buffer[0] = SENSOR_I2C_READ_ADDRESS;
        preamble.length = 1;
        preamble.ctrlMask = 0x0000;

        status = CyU3PI2cReceiveBytes (&preamble, buf, count,0);
        CyU3PThreadSleep(1);
        if (status == CY_U3P_SUCCESS)
        {
            break;
        }
//#ifdef SENSOR_DEBUG
        else
            CyU3PDebugPrint(4,"\r\nImageSensorSensorRead Failed addr=0x%x",regAddr);
//#endif
    }
    return status;
}

0 Likes

Hello,

You have used Cypress APIs to meet your slave requirement. That will be fine.

Regards,

Sridhar

0 Likes