cyfxusbi2cregmode - How to read I2C address with 32 Bits?

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

cross mob
LuTa_4642501
Level 3
Level 3
Welcome!

Hi,

I'm trying to change cyfxusbi2cregmode to read other I2C devices in the bus.

I made some changes and this is my current code: I2C Cypress - Pastebin.com

I basically removed the hardcode EEPROM I2C address from the code and change to receive from the USB Bus.

But now I need to read a 32 bits address from that I2C device.

How Can I read 32-bit I2C byte address from a slave I2C device?

Thanks

Lucas

0 Likes
1 Solution

Works, but your code can't be used because byteAddress is an uint16_t, so it can only hold half of the address.

The answer is to use byteAddress and devAddr ( both uint16_t ) to get the full address.

And that means that the I2C_address can't be passed in a single call from the host. The host needs to configure the I2C address first with one single call and after that, the firmware will only talk to that address. If the host wants to talk to a different I2C device it will need to issue a new call to change the I2C address.

        if (isRead) {

            preamble.length    = 6;

            preamble.buffer[0] = i2c_addr;  /* global variable set in a setup call before actually talking to the device */

            preamble.buffer[1] = (uint8_t)((byteAddress &  0xFF00) >> 8);

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

            preamble.buffer[3] = (uint8_t)((devAddr     &  0xFF00) >> 8);

            preamble.buffer[4] = (uint8_t)( devAddr     &  0x00FF);

            preamble.buffer[5] = (i2c_addr | 0x01);

            preamble.ctrlMask  = 0x0010;

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

            if (status != CY_U3P_SUCCESS)

                return status;

        } else {

            preamble.length    = 5;

            preamble.buffer[0] = i2c_addr;   /* global variable set in a setup call before actually talking to the device */

            preamble.buffer[1] = (uint8_t)((byteAddress &  0xFF00) >> 8);

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

            preamble.buffer[3] = (uint8_t)((devAddr     &  0xFF00) >> 8);

            preamble.buffer[4] = (uint8_t)( devAddr     &  0x00FF);

            preamble.ctrlMask  = 0x0000;

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

            if (status != CY_U3P_SUCCESS)

                return status;

            /* Wait for the write to complete. */

            preamble.length = 1;

            status = CyU3PI2cWaitForAck(&preamble, 200);

            if (status != CY_U3P_SUCCESS)

                return status;

        }

View solution in original post

0 Likes
4 Replies
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello Lucas,

I basically removed the hardcode EEPROM I2C address from the code and change to receive from the USB Bus.

>> Please let me know if this works as expected? Is the I2C slave address of 32 bits in this case? In the code that you have shared i see that the CyFxUsbI2cTransfer uses devaddr which is uint8_t.

How Can I read 32-bit I2C byte address from a slave I2C device?

>> To read from the I2C slave, the slave address should be known before sending/ receiving the data from the slave.

Regards,

Rashi

Regards,
Rashi
0 Likes

Hi,

The devaddr is still one Byte as you can see at the code. That works fine.

But I need a way to specify a 32Bit byte address.

This is what I need.

Talk to the device 0x40 and read from 0x0001001c position 32 bits.

And I should receive 0x00000003.

This is a raspberry Pi I2C recording using saleae logic analyser.

works.png

0 Likes

Hello Lucas,

Please add this code snippet to the firmware for 4 bytes addressing

/* Update the preamble information. */

            preamble.length    = 6;

            preamble.buffer[0] = devAddr;

            preamble.buffer[1] = (uint8_t)((byteAddress &  0xFF000000)>> 24);

            preamble.buffer[2] = (uint8_t)((byteAddress &  0x00FF0000) >> 16);

            preamble.buffer[3] = (uint8_t)((byteAddress &  0x0000FF00)  >> 8);

            preamble.buffer[4] = (uint8_t)(byteAddress &   0x000000FF);

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

            preamble.ctrlMask  = 0x0010;

            status = CyU3PI2cReceiveBytes (&preamble, buffer, 4, 0);    \\4 bytes (32 bits) expected to be read from slave

            if (status != CY_U3P_SUCCESS)

            {

                return status;

            }

Please let me know if any queries on this

Regards,

Rashi

Regards,
Rashi
0 Likes

Works, but your code can't be used because byteAddress is an uint16_t, so it can only hold half of the address.

The answer is to use byteAddress and devAddr ( both uint16_t ) to get the full address.

And that means that the I2C_address can't be passed in a single call from the host. The host needs to configure the I2C address first with one single call and after that, the firmware will only talk to that address. If the host wants to talk to a different I2C device it will need to issue a new call to change the I2C address.

        if (isRead) {

            preamble.length    = 6;

            preamble.buffer[0] = i2c_addr;  /* global variable set in a setup call before actually talking to the device */

            preamble.buffer[1] = (uint8_t)((byteAddress &  0xFF00) >> 8);

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

            preamble.buffer[3] = (uint8_t)((devAddr     &  0xFF00) >> 8);

            preamble.buffer[4] = (uint8_t)( devAddr     &  0x00FF);

            preamble.buffer[5] = (i2c_addr | 0x01);

            preamble.ctrlMask  = 0x0010;

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

            if (status != CY_U3P_SUCCESS)

                return status;

        } else {

            preamble.length    = 5;

            preamble.buffer[0] = i2c_addr;   /* global variable set in a setup call before actually talking to the device */

            preamble.buffer[1] = (uint8_t)((byteAddress &  0xFF00) >> 8);

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

            preamble.buffer[3] = (uint8_t)((devAddr     &  0xFF00) >> 8);

            preamble.buffer[4] = (uint8_t)( devAddr     &  0x00FF);

            preamble.ctrlMask  = 0x0000;

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

            if (status != CY_U3P_SUCCESS)

                return status;

            /* Wait for the write to complete. */

            preamble.length = 1;

            status = CyU3PI2cWaitForAck(&preamble, 200);

            if (status != CY_U3P_SUCCESS)

                return status;

        }

0 Likes