Skip to content

Commit

Permalink
driver/i2c: STM32: Solves I2C driver performanc issue.
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
affrinpinhero-2356 committed Jul 1, 2021
1 parent 472c688 commit 98dde59
Show file tree
Hide file tree
Showing 34 changed files with 288 additions and 627 deletions.
46 changes: 0 additions & 46 deletions targets/TARGET_STM/TARGET_STM32F0/i2c_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 5 additions & 5 deletions targets/TARGET_STM/TARGET_STM32F0/i2c_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ 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)

/* Family specifc settings for clock source */
#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);
Expand Down
1 change: 1 addition & 0 deletions targets/TARGET_STM/TARGET_STM32F0/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
61 changes: 0 additions & 61 deletions targets/TARGET_STM/TARGET_STM32F3/i2c_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 3 additions & 3 deletions targets/TARGET_STM/TARGET_STM32F3/i2c_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions targets/TARGET_STM/TARGET_STM32F3/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 0 additions & 41 deletions targets/TARGET_STM/TARGET_STM32F7/i2c_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 5 additions & 5 deletions targets/TARGET_STM/TARGET_STM32F7/i2c_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions targets/TARGET_STM/TARGET_STM32F7/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
42 changes: 0 additions & 42 deletions targets/TARGET_STM/TARGET_STM32G0/i2c_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 5 additions & 5 deletions targets/TARGET_STM/TARGET_STM32G0/i2c_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions targets/TARGET_STM/TARGET_STM32G0/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
40 changes: 0 additions & 40 deletions targets/TARGET_STM/TARGET_STM32G4/i2c_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading

0 comments on commit 98dde59

Please sign in to comment.