OpenCores
Issue List
Presacler or Documentation wrong #24
Open but5693 opened this issue about 16 years ago
but5693 commented about 16 years ago

Using prescale formular ((sysclk/(5 x scl)))-1 with sysclk = 16000 (for 16Mhz) and scl = 100 (for 100kbit target i2c clock) generates 90kbit i2c clock instead of 100kbit.

By the way, the latest documentation v0.9 (in the trunk/doc folder)is dated from 2003, is that the latest? Rev. 0.3 March 6, 2001 Rev. 0.9 July 3, 2003 Might be there a new formular for calculating scl?

Lutz

poluektik commented almost 15 years ago

?ause of this effect is slave_wait signal in i2c_master_bit_ctrl block. Though slave clock stretching is absent, slave_wait is active some periods of system clock.

poluektik commented almost 15 years ago

?ause of this effect is slave_wait signal in i2c_master_bit_ctrl block. Though slave clock stretching is absent, slave_wait is active some periods of system clock.

uecasm commented almost 14 years ago

Did you find a workaround for this? I have a similar but slightly weirder issue: with a 100MHz sysclk, in simulation I get a 90kbit clock just as you did; but with actual implementation I'm only getting a 58kbit clock. The device I'm talking to is an EEPROM rated to 400kbit, so I don't think it's doing any clock stretching.

mrburns42 commented about 12 years ago

I ran this in both the Xilinx simulator and in actual HW. It appears to wait for clock sync on every cycle. For me this adds approximately 27 extra dead clock cycles per I2C clock. If I account for this extra dead time when calculating the prescaler, then the clock rate is pretty good. My system clock is 33MHZ. Below is my C code calculation.

fModSMBUS_Period = (1.0f/nDesiredClkRate) - (27.5f/33000000.0f);
nPrescaler = (u_int32_t)(( 33000000.0f / (5.0f * (1/fModSMBUS_Period)))) - 1;
NULL commented 6 months ago

Hey guys, just connect to slave_wait ground and it works! Below is my change to i2c_master_bit_ctrl.v:

// slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
// slave_wait remains asserted until the slave releases SCL
    always @(posedge clk or negedge nReset)
      if (!nReset) slave_wait <= 1'b0;
//      else         slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL); // Not work!

Now the frequency of SCL can be calculated by: f_scl = f_clk/(5 * (clk_cnt + 1)); If frequency of clk is 100MHz, then set prescaler(clk_cnt) to 49 for 400kHz and 199 for 100kHz. I've simulated the code on Vivado2025.2 and get verified. Not only that, after making a few minor adjustments(change reg data bits: 8 to 16bits), I tested this code on the DAC53401, and it worked.


Assignee
No one
Labels
Bug