mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #14808 from affrinpinhero-2356/i2cTimingPerformanceSolved
driver/i2c: STM32: I2C performance issue solved.pull/14897/head
commit
1d5d3b054f
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue