cancel
Showing results for 
Search instead for 
Did you mean: 

How can I maually calculate the values of SCLL and SCLH for the I2C modules?

Ade G.2
Associate II

 I'm using a custom STM32L452RE with the processor clocking at 80Mhz.

4 REPLIES 4
dbgarasiya
Senior II

please clarify your requirement

I'm writing a driver for the I2C modules on a custom STM32L452RE. The driver configure function needs to be able to take a desired operation speed and calculate the values for the timing register (I2C_TIMINGR) accordingly. Thanks in advance for your help.

SCLL and SCLH in I2C_TIMINGR register basically determine tLOW and tHIGH from the I2C specification, i.e. the baudrate (some other, quite related, START and STOP timing parameters are also determined by these two registers, it's documented in the description of the I2C_TIMINGR register in the I2C chapter in Reference Manual (RM)).

Formulae to calculate these fields are given in the description of the I2C_TIMINGR register, and in the I2C timings subchapter, in the I2C chapter in RM. Basically, tHIGH/tLOW is given by the period of I2C clock (see RCC chapter for I2C clock selection), multiplied by PRESC+1 from I2C_TIMINGR, multiplied by SCLH+1/SCLL+1, and that should be more than the minimum duration for tHIGH/tLOW for the required I2C data rate, as defined by the I2C specification (the table from specification can be found also in the I2C timing subchapter).

See also the I2C_TIMINGR register configuration examples subchapter.

JW

​Thank you for your help, it certainly guided me along the right path, the process I came up with as a result (in semi pseudo code) is as follows:

processorFrequency and desiredFrequency are provided, prescaler starts at 0, ticksPerI2cClockValid starts at FALSE.

while (ticksPerI2cClockValid == FALSE)

{

    timePerProcessorTickNs = ((1/(processorFrequency / (prescaler + 1)) * 1000000000)

    timePerDesiredFrequencyTickNs = ((1/desiredFrequency) * 1000000000)

    ticksPerI2cClock = timePerDesiredFrequencyTickNs / timePerProcessorTickNs

    if (ticksPerI2cClock < THRESHOLD)

    {

        ticksPerI2cClockValid = TRUE

    }

}

The value of ticksPerI2cClock is then split between SCLH, SCLL, SCLDEL and SDADEL in the required proportions.