Skip to content

Avoid I2C timing computation when input clock is unchanged #646

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 12, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions cores/arduino/stm32/twi.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ extern "C" {
#ifndef I2C_VALID_TIMING_NBR
#define I2C_VALID_TIMING_NBR 8U
#endif
#define I2C_SPEED_FREQ_STANDARD 0U /* 100 kHz */
#define I2C_SPEED_FREQ_FAST 1U /* 400 kHz */
#define I2C_SPEED_FREQ_FAST_PLUS 2U /* 1 MHz */
#define I2C_ANALOG_FILTER_DELAY_MIN 50U /* ns */
#ifndef I2C_ANALOG_FILTER_DELAY_MAX
#define I2C_ANALOG_FILTER_DELAY_MAX 260U /* ns */
Expand All @@ -82,6 +79,22 @@ extern "C" {
#define I2C_SCLL_MAX 256U
#define SEC2NSEC 1000000000UL

typedef enum {
I2C_SPEED_FREQ_STANDARD, /* 100 kHz */
I2C_SPEED_FREQ_FAST, /* 400 kHz */
I2C_SPEED_FREQ_FAST_PLUS, /* 1 MHz */
I2C_SPEED_FREQ_NUMBER /* Must be the last entry */
} i2c_speed_freq_t;

#ifdef I2C_TIMING
typedef struct {
uint32_t input_clock; /* I2C Input clock */
uint32_t timing; /* I2C timing corresponding to Input clock */
} I2C_timing_t;

static I2C_timing_t I2C_ClockTiming[I2C_SPEED_FREQ_NUMBER] = {0};
#endif

typedef struct {
uint32_t freq; /* Frequency in Hz */
uint32_t freq_min; /* Minimum frequency in Hz */
Expand Down Expand Up @@ -354,6 +367,16 @@ static uint32_t i2c_computeTiming(uint32_t clkSrcFreq, uint32_t i2c_speed)
uint8_t presc, scldel, sdadel;
uint32_t tafdel_min, tafdel_max;

if (i2c_speed > I2C_SPEED_FREQ_NUMBER) {
return ret;
}
/* Don't compute timing if already available value for the requested speed with the same I2C input frequency */
if ((I2C_ClockTiming[i2c_speed].input_clock == clkSrcFreq) && (I2C_ClockTiming[i2c_speed].timing != 0U)) {
return I2C_ClockTiming[i2c_speed].timing;
}

I2C_ClockTiming[i2c_speed].input_clock = clkSrcFreq; // Save the I2C input clock for which we will save timing

ti2cclk = (SEC2NSEC + (clkSrcFreq / 2U)) / clkSrcFreq;
ti2cspeed = (SEC2NSEC + (I2C_Charac[i2c_speed].freq / 2U)) / I2C_Charac[i2c_speed].freq;

Expand Down Expand Up @@ -437,6 +460,8 @@ static uint32_t i2c_computeTiming(uint32_t clkSrcFreq, uint32_t i2c_speed)
((sclh & 0xFFU) << 8) | \
((scll & 0xFFU) << 0);
prev_presc = presc;
/* Save I2C Timing found for further reuse (and avoid to compute again) */
I2C_ClockTiming[i2c_speed].timing = ret;
}
}
}
Expand Down Expand Up @@ -736,7 +761,6 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address,
Master restarts communication */
} while (((HAL_I2C_GetError(&(obj->handle)) & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)
&& (delta < I2C_TIMEOUT_TICK));

return ret;
}

Expand Down