Skip to content

Commit caa48d2

Browse files
ABOSTMfpistm
authored andcommitted
Avoid I2C timing computation when input clock is unchanged (#646)
1 parent bcf1463 commit caa48d2

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

cores/arduino/stm32/twi.c

+27-4
Original file line numberDiff line numberDiff line change
@@ -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+
8596
typedef 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

Comments
 (0)