12 Replies Latest reply on Nov 18, 2013 1:25 PM by helic_263931

    I2C "read" transactions that start with a write

      It's cool that the I2C master component supports buffer-at-a-time reads and writes with a Cypress-written builtin ISR. The only feature missing from the API is a function with a signature like:


      uint8 MasterWriteReadBuf(uint8 slaveAddress, uint8* wrData, uint8 wrCnt, uint8* rdData, uint8 rdCnt, uint8 mode)


      The function would write the bytes from wrData, send a restart, and then read rdCnt bytes into rdData. In other words it would be equivalent to:


      status = MasterWriteBuf(slaveAddress, wrData, wrCnt, mode);
      // possibly error handling based on status
      return MasterReadBuf(slaveAddress, rdData, rdCnt, I2C_MODE_REPEAT_START);


      except that it would be handled by the builtin ISR.




      Almost all of my I2C interactions are this way: I need to write the "register address" within the device that I am interested in reading, and then read the contents of that register. Performing the transition without having  the interrupt handle it is tricky to do without spinning the processor waiting for the initial write transaction to take place at the much-slower-than-bus-clock I2C clock rate. This is a very, very common pattern of use of the I2C bus, almost every I2C device datasheet I know of works this way.

        • 1. Re: I2C "read" transactions that start with a write

          Yes,you've raised a valid point. Perhaps component developers browsing this forum will include this in the next revision.Till then,feel free to add that function to your copy of the component :-)

          • 2. Re: I2C "read" transactions that start with a write

            I think this would be good to have this API included in later revision of creator.

            • 3. Re: I2C "read" transactions that start with a write

              I am not a "content" guy but I've created an internal case to make sure we discuss this enhancement. I cannot predict what will be decided but we will talk about it. We appreciate all these suggestions to make Creator better!


              As an aside, if you are on PSoC Creator 2.0, you will soon be seeing a component pack release from us, which contains updates to some existing and a couple of brand new components. This will install into your existing 2.0 image (really quickly). The idea behind these releases is that they are easier to do (because only the content changes, not the whole tool) and we can crank them out faster... which means more components and faster updates of existing ones. So, now is a good time to be making requests for component features...


              -- Mark.

              • 4. Re: I2C "read" transactions that start with a write

                Anyone knows if this enhancement is planned for the future PSoC Creator?  I still don't see this in PSoC Creator 2.1.

                • 5. Re: I2C "read" transactions that start with a write



                  That’s exactly the problem where I’m also struggling with.


                  I have made a module to control a Si570 XO module. To set the frequency of that module I (among other things) have to read a register, changed it and write it back.


                  The read action should start with a write to select the register and after the write,  reading the contents of that register.


                  I tried everything:  MasterWriteBuf  with NO-STOP mode and MasterReadBuf with REPEAT_START or COMPLETE_XFER mode, but none of them are working.


                  I’m using Creater 3 with the FreeSocMini  development board with a PSoC-5.


                  I hope anybody can bring me the right solution!



                  • 6. Re: I2C "read" transactions that start with a write
                            Hi Roberto48   
                    I2C interface is sometime difficult   
                    It has critical handshakes, and depend on objective device's timing   
                    Please refer this article, 31th Jul 2013   
                    And change 4 CyDelay(1) to CyDelayUs(50~500?)   
                    Might it be meets for you.   
                    • 8. Re: I2C "read" transactions that start with a write

                      I suggest not to use the high-level functions I2C_Readbuff() and I2C_WriteBuff() for the given purpose.


                      When you use I2C_SendStart(), I2C_WriteByte(),I2C_SendRestart(),I2C_ReadByte() sequences together with the appropiate waiting for a status indicating the device did finish the command you'll be probably better off.


                      Depending of using a PSoC1,,3,4,5 the syntax is slightly different.





                      • 9. Re: I2C "read" transactions that start with a write

                        Hi PSoC73 and Bob,




                        Thanks for your suggestions. The I2C is not realy the problem, because I have also on the same SDA and SCL lines an also modified LCD module active, and that module is working fine.


                        But I will try (as Cy called it) the manual method. I did it earlier but now I realise that I was forgotten to wait for the transfer complete status....oops..


                        As soon I succeded, I'll  tell you!



                        • 10. Re: I2C "read" transactions that start with a write
                          If you couldn't get success,   
                          Try to be lower Bus-clock as half of Master clock.   
                          I don't know root cause but   
                          Become working that doesn't got work I2C.   
                          • 11. Re: I2C "read" transactions that start with a write

                            Hi Bob and PSoC73,


                            Problem solved! I used following steps and it's working fine. But that was not the only problem. The main problem was in the slave address.  I put the slave address as a parameter in the I2C_Si570 module and used the same method as used in the I2C_LCD module. But in that module the slave address is shifted one bit to the right, don't know why, and that's no problem if the address is 0x40, but when the address is 0x55 (in the Si570 case) it's losing the LSB!  After I have changed that, all was working OK.


                            Maybe anyone knows the reason why in the I2C_LCD module the I2C_address is shifted for 7-bit mode. See below:


                            #define `$INSTANCE_NAME`_ADDRESS_SHIFT              (0x01u)

                            /* Default I2C address in 7-bit mode */
                            #define `$INSTANCE_NAME`_DEFAULT_I2C_ADDRESS        ((uint8)((uint8)(`$DefaultI2cAddress`u) >> \



                            But anyway thanks for your help, now I can make it  a working the module!


                            Best regards,




                            void I2C_Si570_ReadRegs(void)
                                uint8 ss, i;

                                ss= I2C_Si570_MasterSendStart( I2C_Si570_address, 0 );  // start
                                if( ss!=I2C_Si570_MSTR_NO_ERROR ) return;

                                ss= I2C_Si570_MasterWriteByte( 0x07 );                             // Register 7 (start)
                                if( ss!=I2C_Si570_MSTR_NO_ERROR ) return;

                                ss= I2C_Si570_MasterSendStop();                                       // stop
                                if( ss!=I2C_Si570_MSTR_NO_ERROR ) return;

                                ss= I2C_Si570_MasterSendStart(I2C_Si570_address, 1 );     // read data
                                if( ss!=I2C_Si570_MSTR_NO_ERROR ) return;
                                for (i=0; i<=5; i++)                                                                     // Read data of 6 consec regs
                                       I2C_Si570_tempBuf[i] = I2C_Si570_MasterReadByte( 1 );

                                ss= I2C_Si570_MasterSendStop();                                          // stop
                                if( ss!=I2C_Si570_MSTR_NO_ERROR ) return;

                            • 12. Re: I2C "read" transactions that start with a write

                              The reason for that confusion is that I2C addresses are only 7 bit long. The 8th bit is used to distinguid read and write access. But there is no real convention how to express that. Some manufacturers give you only the address part, so you need to left shift that and add the read / write bit. Others give a read and a write address, which differ only on the last bit (which is set for read access) - then you don't need to shift the address. One needs to look at the data sheet and find out how the addressing works.