3 Replies Latest reply on Jan 17, 2020 1:31 PM by WaPi_297581



      The datasheet states that a noise-triggered start condition could cause the bus to be in a "busy" state forever.  What's the best way to detect this state and get back on-track?

        • 1. Re: SCB_I2CMasterWriteBuf



          Can the following topic be a hint?

          Regarding PSoC4 I2C reset for I2C slave hang up(SDA is low)



          • 2. Re: SCB_I2CMasterWriteBuf

            Hi WaPi_297581,


            If you are the only master in the bus and you get the SCB_I2C_MSTR_BUS_BUSY flag, this definitely means that it is an error. You can straight away reset the SCB block by calling the SCB_Stop() and SCB_Start() functions.


            But in a multi- master system, this can not be differentiated. So, if you get a SCB_I2C_MSTR_BUS_BUSY flag it could mean an on-going transaction or it could be due to the ESD event triggered start condition. In that case, you can implement a counter to see how many times your read/ write function returns SCB_I2C_MSTR_BUS_BUSY. If certain counter value is crossed, you can reset the block and try again. Or you can implement a timeout (max time taken to complete a transaction) and reset the block by calling SCB_Stop() and SCB_Start() functions.


            In general, it is highly recommended that the ESD events should not strike your device through the I2C lines.


            Hope this helps.




            • 3. Re: SCB_I2CMasterWriteBuf

              Just had another thought....


              Assuming a single bus master and that a slave is holding SDA low waiting for a clock, rather than the messy low-level-hardware firmware wiggling of SCL, what do you think about creating a special "SCB_I2CMasterWriteBuf" routine by copying the code from SBC_I2C_MASTER.c after the bus-busy check?  Then perform the following steps:


              1. SCB_I2CMasterWriteBuf detects bus busy

              2. Call the "special" created routine using an unused address (ideally 0xFF) to wiggle just the clock

              3. Wait for completion using this code


                  for (y=0; y<WR_LIMIT; y++) {                                               // then wait for completed transfer

                      i2c_status = I2C_I2CMasterStatus();

                      if (0u != (i2c_status & I2C_I2C_MSTAT_WR_CMPLT))   // are we done?




                  which will complete with I2C_I2C_MSTAT_ERR_XFER flag set since there is no slave to ACK


              4. Repeat step 3 x number of times for 8x clock pulses

              5. Hopefully device releases SDA and bus is back to the idle state