1 2 Previous Next 29 Replies Latest reply on Oct 15, 2018 12:11 PM by user_80002741

    I2C Between two PSoc5 CY8CKIT-059 Master to Slave

    user_80002741

      Hello, I trying to develop a simple I2C program using two PSoC5 CY8CKIT-059's. I have one kit acting as the Master and the other kit as a Slave. The idea is to have the slave PWM control the onboard blue LED. The Slave expects to receive two bytes, byte 1 will turn on the LED and byte 2 will control the PWM frequency. I got it working using the Bridge Control Panel. I was so happy. Here is my code:

       

      int main(void)

      {

          uint8 i2cbuff[2];

          CyGlobalIntEnable; /* Enable global interrupts. */

          I2C_Start();

          I2C_SetBuffer1(2,2, i2cbuff);

          i2cbuff[0] = 0;

          PWM_1_WriteCompare1(1);

         

          for(;;)

         {

              if(i2cbuff[0] == 0)     // Byte 0 is the on/off control, if equal to 0 stops the PWM

                  PWM_1_Stop();

              else if(i2cbuff[0] == 1)  // Byte 0 is 1 start PWM module

              {

                  PWM_1_Start();

                  PWM_1_WriteCompare1(255);

              }

          }

      }

       

      The Slave was very easy because there was a great PSoC 101 video on the topic and I used EZI2C module.

       

      The problem I now have is getting the Master I2C to work. The Master should send out two bytes to Slave. I have connected together the SCL on both kits and also connected together the SDA pins. Here is my Master Code:

       

      int main()

      {

           LED_ON;  //   define macro to turn on blue led

          CyGlobalIntEnable;

          I2CM_Start();

          LED_ON;

          WriteCommandPacket();   // call function to transmit to slave

         return 0;   

      }

      /*******************************************************************************

      * WriteCommandPacket(): Writes command packet to I2C slave

      *******************************************************************************/

      uint32 WriteCommandPacket(void)

      {

          uint8  buffer[2];

          uint32 status = TRANSFER_ERROR;

          uint8 read = 0;

          /* Initialize buffer with packet */

          buffer[0] = 1;

          buffer[1] = 255;

         

          I2CM_MasterClearStatus();

          I2CM_MasterWriteBuf(0x8, (uint8 *) buffer, 2, I2CM_MODE_COMPLETE_XFER);

          read = I2CM_MasterStatus();

          read = I2CM_MasterStatus(); 

         

          while (0u == (I2CM_MasterStatus() & I2CM_MSTAT_WR_CMPLT))

          {

              /* Waits until master completes write transfer */

                  LED_OFF;

                  CyDelay(1200u);

                  LED_ON;

                  CyDelay(1200u);

                  LED_OFF;

                  CyDelay(300u);

                  LED_ON;

                  CyDelay(300u);

                

          }

         

          LED_OFF;

       

       

          I2CM_MasterClearStatus();

          return (status);

      }

       

      The MasterStatus return 0x004 which is means the transfer in progress.

       

      I have the Master power using a MiniProg3 and the Slave plugs into my laptop. I measured the voltage on the Master and it is 3.3V and the voltage on the Slave is 5.

      Could that be the problem?

       

      Thanks,

      Joe

        • 1. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
          user_80002741

          I found another PSoc5 Kit and snapped off the KitProg so know I have two Kits powered using two MiniProg3 programmers. One laptop has the Master and another laptop has a Slave. Hope this helps.

          • 2. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
            user_80002741

            Seems like the Master stays in the "Transfer in Progress" state and the transfer never completes. Any ideas?

             

            Thanks,

            Joe

            • 3. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
              user_1377889

              A few changes:

              At first set both (master and slave) to the same speed (i.e. 100kbs) using internal clock.

              For Master p12_0 and P12_1 is ok. For the slave use a different set as P12[5:4] to avoid doubly pull-up resistors.

              EZI2C protocol is: First byte address, second(and following bytes) data

              So when you send "1,255" you will receive in your slave buffer[1] the value 255. You never test for that.

              You issue multiple starts and stops to your PWM even when the I2C data did not change. Could be done better when you wait for a successful transfer, then check the data and act accordingly.

               

              And at last a hint: To make life(and debugging) easier you may create I2C Master and Slave un the same device with external connections.

               

              Happy coding

              Bob

              • 4. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                user_80002741

                Thanks Bob! I'll try your suggestions and let you know if I have any problems.

                 

                Thanks again!

                • 5. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                  user_80002741

                  Bob,

                   

                  HI, I've made a project with a Master and Slave module. Two quick questions for you. Do I need to use pull-up resistors on the SCL and SDA external pins? Last, what drive mode should I use for the SDA and SCL for Master pins and the Slave pins?

                   

                  Thanks,

                  Joe

                  • 6. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                    user_1377889

                    The CY8CKIT-059 prototyping kit has got pullups at pins P12_0 and P12_1 already. Connect those to the I2C master. Of course you may use different pins, but then you need to provide your own pullup resistrors.

                    AllI2C pins should be "Open Drain drives low". This ensures that the pullup resistors care for the "High" state and that any device can pull a signal low.Needed for slave clock stretching.

                     

                    Bob

                    • 7. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                      user_80002741

                      Bob,

                       

                      Hello, I have removed the external pull-ups and changed the pin mode to Open Drain drives Low.  Here is my code:

                       

                      #include "project.h"

                      #include "header.h"

                      int main()

                      {

                          uint8 i2cbuff[1];

                          uint8 compare = 0;

                          i2cbuff[0]=3;  

                          I2C_SetBuffer1(1,1, i2cbuff);  

                          I2CM_Start();  // start master

                          I2C_Start();  // start slave

                          CyGlobalIntEnable;

                          WriteCommandPacket();  

                          PWM_1_Start();

                          PWM_1_WriteCompare1(1);

                        

                          for(;;)

                          {

                       

                              if(compare != i2cbuff[0])

                              {

                                  PWM_1_WriteCompare1(i2cbuff[0]);

                                  compare = i2cbuff[0];

                              }

                       

                        }

                        return 0;  

                      }

                       

                       

                      /*******************************************************************************

                      * WriteCommandPacket(): Writes command packet to I2C slave

                      *******************************************************************************/

                      uint32 WriteCommandPacket(void)

                      {

                          uint8  buffer[1];

                          uint32 status = TRANSFER_ERROR;

                          uint8 read = 0;

                          uint32 i2cmWriteSize = 0;

                          /* Initialize buffer with packet */

                          buffer[0] = 255;

                       

                        

                          I2CM_MasterClearStatus();

                          I2CM_MasterWriteBuf(0x8,  buffer, sizeof(buffer), I2CM_MODE_COMPLETE_XFER);

                          read = I2CM_MasterStatus();

                          read = I2CM_MasterStatus();

                        

                          /* Waits until master completes write transfer */

                          while(0u == (I2CM_MasterStatus() & I2CM_MSTAT_WR_CMPLT));

                        

                          i2cmWriteSize = I2CM_MasterGetWriteBufSize();

                       

                          I2CM_MasterClearStatus();

                          return (status);

                      }

                       

                      When I step through the code it never finishes the command:

                      while(0u == (I2CM_MasterStatus() & I2CM_MSTAT_WR_CMPLT));

                       

                      I have have 12[5] SDA connected to 12[1]. I have 12[4] SCL connected to 12[0]. If you could quickly look over what I have attached perhaps you may see what I'm doing wrong. I did attach an o-scope to the SCL and I only saw three low going saw tooth pulses, but that was with the wrong Pin mode settings. I'll try again.

                       

                      Thank you very much,

                      Joe

                      • 8. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                        user_80002741

                        I decided to try a different kit. The one that I was using I snapped off the KitProg. I decided to try a brand new kit with the KitProg still attached. I was able to get past the line:

                        while(0u == (I2CM_MasterStatus() & I2CM_MSTAT_WR_CMPLT));

                        and the line

                          i2cmWriteSize = I2CM_MasterGetWriteBufSize();

                        showed that i2cmWriteSize was 1 which is what I expect, 1 Byte was sent.

                         

                        However, the receive buffer uint8 i2cbuff[1] did not show the value of 255 which the Master sent. Maybe I'm getting closer. Any ideas?

                         

                        thanks,

                        Joe

                        • 10. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                          user_80002741

                          Bob,

                           

                          Thank you very much for those additions to the code. I did run the code on a complete PSoC CYCKit-059 and it did get past the line Wait() function, but there was nothing in the receiver buffer, only 0's. If I run the code only on a PSoc 5LP (Target only) the code never gets past the Wait() function. I have wires connecting the SDA lines and the SCL lines together and not using any external pull-up resistors. Can you think of anything outside of the code that could be cause this problem. I did connect connect an oscope on the SCL lines but did not see a clock. Do I need to run the Kit at 5V instead of 3.3V?

                           

                          Thank you,

                          Joe

                          • 11. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                            user_80002741

                            Bob,

                             

                            Hi, it appears when using the Target and the KitProg the value returned by the line:

                            read = I2CM_MasterStatus();

                            is 0x92 which on page 21/61 of the I2C Master doc means the following bits were set:

                            I2C_MSTAT_WR_CMPLT

                            I2C_MSTAT_ERR_SHORT_XFER: write xfer completed before all bytes were transfered

                            I2C_MSTAT_ERR_XFER

                             

                            I don't see any transitions on the SDA or SCL pins on the o-scope.

                             

                             

                            If I run with only the Target (KitProg broken off) then the it never gets past the Wait() call. Could this be a MiniProg configuration?

                             

                            I'll look over the EZI2C doc and maybe I'll find something.

                             

                            Joe

                            • 12. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                              user_80002741

                              I ran the code with the Target only and if you wait long enough it will get past the Wait() call and the call read = I2CM_MasterStatus(); return 0x92. Maybe that will help find what the problem is. Joe

                              • 13. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                                user_80002741

                                I was reading page 4/24 of the EZI2C Slave ver 2.0 and under Pin connections I decided to choose I2C1 option which set SCL to 12.0 and SDA to 12.1. I was already using these two pins for those functions but decided to try something. After running the code on the Target only it did get past the Wait() and it returned 0xA2 from the I2C_MasterStatus() call. The error 0xA2 says the Slave is not acking back. I'll keep working on it.

                                • 14. Re: I2C Between two PSoc5 CY8CKIT-059 Master to Slave
                                  user_80002741

                                  Hello, well I've made some progress. Below is a screen shot of one Master write:

                                   

                                  scope_0.bmp

                                  I have not used the Serial Decode on the scope before but I believe the first word it the address, the next word is the Address within the EZI2C Buffer, and the last is the data that is transmitted (decimal  201). So, it looks like I'm transmitting okay. I did change some pins to the following:

                                   

                                  Master:

                                  SDA: P12[3]

                                  SCL: P0[1]

                                  Slave:

                                  SDA: P12[1]

                                  SCL: P12[0]

                                   

                                  I am using the PSoc5 Kit with the ProgKit and the Target connected together.

                                   

                                  Now, here's my problem the EZI2C Slave buffer is not getting filled with the data. The line I2CM_MasterStatus() returns the hex value of 0x92 which I think means the Slave did not acknowledge the address. I'll start looking into this problem next.

                                   

                                  Joe

                                  1 2 Previous Next