t

Fork of mbed-dev by mbed official

Revision:
158:b23ee177fd68
Parent:
157:ff67d9f36b67
Child:
160:d5399cc887bb
--- a/targets/TARGET_STM/i2c_api.c	Thu Feb 02 17:01:33 2017 +0000
+++ b/targets/TARGET_STM/i2c_api.c	Tue Feb 14 14:44:10 2017 +0000
@@ -238,6 +238,23 @@
 #endif
 }
 
+void i2c_sw_reset(i2c_t *obj)
+{
+    struct i2c_s *obj_s = I2C_S(obj);
+    I2C_HandleTypeDef *handle = &(obj_s->handle);
+    /*  SW reset procedure:
+     *  PE must be kept low during at least 3 APB clock cycles
+     *  in order to perform the software reset.
+     *  This is ensured by writing the following software sequence:
+     *  - Write PE=0
+     *  - Check PE=0
+     *  - Write PE=1.
+     */
+    handle->Instance->CR1 &=  ~I2C_CR1_PE;
+    while(handle->Instance->CR1 & I2C_CR1_PE);
+    handle->Instance->CR1 |=  I2C_CR1_PE;
+}
+
 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
 
     struct i2c_s *obj_s = I2C_S(obj);
@@ -492,14 +509,12 @@
 int i2c_stop(i2c_t *obj) {
     struct i2c_s *obj_s = I2C_S(obj);
     I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c;
-    I2C_HandleTypeDef *handle = &(obj_s->handle);
-    int timeout;
 
     // Generate the STOP condition
     i2c->CR1 |= I2C_CR1_STOP;
 
     /*  In case of mixed usage of the APIs (unitary + SYNC)
-     *  re-inti HAL state
+     *  re-init HAL state
      */
     if(obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME)
             i2c_init(obj, obj_s->sda, obj_s->scl);
@@ -597,8 +612,14 @@
      * to know when we need to prepare next start */
     handle->Instance->CR2 &=  ~I2C_CR2_SADD;
 
+    /*
+     * V2 IP is meant for automatic STOP, not user STOP
+     * SW reset the IP state machine before next transaction
+     */
+    i2c_sw_reset(obj);
+
     /*  In case of mixed usage of the APIs (unitary + SYNC)
-     *  re-inti HAL state */
+     *  re-init HAL state */
     if (obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME) {
         i2c_init(obj, obj_s->sda, obj_s->scl);
     }