PSoC5 Freezes during I2C Transmission

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

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi,

   

 

   

We are using 3 PSoCs on our board. We are using CY8C5268AXI-LP047 (PSoC5), CY8C4247AZI-M485 (PSoC4200M) and CY8C4245AXI-483 (PSoC4200).

   

The PSoC5 is connected to the PC via USBUART and I get to send commands using a hyperterminal. The commands include GPIO write/read. The PSoC4200M (address: 0x0A) and PSoC4200 (address: 0x08) are connected to the PSoC5 via I2C. Whenever I issue a GPIO read/write command in the hyperterminal, the PSoC5 will return ^OK or ^ERROR for GPIO Write and ^LOW or ^HIGH for GPIO read.

   

In the hardware, we had incorporated an LED which serves as the heartbeat of PSoC5. Using Systick timer, the LED is set to toggle every 1 second. This indicates that the PSoC5 is fully operational.

   

For the debugging of our board, I did a modular testing with the following flow:

   

1. PSoC5 Test - Issue GPIO Read/Write Command via I2C to read/write to PSoC5 GPIO. USB comm is ok and result is as expected.

   

2. PSoC5 and PSoC4200M Test - Issue GPIO Read/Write Command via I2C to read/write to PSoC4200M GPIO. USB comm is ok. I2C comm is ok. Result is as expected.

   

3. PSoC5, PSoC4200M and PSoC4200 Test - Issue GPIO Read/Write Command via I2C to read/write to PSoC4200 GPIO. Error received. PSoC5 hangs. PSoC5 LED does not toggle.

   

 

   

The I2C code for the I2C slaves are identical. I was not expecting an error for the PSoC5, PSoC4200M and PSoC4200 Test. I did some debugging and included multiple printfs in the PSoC5 I2C Write. See code excerpt below:

   

void I2C_Master_Write(uint8 SlaveAddress, int i)
{               
    USB_printf("\r\nMaster I2C Write attempt...\r\n");
    if (0u == WriteCommandPacket(SlaveAddress, i))
    {
        USB_printf("\r\nMaster Write I2C attempt success\r\n");
        /* Read response packet from the slave */
        USB_printf("\r\nMaster Read I2C attempt\r\n");
        if (0u == ReadStatusPacket(SlaveAddress))
        {
            USB_printf("\r\nMaster Read I2C attempt successful\r\n");
            ReadBufferProcessing();                
        }
        else
        {
            USB_printf("Error Reading Buffer!");
        }
        
        I2C_Clear();
        USB_Clear();
    }
    else
    {
        USB_printf("\r\nMaster Write I2C attempt fail\r\n");   
    }
       
}

   

uint32 WriteCommandPacket(uint8 SlaveAddress, int i)
{

   

    uint32 status = TRANSFER_ERROR;
    uint8 write_err;
    char res[24];
    write_err = DFE_I2C_MasterWriteBuf(SlaveAddress, dfe_i2cbufw, i, DFE_I2C_MODE_COMPLETE_XFER);
    sprintf((char *) res, "\r\n%u Error in DFE Master Write\r\n", write_err);
    USB_printf(res);
    while (0u == (DFE_I2C_MasterStatus() & DFE_I2C_MSTAT_WR_CMPLT))
    {
       
    }

   

    /* Displays transfer status */
    if (0u == (DFE_I2C_MSTAT_ERR_XFER & DFE_I2C_MasterStatus()))
    {
       
        /* Check if all bytes was written */
        if (DFE_I2C_MasterGetWriteBufSize() == i)
        {
           
            status = TRANSFER_CMPLT;          
        }
        
    }
    else
    {
       USB_printf("\r\nDFE_I2C_MasterStatus() = %u\r\n", DFE_I2C_MasterStatus());
    }

   

    DFE_I2C_MasterClearStatus();
   
    sprintf((char *)res, "\r\n write command status: %lu\r\n", status);
    USB_printf(res);
       
    return (status);
}

   

 

   

I've attached an image of the PSoC5 response to the hyperterminal. 

   

The I2C_MasterWriteBuf() API returns 0 errors.

   

I2C_MasterStatus() API returns 162 thus the WriteCommandPacket returns 0xFF or 255. I am expecting that after printing the message "write command status: 255" in the hyperterminal, it should immediately be followed by "Master Write I2C attempt fail" however the PSoC5 freezes and I need to power cycle the whole board to unfreeze the PSoC5.

   

I've worked on this issue for quite some time now and I'm still stuck. Can anyone indicate what may be wrong or what I've missed? Also, I cannot provide directly the project zip file in the forum as it is not approved by our client. I can, however, forward a copy of the projects via email (kathleen.gayo@gintuga.com) for anyone who can help.

   

 

   

Thanks,

   

K

0 Likes
1 Solution
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

At very first sight:

   

    char res[24];
    write_err = DFE_I2C_MasterWriteBuf(SlaveAddress, dfe_i2cbufw, i, DFE_I2C_MODE_COMPLETE_XFER);
    sprintf((char *) res, "\r\n%u Error in DFE Master Write\r\n", write_err);

   

The sprintf() will exceed the 24 bytes for "res" by far, thus clobbering the stack...   😉

   

 

   

Bob
 

View solution in original post

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

At very first sight:

   

    char res[24];
    write_err = DFE_I2C_MasterWriteBuf(SlaveAddress, dfe_i2cbufw, i, DFE_I2C_MODE_COMPLETE_XFER);
    sprintf((char *) res, "\r\n%u Error in DFE Master Write\r\n", write_err);

   

The sprintf() will exceed the 24 bytes for "res" by far, thus clobbering the stack...   😉

   

 

   

Bob
 

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

Hi Bob,

   

This resolved the issue of PSoC5 hanging up. Thanks.

   

Another question though, the I2C communication to the PSoC4200 is still erroneous. However the I2C communication to the PSoC4200M is working. Whenever I attempt to write a command for PSoC 4200, the values of the API returns are :

   

The I2C_MasterWriteBuf() API returns 0 errors.

   

I2C_MasterStatus() API returns 162 thus the WriteCommandPacket returns 0xFF or 255.  

   

 

   

I've attached 2 images here which are snips of the hyperterminal display whenever I attempt an I2C write to PSoC4200 and PSoC4200M. I've also checked the hardware connection and power. Hardware aspect is diagnosed as ok. What could cause the error wherein the I2C_MasterStatus() API returns 162? 

   

 

   

Thanks,

   

K

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

See .h file for bit patterns

   

/* Master API returns */
#define I2C_1_I2C_MSTR_NO_ERROR          (0x00u)  /* Function complete without error                       */
#define I2C_1_I2C_MSTR_ERR_ARB_LOST      (0x01u)  /* Master lost arbitration: INTR_MASTER_I2C_ARB_LOST     */
#define I2C_1_I2C_MSTR_ERR_LB_NAK        (0x02u)  /* Last Byte Naked: INTR_MASTER_I2C_NACK                 */
#define I2C_1_I2C_MSTR_NOT_READY         (0x04u)  /* Master on the bus or Slave operation is in progress   */
#define I2C_1_I2C_MSTR_BUS_BUSY          (0x08u)  /* Bus is busy, process not started                      */
#define I2C_1_I2C_MSTR_ERR_ABORT_START   (0x10u)  /* Slave was addressed before master begin Start gen     */
#define I2C_1_I2C_MSTR_ERR_BUS_ERR       (0x100u) /* Bus error has: INTR_MASTER_I2C_BUS_ERROR              */

   


162 is invalid, please clear the error status before transmission. Last byte NAKed might be the error.

   

Have you got a logic analyzer that is able to decode I2C and other protocols? Might be quite helpful.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hi Bob,

   

I've issued I2C_MasterClearStatus(); before I2C transmission however, I still receive the same error. I've checked the header file before and found no 162 value as well which made the debugging a bit difficult.

   

I could try to probe the I2C lines using a standard oscilloscope. I'll upload the image as soon as I have it.

   

 

   

Thanks,

   

K

0 Likes
Anonymous
Not applicable

Hi Bob,

   

 

   

I was able to trace where the 162 value comes from. Apparently it was from the Address NACK

   

​DFE_I2C_mstrStatus |= (DFE_I2C_MSTAT_ERR_XFER | DFE_I2C_MSTAT_ERR_ADDR_NAK); 

   

I've checked the address (Slave address in 0x08) and the data rate (100kbps). Both the I2C slave and master are in sync with the settings. What could be the possible cause of Address NACK? 

   

 

   

Thanks,

   

K

0 Likes
Anonymous
Not applicable

Hi Bob,

   

When I was preparing myself to open a forum entry, I noticed, the you have opened a ticket in a very similar case. I do not know whether my findings has a relation with your problems, or not, but here is my entry.

   

<a href="http://www.cypress.com/forum/psoc-5-known-problems-and-solutions/cyassert-i2c-isr-causing-psoc-freez...">http://www.cypress.com/forum/psoc-5-known-problems-and-solutions/cyassert-i2c-isr-causing-psoc-freez...</A>

   

​Br,

   

Lajos

   

0 Likes
Anonymous
Not applicable

Seems, the link was not successfully added. This is the URL, where you cen find it:

   

http://www.cypress.com/forum/psoc-5-known-problems-and-solutions/cyassert-i2c-isr-causing-psoc-freez...

0 Likes
Anonymous
Not applicable

Hi Lajos,

   

 

   

I've checked your forum entry. Were you receiving NAK from the I2C slave as well?

   

The I2C Master in my project has 2 slaves and I am able to communicate to one of the slaves(PSoC4200M) successfully without any issues. Bob was able to point out my code error as to why I encounter a "freeze" in my PSoC5 which was already resolved.

   

Whenever I try to communicate with the other slave (PSoC4200), I received Address NAK error based on the value of the I2C_mstrStatus. 

   

I am trying to investigate the chip as well as the PSoC4200 from one of the board heated at boot up. This is the first time I've encountered an Address NAK  in I2C which is why I'm quite in the gray in figuring out what's wrong. We're using a customized board by the way.

   

 

   

Thanks,

   

K

0 Likes
Anonymous
Not applicable

Hi,

   

It is quite normal in I2C world, if the slave device is not ready, simply the device does not listen to the I2C SDA/SCL lines, thus the address byte sent by the master is not acknowledged by the slave. I did not catch this error in my case. If I remember well I caught case, when several bytes was assumed to send by the master, and one of the data byte contained invalid value, which was nacked by the slave, so master did not sent further bytes. PSoC controller worked further, but both I2C lines remained in pulled low state. And surprinngly PSoC fell into freeze on the next I2C operation, but indeed on this I2C lines the I2C start can not be initiated, as I2C lines must be in high for that. But again, it was many days ago, and I may not remember correctly.

   

 

   

If you think, your PSoC freeze is derived from the I2C API ISR, I really recommend to add some visible sign of it. For me it was easiest to change the logic level of an output pin. This relies on the fact if the ARM core of PSoC becomes frozen, the hardware part of the chip is still working, so the logic level of the test pin is kept on the last state.

   

It requires only one line of code just before the CYASSERT instructions:

   

*((uint8 *) (addr))=(0x0C+((value)&1));

   

where addr=(0x40005000 + ((port)<<3) + (pin)), and value=0 or 1. E.g. for P2_3 port=2, pin=3.

   

Br,

   

Lajos

0 Likes