6 Replies Latest reply on Jul 25, 2019 9:45 PM by MoTa_728816

    I2C Connection between PSoC 4.2 (CY8CKIT-042) and PSoC 4.0 (CY8CKIT-040)

    NaJa_4363881

      Hello,

       

      I am trying to establish an I2C connection from PSoC 4 device to PSoC 4.2 using two different development kits, but there doesn't seem to be any transfer of data between the two devices. I initially felt it had to do with the internal pull-up resistors, but the PSoC 4 Kit already have the internal pull up resistors enabled for the GPIO I2C ports (P1.3 and P1.2). I made the interconnections between the two development kits for I2C ports (SDA, SCL) and the GND connection.  I am not sure whether it is the differences in Firmware versions that is not letting the devices connect over I2C.

       

      Can anyone review and help me in finding the issue?

       

      Thanks and Regards,

      Nandhini Jayapandian

        • 1. Re: I2C Connection between PSoC 4.2 (CY8CKIT-042) and PSoC 4.0 (CY8CKIT-040)
          JoMe_264151

          It is definitively not the software version. Can you elaborate the correct kits CY8CKIT-0XX. Which Creator version are you using (4.2?)

          And can you please post your complete project so that we all can have a look at all of your settings. To do so, use

          Creator->File->Create Workspace Bundle (minimal)

          and attach the resulting file.

           

          Bob

          • 2. Re: I2C Connection between PSoC 4.2 (CY8CKIT-042) and PSoC 4.0 (CY8CKIT-040)
            MoTa_728816

            Hi,

             

            As I have never tried to use I2C as Slave, I took the chance.

             

            I let the master send 0x00, 0x01, 0x02 .. one byte each loop

            then let the slave receive a byte and return 0xFF - (received value)

            so that I can tell that the master is receiving correct data.

             

            At first it seemed to be too complicated to use a couple of boards,

            so I used two I2C modules in one CY8CKIT-042.

            The schematic was like

            003-loop-back-schematic.JPG

            I assigned pins as

            pin_loopback.JPG

            The board with jumper wires

            loop_back.JPG

             

            main.c

            ======================

            #include "project.h"

            #include "stdio.h"

             

            #define TIMEOUT_MSEC      100

            #define I2C_SLAVE_ADDRESS 0x13

            #define WRITE_BIT        (0u)

            #define READ_BIT          (1u)

             

            #define BUF_SIZE 32

             

            uint8_t master_rx_buf[BUF_SIZE] ;

            uint8_t master_tx_buf[BUF_SIZE] ;

            uint8_t slave_write_buf[BUF_SIZE] ;

            uint8_t slave_read_buf[BUF_SIZE] ;

             

            char str[64] ; /* print buffer */

            void print(char *str)

            {

                UART_PutString(str) ;

            }

             

            void init_hardware(void)

            {

                UART_Start() ;

             

                I2CS_I2CSlaveInitReadBuf(slave_read_buf, BUF_SIZE) ;

                I2CS_I2CSlaveInitWriteBuf(slave_write_buf, BUF_SIZE) ;

                I2CS_Start() ;

             

                I2CM_Start() ;

                 

                CyGlobalIntEnable; /* Enable global interrupts. */

            }

             

            void splash(void)

            {

                sprintf(str, "I2C Test (%s %s)\n", __DATE__, __TIME__) ;

                print(str) ;

            }

             

            int main(void)

            {

                uint8_t tx_data = 0 ;

                uint8_t rx_data = 0 ;

                int status ;

             

                init_hardware() ;

             

                splash() ;

             

                for(;;)

                {

                    I2CS_I2CSlaveInitWriteBuf(slave_write_buf, BUF_SIZE) ;

                   

                    sprintf(str, "Master Sending [0x%02X] ... ", tx_data) ;

                    print(str) ;

                    status = I2CM_I2CMasterWriteBuf(I2C_SLAVE_ADDRESS, &tx_data, 1, I2CM_I2C_MODE_COMPLETE_XFER) ;

                    if (status == I2CM_I2C_MSTR_NO_ERROR) {

                        print("OK\n") ;

                    } else {

                        sprintf(str, "Failed with Error [0x%02X]\n", status & 0xFF) ;

                        print(str) ;

                    }

                 

                    while(I2CM_I2CMasterStatus() == I2CM_I2C_MSTAT_XFER_INP)  {

                            ; /* wait for the transfer complete */

                    }

                 

                    if (I2CS_I2CSlaveGetWriteBufSize()) {

                        sprintf(str, "Slave Recived [0x%02X]\n", slave_write_buf[0]) ;

                        print(str) ;

                     

                        slave_read_buf[0] = 0xFF - slave_write_buf[0] ;

                        I2CS_I2CSlaveInitReadBuf(slave_read_buf, BUF_SIZE) ; 

                        I2CM_I2CMasterClearReadBuf() ;

                     

                     

                        print("Master Reading ... ") ;

                        status = I2CM_I2CMasterReadBuf(I2C_SLAVE_ADDRESS, &rx_data, 1, I2CM_I2C_MODE_COMPLETE_XFER) ;

                     

                        CyDelay(100) ;

                     

                        while(I2CM_I2CMasterStatus() == I2CM_I2C_MSTAT_XFER_INP)  {

                                ; /* wait for the transfer complete */

                        }

                     

                        if (status == I2CM_I2C_MSTR_NO_ERROR) {

                          sprintf(str, " [0x%02X} received\n", rx_data) ;

                        } else {

                            sprintf(str, "Failed with Error [0x%02X]\n", status & 0xFF) ;

                        }         

                        print(str) ;

                    }

                    print("\n") ;

                 

                    tx_data = (tx_data + 1) % 0x100 ;

                    CyDelay(2000) ;

                }

            }

            ======================

             

            The Tera Term log looked like

            002-loop-back.JPG

            It seemed to be working.

             

            So now I separated the project in to two projects

            Master schematic

            004-Master_schematic.JPG

            Master pin assign

            master_pin_assing.JPG

            main.c (master)

            ========================

            #include "project.h"

            #include "stdio.h"

             

            #define TIMEOUT_MSEC      100

            #define I2C_SLAVE_ADDRESS 0x13

            #define WRITE_BIT        (0u)

            #define READ_BIT          (1u)

             

            #define BUF_SIZE 32

             

            uint8_t master_rx_buf[BUF_SIZE] ;

            uint8_t master_tx_buf[BUF_SIZE] ;

             

            char str[64] ; /* print buffer */

            void print(char *str)

            {

                UART_PutString(str) ;

            }

             

            void init_hardware(void)

            {

                UART_Start() ;

               

                I2CM_Start() ;

                 

                CyGlobalIntEnable; /* Enable global interrupts. */

            }

             

            void splash(void)

            {

                sprintf(str, "I2C Test (%s %s)\n", __DATE__, __TIME__) ;

                print(str) ;

            }

             

            int main(void)

            {

                uint8_t tx_data = 0 ;

                uint8_t rx_data = 0 ;

                int status ;

             

                init_hardware() ;

             

                splash() ;

             

                for(;;)

                {

                    sprintf(str, "Master Sending [0x%02X] ... ", tx_data) ;

                    print(str) ;

                    status = I2CM_I2CMasterWriteBuf(I2C_SLAVE_ADDRESS, &tx_data, 1, I2CM_I2C_MODE_COMPLETE_XFER) ;

                    if (status == I2CM_I2C_MSTR_NO_ERROR) {

                        print("OK\n") ;

                    } else {

                        sprintf(str, "Failed with Error [0x%02X]\n", status & 0xFF) ;

                        print(str) ;

                    }

                 

                    while(I2CM_I2CMasterStatus() == I2CM_I2C_MSTAT_XFER_INP)  {

                            ; /* wait for the transfer complete */

                    }

             

             

                    I2CM_I2CMasterClearReadBuf() ;

                                 

                    print("Master Reading ... ") ;

                    status = I2CM_I2CMasterReadBuf(I2C_SLAVE_ADDRESS, &rx_data, 1, I2CM_I2C_MODE_COMPLETE_XFER) ;

                     

                    CyDelay(100) ;

                     

                    while(I2CM_I2CMasterStatus() == I2CM_I2C_MSTAT_XFER_INP)  {

                        ; /* wait for the transfer complete */

                    }

                     

                    if (status == I2CM_I2C_MSTR_NO_ERROR) {

                        sprintf(str, " [0x%02X} received\n", rx_data) ;

                    } else {

                        sprintf(str, "Failed with Error [0x%02X]\n", status & 0xFF) ;

                    }         

                    print(str) ;

                    print("\n") ;

                 

                    tx_data = (tx_data + 1) % 0x100 ;

                    CyDelay(2000) ;

                }

            }

            ========================

             

            Slave schematic

            005-slave-schematic.JPG

            Slave pin assign

            slave-pin_assign.JPG

            main.c (slave)

            ========================

            #include "project.h"

            #include "stdio.h"

             

            #define TIMEOUT_MSEC      100

            #define I2C_SLAVE_ADDRESS 0x13

            #define WRITE_BIT        (0u)

            #define READ_BIT          (1u)

             

            #define BUF_SIZE 32

             

            uint8_t slave_write_buf[BUF_SIZE] ;

            uint8_t slave_read_buf[BUF_SIZE] ;

             

            char str[64] ; /* print buffer */

            void print(char *str)

            {

                UART_PutString(str) ;

            }

             

            void init_hardware(void)

            {

                UART_Start() ;

             

                I2CS_I2CSlaveInitReadBuf(slave_read_buf, BUF_SIZE) ;

                I2CS_I2CSlaveInitWriteBuf(slave_write_buf, BUF_SIZE) ;

                I2CS_Start() ;

                     

                CyGlobalIntEnable; /* Enable global interrupts. */

            }

             

            void splash(void)

            {

                sprintf(str, "I2C Slave Test (%s %s)\n", __DATE__, __TIME__) ;

                print(str) ;

            }

             

            int main(void)

            {

                init_hardware() ;

             

                splash() ;

             

                for(;;)

                {

                    slave_write_buf[0] = 0 ;

                    I2CS_I2CSlaveInitWriteBuf(slave_write_buf, BUF_SIZE) ;

                 

                    while(I2CS_I2CSlaveGetWriteBufSize() == 0) {

                        ;

                    }

                         

                    sprintf(str, "Slave Recived [0x%02X]\n", slave_write_buf[0]) ;

                    print(str) ;

                     

                    slave_read_buf[0] = 0xFF - slave_write_buf[0] ;

                 

                    I2CS_I2CSlaveInitReadBuf(slave_read_buf, BUF_SIZE) ;

                    sprintf(str, "Slave Set data to [0x%02X]\n", slave_read_buf[0]) ;

                    print(str) ;

                }

            }

            ========================

             

            Then I connected the boards like

            SCL <-> SCL

            SDA <-> SDA

            GND <-> GND

            master_slave.JPG

             

            The TeraTerm log (Master)

            001-Master-TeraTerm.JPG

            Tera Term log (Slave)

            000-Slave_TeraTerm.JPG

             

            As I wrote at the beginning, this was my first code using I2C slave,

            so there must be better/other ways of writing codes.

            But at least it seems to be working.

             

            Also as you can see from the picture, as I don't have 040 board,

            I used a couple of CY8CKIT-042, so please re-target Slave project to 040 board.

             

            moto

            • 3. Re: I2C Connection between PSoC 4.2 (CY8CKIT-042) and PSoC 4.0 (CY8CKIT-040)
              NaJa_4363881

              Hello Bob!

               

              As per your comments, I have archived my project files and attached here. Project zip -> Workspace18.cywrk.Archive01.zip is created using PSoC Creator 4.0 and Project zip -> Workspace19.cywrk.Archive.zip is created using PSoC Creator 4.2. In my project, I am using two kits -> CY8CKIT-042 (Slave) and CY8CKIT-040 (Master). I made the I2C (SDA and SCL) and Ground (GND) connections between the two development kits before programing them. Later used PSoC Creator 4.0 to program CY8CKIT-040 and PSoC Creator 4.2 to program CY8CKIT-042. Also, I am a bit confused with the addressing. In the I2C Slave configuration, I could see the default address to be set as 0x08 for CY8CKIT-042. But I couldn't find proper references online for addresses that are already assigned for the devices (like FRAM, PSoC 4 MCU, PSoC 5LP) on the Cypress development kit.

               

              It will be great if you will be able to review my code.

               

              Thanks and Regards,

              Nandhini Jayapandian

              • 4. Re: I2C Connection between PSoC 4.2 (CY8CKIT-042) and PSoC 4.0 (CY8CKIT-040)
                NaJa_4363881

                Hello Moto,

                 

                Thank you very much for the detailed explanation on your project. In my project, I have used two different kits (CY8CKIT-040 -> Master and CY8CKIT-042 -> Slave). The below attached files are created in two different PSoC creator versions (4.0 and 4.2). Also I was not clear whether there are any updates in addressing that was made to the CY8CKIT-042, I proceeded with the code using 0x08 as the slave address for CY8CKIT-042.

                 

                I will try to run your code as reference on my system and then try correcting my code based on my requirement. Attached my project files for reference.

                 

                Workspace18.cywrk.Archive01.zip (Created using PSoC Creator 4.0) -> Contains the Master code for CY8CKIT-040

                Workspace19.cywrk.Archive.zip (Created using PSoC Creator 4.2) -> Contains Slave code for CY8CKIT-042

                 

                Thanks and Regards,

                Nandhini Jayapandian

                • 5. Re: I2C Connection between PSoC 4.2 (CY8CKIT-042) and PSoC 4.0 (CY8CKIT-040)
                  JoMe_264151

                  The address range for normal I2C is from 0x01 to 0x78. When you get an I2C device (EEPROM, FRam etc) the dataseet will show its default address. This can be changed on some devices using an additional pin, consult datasheet for that feature.

                  PSoCs as a slave do not have a fixed slave address. Instead this is programmable and can be set to any of the valid addresses.

                  Very tricky is to use a PSoC4 or 5, create a master AND a slave within the same chip. So you can debug and checkout easily the communication without having to program two different devices. An example is attached.

                  Is there any reason why you are using two different Creator versions? There have been some changes done recently which implemented a timeout feature on some devices. I would recommend to use the latest actual version.

                   

                  Bob

                  • 6. Re: I2C Connection between PSoC 4.2 (CY8CKIT-042) and PSoC 4.0 (CY8CKIT-040)
                    MoTa_728816

                    Dear Bob-san,

                     

                    > There have been some changes done recently which implemented a timeout feature on some devices.

                    > I would recommend to use the latest actual version.

                     

                    That is a very good point out!

                     

                    Although I knew that there is/are APIs which support timeout,

                    somehow I did not use them yesterday.

                    So I reviewed my code why I did not use those.

                     

                    Then I realized that the API with timeout requires "some" more work.

                    Anyway, I agree that we should use API with timeout support.

                     

                    I replaced

                    =======

                        status = I2CM_I2CMasterWriteBuf(I2C_SLAVE_ADDRESS, &tx_data, 1, I2CM_I2C_MODE_COMPLETE_XFER) ;

                    =======

                    with

                    =======

                            status  = I2CM_I2CMasterSendStart(I2C_SLAVE_ADDRESS, I2CM_I2C_WRITE_XFER_MODE, TIMEOUT_MSEC) ;

                            status |= I2CM_I2CMasterWriteByte(tx_data, TIMEOUT_MSEC) ;

                            status |= I2CM_I2CMasterSendStop(TIMEOUT_MSEC) ;

                    =======

                     

                    I replaced

                    =======

                               status = I2CM_I2CMasterReadBuf(I2C_SLAVE_ADDRESS, &rx_data, 1, I2CM_I2C_MODE_COMPLETE_XFER) ;

                    =======

                    with

                    =======

                                status  = I2CM_I2CMasterSendStart(I2C_SLAVE_ADDRESS, I2CM_I2C_READ_XFER_MODE, TIMEOUT_MSEC) ;

                                if (status == I2CM_I2C_MSTR_NO_ERROR) {

                                    status = I2CM_I2CMasterReadByte(I2CM_I2C_NAK_DATA, &rx_data, TIMEOUT_MSEC) ;

                                }

                                status |= I2CM_I2CMasterSendStop(TIMEOUT_MSEC) ;

                    =======

                     

                    I replaced

                    =======

                            while(I2CM_I2CMasterStatus() == I2CM_I2C_MSTAT_XFER_INP)  {

                                    ; /* wait for the transfer complete */

                            }

                    =======

                    with

                    =======

                                timeout_count = 0 ;

                                while((I2CM_I2CMasterStatus() == I2CM_I2C_MSTAT_XFER_INP)&&(timeout_count < TIMEOUT_MSEC))  {

                                    /* wait for the transfer complete */

                                    CyDelay(1) ; /* wait 1ms */

                                    timeout_count++ ;

                                }   

                    =======

                     

                    Best Regards,

                    26-Jul-2019

                    Motoo Tanaka