Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

PSoC™ 4 Forum Discussions

WaPi_297581
Level 2
Level 2
First like received

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?

0 Likes
1 Solution

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?

            break;

    }

    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

View solution in original post

3 Replies
MotooTanaka
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

Hi,

Can the following topic be a hint?

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

moto

0 Likes

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?

            break;

    }

    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

BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

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.

Regards,

Bragadeesh

Regards,
Bragadeesh
0 Likes