mbed library sources
Fork of mbed-src by
Revision 305:1f0269907d8b, committed 2014-08-29
- Comitter:
- mbed_official
- Date:
- Fri Aug 29 20:45:07 2014 +0100
- Parent:
- 304:89b9c3a9a045
- Child:
- 306: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);