Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
Revision 306:1f0269907d8b, committed 2014-08-29
- Comitter:
- mbed_official
- Date:
- Fri Aug 29 20:45:07 2014 +0100
- Parent:
- 305:89b9c3a9a045
- Child:
- 307:d33324c3b5a2
- Commit message:
- Synchronized with git revision f304c6ba83591678388024d30440e94781fa8d65
Full URL: https://github.com/mbedmicro/mbed/commit/f304c6ba83591678388024d30440e94781fa8d65/
[NUCLEOs] enhance i2c api
Changed in this revision
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -55,6 +55,9 @@
{NC, NC, 0}
};
+int i2c1_inited = 0;
+int i2c2_inited = 0;
+
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
@@ -63,20 +66,28 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- if (obj->i2c == I2C_1) {
+ // Enable I2C1 clock and pinout if not done
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
- }
- if (obj->i2c == I2C_2) {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
+ // Configure I2C pins
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(scl, OpenDrain);
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pin_mode(sda, OpenDrain);
}
- // Configure I2C pins
- pinmap_pinout(scl, PinMap_I2C_SCL);
- pin_mode(scl, OpenDrain);
- pinmap_pinout(sda, PinMap_I2C_SDA);
- pin_mode(sda, OpenDrain);
+ // Enable I2C2 clock and pinout if not done
+ if ((obj->i2c == I2C_2)&& !i2c2_inited) {
+ i2c2_inited = 1;
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
+ // Configure I2C pins
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(scl, OpenDrain);
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pin_mode(sda, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -90,6 +101,11 @@
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2C_InitTypeDef I2C_InitStructure;
uint32_t tim = 0;
+ int timeout;
+
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Disable the Fast Mode Plus capability
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Enable SYSCFG clock
@@ -260,6 +276,13 @@
}
void i2c_reset(i2c_t *obj) {
+ I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
if (obj->i2c == I2C_1) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F072RB/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F072RB/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -59,6 +59,9 @@
I2C_HandleTypeDef I2cHandle;
+int i2c1_inited = 0;
+int i2c2_inited = 0;
+
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
@@ -67,20 +70,27 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- if (obj->i2c == I2C_1) {
+ // Enable I2C1 clock and pinout if not done
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__I2C1_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
}
- if (obj->i2c == I2C_2) {
+ // Enable I2C2 clock and pinout if not done
+ if ((obj->i2c == I2C_2)&& !i2c2_inited) {
+ i2c2_inited = 1;
__I2C2_CLK_ENABLE();
- }
-
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -91,8 +101,12 @@
void i2c_frequency(i2c_t *obj, int hz) {
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
+ I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
- I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Common settings: I2C clock = 48 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
@@ -274,6 +288,12 @@
}
void i2c_reset(i2c_t *obj) {
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -55,7 +55,13 @@
{NC, NC, 0}
};
+int i2c1_inited = 0;
+int i2c2_inited = 0;
+
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
+ int timeout;
+ I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
+
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
@@ -63,19 +69,25 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- if (obj->i2c == I2C_1) {
+ // Enable I2C clock and configure I2C pins if not done before
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
+ // Configure I2C pins
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(scl, OpenDrain);
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pin_mode(sda, OpenDrain);
}
- if (obj->i2c == I2C_2) {
+ if ((obj->i2c == I2C_2)&& !i2c2_inited) {
+ i2c2_inited = 1;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
- }
-
// Configure I2C pins
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(scl, OpenDrain);
pinmap_pinout(sda, PinMap_I2C_SDA);
pin_mode(sda, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -85,10 +97,17 @@
}
void i2c_frequency(i2c_t *obj, int hz) {
+ int timeout;
+
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2C_InitTypeDef I2C_InitStructure;
if ((hz != 0) && (hz <= 400000)) {
+
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
I2C_DeInit(i2c);
// I2C configuration
@@ -253,6 +272,13 @@
}
void i2c_reset(i2c_t *obj) {
+ I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
if (obj->i2c == I2C_1) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F302R8/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F302R8/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -63,6 +63,10 @@
{NC, NC, 0}
};
+int i2c1_inited = 0;
+int i2c2_inited = 0;
+int i2c3_inited = 0;
+
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
@@ -71,23 +75,39 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- if (obj->i2c == I2C_1) {
+ // Enable I2C1 clock and pinout if not done
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
- }
- if (obj->i2c == I2C_2) {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
- }
- if (obj->i2c == I2C_3) {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);
+ // Configure I2C pins
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(scl, OpenDrain);
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pin_mode(sda, OpenDrain);
}
- // Configure I2C pins
- pinmap_pinout(scl, PinMap_I2C_SCL);
- pin_mode(scl, OpenDrain);
- pinmap_pinout(sda, PinMap_I2C_SDA);
- pin_mode(sda, OpenDrain);
+ // Enable I2C2 clock and pinout if not done
+ if ((obj->i2c == I2C_2)&& !i2c2_inited) {
+ i2c2_inited = 1;
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
+ // Configure I2C pins
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(scl, OpenDrain);
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pin_mode(sda, OpenDrain);
+ }
+
+ // Enable I2C3 clock and pinout if not done
+ if ((obj->i2c == I2C_3)&& !i2c3_inited) {
+ i2c3_inited = 1;
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);
+ // Configure I2C pins
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(scl, OpenDrain);
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pin_mode(sda, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -100,6 +120,11 @@
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2C_InitTypeDef I2C_InitStructure;
uint32_t tim = 0;
+ int timeout;
+
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Disable the Fast Mode Plus capability
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Enable SYSCFG clock
@@ -302,6 +327,13 @@
}
void i2c_reset(i2c_t *obj) {
+ I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
if (obj->i2c == I2C_1) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F334R8/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F334R8/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -57,8 +57,9 @@
I2C_HandleTypeDef I2cHandle;
-void i2c_init(i2c_t *obj, PinName sda, PinName scl)
-{
+int i2c1_inited = 0;
+
+void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
@@ -66,17 +67,17 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- __I2C1_CLK_ENABLE();
-
- // Configure the I2C clock source
- __HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
-
- // Configure I2C pins
- pinmap_pinout(sda, PinMap_I2C_SDA);
- pinmap_pinout(scl, PinMap_I2C_SCL);
- pin_mode(sda, OpenDrain);
- pin_mode(scl, OpenDrain);
+ // Enable I2C1 clock and pinout if not done
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
+ __HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
+ __I2C1_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -92,6 +93,11 @@
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
+
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Update the SystemCoreClock variable.
SystemCoreClockUpdate();
@@ -313,6 +319,12 @@
void i2c_reset(i2c_t *obj)
{
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -60,6 +60,10 @@
I2C_HandleTypeDef I2cHandle;
+int i2c1_inited = 0;
+int i2c2_inited = 0;
+int i2c3_inited = 0;
+
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
@@ -68,22 +72,36 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- if (obj->i2c == I2C_1) {
+ // Enable I2C1 clock and pinout if not done
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
__I2C1_CLK_ENABLE();
- }
- if (obj->i2c == I2C_2) {
- __I2C2_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
}
- if (obj->i2c == I2C_3) {
- __I2C3_CLK_ENABLE();
+ // Enable I2C2 clock and pinout if not done
+ if ((obj->i2c == I2C_2)&& !i2c2_inited) {
+ i2c2_inited = 1;
+ __I2C2_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
}
-
- // Configure I2C pins
- pinmap_pinout(sda, PinMap_I2C_SDA);
- pinmap_pinout(scl, PinMap_I2C_SCL);
- pin_mode(sda, OpenDrain);
- pin_mode(scl, OpenDrain);
+ // Enable I2C3 clock and pinout if not done
+ if ((obj->i2c == I2C_3)&& !i2c3_inited) {
+ i2c3_inited = 1;
+ __I2C3_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -98,6 +116,11 @@
void i2c_frequency(i2c_t *obj, int hz) {
MBED_ASSERT((hz != 0) && (hz <= 400000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
+
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// I2C configuration
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
@@ -285,6 +308,12 @@
}
void i2c_reset(i2c_t *obj) {
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F411RE/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F411RE/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -62,8 +62,11 @@
I2C_HandleTypeDef I2cHandle;
-void i2c_init(i2c_t *obj, PinName sda, PinName scl)
-{
+int i2c1_inited = 0;
+int i2c2_inited = 0;
+int i2c3_inited = 0;
+
+void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
@@ -71,22 +74,36 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- if (obj->i2c == I2C_1) {
+ // Enable I2C1 clock and pinout if not done
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
__I2C1_CLK_ENABLE();
- }
- if (obj->i2c == I2C_2) {
- __I2C2_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
}
- if (obj->i2c == I2C_3) {
- __I2C3_CLK_ENABLE();
+ // Enable I2C2 clock and pinout if not done
+ if ((obj->i2c == I2C_2)&& !i2c2_inited) {
+ i2c2_inited = 1;
+ __I2C2_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
}
-
- // Configure I2C pins
- pinmap_pinout(sda, PinMap_I2C_SDA);
- pinmap_pinout(scl, PinMap_I2C_SCL);
- pin_mode(sda, OpenDrain);
- pin_mode(scl, OpenDrain);
+ // Enable I2C3 clock and pinout if not done
+ if ((obj->i2c == I2C_3)&& !i2c3_inited) {
+ i2c3_inited = 1;
+ __I2C3_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -98,10 +115,14 @@
obj->slave = 0;
}
-void i2c_frequency(i2c_t *obj, int hz)
-{
+void i2c_frequency(i2c_t *obj, int hz) {
MBED_ASSERT((hz != 0) && (hz <= 400000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
+
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// I2C configuration
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
@@ -120,8 +141,7 @@
}
-inline int i2c_start(i2c_t *obj)
-{
+inline int i2c_start(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
@@ -144,8 +164,7 @@
return 0;
}
-inline int i2c_stop(i2c_t *obj)
-{
+inline int i2c_stop(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
@@ -154,8 +173,7 @@
return 0;
}
-int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
-{
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
@@ -205,8 +223,7 @@
return length;
}
-int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
-{
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
@@ -251,8 +268,7 @@
return count;
}
-int i2c_byte_read(i2c_t *obj, int last)
-{
+int i2c_byte_read(i2c_t *obj, int last) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
@@ -275,8 +291,7 @@
return (int)i2c->DR;
}
-int i2c_byte_write(i2c_t *obj, int data)
-{
+int i2c_byte_write(i2c_t *obj, int data) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
@@ -294,8 +309,13 @@
return 1;
}
-void i2c_reset(i2c_t *obj)
-{
+void i2c_reset(i2c_t *obj) {
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
@@ -312,8 +332,7 @@
#if DEVICE_I2CSLAVE
-void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
-{
+void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg = 0;
@@ -327,8 +346,7 @@
i2c->OAR1 = tmpreg;
}
-void i2c_slave_mode(i2c_t *obj, int enable_slave)
-{
+void i2c_slave_mode(i2c_t *obj, int enable_slave) {
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
if (enable_slave) {
obj->slave = 1;
@@ -343,8 +361,7 @@
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
-int i2c_slave_receive(i2c_t *obj)
-{
+int i2c_slave_receive(i2c_t *obj) {
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
@@ -361,8 +378,7 @@
return (retValue);
}
-int i2c_slave_read(i2c_t *obj, char *data, int length)
-{
+int i2c_slave_read(i2c_t *obj, char *data, int length) {
uint32_t Timeout;
int size = 0;
@@ -416,8 +432,7 @@
return size;
}
-int i2c_slave_write(i2c_t *obj, const char *data, int length)
-{
+int i2c_slave_write(i2c_t *obj, const char *data, int length) {
uint32_t Timeout;
int size = 0;
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -60,6 +60,9 @@
I2C_HandleTypeDef I2cHandle;
+int i2c1_inited = 0;
+int i2c2_inited = 0;
+
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
@@ -68,20 +71,27 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- if (obj->i2c == I2C_1) {
+ // Enable I2C1 clock and pinout if not done
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__I2C1_CLK_ENABLE();
- }
- if (obj->i2c == I2C_2) {
- __I2C2_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
}
-
- // Configure I2C pins
- pinmap_pinout(sda, PinMap_I2C_SDA);
- pinmap_pinout(scl, PinMap_I2C_SCL);
- pin_mode(sda, OpenDrain);
- pin_mode(scl, OpenDrain);
+ // Enable I2C2 clock and pinout if not done
+ if ((obj->i2c == I2C_2)&& !i2c2_inited) {
+ i2c2_inited = 1;
+ __I2C2_CLK_ENABLE();
+ // Configure I2C pins
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(sda, OpenDrain);
+ pin_mode(scl, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -93,6 +103,11 @@
void i2c_frequency(i2c_t *obj, int hz) {
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
+
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Common settings: I2C clock = 32 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
@@ -274,6 +289,12 @@
}
void i2c_reset(i2c_t *obj) {
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/i2c_api.c Fri Aug 29 17:15:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/i2c_api.c Fri Aug 29 20:45:07 2014 +0100
@@ -56,6 +56,9 @@
{NC, NC, 0}
};
+int i2c1_inited = 0;
+int i2c2_inited = 0;
+
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
@@ -64,19 +67,27 @@
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
- // Enable I2C clock
- if (obj->i2c == I2C_1) {
+ // Enable I2C1 clock and pinout if not done
+ if ((obj->i2c == I2C_1)&& !i2c1_inited) {
+ i2c1_inited = 1;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
- }
- if (obj->i2c == I2C_2) {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
+ // Configure I2C pins
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(scl, OpenDrain);
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pin_mode(sda, OpenDrain);
}
- // Configure I2C pins
- pinmap_pinout(scl, PinMap_I2C_SCL);
- pin_mode(scl, OpenDrain);
- pinmap_pinout(sda, PinMap_I2C_SDA);
- pin_mode(sda, OpenDrain);
+ // Enable I2C2 clock and pinout if not done
+ if ((obj->i2c == I2C_2)&& !i2c2_inited) {
+ i2c2_inited = 1;
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
+ // Configure I2C pins
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+ pin_mode(scl, OpenDrain);
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pin_mode(sda, OpenDrain);
+ }
// Reset to clear pending flags if any
i2c_reset(obj);
@@ -88,10 +99,15 @@
void i2c_frequency(i2c_t *obj, int hz) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2C_InitTypeDef I2C_InitStructure;
+ int timeout;
if (hz == 0) return;
if (hz > 400000) hz = 400000;
+ // wait before init
+ timeout = LONG_TIMEOUT;
+ while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
/* Warning: To use the I2C at 400 kHz (in fast mode), the PCLK1 frequency
(I2C peripheral input clock) must be a multiple of 10 MHz.
With the actual clock configuration, the max frequency is measured at 296 kHz */
@@ -272,6 +288,13 @@
}
void i2c_reset(i2c_t *obj) {
+ I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
+ int timeout;
+
+ // wait before reset
+ timeout = LONG_TIMEOUT;
+ while((I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY)) && (timeout-- != 0));
+
if (obj->i2c == I2C_1) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
