From 7645bf2d485a74e11ae55fe1f281ff68fc49290f Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Fri, 22 Jun 2012 14:44:15 -0400 Subject: I2C: Move CCR/TRISE config helper back to libmaple/i2c.c. We can implement it in terms of _i2c_bus_clk() instead of hard-coding STM32_PCLK1. This might be overkill, since I2C peripherals are slow and thus likely to be on APB1 for all STM32 devices (that is the case for F2/F4, for instance), but if we're going to have _i2c_bus_clk(), we might as well respect it. Signed-off-by: Marti Bolivar --- libmaple/i2c.c | 42 +++++++++++++++++++++++++++++++++++++++++- libmaple/stm32f1/i2c.c | 36 ------------------------------------ 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/libmaple/i2c.c b/libmaple/i2c.c index 3c92bef..9c93d3f 100644 --- a/libmaple/i2c.c +++ b/libmaple/i2c.c @@ -47,6 +47,7 @@ static inline int32 wait_for_state_change(i2c_dev *dev, i2c_state state, uint32 timeout); +static void set_ccr_trise(i2c_dev *dev, uint32 flags); /** * @brief Fill data register with slave address @@ -190,7 +191,7 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) { i2c_config_gpios(dev); /* Configure clock and rise time */ - _i2c_set_ccr_trise(dev, flags); + set_ccr_trise(dev, flags); /* Enable event and buffer interrupts */ nvic_irq_enable(dev->ev_nvic_line); @@ -467,3 +468,42 @@ void _i2c_irq_error_handler(i2c_dev *dev) { i2c_disable_irq(dev, I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR); dev->state = I2C_STATE_ERROR; } + +/* + * CCR/TRISE configuration helper + */ +static void set_ccr_trise(i2c_dev *dev, uint32 flags) { + uint32 ccr = 0; + uint32 trise = 0; + uint32 clk_mhz = _i2c_bus_clk(dev); + uint32 clk_hz = clk_mhz * (1000 * 1000); + + i2c_set_input_clk(dev, clk_mhz); + + if (flags & I2C_FAST_MODE) { + ccr |= I2C_CCR_FS; + + if (flags & I2C_DUTY_16_9) { + /* Tlow/Thigh = 16/9 */ + ccr |= I2C_CCR_DUTY_16_9; + ccr |= clk_hz / (400000 * 25); + } else { + /* Tlow/Thigh = 2 */ + ccr |= clk_hz / (400000 * 3); + } + + trise = (300 * clk_mhz / 1000) + 1; + } else { + /* Tlow/Thigh = 1 */ + ccr = clk_hz / (100000 * 2); + trise = clk_mhz + 1; + } + + /* Set minimum required value if CCR < 1*/ + if ((ccr & I2C_CCR_CCR) == 0) { + ccr |= 0x1; + } + + i2c_set_clk_control(dev, ccr); + i2c_set_trise(dev, trise); +} diff --git a/libmaple/stm32f1/i2c.c b/libmaple/stm32f1/i2c.c index 3e0e146..8439793 100644 --- a/libmaple/stm32f1/i2c.c +++ b/libmaple/stm32f1/i2c.c @@ -127,39 +127,3 @@ void _i2c_irq_priority_fixup(i2c_dev *dev) { nvic_irq_set_priority(dev->ev_nvic_line, 0); nvic_irq_set_priority(dev->er_nvic_line, 0); } - -void _i2c_set_ccr_trise(i2c_dev *dev, uint32 flags) { -#define I2C_CLK (STM32_PCLK1/1000000) - uint32 ccr = 0; - uint32 trise = 0; - - /* I2C1 and I2C2 are fed from APB1, clocked at 36MHz */ - i2c_set_input_clk(dev, I2C_CLK); - - if (flags & I2C_FAST_MODE) { - ccr |= I2C_CCR_FS; - - if (flags & I2C_DUTY_16_9) { - /* Tlow/Thigh = 16/9 */ - ccr |= I2C_CCR_DUTY; - ccr |= STM32_PCLK1/(400000 * 25); - } else { - /* Tlow/Thigh = 2 */ - ccr |= STM32_PCLK1/(400000 * 3); - } - - trise = (300 * (I2C_CLK)/1000) + 1; - } else { - /* Tlow/Thigh = 1 */ - ccr = STM32_PCLK1/(100000 * 2); - trise = I2C_CLK + 1; - } - - /* Set minimum required value if CCR < 1*/ - if ((ccr & I2C_CCR_CCR) == 0) { - ccr |= 0x1; - } - - i2c_set_clk_control(dev, ccr); - i2c_set_trise(dev, trise); -} -- cgit v1.2.3