Skip to content

Commit 1d5d3b0

Browse files
authored
Merge pull request #14808 from affrinpinhero-2356/i2cTimingPerformanceSolved
driver/i2c: STM32: I2C performance issue solved.
2 parents 97b9754 + b559cec commit 1d5d3b0

File tree

35 files changed

+328
-631
lines changed

35 files changed

+328
-631
lines changed

targets/TARGET_STM/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,31 @@ You can change this in you local mbed_app.json:
408408
}
409409
```
410410

411+
#### I2C TIming calculation algorothm
412+
413+
I2C drivers version 2 use I2C timing register.
414+
415+
Enable I2C timing algorithm by setting the value of `i2c_timing_value_algo`
416+
target config to `true`
417+
418+
```
419+
"i2c_timing_value_algo": {
420+
"help": "If value was set to true I2C timing algorithm is
421+
enabled. Enabling may leads to performance issue. Keeping this
422+
false and changing system clock will trigger assert.",
423+
"value": false
424+
}
425+
```
426+
Default configuration disables I2C timing algorithm. If user need to use
427+
different system clock speed other than default system clock configuration.
428+
Then I2C timing calculation algorithm need to enable. To enable
429+
430+
```
431+
"i2c_timing_value_algo": {
432+
"value": true
433+
}
434+
```
435+
411436

412437
### Sleep feature
413438

targets/TARGET_STM/TARGET_STM32F0/i2c_device.c

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ uint32_t i2c_get_pclk(I2CName i2c)
4141
pclk = HSI_VALUE;
4242
break;
4343
}
44-
}
44+
}
4545
#if defined I2C2_BASE
4646
else if (i2c == I2C_2) {
4747
pclk = HAL_RCC_GetSysClockFreq();
@@ -53,50 +53,4 @@ uint32_t i2c_get_pclk(I2CName i2c)
5353
}
5454
return pclk;
5555
}
56-
57-
/**
58-
* @brief Provide the suitable timing depending on requested frequency
59-
* @param hz Required I2C clock in Hz.
60-
* @retval I2C timing or 0 in case of error.
61-
*/
62-
uint32_t i2c_get_timing(I2CName i2c, int hz)
63-
{
64-
uint32_t tim;
65-
uint32_t pclk;
66-
67-
pclk = i2c_get_pclk(i2c);
68-
69-
if (pclk == I2C_PCLK_DEF) {
70-
switch (hz) {
71-
case 100000:
72-
tim = TIMING_VAL_DEFAULT_CLK_100KHZ;
73-
break;
74-
case 400000:
75-
tim = TIMING_VAL_DEFAULT_CLK_400KHZ;
76-
break;
77-
case 1000000:
78-
tim = TIMING_VAL_DEFAULT_CLK_1MHZ;
79-
break;
80-
default:
81-
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
82-
break;
83-
}
84-
}
85-
86-
else {
87-
/* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered.
88-
User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target.
89-
Enabling this may impact performance*/
90-
MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO);
91-
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
92-
tim = i2c_compute_timing(pclk, hz);
93-
#endif
94-
}
95-
return tim;
96-
}
97-
98-
/**
99-
* @}
100-
*/
101-
10256
#endif // DEVICE_I2C

targets/TARGET_STM/TARGET_STM32F0/i2c_device.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,18 @@ extern "C" {
3737
/* Define IP version */
3838
#define I2C_IP_VERSION_V2
3939

40-
#define TIMING_VAL_DEFAULT_CLK_100KHZ 0x10805E89 // Standard mode with Rise Time = 400ns and Fall Time = 100ns
41-
#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x00901850 // Fast mode with Rise Time = 250ns and Fall Time = 100ns
42-
#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x00700818 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
43-
#define I2C_PCLK_DEF 48000000 // 48 MHz
40+
#define TIMING_VAL_48M_CLK_100KHZ 0x10805E89 // Standard mode with Rise Time = 400ns and Fall Time = 100ns
41+
#define TIMING_VAL_48M_CLK_400KHZ 0x00901850 // Fast mode with Rise Time = 250ns and Fall Time = 100ns
42+
#define TIMING_VAL_48M_CLK_1MHZ 0x00700818 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
43+
#define I2C_PCLK_48M 48000000 // 48 MHz
4444

4545
#define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI)
4646

4747
/* Family specifc settings for clock source */
4848
#define I2CAPI_I2C1_CLKSRC RCC_I2C1CLKSOURCE_SYSCLK
4949

5050
uint32_t i2c_get_pclk(I2CName i2c);
51-
uint32_t i2c_get_timing(I2CName i2c, int hz);
51+
uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz);
5252

5353
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
5454
uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq);

targets/TARGET_STM/TARGET_STM32F0/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct i2c_s {
9494
uint32_t XferOperation;
9595
volatile uint8_t event;
9696
volatile int pending_start;
97+
int current_hz;
9798
#if DEVICE_I2CSLAVE
9899
uint8_t slave;
99100
volatile uint8_t pending_slave_tx_master_rx;

targets/TARGET_STM/TARGET_STM32F3/i2c_device.c

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -76,65 +76,4 @@ uint32_t i2c_get_pclk(I2CName i2c)
7676
}
7777
return pclk;
7878
}
79-
80-
/**
81-
* @brief Provide the suitable timing depending on requested frequency
82-
* @param hz Required I2C clock in Hz.
83-
* @retval I2C timing or 0 in case of error.
84-
*/
85-
uint32_t i2c_get_timing(I2CName i2c, int hz)
86-
{
87-
uint32_t tim;
88-
uint32_t pclk;
89-
90-
pclk = i2c_get_pclk(i2c);
91-
92-
if (pclk == I2C_PCLK_HSI) {
93-
switch (hz) {
94-
case 100000:
95-
tim = TIMING_VAL_64M_CLK_100KHZ;
96-
break;
97-
case 400000:
98-
tim = TIMING_VAL_64M_CLK_400KHZ;
99-
break;
100-
case 1000000:
101-
tim = TIMING_VAL_64M_CLK_1MHZ;
102-
break;
103-
default:
104-
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
105-
break;
106-
}
107-
} else if (pclk == I2C_PCLK_HSE) {
108-
switch (hz) {
109-
case 100000:
110-
tim = TIMING_VAL_72M_CLK_100KHZ;
111-
break;
112-
case 400000:
113-
tim = TIMING_VAL_72M_CLK_400KHZ;
114-
break;
115-
case 1000000:
116-
tim = TIMING_VAL_72M_CLK_1MHZ;
117-
break;
118-
default:
119-
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
120-
break;
121-
}
122-
}
123-
124-
else {
125-
/* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered.
126-
User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target.
127-
Enabling this may impact performance*/
128-
MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO);
129-
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
130-
tim = i2c_compute_timing(pclk, hz);
131-
#endif
132-
}
133-
return tim;
134-
}
135-
136-
/**
137-
* @}
138-
*/
139-
14079
#endif // DEVICE_I2C

targets/TARGET_STM/TARGET_STM32F3/i2c_device.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ extern "C" {
4343
#define TIMING_VAL_64M_CLK_100KHZ 0x10B17DB4 // Standard mode with Rise time = 120ns, Fall time = 120ns
4444
#define TIMING_VAL_64M_CLK_400KHZ 0x00E22163 // Fast Mode with Rise time = 120ns, Fall time = 120ns
4545
#define TIMING_VAL_64M_CLK_1MHZ 0x00A00D1E // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
46-
#define I2C_PCLK_HSI 64000000 // 64 MHz
46+
#define I2C_PCLK_64M 64000000 // 64 MHz
4747

4848
#define TIMING_VAL_72M_CLK_100KHZ 0x10D28DCB // Standard mode with Rise time = 120ns, Fall time = 120ns
4949
#define TIMING_VAL_72M_CLK_400KHZ 0x00F32571 // Fast Mode with Rise time = 120ns, Fall time = 120ns
5050
#define TIMING_VAL_72M_CLK_1MHZ 0x00C00D24 // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
51-
#define I2C_PCLK_HSE 72000000 // 72 MHz
51+
#define I2C_PCLK_72M 72000000 // 72 MHz
5252

5353

5454
#define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI)
@@ -62,7 +62,7 @@ extern "C" {
6262
#define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_SYSCLK
6363

6464
uint32_t i2c_get_pclk(I2CName i2c);
65-
uint32_t i2c_get_timing(I2CName i2c, int hz);
65+
uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz);
6666

6767
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
6868
uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq);

targets/TARGET_STM/TARGET_STM32F3/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct i2c_s {
109109
uint32_t XferOperation;
110110
volatile uint8_t event;
111111
volatile int pending_start;
112+
int current_hz;
112113
#if DEVICE_I2CSLAVE
113114
uint8_t slave;
114115
volatile uint8_t pending_slave_tx_master_rx;

targets/TARGET_STM/TARGET_STM32F7/i2c_device.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -106,45 +106,4 @@ uint32_t i2c_get_pclk(I2CName i2c)
106106
}
107107
return pclk;
108108
}
109-
110-
/**
111-
* @brief Provide the suitable timing depending on requested frequency
112-
* @param hz Required I2C clock in Hz.
113-
* @retval I2C timing or 0 in case of error.
114-
*/
115-
uint32_t i2c_get_timing(I2CName i2c, int hz)
116-
{
117-
uint32_t tim;
118-
uint32_t pclk;
119-
pclk = i2c_get_pclk(i2c);
120-
if (pclk == I2C_PCLK_DEF) {
121-
switch (hz) {
122-
case 100000:
123-
tim = TIMING_VAL_DEFAULT_CLK_100KHZ;
124-
break;
125-
case 400000:
126-
tim = TIMING_VAL_DEFAULT_CLK_400KHZ;
127-
break;
128-
case 1000000:
129-
tim = TIMING_VAL_DEFAULT_CLK_1MHZ;
130-
break;
131-
default:
132-
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
133-
break;
134-
}
135-
} else {
136-
/* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered.
137-
User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target.
138-
Enabling this may impact performance*/
139-
MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO);
140-
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
141-
tim = i2c_compute_timing(pclk, hz);
142-
#endif
143-
}
144-
return tim;
145-
}
146-
147-
/**
148-
* @}
149-
*/
150109
#endif // DEVICE_I2C

targets/TARGET_STM/TARGET_STM32F7/i2c_device.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ extern "C" {
4040
/* Define I2C Device */
4141
#if DEVICE_I2C
4242

43-
#define TIMING_VAL_DEFAULT_CLK_100KHZ 0x10916998 // Standard mode with Rise time = 120ns, Fall time = 120ns
44-
#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x00B11B54 // Fast Mode with Rise time = 120ns, Fall time = 120ns
45-
#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x0090091B // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
46-
#define I2C_PCLK_DEF 54000000 // 54 MHz
43+
#define TIMING_VAL_54M_CLK_100KHZ 0x10916998 // Standard mode with Rise time = 120ns, Fall time = 120ns
44+
#define TIMING_VAL_54M_CLK_400KHZ 0x00B11B54 // Fast Mode with Rise time = 120ns, Fall time = 120ns
45+
#define TIMING_VAL_54M_CLK_1MHZ 0x0090091B // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
46+
#define I2C_PCLK_54M 54000000 // 54 MHz
4747

4848
/* Define IP version */
4949
#define I2C_IP_VERSION_V2
@@ -57,7 +57,7 @@ extern "C" {
5757
#define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_PCLK1
5858

5959
uint32_t i2c_get_pclk(I2CName i2c);
60-
uint32_t i2c_get_timing(I2CName i2c, int hz);
60+
uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz);
6161

6262
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
6363
uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq);

targets/TARGET_STM/TARGET_STM32F7/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ struct i2c_s {
125125
uint32_t XferOperation;
126126
volatile uint8_t event;
127127
volatile int pending_start;
128+
int current_hz;
128129
#if DEVICE_I2CSLAVE
129130
uint8_t slave;
130131
volatile uint8_t pending_slave_tx_master_rx;

targets/TARGET_STM/TARGET_STM32G0/i2c_device.c

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -51,46 +51,4 @@ uint32_t i2c_get_pclk(I2CName i2c)
5151
}
5252
return pclk;
5353
}
54-
55-
/**
56-
* @brief Provide the suitable timing depending on requested frequency
57-
* @param hz Required I2C clock in Hz.
58-
* @retval I2C timing or 0 in case of error.
59-
*/
60-
uint32_t i2c_get_timing(I2CName i2c, int hz)
61-
{
62-
uint32_t tim;
63-
uint32_t pclk;
64-
pclk = i2c_get_pclk(i2c);
65-
if (pclk == I2C_PCLK_DEF) {
66-
switch (hz) {
67-
case 100000:
68-
tim = TIMING_VAL_DEFAULT_CLK_100KHZ;
69-
break;
70-
case 400000:
71-
tim = TIMING_VAL_DEFAULT_CLK_400KHZ;
72-
break;
73-
case 1000000:
74-
tim = TIMING_VAL_DEFAULT_CLK_1MHZ;
75-
break;
76-
default:
77-
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
78-
break;
79-
}
80-
} else {
81-
/* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered.
82-
User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target.
83-
Enabling this may impact performance*/
84-
MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO);
85-
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
86-
tim = i2c_compute_timing(pclk, hz);
87-
#endif
88-
}
89-
return tim;
90-
}
91-
92-
/**
93-
* @}
94-
*/
95-
9654
#endif // DEVICE_I2C

targets/TARGET_STM/TARGET_STM32G0/i2c_device.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ extern "C" {
2626
#if DEVICE_I2C
2727

2828
// Common settings: I2C clock = 64 MHz, Analog filter = ON, Digital filter coefficient = 0
29-
#define TIMING_VAL_DEFAULT_CLK_100KHZ 0xC0311319 // Standard mode with Rise Time = 400ns and Fall Time = 100ns
30-
#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x10B1102E // Fast mode with Rise Time = 250ns and Fall Time = 100ns
31-
#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x00710B1E // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
32-
#define I2C_PCLK_DEF 64000000 // 64 MHz
29+
#define TIMING_VAL_64M_CLK_100KHZ 0xC0311319 // Standard mode with Rise Time = 400ns and Fall Time = 100ns
30+
#define TIMING_VAL_64M_CLK_400KHZ 0x10B1102E // Fast mode with Rise Time = 250ns and Fall Time = 100ns
31+
#define TIMING_VAL_64M_CLK_1MHZ 0x00710B1E // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
32+
#define I2C_PCLK_64M 64000000 // 64 MHz
3333

3434
/* Define IP version */
3535
#define I2C_IP_VERSION_V2
@@ -47,7 +47,7 @@ extern "C" {
4747
#define I2CAPI_I2C2_CLKSRC RCC_I2C2CLKSOURCE_SYSCLK
4848

4949
uint32_t i2c_get_pclk(I2CName i2c);
50-
uint32_t i2c_get_timing(I2CName i2c, int hz);
50+
uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz);
5151

5252
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
5353
uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq);

targets/TARGET_STM/TARGET_STM32G0/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ struct i2c_s {
108108
uint32_t XferOperation;
109109
volatile uint8_t event;
110110
volatile int pending_start;
111+
int current_hz;
111112
#if DEVICE_I2CSLAVE
112113
uint8_t slave;
113114
volatile uint8_t pending_slave_tx_master_rx;

0 commit comments

Comments
 (0)