Raspberry PI read & write to PSoC

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

cross mob
DaHe_4770596
Level 1
Level 1

I have a CY8CKIT-059 PSoC 5LP prototyping kit, and I am trying to have my Rasberry PI 3b+ send data through an  I2C connection to the PSoC to adjust the PWM of the onboard LED on the PSoC. I am able to send an increase, decrease, and clear command to the PSoC, but when I try to read the data from the PSoC, I am no longer able to send commands. Note: I am using an EZI2C component.

Here is my PSoC code:

#include "project.h"

uint8 I2Cbuffer[128];

int main(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    uint8 PWMValue = 0;

    I2C_Start();

    PWM_Start();

    I2C_SetBuffer1(128, sizeof(I2Cbuffer), I2Cbuffer);

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */

    while(1)

    {      

        if(I2C_curStatus == I2C_STATUS_WRITE1 )

        {

            I2C_GetActivity(); //Clears the flag

          

            if (I2Cbuffer[0] == 0x46)

            {

                PWMValue = PWMValue + 10;

            }

          

            else if (I2Cbuffer[0] == 0x52)

            {

                PWMValue = PWMValue - 10;

            }

          

            else if (I2Cbuffer[0] == 0x5A)

            {

                PWMValue = 0;

            }

            I2Cbuffer[8] = PWMValue; //subaddress I will look for the data

            PWM_WriteCompare(PWMValue);

        }

    }

}

/* [] END OF FILE */

My python code through the Raspberry PI uses smbus to send data to address 8, sub-address 0.  I then read data from address: 8, sub-address: 8. For read commands I print the read data to the console.

My PSoC code was generated using PSoC creator 4.3.

I'm fairly new to the PSoC devices, any idea where there might be a fault?

0 Likes
1 Solution

Hi DaHe_4770596​,

The issue is with the if condition that is checking the status of EZI2C activity. The EZI2C status sets multiple bits based on the different events. For example, I2C_STATUS_WRITE1 and  I2C_STATUS_ERR can happen at the same time. Therefore the right way to identify different events is to check for each bit in the return of I2C_GetActivity()

Example:

if((I2C_GetActivity() & I2C_STATUS_WRITE1) != 0)

{

     //write event occurred.

}

if((I2C_GetActivity() & I2C_STATUS_ERR ) != 0)

{

     //I2C error occurred.

}

What was happening in your case?

When a read event occurred, the read bit in the status was set. This read bit is set as long as the  I2C_GetActivity() is called. In your firmware you are never checking for this bit using  I2C_GetActivity(), therefore it is never cleared. When a write event happens, both the read and write bit will be set and this is why the current status variable would never be I2C_STATUS_WRITE1 alone. That is why you should check for individual bits by using the snippet above. Please avoid using internal global variables such as I2C_curStatus. Use the wrapper function (I2C_GetActivity() for more reliability.

Regards,

Bragadeesh

Regards,
Bragadeesh

View solution in original post

4 Replies
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi DaHe_4770596​,

We do not see any issues with the code. Can you share the following?

1. PSoC Creator project archive file. We would like to see the component settings.

2. Bus Transaction while the issue occurs. Is the PSoC device NACKing the read?

A minor comment. Instead of using the internal global variable I2C_curStatus , you can use the I2C_GetActivity() directly to return the status and clear the status in a single function.

Regards,

Bragadeesh

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

Hello BragadeeshV_41,

Thank you for taking a look at my issue. I have attached the archive file. For the bus transaction, is this data displayed anywhere through the PSoC creator software, or are you looking for an oscilloscope readout?

I have tried running this program through the BridgeController and I have noticed that Read commands (r 8 x p) will read the value in the buffer, but further write commands will no longer change the LED brightness. The signal is still acknowledging, however. See picture. I send three "increase" commands, followed by a "read", then another "increase". After the read the LED no longer increases in brightness. See attached photo.

Regards,

Daniel Henderson

0 Likes

Hi DaHe_4770596​,

The issue is with the if condition that is checking the status of EZI2C activity. The EZI2C status sets multiple bits based on the different events. For example, I2C_STATUS_WRITE1 and  I2C_STATUS_ERR can happen at the same time. Therefore the right way to identify different events is to check for each bit in the return of I2C_GetActivity()

Example:

if((I2C_GetActivity() & I2C_STATUS_WRITE1) != 0)

{

     //write event occurred.

}

if((I2C_GetActivity() & I2C_STATUS_ERR ) != 0)

{

     //I2C error occurred.

}

What was happening in your case?

When a read event occurred, the read bit in the status was set. This read bit is set as long as the  I2C_GetActivity() is called. In your firmware you are never checking for this bit using  I2C_GetActivity(), therefore it is never cleared. When a write event happens, both the read and write bit will be set and this is why the current status variable would never be I2C_STATUS_WRITE1 alone. That is why you should check for individual bits by using the snippet above. Please avoid using internal global variables such as I2C_curStatus. Use the wrapper function (I2C_GetActivity() for more reliability.

Regards,

Bragadeesh

Regards,
Bragadeesh

The other thing to do is use the Bridge Control panel to sends commands while acting as an I2C master to make sure that you understand the total behavior of the slave.

I have written extensively about using BCP on my website https://iotexpert.com/?s=bridge+control+panel

0 Likes