diff --git a/include/dynamixel_master_uart.h b/include/dynamixel_master_uart_dma.h
similarity index 100%
rename from include/dynamixel_master_uart.h
rename to include/dynamixel_master_uart_dma.h
diff --git a/include/dynamixel_slave_spi.h b/include/dynamixel_slave_spi.h
index 81d505a04fdebb06a87baf30a351413b375863de..cbf764a92eb7b8cfbf6e296f30f45c366adf8283 100644
--- a/include/dynamixel_slave_spi.h
+++ b/include/dynamixel_slave_spi.h
@@ -1,6 +1,9 @@
 #ifndef _DYNAMIXEL_SLAVE_SPI_H
 #define _DYNAMIXEL_SLAVE_SPI_H
 
+#include "stm32f4xx.h"
+#include "dynamixel.h"
+
 // public functions
 void dyn_slave_init(void);
 void dyn_slave_set_address(uint8_t id);
diff --git a/include/dynamixel_slave_uart_dma.h b/include/dynamixel_slave_uart_dma.h
new file mode 100644
index 0000000000000000000000000000000000000000..706ca3b4bfca758e666044a5834adbc81f2757ee
--- /dev/null
+++ b/include/dynamixel_slave_uart_dma.h
@@ -0,0 +1,16 @@
+#ifndef _DYNAMIXEL_SLAVE_UART_DMA_H
+#define _DYNAXIXEL_SLAVE_UART_DMA_H
+
+#include "dynamixel.h"
+#include "stm32f4xx.h"
+
+// public functions
+void dyn_slave_init(void);
+void dyn_slave_set_address(uint8_t id);
+uint8_t dyn_slave_get_address(void);
+uint8_t dyn_slave_is_packet_ready(void);
+void dyn_slave_get_inst_packet(uint8_t *packet);
+void dyn_slave_send_status_packet(uint8_t error,uint8_t length, uint8_t *data);
+void dyn_slave_resend_status_packet(uint8_t *packet);
+
+#endif
diff --git a/src/bioloid_stm32.c b/src/bioloid_stm32.c
index 702a1d02d548e8272fd2b5114d4e5b544778749d..0c268d7020b3d13527d633aae1335c29066d8166 100644
--- a/src/bioloid_stm32.c
+++ b/src/bioloid_stm32.c
@@ -3,8 +3,8 @@
 
 #include "time.h"
 #include "dynamixel.h"
-#include "dynamixel_master_uart.h"
-#include "dynamixel_slave_spi.h"
+#include "dynamixel_master_uart_dma.h"
+#include "dynamixel_slave_uart_dma.h"
 #include "eeprom.h"
 #include "imu_9dof_dma.h"
 #include "gpio.h"
@@ -30,11 +30,6 @@ uint8_t read_operation(uint8_t address, uint8_t length, uint8_t *data)
   }
 }
 
-void test_led(void)
-{
-  gpio_toggle_led(NORTH_LED);
-}
-
 int32_t main(void)
 {
   uint8_t inst_packet[1024];
diff --git a/src/dynamixel_master_uart_dma.c b/src/dynamixel_master_uart_dma.c
index 83c88c7c8a094c54668465565f081681873ceb39..d00178c78760f4c943e02e2d92fad74b6cd1a3ce 100755
--- a/src/dynamixel_master_uart_dma.c
+++ b/src/dynamixel_master_uart_dma.c
@@ -1,4 +1,4 @@
-#include "dynamixel_master_uart.h"
+#include "dynamixel_master_uart_dma.h"
 #include "time.h"
 
 #define     USART                    USART2
diff --git a/src/dynamixel_slave_spi.c b/src/dynamixel_slave_spi.c
deleted file mode 100644
index ca551a3cb3cf215e3170d2893e8587ad94ba95e7..0000000000000000000000000000000000000000
--- a/src/dynamixel_slave_spi.c
+++ /dev/null
@@ -1,252 +0,0 @@
-#include "stm32f4xx.h"
-#include "system_stm32f4xx.h"
-#include "dynamixel.h"
-#include "dynamixel_slave_spi.h"
-
-#define SPI                           SPI1
-#define SPI_CLK                       RCC_APB2Periph_SPI1
-#define SPI_CLK_INIT                  RCC_APB2PeriphClockCmd
-#define SPI_IRQn                      SPI1_IRQn
-#define SPI_IRQHANDLER                SPI1_IRQHandler
-
-#define SPI_SCK_PIN                   GPIO_Pin_5
-#define SPI_SCK_GPIO_PORT             GPIOA
-#define SPI_SCK_GPIO_CLK              RCC_AHB1Periph_GPIOA
-#define SPI_SCK_SOURCE                GPIO_PinSource5
-#define SPI_SCK_AF                    GPIO_AF_SPI1
-
-#define SPI_MISO_PIN                  GPIO_Pin_6
-#define SPI_MISO_GPIO_PORT            GPIOA
-#define SPI_MISO_GPIO_CLK             RCC_AHB1Periph_GPIOA
-#define SPI_MISO_SOURCE               GPIO_PinSource6
-#define SPI_MISO_AF                   GPIO_AF_SPI1
-
-#define SPI_MOSI_PIN                  GPIO_Pin_7
-#define SPI_MOSI_GPIO_PORT            GPIOA
-#define SPI_MOSI_GPIO_CLK             RCC_AHB1Periph_GPIOA
-#define SPI_MOSI_SOURCE               GPIO_PinSource7
-#define SPI_MOSI_AF                   GPIO_AF_SPI1
-
-#define SPI_NSS_PIN                   GPIO_Pin_4
-#define SPI_NSS_GPIO_PORT             GPIOA
-#define SPI_NSS_GPIO_CLK              RCC_AHB1Periph_GPIOA
-#define SPI_NSS_SOURCE                GPIO_PinSource4
-#define SPI_NSS_AF                    GPIO_AF_SPI1
-
-#define MAX_BUFFER_LEN                1024
-
-// private varibales
-uint8_t dyn_slave_address;// this module slave address
-// input buffer
-uint8_t dyn_slave_rx_buffer[MAX_BUFFER_LEN];
-uint16_t dyn_slave_rx_num_data;
-// output buffer
-uint8_t dyn_slave_tx_buffer[MAX_BUFFER_LEN];
-uint16_t dyn_slave_tx_num_data;
-uint16_t dyn_slave_tx_ptr;
-// instruction packet ready flag
-volatile uint8_t dyn_slave_packet_ready;
-// sending status packet flag
-volatile uint8_t dyn_slave_sending_packet;
-
-// private functions
-void dyn_parse_inst_packet(void)
-{
-  if(dyn_slave_rx_num_data>3)// the length byte has been received
-  {
-    if(dyn_slave_rx_num_data==(dyn_get_length(dyn_slave_rx_buffer)+4))// payload size plus header size
-    {
-      dyn_slave_packet_ready=0x01;
-    }
-  }
-}
-
-void dyn_slave_set_rx_mode(void)
-{
-  /* Disable the Tx empty interrupt */
-  SPI_I2S_ITConfig(SPI, SPI_I2S_IT_TXE, DISABLE);
-  /* Enable the Rx buffer not empty interrupt */
-  SPI_I2S_ITConfig(SPI, SPI_I2S_IT_RXNE, ENABLE);
-}
-
-void dyn_slave_set_tx_mode(void)
-{
-  /* Disable the Rx buffer not empty interrupt */
-  SPI_I2S_ITConfig(SPI, SPI_I2S_IT_RXNE, DISABLE);
-  /* Enable the Tx empty interrupt */
-  SPI_I2S_ITConfig(SPI, SPI_I2S_IT_TXE, ENABLE);
-}
-
-// interrupt handlers
-void SPI_IRQHANDLER(void)
-{
-  /* SPI in Receiver mode */
-  if (SPI_I2S_GetITStatus(SPI, SPI_I2S_IT_RXNE) == SET)
-  {
-    if(dyn_slave_sending_packet==0x00)
-    {
-      GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
-      dyn_slave_rx_buffer[dyn_slave_rx_num_data++] = SPI_I2S_ReceiveData(SPI);
-      dyn_parse_inst_packet(); 
-    }
-    else
-      SPI_I2S_ReceiveData(SPI);
-  }
-  /* SPI in Tramitter mode */
-  if (SPI_I2S_GetITStatus(SPI, SPI_I2S_IT_TXE) == SET)
-  {
-    if(dyn_slave_sending_packet==0x01)
-    {
-      if(dyn_slave_tx_num_data==0x00)// there is no more data to be sent
-      {
-        dyn_slave_tx_ptr=0x00;
-        dyn_slave_sending_packet=0x00;
-        // disable interrupts
-        dyn_slave_set_rx_mode();
-        SPI_I2S_ReceiveData(SPI);
-      }
-      else
-      {
-        SPI_I2S_SendData(SPI,dyn_slave_tx_buffer[dyn_slave_tx_ptr++]);// send the next_byte
-        dyn_slave_tx_num_data--;
-      }
-    }
-  }
-}
-
-// public functions
-void dyn_slave_init(void)
-{
-  uint16_t i;
-  GPIO_InitTypeDef GPIO_InitStructure;
-  NVIC_InitTypeDef NVIC_InitStructure;
-  SPI_InitTypeDef  SPI_InitStructure;
-
-  // initialize the buffers
-  for(i=0;i<MAX_BUFFER_LEN;i++)
-  {
-    dyn_slave_rx_buffer[i]=0x00;
-    dyn_slave_tx_buffer[i]=0x00;
-  }
-  dyn_slave_rx_num_data=0x00;
-  dyn_slave_tx_num_data=0x00;
-  dyn_slave_tx_ptr=0x00;
-  // initialize the flags
-  dyn_slave_packet_ready=0x00;
-  dyn_slave_sending_packet=0x00;
-
-  /* Enable the SPI clock */
-  SPI_CLK_INIT(SPI_CLK, ENABLE);
-
-  /* Enable GPIO clocks */
-  RCC_AHB1PeriphClockCmd(SPI_SCK_GPIO_CLK | SPI_MISO_GPIO_CLK | SPI_MOSI_GPIO_CLK | SPI_NSS_GPIO_CLK, ENABLE);
-
-  /* SPI GPIO Configuration --------------------------------------------------*/
-
-  /* Connect SPI pins to AF5 */
-  GPIO_PinAFConfig(SPI_SCK_GPIO_PORT, SPI_SCK_SOURCE, SPI_SCK_AF);
-  GPIO_PinAFConfig(SPI_MISO_GPIO_PORT, SPI_MISO_SOURCE, SPI_MISO_AF);
-  GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, SPI_MOSI_SOURCE, SPI_MOSI_AF);
-  GPIO_PinAFConfig(SPI_NSS_GPIO_PORT, SPI_NSS_SOURCE, SPI_NSS_AF);
-
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
-  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
-
-  /* SPI SCK pin configuration */
-  GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN;
-  GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
-
-  /* SPI  MISO pin configuration */
-  GPIO_InitStructure.GPIO_Pin =  SPI_MISO_PIN;
-  GPIO_Init(SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
-
-  /* SPI  MOSI pin configuration */
-  GPIO_InitStructure.GPIO_Pin =  SPI_MOSI_PIN;
-  GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
-
-  /* SPI  NSS pin configuration */
-  GPIO_InitStructure.GPIO_Pin =  SPI_NSS_PIN;
-  GPIO_Init(SPI_NSS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* SPI configuration -------------------------------------------------------*/
-  SPI_I2S_DeInit(SPI);
-  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
-  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
-  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
-  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
-  SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
-  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
-  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
-  SPI_InitStructure.SPI_CRCPolynomial = 7;
-  SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
-  SPI_Init(SPI, &SPI_InitStructure);
-
-  /* Configure the SPI interrupt priority */
-  NVIC_InitStructure.NVIC_IRQChannel = SPI_IRQn;
-  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-  NVIC_Init(&NVIC_InitStructure);
-
-  /* by default set receive mode */
-  dyn_slave_set_rx_mode();
-
-  /* Enable the SPI peripheral */
-  SPI_Cmd(SPI, ENABLE);
-}
-
-void dyn_slave_set_address(uint8_t id)
-{
-  dyn_slave_address=id;
-}
-
-uint8_t dyn_slave_get_address(void)
-{
-  return dyn_slave_address;
-}
-
-uint8_t dyn_slave_is_packet_ready(void)
-{
-  return dyn_slave_packet_ready;
-}
-
-void dyn_slave_get_inst_packet(uint8_t *packet)
-{
-  uint8_t i;
-
-  for(i=0;i<dyn_slave_rx_num_data;i++)
-    packet[i]=dyn_slave_rx_buffer[i];
-  dyn_slave_rx_num_data=0x00;
-  dyn_slave_packet_ready=0x00;
-}
-
-void dyn_slave_send_status_packet(uint8_t error,uint8_t length, uint8_t *data)
-{
-  // wait until the previous transmission has ended (if any)
-  while(dyn_slave_sending_packet==0x01);
-  // create the status packet
-  dyn_init_status_packet(dyn_slave_tx_buffer);
-  dyn_set_status_error(dyn_slave_tx_buffer,error);
-  dyn_set_id(dyn_slave_tx_buffer,dyn_slave_address);
-  dyn_set_status_data(dyn_slave_tx_buffer,length,data);
-  dyn_set_checksum(dyn_slave_tx_buffer);
-  // start sending the package
-  dyn_slave_tx_num_data=dyn_get_length(dyn_slave_tx_buffer)+4+1;
-  dyn_slave_sending_packet=0x01;
-  dyn_slave_set_tx_mode();
-}
-
-void dyn_slave_resend_status_packet(uint8_t *packet)
-{
-  // wait until the previous transmission has ended (if any)
-  while(dyn_slave_sending_packet==0x01);
-  // create the status packet
-  dyn_init_status_packet(dyn_slave_tx_buffer);
-  dyn_copy_packet(packet,dyn_slave_tx_buffer);
-  // start sending the package
-  dyn_slave_tx_num_data=dyn_get_length(dyn_slave_tx_buffer)+4+1;
-  dyn_slave_sending_packet=0x01;
-  dyn_slave_set_tx_mode();
-}
diff --git a/src/dynamixel_slave_uart_dma.c b/src/dynamixel_slave_uart_dma.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b981fd6cc025d2d565d429ee2cd0f13649f4e5b
--- /dev/null
+++ b/src/dynamixel_slave_uart_dma.c
@@ -0,0 +1,290 @@
+#include "dynamixel_slave_uart_dma.h"
+
+#define     DYN_SLAVE                    USART3
+#define     DYN_SLAVE_CLK                RCC_APB1Periph_USART3
+#define     DYN_SLAVE_CLK_INIT           RCC_APB1PeriphClockCmd
+#define     DYN_SLAVE_IRQn               USART3_IRQn
+#define     DYN_SLAVE_IRQHandler         USART3_IRQHandler
+
+#define     DYN_SLAVE_TX_PIN             GPIO_Pin_10                
+#define     DYN_SLAVE_TX_GPIO_PORT       GPIOC
+#define     DYN_SLAVE_TX_GPIO_CLK        RCC_AHB1Periph_GPIOC
+#define     DYN_SLAVE_TX_SOURCE          GPIO_PinSource10
+#define     DYN_SLAVE_TX_AF              GPIO_AF_USART3
+
+#define     DYN_SLAVE_RX_PIN             GPIO_Pin_11
+#define     DYN_SLAVE_RX_GPIO_PORT       GPIOC
+#define     DYN_SLAVE_RX_GPIO_CLK        RCC_AHB1Periph_GPIOB
+#define     DYN_SLAVE_RX_SOURCE          GPIO_PinSource11
+#define     DYN_SLAVE_RX_AF              GPIO_AF_USART3
+
+/* DMA configuration */
+#define     DYN_SLAVE_DR_ADDRESS         ((uint32_t)USART3 + 0x04) 
+#define     DYN_SLAVE_DMA                DMA1
+#define     DYN_SLAVE_DMA_CLK            RCC_AHB1Periph_DMA1
+
+#define     DYN_SLAVE_TX_DMA_CHANNEL     DMA_Channel_4
+#define     DYN_SLAVE_TX_DMA_STREAM      DMA1_Stream3
+#define     DYN_SLAVE_TX_DMA_FLAG_FEIF   DMA_FLAG_FEIF3
+#define     DYN_SLAVE_TX_DMA_FLAG_DMEIF  DMA_FLAG_DMEIF3
+#define     DYN_SLAVE_TX_DMA_FLAG_TEIF   DMA_FLAG_TEIF3
+#define     DYN_SLAVE_TX_DMA_FLAG_HTIF   DMA_FLAG_HTIF3
+#define     DYN_SLAVE_TX_DMA_FLAG_TCIF   DMA_FLAG_TCIF3
+
+#define     DYN_SLAVE_RX_DMA_CHANNEL     DMA_Channel_4
+#define     DYN_SLAVE_RX_DMA_STREAM      DMA1_Stream1
+#define     DYN_SLAVE_RX_DMA_FLAG_FEIF   DMA_FLAG_FEIF1
+#define     DYN_SLAVE_RX_DMA_FLAG_DMEIF  DMA_FLAG_DMEIF1
+#define     DYN_SLAVE_RX_DMA_FLAG_TEIF   DMA_FLAG_TEIF1
+#define     DYN_SLAVE_RX_DMA_FLAG_HTIF   DMA_FLAG_HTIF1
+#define     DYN_SLAVE_RX_DMA_FLAG_TCIF   DMA_FLAG_TCIF1
+
+#define     DYN_SLAVE_DMA_TX_IRQn        DMA1_Stream3_IRQn
+#define     DYN_SLAVE_DMA_RX_IRQn        DMA1_Stream1_IRQn
+#define     DYN_SLAVE_DMA_TX_IRQHandler  DMA1_Stream3_IRQHandler
+#define     DYN_SLAVE_DMA_RX_IRQHandler  DMA1_Stream1_IRQHandler
+
+#define     MAX_BUFFER_LEN                1024
+
+// private variables
+uint8_t dyn_slave_address;// this module slave address
+// input buffer
+uint8_t dyn_slave_rx_buffer[MAX_BUFFER_LEN];
+volatile uint8_t dyn_slave_receiving_header;
+// output buffer
+uint8_t dyn_slave_tx_buffer[MAX_BUFFER_LEN];
+// instruction packet ready flag
+volatile uint8_t dyn_slave_packet_ready;
+// sending status packet flag
+volatile uint8_t dyn_slave_sending_packet;
+// DMA initialization data structures
+DMA_InitTypeDef  DYN_SLAVE_DMA_TX_InitStructure;
+DMA_InitTypeDef  DYN_SLAVE_DMA_RX_InitStructure;
+
+// private functions
+
+// interrupt handlers
+void DYN_SLAVE_IRQHandler(void)
+{
+  if(USART_GetITStatus(DYN_SLAVE, USART_IT_TC) != RESET)
+  {
+    USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC);
+    USART_ITConfig(DYN_SLAVE, USART_IT_TC, DISABLE);
+    dyn_slave_sending_packet=0x00;
+    // set up the DMA RX transaction
+    DYN_SLAVE_DMA_RX_InitStructure.DMA_BufferSize = 4;
+    DYN_SLAVE_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dyn_slave_rx_buffer;
+    DMA_Init(DYN_SLAVE_RX_DMA_STREAM,&DYN_SLAVE_DMA_RX_InitStructure);
+    DMA_ITConfig(DYN_SLAVE_RX_DMA_STREAM,DMA_IT_TC,ENABLE);
+    DMA_Cmd(DYN_SLAVE_RX_DMA_STREAM,ENABLE);
+    USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, ENABLE);
+    dyn_slave_receiving_header=0x01;
+  }
+}
+
+void DYN_SLAVE_DMA_TX_IRQHandler(void)
+{
+  DMA_ClearFlag(DYN_SLAVE_TX_DMA_STREAM,DYN_SLAVE_TX_DMA_FLAG_TCIF);
+  DMA_ClearITPendingBit(DYN_SLAVE_TX_DMA_STREAM,DYN_SLAVE_TX_DMA_FLAG_TCIF);
+  USART_ITConfig(DYN_SLAVE, USART_IT_TC, ENABLE);
+}
+
+void DYN_SLAVE_DMA_RX_IRQHandler(void)
+{
+  if(dyn_slave_receiving_header==0x01)
+  {
+    DMA_ClearFlag(DYN_SLAVE_RX_DMA_STREAM,DYN_SLAVE_RX_DMA_FLAG_TCIF);
+    DMA_ClearITPendingBit(DYN_SLAVE_RX_DMA_STREAM,DYN_SLAVE_RX_DMA_FLAG_TCIF);
+    DYN_SLAVE_DMA_RX_InitStructure.DMA_BufferSize = dyn_get_length(dyn_slave_rx_buffer);
+    DYN_SLAVE_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&dyn_slave_rx_buffer[4];
+    DMA_Init(DYN_SLAVE_RX_DMA_STREAM,&DYN_SLAVE_DMA_RX_InitStructure);
+    DMA_Cmd(DYN_SLAVE_RX_DMA_STREAM,ENABLE);
+    USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, ENABLE);
+    dyn_slave_receiving_header=0x00;
+  }
+  else
+  {
+    DMA_ClearFlag(DYN_SLAVE_RX_DMA_STREAM,DYN_SLAVE_RX_DMA_FLAG_TCIF);
+    DMA_ClearITPendingBit(DYN_SLAVE_RX_DMA_STREAM,DYN_SLAVE_RX_DMA_FLAG_TCIF);
+    DMA_ITConfig(DYN_SLAVE_RX_DMA_STREAM,DMA_IT_TC,DISABLE);
+    dyn_slave_packet_ready=0x01;
+  }
+}
+
+// public functions
+void dyn_slave_init(void)
+{
+  uint16_t i;
+  GPIO_InitTypeDef GPIO_InitStructure;
+  NVIC_InitTypeDef NVIC_InitStructure;
+  USART_InitTypeDef USART_InitStructure;
+
+  /* Enable GPIO clock */
+  DYN_SLAVE_CLK_INIT(DYN_SLAVE_CLK, ENABLE);
+  RCC_AHB1PeriphClockCmd(DYN_SLAVE_TX_GPIO_CLK | DYN_SLAVE_RX_GPIO_CLK, ENABLE);
+  // configure the GPIO pins
+
+  /* Connect USART pins to AF7 */
+  GPIO_PinAFConfig(DYN_SLAVE_TX_GPIO_PORT, DYN_SLAVE_TX_SOURCE, DYN_SLAVE_TX_AF);
+  GPIO_PinAFConfig(DYN_SLAVE_RX_GPIO_PORT, DYN_SLAVE_RX_SOURCE, DYN_SLAVE_RX_AF);
+
+  /* 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 = DYN_SLAVE_TX_PIN;
+  GPIO_Init(DYN_SLAVE_TX_GPIO_PORT, &GPIO_InitStructure);
+
+  GPIO_InitStructure.GPIO_Pin = DYN_SLAVE_RX_PIN;
+  GPIO_Init(DYN_SLAVE_RX_GPIO_PORT, &GPIO_InitStructure);
+
+  // initialize the buffers
+  for(i=0;i<MAX_BUFFER_LEN;i++)
+  {
+    dyn_slave_rx_buffer[i]=0x00;
+    dyn_slave_tx_buffer[i]=0x00;
+  }
+  // initialize the flags
+  dyn_slave_packet_ready=0x00;
+  dyn_slave_sending_packet=0x00;
+  dyn_slave_receiving_header=0x01;
+
+  USART_DeInit(DYN_SLAVE);
+  USART_StructInit(&USART_InitStructure);
+  // configure the serial port
+  USART_InitStructure.USART_BaudRate = 115200;
+  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
+  USART_InitStructure.USART_StopBits = USART_StopBits_1;
+  USART_InitStructure.USART_Parity = USART_Parity_No;
+  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+  USART_Init(DYN_SLAVE, &USART_InitStructure);
+
+  NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  USART_ITConfig(DYN_SLAVE, 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);
+  USART_ClearFlag(DYN_SLAVE,USART_FLAG_RXNE | USART_FLAG_ORE | USART_FLAG_TXE | USART_FLAG_CTS | USART_FLAG_LBD | USART_FLAG_IDLE | USART_FLAG_PE | USART_FLAG_TC);
+  USART_ClearITPendingBit(DYN_SLAVE, USART_FLAG_RXNE | USART_FLAG_ORE | USART_FLAG_TXE | USART_FLAG_CTS | USART_FLAG_LBD | USART_FLAG_IDLE | USART_FLAG_PE | USART_FLAG_TC);
+  /* Enable the DYN_SLAVE3 */
+  USART_Cmd(DYN_SLAVE, ENABLE);
+
+  // configure the DMA channels
+  /* Configure TX DMA */
+  RCC_AHB1PeriphClockCmd(DYN_SLAVE_DMA_CLK, ENABLE);
+  DMA_DeInit(DYN_SLAVE_TX_DMA_STREAM);
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_Mode = DMA_Mode_Normal;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(DYN_SLAVE->DR));
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_Priority = DMA_Priority_High;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_Channel = DYN_SLAVE_TX_DMA_CHANNEL;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
+  DYN_SLAVE_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dyn_slave_tx_buffer;
+  DMA_Init(DYN_SLAVE_TX_DMA_STREAM,&DYN_SLAVE_DMA_TX_InitStructure);
+  /* initialize DMA interrupts */
+  NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_DMA_TX_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+  DMA_ITConfig(DYN_SLAVE_TX_DMA_STREAM,DMA_IT_TC,ENABLE);
+  DMA_ITConfig(DYN_SLAVE_TX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE);
+
+  /* Configure RX DMA */
+  DMA_DeInit(DYN_SLAVE_RX_DMA_STREAM);
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_BufferSize = 4;// transfer the first 3 bytes
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_Mode = DMA_Mode_Normal;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(DYN_SLAVE->DR));
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_Priority = DMA_Priority_High;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_Channel = DYN_SLAVE_RX_DMA_CHANNEL;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
+  DYN_SLAVE_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dyn_slave_rx_buffer;
+  DMA_Init(DYN_SLAVE_RX_DMA_STREAM,&DYN_SLAVE_DMA_RX_InitStructure);
+  /* initialize DMA interrupts */
+  NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_DMA_RX_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+  DMA_ITConfig(DYN_SLAVE_RX_DMA_STREAM,DMA_IT_TC,ENABLE);
+  DMA_ITConfig(DYN_SLAVE_RX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE);
+
+  DMA_Cmd(DYN_SLAVE_RX_DMA_STREAM,ENABLE);
+  USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, ENABLE);
+}
+
+void dyn_slave_set_address(uint8_t id)
+{
+  dyn_slave_address=id;  
+}
+
+uint8_t dyn_slave_get_address(void)
+{
+  return dyn_slave_address;
+}
+
+uint8_t dyn_slave_is_packet_ready(void)
+{
+  return dyn_slave_packet_ready;
+}
+
+void dyn_slave_get_inst_packet(uint8_t *packet)
+{
+  uint8_t i;
+
+  for(i=0;i<dyn_get_length(dyn_slave_rx_buffer)+4;i++)
+    packet[i]=dyn_slave_rx_buffer[i];
+  dyn_slave_packet_ready=0x00;
+}
+
+void dyn_slave_send_status_packet(uint8_t error,uint8_t length, uint8_t *data)
+{
+  // wait until the previous transmission has ended (if any)
+  while(dyn_slave_sending_packet==0x01);
+  // create the status packet
+  dyn_init_status_packet(dyn_slave_tx_buffer);
+  dyn_set_status_error(dyn_slave_tx_buffer,error);
+  dyn_set_id(dyn_slave_tx_buffer,dyn_slave_address);
+  dyn_set_status_data(dyn_slave_tx_buffer,length,data);
+  dyn_set_checksum(dyn_slave_tx_buffer);
+  // set the DMA transfer
+  DMA_SetCurrDataCounter(DYN_SLAVE_TX_DMA_STREAM,dyn_get_length(dyn_slave_tx_buffer)+4);
+  DMA_Cmd(DYN_SLAVE_TX_DMA_STREAM,ENABLE);
+  USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC);
+  USART_DMACmd(DYN_SLAVE, USART_DMAReq_Tx, ENABLE);
+  dyn_slave_sending_packet=0x01;
+}
+
+void dyn_slave_resend_status_packet(uint8_t *packet)
+{
+  // wait until the previous transmission has ended (if any)
+  while(dyn_slave_sending_packet==0x01);
+  // create the status packet
+  dyn_init_status_packet(dyn_slave_tx_buffer);
+  dyn_copy_packet(packet,dyn_slave_tx_buffer); 
+  // set the DMA transfer
+  DMA_SetCurrDataCounter(DYN_SLAVE_TX_DMA_STREAM,dyn_get_length(dyn_slave_tx_buffer)+4);
+  DMA_Cmd(DYN_SLAVE_TX_DMA_STREAM,ENABLE);
+  USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC);
+  USART_DMACmd(DYN_SLAVE, USART_DMAReq_Tx, ENABLE);
+  dyn_slave_sending_packet=0x01;
+}