diff --git a/f4/usart/include/usart1.h b/f4/usart/include/usart1.h
index 8291075445980ee2f908e8621e0a1e9379997b0a..4c5f41eebcd5d2205f0e88f030e2d1bdb911f815 100644
--- a/f4/usart/include/usart1.h
+++ b/f4/usart/include/usart1.h
@@ -1,9 +1,22 @@
 #ifndef USART1_F4_H
 #define USART1_F4_H
 
+#include "stm32f4xx_hal.h"
+#include "usart_common.h"
 #include "comm.h"
 
 /* public functions */
-void usart1_init(TComm *comm_dev);
+void usart1_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities);
+void usart1_config(TComm *comm_dev,UART_InitTypeDef *conf);
+void usart1_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities);
+/* IRQ functions */
+unsigned char usart1_send_irq(unsigned char first_byte);
+unsigned char usart1_enable_tx_irq(void);
+unsigned char usart1_receive_irq(void);
+unsigned char usart1_cancel_receive_irq(void);
+/* DMA functions */
+unsigned char usart1_send_dma(unsigned char *data,unsigned short int length);
+unsigned char usart1_receive_dma(unsigned char *data,unsigned short int length);
+unsigned char usart1_cancel_receive_dma(void);
 
 #endif
diff --git a/f4/usart/include/usart2.h b/f4/usart/include/usart2.h
index fd9c29fd28d12df3369275a6b3a4f6df525e402c..65bbfaea37e42f7987a7c62ffe0f996b625a4864 100644
--- a/f4/usart/include/usart2.h
+++ b/f4/usart/include/usart2.h
@@ -1,18 +1,22 @@
 #ifndef USART2_F4_H
 #define USART2_F4_H
 
+#include "stm32f4xx_hal.h"
 #include "usart_common.h"
 #include "comm.h"
 
 /* public functions */
-void usart2_init(TComm *comm_dev,TUSART_IRQ_Priorities *priorities);
+void usart2_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities);
+void usart2_config(TComm *comm_dev,UART_InitTypeDef *conf);
+void usart2_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities);
 /* IRQ functions */
-unsigned char usart2_send_irq(unsigned char *data,unsigned int length);
-unsigned char usart2_receive_irq(unsigned int length);
+unsigned char usart2_send_irq(unsigned char first_byte);
+unsigned char usart2_enable_tx_irq(void);
+unsigned char usart2_receive_irq(void);
 unsigned char usart2_cancel_receive_irq(void);
 /* DMA functions */
-unsigned char usart2_send_dma(unsigned char *data,unsigned int lenght);
-unsigned char usart2_receive_dma(unsigned int length);
+unsigned char usart2_send_dma(unsigned char *data,unsigned short int length);
+unsigned char usart2_receive_dma(unsigned char *data,unsigned short int length);
 unsigned char usart2_cancel_receive_dma(void);
 
 #endif
diff --git a/f4/usart/include/usart4.h b/f4/usart/include/usart4.h
new file mode 100644
index 0000000000000000000000000000000000000000..78213da290f03c2c9769082e76f6625ef558b146
--- /dev/null
+++ b/f4/usart/include/usart4.h
@@ -0,0 +1,22 @@
+#ifndef USART4_F4_H
+#define USART4_F4_H
+
+#include "stm32f4xx_hal.h"
+#include "usart_common.h"
+#include "comm.h"
+
+/* public functions */
+void usart4_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities);
+void usart4_config(TComm *comm_dev,UART_InitTypeDef *conf);
+void usart4_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities);
+/* IRQ functions */
+unsigned char usart4_send_irq(unsigned char first_byte);
+unsigned char usart4_enable_tx_irq(void);
+unsigned char usart4_receive_irq(void);
+unsigned char usart4_cancel_receive_irq(void);
+/* DMA functions */
+unsigned char usart4_send_dma(unsigned char *data,unsigned short int length);
+unsigned char usart4_receive_dma(unsigned char *data,unsigned short int length);
+unsigned char usart4_cancel_receive_dma(void);
+
+#endif
diff --git a/f4/usart/src/usart1.c b/f4/usart/src/usart1.c
index 70304ca31394486265883f654f427a772a3b2a3c..1622ccfd6e2d6e00906f044f30bc4243f20462a4 100644
--- a/f4/usart/src/usart1.c
+++ b/f4/usart/src/usart1.c
@@ -1,7 +1,342 @@
 #include "usart1.h"
 
+#define     USART                    USART1
+#define     USART_ENABLE_CLK         __HAL_RCC_USART1_CLK_ENABLE()
+#define     USART_IRQn               USART1_IRQn
+#define     USART_IRQHandler         USART1_IRQHandler
+
+#define     USART_TX_PIN             GPIO_PIN_9                
+#define     USART_TX_GPIO_PORT       GPIOA
+#define     USART_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE()
+
+#define     USART_RX_PIN             GPIO_PIN_10
+#define     USART_RX_GPIO_PORT       GPIOA
+#define     USART_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE()
+
+/* DMA configuration */
+#define     USART_DMA_CHANNEL        DMA_CHANNEL_4
+#define     USART_ENABLE_DMA_CLK     __HAL_RCC_DMA2_CLK_ENABLE()
+
+#define     USART_TX_DMA_STREAM      DMA2_Stream7
+#define     USART_RX_DMA_STREAM      DMA2_Stream2
+
+#define     USART_DMA_TX_IRQn        DMA2_Stream7_IRQn
+#define     USART_DMA_RX_IRQn        DMA2_Stream2_IRQn
+#define     USART_DMA_TX_IRQHandler  DMA2_Stream7_IRQHandler
+#define     USART_DMA_RX_IRQHandler  DMA2_Stream2_IRQHandler
+
+// private variables
+UART_HandleTypeDef Uart1Handle;
+DMA_HandleTypeDef usart1_hdma_tx;
+DMA_HandleTypeDef usart1_hdma_rx;
+TComm *usart1_comm_dev;
+
+// interrupt handlers
+void USART_IRQHandler(void)
+{
+  unsigned char data,ret;
+  uint32_t source;
+
+  if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_RXNE) != RESET)
+  {
+    if(__HAL_UART_GET_IT_SOURCE(&Uart1Handle, UART_IT_RXNE) !=RESET)
+    {
+      __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_RXNE);
+      data=(uint8_t)(Uart1Handle.Instance->DR & (uint8_t)0x00FF);
+      // call the reception function
+      if(!comm_do_irq_receive(usart1_comm_dev,data))
+        __HAL_UART_DISABLE_IT(&Uart1Handle, UART_IT_RXNE);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_TC) != RESET)
+  {
+    if(__HAL_UART_GET_IT_SOURCE(&Uart1Handle, UART_IT_TC) !=RESET)
+    {
+      __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_TC);
+      ret=comm_do_irq_send(usart1_comm_dev,&data);
+      if(ret==0x01)
+        Uart1Handle.Instance->DR=data;
+      else if(ret==0x00)
+        __HAL_UART_DISABLE_IT(&Uart1Handle, UART_IT_TC);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_PE) != RESET)// parity error
+  {
+    if(__HAL_UART_GET_IT_SOURCE(&Uart1Handle, UART_IT_PE) !=RESET)
+    {
+      __HAL_UART_CLEAR_PEFLAG(&Uart1Handle);
+    }
+  }
+  source=__HAL_UART_GET_IT_SOURCE(&Uart1Handle, UART_IT_ERR);
+  if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_FE) != RESET)// frame error
+  {
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_FEFLAG(&Uart1Handle);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_NE) != RESET)// noise error
+  {
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_NEFLAG(&Uart1Handle);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart1Handle, UART_FLAG_ORE) != RESET)// overrun error
+  {
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_OREFLAG(&Uart1Handle);
+    }
+  }
+}
+
+void USART_DMA_TX_IRQHandler(void)
+{
+  if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmatx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart1Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmatx, DMA_IT_TE) != RESET)
+    {
+      /* Disable the transfer error interrupt */
+      __HAL_DMA_DISABLE_IT(Uart1Handle.hdmatx, DMA_IT_TE);
+      /* Clear the transfer error flag */
+      __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmatx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart1Handle.hdmatx));
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmatx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart1Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmatx, DMA_IT_TC) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart1Handle.hdmatx, DMA_IT_TC);
+      /* Clear the transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart1Handle.hdmatx));
+      CLEAR_BIT(Uart1Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+      HAL_DMA_Abort(Uart1Handle.hdmatx);
+      // call the user function
+      comm_do_dma_send(usart1_comm_dev);
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart1Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmatx, DMA_IT_HT) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart1Handle.hdmatx, DMA_IT_HT);
+      /* Clear the half transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart1Handle.hdmatx));
+    }
+  }
+}
+
+void USART_DMA_RX_IRQHandler(void)
+{
+  if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmarx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart1Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmarx, DMA_IT_TE) != RESET)
+    {
+      /* Disable the transfer error interrupt */
+      __HAL_DMA_DISABLE_IT(Uart1Handle.hdmarx, DMA_IT_TE);
+      /* Clear the transfer error flag */
+      __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmarx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart1Handle.hdmarx));
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart1Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmarx, DMA_IT_TC) != RESET)
+    {
+      /* Disable the transfer complete interrupt */
+      __HAL_DMA_DISABLE_IT(Uart1Handle.hdmarx, DMA_IT_TC);
+      /* Clear the transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart1Handle.hdmarx));
+      CLEAR_BIT(Uart1Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+      HAL_DMA_Abort(Uart1Handle.hdmarx);
+      // call the user function
+      comm_do_dma_receive(usart1_comm_dev);
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart1Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart1Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart1Handle.hdmarx, DMA_IT_HT) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart1Handle.hdmarx, DMA_IT_HT);
+      /* Clear the half transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart1Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart1Handle.hdmarx));
+    }
+  }
+}
+
 /* public functions*/
-void usart1_init(TComm *comm_dev)
+void usart1_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities)
+{
+  GPIO_InitTypeDef GPIO_InitStructure;
+
+  /* Enable GPIO clock */
+  USART_ENABLE_TX_GPIO_CLK;
+  USART_ENABLE_RX_GPIO_CLK;
+  USART_ENABLE_DMA_CLK;
+  // configure the GPIO pins
+
+  /* Configure USART Tx and Rx as alternate function push-pull */
+  GPIO_InitStructure.Pin       = USART_TX_PIN;
+  GPIO_InitStructure.Mode      = GPIO_MODE_AF_PP;
+  GPIO_InitStructure.Pull      = GPIO_PULLUP;
+  GPIO_InitStructure.Speed     = GPIO_SPEED_LOW;
+  GPIO_InitStructure.Alternate = GPIO_AF7_USART1;
+  HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure);
+
+  GPIO_InitStructure.Pin       = USART_RX_PIN;
+  HAL_GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure);
+
+  USART_ENABLE_CLK;
+
+  Uart1Handle.Instance          = USART;
+  usart1_config(comm_dev,conf);
+
+  if(comm_dev->use_dma)
+  {
+    // configure the DMA channels
+    usart1_hdma_tx.Instance                 = USART_TX_DMA_STREAM;
+    usart1_hdma_tx.Init.Channel             = USART_DMA_CHANNEL;
+    usart1_hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
+    usart1_hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
+    usart1_hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
+    usart1_hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    usart1_hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+    usart1_hdma_tx.Init.Mode                = DMA_NORMAL;
+    usart1_hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
+    usart1_hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+
+    HAL_DMA_Init(&usart1_hdma_tx);
+
+    /* Associate the initialized DMA handle to the UART handle */
+    __HAL_LINKDMA(&Uart1Handle, hdmatx, usart1_hdma_tx);
+
+    /* Configure the DMA handler for reception process */
+    usart1_hdma_rx.Instance                 = USART_RX_DMA_STREAM;
+    usart1_hdma_rx.Init.Channel             = USART_DMA_CHANNEL;
+    usart1_hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+    usart1_hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
+    usart1_hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
+    usart1_hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    usart1_hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+    usart1_hdma_rx.Init.Mode                = DMA_NORMAL;
+    usart1_hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
+    usart1_hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+
+    HAL_DMA_Init(&usart1_hdma_rx);
+
+    /* Associate the initialized DMA handle to the the UART handle */
+    __HAL_LINKDMA(&Uart1Handle, hdmarx, usart1_hdma_rx);
+  }
+  usart1_set_priorities(comm_dev,priorities);
+
+  /* Initialize the comm structure */
+  comm_dev->send_irq=usart1_send_irq;
+  comm_dev->enable_tx_irq=usart1_enable_tx_irq;
+  comm_dev->receive_irq=usart1_receive_irq;
+  comm_dev->cancel_receive_irq=usart1_cancel_receive_irq;
+  if(comm_dev->use_dma)
+  {
+    comm_dev->send_dma=usart1_send_dma;
+    comm_dev->receive_dma=usart1_receive_dma;
+    comm_dev->cancel_receive_dma=usart1_cancel_receive_dma;
+  }
+  comm_dev->irq_send_cb=0x00000000;
+  comm_dev->irq_receive_cb=0x00000000;
+  comm_dev->dma_send_cb=0x00000000;
+  comm_dev->dma_receive_cb=0x00000000;
+
+  /* initialize internal variables */
+  usart1_comm_dev=comm_dev;
+}
+
+void usart1_config(TComm *comm_dev,UART_InitTypeDef *conf)
+{
+  Uart1Handle.Init.BaudRate     = conf->BaudRate;
+  Uart1Handle.Init.WordLength   = conf->WordLength;
+  Uart1Handle.Init.StopBits     = conf->StopBits;
+  Uart1Handle.Init.Parity       = conf->Parity;
+  Uart1Handle.Init.Mode         = conf->Mode;
+  Uart1Handle.Init.HwFlowCtl    = conf->HwFlowCtl;
+  Uart1Handle.Init.OverSampling = conf->OverSampling;
+  HAL_UART_Init(&Uart1Handle);
+}
+
+void usart1_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities)
+{
+  HAL_NVIC_SetPriority(USART_IRQn, priorities->irq_priority,priorities->irq_subpriority);
+  HAL_NVIC_EnableIRQ(USART_IRQn);
+  if(comm_dev->use_dma)
+  {
+    HAL_NVIC_SetPriority(USART_DMA_TX_IRQn, priorities->dma_tx_priority,priorities->dma_tx_subpriority);
+    HAL_NVIC_EnableIRQ(USART_DMA_TX_IRQn);
+    HAL_NVIC_SetPriority(USART_DMA_RX_IRQn, priorities->dma_rx_priority,priorities->dma_rx_subpriority);
+    HAL_NVIC_EnableIRQ(USART_DMA_RX_IRQn);
+  }
+}
+
+/* IRQ functions */
+unsigned char usart1_send_irq(unsigned char first_byte)
+{
+  __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_TC);
+  __HAL_UART_ENABLE_IT(&Uart1Handle, UART_IT_TC);
+  Uart1Handle.Instance->DR=first_byte;
+
+  return 0x00;
+}
+
+unsigned char usart1_enable_tx_irq(void)
+{
+  __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_TC);
+  __HAL_UART_ENABLE_IT(&Uart1Handle, UART_IT_TC);
+
+  return 0x00;
+}
+
+unsigned char usart1_receive_irq(void)
+{
+  /* enable the rx interrupt */
+  __HAL_UART_ENABLE_IT(&Uart1Handle, UART_IT_RXNE);
+
+  return 0x00;
+}
+
+unsigned char usart1_cancel_receive_irq(void)
+{
+  /* disable the rx interrupt */
+  __HAL_UART_DISABLE_IT(&Uart1Handle, UART_IT_RXNE);
+
+  return 0x00;
+}
+
+/* DMA functions */
+unsigned char usart1_send_dma(unsigned char *data,unsigned short int length)
+{
+  HAL_DMA_Start_IT(Uart1Handle.hdmatx,(uint32_t)data,(uint32_t)&Uart1Handle.Instance->DR,length);
+  /* Clear the TC flag in the SR register by writing 0 to it */
+  __HAL_UART_CLEAR_FLAG(&Uart1Handle,UART_FLAG_TC);
+  /* Enable the DMA transfer for transmit request by setting the DMAT bit
+     in the UART CR3 register */
+  SET_BIT(Uart1Handle.Instance->CR3, USART_CR3_DMAT);
+
+  return 0x00;
+}
+
+unsigned char usart1_receive_dma(unsigned char *data,unsigned short int length)
+{
+  HAL_DMA_Start_IT(Uart1Handle.hdmarx,(uint32_t)&Uart1Handle.Instance->DR,(uint32_t)data,length);
+  SET_BIT(Uart1Handle.Instance->CR3, USART_CR3_DMAR);
+
+  return 0x00;
+}
+
+unsigned char usart1_cancel_receive_dma(void)
 {
+  CLEAR_BIT(Uart1Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+  HAL_DMA_Abort(Uart1Handle.hdmarx);
 
+  return 0x00;
 }
+
diff --git a/f4/usart/src/usart2.c b/f4/usart/src/usart2.c
index 2d9a4c2aca734d62621df44d306208dba5840cd3..ee1cc5562244f5717523f9479216bb3873d0f5a5 100644
--- a/f4/usart/src/usart2.c
+++ b/f4/usart/src/usart2.c
@@ -1,41 +1,24 @@
 #include "usart2.h"
 
 #define     USART                    USART2
-#define     USART_CLK                RCC_APB1Periph_USART2
-#define     USART_CLK_INIT           RCC_APB1PeriphClockCmd
+#define     USART_ENABLE_CLK         __HAL_RCC_USART2_CLK_ENABLE()
 #define     USART_IRQn               USART2_IRQn
 #define     USART_IRQHandler         USART2_IRQHandler
 
-#define     USART_TX_PIN             GPIO_Pin_2                
-#define     USART_TX_GPIO_PORT       GPIOA 
-#define     USART_TX_GPIO_CLK        RCC_AHB1Periph_GPIOA
-#define     USART_TX_SOURCE          GPIO_PinSource2
-#define     USART_TX_AF              GPIO_AF_USART2
+#define     USART_TX_PIN             GPIO_PIN_2                
+#define     USART_TX_GPIO_PORT       GPIOA
+#define     USART_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE()
 
-#define     USART_RX_PIN             GPIO_Pin_3
+#define     USART_RX_PIN             GPIO_PIN_3
 #define     USART_RX_GPIO_PORT       GPIOA
-#define     USART_RX_GPIO_CLK        RCC_AHB1Periph_GPIOA
-#define     USART_RX_SOURCE          GPIO_PinSource3
-#define     USART_RX_AF              GPIO_AF_USART2
+#define     USART_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOA_CLK_ENABLE()
 
-#define     USART_DMA                DMA1
-#define     USART_DMA_CLK            RCC_AHB1Periph_DMA1
+/* DMA configuration */
+#define     USART_DMA_CHANNEL        DMA_CHANNEL_4
+#define     USART_ENABLE_DMA_CLK     __HAL_RCC_DMA1_CLK_ENABLE()
 
-#define     USART_TX_DMA_CHANNEL     DMA_Channel_4
 #define     USART_TX_DMA_STREAM      DMA1_Stream6
-#define     USART_TX_DMA_FLAG_FEIF   DMA_FLAG_FEIF6
-#define     USART_TX_DMA_FLAG_DMEIF  DMA_FLAG_DMEIF6
-#define     USART_TX_DMA_FLAG_TEIF   DMA_FLAG_TEIF6
-#define     USART_TX_DMA_FLAG_HTIF   DMA_FLAG_HTIF6
-#define     USART_TX_DMA_FLAG_TCIF   DMA_FLAG_TCIF6
-
-#define     USART_RX_DMA_CHANNEL     DMA_Channel_4
 #define     USART_RX_DMA_STREAM      DMA1_Stream5
-#define     USART_RX_DMA_FLAG_FEIF   DMA_FLAG_FEIF5
-#define     USART_RX_DMA_FLAG_DMEIF  DMA_FLAG_DMEIF5
-#define     USART_RX_DMA_FLAG_TEIF   DMA_FLAG_TEIF5
-#define     USART_RX_DMA_FLAG_HTIF   DMA_FLAG_HTIF5
-#define     USART_RX_DMA_FLAG_TCIF   DMA_FLAG_TCIF5
 
 #define     USART_DMA_TX_IRQn        DMA1_Stream6_IRQn
 #define     USART_DMA_RX_IRQn        DMA1_Stream5_IRQn
@@ -43,182 +26,215 @@
 #define     USART_DMA_RX_IRQHandler  DMA1_Stream5_IRQHandler
 
 // private variables
-DMA_InitTypeDef DMA_TX_InitStructure;
-DMA_InitTypeDef DMA_RX_InitStructure;
+UART_HandleTypeDef Uart2Handle;
+DMA_HandleTypeDef usart2_hdma_tx;
+DMA_HandleTypeDef usart2_hdma_rx;
 TComm *usart2_comm_dev;
 
 // interrupt handlers
 void USART_IRQHandler(void)
 {
-  unsigned char data;
+  unsigned char data,ret;
+  uint32_t source;
 
-  if(USART_GetITStatus(USART, USART_IT_RXNE) != RESET)
+  if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_RXNE) != RESET)
+  {
+    if(__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_RXNE) !=RESET)
+    {
+      __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_RXNE);
+      data=(uint8_t)(Uart2Handle.Instance->DR & (uint8_t)0x00FF);
+      // call the reception function
+      if(!comm_do_irq_receive(usart2_comm_dev,data))
+        __HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_RXNE);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_TC) != RESET)
+  {
+    if(__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_TC) !=RESET)
+    {
+      __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_TC);
+      ret=comm_do_irq_send(usart2_comm_dev,&data);
+      if(ret==0x01)
+        Uart2Handle.Instance->DR=data;
+      else if(ret==0x00)
+        __HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_TC);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_PE) != RESET)// parity error
   {
-    USART_ClearFlag(USART,USART_FLAG_RXNE);
-    data=USART_ReceiveData(USART);
-    // call the reception function
-    if(!comm_do_irq_receive(usart2_comm_dev,data))
-      USART_ITConfig(USART, USART_IT_RXNE, DISABLE);
+    if(__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_PE) !=RESET)
+    {
+      __HAL_UART_CLEAR_PEFLAG(&Uart2Handle);
+    }
   }
-  if(USART_GetITStatus(USART, USART_IT_TC) != RESET)
+  source=__HAL_UART_GET_IT_SOURCE(&Uart2Handle, UART_IT_ERR);
+  if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_FE) != RESET)// frame error
   {
-    USART_ClearFlag(USART,USART_FLAG_TC);
-    if(comm_do_irq_send(usart2_comm_dev,&data))
-      USART_SendData(USART,data);
-    else
-      USART_ITConfig(USART, USART_IT_TC, DISABLE);
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_FEFLAG(&Uart2Handle);
+    }
   }
-  if(USART_GetITStatus(USART,USART_FLAG_ORE) != RESET)// overrun error
+  if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_NE) != RESET)// noise error
   {
-    // cancel any pending reception
-    USART_ITConfig(USART, USART_IT_RXNE, DISABLE);
-    usart2_comm_dev->irq_receiving=0x00;
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_NEFLAG(&Uart2Handle);
+    }
   }
-  if(USART_GetITStatus(USART,USART_IT_PE) != RESET)// parity error
+  if(__HAL_UART_GET_FLAG(&Uart2Handle, UART_FLAG_ORE) != RESET)// overrun error
   {
-    // cancel any pending reception
-    USART_ITConfig(USART, USART_IT_RXNE, DISABLE);
-    usart2_comm_dev->irq_receiving=0x00;
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_OREFLAG(&Uart2Handle);
+    }
   }
 }
 
 void USART_DMA_TX_IRQHandler(void)
 {
-  DMA_Cmd(USART_TX_DMA_STREAM,DISABLE);
-  DMA_ClearFlag(USART_TX_DMA_STREAM,USART_TX_DMA_FLAG_TCIF);
-  DMA_ClearITPendingBit(USART_TX_DMA_STREAM,USART_TX_DMA_FLAG_TCIF);
-  USART_DMACmd(USART, USART_DMAReq_Tx, DISABLE);
-  // call the user function
+  if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmatx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmatx, DMA_IT_TE) != RESET)
+    {
+      /* Disable the transfer error interrupt */
+      __HAL_DMA_DISABLE_IT(Uart2Handle.hdmatx, DMA_IT_TE);
+      /* Clear the transfer error flag */
+      __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmatx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmatx));
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmatx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart2Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmatx, DMA_IT_TC) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart2Handle.hdmatx, DMA_IT_TC);
+      /* Clear the transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart2Handle.hdmatx));
+      CLEAR_BIT(Uart2Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+      HAL_DMA_Abort(Uart2Handle.hdmatx);
+      // call the user function
+      comm_do_dma_send(usart2_comm_dev);
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart2Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmatx, DMA_IT_HT) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart2Handle.hdmatx, DMA_IT_HT);
+      /* Clear the half transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart2Handle.hdmatx));
+    }
+  }
 }
 
 void USART_DMA_RX_IRQHandler(void)
 {
-  DMA_Cmd(USART_RX_DMA_STREAM,DISABLE);
-  DMA_ClearFlag(USART_RX_DMA_STREAM,USART_RX_DMA_FLAG_TCIF);
-  DMA_ClearITPendingBit(USART_RX_DMA_STREAM,USART_RX_DMA_FLAG_TCIF);
-  USART_DMACmd(USART, USART_DMAReq_Rx, DISABLE);
-  // call the user function
+  if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmarx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmarx, DMA_IT_TE) != RESET)
+    {
+      /* Disable the transfer error interrupt */
+      __HAL_DMA_DISABLE_IT(Uart2Handle.hdmarx, DMA_IT_TE);
+      /* Clear the transfer error flag */
+      __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmarx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart2Handle.hdmarx));
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart2Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmarx, DMA_IT_TC) != RESET)
+    {
+      /* Disable the transfer complete interrupt */
+      __HAL_DMA_DISABLE_IT(Uart2Handle.hdmarx, DMA_IT_TC);
+      /* Clear the transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart2Handle.hdmarx));
+      CLEAR_BIT(Uart2Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+      HAL_DMA_Abort(Uart2Handle.hdmarx);
+      // call the user function
+      comm_do_dma_receive(usart2_comm_dev);
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart2Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart2Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart2Handle.hdmarx, DMA_IT_HT) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart2Handle.hdmarx, DMA_IT_HT);
+      /* Clear the half transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart2Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart2Handle.hdmarx));
+    }
+  }
 }
 
 /* public functions*/
-void usart2_init(TComm *comm_dev,TUSART_IRQ_Priorities *priorities)
+void usart2_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities)
 {
   GPIO_InitTypeDef GPIO_InitStructure;
-  NVIC_InitTypeDef NVIC_InitStructure;
 
   /* Enable GPIO clock */
-  USART_CLK_INIT(USART_CLK, ENABLE);
-  USART_TX_GPIO_CLK(USART_TX_GPIO_CLK,ENABLE)
-  USART_RX_GPIO_CLK(USART_RX_GPIO_CLK,ENABLE);
-
-  /* Connect USART pins to AF7 */
-  GPIO_PinAFConfig(USART_TX_GPIO_PORT, USART_TX_SOURCE, USART_TX_AF);
-  GPIO_PinAFConfig(USART_RX_GPIO_PORT, USART_RX_SOURCE, USART_RX_AF);
+  USART_ENABLE_TX_GPIO_CLK;
+  USART_ENABLE_RX_GPIO_CLK;
+  USART_ENABLE_DMA_CLK;
+  // configure the GPIO pins
 
   /* Configure USART Tx and Rx as alternate function push-pull */
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
-  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
-  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
-  GPIO_InitStructure.GPIO_Pin = USART_TX_PIN;
-  GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure);
-
-  GPIO_InitStructure.GPIO_Pin = USART_RX_PIN;
-  GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure);
-
-  /* configure the interrupts */
-  NVIC_InitStructure.NVIC_IRQChannel = USART_IRQn;
-  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priorities->irq_priority;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = priorities->irq_subpriority;
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-  NVIC_Init(&NVIC_InitStructure);
-
-  USART_ITConfig(USART, USART_IT_RXNE |
-                        USART_IT_ORE |
-                        USART_IT_TXE |
-                        USART_IT_CTS |
-                        USART_IT_LBD |
-                        USART_IT_IDLE |
-                        USART_IT_PE |
-                        USART_IT_ERR |
-                        USART_IT_TC, DISABLE);
-
-  /* Clear all USART interrupt flags */
-  USART_ClearFlag(USART,USART_FLAG_RXNE |
-                        USART_FLAG_ORE |
-                        USART_FLAG_TXE |
-                        USART_FLAG_CTS |
-                        USART_FLAG_LBD |
-                        USART_FLAG_IDLE |
-                        USART_FLAG_PE |
-                        USART_FLAG_TC);
-
-  /* Clear all USART interrupt pending bits */
-  USART_ClearITPendingBit(USART, USART_FLAG_RXNE |
-                                 USART_FLAG_ORE |
-                                 USART_FLAG_TXE |
-                                 USART_FLAG_CTS |
-                                 USART_FLAG_LBD |
-                                 USART_FLAG_IDLE |
-                                 USART_FLAG_PE |
-                                 USART_FLAG_TC);
-
-  // configure the DMA channels
+  GPIO_InitStructure.Pin       = USART_TX_PIN;
+  GPIO_InitStructure.Mode      = GPIO_MODE_AF_PP;
+  GPIO_InitStructure.Pull      = GPIO_PULLUP;
+  GPIO_InitStructure.Speed     = GPIO_SPEED_LOW;
+  GPIO_InitStructure.Alternate = GPIO_AF7_USART2;
+  HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure);
+
+  GPIO_InitStructure.Pin       = USART_RX_PIN;
+  HAL_GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure);
+
+  USART_ENABLE_CLK;
+
+  Uart2Handle.Instance          = USART;
+  usart2_config(comm_dev,conf);
+
   if(comm_dev->use_dma)
   {
-    /* enable the DMA clock */
-    USART_DMA_CLK(USART_DMA_CLK, ENABLE);
-    /* Configure TX DMA */
-    DMA_DeInit(USART_TX_DMA_STREAM);
-    DMA_TX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
-    DMA_TX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
-    DMA_TX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
-    DMA_TX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
-    DMA_TX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
-    DMA_TX_InitStructure.DMA_Mode = DMA_Mode_Normal;
-    DMA_TX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(USART->DR));
-    DMA_TX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
-    DMA_TX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
-    DMA_TX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
-    DMA_TX_InitStructure.DMA_Priority = DMA_Priority_High;
-    DMA_TX_InitStructure.DMA_Channel = USART_TX_DMA_CHANNEL;
-    DMA_TX_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
-    /* initialize DMA interrupts */
-    NVIC_InitStructure.NVIC_IRQChannel = USART_DMA_TX_IRQn;
-    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priorities->dma_tx_priority;
-    NVIC_InitStructure.NVIC_IRQChannelSubPriority = priorities->dma_tx_subpriority;
-    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-    NVIC_Init(&NVIC_InitStructure);
-    DMA_ITConfig(USART_TX_DMA_STREAM,DMA_IT_TC,ENABLE);
-    DMA_ITConfig(USART_TX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE);
-
-    /* Configure RX DMA */
-    DMA_DeInit(USART_RX_DMA_STREAM);
-    DMA_RX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
-    DMA_RX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
-    DMA_RX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
-    DMA_RX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
-    DMA_RX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
-    DMA_RX_InitStructure.DMA_Mode = DMA_Mode_Normal;
-    DMA_RX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(USART->DR));
-    DMA_RX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
-    DMA_RX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
-    DMA_RX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
-    DMA_RX_InitStructure.DMA_Priority = DMA_Priority_High;
-    DMA_RX_InitStructure.DMA_Channel = USART_RX_DMA_CHANNEL;
-    DMA_RX_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
-    /* initialize DMA interrupts */
-    NVIC_InitStructure.NVIC_IRQChannel = USART_DMA_RX_IRQn;
-    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priorities->dma_rx_priority;
-    NVIC_InitStructure.NVIC_IRQChannelSubPriority = priority->dma_rx_subpriority;
-    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-    NVIC_Init(&NVIC_InitStructure);
-    DMA_ITConfig(USART_RX_DMA_STREAM,DMA_IT_TC,ENABLE);
-    DMA_ITConfig(USART_RX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE);
+    // configure the DMA channels
+    usart2_hdma_tx.Instance                 = USART_TX_DMA_STREAM;
+    usart2_hdma_tx.Init.Channel             = USART_DMA_CHANNEL;
+    usart2_hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
+    usart2_hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
+    usart2_hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
+    usart2_hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    usart2_hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+    usart2_hdma_tx.Init.Mode                = DMA_NORMAL;
+    usart2_hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
+    usart2_hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+
+    HAL_DMA_Init(&usart2_hdma_tx);
+
+    /* Associate the initialized DMA handle to the UART handle */
+    __HAL_LINKDMA(&Uart2Handle, hdmatx, usart2_hdma_tx);
+
+    /* Configure the DMA handler for reception process */
+    usart2_hdma_rx.Instance                 = USART_RX_DMA_STREAM;
+    usart2_hdma_rx.Init.Channel             = USART_DMA_CHANNEL;
+    usart2_hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+    usart2_hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
+    usart2_hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
+    usart2_hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    usart2_hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+    usart2_hdma_rx.Init.Mode                = DMA_NORMAL;
+    usart2_hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
+    usart2_hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+
+    HAL_DMA_Init(&usart2_hdma_rx);
+
+    /* Associate the initialized DMA handle to the the UART handle */
+    __HAL_LINKDMA(&Uart2Handle, hdmarx, usart2_hdma_rx);
   }
+  usart2_set_priorities(comm_dev,priorities);
+
   /* Initialize the comm structure */
-  comm_dev->receive=usart2_receive;
   comm_dev->send_irq=usart2_send_irq;
+  comm_dev->enable_tx_irq=usart2_enable_tx_irq;
   comm_dev->receive_irq=usart2_receive_irq;
   comm_dev->cancel_receive_irq=usart2_cancel_receive_irq;
   if(comm_dev->use_dma)
@@ -234,40 +250,93 @@ void usart2_init(TComm *comm_dev,TUSART_IRQ_Priorities *priorities)
 
   /* initialize internal variables */
   usart2_comm_dev=comm_dev;
+}
+
+void usart2_config(TComm *comm_dev,UART_InitTypeDef *conf)
+{
+  Uart2Handle.Init.BaudRate     = conf->BaudRate;
+  Uart2Handle.Init.WordLength   = conf->WordLength;
+  Uart2Handle.Init.StopBits     = conf->StopBits;
+  Uart2Handle.Init.Parity       = conf->Parity;
+  Uart2Handle.Init.Mode         = conf->Mode;
+  Uart2Handle.Init.HwFlowCtl    = conf->HwFlowCtl;
+  Uart2Handle.Init.OverSampling = conf->OverSampling;
+  HAL_UART_Init(&Uart2Handle);
+}
 
-  /* Enable the USART2 */
-  USART_Cmd(USART, ENABLE);
+void usart2_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities)
+{
+  HAL_NVIC_SetPriority(USART_IRQn, priorities->irq_priority,priorities->irq_subpriority);
+  HAL_NVIC_EnableIRQ(USART_IRQn);
+  if(comm_dev->use_dma)
+  {
+    HAL_NVIC_SetPriority(USART_DMA_TX_IRQn, priorities->dma_tx_priority,priorities->dma_tx_subpriority);
+    HAL_NVIC_EnableIRQ(USART_DMA_TX_IRQn);
+    HAL_NVIC_SetPriority(USART_DMA_RX_IRQn, priorities->dma_rx_priority,priorities->dma_rx_subpriority);
+    HAL_NVIC_EnableIRQ(USART_DMA_RX_IRQn);
+  }
 }
 
 /* IRQ functions */
-unsigned char usart2_send_irq(unsigned char *data,unsigned int length)
+unsigned char usart2_send_irq(unsigned char first_byte)
 {
+  __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_TC);
+  __HAL_UART_ENABLE_IT(&Uart2Handle, UART_IT_TC);
+  Uart2Handle.Instance->DR=first_byte;
 
+  return 0x00;
 }
 
-unsigned char usart2_receive_irq(unsigned int length)
+unsigned char usart2_enable_tx_irq(void)
 {
+  __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_TC);
+  __HAL_UART_ENABLE_IT(&Uart2Handle, UART_IT_TC);
 
+  return 0x00;
+}
+
+unsigned char usart2_receive_irq(void)
+{
+  /* enable the rx interrupt */
+  __HAL_UART_ENABLE_IT(&Uart2Handle, UART_IT_RXNE);
+
+  return 0x00;
 }
 
 unsigned char usart2_cancel_receive_irq(void)
 {
+  /* disable the rx interrupt */
+  __HAL_UART_DISABLE_IT(&Uart2Handle, UART_IT_RXNE);
 
+  return 0x00;
 }
 
 /* DMA functions */
-unsigned char usart2_send_dma(unsigned char *data,unsigned int lenght)
+unsigned char usart2_send_dma(unsigned char *data,unsigned short int length)
 {
-
+  HAL_DMA_Start_IT(Uart2Handle.hdmatx,(uint32_t)data,(uint32_t)&Uart2Handle.Instance->DR,length);
+  /* Clear the TC flag in the SR register by writing 0 to it */
+  __HAL_UART_CLEAR_FLAG(&Uart2Handle,UART_FLAG_TC);
+  /* Enable the DMA transfer for transmit request by setting the DMAT bit
+     in the UART CR3 register */
+  SET_BIT(Uart2Handle.Instance->CR3, USART_CR3_DMAT);
+
+  return 0x00;
 }
 
-unsigned char usart2_receive_dma(unsigned int length)
+unsigned char usart2_receive_dma(unsigned char *data,unsigned short int length)
 {
+  HAL_DMA_Start_IT(Uart2Handle.hdmarx,(uint32_t)&Uart2Handle.Instance->DR,(uint32_t)data,length);
+  SET_BIT(Uart2Handle.Instance->CR3, USART_CR3_DMAR);
 
+  return 0x00;
 }
 
 unsigned char usart2_cancel_receive_dma(void)
 {
+  CLEAR_BIT(Uart2Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+  HAL_DMA_Abort(Uart2Handle.hdmarx);
 
+  return 0x00;
 }
 
diff --git a/f4/usart/src/usart3.c b/f4/usart/src/usart3.c
index 24a1f696fa387bd43805a2657da20d58e4500807..921746cd4ead2ee457dbf592cf21524119d51954 100644
--- a/f4/usart/src/usart3.c
+++ b/f4/usart/src/usart3.c
@@ -182,7 +182,7 @@ void usart3_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *p
   GPIO_InitStructure.Pin       = USART_TX_PIN;
   GPIO_InitStructure.Mode      = GPIO_MODE_AF_PP;
   GPIO_InitStructure.Pull      = GPIO_PULLUP;
-  GPIO_InitStructure.Speed     = GPIO_SPEED_HIGH;
+  GPIO_InitStructure.Speed     = GPIO_SPEED_LOW;
   GPIO_InitStructure.Alternate = GPIO_AF7_USART3;
   HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure);
 
@@ -197,7 +197,7 @@ void usart3_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *p
   if(comm_dev->use_dma)
   {
     // configure the DMA channels
-    usart3_hdma_tx.Instance                 = USART_RX_DMA_STREAM;
+    usart3_hdma_tx.Instance                 = USART_TX_DMA_STREAM;
     usart3_hdma_tx.Init.Channel             = USART_DMA_CHANNEL;
     usart3_hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
     usart3_hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
diff --git a/f4/usart/src/usart4.c b/f4/usart/src/usart4.c
new file mode 100644
index 0000000000000000000000000000000000000000..301468416126104a99bf0ee869b01d5824fd4050
--- /dev/null
+++ b/f4/usart/src/usart4.c
@@ -0,0 +1,342 @@
+#include "usart4.h"
+
+#define     USART                    USART4
+#define     USART_ENABLE_CLK         __HAL_RCC_USART4_CLK_ENABLE()
+#define     USART_IRQn               USART4_IRQn
+#define     USART_IRQHandler         USART4_IRQHandler
+
+#define     USART_TX_PIN             GPIO_PIN_10                
+#define     USART_TX_GPIO_PORT       GPIOC
+#define     USART_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOC_CLK_ENABLE()
+
+#define     USART_RX_PIN             GPIO_PIN_11
+#define     USART_RX_GPIO_PORT       GPIOC
+#define     USART_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOC_CLK_ENABLE()
+
+/* DMA configuration */
+#define     USART_DMA_CHANNEL        DMA_CHANNEL_4
+#define     USART_ENABLE_DMA_CLK     __HAL_RCC_DMA1_CLK_ENABLE()
+
+#define     USART_TX_DMA_STREAM      DMA1_Stream4
+#define     USART_RX_DMA_STREAM      DMA1_Stream2
+
+#define     USART_DMA_TX_IRQn        DMA1_Stream4_IRQn
+#define     USART_DMA_RX_IRQn        DMA1_Stream2_IRQn
+#define     USART_DMA_TX_IRQHandler  DMA1_Stream4_IRQHandler
+#define     USART_DMA_RX_IRQHandler  DMA1_Stream2_IRQHandler
+
+// private variables
+UART_HandleTypeDef Uart4Handle;
+DMA_HandleTypeDef usart4_hdma_tx;
+DMA_HandleTypeDef usart4_hdma_rx;
+TComm *usart4_comm_dev;
+
+// interrupt handlers
+void USART_IRQHandler(void)
+{
+  unsigned char data,ret;
+  uint32_t source;
+
+  if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_RXNE) != RESET)
+  {
+    if(__HAL_UART_GET_IT_SOURCE(&Uart4Handle, UART_IT_RXNE) !=RESET)
+    {
+      __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_RXNE);
+      data=(uint8_t)(Uart4Handle.Instance->DR & (uint8_t)0x00FF);
+      // call the reception function
+      if(!comm_do_irq_receive(usart4_comm_dev,data))
+        __HAL_UART_DISABLE_IT(&Uart4Handle, UART_IT_RXNE);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_TC) != RESET)
+  {
+    if(__HAL_UART_GET_IT_SOURCE(&Uart4Handle, UART_IT_TC) !=RESET)
+    {
+      __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_TC);
+      ret=comm_do_irq_send(usart4_comm_dev,&data);
+      if(ret==0x01)
+        Uart4Handle.Instance->DR=data;
+      else if(ret==0x00)
+        __HAL_UART_DISABLE_IT(&Uart4Handle, UART_IT_TC);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_PE) != RESET)// parity error
+  {
+    if(__HAL_UART_GET_IT_SOURCE(&Uart4Handle, UART_IT_PE) !=RESET)
+    {
+      __HAL_UART_CLEAR_PEFLAG(&Uart4Handle);
+    }
+  }
+  source=__HAL_UART_GET_IT_SOURCE(&Uart4Handle, UART_IT_ERR);
+  if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_FE) != RESET)// frame error
+  {
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_FEFLAG(&Uart4Handle);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_NE) != RESET)// noise error
+  {
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_NEFLAG(&Uart4Handle);
+    }
+  }
+  if(__HAL_UART_GET_FLAG(&Uart4Handle, UART_FLAG_ORE) != RESET)// overrun error
+  {
+    if(source !=RESET)
+    {
+      __HAL_UART_CLEAR_OREFLAG(&Uart4Handle);
+    }
+  }
+}
+
+void USART_DMA_TX_IRQHandler(void)
+{
+  if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmatx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart4Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmatx, DMA_IT_TE) != RESET)
+    {
+      /* Disable the transfer error interrupt */
+      __HAL_DMA_DISABLE_IT(Uart4Handle.hdmatx, DMA_IT_TE);
+      /* Clear the transfer error flag */
+      __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmatx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart4Handle.hdmatx));
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmatx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart4Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmatx, DMA_IT_TC) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart4Handle.hdmatx, DMA_IT_TC);
+      /* Clear the transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart4Handle.hdmatx));
+      CLEAR_BIT(Uart4Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+      HAL_DMA_Abort(Uart4Handle.hdmatx);
+      // call the user function
+      comm_do_dma_send(usart4_comm_dev);
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart4Handle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmatx, DMA_IT_HT) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart4Handle.hdmatx, DMA_IT_HT);
+      /* Clear the half transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart4Handle.hdmatx));
+    }
+  }
+}
+
+void USART_DMA_RX_IRQHandler(void)
+{
+  if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmarx,__HAL_DMA_GET_TE_FLAG_INDEX(Uart4Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmarx, DMA_IT_TE) != RESET)
+    {
+      /* Disable the transfer error interrupt */
+      __HAL_DMA_DISABLE_IT(Uart4Handle.hdmarx, DMA_IT_TE);
+      /* Clear the transfer error flag */
+      __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmarx, __HAL_DMA_GET_TE_FLAG_INDEX(Uart4Handle.hdmarx));
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(Uart4Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmarx, DMA_IT_TC) != RESET)
+    {
+      /* Disable the transfer complete interrupt */
+      __HAL_DMA_DISABLE_IT(Uart4Handle.hdmarx, DMA_IT_TC);
+      /* Clear the transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX(Uart4Handle.hdmarx));
+      CLEAR_BIT(Uart4Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+      HAL_DMA_Abort(Uart4Handle.hdmarx);
+      // call the user function
+      comm_do_dma_receive(usart4_comm_dev);
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(Uart4Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart4Handle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(Uart4Handle.hdmarx, DMA_IT_HT) != RESET)
+    {
+      /* Disable the half transfer interrupt */
+      __HAL_DMA_DISABLE_IT(Uart4Handle.hdmarx, DMA_IT_HT);
+      /* Clear the half transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(Uart4Handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(Uart4Handle.hdmarx));
+    }
+  }
+}
+
+/* public functions*/
+void usart4_init(TComm *comm_dev,UART_InitTypeDef *conf,TUSART_IRQ_Priorities *priorities)
+{
+  GPIO_InitTypeDef GPIO_InitStructure;
+
+  /* Enable GPIO clock */
+  USART_ENABLE_TX_GPIO_CLK;
+  USART_ENABLE_RX_GPIO_CLK;
+  USART_ENABLE_DMA_CLK;
+  // configure the GPIO pins
+
+  /* Configure USART Tx and Rx as alternate function push-pull */
+  GPIO_InitStructure.Pin       = USART_TX_PIN;
+  GPIO_InitStructure.Mode      = GPIO_MODE_AF_PP;
+  GPIO_InitStructure.Pull      = GPIO_PULLUP;
+  GPIO_InitStructure.Speed     = GPIO_SPEED_LOW;
+  GPIO_InitStructure.Alternate = GPIO_AF7_USART4;
+  HAL_GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure);
+
+  GPIO_InitStructure.Pin       = USART_RX_PIN;
+  HAL_GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure);
+
+  USART_ENABLE_CLK;
+
+  Uart4Handle.Instance          = USART;
+  usart4_config(comm_dev,conf);
+
+  if(comm_dev->use_dma)
+  {
+    // configure the DMA channels
+    usart4_hdma_tx.Instance                 = USART_TX_DMA_STREAM;
+    usart4_hdma_tx.Init.Channel             = USART_DMA_CHANNEL;
+    usart4_hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
+    usart4_hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
+    usart4_hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
+    usart4_hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    usart4_hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+    usart4_hdma_tx.Init.Mode                = DMA_NORMAL;
+    usart4_hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
+    usart4_hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+
+    HAL_DMA_Init(&usart4_hdma_tx);
+
+    /* Associate the initialized DMA handle to the UART handle */
+    __HAL_LINKDMA(&Uart4Handle, hdmatx, usart4_hdma_tx);
+
+    /* Configure the DMA handler for reception process */
+    usart4_hdma_rx.Instance                 = USART_RX_DMA_STREAM;
+    usart4_hdma_rx.Init.Channel             = USART_DMA_CHANNEL;
+    usart4_hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+    usart4_hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
+    usart4_hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
+    usart4_hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    usart4_hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+    usart4_hdma_rx.Init.Mode                = DMA_NORMAL;
+    usart4_hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
+    usart4_hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+
+    HAL_DMA_Init(&usart4_hdma_rx);
+
+    /* Associate the initialized DMA handle to the the UART handle */
+    __HAL_LINKDMA(&Uart4Handle, hdmarx, usart4_hdma_rx);
+  }
+  usart4_set_priorities(comm_dev,priorities);
+
+  /* Initialize the comm structure */
+  comm_dev->send_irq=usart4_send_irq;
+  comm_dev->enable_tx_irq=usart4_enable_tx_irq;
+  comm_dev->receive_irq=usart4_receive_irq;
+  comm_dev->cancel_receive_irq=usart4_cancel_receive_irq;
+  if(comm_dev->use_dma)
+  {
+    comm_dev->send_dma=usart4_send_dma;
+    comm_dev->receive_dma=usart4_receive_dma;
+    comm_dev->cancel_receive_dma=usart4_cancel_receive_dma;
+  }
+  comm_dev->irq_send_cb=0x00000000;
+  comm_dev->irq_receive_cb=0x00000000;
+  comm_dev->dma_send_cb=0x00000000;
+  comm_dev->dma_receive_cb=0x00000000;
+
+  /* initialize internal variables */
+  usart4_comm_dev=comm_dev;
+}
+
+void usart4_config(TComm *comm_dev,UART_InitTypeDef *conf)
+{
+  Uart4Handle.Init.BaudRate     = conf->BaudRate;
+  Uart4Handle.Init.WordLength   = conf->WordLength;
+  Uart4Handle.Init.StopBits     = conf->StopBits;
+  Uart4Handle.Init.Parity       = conf->Parity;
+  Uart4Handle.Init.Mode         = conf->Mode;
+  Uart4Handle.Init.HwFlowCtl    = conf->HwFlowCtl;
+  Uart4Handle.Init.OverSampling = conf->OverSampling;
+  HAL_UART_Init(&Uart4Handle);
+}
+
+void usart4_set_priorities(TComm *comm_dev,TUSART_IRQ_Priorities *priorities)
+{
+  HAL_NVIC_SetPriority(USART_IRQn, priorities->irq_priority,priorities->irq_subpriority);
+  HAL_NVIC_EnableIRQ(USART_IRQn);
+  if(comm_dev->use_dma)
+  {
+    HAL_NVIC_SetPriority(USART_DMA_TX_IRQn, priorities->dma_tx_priority,priorities->dma_tx_subpriority);
+    HAL_NVIC_EnableIRQ(USART_DMA_TX_IRQn);
+    HAL_NVIC_SetPriority(USART_DMA_RX_IRQn, priorities->dma_rx_priority,priorities->dma_rx_subpriority);
+    HAL_NVIC_EnableIRQ(USART_DMA_RX_IRQn);
+  }
+}
+
+/* IRQ functions */
+unsigned char usart4_send_irq(unsigned char first_byte)
+{
+  __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_TC);
+  __HAL_UART_ENABLE_IT(&Uart4Handle, UART_IT_TC);
+  Uart4Handle.Instance->DR=first_byte;
+
+  return 0x00;
+}
+
+unsigned char usart4_enable_tx_irq(void)
+{
+  __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_TC);
+  __HAL_UART_ENABLE_IT(&Uart4Handle, UART_IT_TC);
+
+  return 0x00;
+}
+
+unsigned char usart4_receive_irq(void)
+{
+  /* enable the rx interrupt */
+  __HAL_UART_ENABLE_IT(&Uart4Handle, UART_IT_RXNE);
+
+  return 0x00;
+}
+
+unsigned char usart4_cancel_receive_irq(void)
+{
+  /* disable the rx interrupt */
+  __HAL_UART_DISABLE_IT(&Uart4Handle, UART_IT_RXNE);
+
+  return 0x00;
+}
+
+/* DMA functions */
+unsigned char usart4_send_dma(unsigned char *data,unsigned short int length)
+{
+  HAL_DMA_Start_IT(Uart4Handle.hdmatx,(uint32_t)data,(uint32_t)&Uart4Handle.Instance->DR,length);
+  /* Clear the TC flag in the SR register by writing 0 to it */
+  __HAL_UART_CLEAR_FLAG(&Uart4Handle,UART_FLAG_TC);
+  /* Enable the DMA transfer for transmit request by setting the DMAT bit
+     in the UART CR3 register */
+  SET_BIT(Uart4Handle.Instance->CR3, USART_CR3_DMAT);
+
+  return 0x00;
+}
+
+unsigned char usart4_receive_dma(unsigned char *data,unsigned short int length)
+{
+  HAL_DMA_Start_IT(Uart4Handle.hdmarx,(uint32_t)&Uart4Handle.Instance->DR,(uint32_t)data,length);
+  SET_BIT(Uart4Handle.Instance->CR3, USART_CR3_DMAR);
+
+  return 0x00;
+}
+
+unsigned char usart4_cancel_receive_dma(void)
+{
+  CLEAR_BIT(Uart4Handle.Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+  HAL_DMA_Abort(Uart4Handle.hdmarx);
+
+  return 0x00;
+}
+