fx3 i2c

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

cross mob
gean_3054931
Level 5
Level 5
10 likes given 5 likes given First like received

Hello,

I am using i2c example cyfxusbi2cregmode.Fx3 is connected to image sensor through i2c.

i am trying to read and write data to sensor.Debugging with segger j link.

below is the code.

if (isRead)

        {

            /* Update the preamble information. */

           // preamble.length    = 4;

           // preamble.buffer[0] = devAddr;

           // preamble.buffer[1] = (uint8_t)(byteAddress >> 8);

           // preamble.buffer[2] = (uint8_t)(byteAddress & 0xFF);

           /// preamble.buffer[3] = (devAddr | 0x01);

           // preamble.ctrlMask  = 0x0004;

            preamble.buffer[0] = 0xBA;//slaveAddr;

           // preamble.buffer[1] = 0x00;//highAddr;

            preamble.buffer[2] = 0x00;//lowAddr;

            preamble.buffer[3] = 0xBB;//lowAddr;

            preamble.length    = 3;             /*  Three byte preamble. */

            preamble.ctrlMask  = 0x0004;        /*  No additional start and stop bits. */

           // buffer[0] =00;// highData;

           // buffer[1] = 00;//lowData;

         //   status = CyU3PI2cReceiveBytes (&preamble, buffer, (pageCount == 1) ? resCount : glI2cPageSize, 0);

            status = CyU3PI2cReceiveBytes (&preamble, buffer, 2, 0);

            if (status != CY_U3P_SUCCESS)

            {

                return status;

            }

        }

        else /* Write */

        {

            /* Update the preamble information. */

         //   preamble.length    = 3;

           // preamble.buffer[0] = devAddr;

           // preamble.buffer[1] = (uint8_t)(byteAddress >> 8);

           // preamble.buffer[2] = (uint8_t)(byteAddress & 0xFF);

            //preamble.ctrlMask  = 0x0000;

                        preamble.buffer[0] = 0xBA;//slaveAddr;

                      preamble.buffer[1] = 0x00;//highAddr;

                        preamble.buffer[2] = 0x09;//lowAddr;

                        preamble.length    = 2;             /*  Three byte preamble. */

                        preamble.ctrlMask  = 0x0000;        /*  No additional start and stop bits. */

                        buffer[0] =0x02;// highData;

                        buffer[1] = 0x04;//lowData;

            status = CyU3PI2cTransmitBytes (&preamble, buffer,2, 0);

            if (status != CY_U3P_SUCCESS)

            {

                return status;

            }

CyU3PI2cTransmitBytes() and CyU3PI2cReceiveBytes () APIs always return (0x4a) CY_U3P_ERROR_FAILURE.why?

is preamble structure contains valid data in my code?

thank you.

0 Likes
1 Solution

Hi,

Please refer to the following thread: https://community.cypress.com/thread/47584.

The thread to be referred explains about the problems in configuring FX3 GPIO's as I2C slave because of the timing constraints.

Please note that the I2C master implementation in the SDK makes use of I2C hardware registers of FX3. There are no such registers( as there is no I2C slave hardware block) available.

So, the only way to implement I2C slave is through GPIO's (which is found to be not feasible as mentioned above).

Regards,

Yashwant

View solution in original post

16 Replies
NoriTan
Employee
Employee
25 sign-ins 5 questions asked 10 sign-ins

Please let me explain with Cypress's F-RAM device FM24W256


https://www.cypress.com/part/fm24w256-g

GS004182.png

A single-byte write sequence is described as above. There is a transfer consisting of four bytes.  All bytes are sent "By Master" and the Acknowledge bits are responded "By F-RAM (Slave)"  In this case, the first three bytes, Slave Address, Address MSB, and Address LSB, are contained in the PREAMBLE array and the last byte, Data Byte, is contained in the buffer.

Because the three bytes are contained in the preamble, the preamble.length field must be set to 3.

Because there is no start/stop conditions during the preamble, the preamble.ctrlMask is set to 0x0000.

In your case two Data Bytes are sent by Master, the third argument of the function CyU3PI2cTransmitBytes() is set to 2.

GS004181.png

A signle-byte read sequence is described above.  There are two transfers concatenated by a repeated start condition.

The first transfer consists of three bytes, Slave Address, Address MSB, and Address LSB.

The second transfer consists of two bytes, Slave Address, and Data Byte.

All bytes of the first transfer and the first byte of the second transfer are contained in the PREAMBLE array and the last byte, Data Byte, is responded "By F-RAM (Slave)" and stored in the buffer.

Because the four bytes are contained in the preamble, the preamble.length field must be set to 4.

The first transfer is a WRITE transfer and the second one is a READ transfer.  The WRITE transfer has a Slave Address which LSB is 0 and the READ transfer has a Slave Address which LSB is 1.  This is the difference of the preamble.buffer[0] and the preamble.buffer[3]

Because there is a start condition the end of the first transfer, preamble.ctrlMask is set to 0x0004

In your case two Data Bytes are sent by Slave, the third argument of CyU3PI2cReceiveBytes() function is set to 2.

Regards,

Noriaki

0 Likes
lock attach
Attachments are accessible only for community members.

Hello,

Thanks for your reply.

FOR READ OPERATION,

            preamble.buffer[0] = 0xBA;//slaveAddr;

            preamble.buffer[1] = 0x00;//highAddr;

            preamble.buffer[2] = 0x09;//lowAddr;

            preamble.buffer[3] = 0xBB;//slaveaddr;

            preamble.length    = 4;            /*  Three byte preamble. */

            preamble.ctrlMask  = 0x0004;        /*  No additional start and stop bits. */

FOR WRITE OPERATION

            preamble.buffer[0] = 0xBA;//slaveAddr;

            preamble.buffer[1] = 0x00;//highAddr;

            preamble.buffer[2] = 0x09;//lowAddr;

            preamble.length    = 3;            /*  Three byte preamble. */

            preamble.ctrlMask  = 0x0000;        /*  No additional start and stop bits. */

            buffer[0] =0x02;// highData;

            buffer[1] = 0x04;//lowData;

I have attached the i2c read ad write operation.

I have tried for below changes also,

FOR READ OPERATION,

            preamble.buffer[0] = 0xBA;//slaveAddr;

           // preamble.buffer[1] = 0x00;//highAddr;

            preamble.buffer[2] = 0x09;//lowAddr;

            preamble.buffer[3] = 0xBB;//slaveaddr;

            preamble.length    = 3;            /*  Three byte preamble. */

            preamble.ctrlMask  = 0x0004;        /*  No additional start and stop bits. */

FOR WRITE OPERATION

            preamble.buffer[0] = 0xBA;//slaveAddr;

           // preamble.buffer[1] = 0x00;//highAddr;

            preamble.buffer[2] = 0x09;//lowAddr;

            preamble.length    = 2;            /*  Three byte preamble. */

            preamble.ctrlMask  = 0x0000;        /*  No additional start and stop bits. */

            buffer[0] =0x02;// highData;

            buffer[1] = 0x04;//lowData;

But CyU3PI2cTransmitBytes() and CyU3PI2cReceiveBytes() returns 0x4a error.

0 Likes

Why did you reduce the preamble.length value?

What are you expecting by reducing the preamble.length value?

It should not be reduced as I explained in my reply.

Regards,

Noriaki

0 Likes

Hello,

Why did you reduce the preamble.length value?

image sensor(slave) has one byte address.There is no lower and higher address like in your case.

thank you.

0 Likes

I understand. Following is a possible solution.

FOR READ OPERATION,

            preamble.buffer[0] = 0xBA;  // slaveAddr WRITE

            preamble.buffer[1] = 0x09;  // lowAddr;

            preamble.buffer[2] = 0xBB;  // slaveaddr READ

            preamble.length    = 3;     // Three byte preamble.

            preamble.ctrlMask  = 0x0002;    // Add start after the second byte

FOR WRITE OPERATION

            preamble.buffer[0] = 0xBA;  // slaveAddr WRITE

            preamble.buffer[1] = 0x09;  // lowAddr;

            preamble.length    = 2;     // Two byte preamble. */

            preamble.ctrlMask  = 0x0000;    // No additional start and stop bits.

Please refer the image sensor specification if this configuration is fit to your image sensor.

Regards,

Noriaki

Hello,

I have tried with above method.

                        preamble.buffer[0] = 0xBA;//slaveAddr;

                        preamble.buffer[1] = 0x09;//highAddr;

                        preamble.length    = 2;             /*  Three byte preamble. */

                        preamble.ctrlMask  = 0x0000;        /*  No additional start and stop bits. */

                        buffer[0] =0x02;// highData;

                        buffer[1] = 0x04;//lowData;

CyU3PI2cTransmitBytes() returns 0x4a error.

regards,

geetha

0 Likes

The error code 0x4A "CY_U3P_ERROR_FAILURE" means an ERROR due to multiple reasons.  So, I cannot point out the cause of ERROR.

First of all, please check if you added pull-up resistors to the I2C bus.  The pull-up resistors are required for all I2C devices.

And second, please ensure the slave address 0xBA is correct.

GS004188.pngGS004187.png 

For example, onsem's MT9M114 has two possible slave addresses, 0xBA and 0x90, which are selected by an external pin SADDR.  In addition the slave address can be overwritten by the internal register USER_DEFINED_DEVICE_ADDRESS_IS (R0x002E).

If possible, please capture the I2C bus, SCL and SDA signals, with an oscilloscope. I want to check if the ACK is responded by Slave.

Regards,

Noriaki

0 Likes
lock attach
Attachments are accessible only for community members.

Hello,

slave address 0xBA is correct.The SADDR signal in our hardware is pulled high with 2.8v IO voltage.sensor slave is not giving ACK after sendIng device address 0xBA.I have captured the i2c lines in the sensor side MT9P031I12STCES at pin 4 and 5.The HEX value 0xBA is reaching to an image sensor.But i cant see data line pulled low at the 9th i2c clock pulse.I have attached the screenshot.Please let me know that waveform is showing 0xBA value properly.The red line is i2c clock and blue line is i2c data.I have attached the code also.I have kept CyU3PI2cTransmitBytes(&preamble, buffer,2, 2); function in while(1) loop.please let me know if anything i am missing.

Thank you.

0 Likes

It was found that the image sensor does not respond to the slave address 0xBA.

I2C6B.png

So, there is a problem in slave device side.

It is a nice idea to use a simple I2C device like temperature sensor instead of the image sensor.  Please ensure the SCL and SDA lines are connected to the device.  At least the ACK response to the salve address must be observed.

Regards,

Noriaki

lock attach
Attachments are accessible only for community members.

Hello,

I have tested for other i2c slave ALS with slave address 0x44.

for this also,there is no ACK at 9TH clock pulse.

FX3 I2C MASTER<-1->I2C BUFFER<-2->LEVEL TRANSLATOR<-3->IMAGE SENSOR I2C SLAVE.

each interval is having two pairs of pullup resistor.it could be the problem for ACK?

1)2K ,2k (sda,scl)and 1.1k,1.1k (sda,scl)

2)1.1k ,1.1k (sda,scl)and 2.2k ,2.2k(sda,scl)

3)100,100 (sda,scl)and 1.5k,1.5k (sda,scl)

regards,

geetha

0 Likes

Please show me the schematic at the "I2C BUFFER" and "LEVEL TRANSLATOR"

Do you mean total six resistors are used each SDA and SCL in parallel?

Regards,

Noriaki

Hello,

I am able to communicate with ALS slave in our hardware.

Thanks for your support.

I am trying to implement FX3 i2c acts as slave.I have created thread regarding this.

any reference/suggestion from cypress?

CyU3PI2cReceiveBytes() and CyU3PI2cTransmitBytes() APIs  can be reuse in my i2c slave code?

thanks.

geetha.

0 Likes

Well, as several documents said the FX3 I2C is supporting I2 MASTER only.

FX3 Datasheet 001-52136

GS004281.png

Application Note AN70707

GS004282.png

If you want any I2C slave device please consider to use another processor like PSoC 4.

Regards,

Noriaki

0 Likes

Hello,

Well, as several documents said the FX3 I2C is supporting I2 MASTER only.

YES.is not possible to implement FX3 I2C as SLAVE?

Please look for this thread FX3 gpios as i2c signals .

My question is that should i write own driver for fx3 i2c slave or can i reuse the existing i2c mastre  driver ?

please let me know.

thanks.

0 Likes

Hi,

Please refer to the following thread: https://community.cypress.com/thread/47584.

The thread to be referred explains about the problems in configuring FX3 GPIO's as I2C slave because of the timing constraints.

Please note that the I2C master implementation in the SDK makes use of I2C hardware registers of FX3. There are no such registers( as there is no I2C slave hardware block) available.

So, the only way to implement I2C slave is through GPIO's (which is found to be not feasible as mentioned above).

Regards,

Yashwant

lock attach
Attachments are accessible only for community members.

Hello,

I have tested for other i2c slave Temperature sensor with slave address 0x30.

for this also,there is no ACK at 9TH clock pulse.

please test the code i have attached to the previous reply.

thank you.

0 Likes