From fe34ca70469f1bd88eb38feb2b0b336ef5b07ff8 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Thu, 21 Jun 2012 16:29:22 -0400 Subject: I2C: Move nonportable CCR/TRISE configuration. Do this via new private _i2c_set_ccr_trise(). Signed-off-by: Marti Bolivar --- libmaple/i2c.c | 37 ++++--------------------------------- libmaple/i2c_private.h | 4 ++++ libmaple/stm32f1/i2c.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 33 deletions(-) (limited to 'libmaple') diff --git a/libmaple/i2c.c b/libmaple/i2c.c index d2447a4..0e6a64c 100644 --- a/libmaple/i2c.c +++ b/libmaple/i2c.c @@ -33,6 +33,8 @@ * Currently, only master mode is supported. */ +#include "i2c_private.h" + #include #include #include @@ -172,10 +174,6 @@ void i2c_init(i2c_dev *dev) { * SDA/PB9. */ void i2c_master_enable(i2c_dev *dev, uint32 flags) { -#define I2C_CLK (STM32_PCLK1/1000000) - uint32 ccr = 0; - uint32 trise = 0; - /* PE must be disabled to configure the device */ ASSERT(!(dev->regs->CR1 & I2C_CR1_PE)); @@ -191,35 +189,8 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) { i2c_init(dev); i2c_config_gpios(dev); - /* 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); + /* Configure clock and rise time */ + _i2c_set_ccr_trise(dev, flags); /* Enable event and buffer interrupts */ nvic_irq_enable(dev->ev_nvic_line); diff --git a/libmaple/i2c_private.h b/libmaple/i2c_private.h index 4a0f01f..05a293c 100644 --- a/libmaple/i2c_private.h +++ b/libmaple/i2c_private.h @@ -43,4 +43,8 @@ struct i2c_dev; void _i2c_irq_handler(struct i2c_dev *dev); void _i2c_irq_error_handler(struct i2c_dev *dev); +/* Auxiliary procedure for enabling an I2C peripheral; `flags' as for + * i2c_master_enable(). */ +void _i2c_set_ccr_trise(i2c_dev *dev, uint32 flags); + #endif /* _LIBMAPLE_I2C_PRIVATE_H_ */ diff --git a/libmaple/stm32f1/i2c.c b/libmaple/stm32f1/i2c.c index 4e918ad..4c9af30 100644 --- a/libmaple/stm32f1/i2c.c +++ b/libmaple/stm32f1/i2c.c @@ -110,3 +110,39 @@ 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