aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-06-22 14:44:15 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-06-22 15:07:08 -0400
commit7645bf2d485a74e11ae55fe1f281ff68fc49290f (patch)
tree7178381157a4a2a85f2b8b5ea784a7629c02b3ee
parent929ef7192a497c7b6dc9d72c8bf455dc152dffbc (diff)
downloadlibrambutan-7645bf2d485a74e11ae55fe1f281ff68fc49290f.tar.gz
librambutan-7645bf2d485a74e11ae55fe1f281ff68fc49290f.zip
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 <mbolivar@leaflabs.com>
-rw-r--r--libmaple/i2c.c42
-rw-r--r--libmaple/stm32f1/i2c.c36
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);
-}