Skip to content

Commit 3b3b4a5

Browse files
mib1-nordicrlubos
authored andcommitted
[nrf fromlist] drivers: i2c: i2c_nrfx_twim: take clock tolerance into account
In calculation of the FREQUENCY register value take into account the tolerance of the peripheral clock to ensure that the SCL frequency does not exceed the specified value. Upstream PR #: 104882 Signed-off-by: Michał Bainczyk <michal.bainczyk@nordicsemi.no>
1 parent 1871817 commit 3b3b4a5

1 file changed

Lines changed: 29 additions & 3 deletions

File tree

drivers/i2c/i2c_nrfx_twim_common.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,25 @@ extern "C" {
1717
#endif
1818

1919
#define I2C_NRFX_TWIM_INVALID_FREQUENCY ((nrf_twim_frequency_t)-1)
20-
#define I2C_NRFX_TWIM_FREQUENCY(bitrate) \
20+
21+
/* Formula for getting the frequency settings is following:
22+
* 2^12 * (2^20 / (f_PCLK / desired_frequency)) where f_PCLK is a frequency that
23+
* drives the TWIM.
24+
*
25+
* @param f_pclk Frequency of the clock that drives the peripheral.
26+
* @param baudrate Desired baudrate.
27+
*
28+
* @return Frequency setting to be written to the FREQUENCY register
29+
*/
30+
#define I2C_NRFX_TWIM_FREQUENCY_CALCULATE(bitrate, f_pclk) \
31+
((nrf_twim_frequency_t)((BIT(20) / DIV_ROUND_CLOSEST(f_pclk, bitrate)) << 12))
32+
33+
#define I2C_NRFX_TWIM_FREQUENCY_CALCULATE_CORRECTED(bitrate, f_pclk, tolerance_percent) \
34+
I2C_NRFX_TWIM_FREQUENCY_CALCULATE(bitrate, \
35+
DIV_ROUND_CLOSEST(f_pclk * (100 + tolerance_percent), \
36+
100))
37+
38+
#define I2C_NRFX_TWIM_FREQUENCY_ENUM_GET(bitrate, f_pclk) \
2139
(bitrate == I2C_BITRATE_STANDARD ? NRF_TWIM_FREQ_100K \
2240
: bitrate == 250000 ? NRF_TWIM_FREQ_250K \
2341
: bitrate == I2C_BITRATE_FAST \
@@ -26,8 +44,16 @@ extern "C" {
2644
(bitrate == I2C_BITRATE_FAST_PLUS ? NRF_TWIM_FREQ_1000K :)) \
2745
I2C_NRFX_TWIM_INVALID_FREQUENCY)
2846

29-
#define I2C_FREQUENCY(inst) \
30-
I2C_NRFX_TWIM_FREQUENCY(DT_INST_PROP_OR(inst, clock_frequency, I2C_BITRATE_STANDARD))
47+
#define INTENDED_CLOCK_FREQUENCY(inst) DT_INST_PROP_OR(inst, clock_frequency, I2C_BITRATE_STANDARD)
48+
#define CLOCK_TOLERANCE(inst) DT_INST_PROP(inst, clock_tolerance_percent)
49+
50+
#define I2C_FREQUENCY(inst) \
51+
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, clock_tolerance_percent), \
52+
(I2C_NRFX_TWIM_FREQUENCY_CALCULATE_CORRECTED(INTENDED_CLOCK_FREQUENCY(inst), \
53+
NRF_PERIPH_GET_FREQUENCY(inst), \
54+
CLOCK_TOLERANCE(inst))), \
55+
(I2C_NRFX_TWIM_FREQUENCY_ENUM_GET(INTENDED_CLOCK_FREQUENCY(inst), \
56+
NRF_PERIPH_GET_FREQUENCY(inst))))
3157

3258
/* Macro determines PM actions interrupt safety level.
3359
*

0 commit comments

Comments
 (0)