OpenCores

I2C Multiple Bus Controller

Issue List
Change SCL Duty cycle to near 50% #4
Closed gallioleo opened this issue about 7 years ago
gallioleo commented about 7 years ago

Hello Sergey,

first of all, thanks for providing the code!!

At the moment i try to simulate your code. I use following parameters:

  • Tclk= 32ns
  • g_f_clk = 31250
  • g_f_scl_0 = 400

When i now measure the times inside my simulator, i recieve following times:

  • SCL,low = 1792ns
  • SCL,high = 1024ns
  • SCL,Tclk = 2816ns => 355.12kHz
  • SCL,Duty = 36%

In my opinion would be better to achieve an SCL, duty cycle in normal operation (without clock strecthing) near 50%. Also would it be very nice to get an clock frequency, which meets better the 400kHz setting.

What do you think?

Thanks for your support.

Best Regards, Andreas

gallioleo commented about 7 years ago

Type your text here

sshuv2 commented about 7 years ago

Hi Andreas,

thank you for your attention to the IICMB core!

The problem is, if you try to achieve 50% duty cycle on SCL you probably begin to violate the IIC specification. For example, in fast mode SCL have to remain high for at least 0.6 us and stay low for at least 1.3 us. Minimum period of SCL in fast mode is 1/(400 kHz) = 2.5 us. Therefore, if you make SCL duty cycle 50%, you would get 1.25 us low period, which is not compatible with IIC specification. So, in case of IIC bus (especially in fast mode) it is much convenient to have uneven duty cycle (unless you keep timing within the specification's constraints).

Another problem you have pointed out is the resulting frequency. It is very difficult to achieve exact frequency on IIC bus. Only low values are actively driven, while high values are pulled up, and therefore low-to-high transitions are quite slow and volatile. The rise time of both SCL and SDA depends on physical properties of particular IIC bus which sometimes are quite difficult to predict. To get rid of the metastability and signal bouncing which may occur at converting continuous slow rising signals to discrete values of '0' and '1' IICMB uses digital filters. They introduce a delay on receiving signals, so you notice signal value change a little bit later than it actually happen and this fact results in SCL frequency is always less then desired. Imagine, that you have stopped driving SCL low and it started to be slowly pulled high. You monitor the value of SCL after the signal have passed through the digital filter and you detect that SCL become '1' some amount of time later than it is actually happened. After that you can start counting SCL minimum high period (0.6 us in fast mode). After you have waited for 0.6 us you drive SCL low. Resulting high time will be longer than 0.6 us due to the filter delay and this will stretch the period of SCL. Thus, to ensure minimum low and ligh periods of SCL we have to sacrifice its exact frequency.

To get as much as possible to the desired value of SCL period, you could try to reduce the filter delay. There are two ways to make it. First, it's recommended to use highest possible system frequency (I mean, 'g_f_clk', the frequency of 'clk' input). And second, you can manually change the filter delay in the file 'conditioner.vhd'. There you can tune the value of the constant 'c_cycles'. Don't use too smal values, otherwise you'll get too sensitive and useless filter. For example, the value of 3 is too low :-)

Hope I've answered your questions.

Best regards, Sergey

sshuv2 closed this about 7 years ago
gallioleo commented over 6 years ago

Hello Sergey, thanks for your answers. You're definitly right with the rise time and the resulting meta stabilities.

Best regards, Andreas


Assignee
No one
Labels
Request