1 2 Previous Next 18 Replies Latest reply on Dec 19, 2013 7:14 AM by user_78878863

    I2C in PSoC creator 2.0

    user_183705841

       Hi,

         

      I'm trying to communicate with a sensor using I2C interface and I use the I2C Master (UDB) component in the PSoC creator 2.0 to do so.The reset is connected to '0' and the SDA, SCL connected to the sensor (slave) with pull-ups resistors. I used many times before I2C interface so I very familiar with the protocol. the problem is that this time I get a complete module with functions that from the datasheet I just can't understand how to make a simple reading from the slave's registers:

         

      I need to access to the sensor's address and then access its registers using another address and then read the data and save it.

         

      The protocol of the sensor interface is simple and standard:

         

      Master|S|AD+W|        |RA|        |S|AD+R|        |          |NACK|P|

         

      Slave  |  |            |ACK|      |ACK|  |           |ACK|DATA|           |  |

         

      If someone can give me a simple code example for how to use the component's functions to make this all work I'll be very grateful...

         

      Thanks,

         

      Michael.

        • 1. Re: I2C in PSoC creator 2.0
          user_1377889

          I do not have a code-example at hand, but from your protocoll I can see  (|AD-W| , |AD+R|) that you might try to modify the sllave's address to indicate a read or write operation. This is handled within the master-software, you just specify the slave's base address where you want to read from or write to.

             

          You'll easily find an example when you right-click un your I2C-module in the schematic or in the component catalog and then click on "Find example Project" which will bring up a dialog where you select your device (PSoC 5). The example given is for an EZI2c-slave, but that will not matter for the master and for the addressing.

             

          Hope that helps

             

          Bob

          • 2. Re: I2C in PSoC creator 2.0
            user_183705841

            Thanks Bob for the reply,

               

            I looked at that example before but I don't see how to address the registers after I address the device. Unlike the EzI2C In my case I use a device with registers... I'ts possible to invent the wheel all over again by writing the codes from scratch but I think that must be an easy way to do that using the I2C component functions which I just don't see/understand them from the datasheet or the EzI2C example...

            • 3. Re: I2C in PSoC creator 2.0
              ki.leung

               It may be better if you can give us the part number or the specification of the slave devices? 

              • 4. Re: I2C in PSoC creator 2.0
                user_183705841

                The slave's datasheet:      http://invensense.com/mems/gyro/documents/PS-MPU-6000A.pdf see pages 36 to 39

                   

                In my case the slave's address is: 0x68

                   

                The slave's register map: invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf

                   

                I need code example for reading/writing one of the data registers.

                   

                Thanks,

                   

                Michael H.

                • 5. Re: I2C in PSoC creator 2.0
                  user_1377889

                  I do not have an example-code right at hand, but it is a two-liner.

                     

                  Have a look at the datasheet of the I2C Master/Multimaster/Slave module, page 19.

                     

                  Use the

                     

                  I2C_MasterReadBuf(SlaveAdr,&DataBuffer,2, I2C_MODE_COMPLETE_XFER);

                     

                  That's all.

                     

                   Bob

                     

                   

                     

                   

                     

                  I2C_MasterWriteBuf(SlaveAdr,&RegisterNumber,1, I2C_MODE_NO_STOP);

                  • 6. Re: I2C in PSoC creator 2.0
                    user_1377889

                    The lines of the above code have gotten mangled, I suppose you can order them correctly again (Write first, then read).

                       

                    Bob

                    • 7. Re: I2C in PSoC creator 2.0
                      user_183705841

                      Thanks Bob for the support,

                         

                      After alot of trying (and failing) the following code works:

                         

                       

                         

                      int32 i;

                         

                      uint8 wrData[1], rdData[2]; // Put in the wrData[0] array the register address

                         

                      volatile uint8 status;

                         

                       

                         

                       

                         

                       

                         

                      I2C_Start();

                         

                      status = I2C_MasterSendStart(MPU6050_ADD, I2C_WRITE_XFER_MODE);

                         

                      if(status == I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */

                         

                      {

                         

                      /* Send array of 1 bytes */

                         

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

                         

                      {

                         

                      status = I2C_MasterWriteByte(wrData[i]);

                         

                      if(status != I2C_MSTR_NO_ERROR) break;

                         

                      }

                         

                      }

                         

                      I2C_MasterSendStop(); /* Send Stop */

                         

                      status = I2C_MasterSendStart(MPU6050_ADD, I2C_READ_XFER_MODE);

                         

                      if(status == I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */

                         

                      {

                         

                      /* Read array of 2 bytes */

                         

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

                         

                      {

                         

                      if(i < 1) rdData[i] = I2C_MasterReadByte(I2C_ACK_DATA);

                         

                      else rdData[i] = I2C_MasterReadByte(I2C_NAK_DATA);

                         

                      }

                         

                      }

                         

                      I2C_MasterSendStop(); /* Send Stop */

                         

                      I2C_Stop();

                      • 8. Re: I2C in PSoC creator 2.0
                        user_1377889

                        Well, looks a bit more than my twoliner... But fine that you've got it and thank you to share your code with us!

                           

                        Bob

                        • 9. Re: I2C in PSoC creator 2.0
                          kmolden

                           Hi guys, I realise this post is very old, but I am hoping you can help me out.

                             

                          I have to read from 16 bit sub address the I2C device. The different registers will be of different lengts, but the one i am attempting should have an array of four bytes. 

                             

                          To give you an example:

                             

                          I will first write to the chip:

                             

                          8bit chip address - 16 sub register - data

                             

                          0x76   -   0x00 0xBF   -  0x00 0xCA 0xDD 0xCF

                             

                          When i read back all i see on the logic analyzer is the first byte ack, as shown in the attachement

                             

                          I only tweaked your code slightly to accomedate for the 16 bit sub address and four bytes instead of 2:

                             

                           

                             

                          uint16 msb = (regAddress >> 8);

                             

                          uint16 lsb = regAddress;

                             

                          int32 i;

                             

                          volatile uint8 status;

                             

                           

                             

                          status = DSP_I2CMasterSendStart(slavechip, DSP_I2C_WRITE_XFER_MODE);

                             

                          if(status == DSP_I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */

                             

                          {

                             

                          /* Send array of 1 bytes */

                             

                          for(i=0; i<1; i++){

                             

                          status = DSP_I2CMasterWriteByte(msb);

                             

                          if(status != DSP_I2C_MSTR_NO_ERROR) break;

                             

                           

                             

                          status = DSP_I2CMasterWriteByte(lsb);

                             

                          if(status != DSP_I2C_MSTR_NO_ERROR) break;

                             

                          }

                             

                          }

                             

                          DSP_I2CMasterSendStop(); /* Send Stop */

                             

                           

                             

                          status = DSP_I2CMasterSendStart(slavechip, DSP_I2C_READ_XFER_MODE);

                             

                          if(status == DSP_I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */

                             

                          {

                             

                          /* Read array of 2 bytes */

                             

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

                             

                          {

                             

                          if(i < 3)rdData[i] = DSP_I2CMasterReadByte(DSP_I2C_ACK_DATA);

                             

                          else rdData[i] = DSP_I2CMasterReadByte(DSP_I2C_NAK_DATA);

                             

                                  }

                             

                          }

                             

                          DSP_I2CMasterSendStop(); /* Send Stop */

                             

                           

                             

                           

                             

                          Any help would be much appreciated.

                             

                          -Kat

                          • 10. Re: I2C in PSoC creator 2.0
                            kmolden

                            Btw, I have confirmed that the first byte read back is correct and not just always 0x00 

                            • 11. Re: I2C in PSoC creator 2.0
                              user_78878863

                              Please, don't hijack old threads with new questions. This will hide your question, and you will get less answers. Just open a new thread.

                                 

                              Thanks,

                                 

                              hli

                              • 12. Re: I2C in PSoC creator 2.0
                                user_78878863

                                What is the question you are having? What do you expect to happen, what what happens instead?

                                   

                                The LA screenshot shows you are trying to read register 0x008f, but your text said 0x00bf. And the LA also shows that three bytes are returned.

                                   

                                Maybe you can tell what you chip you are talking to? Typically, when reading a register, one doesn't send a stop bit after sending the address, but just another start condition. Maybe leaving out the SendStop() helps?

                                • 13. Re: I2C in PSoC creator 2.0
                                  kmolden

                                   What is the question you are having? What do you expect to happen, what what happens instead?

                                     

                                  The LA screenshot shows you are trying to read register 0x008f, but your text said 0x00bf. And the LA also shows that three bytes are returned.

                                     

                                  Maybe you can tell what you chip you are talking to? Typically, when reading a register, one doesn't send a stop bit after sending the address, but just another start condition. Maybe leaving out the SendStop() helps?

                                     
                                          
                                     
                                          
                                     
                                      My apologies, it was my impression Mike was faced with the same problem as myself.   
                                     
                                          
                                     
                                      The text was a typo, i was trying to read from 0x008F. I don't see how you say three bytes are returned. All i see from the logic analyzer screen shot is that i make a write command to chip (0x76), to the volume register (0x008F). I then see that a Read is initiated to the chip (0x77) and the first byte return (0x00), but that I am missing the remaing three bytes (e.g. 0xCA 0xDD 0xCF) and a stop bit.   
                                     
                                          
                                     
                                      If i remove the Send Stop() function as you suggested I only see the write commands and no read command or returns - please see attached screen shot   
                                  • 14. Re: I2C in PSoC creator 2.0
                                    user_1377889

                                    I used SendStop() between writing the address and data(secondary address) via the I2C instead I used a Restart() when reading. When reading is finished the last instruction is a SendStop().

                                       

                                    Bob

                                    1 2 Previous Next