mbed

Fork of mbed-dev by mbed official

Revision:
154:37f96f9d4de2
Parent:
153:fa9ff456f731
Child:
156:95d6b41a828b
--- a/targets/TARGET_STM/i2c_api.c	Tue Dec 20 17:27:56 2016 +0000
+++ b/targets/TARGET_STM/i2c_api.c	Wed Jan 04 16:58:05 2017 +0000
@@ -38,8 +38,6 @@
 #include "cmsis.h"
 #include "pinmap.h"
 #include "PeripheralPins.h"
-/*  F1 HAL not ready to move to I2C common code - this is ongoing */
-#if !defined(__STM32F1xx_HAL_H)
 #include "i2c_device.h" // family specific defines
 
 #ifndef DEBUG_STDIO
@@ -442,60 +440,6 @@
     return (obj);
 }
 
-/* SYNCHRONOUS API FUNCTIONS */
-
-int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
-    struct i2c_s *obj_s = I2C_S(obj);
-    I2C_HandleTypeDef *handle = &(obj_s->handle);
-    int count = 0, ret = 0;
-    uint32_t timeout = 0;
-
-    if ((obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) ||
-        (obj_s->XferOperation == I2C_LAST_FRAME)) {
-        if (stop)
-            obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
-        else
-            obj_s->XferOperation = I2C_FIRST_FRAME;
-    } else if ((obj_s->XferOperation == I2C_FIRST_FRAME) ||
-        (obj_s->XferOperation == I2C_NEXT_FRAME)) {
-        if (stop)
-            obj_s->XferOperation = I2C_LAST_FRAME;
-        else
-            obj_s->XferOperation = I2C_NEXT_FRAME;
-    }
-
-    obj_s->event = 0;
-
-     /* Activate default IRQ handlers for sync mode
-     * which would be overwritten in async mode
-     */
-    i2c_ev_err_enable(obj, i2c_get_irq_handler(obj));
-
-    ret = HAL_I2C_Master_Sequential_Receive_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation);
-
-    if(ret == HAL_OK) {
-        timeout = BYTE_TIMEOUT_US * length;
-        /*  transfer started : wait completion or timeout */
-        while(!(obj_s->event & I2C_EVENT_ALL) && (--timeout != 0)) {
-            wait_us(1);
-        }
-
-        i2c_ev_err_disable(obj);
-
-        if((timeout == 0) || (obj_s->event != I2C_EVENT_TRANSFER_COMPLETE)) {
-            DEBUG_PRINTF(" TIMEOUT or error in i2c_read\r\n");
-            /* re-init IP to try and get back in a working state */
-            i2c_init(obj, obj_s->sda, obj_s->scl);
-        } else {
-            count = length;
-        }
-    } else {
-        DEBUG_PRINTF("ERROR in i2c_read\r\n");
-    }
-
-    return count;
-}
-
 /*
  *  UNITARY APIS.
  *  For very basic operations, direct registers access is needed
@@ -537,10 +481,18 @@
 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
+     */
+    if(obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME)
+            i2c_init(obj, obj_s->sda, obj_s->scl);
+
     return 0;
 }
 
@@ -685,12 +637,78 @@
 /*
  *  SYNC APIS
  */
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
+    struct i2c_s *obj_s = I2C_S(obj);
+    I2C_HandleTypeDef *handle = &(obj_s->handle);
+    int count = I2C_ERROR_BUS_BUSY, ret = 0;
+    uint32_t timeout = 0;
+
+    if((length == 0) || (data == 0)) {
+        if(HAL_I2C_IsDeviceReady(handle, address, 1, 10) == HAL_OK)
+            return 0;
+        else
+            return I2C_ERROR_BUS_BUSY;
+    }
+
+    if ((obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) ||
+        (obj_s->XferOperation == I2C_LAST_FRAME)) {
+        if (stop)
+            obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
+        else
+            obj_s->XferOperation = I2C_FIRST_FRAME;
+    } else if ((obj_s->XferOperation == I2C_FIRST_FRAME) ||
+        (obj_s->XferOperation == I2C_NEXT_FRAME)) {
+        if (stop)
+            obj_s->XferOperation = I2C_LAST_FRAME;
+        else
+            obj_s->XferOperation = I2C_NEXT_FRAME;
+    }
+
+    obj_s->event = 0;
+
+     /* Activate default IRQ handlers for sync mode
+     * which would be overwritten in async mode
+     */
+    i2c_ev_err_enable(obj, i2c_get_irq_handler(obj));
+
+    ret = HAL_I2C_Master_Sequential_Receive_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation);
+
+    if(ret == HAL_OK) {
+        timeout = BYTE_TIMEOUT_US * (length + 1);
+        /*  transfer started : wait completion or timeout */
+        while(!(obj_s->event & I2C_EVENT_ALL) && (--timeout != 0)) {
+            wait_us(1);
+        }
+
+        i2c_ev_err_disable(obj);
+
+        if((timeout == 0) || (obj_s->event != I2C_EVENT_TRANSFER_COMPLETE)) {
+            DEBUG_PRINTF(" TIMEOUT or error in i2c_read\r\n");
+            /* re-init IP to try and get back in a working state */
+            i2c_init(obj, obj_s->sda, obj_s->scl);
+        } else {
+            count = length;
+        }
+    } else {
+        DEBUG_PRINTF("ERROR in i2c_read:%d\r\n", ret);
+    }
+
+    return count;
+}
+
 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
     struct i2c_s *obj_s = I2C_S(obj);
     I2C_HandleTypeDef *handle = &(obj_s->handle);
-    int count = 0, ret = 0;
+    int count = I2C_ERROR_BUS_BUSY, ret = 0;
     uint32_t timeout = 0;
 
+    if((length == 0) || (data == 0)) {
+        if(HAL_I2C_IsDeviceReady(handle, address, 1, 10) == HAL_OK)
+            return 0;
+        else
+            return I2C_ERROR_BUS_BUSY;
+    }
+
     if ((obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) ||
         (obj_s->XferOperation == I2C_LAST_FRAME)) {
         if (stop)
@@ -712,7 +730,7 @@
     ret = HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation); 
 
     if(ret == HAL_OK) {
-        timeout = BYTE_TIMEOUT_US * length;
+        timeout = BYTE_TIMEOUT_US * (length + 1);
         /*  transfer started : wait completion or timeout */
         while(!(obj_s->event & I2C_EVENT_ALL) && (--timeout != 0)) {
             wait_us(1);
@@ -891,7 +909,7 @@
     ret = HAL_I2C_Slave_Sequential_Receive_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME);
 
     if(ret == HAL_OK) {
-        timeout = BYTE_TIMEOUT_US * length;
+        timeout = BYTE_TIMEOUT_US * (length + 1);
         while(obj_s->pending_slave_rx_maxter_tx && (--timeout != 0)) {
             wait_us(1);
         }
@@ -916,7 +934,7 @@
     ret = HAL_I2C_Slave_Sequential_Transmit_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME);
 
     if(ret == HAL_OK) {
-        timeout = BYTE_TIMEOUT_US * length;
+        timeout = BYTE_TIMEOUT_US * (length + 1);
         while(obj_s->pending_slave_tx_master_rx && (--timeout != 0)) {
             wait_us(1);
         }
@@ -1048,6 +1066,4 @@
 
 #endif // DEVICE_I2C_ASYNCH
 
-#endif // STM32F1
-
 #endif // DEVICE_I2C