OpenCores
Issue List
Clock synchronization for multi-master system #6
Closed ocghost opened this issue over 15 years ago
ocghost commented over 15 years ago
  1. The open-core I2C documentation suggests that clock synchronization is performed as defined in the NXP I2C specifcation to accomodate a multi-master system. However, the open-core master does not start counting off its LOW period once a HIGH to LOW transition on the SCL line occurs (e.g. from another master) and does not hold the SCL line low for this duration. This means in a multi-master system the open-core I2C master will never extend the SCL LOW period on the bus to the programmed clock frequency. This may not be an issue in practise but it should be made clear in the documentation.

  2. The "slave_wait" signal in "i2c_master_bit_ctrl.v" causes "cnt" to hold its value until "slave_wait" is no longer true. In a muti-master system, the present logic may result in a VERY SHORT HIGH period. For example: another master takes SCL low just prior to the open-core I2C master; this causes the open-core I2C master to enter its wait state with a low value of "cnt" (e.g. 1). When SCL is HIGH again, the open-core I2C master will resume counting from where it left off and subsequently take SCL low after 1 clock cycle resulting in a SCL HIGH period that clearly violates the I2C specification. To circumvent this problem, a solution would be to set "cnt" to "clk_cnt" when "slave_wait" is true. This will cause the open-core I2C master to subsequntly generate a whole HIGH period when SCL is HIGH again.

rherveille commented over 15 years ago

I understand now what you're saying. Basically #1 and #2 describe the same issue.

The opencores i2c master uses a signal called slave-wait. This signal holds the clock-count value when the opencores i2c master wants to drive SCL high, but another i2c device drives it low. This would typically be a slave inserting a wait state, but it could be another master. Just thinking about it (no checks or simulations done) I can see that #2 would be true. A slave wait is only true when the opencores i2c master currently drives SCL low and then wants to drive it high, while another device (slave/master) holds it low. If the opencores i2c master already drives SCL high and then another device (only master) drives it low, slave wait should not be triggered. Instead the opencores i2c master should start counting its low period. The solution you propose doesn't fix the problem; it causes the i2c bit controller to get out of sync. Let me think about this for a while. I described the solution, now I need to code it :)

ocghost commented over 15 years ago

Need to differentiate between a slave wait condition (i.e. clock stretching due to slave keeping SCL low) and clock synchronisation due to another master taking SCL low. A slave wait condition should be set on rising edge of scl_oen and SCL=0. Slave wait condition is cleared when SCL = scl_oen = 1. Clock sync condition is detected when there is a falling edge of SCL and scl_oen = 1. Hope this helps.

rherveille was assigned about 15 years ago
rherveille closed this about 15 years ago

Assignee
rherveille
Labels
Bug