aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmaple/i2c.c37
-rw-r--r--libmaple/i2c_private.h4
-rw-r--r--libmaple/stm32f1/i2c.c36
3 files changed, 44 insertions, 33 deletions
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 <libmaple/libmaple.h>
#include <libmaple/rcc.h>
#include <libmaple/gpio.h>
@@ -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);
+}