From d8cbd68dc2c683903c167e6f8b2f29d59285b1a2 Mon Sep 17 00:00:00 2001 From: Affrin Pinhero Date: Thu, 1 Jul 2021 12:04:48 +0530 Subject: [PATCH 1/2] driver/i2c: STM32: Solves I2C driver performanc issue. This commit solves issue related to i2c driver performance. With this commit delay in read write when using i2c timing algorithm is solved. Used flag mechanism which will check tim reg value and hz passed. Signed-off-by: Affrin Pinhero --- .../TARGET_STM/TARGET_STM32F0/i2c_device.c | 48 +--- .../TARGET_STM/TARGET_STM32F0/i2c_device.h | 10 +- targets/TARGET_STM/TARGET_STM32F0/objects.h | 1 + .../TARGET_STM/TARGET_STM32F3/i2c_device.c | 61 ----- .../TARGET_STM/TARGET_STM32F3/i2c_device.h | 6 +- targets/TARGET_STM/TARGET_STM32F3/objects.h | 1 + .../TARGET_STM/TARGET_STM32F7/i2c_device.c | 41 --- .../TARGET_STM/TARGET_STM32F7/i2c_device.h | 10 +- targets/TARGET_STM/TARGET_STM32F7/objects.h | 1 + .../TARGET_STM/TARGET_STM32G0/i2c_device.c | 42 --- .../TARGET_STM/TARGET_STM32G0/i2c_device.h | 10 +- targets/TARGET_STM/TARGET_STM32G0/objects.h | 1 + .../TARGET_STM/TARGET_STM32G4/i2c_device.c | 40 --- .../TARGET_STM/TARGET_STM32G4/i2c_device.h | 10 +- targets/TARGET_STM/TARGET_STM32G4/objects.h | 1 + .../TARGET_STM/TARGET_STM32H7/i2c_device.c | 47 ---- .../TARGET_STM/TARGET_STM32H7/i2c_device.h | 10 +- targets/TARGET_STM/TARGET_STM32H7/objects.h | 1 + .../TARGET_STM/TARGET_STM32L0/i2c_device.c | 47 ---- .../TARGET_STM/TARGET_STM32L0/i2c_device.h | 10 +- targets/TARGET_STM/TARGET_STM32L0/objects.h | 1 + .../TARGET_STM/TARGET_STM32L4/i2c_device.c | 77 ------ .../TARGET_STM/TARGET_STM32L4/i2c_device.h | 4 +- targets/TARGET_STM/TARGET_STM32L4/objects.h | 1 + .../TARGET_STM/TARGET_STM32L5/i2c_device.c | 50 ---- .../TARGET_STM/TARGET_STM32L5/i2c_device.h | 10 +- targets/TARGET_STM/TARGET_STM32L5/objects.h | 1 + .../TARGET_STM/TARGET_STM32WB/i2c_device.c | 67 ----- .../TARGET_STM/TARGET_STM32WB/i2c_device.h | 6 +- targets/TARGET_STM/TARGET_STM32WB/objects.h | 1 + .../TARGET_STM/TARGET_STM32WL/i2c_device.c | 50 ---- .../TARGET_STM/TARGET_STM32WL/i2c_device.h | 10 +- targets/TARGET_STM/TARGET_STM32WL/objects.h | 1 + targets/TARGET_STM/i2c_api.c | 257 +++++++++++++++++- 34 files changed, 303 insertions(+), 631 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/i2c_device.c b/targets/TARGET_STM/TARGET_STM32F0/i2c_device.c index bcc29d82dc8..7cb9b2a4b47 100755 --- a/targets/TARGET_STM/TARGET_STM32F0/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32F0/i2c_device.c @@ -41,7 +41,7 @@ uint32_t i2c_get_pclk(I2CName i2c) pclk = HSI_VALUE; break; } - } + } #if defined I2C2_BASE else if (i2c == I2C_2) { pclk = HAL_RCC_GetSysClockFreq(); @@ -53,50 +53,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } - -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - - pclk = i2c_get_pclk(i2c); - - if (pclk == I2C_PCLK_DEF) { - switch (hz) { - case 100000: - tim = TIMING_VAL_DEFAULT_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_DEFAULT_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_DEFAULT_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } - - else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance*/ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} - -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32F0/i2c_device.h b/targets/TARGET_STM/TARGET_STM32F0/i2c_device.h index 8cd4f5857be..07dcf35afd9 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32F0/i2c_device.h @@ -37,10 +37,10 @@ extern "C" { /* Define IP version */ #define I2C_IP_VERSION_V2 -#define TIMING_VAL_DEFAULT_CLK_100KHZ 0x10805E89 // Standard mode with Rise Time = 400ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x00901850 // Fast mode with Rise Time = 250ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x00700818 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_DEF 48000000 // 48 MHz +#define TIMING_VAL_48M_CLK_100KHZ 0x10805E89 // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_48M_CLK_400KHZ 0x00901850 // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_48M_CLK_1MHZ 0x00700818 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_48M 48000000 // 48 MHz #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) @@ -48,7 +48,7 @@ extern "C" { #define I2CAPI_I2C1_CLKSRC RCC_I2C1CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32F0/objects.h b/targets/TARGET_STM/TARGET_STM32F0/objects.h index a8e0fbc8bef..86de2fec38a 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/objects.h @@ -94,6 +94,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32F3/i2c_device.c b/targets/TARGET_STM/TARGET_STM32F3/i2c_device.c index c0e2294f45f..16554a177dc 100755 --- a/targets/TARGET_STM/TARGET_STM32F3/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32F3/i2c_device.c @@ -76,65 +76,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } - -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - - pclk = i2c_get_pclk(i2c); - - if (pclk == I2C_PCLK_HSI) { - switch (hz) { - case 100000: - tim = TIMING_VAL_64M_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_64M_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_64M_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else if (pclk == I2C_PCLK_HSE) { - switch (hz) { - case 100000: - tim = TIMING_VAL_72M_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_72M_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_72M_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } - - else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance*/ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} - -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32F3/i2c_device.h b/targets/TARGET_STM/TARGET_STM32F3/i2c_device.h index 6b39b244d5d..6c8c17db8a8 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32F3/i2c_device.h @@ -43,12 +43,12 @@ extern "C" { #define TIMING_VAL_64M_CLK_100KHZ 0x10B17DB4 // Standard mode with Rise time = 120ns, Fall time = 120ns #define TIMING_VAL_64M_CLK_400KHZ 0x00E22163 // Fast Mode with Rise time = 120ns, Fall time = 120ns #define TIMING_VAL_64M_CLK_1MHZ 0x00A00D1E // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns -#define I2C_PCLK_HSI 64000000 // 64 MHz +#define I2C_PCLK_64M 64000000 // 64 MHz #define TIMING_VAL_72M_CLK_100KHZ 0x10D28DCB // Standard mode with Rise time = 120ns, Fall time = 120ns #define TIMING_VAL_72M_CLK_400KHZ 0x00F32571 // Fast Mode with Rise time = 120ns, Fall time = 120ns #define TIMING_VAL_72M_CLK_1MHZ 0x00C00D24 // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns -#define I2C_PCLK_HSE 72000000 // 72 MHz +#define I2C_PCLK_72M 72000000 // 72 MHz #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" { #define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32F3/objects.h b/targets/TARGET_STM/TARGET_STM32F3/objects.h index bca32ef2688..3ef4aeb0d0b 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/objects.h @@ -109,6 +109,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32F7/i2c_device.c b/targets/TARGET_STM/TARGET_STM32F7/i2c_device.c index 6eb967be519..50e280c9c1f 100755 --- a/targets/TARGET_STM/TARGET_STM32F7/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32F7/i2c_device.c @@ -106,45 +106,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } - -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_DEF) { - switch (hz) { - case 100000: - tim = TIMING_VAL_DEFAULT_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_DEFAULT_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_DEFAULT_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance*/ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} - -/** - * @} - */ #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32F7/i2c_device.h b/targets/TARGET_STM/TARGET_STM32F7/i2c_device.h index 8bc86a31068..2b48bc8f207 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32F7/i2c_device.h @@ -40,10 +40,10 @@ extern "C" { /* Define I2C Device */ #if DEVICE_I2C -#define TIMING_VAL_DEFAULT_CLK_100KHZ 0x10916998 // Standard mode with Rise time = 120ns, Fall time = 120ns -#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x00B11B54 // Fast Mode with Rise time = 120ns, Fall time = 120ns -#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x0090091B // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns -#define I2C_PCLK_DEF 54000000 // 54 MHz +#define TIMING_VAL_54M_CLK_100KHZ 0x10916998 // Standard mode with Rise time = 120ns, Fall time = 120ns +#define TIMING_VAL_54M_CLK_400KHZ 0x00B11B54 // Fast Mode with Rise time = 120ns, Fall time = 120ns +#define TIMING_VAL_54M_CLK_1MHZ 0x0090091B // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns +#define I2C_PCLK_54M 54000000 // 54 MHz /* Define IP version */ #define I2C_IP_VERSION_V2 @@ -57,7 +57,7 @@ extern "C" { #define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_PCLK1 uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32F7/objects.h b/targets/TARGET_STM/TARGET_STM32F7/objects.h index 18789b8d9a0..3daf779fea7 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/objects.h @@ -125,6 +125,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32G0/i2c_device.c b/targets/TARGET_STM/TARGET_STM32G0/i2c_device.c index f9a60d3af3f..e7d9894ba91 100755 --- a/targets/TARGET_STM/TARGET_STM32G0/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32G0/i2c_device.c @@ -51,46 +51,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } - -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_DEF) { - switch (hz) { - case 100000: - tim = TIMING_VAL_DEFAULT_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_DEFAULT_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_DEFAULT_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance*/ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} - -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32G0/i2c_device.h b/targets/TARGET_STM/TARGET_STM32G0/i2c_device.h index ec808d37a76..dfc765c259b 100644 --- a/targets/TARGET_STM/TARGET_STM32G0/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32G0/i2c_device.h @@ -26,10 +26,10 @@ extern "C" { #if DEVICE_I2C // Common settings: I2C clock = 64 MHz, Analog filter = ON, Digital filter coefficient = 0 -#define TIMING_VAL_DEFAULT_CLK_100KHZ 0xC0311319 // Standard mode with Rise Time = 400ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x10B1102E // Fast mode with Rise Time = 250ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x00710B1E // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_DEF 64000000 // 64 MHz +#define TIMING_VAL_64M_CLK_100KHZ 0xC0311319 // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_64M_CLK_400KHZ 0x10B1102E // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_64M_CLK_1MHZ 0x00710B1E // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_64M 64000000 // 64 MHz /* Define IP version */ #define I2C_IP_VERSION_V2 @@ -47,7 +47,7 @@ extern "C" { #define I2CAPI_I2C2_CLKSRC RCC_I2C2CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32G0/objects.h b/targets/TARGET_STM/TARGET_STM32G0/objects.h index 638d4e87252..3673f6e755d 100644 --- a/targets/TARGET_STM/TARGET_STM32G0/objects.h +++ b/targets/TARGET_STM/TARGET_STM32G0/objects.h @@ -108,6 +108,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32G4/i2c_device.c b/targets/TARGET_STM/TARGET_STM32G4/i2c_device.c index d32c4132988..52be954fe56 100755 --- a/targets/TARGET_STM/TARGET_STM32G4/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32G4/i2c_device.c @@ -106,44 +106,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } - -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_DEF) { - switch (hz) { - case 100000: - tim = TIMING_VAL_DEFAULT_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_DEFAULT_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_DEFAULT_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance*/ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} -/** - * @} - */ #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32G4/i2c_device.h b/targets/TARGET_STM/TARGET_STM32G4/i2c_device.h index 5d61cf1f912..b41fc591d5b 100644 --- a/targets/TARGET_STM/TARGET_STM32G4/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32G4/i2c_device.h @@ -26,10 +26,10 @@ extern "C" { #if DEVICE_I2C // Common settings: I2C clock = 64 MHz, Analog filter = ON, Digital filter coefficient = 0 -#define TIMING_VAL_DEFAULT_CLK_100KHZ 0xC0311319 // Standard mode with Rise Time = 400ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x10B1102E // Fast mode with Rise Time = 250ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x00710B1E // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_DEF 160000000 // 160 MHz +#define TIMING_VAL_160M_CLK_100KHZ 0xC0311319 // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_160M_CLK_400KHZ 0x10B1102E // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_160M_CLK_1MHZ 0x00710B1E // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_160M 160000000 // 160 MHz /* Define IP version */ #define I2C_IP_VERSION_V2 @@ -43,7 +43,7 @@ extern "C" { #define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32G4/objects.h b/targets/TARGET_STM/TARGET_STM32G4/objects.h index bb466ce224c..53098ec6bdb 100644 --- a/targets/TARGET_STM/TARGET_STM32G4/objects.h +++ b/targets/TARGET_STM/TARGET_STM32G4/objects.h @@ -107,6 +107,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32H7/i2c_device.c b/targets/TARGET_STM/TARGET_STM32H7/i2c_device.c index ae3f5623570..91a79daccdf 100755 --- a/targets/TARGET_STM/TARGET_STM32H7/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32H7/i2c_device.c @@ -83,51 +83,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } -/** - * @} - */ - -/** @defgroup I2C_DEVICE_Exported_Functions I2C_DEVICE Exported Functions - * @{ - */ -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_DEF) { - switch (hz) { - case 100000: - tim = TIMING_VAL_DEFAULT_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_DEFAULT_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_DEFAULT_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance*/ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h b/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h index 655d697a293..8765199e3c8 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h @@ -29,10 +29,10 @@ extern "C" { /* Define IP version */ #define I2C_IP_VERSION_V2 -#define TIMING_VAL_DEFAULT_CLK_100KHZ 0x40E15676 // Standard mode with Rise Time = 400ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x20C11434 // Fast mode with Rise Time = 250ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x00C31536 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_DEF 120000000 // 120 MHz +#define TIMING_VAL_120M_CLK_100KHZ 0x40E15676 // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_120M_CLK_400KHZ 0x20C11434 // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_120M_CLK_1MHZ 0x00C31536 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_120M 120000000 // 120 MHz #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) @@ -43,7 +43,7 @@ extern "C" { #define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_D3PCLK1 uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32H7/objects.h b/targets/TARGET_STM/TARGET_STM32H7/objects.h index 727d0e1033b..6f171478860 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/objects.h +++ b/targets/TARGET_STM/TARGET_STM32H7/objects.h @@ -114,6 +114,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32L0/i2c_device.c b/targets/TARGET_STM/TARGET_STM32L0/i2c_device.c index 0628b2658fe..e728a413e6e 100755 --- a/targets/TARGET_STM/TARGET_STM32L0/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32L0/i2c_device.c @@ -70,51 +70,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } -/** - * @} - */ - -/** @defgroup I2C_DEVICE_Exported_Functions I2C_DEVICE Exported Functions - * @{ - */ -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_DEF) { - switch (hz) { - case 100000: - tim = TIMING_VAL_DEFAULT_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_DEFAULT_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_DEFAULT_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance*/ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32L0/i2c_device.h b/targets/TARGET_STM/TARGET_STM32L0/i2c_device.h index f4aac1f738d..d48f2a133a8 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32L0/i2c_device.h @@ -41,10 +41,10 @@ extern "C" { #define I2C3_ER_IRQn I2C3_IRQn #endif -#define TIMING_VAL_DEFAULT_CLK_100KHZ 0x20602938 // Standard mode with Rise Time = 400ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x00B0122A // Fast mode with Rise Time = 250ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x0030040E // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_DEF 32000000 // 32 MHz +#define TIMING_VAL_32M_CLK_100KHZ 0x20602938 // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_32M_CLK_400KHZ 0x00B0122A // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_32M_CLK_1MHZ 0x0030040E // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_32M 32000000 // 32 MHz #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) @@ -54,7 +54,7 @@ extern "C" { #define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32L0/objects.h b/targets/TARGET_STM/TARGET_STM32L0/objects.h index 642a202c18c..a94dd3f04f3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/objects.h @@ -110,6 +110,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32L4/i2c_device.c b/targets/TARGET_STM/TARGET_STM32L4/i2c_device.c index bb5df31cbdb..3aecc08d058 100755 --- a/targets/TARGET_STM/TARGET_STM32L4/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32L4/i2c_device.c @@ -105,81 +105,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } -/** - * @} - */ - -/** @defgroup I2C_DEVICE_Exported_Functions I2C_DEVICE Exported Functions - * @{ - */ -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_80M) { - switch (hz) { - case 100000: - tim = TIMING_VAL_80M_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_80M_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_80M_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else if (pclk == I2C_PCLK_48M) { - switch (hz) { - case 100000: - tim = TIMING_VAL_48M_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_48M_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_48M_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else if (pclk == I2C_PCLK_120M) { - switch (hz) { - case 100000: - tim = TIMING_VAL_120M_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_120M_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_120M_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance*/ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32L4/i2c_device.h b/targets/TARGET_STM/TARGET_STM32L4/i2c_device.h index 8ee00140150..cdd1479284d 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32L4/i2c_device.h @@ -34,7 +34,7 @@ extern "C" { #define TIMING_VAL_80M_CLK_100KHZ 0x30C14E6B // Standard mode with Rise Time = 400ns and Fall Time = 100ns #define TIMING_VAL_80M_CLK_400KHZ 0x10D1143A // Fast mode with Rise Time = 250ns and Fall Time = 100ns #define TIMING_VAL_80M_CLK_1MHZ 0x00810E27 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_80M 80000000 // 80 MHz +#define I2C_PCLK_80M 80000000 // 80 MHz // Common settings: I2C clock = 48 MHz, Analog filter = ON, Digital filter coefficient = 0 #define TIMING_VAL_48M_CLK_100KHZ 0x20A03E55 // Standard mode with Rise Time = 400ns and Fall Time = 100ns @@ -57,7 +57,7 @@ extern "C" { #define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32L4/objects.h b/targets/TARGET_STM/TARGET_STM32L4/objects.h index b5993913f7f..15196a6cbc2 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/objects.h @@ -106,6 +106,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32L5/i2c_device.c b/targets/TARGET_STM/TARGET_STM32L5/i2c_device.c index bd593f5dc5c..36f6cdae4c0 100755 --- a/targets/TARGET_STM/TARGET_STM32L5/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32L5/i2c_device.c @@ -106,54 +106,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } -/** - * @} - */ - -/** @defgroup I2C_DEVICE_Exported_Functions I2C_DEVICE Exported Functions - * @{ - */ -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_DEF) { - switch (hz) { - case 100000: - tim = TIMING_VAL_DEFAULT_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_DEFAULT_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_DEFAULT_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } - - else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance */ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32L5/i2c_device.h b/targets/TARGET_STM/TARGET_STM32L5/i2c_device.h index 089bfeb875a..1693ef6ee84 100644 --- a/targets/TARGET_STM/TARGET_STM32L5/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32L5/i2c_device.h @@ -29,10 +29,10 @@ extern "C" { #define I2C_IP_VERSION_V2 // Common settings: I2C clock = 110 MHz, Analog filter = ON, Digital filter coefficient = 0 -#define TIMING_VAL_DEFAULT_CLK_100KHZ 0x40E15676 // Standard mode with Rise Time = 400ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x20C11434 // Fast mode with Rise Time = 250ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x00C31536 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_DEF 110000000 // 110 MHz +#define TIMING_VAL_110M_CLK_100KHZ 0x40E15676 // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_110M_CLK_400KHZ 0x20C11434 // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_110M_CLK_1MHZ 0x00C31536 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_110M 110000000 // 110 MHz #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) @@ -43,7 +43,7 @@ extern "C" { #define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32L5/objects.h b/targets/TARGET_STM/TARGET_STM32L5/objects.h index 5dbd6abb696..f49dce7d937 100644 --- a/targets/TARGET_STM/TARGET_STM32L5/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L5/objects.h @@ -114,6 +114,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32WB/i2c_device.c b/targets/TARGET_STM/TARGET_STM32WB/i2c_device.c index b3292c90596..9b99d3a0549 100755 --- a/targets/TARGET_STM/TARGET_STM32WB/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32WB/i2c_device.c @@ -87,71 +87,4 @@ uint32_t i2c_get_pclk(I2CName i2c) } return pclk; } -/** - * @} - */ - -/** @defgroup I2C_DEVICE_Exported_Functions I2C_DEVICE Exported Functions - * @{ - */ -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_64M) { - switch (hz) { - case 100000: - tim = TIMING_VAL_64M_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_64M_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_64M_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } - - else if (pclk == I2C_PCLK_32M) { - switch (hz) { - case 100000: - tim = TIMING_VAL_32M_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_32M_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_32M_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } - - else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance */ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32WB/i2c_device.h b/targets/TARGET_STM/TARGET_STM32WB/i2c_device.h index d2750891305..83e63e8d78d 100644 --- a/targets/TARGET_STM/TARGET_STM32WB/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32WB/i2c_device.h @@ -34,13 +34,13 @@ extern "C" { #define TIMING_VAL_64M_CLK_100KHZ 0x10707DBC // Standard mode with Rise Time = 400ns and Fall Time = 100ns #define TIMING_VAL_64M_CLK_400KHZ 0x00602173 // Fast mode with Rise Time = 250ns and Fall Time = 100ns #define TIMING_VAL_64M_CLK_1MHZ 0x00300B29 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_64M 64000000 // 64 MHz +#define I2C_PCLK_64M 64000000 // 64 MHz // Common settings: I2C clock = 32 MHz, Analog filter = ON, Digital filter coefficient = 0 #define TIMING_VAL_32M_CLK_100KHZ 0x00707CBB // Standard mode with Rise Time = 400ns and Fall Time = 100ns #define TIMING_VAL_32M_CLK_400KHZ 0x00300F38 // Fast mode with Rise Time = 250ns and Fall Time = 100ns #define TIMING_VAL_32M_CLK_1MHZ 0x00100413 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_32M 32000000 // 32 MHz +#define I2C_PCLK_32M 32000000 // 32 MHz #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) @@ -50,7 +50,7 @@ extern "C" { #define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32WB/objects.h b/targets/TARGET_STM/TARGET_STM32WB/objects.h index ead49f7692c..7fb437dc546 100644 --- a/targets/TARGET_STM/TARGET_STM32WB/objects.h +++ b/targets/TARGET_STM/TARGET_STM32WB/objects.h @@ -97,6 +97,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/TARGET_STM32WL/i2c_device.c b/targets/TARGET_STM/TARGET_STM32WL/i2c_device.c index 118f9e278c0..d4c022b3b55 100755 --- a/targets/TARGET_STM/TARGET_STM32WL/i2c_device.c +++ b/targets/TARGET_STM/TARGET_STM32WL/i2c_device.c @@ -89,54 +89,4 @@ uint32_t i2c_get_pclk(I2CName i2c) return pclk; } -/** - * @} - */ - -/** @defgroup I2C_DEVICE_Exported_Functions I2C_DEVICE Exported Functions - * @{ - */ -/** - * @brief Provide the suitable timing depending on requested frequency - * @param hz Required I2C clock in Hz. - * @retval I2C timing or 0 in case of error. - */ -uint32_t i2c_get_timing(I2CName i2c, int hz) -{ - uint32_t tim; - uint32_t pclk; - - pclk = i2c_get_pclk(i2c); - if (pclk == I2C_PCLK_DEF) { - switch (hz) { - case 100000: - tim = TIMING_VAL_DEFAULT_CLK_100KHZ; - break; - case 400000: - tim = TIMING_VAL_DEFAULT_CLK_400KHZ; - break; - case 1000000: - tim = TIMING_VAL_DEFAULT_CLK_1MHZ; - break; - default: - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - break; - } - } - - else { - /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. - User needs to enable I2C_TIMING_VALUE_ALGO in target.json for specific target. - Enabling this may impact performance */ - MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); -#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO - tim = i2c_compute_timing(pclk, hz); -#endif - } - return tim; -} -/** - * @} - */ - #endif // DEVICE_I2C diff --git a/targets/TARGET_STM/TARGET_STM32WL/i2c_device.h b/targets/TARGET_STM/TARGET_STM32WL/i2c_device.h index a84d941f89e..9211e30b779 100644 --- a/targets/TARGET_STM/TARGET_STM32WL/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32WL/i2c_device.h @@ -29,10 +29,10 @@ extern "C" { #define I2C_IP_VERSION_V2 // Common settings: I2C clock = 48 MHz, Analog filter = ON, Digital filter coefficient = 0 -#define TIMING_VAL_DEFAULT_CLK_100KHZ 0x20E03F53 // Standard mode with Rise Time = 640ns and Fall Time = 20ns -#define TIMING_VAL_DEFAULT_CLK_400KHZ 0x20500817 // Fast mode with Rise Time = 250ns and Fall Time = 100ns -#define TIMING_VAL_DEFAULT_CLK_1MHZ 0x00500A18 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns -#define I2C_PCLK_DEF 48000000 // 48 MHz +#define TIMING_VAL_48M_CLK_100KHZ 0x20E03F53 // Standard mode with Rise Time = 640ns and Fall Time = 20ns +#define TIMING_VAL_48M_CLK_400KHZ 0x20500817 // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_48M_CLK_1MHZ 0x00500A18 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_48M 48000000 // 48 MHz #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) @@ -42,7 +42,7 @@ extern "C" { #define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_SYSCLK uint32_t i2c_get_pclk(I2CName i2c); -uint32_t i2c_get_timing(I2CName i2c, int hz); +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz); #if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq); diff --git a/targets/TARGET_STM/TARGET_STM32WL/objects.h b/targets/TARGET_STM/TARGET_STM32WL/objects.h index 72270cd4c26..66f06eab289 100644 --- a/targets/TARGET_STM/TARGET_STM32WL/objects.h +++ b/targets/TARGET_STM/TARGET_STM32WL/objects.h @@ -100,6 +100,7 @@ struct i2c_s { uint32_t XferOperation; volatile uint8_t event; volatile int pending_start; + int current_hz; #if DEVICE_I2CSLAVE uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; diff --git a/targets/TARGET_STM/i2c_api.c b/targets/TARGET_STM/i2c_api.c index e4ace431e29..2676e19fd6f 100644 --- a/targets/TARGET_STM/i2c_api.c +++ b/targets/TARGET_STM/i2c_api.c @@ -152,7 +152,7 @@ static const I2C_Charac_t I2C_Charac[] = { */ static I2C_Timings_t I2c_valid_timing[I2C_VALID_TIMING_NBR]; static uint32_t I2c_valid_timing_nbr = 0; -#endif // MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO +#endif // MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO #ifndef DEBUG_STDIO # define DEBUG_STDIO 0 @@ -398,7 +398,14 @@ void i2c_init_internal(i2c_t *obj, const i2c_pinmap_t *pinmap) { struct i2c_s *obj_s = I2C_S(obj); - // Determine the I2C to use +#ifdef I2C_IP_VERSION_V2 + /* These variables are initialized with 0, to overcome possiblity of + garbage assignment */ + obj_s->current_hz = 0; + obj_s->handle.Init.Timing = 0; +#endif + + /* Determine the I2C to use */ if (pinmap != NULL) { obj_s->sda = pinmap->sda_pin; obj_s->scl = pinmap->scl_pin; @@ -488,6 +495,10 @@ void i2c_init_internal(i2c_t *obj, const i2c_pinmap_t *pinmap) i2c_hw_reset(obj); i2c_frequency(obj, obj_s->hz); +#ifdef I2C_IP_VERSION_V2 + obj_s->current_hz = obj_s->hz; +#endif + #if DEVICE_I2CSLAVE // I2C master by default obj_s->slave = 0; @@ -583,7 +594,6 @@ void i2c_free(i2c_t *obj) i2c_deinit_internal(obj); } - void i2c_frequency(i2c_t *obj, int hz) { int timeout; @@ -657,12 +667,6 @@ void i2c_frequency(i2c_t *obj, int hz) __HAL_RCC_I2C4_CONFIG(I2CAPI_I2C4_CLKSRC); } #endif -#ifdef I2C_IP_VERSION_V2 -/* Only predefined timing for below frequencies are supported */ - MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); - /* Calculates I2C timing value with respect to I2C input clock and I2C bus frequency */ - handle->Init.Timing = i2c_get_timing(obj_s->i2c, hz); -#endif #if defined(DUAL_CORE) && (TARGET_STM32H7) LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT); #endif /* DUAL_CORE */ @@ -672,6 +676,23 @@ void i2c_frequency(i2c_t *obj, int hz) HAL_I2CEx_ConfigAnalogFilter(handle, I2C_ANALOGFILTER_ENABLE); #endif +#ifdef I2C_IP_VERSION_V2 + /* Only predefined timing for below frequencies are supported */ + MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000)); + + /* Derives I2C timing value with respect to I2C input clock source speed + and I2C bus frequency requested. "Init.Timing" is passed to this function to + reduce multiple computation of timing value which there by reduces CPU load. + */ + handle->Init.Timing = i2c_get_timing(obj_s->i2c, handle->Init.Timing, \ + obj_s->current_hz, hz); + /* Only non-zero timing value is supported */ + MBED_ASSERT(handle->Init.Timing != 0); + + /* hz value is stored for computing timing value next time */ + obj_s->current_hz = hz; +#endif // I2C_IP_VERSION_V2 + // I2C configuration handle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; handle->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; @@ -1306,7 +1327,7 @@ void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle) if (obj_s->slave == SLAVE_MODE_LISTEN) { obj_s->slave_rx_count++; - if (obj_s->slave_rx_count < obj_s->slave_rx_buffer_size){ + if (obj_s->slave_rx_count < obj_s->slave_rx_buffer_size) { HAL_I2C_Slave_Seq_Receive_IT(I2cHandle, &(obj_s->slave_rx_buffer[obj_s->slave_rx_count]), 1, I2C_NEXT_FRAME); } else { obj_s->pending_slave_rx_maxter_tx = 0; @@ -1356,12 +1377,12 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) int _length = 0; if (obj_s->slave == SLAVE_MODE_LISTEN) { - /* We don't know in advance how many bytes will be sent by master so - * we'll fetch one by one until master ends the sequence */ + /* We don't know in advance how many bytes will be sent by master so + * we'll fetch one by one until master ends the sequence */ _length = 1; obj_s->slave_rx_buffer_size = length; obj_s->slave_rx_count = 0; - obj_s->slave_rx_buffer = (uint8_t*)data; + obj_s->slave_rx_buffer = (uint8_t *)data; } else { _length = length; } @@ -1733,7 +1754,215 @@ uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq) return ret; } -#endif // MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO +#endif /* MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO */ + +#ifdef I2C_IP_VERSION_V2 +/** + * @brief Provide the suitable timing depending on requested frequency + * @param i2c Required I2C instance. + * @param current_timing Required I2C timing value. + * @param current_hz Required I2C current hz value. + * @param hz Required I2C bus clock speed. + * @retval I2C timing value or 0 in case of error. + */ +uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, + int hz) +{ + uint32_t tim = 0; + uint32_t pclk; + + pclk = i2c_get_pclk(i2c); + + if ((current_timing == 0) || (current_hz != hz)) { + switch (pclk) { +#if defined (I2C_PCLK_32M) + case I2C_PCLK_32M: + switch (hz) { + case 100000: + tim = TIMING_VAL_32M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_32M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_32M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined (I2C_PCLK_48M) + case I2C_PCLK_48M: + switch (hz) { + case 100000: + tim = TIMING_VAL_48M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_48M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_48M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined (I2C_PCLK_54M) + case I2C_PCLK_54M: + switch (hz) { + case 100000: + tim = TIMING_VAL_54M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_54M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_54M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined(I2C_PCLK_64M) + case I2C_PCLK_64M: + switch (hz) { + case 100000: + tim = TIMING_VAL_64M_CLK_100KHZ; + case 400000: + tim = TIMING_VAL_64M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_64M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined (I2C_PCLK_72M) + case I2C_PCLK_72M: + switch (hz) { + case 100000: + tim = TIMING_VAL_72M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_72M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_72M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined (I2C_PCLK_80M) + case I2C_PCLK_80M: + switch (hz) { + case 100000: + tim = TIMING_VAL_80M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_80M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_80M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined (I2C_PCLK_110M) + case I2C_PCLK_110M: + switch (hz) { + case 100000: + tim = TIMING_VAL_110M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_110M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_110M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined (I2C_PCLK_120M) + case I2C_PCLK_120M: + switch (hz) { + case 100000: + tim = TIMING_VAL_120M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_120M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_120M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined (I2C_PCLK_160M) + case I2C_PCLK_160M: + switch (hz) { + case 100000: + tim = TIMING_VAL_160M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_160M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_160M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif + default: + /* If MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO assert is triggered. + User need to enable I2C_TIMING_VALUE_ALGO in target.json for specific + target. Enabling this may impact performance*/ + MBED_ASSERT(MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO); +#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO + tim = i2c_compute_timing(pclk, hz); +#endif + break; + } + } else { + tim = current_timing; + } + return tim; +} + + +#endif /* I2C_IP_VERSION_V2 */ #endif // DEVICE_I2C_ASYNCH From b559cec29ebc64f1076b582ba8faa3a400ae0cc2 Mon Sep 17 00:00:00 2001 From: Affrin Pinhero Date: Fri, 2 Jul 2021 10:52:13 +0530 Subject: [PATCH 2/2] I2C: STM32: Upating documentation for I2C timing Algorithm This commit modifies readme file. Descption for using I2C timing algorithm and how to enable and disable included. Signed-off-by: Affrin Pinhero --- targets/TARGET_STM/README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/targets/TARGET_STM/README.md b/targets/TARGET_STM/README.md index 245a93f6662..f744e1d2c7a 100644 --- a/targets/TARGET_STM/README.md +++ b/targets/TARGET_STM/README.md @@ -408,6 +408,31 @@ You can change this in you local mbed_app.json: } ``` +#### I2C TIming calculation algorothm + +I2C drivers version 2 use I2C timing register. + +Enable I2C timing algorithm by setting the value of `i2c_timing_value_algo` +target config to `true` + +``` +"i2c_timing_value_algo": { + "help": "If value was set to true I2C timing algorithm is + enabled. Enabling may leads to performance issue. Keeping this + false and changing system clock will trigger assert.", + "value": false + } +``` +Default configuration disables I2C timing algorithm. If user need to use +different system clock speed other than default system clock configuration. +Then I2C timing calculation algorithm need to enable. To enable + +``` +"i2c_timing_value_algo": { + "value": true + } +``` + ### Sleep feature