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

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

cross mob
NaJa_4363881
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted

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

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

View solution in original post

0 Likes
6 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

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

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

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

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

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

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

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

0 Likes