12 Replies Latest reply on Dec 22, 2015 9:45 AM by iamfantom

    PSoC 4 BLE - Si1146 sensor I2C interface

    iamfantom

      Hi, I'm trying to interface my PSoC 4 BLE pioneer kit with Silicon Labs Si1146 sensor using I2C communication protocol.

         

      I was wondering if the following sequence of functions would be sufficient.

         

      I2CMaster_Start();

         

      I2CMaster_I2CMasterReadBuf(I2CSlaveAddress, (uint8 *) I2CReadBuffer, sizeof(I2CReadBuffer), I2C_I2C_MODE_COMPLETE_XFER);

         

      I2CMaster_Stop();

         

      Thanks in advance,

         

      Ganesh

        • 1. Re: PSoC 4 BLE - Si1146 sensor I2C interface
          user_14586677

          On Creator start page, "Find Example Project" link, there are

             

          example I2C projects you can look at.

             

           

             

          Regards, Dana.

          • 2. Re: PSoC 4 BLE - Si1146 sensor I2C interface
            iamfantom

            Hi Dana,

               

            How do I select the specific register in the slave whose data I want to access? For example if I desire to access the register whose address is 0x20 in my Si1146 sensor (whose slave address is 0x60), which API should I use?

               

            Ganesh

            • 3. Re: PSoC 4 BLE - Si1146 sensor I2C interface
              user_14586677

              Look at your Si1146 datasheet, pages 22, shows you the sequence you have

                 

              to do to interrogate the part.

                 

               

                 

              Regards, Dana.

              • 4. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                iamfantom

                Hi Dana,

                   

                 

                   

                I am not able to fully understand the functions SCB_I2CMasterWriteBuf() and SCB_I2CMasterReadBuf(). Can you help me out by explaining the functions and most importantly the arguments of these functions?

                   

                Thanks,

                   

                Ganesh

                • 5. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                  user_14586677

                  Basically what you are doing here is instead oif writing/reading byte per start - address - R/W - end s

                     

                  equence, an automatic transfer of a whole buffer (array) of data is done with one command. Its an interrupt

                     

                  driven mode. Imagine a display, for example, like a 2 x 16, where you want to update the entire row. Then you

                     

                  would like to transfer the complete row to the display controller memory, generally fast and efficient. So you would

                     

                  use the buf APIs to implement.

                     

                   

                     

                  The mode selection depends on the slave device, how it handles bulk transfers.

                     

                   

                     

                   

                     

                   

                     

                  The API parameters self explanatory, slave address, buffer pointer, # bytes to transfer....

                     

                   

                     

                  Youtube has several videos on I2C that may be of use. Or the NXP site (Phillips in the past)

                     

                  who originated I2C.

                     

                   

                     

                  Regards, Dana.

                  • 6. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                    user_1377889

                    use

                       

                    SCB_I2CMasterWriteBuf() sending the register you want to read with SCB_I2C_MODE_NO_STOP
                    SCB_I2CMasterReadBuf() reading as many bytes as you need with SCB_I2C_MODE_REPEAT_START
                    Keep in mind that interrupts must be enabled.

                    Bob

                     

                    • 7. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                      iamfantom

                      The first SCB_I2CMasterWriteBuf() is to basically point to the register that I want to access and the subsequent function that I write defines whether I want to read or write from the register specified, depending on whether the function is a SCB_I2CMasterWriteBuf or a SCB_I2CMasterReadBuf().

                         

                       

                         

                      Is my understanding correct?

                         

                       

                         

                      Does that mean that irrespective of whether I want to read or write from a register in the I2C slave, my first command should always be a SCB_I2CMasterWriteBuf() function with the parameters specifying the slave address and the corresponding register that I would like to access?

                         

                       

                         

                      Thanks in advance,

                         

                      Ganesh

                      • 8. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                        user_1377889

                        Ganesh,

                           

                        yes, this is my usual way. Gives the slave a little bit of time to arrange its buffers for the Master to read from. I was always successful with this programming structure.

                           

                        Do not forget to check the returned value for errors at least in the testing phase. Result should be always CYRET_SUCCESS. When not analyze the state for the issue (mostly bad hw-connection or wrong slave address)

                           

                         

                           

                        Bob

                        • 9. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                          iamfantom

                          Hi Bob,

                             

                          If I do not want to read the registers sequentially and instead want to read from different registers (for example, the registers 0x17, 0x25 and 0X03 have to be read in that particular order), will it be sufficient if I use a uint32 SCB_I2CMasterSendRestart(uint32 slaveAddress, uint32 bitRnW) every time I finish reading from a particular register?

                          • 10. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                            user_1377889

                            There are two sets of APIs which you may not mix at all. The High-level APIs MasterReadBuf() and MasterWriteBuf() and the low-level APIs SendStart(), SendStop() and all the others.

                               

                            When using the basic APIs the last read is stopped with an NAK instead of ACK. This methods can be easier to use than the (more complicated) APIs using arrays.

                               

                             

                               

                            Bob

                            • 11. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                              iamfantom

                              Hi Bob,

                                 

                              I followed the sequence that you suggested and was able to read from the I2C registers in the Si1146 sensor.

                                 

                              Thanks a lot.

                                 

                               

                                 

                              Ganesh

                              • 12. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                                igor.kuksin

                                Hi Ganesh, 

                                   

                                Could you please share you peace of code that you implement to achieve the data from you sensor. I'm trying to decide the same task.

                                   

                                Thankyou, 

                                   

                                Best, Igor.

                                • 13. Re: PSoC 4 BLE - Si1146 sensor I2C interface
                                  iamfantom

                                  Hi Igor,

                                     

                                  My apologies for the late reply.

                                     

                                  Here is the code that I used.

                                     

                                   

                                     

                                  #include <project.h>

                                     

                                  uint32 return_value,return_value_1,return_value_2;

                                     

                                  uint8 read_buffer[0x02]={0x18,0xA1};

                                     

                                  uint8 read_buf[12];

                                     

                                  uint8 read_buffer_1[0x02]={0x17,0x37};

                                     

                                  uint8 read_buffer_2[0x02]={0x18,0x81};

                                     

                                  uint8 read_buffer_3[0x01]={0x2E};

                                     

                                   

                                     

                                  uint8 result_buffer[0x01]={0x22};

                                     

                                   

                                     

                                  int main()

                                     

                                  {

                                     

                                     

                                     

                                      CyGlobalIntEnable; /* Enable global interrupts. */

                                     

                                   

                                     

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

                                     

                                      I2C_Start();

                                     

                                      I2C_I2CMasterSendStart(0x60,I2C_I2C_WRITE_XFER_MODE);

                                     

                                      I2C_I2CMasterWriteByte(0x07);

                                     

                                      I2C_I2CMasterWriteByte(0x17);

                                     

                                      I2C_I2CMasterSendStop();

                                     

                                     

                                     

                                    

                                     

                                      I2C_I2CMasterSendStart(0x60,I2C_I2C_WRITE_XFER_MODE);

                                     

                                      I2C_I2CMasterWriteByte(0x18);

                                     

                                      I2C_I2CMasterWriteByte(0x01);

                                     

                                      I2C_I2CMasterSendStop();

                                     

                                     

                                     

                                     

                                     

                                      I2C_I2CMasterSendStart(0x60,I2C_I2C_WRITE_XFER_MODE);

                                     

                                      I2C_I2CMasterWriteByte(0x18);

                                     

                                      I2C_I2CMasterSendRestart(0x60,I2C_I2C_READ_XFER_MODE);

                                     

                                      return_value=I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA);

                                     

                                      I2C_I2CMasterSendStop();

                                     

                                    

                                     

                                       I2C_I2CMasterSendStart(0x60,I2C_I2C_WRITE_XFER_MODE);

                                     

                                      I2C_I2CMasterWriteByte(0x18);

                                     

                                      I2C_I2CMasterWriteByte(0x05);

                                     

                                      I2C_I2CMasterSendStop();

                                     

                                     

                                     

                                      I2C_I2CMasterSendStart(0x60,I2C_I2C_WRITE_XFER_MODE);

                                     

                                      I2C_I2CMasterWriteByte(0x00);

                                     

                                      I2C_I2CMasterSendRestart(0x60,I2C_I2C_READ_XFER_MODE);

                                     

                                      return_value=I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA);

                                     

                                      I2C_I2CMasterSendStop();

                                     

                                    

                                     

                                      I2C_I2CMasterSendStart(0x60,I2C_I2C_WRITE_XFER_MODE);

                                     

                                      I2C_I2CMasterWriteByte(0x18);

                                     

                                      I2C_I2CMasterWriteByte(0xA1);

                                     

                                      I2C_I2CMasterSendStop();

                                     

                                     

                                     

                                       I2C_I2CMasterSendStart(0x60,I2C_I2C_WRITE_XFER_MODE);

                                     

                                      I2C_I2CMasterWriteByte(0xA1);

                                     

                                      I2C_I2CMasterWriteByte(0xF7);

                                     

                                      I2C_I2CMasterSendStop();