I2C Master differences from PSOC4 to PSOC5

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

cross mob
rojkc_1859651
Level 1
Level 1

Some how all the PSOC5 code written for I2CMaster component in POSC5 fails when ported over to PSOC4

This is a snippet for Inter Processor communication using I2C( I2C Master on PSOC5 and EzI2C on PSOC4 slave) in a multi-processor system that I have written. And it works.

Now When I tried to port this code which was written for PSOC5 to another system using PSOC4() and another controller, I saw that it breaks. I had to bit-bag for it to work.

In fact, the code examples from Cypress Website also can not send any data on the bus as I tried to monitor using a beagle I2C sniffer. Any idea? I can configure my SCL and SDA as Open Drain pins in PSOC5. in PSOC4 I have no option of creating GPIO  pins first and then wiring/connecting the I2CMaster block on to them.

///////////////////////////////////////////////////

// Reading data from Monitor CPU

//////////////////////////////////////////////////

uint8 MonitorCPUI2CReadByte(uint8 read_cmd)

{

uint8 i2c_status=FALSE;   

uint8 return_data = 0;

    //uint8 i;

    i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */

if(I2C_Master_MSTR_NO_ERROR == i2c_status ) // Check if transfer completed without errors

{    

    i2c_status = I2C_Master_MasterSendStart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_WRITE_XFER_MODE); // device address

    if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors

    {

            i2c_status = I2C_Master_MasterWriteByte(read_cmd);  // EXT EEPROM command

            if(i2c_status == I2C_Master_MSTR_NO_ERROR)

            {   

            i2c_status = I2C_Master_MasterSendRestart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_READ_XFER_MODE);

                if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors

            {

       

            return_data = I2C_Master_MasterReadByte(I2C_Master_NAK_DATA);  // MSB data

            }

            else

            {

            GUI_DispStringAt ("ERR1_I2C_MONITOR_CPU_RX", 100,70);

            }

            }

            else

            {

                GUI_DispStringAt ("ERR2_I2C_MONITOR_CPU_RX", 100,10);

            }

    }

    else

    {

    GUI_DispStringAt ("ERR3_I2C_MONITOR_CPU_RX", 100,50);

    }

    I2C_Master_MasterSendStop(); // Send Stop

        i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */

    }

    else

    {

        GUI_DispStringAt ("ERR4_I2C_MONITOR_CPU_RX", 100,70);

    }

    if(I2C_Master_MSTR_NO_ERROR != i2c_status )

    {

        return_data = FALSE;

    }

    CyDelay(EEPROM_OP_DELAY_MS);  

    ServiceWatchDogAndCheckHeartBeat();   

return(return_data);

}

///////////////////////////////////////////////////

// Sending a command to Monitor CPU

//////////////////////////////////////////////////

uint8 MonitorCPUI2CWriteByte(uint8 write_addr, uint8 write_data)  

{

uint8 i2c_status=FALSE;

    uint8 status =FALSE;

    i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */

if(I2C_Master_MSTR_NO_ERROR == i2c_status ) // Check if transfer completed without errors

{     

        i2c_status = I2C_Master_MasterSendStart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_WRITE_XFER_MODE); // device address

    if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors

    {

            i2c_status = I2C_Master_MasterWriteByte(write_addr);  // EXT EEPROM command

            if(I2C_Master_MSTR_NO_ERROR == status)

            {

                status = I2C_Master_MasterWriteByte(write_data);  // EXT EEPROM command

                if(status == I2C_Master_MSTR_NO_ERROR)

                {

                    status =TRUE;

                }

                else

                {

                    GUI_DispStringAt ("ERR1_I2C_MONITOR_CPU_WR", 100,10);

                }

                        

                   

            }

            else

            {

                GUI_DispStringAt ("ERR2_I2C_MONITOR_CPU_WR", 100,10);

            }

        }

        else

        {

           GUI_DispStringAt ("ERR3_I2C_MONITOR_CPU_WR", 100,50);

       

        }

        I2C_Master_MasterSendStop(); // Send Stop

        i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */

    }

    else

    {

        GUI_DispStringAt ("ERR4_I2C_MONITOR_CPU_WR", 100,70);

    }

    if(I2C_Master_MSTR_NO_ERROR != i2c_status )

    {

        status = FALSE;

    }

    CyDelay(EEPROM_OP_DELAY_MS);  

    ServiceWatchDogAndCheckHeartBeat();   

return(status);

}

///////////////////////////////////////////////////

// Reading data from Monitor CPU

//////////////////////////////////////////////////

uint8 MonitorCPUI2CBlockRead(uint8 read_cmd, uint8* read_data, uint8* data_len)

{

uint8 i2c_status=FALSE; 

    uint8 status=FALSE;

uint8 i=0;

    //uint8 read_buff[CPU2_BLK_READ_SIZE]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

    if(NULL != data_len)

    {

        //uint8 i;

        if(*data_len < CPU2_BLK_READ_SIZE)

        {

            i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */

        if(I2C_Master_MSTR_NO_ERROR == i2c_status ) // Check if transfer completed without errors

        {    

            i2c_status = I2C_Master_MasterSendStart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_WRITE_XFER_MODE); // device address

            if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors

            {

                    i2c_status = I2C_Master_MasterWriteByte(read_cmd);  // EXT EEPROM command

                    if(i2c_status == I2C_Master_MSTR_NO_ERROR)

                    {   

                    i2c_status = I2C_Master_MasterSendRestart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_READ_XFER_MODE);

                        if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors

                    {

               

                    for(i=0;i<(*data_len);i++)

                            {

                                if(i<((*data_len)-1))

                                {

                                    read_data=I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);

                                }

                                else

                                {

                                    read_data=I2C_Master_MasterReadByte(I2C_Master_NAK_DATA);

                                }

                                ServiceWatchDogAndCheckHeartBeat();

                            }

                           

                    }

                    else

                    {

                    GUI_DispStringAt ("ERR1_I2C_MONITOR_CPU_RD", 100,70);

                    }

                    }

                    else

                    {

                        GUI_DispStringAt ("ERR2_I2C_MONITOR_CPU_RD", 100,10);

                    }

            }

            else

            {

            GUI_DispStringAt ("ERR3_I2C_MONITOR_CPU_RD", 100,50);

            }

       

            I2C_Master_MasterSendStop(); // Send Stop

                i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */

            }

            else

            {

                GUI_DispStringAt ("ERR4_I2C_MONITOR_CPU_RD", 100,70);

            }

if(I2C_Master_MSTR_NO_ERROR != i2c_status )

{

status = FALSE;

(*data_len) =0;

}

}

else

{

(*data_len) =0;

}

CyDelay(EEPROM_OP_DELAY_MS);

    ServiceWatchDogAndCheckHeartBeat();   

return(status);

}

///////////////////////////////////////////////////

// Sending a block of data to Monitor CPU

//////////////////////////////////////////////////

uint8 MonitorCPUI2CBlockWrite(uint8 write_addr, uint8 *write_data, uint8 data_len)  

{

    uint8 i2c_status=FALSE;

    uint8 status =FALSE;

uint8 i;   

   if((NULL != write_data) && (data_len <CPU2_BLK_WRITE_SIZE))

   {

        i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */

    if(I2C_Master_MSTR_NO_ERROR == i2c_status ) // Check if transfer completed without errors

    {     

            i2c_status = I2C_Master_MasterSendStart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_WRITE_XFER_MODE); // device address

        if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors

        {

                i2c_status = I2C_Master_MasterWriteByte(write_addr);  // EXT EEPROM command

                if(I2C_Master_MSTR_NO_ERROR == i2c_status)

                {

                    for(i=0;((i<data_len)&&(I2C_Master_MSTR_NO_ERROR == i2c_status ));i++)

                    {           

                        i2c_status = I2C_Master_MasterWriteByte(write_data); // device address

                        ServiceWatchDogAndCheckHeartBeat();

                    }

                if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors

                {

                        status=TRUE;

                    }

                else

                {

                        GUI_DispStringAt ("ERR1_I2C_ERTC_WR", 100,50);

                }

                }  

                else

                {

                    GUI_DispStringAt ("ERR2_I2C_MONITOR_CPU_WR", 100,10);

                }

         

            }

            else

            {

               GUI_DispStringAt ("ERR3_I2C_MONITOR_CPU_WR", 100,50);

           

            }

            I2C_Master_MasterSendStop(); // Send Stop

            i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */

        }

        else

        {

            GUI_DispStringAt ("ERR4_I2C_MONITOR_CPU_WR", 100,70);

        }

        if(I2C_Master_MSTR_NO_ERROR != i2c_status )

        {

            status = FALSE;

        }

        CyDelay(EEPROM_OP_DELAY_MS);   

    }

    ServiceWatchDogAndCheckHeartBeat();

return(status);

}


///////////////////////////////////////////////////// Reading data from Safety CPU//////////////////////////////////////////////////uint8 MonitorCPUI2CReadByte(uint8 read_cmd) { uint8 i2c_status=FALSE;    uint8 return_data = 0;     //uint8 i;    i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */ if(I2C_Master_MSTR_NO_ERROR == i2c_status ) // Check if transfer completed without errors {         i2c_status = I2C_Master_MasterSendStart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_WRITE_XFER_MODE); // device address    if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors     {            i2c_status = I2C_Master_MasterWriteByte(read_cmd);  // EXT EEPROM command            if(i2c_status == I2C_Master_MSTR_NO_ERROR)            {                i2c_status = I2C_Master_MasterSendRestart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_READ_XFER_MODE);                if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors             {                    return_data = I2C_Master_MasterReadByte(I2C_Master_NAK_DATA);  // MSB data            }             else            {            GUI_DispStringAt ("ERR1_I2C_MONITOR_CPU_RX", 100,70);            }            }            else            {                GUI_DispStringAt ("ERR2_I2C_MONITOR_CPU_RX", 100,10);            }    }    else    {    GUI_DispStringAt ("ERR3_I2C_MONITOR_CPU_RX", 100,50);    }     I2C_Master_MasterSendStop(); // Send Stop         i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */    }    else    {        GUI_DispStringAt ("ERR4_I2C_MONITOR_CPU_RX", 100,70);    }    if(I2C_Master_MSTR_NO_ERROR != i2c_status )    {        return_data = FALSE;    }     CyDelay(EEPROM_OP_DELAY_MS);       ServiceWatchDogAndCheckHeartBeat();    return(return_data); }

///////////////////////////////////////////////////// Sending a command to Safety CPU//////////////////////////////////////////////////uint8 MonitorCPUI2CWriteByte(uint8 write_addr, uint8 write_data)   { uint8 i2c_status=FALSE;    uint8 status =FALSE;    i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */ if(I2C_Master_MSTR_NO_ERROR == i2c_status ) // Check if transfer completed without errors {              i2c_status = I2C_Master_MasterSendStart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_WRITE_XFER_MODE); // device address    if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors     {            i2c_status = I2C_Master_MasterWriteByte(write_addr);  // EXT EEPROM command            if(I2C_Master_MSTR_NO_ERROR == status)            {                status = I2C_Master_MasterWriteByte(write_data);  // EXT EEPROM command                if(status == I2C_Master_MSTR_NO_ERROR)                {                    status =TRUE;                }                else                {                    GUI_DispStringAt ("ERR1_I2C_MONITOR_CPU_WR", 100,10);                }                                                         }            else            {                GUI_DispStringAt ("ERR2_I2C_MONITOR_CPU_WR", 100,10);            }        }        else        {           GUI_DispStringAt ("ERR3_I2C_MONITOR_CPU_WR", 100,50);                }        I2C_Master_MasterSendStop(); // Send Stop         i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */    }    else    {        GUI_DispStringAt ("ERR4_I2C_MONITOR_CPU_WR", 100,70);    }    if(I2C_Master_MSTR_NO_ERROR != i2c_status )    {        status = FALSE;    }     CyDelay(EEPROM_OP_DELAY_MS);       ServiceWatchDogAndCheckHeartBeat();    return(status); }
///////////////////////////////////////////////////// Reading data from Safety CPU//////////////////////////////////////////////////uint8 MonitorCPUI2CBlockRead(uint8 read_cmd, uint8* read_data, uint8* data_len) { uint8 i2c_status=FALSE;      uint8 status=FALSE; uint8 i=0;    //uint8 read_buff[CPU2_BLK_READ_SIZE]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};     if(NULL != data_len)    {        //uint8 i;        if(*data_len < CPU2_BLK_READ_SIZE)        {            i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */        if(I2C_Master_MSTR_NO_ERROR == i2c_status ) // Check if transfer completed without errors         {                 i2c_status = I2C_Master_MasterSendStart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_WRITE_XFER_MODE); // device address            if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors             {                    i2c_status = I2C_Master_MasterWriteByte(read_cmd);  // EXT EEPROM command                    if(i2c_status == I2C_Master_MSTR_NO_ERROR)                    {                        i2c_status = I2C_Master_MasterSendRestart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_READ_XFER_MODE);                        if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors                     {                                    for(i=0;i<(*data_len);i++)                            {                                if(i<((*data_len)-1))                                {                                    read_data=I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);                                }                                else                                {                                    read_data=I2C_Master_MasterReadByte(I2C_Master_NAK_DATA);                                }                                ServiceWatchDogAndCheckHeartBeat();                            }                                                }                     else                    {                    GUI_DispStringAt ("ERR1_I2C_MONITOR_CPU_RD", 100,70);                    }                    }                    else                    {                        GUI_DispStringAt ("ERR2_I2C_MONITOR_CPU_RD", 100,10);                    }            }            else            {            GUI_DispStringAt ("ERR3_I2C_MONITOR_CPU_RD", 100,50);            }                    I2C_Master_MasterSendStop(); // Send Stop                 i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */            }            else            {                GUI_DispStringAt ("ERR4_I2C_MONITOR_CPU_RD", 100,70);            } if(I2C_Master_MSTR_NO_ERROR != i2c_status ) { status = FALSE; (*data_len) =0; } } else { (*data_len) =0; } CyDelay(EEPROM_OP_DELAY_MS); }      ServiceWatchDogAndCheckHeartBeat();    return(status); }///////////////////////////////////////////////////// Sending a block of data to Safety CPU//////////////////////////////////////////////////uint8 MonitorCPUI2CBlockWrite(uint8 write_addr, uint8 *write_data, uint8 data_len)   {     uint8 i2c_status=FALSE;    uint8 status =FALSE; uint8 i;       if((NULL != write_data) && (data_len <CPU2_BLK_WRITE_SIZE))   {        i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */    if(I2C_Master_MSTR_NO_ERROR == i2c_status ) // Check if transfer completed without errors     {                  i2c_status = I2C_Master_MasterSendStart(I2C_SLAVE_ADDR_SAFETY_CPU, I2C_Master_WRITE_XFER_MODE); // device address        if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors         {                i2c_status = I2C_Master_MasterWriteByte(write_addr);  // EXT EEPROM command                if(I2C_Master_MSTR_NO_ERROR == i2c_status)                {                    for(i=0;((i<data_len)&&(I2C_Master_MSTR_NO_ERROR == i2c_status ));i++)                    {                                    i2c_status = I2C_Master_MasterWriteByte(write_data); // device address                        ServiceWatchDogAndCheckHeartBeat();                    }                if(I2C_Master_MSTR_NO_ERROR == i2c_status) // Check if transfer completed without errors                 {                        status=TRUE;                    }                else                {                        GUI_DispStringAt ("ERR1_I2C_ERTC_WR", 100,50);                }                }                   else                {                    GUI_DispStringAt ("ERR2_I2C_MONITOR_CPU_WR", 100,10);                }                      }            else            {               GUI_DispStringAt ("ERR3_I2C_MONITOR_CPU_WR", 100,50);                        }            I2C_Master_MasterSendStop(); // Send Stop             i2c_status =  I2C_Master_MasterClearStatus();  /* Clear any previous status */        }        else        {            GUI_DispStringAt ("ERR4_I2C_MONITOR_CPU_WR", 100,70);        }        if(I2C_Master_MSTR_NO_ERROR != i2c_status )        {            status = FALSE;        }         CyDelay(EEPROM_OP_DELAY_MS);        }    ServiceWatchDogAndCheckHeartBeat(); return(status); }

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

> When I tested, I tested with a slave device. And it works(Slave device get initialized)

> when I use the bit-bang code. But not when I use the I2C/SCB component.

From what I tested with your code and another I2C sensor

I think that both the I2C/SCB component and your code are working.

But from the Sniffer data, I imagine something quite similar to the previously attached picture is taking place.

IMG_3312.JPG

In this picture, after the start condition, 7bits are "0x72" and 8th bit is "0" for write which form "E4".

Next the slave device with address 0x72 is expected to generate "ACK" but since there was no slave device

connected ACK was not generated, which in turn means the Master received "NACK" and transaction was aborted.

Then with the next transaction loop, the program starts with generating address, and again only "E4" will be detected.

On the other hand the picture with HIH6130(address = 0x27) is connected

IMG_3313.JPG

After start condition 0x27 + 0 is sent, at the next SCL, SDA was pulled to LOW

by HIH6130 which is "ACK". Then remaining bytes were sent.

So if you are connecting your I2C slave device and the transaction is like the first one above,

I suspect that your slave is not generating "ACK" by some reason(s).

I think that as the bit-bang does not care about ACK/NACK

and just sends the data so that the slave could receive all the data and could be initialized.

Best Regards,

17-Jan-2019

Motoo Tanaka

View solution in original post

0 Likes
21 Replies
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,

There could be many things which can go wrong.

Among them, at first I would check hardware.

(1) Make sure that in the "Pins" the SCL and SDA signals are connected to correct pins?

(2) Are both  SCL and SDA signals are pulled up with 2K~10K to VDD?

(3) Attached is an I2C bus_scan program I wrote while back.

At least it is working on CY8CKIT-044,

so may be you can use it to check if the signal is (at least) moving.

> In fact, the code examples from Cypress Website also can not send any data on the bus as I tried to monitor using a beagle I2C sniffer.

> Any idea? I can configure my SCL and SDA as Open Drain pins in PSOC5. in PSOC4 I have no option of creating GPIO  pins first

> and then wiring/connecting the I2CMaster block on to them.

I think that if we insert I2C (SCB) component and assign pins for SCL, SDA,

these pins are configured as Open Drain(s).

Or we could configure I2C module, in the Congire I2C check "Show I2C terminals"

then attach GPIO and configure them as open drain.

moto

0 Likes

"I think that if we insert I2C (SCB) component and assign pins for SCL, SDA,

these pins are configured as Open Drain(s).

Or we could configure I2C module, in the Congire I2C check "Show I2C terminals"

then attach GPIO and configure them as open drain."

I am not sure about the first part. But for second part, it is not correct. ""Show I2C terminals" can not be selected when "Master mode is enabled. I am using a custom board. I have more than 5years experience using PSOC controllers. Mainly PSOC5. All previous cases PSOC4 controllers I used, I used in slave mode and EZI2c.

But now I am trying to port over my PSOC5 MASTER code( which is more than proven, used in 4 commercial products by our company, written by me)

I can port over my code to Pioneer Kit and publish here so that you can analyze.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

In my previous message I was concerning only about the basic setup.

And yes there are many difference in the name of APIs between PSoC 4 and PSoC 5

for example

PSoC 5 : UART_PutString()

PSoC 4 : UART_UartPutString()

So, we may have to modify not a little portion of our intermediate functions

between the API and the Application.

> I can port over my code to Pioneer Kit and publish here so that you can analyze.

That will be a very nice of you. (I prefer CY8CKIT-044)

> I am not sure about the first part. But for second part, it is not correct.

>  ""Show I2C terminals" can not be selected when "Master mode is enabled. I am using a custom board.

> I have more than 5years experience using PSOC controllers. Mainly PSOC5.

> All previous cases PSOC4 controllers I used, I used in slave mode and EZI2c.

I'm using PSoC Creator v4.2 and to test this, I created a project for 4200M (CY8CKIT-044).

I inserted a SCB I2C Component and configured it as a "Master"

000-I2C_as_Master.JPG

Then in the IC2 Pins tab, I checked Show I2C terminals

001-I2C_show_terminal.JPG

When I select Apply or OK

002-I2C_Symbol.JPG

Best Regards,

11-Jan-2019

Motoo Tanaka

0 Likes

Dear Tanaka -San,

On my real target board it is possible which has CY8C4246AZI-L433. But on Pioneer Kit which uses "CY8C4245AXI-483 44TQFP" when I tried to port over an example, it is not possible.

See the below error.

I2C_SS1.jpgI2C_SS2.jpg

I2C_SS3.jpg

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

You are correct!

I have just confirmed the same symptom when I selected the device as CY8C4245AXI-483.

So it was my bad that I failed to consider about that device.

Meantime, I'm glad that both CY8C4246AZI-L433 on your real system

and CY8C4247AZI-M485 on my CY8CKIT-044 are capable of handling this choice.

As we found, even within PSoC 4 family devices there are such differences,

then we must be preparing for more differences between PSoC 5 and PSoC 4...

I have posted some of my I2C samples for PSoC 4, although they may not be

as professional as you'd like to see, I hope they can be some sample reference

for your I2C project.

I2C (and SPI) Temperature, Humidity, Pressure and Gas Sensor (BME680)

I2C Gas Sensor for Monitoring IAQ (CCS811) Sample Project

I2C Temperature and Humidity Sensor (SHT31)

Maze, my first demo binary

Best Regards,

14-Jan-2019

Motoo Tanaka

0 Likes

Dear Tanaka-San,

But even on my target board the I2C functions are not working. Attached is the sample code I wrote for the target board. We can port over to PioneerKit but then will have to remove "Show terminals" option.

Also attached is the schematic of the PSOC4 chip. Chip does not have any external XTAL oscillators. Tried for both 24MHz and 48MHz IMO. ILO configured to be 32KHz,.  I believe what I am facing is related to "Clock Setting"

Any Idea? Attached is the full code.

This code fails to send any data including the Start Condition on I2C Bus. Running my Bitbang code on the same connection gets me successful communication. So nothing to do we H/W. Attached is the full test code, which is supposed to send 4bytes of Data to a slave address 0x72 every 4 seconds. Pressing P4_0 will .make the PSOC sent the 4bytes 1 byte at a time while not pressing P4_0 will make it, send in Block Write mode. Both the write modes FAIL.

CY8C4246AZI-L433_Schematic.jpg

0 Likes

Here is the download link to the code.

I can't upload the code here. I do not see any options for the same.

https://we.tl/t-8FO855LVyS

0 Likes

Hi,

You can send the project by archiving it in PSoC Creator. Please follow these steps:

In PSoC Creator, Project -> Archive Workspace/ Project and attach the zip file here. Click Use advanced editor in the text area, it shows you the attach file symbol there.

Regards,

Bragadeesh

Regards,
Bragadeesh
0 Likes
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi,

Also, could you please send your project file so that we can test your code from our side?

Regards,

Bragadeesh

Regards,
Bragadeesh
0 Likes
lock attach
Attachments are accessible only for community members.
rojkc_1859651
Level 1
Level 1

Attached here. Thanks Brageesh.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

I downloaded your I2cTest.zip and changed the device to CY84248BZI-L489,

which is the device mounted on the CY8CKIT-046 evaluation board I'm using.

And I changed pin assignments to fit the board.

(1) When I ran the program without any other modification.

Yes, as you stated no I2C signal came out.

Actually at the first place in I2C_M_I2C_MASTER.c

if(I2C_M_CHECK_I2C_STATUS(I2C_M_I2C_STATUS_BUS_BUSY))

is returning I2C_STATUS_BUS_BUSY, so no farther operation was done.

(2) I tried modifying the pin configuration of SCL_1, SDA_1 but had no improvement, so far.

(3) Then I changed the configuration of I2C_M to un-check the Show I2C terminals

011-no-external-terminal.JPG

which changed the schematic as below

012-Schematic-after.JPG

And I reassigned \I2C_M:scl\ and \I2C_M:sda\ to where SCL_1 and SDA_1 were assigned

013-pin-assign.JPG

Then I rebuilt and ran the program

IMG_3304.JPG

Now I2C module seems to be working.

So far, I have no idea why the external terminals did not work,

as in my sample below I was doing similar configuration, but I2C was working.

I2C (and SPI) Temperature, Humidity, Pressure and Gas Sensor (BME680)

Anyway, if you can put up with not having "external terminals" with I2C_M,

(I hope that) you can proceed your project.

Best Regards,

15-Jan-2019

Motoo Tanaka

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

I think that I found the cause, in the configuration of SCL_1

you did not check "Input buffer enabled", as SCL seems to be only output.

But in I2C, scl is also used as input to check if the bus is busy.

020-SCL_1_input_not_enabled.JPG

So I checked "Input buffer enabled" and re-built the project.

021-SCL_1_input_enabled.JPG

And your project is now generating I2C signal with my board.

IMG_3305.JPG

Best Regards,

15-Jan-2019

Motoo Tanaka

0 Likes

It still does not work.

I took the exact code, put in the target board. And ran with "Show Terminals" and Without "Show Terminals" All I see on my beagle sniffer is E4. Then I ran my bit-bang code with out any changes and It showed the actual Data.

When you saw the Waveform on Scope did you verify those waveforms are able to be interpreted correctly by any device?

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

I'm sorry, but I did not use protocol analyzer nor check the data on the Oscilloscope, so I can not tell if the data was correct.

BTW, by "It still does not work." what exactly you mean?

(1) SCL and SDA signals are not generated?

(2) Although Signals are generated they are incorrect?

Meantime, I noticed something interesting.

As it's already at night in Japan, and I have only CY8CKIT-044 at home, I tried to change device of the project you attached.

Then I received "Clock Setting Related Errors for PLL0 and PLL1" during the application generation.

This sounds something like you were writing in earlier response.

I tried to fix the clock settings but I could not figured out how.

So I created a brand new project for CY8CKIT-044 (CY8C4247AZI-M485) then copied main.c and device.c into this new project.

Then the project could be built without the errors.

So far, I have not been able to check the signal, but this might be a good trial to port your project to your target PSoC 4.

Best Regards,

16-Jan-2019

Motoo Tanaka

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

So I connected my oscilloscope to my CY8CKIT-044 and tried to view the data.

(1) The good news is that the first byte seems to be E4, which is 72 + write

(2) The bad news is I could not catch next byte with my oscilloscope

IMG_3312.JPG

Then I noticed that there is no I2C slave device with address 0x72 connected in my system.

So I grabbed HIH6130, whose I2C address is known to be 0x27.

And I connected the device via MSS (Marubun Sensor Shield).

IMG_3314.JPG

Then I modified I2C_WRITE_ADDR in your device.h to 0x27.

And rebuilt the project and ran the test.

IMG_3313.JPG

It's after mid-night in Japan, may I go to bed now?

Best Regards,

17-Jan-2019

Motoo Tanaka

0 Likes

Dear Tanaka-San,

Thank you very much for your effort. Good night

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

> This code below does not even check for ACK. But it works...

Yes, this is what I was trying to show.

The I2C Master checks for ACK and if it does not get ACK, it won't proceed.

So we need the slave device of address 0x72 which will return ACK when its address is sent from the master.

As I tested, with HIH6130 (address 0x27), your program seemed to be working OK with a slave device.

Best Regards,

17-Jan-2019

Motoo Tanaka

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

When I tested, I tested with a slave device. And it works(Slave device get initialized) when I use the bit-bang code. But not when I use the I2C/SCB component.

Attached is the screenshot when it does not work as taken on I2C sniffer(Beagle)

I2C_Sniffer_SS1.jpg

I2C_Sniffer_SS2.jpg

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ronnie-san,

> When I tested, I tested with a slave device. And it works(Slave device get initialized)

> when I use the bit-bang code. But not when I use the I2C/SCB component.

From what I tested with your code and another I2C sensor

I think that both the I2C/SCB component and your code are working.

But from the Sniffer data, I imagine something quite similar to the previously attached picture is taking place.

IMG_3312.JPG

In this picture, after the start condition, 7bits are "0x72" and 8th bit is "0" for write which form "E4".

Next the slave device with address 0x72 is expected to generate "ACK" but since there was no slave device

connected ACK was not generated, which in turn means the Master received "NACK" and transaction was aborted.

Then with the next transaction loop, the program starts with generating address, and again only "E4" will be detected.

On the other hand the picture with HIH6130(address = 0x27) is connected

IMG_3313.JPG

After start condition 0x27 + 0 is sent, at the next SCL, SDA was pulled to LOW

by HIH6130 which is "ACK". Then remaining bytes were sent.

So if you are connecting your I2C slave device and the transaction is like the first one above,

I suspect that your slave is not generating "ACK" by some reason(s).

I think that as the bit-bang does not care about ACK/NACK

and just sends the data so that the slave could receive all the data and could be initialized.

Best Regards,

17-Jan-2019

Motoo Tanaka

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

Hi Ronnie,

I tried your I2C test sample project in one of our Cypress kits CY8CKIT-046 PSoC 4L series kit that has CY8C4248BZI-L489 in it. I used Aadvark I2C host adapter as the slave device configured with device slave address 0x72. I used a Saleae analyzer to probe the bus. I incorporated the right changes suggested by Motoo -san and the code is working as expected. Please find the attached screenshots with this message.

You will have to probe your bus and check if your slave is Nack-ing. If this is not happening then there should be something wrong with the slave side. Please probe your bus and share your results.

Regards,

Bragadeesh

Regards,
Bragadeesh
lock attach
Attachments are accessible only for community members.

Yes it is generating some signals but the protocol generator just print "0xE0" all the way. When I disabled the H/W SCB and wrote the following I2C Bitbang code. Protocol analyzer can see what is being sent correctly. This code below does not even check for ACK. But it works...

#define PERIPHERAL_1_I2C_CLOCK_Write(high_low) (P0_4_SCL_Write(high_low))

#define PERIPHERAL_1_I2C_DATA_Write(high_low) (P0_5_SDA_Write(high_low))

#define PERIPHERAL_1_I2C_DATA_Read P0_5_SDA_Read

static void fnPERIPHERAL_1_I2C_Init();

static void fnPERIPHERAL_1_I2C_SendStart();

static void fnPERIPHERAL_1_I2C_SendStop();

static uint8 fnPERIPHERAL_1_I2C_SendByte(uint8);

//////////////////////////////////////////////////////////////

// Write a block to PERIPHERAL_1_ VIDEO CONTROLLER in BIT BANGING MODE

//////////////////////////////////////////////////////////////

uint8 PERIPHERAL_1_I2CBlockWriteBitBang(uint8 *reg_data, uint8 data_len)

{

    //uint32 i2c_status=FALSE;

    uint8 status=TRUE;

uint8 i = 0;

if((NULL != reg_data) && (0!=data_len))

    {

        fnPERIPHERAL_1_I2C_Init();

        fnPERIPHERAL_1_I2C_SendStart();

        fnPERIPHERAL_1_I2C_SendByte(I2C_SLAVE_ADDR_PERIPHERAL_1_CHIP);

for(i=0; i< data_len; i++)

{

fnPERIPHERAL_1_I2C_SendByte((uint32)reg_data);

}

    }

    fnPERIPHERAL_1_I2C_SendStop();

    return(status);

}

// Inits bitbanging port, must be called before using the functions below

//

static void fnPERIPHERAL_1_I2C_Init()

{

PERIPHERAL_1_I2C_CLOCK_Write(HIGH);

PERIPHERAL_1_I2C_DATA_Write(HIGH);

CyDelay(I2C_INTER_BIT_DELAY);

}

  

/*** Executable Functions ***/

static void fnPERIPHERAL_1_I2C_SendStart()

{

//OUTPUT

PERIPHERAL_1_I2C_DATA_Write(HIGH);

PERIPHERAL_1_I2C_CLOCK_Write(HIGH);

CyDelay(I2C_DELAY_HALF);

PERIPHERAL_1_I2C_DATA_Write(LOW);

CyDelay(I2C_DELAY_HALF);

PERIPHERAL_1_I2C_CLOCK_Write(LOW);

CyDelay(I2C_DELAY_HALF);

}

static void fnPERIPHERAL_1_I2C_SendStop()

{

//OUTPUT

PERIPHERAL_1_I2C_CLOCK_Write(LOW);

PERIPHERAL_1_I2C_DATA_Write(LOW);

PERIPHERAL_1_I2C_CLOCK_Write(HIGH);

CyDelay(I2C_DELAY_HALF);

PERIPHERAL_1_I2C_DATA_Write(HIGH);

CyDelay(I2C_DELAY_HALF);

PERIPHERAL_1_I2C_CLOCK_Write(LOW);

CyDelay(I2C_DELAY_HALF);

}

/* Send Byte */

static uint8 fnPERIPHERAL_1_I2C_SendByte(uint8 uchByte)

{

uint8 uchBitCounter;

uint8 uchBitSelection;

//OUTPUT

uchBitSelection = 0x80;

for(uchBitCounter = 0; uchBitCounter <8; uchBitCounter ++)

{

if(uchByte & uchBitSelection)

{

PERIPHERAL_1_I2C_DATA_Write(HIGH);

}

else

{

PERIPHERAL_1_I2C_DATA_Write(LOW);

}

uchBitSelection >>= 1;

PERIPHERAL_1_I2C_CLOCK_Write(HIGH);

CyDelay(I2C_DELAY_FULL);

PERIPHERAL_1_I2C_CLOCK_Write(LOW);

CyDelay(I2C_DELAY_FULL);

}

    PERIPHERAL_1_I2C_DATA_Write(HIGH);

CyDelay(I2C_DELAY_HALF);

//INPUT

PERIPHERAL_1_I2C_CLOCK_Write(HIGH);

CyDelay(I2C_DELAY_FULL);

// should check if acknowledge is received uchBitSelection = _PTA.Byte;

if(PERIPHERAL_1_I2C_DATA_Read())

{

uchBitSelection=FALSE;

}

else

{

uchBitSelection=TRUE;

}

PERIPHERAL_1_I2C_CLOCK_Write(LOW);

/*uchBitSelection ^= 0xFF;

uchBitSelection &= 0x08; //20 SHOULD BE 08

*/

CyDelay(I2C_DELAY_FULL);

return (uchBitSelection);

}

0 Likes