diff --git a/targets/TARGET_STM/i2c_api.c b/targets/TARGET_STM/i2c_api.c index 2c2dbb59510..c25171d577c 100644 --- a/targets/TARGET_STM/i2c_api.c +++ b/targets/TARGET_STM/i2c_api.c @@ -186,6 +186,48 @@ uint32_t i2c_get_irq_handler(i2c_t *obj) return handler; } +void i2c_hw_reset(i2c_t *obj) { + int timeout; + struct i2c_s *obj_s = I2C_S(obj); + I2C_HandleTypeDef *handle = &(obj_s->handle); + + handle->Instance = (I2C_TypeDef *)(obj_s->i2c); + + // wait before reset + timeout = BYTE_TIMEOUT; + while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BUSY)) && (--timeout != 0)); +#if defined I2C1_BASE + if (obj_s->i2c == I2C_1) { + __HAL_RCC_I2C1_FORCE_RESET(); + __HAL_RCC_I2C1_RELEASE_RESET(); + } +#endif +#if defined I2C2_BASE + if (obj_s->i2c == I2C_2) { + __HAL_RCC_I2C2_FORCE_RESET(); + __HAL_RCC_I2C2_RELEASE_RESET(); + } +#endif +#if defined I2C3_BASE + if (obj_s->i2c == I2C_3) { + __HAL_RCC_I2C3_FORCE_RESET(); + __HAL_RCC_I2C3_RELEASE_RESET(); + } +#endif +#if defined I2C4_BASE + if (obj_s->i2c == I2C_4) { + __HAL_RCC_I2C4_FORCE_RESET(); + __HAL_RCC_I2C4_RELEASE_RESET(); + } +#endif +#if defined FMPI2C1_BASE + if (obj_s->i2c == FMPI2C_1) { + __HAL_RCC_FMPI2C1_FORCE_RESET(); + __HAL_RCC_FMPI2C1_RELEASE_RESET(); + } +#endif +} + void i2c_init(i2c_t *obj, PinName sda, PinName scl) { struct i2c_s *obj_s = I2C_S(obj); @@ -203,6 +245,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Enable I2C1 clock and pinout if not done if (obj_s->i2c == I2C_1) { obj_s->index = 0; + __HAL_RCC_I2C1_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); @@ -210,13 +253,13 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { pin_mode(scl, PullUp); obj_s->event_i2cIRQ = I2C1_EV_IRQn; obj_s->error_i2cIRQ = I2C1_ER_IRQn; - __HAL_RCC_I2C1_CLK_ENABLE(); } #endif #if defined I2C2_BASE // Enable I2C2 clock and pinout if not done if (obj_s->i2c == I2C_2) { obj_s->index = 1; + __HAL_RCC_I2C2_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); @@ -224,13 +267,13 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { pin_mode(scl, PullUp); obj_s->event_i2cIRQ = I2C2_EV_IRQn; obj_s->error_i2cIRQ = I2C2_ER_IRQn; - __HAL_RCC_I2C2_CLK_ENABLE(); } #endif #if defined I2C3_BASE // Enable I2C3 clock and pinout if not done if (obj_s->i2c == I2C_3) { obj_s->index = 2; + __HAL_RCC_I2C3_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); @@ -238,13 +281,13 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { pin_mode(scl, PullUp); obj_s->event_i2cIRQ = I2C3_EV_IRQn; obj_s->error_i2cIRQ = I2C3_ER_IRQn; - __HAL_RCC_I2C3_CLK_ENABLE(); } #endif #if defined I2C4_BASE // Enable I2C3 clock and pinout if not done if (obj_s->i2c == I2C_4) { obj_s->index = 3; + __HAL_RCC_I2C4_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); @@ -252,13 +295,13 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { pin_mode(scl, PullUp); obj_s->event_i2cIRQ = I2C4_EV_IRQn; obj_s->error_i2cIRQ = I2C4_ER_IRQn; - __HAL_RCC_I2C4_CLK_ENABLE(); } #endif #if defined FMPI2C1_BASE // Enable I2C3 clock and pinout if not done if (obj_s->i2c == FMPI2C_1) { obj_s->index = 4; + __HAL_RCC_FMPI2C1_CLK_ENABLE(); // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); @@ -266,16 +309,16 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { pin_mode(scl, PullUp); obj_s->event_i2cIRQ = FMPI2C1_EV_IRQn; obj_s->error_i2cIRQ = FMPI2C1_ER_IRQn; - __HAL_RCC_FMPI2C1_CLK_ENABLE(); } #endif - // Reset to clear pending flags if any - i2c_reset(obj); - // I2C configuration + // Default hz value used for timeout computation if(!obj_s->hz) obj_s->hz = 100000; // 100 kHz per default + + // Reset to clear pending flags if any + i2c_hw_reset(obj); i2c_frequency(obj, obj_s->hz ); #if DEVICE_I2CSLAVE @@ -387,49 +430,6 @@ i2c_t *get_i2c_obj(I2C_HandleTypeDef *hi2c){ return (obj); } -void i2c_reset(i2c_t *obj) { - - int timeout; - struct i2c_s *obj_s = I2C_S(obj); - I2C_HandleTypeDef *handle = &(obj_s->handle); - - handle->Instance = (I2C_TypeDef *)(obj_s->i2c); - - // wait before reset - timeout = BYTE_TIMEOUT; - while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BUSY)) && (--timeout != 0)); -#if defined I2C1_BASE - if (obj_s->i2c == I2C_1) { - __HAL_RCC_I2C1_FORCE_RESET(); - __HAL_RCC_I2C1_RELEASE_RESET(); - } -#endif -#if defined I2C2_BASE - if (obj_s->i2c == I2C_2) { - __HAL_RCC_I2C2_FORCE_RESET(); - __HAL_RCC_I2C2_RELEASE_RESET(); - } -#endif -#if defined I2C3_BASE - if (obj_s->i2c == I2C_3) { - __HAL_RCC_I2C3_FORCE_RESET(); - __HAL_RCC_I2C3_RELEASE_RESET(); - } -#endif -#if defined I2C4_BASE - if (obj_s->i2c == I2C_4) { - __HAL_RCC_I2C4_FORCE_RESET(); - __HAL_RCC_I2C4_RELEASE_RESET(); - } -#endif -#if defined FMPI2C1_BASE - if (obj_s->i2c == FMPI2C_1) { - __HAL_RCC_FMPI2C1_FORCE_RESET(); - __HAL_RCC_FMPI2C1_RELEASE_RESET(); - } -#endif -} - /* SYNCHRONOUS API FUNCTIONS */ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { @@ -662,6 +662,14 @@ int i2c_byte_write(i2c_t *obj, int data) { } #endif //I2C_IP_VERSION_V2 +void i2c_reset(i2c_t *obj) { + struct i2c_s *obj_s = I2C_S(obj); + /* As recommended in i2c_api.h, mainly send stop */ + i2c_stop(obj); + /* then re-init */ + i2c_init(obj, obj_s->sda, obj_s->scl); +} + /* * SYNC APIS */