@@ -62,9 +62,6 @@ extern "C" {
6262#ifndef I2C_VALID_TIMING_NBR
6363#define I2C_VALID_TIMING_NBR 8U
6464#endif
65- #define I2C_SPEED_FREQ_STANDARD 0U /* 100 kHz */
66- #define I2C_SPEED_FREQ_FAST 1U /* 400 kHz */
67- #define I2C_SPEED_FREQ_FAST_PLUS 2U /* 1 MHz */
6865#define I2C_ANALOG_FILTER_DELAY_MIN 50U /* ns */
6966#ifndef I2C_ANALOG_FILTER_DELAY_MAX
7067#define I2C_ANALOG_FILTER_DELAY_MAX 260U /* ns */
@@ -82,6 +79,20 @@ extern "C" {
8279#define I2C_SCLL_MAX 256U
8380#define SEC2NSEC 1000000000UL
8481
82+ typedef enum {
83+ I2C_SPEED_FREQ_STANDARD , /* 100 kHz */
84+ I2C_SPEED_FREQ_FAST , /* 400 kHz */
85+ I2C_SPEED_FREQ_FAST_PLUS , /* 1 MHz */
86+ I2C_SPEED_FREQ_NUMBER /* Must be the last entry */
87+ } I2C_speed_freq_t ;
88+
89+ typedef struct {
90+ uint32_t input_clock ; /* I2C Input clock */
91+ uint32_t timing ; /* I2C timing corresponding to Input clock */
92+ } I2C_timing_t ;
93+
94+ static I2C_timing_t I2C_ClockTiming [I2C_SPEED_FREQ_NUMBER ] = {0 };
95+
8596typedef struct {
8697 uint32_t freq ; /* Frequency in Hz */
8798 uint32_t freq_min ; /* Minimum frequency in Hz */
@@ -354,6 +365,17 @@ static uint32_t i2c_computeTiming(uint32_t clkSrcFreq, uint32_t i2c_speed)
354365 uint8_t presc , scldel , sdadel ;
355366 uint32_t tafdel_min , tafdel_max ;
356367
368+ if (i2c_speed > I2C_SPEED_FREQ_NUMBER ) {
369+ return ret ;
370+ }
371+ /* Don't compute timing if already available value for the requested speed with the same I2C input frequency */
372+ if ((I2C_ClockTiming [i2c_speed ].input_clock == clkSrcFreq ) && (I2C_ClockTiming [i2c_speed ].timing != 0U )) {
373+ return I2C_ClockTiming [i2c_speed ].timing ;
374+ }
375+
376+ /* Save the I2C input clock for which the timing will be saved */
377+ I2C_ClockTiming [i2c_speed ].input_clock = clkSrcFreq ;
378+
357379 ti2cclk = (SEC2NSEC + (clkSrcFreq / 2U )) / clkSrcFreq ;
358380 ti2cspeed = (SEC2NSEC + (I2C_Charac [i2c_speed ].freq / 2U )) / I2C_Charac [i2c_speed ].freq ;
359381
@@ -437,6 +459,8 @@ static uint32_t i2c_computeTiming(uint32_t clkSrcFreq, uint32_t i2c_speed)
437459 ((sclh & 0xFFU ) << 8 ) | \
438460 ((scll & 0xFFU ) << 0 );
439461 prev_presc = presc ;
462+ /* Save I2C Timing found for further reuse (and avoid to compute again) */
463+ I2C_ClockTiming [i2c_speed ].timing = ret ;
440464 }
441465 }
442466 }
@@ -736,7 +760,6 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address,
736760 Master restarts communication */
737761 } while (((HAL_I2C_GetError (& (obj -> handle )) & HAL_I2C_ERROR_AF ) == HAL_I2C_ERROR_AF )
738762 && (delta < I2C_TIMEOUT_TICK ));
739-
740763 return ret ;
741764}
742765
0 commit comments