mbed w/ spi bug fig

Dependents:   display-puck

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Wed May 21 15:00:07 2014 +0100
Parent:
201:fa203361dc70
Child:
203:0f54f988aa69
Commit message:
Synchronized with git revision b94c8a221b8b7db227cfd749fb637c0ee27e986b

Full URL: https://github.com/mbedmicro/mbed/commit/b94c8a221b8b7db227cfd749fb637c0ee27e986b/

[NUCLEO_L053R8] enhance I2C master (stop) and add I2C slave

Changed in this revision

targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/device.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/i2c_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/device.h	Wed May 21 10:30:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/device.h	Wed May 21 15:00:07 2014 +0100
@@ -42,7 +42,7 @@
 #define DEVICE_SERIAL           1
 
 #define DEVICE_I2C              1
-#define DEVICE_I2CSLAVE         0 // Not supported yet
+#define DEVICE_I2CSLAVE         1
 
 #define DEVICE_SPI              1
 #define DEVICE_SPISLAVE         0 // Not supported yet
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/i2c_api.c	Wed May 21 10:30:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_L053R8/i2c_api.c	Wed May 21 15:00:07 2014 +0100
@@ -154,43 +154,102 @@
 }
 
 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;
+    int count;
+    int value;
+
     if (length == 0) return 0;
 
-    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+    /* update CR2 register */
+    i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
+             | (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16 ) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
+            
+    // Read all bytes
+    for (count = 0; count < length; count++) {
+        value = i2c_byte_read(obj, 0);
+        data[count] = (char)value;
+    }
 
-    // Reception process with 5 seconds timeout
-    if (HAL_I2C_Master_Receive(&I2cHandle, (uint16_t)address, (uint8_t *)data, length, 5000) != HAL_OK) {
-        return 0; // Error
+    // Wait transfer complete
+    timeout = FLAG_TIMEOUT;
+    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
+        timeout--;
+        if (timeout == 0) {
+            return 0;
+        }
+    }
+    __HAL_I2C_CLEAR_FLAG(&I2cHandle,I2C_FLAG_TC);
+
+    // If not repeated start, send stop.
+    if (stop) {
+        i2c_stop(obj);
+        /* Wait until STOPF flag is set */
+        timeout = FLAG_TIMEOUT;
+        while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
+            timeout--;
+            if (timeout == 0) {
+                return 0;
+            }
+        }
+        /* Clear STOP Flag */
+        __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
     }
 
     return length;
 }
 
 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;
+    int count;
+
     if (length == 0) return 0;
 
-    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+    /* update CR2 register */
+    i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
+             | (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16 ) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
+   
 
-    // Transmission process with 5 seconds timeout
-    if (HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)address, (uint8_t *)data, length, 5000) != HAL_OK) {
-        return 0; // Error
+    
+    for (count = 0; count < length; count++) {
+        i2c_byte_write(obj, data[count]);
     }
 
-    return length;
+    // Wait transfer complete
+    timeout = FLAG_TIMEOUT;
+    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
+        timeout--;
+        if (timeout == 0) {
+            return 0;
+    }
+    }
+    __HAL_I2C_CLEAR_FLAG(&I2cHandle,I2C_FLAG_TC);
+
+    // If not repeated start, send stop.
+    if (stop) {
+        i2c_stop(obj);
+        /* Wait until STOPF flag is set */
+        timeout = FLAG_TIMEOUT;
+        while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
+            timeout--;
+            if (timeout == 0) {
+                return 0;
+            }
+        }
+        /* Clear STOP Flag */
+        __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
+    }
+
+    return count;
 }
 
 int i2c_byte_read(i2c_t *obj, int last) {
     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
     int timeout;
 
-    if (last) {
-        // Don't acknowledge the last byte
-        i2c->CR2 &= ~I2C_CR2_NACK;
-    } else {
-        // Acknowledge the byte
-        i2c->CR2 |= I2C_CR2_NACK;
-    }
-
     // Wait until the byte is received
     timeout = FLAG_TIMEOUT;
     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
@@ -206,16 +265,16 @@
     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
     int timeout;
 
-    i2c->TXDR = (uint8_t)data;
-
-    // Wait until the byte is transmitted
+    // Wait until the previous byte is transmitted
     timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
+    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
         if ((timeout--) == 0) {
             return 0;
         }
     }
 
+    i2c->TXDR = (uint8_t)data;
+    
     return 1;
 }
 
@@ -237,7 +296,7 @@
     uint16_t tmpreg;
 
     // disable
-    i2c->OAR1 &= (uin32_t)(~I2C_OAR1_OA1EN);
+    i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
     // Get the old register value
     tmpreg = i2c->OAR1;
     // Reset address bits
@@ -262,7 +321,7 @@
     if (enable_slave == 1) {
         tmpreg |= I2C_OAR1_OA1EN;
     } else {
-        tmpreg &= (uin32_t)(~I2C_OAR1_OA1EN);
+        tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
     }
 
     // Set new mode
@@ -277,8 +336,7 @@
 #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
 
 int i2c_slave_receive(i2c_t *obj) {
-    I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
-    char address;
+    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
     int retValue = NoData;
 
     if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
@@ -295,25 +353,21 @@
 }
 
 int i2c_slave_read(i2c_t *obj, char *data, int length) {
+    char size = 0;
+  
     if (length == 0) return 0;
 
-    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
+    while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
 
-    // Reception process with 5 seconds timeout
-    if (HAL_I2C_Slave_Receive(&I2cHandle, (uint8_t *)data, length, 5000) != HAL_OK) {
-        return 0; // Error
-    }
-
-    return length;
+    return size;
 }
 
 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
     char size = 0;
+    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
 
     if (length == 0) return 0;
 
-    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
-
     do {
         i2c_byte_write(obj, data[size]);
         size++;