diff options
author | Marti Bolivar <mbolivar@leaflabs.com> | 2012-06-20 14:28:32 -0400 |
---|---|---|
committer | Marti Bolivar <mbolivar@leaflabs.com> | 2012-06-22 14:06:09 -0400 |
commit | c61a99d053d5ea230e41efe11772bac12ca2d51a (patch) | |
tree | d3bd2c1b60de5e13a2df65b38547b588279f92a7 | |
parent | 2fa8bdb7509e81789e76ca95e8b537272ce95ad5 (diff) | |
download | librambutan-c61a99d053d5ea230e41efe11772bac12ca2d51a.tar.gz librambutan-c61a99d053d5ea230e41efe11772bac12ca2d51a.zip |
i2c_set_input_clk(): fix an F1-ism.
i2c_set_input_clk()'s documentation says that the maximum peripheral
clock frequency is 36 MHz, but that's a hard-coded magic number. The
actual limit is the device's APB frequency or 46 MHz, whichever is
lower (F2 and F4 share the 46 MHz limit).
Fix the documentation to reflect that fact, and add an internal
series-provided function to get the maximum clock frequency for a
device. To help users porting to F2, have i2c_set_input_clk()
assert-check that the provided frequency is less than that maximum
value and the hard 46 MHz limit.
Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
-rw-r--r-- | libmaple/include/libmaple/i2c.h | 17 | ||||
-rw-r--r-- | libmaple/stm32f1/include/series/i2c.h | 10 |
2 files changed, 26 insertions, 1 deletions
diff --git a/libmaple/include/libmaple/i2c.h b/libmaple/include/libmaple/i2c.h index d327c72..6d1fadf 100644 --- a/libmaple/include/libmaple/i2c.h +++ b/libmaple/include/libmaple/i2c.h @@ -37,6 +37,15 @@ extern "C" { #endif +/* + * Series header must provide: + * + * - uint32 _i2c_bus_clk(i2c_dev*): Clock frequency of dev's bus, in + * MHz. (This is for internal use only). + * + * - Reg. map base pointers, device pointer declarations. + */ + #include <series/i2c.h> #include <libmaple/i2c_common.h> @@ -212,13 +221,19 @@ static inline void i2c_write(i2c_dev *dev, uint8 byte) { /** * @brief Set input clock frequency, in MHz * @param dev I2C device - * @param freq Frequency in megahertz (2-36) + * @param freq Frequency, in MHz. This must be at least 2, and at most + * the APB frequency of dev's bus. (For example, if + * rcc_dev_clk(dev) == RCC_APB1, freq must be at most + * PCLK1, in MHz). There is an additional limit of 46 MHz. */ static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) { +#define I2C_MAX_FREQ_MHZ 46 + ASSERT(2 <= freq && freq <= _i2c_bus_clk(dev) && freq <= I2C_MAX_FREQ_MHZ); uint32 cr2 = dev->regs->CR2; cr2 &= ~I2C_CR2_FREQ; cr2 |= freq; dev->regs->CR2 = freq; +#undef I2C_MAX_FREQ_MHZ } /** diff --git a/libmaple/stm32f1/include/series/i2c.h b/libmaple/stm32f1/include/series/i2c.h index f9f1e43..0c89df4 100644 --- a/libmaple/stm32f1/include/series/i2c.h +++ b/libmaple/stm32f1/include/series/i2c.h @@ -34,6 +34,7 @@ #define _LIBMAPLE_STM32F1_I2C_H_ #include <libmaple/i2c_common.h> +#include <libmaple/stm32.h> /* * Register maps @@ -53,4 +54,13 @@ struct i2c_reg_map; extern i2c_dev* const I2C1; extern i2c_dev* const I2C2; +/* + * For internal use + */ + +static inline uint32 _i2c_bus_clk(i2c_dev *dev) { + /* Both I2C peripherals are on APB1 */ + return STM32_PCLK1 / (1000 * 1000); +} + #endif /* _LIBMAPLE_STM32F1_I2C_H_ */ |