mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Mon Feb 22 13:15:10 2016 +0000
Parent:
68:59749b18b9de
Child:
70:885f1c2f67b1
Commit message:
Synchronized with git revision 028465a9b8e42300bf0eb1b362f8f474f40fae9b

Full URL: https://github.com/mbedmicro/mbed/commit/028465a9b8e42300bf0eb1b362f8f474f40fae9b/

Use only the index, not the UARTName any more.
In case of app with 2 serial (using DMA) + 1 serial (stdio), we have found a bug. The dma handler is overwritten by the last initialized serial object.
Therefore read and write functions did not work anymore.
We have reworked this file to save 1 handler per UART IP, and align it with MBED OS file.
Tests have been passed. Same status as before (OK except MBED_37, manual test for SERIAL_ASYNC also OK).

Changed in this revision

targets/hal/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/objects.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F4/serial_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/objects.h	Mon Feb 22 11:15:09 2016 +0000
+++ b/targets/hal/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/objects.h	Mon Feb 22 13:15:10 2016 +0000
@@ -66,8 +66,7 @@
 };
 
 struct serial_s {
-    UARTName uart;
-    int index; // Used by irq
+    int index;
     uint32_t baudrate;
     uint32_t databits;
     uint32_t stopbits;
--- a/targets/hal/TARGET_STM/TARGET_STM32F4/serial_api.c	Mon Feb 22 11:15:09 2016 +0000
+++ b/targets/hal/TARGET_STM/TARGET_STM32F4/serial_api.c	Mon Feb 22 13:15:10 2016 +0000
@@ -27,7 +27,13 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *******************************************************************************
  */
+#ifdef YOTTA_CFG_MBED_OS
+#include "target_config.h"
+#include "uvisor-lib/uvisor-lib.h"
+#include "mbed-drivers/mbed_assert.h"
+#else
 #include "mbed_assert.h"
+#endif
 #include "serial_api.h"
 
 #if DEVICE_SERIAL
@@ -36,25 +42,53 @@
 #include "pinmap.h"
 #include <string.h>
 #include "PeripheralPins.h"
+#ifdef YOTTA_CFG_MBED_OS
+#include "mbed-drivers/mbed_error.h"
+#else
 #include "mbed_error.h"
+#endif
+
+#define DEBUG_STDIO 0
+
+#ifndef DEBUG_STDIO
+#   define DEBUG_STDIO 0
+#endif
+
+#if DEBUG_STDIO
+#   include <stdio.h>
+#   define DEBUG_PRINTF(...) do { printf(__VA_ARGS__); } while(0)
+#else
+#   define DEBUG_PRINTF(...) {}
+#endif
 
 #define UART_NUM (8)
 #define UART_STATE_RX_ACTIVE 0x20
 #define UART_STATE_TX_ACTIVE 0x10
 
-static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0, 0, 0, 0, 0};
+#if DEVICE_SERIAL_ASYNCH_DMA
+static const uint32_t DMA_UartRx_Channel[UART_NUM] = {DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, \
+                                                      DMA_CHANNEL_4, DMA_CHANNEL_5, DMA_CHANNEL_5, DMA_CHANNEL_5};
+DMA_Stream_TypeDef *DMA_UartRx_Stream[UART_NUM] = {
+  DMA2_Stream5, DMA1_Stream5, DMA1_Stream1, \
+  DMA1_Stream2, DMA1_Stream0, DMA2_Stream1, \
+  DMA1_Stream3, DMA1_Stream6
+};
+static const uint32_t DMA_UartTx_Channel[UART_NUM] = {DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, \
+                                                      DMA_CHANNEL_4, DMA_CHANNEL_5, DMA_CHANNEL_5, DMA_CHANNEL_5};
+DMA_Stream_TypeDef *DMA_UartTx_Stream[UART_NUM] = {
+    DMA2_Stream7, DMA1_Stream6, DMA1_Stream3, \
+    DMA1_Stream4, DMA1_Stream7, DMA2_Stream6,\
+    DMA1_Stream1, DMA1_Stream0
+};
+DMA_HandleTypeDef DmaHandle;
+#endif
 
-#if DEVICE_SERIAL_ASYNCH_DMA
-static const uint32_t DMA_UartRx_Channel[UART_NUM] = {DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_5, DMA_CHANNEL_5, DMA_CHANNEL_5};
-static const uint32_t DMA_UartRx_Stream[UART_NUM]  = {(uint32_t)DMA2_Stream5, (uint32_t) DMA1_Stream5, (uint32_t) DMA1_Stream1, (uint32_t) DMA1_Stream2, (uint32_t) DMA1_Stream0, (uint32_t) DMA2_Stream5, (uint32_t) DMA1_Stream3, (uint32_t) DMA1_Stream6};
-static const uint32_t DMA_UartTx_Channel[UART_NUM] = {DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_5, DMA_CHANNEL_5, DMA_CHANNEL_5};
-static const uint32_t DMA_UartTx_Stream[UART_NUM]  = {(uint32_t)DMA2_Stream7, (uint32_t) DMA1_Stream6, (uint32_t) DMA1_Stream3, (uint32_t) DMA1_Stream4, (uint32_t) DMA1_Stream7, (uint32_t) DMA2_Stream6, (uint32_t) DMA1_Stream1, (uint32_t) DMA1_Stream0};
-
-#endif
+uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0, 0, 0, 0, 0};
 static uart_irq_handler irq_handler;
 
-DMA_HandleTypeDef DmaHandle;
-UART_HandleTypeDef UartHandle;
+static DMA_HandleTypeDef DmaTxHandle[UART_NUM];
+static DMA_HandleTypeDef DmaRxHandle[UART_NUM];
+static UART_HandleTypeDef UartHandle[UART_NUM];
 
 int stdio_uart_inited = 0;
 serial_t stdio_uart;
@@ -65,81 +99,91 @@
 #define SERIAL_OBJ(X) (obj->X)
 #endif
 
-static void init_uart(serial_t *obj)
+static void init_uart(serial_t *obj, UARTName instance)
 {
-#if DEVICE_SERIAL_ASYNCH_DMA
-    static DMA_HandleTypeDef hdma_tx;
-    static DMA_HandleTypeDef hdma_rx;
-#endif
 
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
+    handle->Instance = (USART_TypeDef *)instance;
 
-    UartHandle.Init.BaudRate     = SERIAL_OBJ(baudrate);
-    UartHandle.Init.WordLength   = SERIAL_OBJ(databits);
-    UartHandle.Init.StopBits     = SERIAL_OBJ(stopbits);
-    UartHandle.Init.Parity       = SERIAL_OBJ(parity);
+    handle->Init.BaudRate     = SERIAL_OBJ(baudrate);
+    handle->Init.WordLength   = SERIAL_OBJ(databits);
+    handle->Init.StopBits     = SERIAL_OBJ(stopbits);
+    handle->Init.Parity       = SERIAL_OBJ(parity);
 #if DEVICE_SERIAL_FC
-    UartHandle.Init.HwFlowCtl    = SERIAL_OBJ(hw_flow_ctl);
+    handle->Init.HwFlowCtl    = SERIAL_OBJ(hw_flow_ctl);
 #else
-    UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
+    handle->Init.HwFlowCtl    = UART_HWCONTROL_NONE;
 #endif
-    UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
+    handle->Init.OverSampling = UART_OVERSAMPLING_16;
+    handle->TxXferCount         = 0;
+    handle->RxXferCount         = 0;
 
     if (SERIAL_OBJ(pin_rx) == NC) {
-        UartHandle.Init.Mode = UART_MODE_TX;
+      handle->Init.Mode = UART_MODE_TX;
     } else if (SERIAL_OBJ(pin_tx) == NC) {
-        UartHandle.Init.Mode = UART_MODE_RX;
+      handle->Init.Mode = UART_MODE_RX;
     } else {
-        UartHandle.Init.Mode = UART_MODE_TX_RX;
+      handle->Init.Mode = UART_MODE_TX_RX;
     }
+    
+#ifdef YOTTA_CFG_MBED_OS
+    if (SERIAL_OBJ(pin_tx) == STDIO_UART_TX && SERIAL_OBJ(pin_rx) == STDIO_UART_RX) {
+        handle->Init.BaudRate = YOTTA_CFG_MBED_OS_STDIO_DEFAULT_BAUD;
+    }
+#endif
+    
 #if DEVICE_SERIAL_ASYNCH_DMA
     if (SERIAL_OBJ(pin_tx) != NC) {
         // set DMA in the UartHandle
+        DMA_HandleTypeDef *hdma_tx = &DmaTxHandle[SERIAL_OBJ(index)];
         /* Configure the DMA handler for Transmission process */
-        hdma_tx.Instance                 = (DMA_Stream_TypeDef *)DMA_UartTx_Stream[SERIAL_OBJ(index)];
-        hdma_tx.Init.Channel             = DMA_UartTx_Channel[SERIAL_OBJ(index)];
-        hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
-        hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
-        hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
-        hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
-        hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
-        hdma_tx.Init.Mode                = DMA_NORMAL;
-        hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
-        hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
-        hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
-        hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
-        hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
+        hdma_tx->Instance                 = (DMA_Stream_TypeDef *)DMA_UartTx_Stream[SERIAL_OBJ(index)];
+        hdma_tx->Init.Channel             = DMA_UartTx_Channel[SERIAL_OBJ(index)];
+        hdma_tx->Init.Direction           = DMA_MEMORY_TO_PERIPH;
+        hdma_tx->Init.PeriphInc           = DMA_PINC_DISABLE;
+        hdma_tx->Init.MemInc              = DMA_MINC_ENABLE;
+        hdma_tx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+        hdma_tx->Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+        hdma_tx->Init.Mode                = DMA_NORMAL;
+        hdma_tx->Init.Priority            = DMA_PRIORITY_LOW;
+        hdma_tx->Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+        hdma_tx->Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+        hdma_tx->Init.MemBurst            = DMA_MBURST_INC4;
+        hdma_tx->Init.PeriphBurst         = DMA_PBURST_INC4;
 
-        HAL_DMA_Init(&hdma_tx);
+        HAL_DMA_Init(hdma_tx);
 
         /* Associate the initialized DMA handle to the UART handle */
-        __HAL_LINKDMA(&UartHandle, hdmatx, hdma_tx);
+        handle->hdmatx = hdma_tx;
+        hdma_tx->Parent = handle;
     }
     
     if (SERIAL_OBJ(pin_rx) != NC) {
         /* Configure the DMA handler for reception process */
-        hdma_rx.Instance                 = (DMA_Stream_TypeDef *)DMA_UartRx_Stream[SERIAL_OBJ(index)];
-        hdma_rx.Init.Channel             = DMA_UartRx_Channel[SERIAL_OBJ(index)];
-        hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
-        hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
-        hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
-        hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
-        hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
-        hdma_rx.Init.Mode                = DMA_NORMAL;
-        hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
-        hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
-        hdma_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
-        hdma_rx.Init.MemBurst            = DMA_MBURST_INC4;
-        hdma_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
+        DMA_HandleTypeDef *hdma_rx = &DmaRxHandle[SERIAL_OBJ(index)];
+        hdma_rx->Instance                 = (DMA_Stream_TypeDef *)DMA_UartRx_Stream[SERIAL_OBJ(index)];
+        hdma_rx->Init.Channel             = DMA_UartRx_Channel[SERIAL_OBJ(index)];
+        hdma_rx->Init.Direction           = DMA_PERIPH_TO_MEMORY;
+        hdma_rx->Init.PeriphInc           = DMA_PINC_DISABLE;
+        hdma_rx->Init.MemInc              = DMA_MINC_ENABLE;
+        hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+        hdma_rx->Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+        hdma_rx->Init.Mode                = DMA_NORMAL;
+        hdma_rx->Init.Priority            = DMA_PRIORITY_HIGH;
+        hdma_rx->Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+        hdma_rx->Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+        hdma_rx->Init.MemBurst            = DMA_MBURST_INC4;
+        hdma_rx->Init.PeriphBurst         = DMA_PBURST_INC4;
 
-        HAL_DMA_Init(&hdma_rx);
+        HAL_DMA_Init(hdma_rx);
 
         /* Associate the initialized DMA handle to the UART handle */
-        __HAL_LINKDMA(&UartHandle, hdmarx, hdma_rx);
+        handle->hdmarx = hdma_rx;
+        hdma_rx->Parent = handle;
     }
 #endif
 
-    if (HAL_UART_Init(&UartHandle) != HAL_OK) {
+    if (HAL_UART_Init(handle) != HAL_OK) {
         error("Cannot initialize UART\n");
     }
 }
@@ -151,12 +195,12 @@
     UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
 
     // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
-    SERIAL_OBJ(uart) = (UARTName)pinmap_merge(uart_tx, uart_rx);
+    UARTName instance = (UARTName)pinmap_merge(uart_tx, uart_rx);
     
-    MBED_ASSERT(SERIAL_OBJ(uart) != (UARTName)NC);
+    MBED_ASSERT(instance != (UARTName)NC);
 
     // Enable USART clock
-    switch (SERIAL_OBJ(uart)) {
+    switch (instance) {
         case UART_1:
             __HAL_RCC_USART1_CLK_ENABLE();
             SERIAL_OBJ(index) = 0;
@@ -247,38 +291,45 @@
     SERIAL_OBJ(pin_tx) = tx;
     SERIAL_OBJ(pin_rx) = rx;
 
-    init_uart(obj);
+    init_uart(obj, instance);
 
+#ifndef YOTTA_CFG_MBED_OS
     // For stdio management
-    if (SERIAL_OBJ(uart) == STDIO_UART) {
+    if ((int)(UartHandle[SERIAL_OBJ(index)].Instance) == STDIO_UART) {
         stdio_uart_inited = 1;
         memcpy(&stdio_uart, obj, sizeof(serial_t));
     }
+#endif
+
+    DEBUG_PRINTF("UART%u: Init\n", obj->serial.module+1);
 }
 
 void serial_free(serial_t *obj)
 {
     // Reset UART and disable clock
-    switch (SERIAL_OBJ(uart)) {
-        case UART_1:
+    switch (SERIAL_OBJ(index)) {
+        case 0:
             __USART1_FORCE_RESET();
             __USART1_RELEASE_RESET();
             __USART1_CLK_DISABLE();
             break;
-        case UART_2:
+        case 1:
             __USART2_FORCE_RESET();
             __USART2_RELEASE_RESET();
             __USART2_CLK_DISABLE();
+#if DEVICE_SERIAL_ASYNCH_DMA
+            __HAL_RCC_DMA1_CLK_DISABLE();
+#endif
             break;
 #if defined(USART3_BASE)
-        case UART_3:
+        case 2:
             __USART3_FORCE_RESET();
             __USART3_RELEASE_RESET();
             __USART3_CLK_DISABLE();
             break;
 #endif
 #if defined(UART4_BASE)
-        case UART_4:
+        case 3:
             __UART4_FORCE_RESET();
             __UART4_RELEASE_RESET();
             __UART4_CLK_DISABLE();
@@ -288,100 +339,138 @@
             break;
 #endif
 #if defined(UART5_BASE)
-        case UART_5:
+        case 4:
             __UART5_FORCE_RESET();
             __UART5_RELEASE_RESET();
             __UART5_CLK_DISABLE();
             break;
 #endif
 #if defined(USART6_BASE)
-        case UART_6:
+        case 5:
             __USART6_FORCE_RESET();
             __USART6_RELEASE_RESET();
             __USART6_CLK_DISABLE();
             break;
 #endif
 #if defined(UART7_BASE)
-        case UART_7:
+        case 6:
             __UART7_FORCE_RESET();
             __UART7_RELEASE_RESET();
             __UART7_CLK_DISABLE();
             break;
 #endif
 #if defined(UART8_BASE)
-        case UART_8:
+        case 7:
             __UART8_FORCE_RESET();
             __UART8_RELEASE_RESET();
             __UART8_CLK_DISABLE();
             break;
 #endif
     }
+    
     // Configure GPIOs
     pin_function(SERIAL_OBJ(pin_tx), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
     pin_function(SERIAL_OBJ(pin_rx), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
 
     serial_irq_ids[SERIAL_OBJ(index)] = 0;
+
+    DEBUG_PRINTF("UART%u: Free\n", obj->serial.module+1);
 }
 
 void serial_baud(serial_t *obj, int baudrate)
 {
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
+    
     SERIAL_OBJ(baudrate) = baudrate;
-    init_uart(obj);
+    handle->Init.BaudRate = baudrate;
+    
+    if (HAL_UART_Init(handle) != HAL_OK) {
+           error("Cannot initialize UART\n");
+    }
+    
+    DEBUG_PRINTF("UART%u: Baudrate: %u\n", obj->serial.module+1, baudrate);
 }
 
 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
 {
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
+  
     if (data_bits == 9) {
         SERIAL_OBJ(databits) = UART_WORDLENGTH_9B;
+        handle->Init.WordLength = UART_WORDLENGTH_9B;
     } else {
         SERIAL_OBJ(databits) = UART_WORDLENGTH_8B;
+        handle->Init.WordLength = UART_WORDLENGTH_8B;
     }
 
     switch (parity) {
         case ParityOdd:
-        case ParityForced0:
             SERIAL_OBJ(parity) = UART_PARITY_ODD;
+            handle->Init.Parity = UART_PARITY_ODD;
             break;
         case ParityEven:
-        case ParityForced1:
             SERIAL_OBJ(parity) = UART_PARITY_EVEN;
+            handle->Init.Parity = UART_PARITY_EVEN;
             break;
         default: // ParityNone
+        case ParityForced0: // unsupported!
+        case ParityForced1: // unsupported!
             SERIAL_OBJ(parity) = UART_PARITY_NONE;
+            handle->Init.Parity = UART_PARITY_NONE;
             break;
     }
 
     if (stop_bits == 2) {
         SERIAL_OBJ(stopbits) = UART_STOPBITS_2;
+        handle->Init.StopBits = UART_STOPBITS_2;
     } else {
         SERIAL_OBJ(stopbits) = UART_STOPBITS_1;
+        handle->Init.StopBits = UART_STOPBITS_1;
     }
 
-    init_uart(obj);
+    if (HAL_UART_Init(handle) != HAL_OK) {
+           error("Cannot initialize UART\n");
+    }
+
+    DEBUG_PRINTF("UART%u: Format: %u, %u, %u\n", obj->serial.module+1, data_bits, parity, stop_bits);
 }
 
 /******************************************************************************
  * INTERRUPTS HANDLING
  ******************************************************************************/
 
-static void uart_irq(UARTName name, int id)
+static void uart_irq(int id)
 {
-    UartHandle.Instance = (USART_TypeDef *)name;
+  UART_HandleTypeDef *handle = &UartHandle[id];
     if (serial_irq_ids[id] != 0) {
-        if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) {
+        if (__HAL_UART_GET_FLAG(handle, UART_FLAG_TC) != RESET) {
             irq_handler(serial_irq_ids[id], TxIrq);
-            __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_TC);
+            __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_TC);
         }
-        if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) {
+        if (__HAL_UART_GET_FLAG(handle, UART_FLAG_RXNE) != RESET) {
             irq_handler(serial_irq_ids[id], RxIrq);
-            __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_RXNE);
+            __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_RXNE);
         }
     }
 }
+
 #if DEVICE_SERIAL_ASYNCH_DMA
-static void dma_irq(DMAName name, int id)
+static void dma_irq(DMAName name, int id, SerialIrq txrxirq)
 {
-  // TO DO
+
+  if (serial_irq_ids[id] != 0) {
+    if (txrxirq == RxIrq) {
+      if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) {
+            irq_handler(serial_irq_ids[id], RxIrq);
+            __HAL_DMA_CLEAR_FLAG(&DmaHandle, DMA_FLAG_TCIF2_6);
+        }
+    } else {
+      if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) {
+            irq_handler(serial_irq_ids[id], TxIrq);
+            __HAL_DMA_CLEAR_FLAG(&DmaHandle, DMA_FLAG_TCIF0_4);
+        }
+    }    
+  }
     DmaHandle.Instance = (DMA_Stream_TypeDef *)name;
     if (serial_irq_ids[id] != 0) {
         if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) {
@@ -398,66 +487,131 @@
 
 static void uart1_irq(void)
 {
-    uart_irq(UART_1, 0);
+    uart_irq(0);
 }
 
 static void uart2_irq(void)
 {
-    uart_irq(UART_2, 1);
+    uart_irq(1);
 }
 
 #if defined(USART3_BASE)
 static void uart3_irq(void)
 {
-    uart_irq(UART_3, 2);
+    uart_irq(2);
 }
 #endif
 
 #if defined(UART4_BASE)
 static void uart4_irq(void)
 {
-    uart_irq(UART_4, 3);
+    uart_irq(3);
 }
+#endif
+
 #if DEVICE_SERIAL_ASYNCH_DMA
 
+#if defined(UART5_BASE)
+static void dma1_stream0_irq(void)
+{
+    dma_irq(DMA_1, 4, RxIrq); // uart5_rx
+}
+#endif
+
+#if defined(USART3_BASE)
+static void dma1_stream1_irq(void)
+{
+    dma_irq(DMA_1, 2, RxIrq); // uart3_rx
+}
+#endif
+
+#if defined(UART4_BASE)
 static void dma1_stream2_irq(void)
 {
-    dma_irq(DMA_1, 3 /* TO DO : ??? WHAT IS THIS 3 ??? */);
+    dma_irq(DMA_1, 3, RxIrq); // uart4_rx
+}
+#endif
+
+#if defined(USART3_BASE)
+static void dma1_stream3_irq(void)
+{
+    dma_irq(DMA_1, 2, TxIrq); // uart3_tx
+}
+#endif
+
+#if defined(UART4_BASE)
+static void dma1_stream4_irq(void)
+{
+    dma_irq(DMA_1, 3, TxIrq); // uart4_tx
+}
+#endif
+
+static void dma1_stream5_irq(void)
+{
+    dma_irq(DMA_1, 1, RxIrq); // uart2_rx
+}
+
+static void dma1_stream6_irq(void)
+{
+    dma_irq(DMA_1, 1, TxIrq); // uart2_tx
 }
 
+#if defined(UART5_BASE)
+static void dma1_stream7_irq(void)
+{
+    dma_irq(DMA_1, 4, TxIrq); // uart5_tx
+}
+#endif
 
-static void dma1_stream4_irq(void)
+#if defined(USART6_BASE)
+static void dma2_stream1_irq(void)
 {
-    dma_irq(DMA_1, 3 /* TO DO : ??? WHAT IS THIS 3 ??? */);
+    dma_irq(DMA_2, 5, RxIrq); // uart6_rx
 }
 #endif
-#endif
+
+static void dma2_stream5_irq(void)
+{
+    dma_irq(DMA_2, 0, RxIrq); // uart1_rx
+}
+
+static void dma2_stream6_irq(void)
+{
+    dma_irq(DMA_2, 5, TxIrq); // uart6_tx
+}
+
+static void dma2_stream7_irq(void)
+{
+    dma_irq(DMA_2, 0, TxIrq); // uart1_tx
+}
+
+#endif // DEVICE_SERIAL_ASYNCH_DMA
 
 #if defined(UART5_BASE)
 static void uart5_irq(void)
 {
-    uart_irq(UART_5, 4);
+    uart_irq(4);
 }
 #endif
 
 #if defined(USART6_BASE)
 static void uart6_irq(void)
 {
-    uart_irq(UART_6, 5);
+    uart_irq(5);
 }
 #endif
 
 #if defined(UART7_BASE)
 static void uart7_irq(void)
 {
-    uart_irq(UART_7, 6);
+    uart_irq(6);
 }
 #endif
 
 #if defined(UART8_BASE)
 static void uart8_irq(void)
 {
-    uart_irq(UART_8, 7);
+    uart_irq(7);
 }
 #endif
 
@@ -476,26 +630,53 @@
     uint32_t vector_dma = 0;
 #endif
 
-    UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart);
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
 
-    switch (SERIAL_OBJ(uart)) {
-        case UART_1:
+    switch (SERIAL_OBJ(index)) {
+        case 0:
             irq_n = USART1_IRQn;
             vector = (uint32_t)&uart1_irq;
+#if DEVICE_SERIAL_ASYNCH_DMA
+            if (irq == RxIrq) {
+                irqn_dma = DMA2_Stream5_IRQn;
+                vector_dma = (uint32_t)&dma2_stream5_irq;
+            } else {
+                irqn_dma = DMA2_Stream7_IRQn;
+                vector_dma = (uint32_t)&dma2_stream7_irq;
+            }
+#endif
             break;
 
-        case UART_2:
+        case 1:
             irq_n = USART2_IRQn;
             vector = (uint32_t)&uart2_irq;
+#if DEVICE_SERIAL_ASYNCH_DMA
+            if (irq == RxIrq) {
+                irqn_dma = DMA1_Stream5_IRQn;
+                vector_dma = (uint32_t)&dma1_stream5_irq;
+            } else {
+                irqn_dma = DMA1_Stream6_IRQn;
+                vector_dma = (uint32_t)&dma1_stream6_irq;
+            }
+#endif
             break;
 #if defined(USART3_BASE)
-        case UART_3:
+        case 2:
             irq_n = USART3_IRQn;
             vector = (uint32_t)&uart3_irq;
+#if DEVICE_SERIAL_ASYNCH_DMA
+            if (irq == RxIrq) {
+                irqn_dma = DMA1_Stream1_IRQn;
+                vector_dma = (uint32_t)&dma1_stream1_irq;
+            } else {
+                irqn_dma = DMA1_Stream3_IRQn;
+                vector_dma = (uint32_t)&dma1_stream3_irq;
+            }
+#endif
             break;
 #endif
 #if defined(UART4_BASE)
-        case UART_4:
+        case 3:
             irq_n = UART4_IRQn;
             vector = (uint32_t)&uart4_irq;
 #if DEVICE_SERIAL_ASYNCH_DMA
@@ -510,25 +691,43 @@
             break;
 #endif
 #if defined(UART5_BASE)
-        case UART_5:
+        case 4:
             irq_n = UART5_IRQn;
             vector = (uint32_t)&uart5_irq;
+#if DEVICE_SERIAL_ASYNCH_DMA
+            if (irq == RxIrq) {
+                irqn_dma = DMA1_Stream0_IRQn;
+                vector_dma = (uint32_t)&dma1_stream0_irq;
+            } else {
+                irqn_dma = DMA1_Stream4_IRQn;
+                vector_dma = (uint32_t)&dma1_stream7_irq;
+            }
+#endif
             break;
 #endif
 #if defined(USART6_BASE)
-        case UART_6:
+        case 5:
             irq_n = USART6_IRQn;
             vector = (uint32_t)&uart6_irq;
+#if DEVICE_SERIAL_ASYNCH_DMA
+            if (irq == RxIrq) {
+                irqn_dma = DMA2_Stream1_IRQn;
+                vector_dma = (uint32_t)&dma2_stream1_irq;
+            } else {
+                irqn_dma = DMA2_Stream6_IRQn;
+                vector_dma = (uint32_t)&dma2_stream6_irq;
+            }
+#endif
             break;
 #endif
 #if defined(UART7_BASE)
-        case UART_7:
+        case 6:
             irq_n = UART7_IRQn;
             vector = (uint32_t)&uart7_irq;
             break;
 #endif
 #if defined(UART8_BASE)
-        case UART_8:
+        case 7:
             irq_n = UART8_IRQn;
             vector = (uint32_t)&uart8_irq;
             break;
@@ -538,7 +737,7 @@
     if (enable) {
 
         if (irq == RxIrq) {
-            __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
+            __HAL_UART_ENABLE_IT(handle, UART_IT_RXNE);
 #if DEVICE_SERIAL_ASYNCH_DMA
             NVIC_SetVector(irq_n, vector_dma);
             NVIC_EnableIRQ(irq_n);
@@ -549,7 +748,7 @@
             NVIC_EnableIRQ(irq_n);
 #endif
         } else { // TxIrq
-            __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC);
+            __HAL_UART_ENABLE_IT(handle, UART_IT_TC);
             NVIC_SetVector(irq_n, vector);
             NVIC_EnableIRQ(irq_n);
 #if DEVICE_SERIAL_ASYNCH_DMA
@@ -562,13 +761,13 @@
         int all_disabled = 0;
 
         if (irq == RxIrq) {
-            __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
+            __HAL_UART_DISABLE_IT(handle, UART_IT_RXNE);
             // Check if TxIrq is disabled too
-            if ((UartHandle.Instance->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1;
+            if ((handle->Instance->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1;
         } else { // TxIrq
-            __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TXE);
+            __HAL_UART_DISABLE_IT(handle, UART_IT_TXE);
             // Check if RxIrq is disabled too
-            if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
+            if ((handle->Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
         }
 
         if (all_disabled) {
@@ -587,41 +786,41 @@
 
 int serial_getc(serial_t *obj)
 {
-    USART_TypeDef *uart = (USART_TypeDef *)(SERIAL_OBJ(uart));
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
     while (!serial_readable(obj));
-    return (int)(uart->DR & 0x1FF);
+    return (int)(handle->Instance->DR & 0x1FF);
 }
 
 void serial_putc(serial_t *obj, int c)
 {
-    USART_TypeDef *uart = (USART_TypeDef *)(SERIAL_OBJ(uart));
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
     while (!serial_writable(obj));
-    uart->DR = (uint32_t)(c & 0x1FF);
+    handle->Instance->DR = (uint32_t)(c & 0x1FF);
 }
 
 int serial_readable(serial_t *obj)
 {
     int status;
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
     // Check if data is received
-    status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) ? 1 : 0);
+    status = ((__HAL_UART_GET_FLAG(handle, UART_FLAG_RXNE) != RESET) ? 1 : 0);
     return status;
 }
 
 int serial_writable(serial_t *obj)
 {
     int status;
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
     // Check if data is transmitted
-    status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TXE) != RESET) ? 1 : 0);
+    status = ((__HAL_UART_GET_FLAG(handle, UART_FLAG_TXE) != RESET) ? 1 : 0);
     return status;
 }
 
 void serial_clear(serial_t *obj)
 {
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
-    __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_TXE);
-    __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_RXNE);
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
+    __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_TXE);
+    __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_RXNE);
 }
 
 void serial_pinout_tx(PinName tx)
@@ -631,12 +830,13 @@
 
 void serial_break_set(serial_t *obj)
 {
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
-    HAL_LIN_SendBreak(&UartHandle);
+    UART_HandleTypeDef *uart = &UartHandle[SERIAL_OBJ(index)];
+    HAL_LIN_SendBreak(uart);
 }
 
 void serial_break_clear(serial_t *obj)
 {
+    (void)obj;
 }
 
 //########################################################################################
@@ -657,7 +857,6 @@
 {
     // We only support byte buffers for now
     MBED_ASSERT(width == 8);
-    UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart);
   
     // Exit if a transmit is already on-going
     if (serial_tx_active(obj)) return;
@@ -729,46 +928,44 @@
 {
     IRQn_Type irq_n = (IRQn_Type)0;
 
-    UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart);
-
-    switch (SERIAL_OBJ(uart)) {
+    switch (SERIAL_OBJ(index)) {
 #if defined(USART1_BASE)
-        case UART_1:
+        case 0:
             irq_n = USART1_IRQn;
             break;
 #endif
 #if defined(USART2_BASE)
-        case UART_2:
+        case 1:
             irq_n = USART2_IRQn;
             break;
 #endif
 #if defined(USART3_BASE)
-        case UART_3:
+        case 2:
             irq_n = USART3_IRQn;
             break;
 #endif
 #if defined(UART4_BASE)
-        case UART_4:
+        case 3:
             irq_n = UART4_IRQn;
             break;
 #endif
-#if defined(UART5_BASE)
-        case UART_5:
+#if defined(USART5_BASE)
+        case 4:
             irq_n = UART5_IRQn;
             break;
 #endif
 #if defined(USART6_BASE)
-        case UART_6:
+        case 5:
             irq_n = USART6_IRQn;
             break;
 #endif
 #if defined(UART7_BASE)
-        case UART_7:
+        case 6:
             irq_n = UART7_IRQn;
             break;
 #endif
 #if defined(UART8_BASE)
-        case UART_8:
+        case 7:
             irq_n = UART8_IRQn;
             break;
 #endif
@@ -781,24 +978,177 @@
 
 #if DEVICE_SERIAL_ASYNCH_DMA
 
-/** The asynchronous TX and RX handler.
- *
- * @param obj The serial object
- * @return Returns event flags if a TX/RX transfer termination condition was met or 0 otherwise
- */
-static void h_serial_txdma_irq_handler_asynch()
+/**
+  * @brief  Start the DMA Transfer with interrupt enabled.
+  * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream.
+  * @param  SrcAddress: The source memory Buffer address
+  * @param  DstAddress: The destination memory Buffer address
+  * @param  DataLength: The length of data to be transferred from source to destination
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef MBED_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
 {
-    HAL_DMA_IRQHandler(UartHandle.hdmatx);
+    /* Process locked */
+    __HAL_LOCK(hdma);
+
+    /* Change DMA peripheral state */
+    hdma->State = HAL_DMA_STATE_BUSY;
+
+     /* Check the parameters */
+    assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+    /* Disable the peripheral */
+    __HAL_DMA_DISABLE(hdma);
+
+    /* Configure the source, destination address and the data length */
+    /* Clear DBM bit */
+    hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
+
+    /* Configure DMA Stream data length */
+    hdma->Instance->NDTR = DataLength;
+
+    /* Peripheral to Memory */
+    if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) {
+        /* Configure DMA Stream destination address */
+        hdma->Instance->PAR = DstAddress;
+
+        /* Configure DMA Stream source address */
+        hdma->Instance->M0AR = SrcAddress;
+    } else {
+        /* Memory to Peripheral */
+        /* Configure DMA Stream source address */
+        hdma->Instance->PAR = SrcAddress;
+
+        /* Configure DMA Stream destination address */
+        hdma->Instance->M0AR = DstAddress;
+    }
+
+    /* Enable all interrupts EXCEPT HALF TRANSFER COMPLETE */
+    hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
+    hdma->Instance->FCR |= DMA_IT_FE;
+
+     /* Enable the Peripheral */
+    __HAL_DMA_ENABLE(hdma);
+
+    return HAL_OK;
+}
+/**
+  * @brief DMA UART receive process half complete callback
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *                the configuration information for the specified DMA module.
+  * @retval None
+  */
+static void h_UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+  HAL_UART_RxHalfCpltCallback(huart);
 }
-/** The asynchronous TX and RX handler.
- *
- * @param obj The serial object
- * @return Returns event flags if a TX/RX transfer termination condition was met or 0 otherwise
- */
-void h_serial_rxdma_irq_handler_asynch(serial_t *obj)
+
+/**
+  * @brief  DMA UART receive process complete callback.
+  * @param  hdma: DMA handle
+  * @retval None
+  */
+static void h_UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+  /* DMA Normal mode*/
+  if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
+  {
+    huart->RxXferCount = 0;
+
+    /* Disable the DMA transfer for the receiver request by setting the DMAR bit
+       in the UART CR3 register */
+    huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR);
+
+    /* Check if a transmit process is ongoing or not */
+    if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
+    {
+      huart->State = HAL_UART_STATE_BUSY_TX;
+    }
+    else
+    {
+      huart->State = HAL_UART_STATE_READY;
+    }
+  }
+  HAL_UART_RxCpltCallback(huart);
+}
+/**
+  * @brief  DMA UART communication error callback.
+  * @param  hdma: DMA handle
+  * @retval None
+  */
+static void h_UART_DMAError(DMA_HandleTypeDef *hdma)
 {
-//    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
-    HAL_DMA_IRQHandler(UartHandle.hdmarx);
+  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+  huart->RxXferCount = 0;
+  huart->TxXferCount = 0;
+  huart->State= HAL_UART_STATE_READY;
+  huart->ErrorCode |= HAL_UART_ERROR_DMA;
+  HAL_UART_ErrorCallback(huart);
+}
+
+/**
+  * @brief  Receives an amount of data in non blocking mode.
+  * @note   This function differs from HAL's function as it does not enable HalfTranferComplete
+  * @param  huart: pointer to a UART_HandleTypeDef structure that contains
+  *                the configuration information for the specified UART module.
+  * @param  pData: Pointer to data buffer
+  * @param  Size: Amount of data to be received
+  * @note   When the UART parity is enabled (PCE = 1) the data received contain the parity bit.
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef MBED_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+    uint32_t *tmp;
+    uint32_t tmp1 = 0;
+
+    tmp1 = huart->State;
+    if((tmp1 == HAL_UART_STATE_READY) || (tmp1 == HAL_UART_STATE_BUSY_TX)) {
+        if((pData == NULL ) || (Size == 0)) {
+          return HAL_ERROR;
+        }
+
+        /* Process Locked */
+        __HAL_LOCK(huart);
+
+        huart->pRxBuffPtr = pData;
+        huart->RxXferSize = Size;
+
+        huart->ErrorCode = HAL_UART_ERROR_NONE;
+        /* Check if a transmit process is ongoing or not */
+        if(huart->State == HAL_UART_STATE_BUSY_TX) {
+            huart->State = HAL_UART_STATE_BUSY_TX_RX;
+        } else {
+            huart->State = HAL_UART_STATE_BUSY_RX;
+        }
+
+        /* Set the UART DMA transfer complete callback */
+        huart->hdmarx->XferCpltCallback = h_UART_DMAReceiveCplt;
+
+        /* Set the UART DMA Half transfer complete callback */
+        huart->hdmarx->XferHalfCpltCallback = h_UART_DMARxHalfCplt;
+
+        /* Set the DMA error callback */
+        huart->hdmarx->XferErrorCallback = h_UART_DMAError;
+
+        /* Enable the DMA Stream */
+        tmp = (uint32_t*)&pData;
+        MBED_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t*)tmp, Size);
+
+        /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+        in the UART CR3 register */
+        huart->Instance->CR3 |= USART_CR3_DMAR;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(huart);
+
+        return HAL_OK;
+    } else {
+        return HAL_BUSY;
+    }
 }
 
 /**
@@ -811,49 +1161,37 @@
 {
     IRQn_Type irq_n = (IRQn_Type)0;
 
-    UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart);
-
-    switch (SERIAL_OBJ(uart)) {
+    switch (SERIAL_OBJ(index)) {
 #if defined(USART1_BASE)
-        case UART_1:
+        case 0:
             irq_n = DMA2_Stream7_IRQn;
             break;
 #endif
 #if defined(USART2_BASE)
-        case UART_2:
+        case 1:
             irq_n = DMA1_Stream6_IRQn;
             break;
 #endif
 #if defined(USART3_BASE)
-        case UART_3:
+        case 2:
             irq_n = DMA1_Stream3_IRQn;
             break;
 #endif
 #if defined(UART4_BASE)
-        case UART_4:
+        case 3:
             irq_n = DMA1_Stream4_IRQn;
             break;
 #endif
 #if defined(UART5_BASE)
-        case UART_5:
+        case 4:
             irq_n = DMA1_Stream7_IRQn;
             break;
 #endif
 #if defined(USART6_BASE)
-        case UART_6:
+        case 5:
             irq_n = DMA2_Stream6_IRQn;
             break;
 #endif
-#if defined(UART7_BASE)
-        case UART_7:
-            irq_n = DMA1_Stream1_IRQn;
-            break;
-#endif
-#if defined(UART8_BASE)
-        case UART_8:
-            irq_n = DMA1_Stream0_IRQn;
-            break;
-#endif
         default:
             irq_n = (IRQn_Type)0;
     }
@@ -870,47 +1208,35 @@
 {
     IRQn_Type irq_n = (IRQn_Type)0;
 
-    UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart);
-
-    switch (SERIAL_OBJ(uart)) {
+    switch (SERIAL_OBJ(index)) {
 #if defined(USART1_BASE)
-        case UART_1:
+        case 0:
             irq_n = DMA2_Stream5_IRQn;
             break;
 #endif
 #if defined(USART2_BASE)
-        case UART_2:
+        case 1:
             irq_n = DMA1_Stream5_IRQn;
             break;
 #endif
 #if defined(USART3_BASE)
-        case UART_3:
+        case 2:
             irq_n = DMA1_Stream1_IRQn;
             break;
 #endif
 #if defined(UART4_BASE)
-        case UART_4:
+        case 3:
             irq_n = DMA1_Stream2_IRQn;
             break;
 #endif
 #if defined(UART5_BASE)
-        case UART_5:
+        case 4:
             irq_n = DMA1_Stream0_IRQn;
             break;
 #endif
 #if defined(USART6_BASE)
-        case UART_6:
-            irq_n = DMA2_Stream2_IRQn;
-            break;
-#endif
-#if defined(UART7_BASE)
-        case UART_7:
-            irq_n = DMA1_Stream3_IRQn;
-            break;
-#endif
-#if defined(UART8_BASE)
-        case UART_8:
-            irq_n = DMA1_Stream6_IRQn;
+        case 5:
+            irq_n = DMA2_Stream1_IRQn;
             break;
 #endif
         default:
@@ -936,9 +1262,15 @@
  * @param hint      A suggestion for how to use DMA with this transfer
  * @return Returns number of data transfered, or 0 otherwise
  */
+#ifdef YOTTA_CFG_MBED_OS
+int serial_tx_asynch(serial_t *obj, void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
+#else
 int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
+#endif
 {
-  
+    // DMA usage is currently ignored
+    (void) hint;
+    
     // Check buffer is ok
     MBED_ASSERT(tx != (void*)0);
     MBED_ASSERT(tx_width == 8); // support only 8b width
@@ -952,13 +1284,13 @@
     h_serial_tx_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events
     h_serial_tx_enable_event(obj, event, 1); // Set only the wanted events
   
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
     // Enable interrupt
     IRQn_Type irqn = h_serial_get_irq_index(obj);
     NVIC_ClearPendingIRQ(irqn);
     NVIC_DisableIRQ(irqn);
     NVIC_SetPriority(irqn, 1);
     NVIC_SetVector(irqn, (uint32_t)handler);
-    UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart);
     NVIC_EnableIRQ(irqn);
 
 #if DEVICE_SERIAL_ASYNCH_DMA
@@ -967,25 +1299,26 @@
     NVIC_ClearPendingIRQ(irqn);
     NVIC_DisableIRQ(irqn);
     NVIC_SetPriority(irqn, 1);
-//    NVIC_SetVector(irqn, (uint32_t)&h_serial_txdma_irq_handler_asynch);
     NVIC_SetVector(irqn, (uint32_t)handler);
     NVIC_EnableIRQ(irqn);
 
     // the following function will enable program and enable the DMA transfer
-    if (HAL_UART_Transmit_DMA(&UartHandle, (uint8_t*)tx, tx_length) != HAL_OK)
+    if (HAL_UART_Transmit_DMA(handle, (uint8_t*)tx, tx_length) != HAL_OK)
     {
       /* Transfer error in transmission process */
       return 0;
     }
 #else
     // the following function will enable UART_IT_TXE and error interrupts
-    if (HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)tx, tx_length) != HAL_OK)
+    if (HAL_UART_Transmit_IT(handle, (uint8_t*)tx, tx_length) != HAL_OK)
     {
       /* Transfer error in transmission process */
       return 0;
     }
 #endif
-  
+
+    DEBUG_PRINTF("UART%u: Tx: 0=(%u, %u) %x\n", obj->serial.module+1, tx_length, tx_width, HAL_UART_GetState(handle));
+
     return tx_length;
 }
 
@@ -1004,6 +1337,9 @@
  */
 void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
 {
+    // DMA usage is currently ignored
+    (void) hint;
+
     /* Sanity check arguments */
     MBED_ASSERT(obj);
     MBED_ASSERT(rx != (void*)0);
@@ -1024,9 +1360,10 @@
     NVIC_SetVector(irqn, (uint32_t)handler);
     NVIC_EnableIRQ(irqn);
 
-    UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart);
+
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
     // flush current data + error flags
-    __HAL_UART_CLEAR_PEFLAG(&UartHandle);
+    __HAL_UART_CLEAR_PEFLAG(handle);
 #if DEVICE_SERIAL_ASYNCH_DMA
     // Enable DMA interrupt
     irqn = h_serial_rx_get_irqdma_index(obj);
@@ -1034,17 +1371,17 @@
     NVIC_DisableIRQ(irqn);
     NVIC_SetPriority(irqn, 1);
     NVIC_SetVector(irqn, (uint32_t)handler);
-
     NVIC_EnableIRQ(irqn);
     // following HAL function will program and enable the DMA transfer
-    HAL_UART_Receive_DMA(&UartHandle, (uint8_t*)rx, rx_length);
+    MBED_UART_Receive_DMA(handle, (uint8_t*)rx, rx_length);
 #else
     // following HAL function will enable the RXNE interrupt + error interrupts    
-    HAL_UART_Receive_IT(&UartHandle, (uint8_t*)rx, rx_length);
+    HAL_UART_Receive_IT(handle, (uint8_t*)rx, rx_length);
 #endif
     /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
-    __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_ERR);
+    __HAL_UART_ENABLE_IT(handle, UART_IT_ERR);
 
+    DEBUG_PRINTF("UART%u: Rx: 0=(%u, %u, %u) %x\n", obj->serial.module+1, rx_length, rx_width, char_match, HAL_UART_GetState(handle));
     return;
 }
 
@@ -1056,8 +1393,8 @@
 uint8_t serial_tx_active(serial_t *obj)
 {
     MBED_ASSERT(obj);
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
-    return ((HAL_UART_GetState(&UartHandle) & UART_STATE_TX_ACTIVE) ? 1 : 0);
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
+    return ((HAL_UART_GetState(handle) & UART_STATE_TX_ACTIVE) ? 1 : 0);
 }
 
 /** Attempts to determine if the serial peripheral is already in use for RX
@@ -1068,8 +1405,8 @@
 uint8_t serial_rx_active(serial_t *obj)
 {
     MBED_ASSERT(obj);
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
-    return ((HAL_UART_GetState(&UartHandle) & UART_STATE_RX_ACTIVE) ? 1 : 0);
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
+    return ((HAL_UART_GetState(handle) & UART_STATE_RX_ACTIVE) ? 1 : 0);
 
 }
 
@@ -1085,62 +1422,62 @@
     uint8_t i = 0;
 
   // Irq handler is common to Tx and Rx
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
 #if DEVICE_SERIAL_ASYNCH_DMA
-    if ((UartHandle.Instance->CR3 & USART_CR3_DMAT) !=0) {
+    if ((handle->Instance->CR3 & USART_CR3_DMAT) !=0) {
         // call dma tx interrupt
-        HAL_DMA_IRQHandler(UartHandle.hdmatx);
+        HAL_DMA_IRQHandler(handle->hdmatx);
     }
-    if ((UartHandle.Instance->CR3 & USART_CR3_DMAR) !=0) {
+    if ((handle->Instance->CR3 & USART_CR3_DMAR) !=0) {
         // call dma rx interrupt
-        HAL_DMA_IRQHandler(UartHandle.hdmarx);
+        HAL_DMA_IRQHandler(handle->hdmarx);
     }
 #endif
-    HAL_UART_IRQHandler(&UartHandle);
+    HAL_UART_IRQHandler(handle);
   // TX PART:
-    if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) {
-        __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_TC);
+    if (__HAL_UART_GET_FLAG(handle, UART_FLAG_TC) != RESET) {
+        __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_TC);
         // return event SERIAL_EVENT_TX_COMPLETE if requested
         if ((SERIAL_OBJ(events) & SERIAL_EVENT_TX_COMPLETE ) != 0){
             return_event |= SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
         }
     }
     // handle error events:
-    if (__HAL_UART_GET_FLAG(&UartHandle, HAL_UART_ERROR_PE)) {
-        __HAL_UART_CLEAR_FLAG(&UartHandle, HAL_UART_ERROR_PE);
+    if (__HAL_UART_GET_FLAG(handle, HAL_UART_ERROR_PE)) {
+        __HAL_UART_CLEAR_FLAG(handle, HAL_UART_ERROR_PE);
         return_event |= SERIAL_EVENT_RX_PARITY_ERROR & obj->serial.events;
     }
-    if (__HAL_UART_GET_FLAG(&UartHandle, HAL_UART_ERROR_NE)||(UartHandle.ErrorCode & HAL_UART_ERROR_NE)!=0) {
-      __HAL_UART_CLEAR_FLAG(&UartHandle, HAL_UART_ERROR_NE);
+    if (__HAL_UART_GET_FLAG(handle, HAL_UART_ERROR_NE)||(handle->ErrorCode & HAL_UART_ERROR_NE)!=0) {
+      __HAL_UART_CLEAR_FLAG(handle, HAL_UART_ERROR_NE);
       // not supported by mbed
     }
-    if (__HAL_UART_GET_FLAG(&UartHandle, HAL_UART_ERROR_FE)||(UartHandle.ErrorCode & HAL_UART_ERROR_FE)!=0) {
-      __HAL_UART_CLEAR_FLAG(&UartHandle, HAL_UART_ERROR_FE);
-        return_event |= SERIAL_EVENT_RX_FRAMING_ERROR & obj->serial.events;
+    if (__HAL_UART_GET_FLAG(handle, HAL_UART_ERROR_FE)||(handle->ErrorCode & HAL_UART_ERROR_FE)!=0) {
+      __HAL_UART_CLEAR_FLAG(handle, HAL_UART_ERROR_FE);
+        return_event |= SERIAL_EVENT_RX_FRAMING_ERROR & SERIAL_OBJ(events);
     }
-    if (__HAL_UART_GET_FLAG(&UartHandle, HAL_UART_ERROR_ORE)||(UartHandle.ErrorCode & HAL_UART_ERROR_ORE)!=0) {
-      __HAL_UART_CLEAR_FLAG(&UartHandle, HAL_UART_ERROR_ORE);
-        return_event |= SERIAL_EVENT_RX_OVERRUN_ERROR & obj->serial.events;
+    if (__HAL_UART_GET_FLAG(handle, HAL_UART_ERROR_ORE)||(handle->ErrorCode & HAL_UART_ERROR_ORE)!=0) {
+      __HAL_UART_CLEAR_FLAG(handle, HAL_UART_ERROR_ORE);
+        return_event |= SERIAL_EVENT_RX_OVERRUN_ERROR & SERIAL_OBJ(events);
     }
 
     //RX PART
     // increment rx_buff.pos
-    if (UartHandle.RxXferSize !=0) { 
-        obj->rx_buff.pos = UartHandle.RxXferSize - UartHandle.RxXferCount;
+    if (handle->RxXferSize !=0) {
+        obj->rx_buff.pos = handle->RxXferSize - handle->RxXferCount;
     }
-    if ((UartHandle.RxXferCount==0)&&(obj->rx_buff.pos >= (obj->rx_buff.length - 1))) {
-        return_event |= SERIAL_EVENT_RX_COMPLETE & obj->serial.events;
+    if ((handle->RxXferCount==0)&&(obj->rx_buff.pos >= (obj->rx_buff.length - 1))) {
+        return_event |= SERIAL_EVENT_RX_COMPLETE & SERIAL_OBJ(events);
     }
     // Chek if Char_match is present
     if (SERIAL_OBJ(events) & SERIAL_EVENT_RX_CHARACTER_MATCH) {
       if (buf != NULL){
-        while((buf[i] != obj->char_match)&&(i<UartHandle.RxXferSize)){//for (i=0;i<UartHandle.RxXferSize;i++){
+        while((buf[i] != obj->char_match)&&(i<handle->RxXferSize)){//for (i=0;i<UartHandle.RxXferSize;i++){
           i++;//if (buf[i] == obj->char_match{
           //}
         }
-        if (i<UartHandle.RxXferSize){
+        if (i<handle->RxXferSize){
             obj->rx_buff.pos = i;
-            return_event |= SERIAL_EVENT_RX_CHARACTER_MATCH & obj->serial.events;
+            return_event |= SERIAL_EVENT_RX_CHARACTER_MATCH & SERIAL_OBJ(events);
         }
       }
     }
@@ -1154,13 +1491,18 @@
  */
 void serial_tx_abort_asynch(serial_t *obj)
 {
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
-    __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC|UART_IT_TXE);
-    UartHandle.Instance = 0;
-
-    obj->tx_buff.buffer = 0;
-    obj->tx_buff.length = 0;
-  
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
+    __HAL_UART_DISABLE_IT(handle, UART_IT_TC|UART_IT_TXE);
+    // clear flags
+      __HAL_UART_CLEAR_PEFLAG(handle);
+      // reset states
+      handle->TxXferCount = 0;
+      // update handle state
+      if (handle->State == HAL_UART_STATE_BUSY_TX_RX) {
+          handle->State = HAL_UART_STATE_BUSY_RX;
+      } else {
+          handle->State = HAL_UART_STATE_READY;
+      }
 }
 
 /** Abort the ongoing RX transaction It disables the enabled interrupt for RX and
@@ -1170,13 +1512,18 @@
  */
 void serial_rx_abort_asynch(serial_t *obj)
 {
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
-    __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
-    UartHandle.Instance = 0;
-  
-    obj->rx_buff.buffer = 0;
-    obj->rx_buff.length = 0;
-
+    UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)];
+    __HAL_UART_DISABLE_IT(handle, UART_IT_RXNE);
+    // clear flags
+    __HAL_UART_CLEAR_PEFLAG(handle);
+    // reset states
+    handle->RxXferCount = 0;
+    // update handle state
+    if (handle->State == HAL_UART_STATE_BUSY_TX_RX) {
+        handle->State = HAL_UART_STATE_BUSY_TX;
+    } else {
+        handle->State = HAL_UART_STATE_READY;
+    }
 }
 
 #endif
@@ -1196,10 +1543,9 @@
     UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);
 
     // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
-    SERIAL_OBJ(uart) = (UARTName)pinmap_merge(uart_cts, uart_rts);
+    UARTName instance = (UARTName)pinmap_merge(uart_cts, uart_rts);
 
-    MBED_ASSERT(SERIAL_OBJ(uart) != (UARTName)NC);
-    UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart));
+    MBED_ASSERT(instance != (UARTName)NC);
 
     if(type == FlowControlNone) {
         // Disable hardware flow control
@@ -1233,7 +1579,7 @@
         // Enable the pin for RTS function
         pinmap_pinout(rxflow, PinMap_UART_RTS);
     }
-    init_uart(obj);
+    init_uart(obj, instance);
 }
 #endif
 #endif