diff --git a/Makefile b/Makefile
index e088643f716087d80e4b17a93b9eb64e12874532..93bfccb771613b510a042179f370c1947bcbc45a 100755
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ BUILD_PATH=build
 COMPILE_OPTS = -mlittle-endian -mcpu=cortex-m4 -mthumb -mthumb-interwork 
 COMPILE_OPTS += -Wall -g -O2 -fno-common 
 COMPILE_OPTS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
-COMPILE_OPTS += -ffreestanding -nostdlib -D$(PROCESSOR_MACRO) -DARM_MATH_CM4 -D__FPU_PRESENT
+COMPILE_OPTS += -ffreestanding -nostdlib -D$(PROCESSOR_MACRO) -DARM_MATH_CM4 -D__FPU_PRESENT -DHSE_VALUE=8000000
 INCLUDE_DIRS = -I$(STM32_LIB_PATH)/include -I$(STM32_LIB_PATH)/include/core -I$(STM32_LIB_PATH)/include/devices -I$(STM32_DSP_LIB_PATH)/include -I${DYNAMIXEL_LIB_PATH}/include -I./include
 LIBRARY_DIRS = -L$(STM32_LIB_PATH)/lib -L$(STM32_DSP_LIB_PATH)/lib -L$(DYNAMIXEL_LIB_PATH)/lib -L/usr/arm-none-eabi/lib/fpu/
 
diff --git a/include/dynamixel_master_uart.h b/include/dynamixel_master_uart.h
index 1e595fd3a71df29fa62e38aad4846a2bd9772bcf..4f86ba0dc5a55a840d1e89c21780229e3af4de0a 100755
--- a/include/dynamixel_master_uart.h
+++ b/include/dynamixel_master_uart.h
@@ -4,9 +4,6 @@
 #include "stm32f4xx.h"
 #include "dynamixel.h"
 
-// interrupt handlers
-void USART2_IRQHandler(void);
-
 // dynamixel master functions
 void dyn_master_init(void);
 void dyn_master_flush(void);
diff --git a/include/dynamixel_slave_spi.h b/include/dynamixel_slave_spi.h
new file mode 100644
index 0000000000000000000000000000000000000000..81d505a04fdebb06a87baf30a351413b375863de
--- /dev/null
+++ b/include/dynamixel_slave_spi.h
@@ -0,0 +1,13 @@
+#ifndef _DYNAMIXEL_SLAVE_SPI_H
+#define _DYNAMIXEL_SLAVE_SPI_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 a501776a8b034743ad5344bfc326bf5dad6d0392..84e7c860d8937929a7c61b4d60374c2824f69e5c 100644
--- a/src/bioloid_stm32.c
+++ b/src/bioloid_stm32.c
@@ -1,158 +1,17 @@
 #include "stm32f4xx.h"
 #include "system_stm32f4xx.h"
 
-#define SPIx                           SPI1
-#define SPIx_CLK                       RCC_APB2Periph_SPI1
-#define SPIx_CLK_INIT                  RCC_APB2PeriphClockCmd
-#define SPIx_IRQn                      SPI1_IRQn
-#define SPIx_IRQHANDLER                SPI1_IRQHandler
-
-#define SPIx_SCK_PIN                   GPIO_Pin_5
-#define SPIx_SCK_GPIO_PORT             GPIOA
-#define SPIx_SCK_GPIO_CLK              RCC_AHB1Periph_GPIOA
-#define SPIx_SCK_SOURCE                GPIO_PinSource5
-#define SPIx_SCK_AF                    GPIO_AF_SPI1
-
-#define SPIx_MISO_PIN                  GPIO_Pin_6
-#define SPIx_MISO_GPIO_PORT            GPIOA
-#define SPIx_MISO_GPIO_CLK             RCC_AHB1Periph_GPIOA
-#define SPIx_MISO_SOURCE               GPIO_PinSource6
-#define SPIx_MISO_AF                   GPIO_AF_SPI1
-
-#define SPIx_MOSI_PIN                  GPIO_Pin_7
-#define SPIx_MOSI_GPIO_PORT            GPIOA
-#define SPIx_MOSI_GPIO_CLK             RCC_AHB1Periph_GPIOA
-#define SPIx_MOSI_SOURCE               GPIO_PinSource7
-#define SPIx_MOSI_AF                   GPIO_AF_SPI1
-
-#define SPIx_NSS_PIN                   GPIO_Pin_4
-#define SPIx_NSS_GPIO_PORT             GPIOA
-#define SPIx_NSS_GPIO_CLK              RCC_AHB1Periph_GPIOA
-#define SPIx_NSS_SOURCE                GPIO_PinSource4
-#define SPIx_NSS_AF                    GPIO_AF_SPI1
-
-uint8_t rx_buffer[32];
-uint8_t rx_num;
-uint8_t tx_buffer[32];
-uint8_t tx_num;
-
-void SPIx_IRQHANDLER(void)
-{
-  /* SPI in Receiver mode */
-  if (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_RXNE) == SET)
-  {
-    GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
-    rx_buffer[rx_num]=SPI_I2S_ReceiveData(SPIx);
-    tx_buffer[rx_num]=rx_buffer[rx_num];
-    rx_num=(rx_num+1)%32;
-    if(rx_num==4)
-    {
-      SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_TXE, ENABLE);
-      SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_RXNE, DISABLE);
-      rx_num=0;
-    }
-  }
-  /* SPI in Tramitter mode */
-  if (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_TXE) == SET)
-  {
-    GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
-    SPI_I2S_SendData(SPIx, tx_buffer[tx_num]);
-    tx_num=(tx_num+1)%32;
-    if(tx_num==4)
-    {
-      SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_TXE, DISABLE);
-      SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_RXNE, ENABLE);
-      tx_num=0;
-    }
-  }
-}
-
-void SPI_Config(void)
-{
-  GPIO_InitTypeDef GPIO_InitStructure;
-  NVIC_InitTypeDef NVIC_InitStructure;
-  SPI_InitTypeDef  SPI_InitStructure;
-
-  /* Peripheral Clock Enable -------------------------------------------------*/
-  /* Enable the SPI clock */
-  SPIx_CLK_INIT(SPIx_CLK, ENABLE);
-
-  /* Enable GPIO clocks */
-  RCC_AHB1PeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK | SPIx_NSS_GPIO_CLK, ENABLE);
-
-  /* SPI GPIO Configuration --------------------------------------------------*/
-  /* GPIO Deinitialisation */
-  GPIO_DeInit(SPIx_SCK_GPIO_PORT);
-  GPIO_DeInit(SPIx_MISO_GPIO_PORT);
-  GPIO_DeInit(SPIx_MOSI_GPIO_PORT);
-  GPIO_DeInit(SPIx_NSS_GPIO_PORT);
-
-  /* Connect SPI pins to AF5 */
-  GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);
-  GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);
-  GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);
-  GPIO_PinAFConfig(SPIx_NSS_GPIO_PORT, SPIx_NSS_SOURCE, SPIx_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 = SPIx_SCK_PIN;
-  GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure);
-
-  /* SPI  MISO pin configuration */
-  GPIO_InitStructure.GPIO_Pin =  SPIx_MISO_PIN;
-  GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure);
-
-  /* SPI  MOSI pin configuration */
-  GPIO_InitStructure.GPIO_Pin =  SPIx_MOSI_PIN;
-  GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);
-
-  /* SPI  NSS pin configuration */
-  GPIO_InitStructure.GPIO_Pin =  SPIx_NSS_PIN;
-  GPIO_Init(SPIx_NSS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* SPI configuration -------------------------------------------------------*/
-  SPI_I2S_DeInit(SPIx);
-  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;
-  /* Configure the Priority Group to 1 bit */
-  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
-
-  /* Configure the SPI interrupt priority */
-  NVIC_InitStructure.NVIC_IRQChannel = SPIx_IRQn;
-  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-  NVIC_Init(&NVIC_InitStructure);
-
-  /* Slave board configuration */
-  /* Initializes the SPI communication */
-  SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
-  SPI_Init(SPIx, &SPI_InitStructure);
-
-  /* Enable the Rx buffer not empty interrupt */
-  SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_RXNE, ENABLE);
-
-  /* Enable the Tx empty interrupt */
-  SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_TXE, DISABLE);
-
-  /* Enable the SPI peripheral */
-  SPI_Cmd(SPIx, ENABLE);
-}
+#include "time.h"
+#include "dynamixel.h"
+#include "dynamixel_master_uart.h"
+#include "dynamixel_slave_spi.h"
 
 int32_t main(void)
 {
+  uint8_t inst_packet[1024];
+  uint8_t status_packet[1024];
+  uint8_t data[1024];
   GPIO_InitTypeDef  GPIO_InitStructure;
-  uint8_t data,i;
 
   /* GPIOD Periph clock enable */
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
@@ -165,21 +24,59 @@ int32_t main(void)
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOD, &GPIO_InitStructure);
 
-  rx_num=0;
-  tx_num=0;
-  for(i=0;i<32;i++)
-  {
-    tx_buffer[i]=0x00;
-    rx_buffer[i]=0x00;
-  }
-
-  /* configure the SPI interface */
-  SPI_Config();
+  /* initialize the 1ms system timer */
+  time_init();
+  /* initialize the dynamixel master interface */
+  dyn_master_init();  
+  dyn_master_set_timeout(10);
+  /* initialize the dynamixel slave interface*/
+  dyn_slave_init();
+  dyn_slave_set_address(13);
 
   while(1)                             /* main function does not return */
   {
+    if(dyn_slave_is_packet_ready())// check if a new instruction packet has been received
+    {
+      dyn_slave_get_inst_packet(inst_packet);// get the received packet
+      // check the packet checksum
+      if(dyn_check_checksum(inst_packet)==0xFF)// the incomming packet is okay
+      {
+        // check address
+        if(dyn_get_id(inst_packet)==dyn_slave_get_address())// the packet is addressed to this device
+        {
+          // process the packet
+          GPIO_ToggleBits(GPIOD, GPIO_Pin_15); 
+          dyn_slave_send_status_packet(DYN_NO_ERROR,0,data);
+        }
+        else// the packet is addressed to another device
+        {
+          // send the incomming packet to the dynamixel bus
+          if(dyn_master_resend_inst_packet(inst_packet,status_packet)==DYN_NO_ERROR)
+          {
+            // send the answer back to the computer
+            dyn_slave_resend_status_packet(status_packet);
+          }
+        }
+      }
+      else
+      {
+        // send a checksum error answer
+        dyn_slave_send_status_packet(DYN_CHECKSUM_ERROR,0,0x00);
+      }
+    }
+
     // polling example
 //    GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
+//    if(dyn_master_ping(4))
+//      GPIO_SetBits(GPIOD, GPIO_Pin_12);
+//    else
+//      GPIO_ResetBits(GPIOD, GPIO_Pin_12);
+//    delay_ms(10);
+//    if(dyn_master_ping(3))
+//      GPIO_SetBits(GPIOD, GPIO_Pin_14);
+//    else
+//      GPIO_ResetBits(GPIOD, GPIO_Pin_14);
+//    delay_ms(1000);
 //    while(!SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE));
 //    data=SPI_I2S_ReceiveData(SPIx);
 //    while(!SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE));
diff --git a/src/dynamixel_master_uart.c b/src/dynamixel_master_uart.c
index ff486616965ffc72018825a5941ec8388e9e7374..ee0728675fbe705f9c92d9cb70bafce32a4bb04c 100755
--- a/src/dynamixel_master_uart.c
+++ b/src/dynamixel_master_uart.c
@@ -19,17 +19,15 @@
 #define     USART_RX_SOURCE          GPIO_PinSource3
 #define     USART_RX_AF              GPIO_AF_USART2
 
-#define     USART_TX_EN_PIN          GPIO_Pin_0
+#define     USART_TX_EN_PIN          GPIO_Pin_1
 #define     USART_TX_EN_GPIO_PORT    GPIOA
 #define     USART_TX_EN_GPIO_CLK     RCC_AHB1Periph_GPIOA
-#define     USART_TX_EN_SOURCE       GPIO_PinSource0
-#define     USART_TX_EN_AF           GPIO_AF_OUT
+#define     USART_TX_EN_SOURCE       GPIO_PinSource1
 
-#define     USART_RX_EN_PIN          GPIO_Pin_1
+#define     USART_RX_EN_PIN          GPIO_Pin_0
 #define     USART_RX_EN_GPIO_PORT    GPIOA
 #define     USART_RX_EN_GPIO_CLK     RCC_AHB1Periph_GPIOA
-#define     USART_RX_EN_SOURCE       GPIO_PinSource1
-#define     USART_RX_EN_AF           GPIO_AF_OUT
+#define     USART_RX_EN_SOURCE       GPIO_PinSource0
 
 #define     MAX_BUFFER_LEN           1024
 
@@ -91,7 +89,7 @@ uint8_t dyn_master_receive(void)
 void dyn_master_enable_tx(void)
 {
   GPIO_ResetBits(USART_RX_EN_GPIO_PORT, USART_RX_EN_PIN);
-  GPIO_SetBits(USART_TX_EN_GPIO_PORT, USART_RX_EN_PIN);
+  GPIO_SetBits(USART_TX_EN_GPIO_PORT, USART_TX_EN_PIN);
 }
 
 void dyn_master_enable_rx(void)
diff --git a/src/dynamixel_slave_spi.c b/src/dynamixel_slave_spi.c
new file mode 100644
index 0000000000000000000000000000000000000000..fc05f85ff702c18fa61d7111ef98f9789f570d13
--- /dev/null
+++ b/src/dynamixel_slave_spi.c
@@ -0,0 +1,259 @@
+#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 --------------------------------------------------*/
+  /* GPIO Deinitialisation */
+  GPIO_DeInit(SPI_SCK_GPIO_PORT);
+  GPIO_DeInit(SPI_MISO_GPIO_PORT);
+  GPIO_DeInit(SPI_MOSI_GPIO_PORT);
+  GPIO_DeInit(SPI_NSS_GPIO_PORT);
+
+  /* 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 Priority Group to 1 bit */
+  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
+
+  /* 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/system_stm32f4xx.c b/src/system_stm32f4xx.c
index 91e0e6f9e0137dd5d3d9e2774a79fef9bbe423d0..b6a72172346cec06c2cdf05e8277e6466b5fb579 100644
--- a/src/system_stm32f4xx.c
+++ b/src/system_stm32f4xx.c
@@ -54,9 +54,9 @@
   *-----------------------------------------------------------------------------
   *        APB2 Prescaler                         | 2
   *-----------------------------------------------------------------------------
-  *        HSE Frequency(Hz)                      | 25000000
+  *        HSE Frequency(Hz)                      | 8000000
   *-----------------------------------------------------------------------------
-  *        PLL_M                                  | 25
+  *        PLL_M                                  | 8
   *-----------------------------------------------------------------------------
   *        PLL_N                                  | 336
   *-----------------------------------------------------------------------------
@@ -86,100 +86,6 @@
   *        SDIO and RNG clock                     |
   *-----------------------------------------------------------------------------
   *=============================================================================
-  *=============================================================================
-  *                    Supported STM32F42xxx/43xxx devices
-  *-----------------------------------------------------------------------------
-  *        System Clock source                    | PLL (HSE)
-  *-----------------------------------------------------------------------------
-  *        SYSCLK(Hz)                             | 180000000
-  *-----------------------------------------------------------------------------
-  *        HCLK(Hz)                               | 180000000
-  *-----------------------------------------------------------------------------
-  *        AHB Prescaler                          | 1
-  *-----------------------------------------------------------------------------
-  *        APB1 Prescaler                         | 4
-  *-----------------------------------------------------------------------------
-  *        APB2 Prescaler                         | 2
-  *-----------------------------------------------------------------------------
-  *        HSE Frequency(Hz)                      | 25000000
-  *-----------------------------------------------------------------------------
-  *        PLL_M                                  | 25
-  *-----------------------------------------------------------------------------
-  *        PLL_N                                  | 360
-  *-----------------------------------------------------------------------------
-  *        PLL_P                                  | 2
-  *-----------------------------------------------------------------------------
-  *        PLL_Q                                  | 7
-  *-----------------------------------------------------------------------------
-  *        PLLI2S_N                               | NA
-  *-----------------------------------------------------------------------------
-  *        PLLI2S_R                               | NA
-  *-----------------------------------------------------------------------------
-  *        I2S input clock                        | NA
-  *-----------------------------------------------------------------------------
-  *        VDD(V)                                 | 3.3
-  *-----------------------------------------------------------------------------
-  *        Main regulator output voltage          | Scale1 mode
-  *-----------------------------------------------------------------------------
-  *        Flash Latency(WS)                      | 5
-  *-----------------------------------------------------------------------------
-  *        Prefetch Buffer                        | ON
-  *-----------------------------------------------------------------------------
-  *        Instruction cache                      | ON
-  *-----------------------------------------------------------------------------
-  *        Data cache                             | ON
-  *-----------------------------------------------------------------------------
-  *        Require 48MHz for USB OTG FS,          | Disabled
-  *        SDIO and RNG clock                     |
-  *-----------------------------------------------------------------------------
-  *=============================================================================
-  *=============================================================================
-  *                         Supported STM32F401xx devices
-  *-----------------------------------------------------------------------------
-  *        System Clock source                    | PLL (HSE)
-  *-----------------------------------------------------------------------------
-  *        SYSCLK(Hz)                             | 84000000
-  *-----------------------------------------------------------------------------
-  *        HCLK(Hz)                               | 84000000
-  *-----------------------------------------------------------------------------
-  *        AHB Prescaler                          | 1
-  *-----------------------------------------------------------------------------
-  *        APB1 Prescaler                         | 2
-  *-----------------------------------------------------------------------------
-  *        APB2 Prescaler                         | 1
-  *-----------------------------------------------------------------------------
-  *        HSE Frequency(Hz)                      | 25000000
-  *-----------------------------------------------------------------------------
-  *        PLL_M                                  | 25
-  *-----------------------------------------------------------------------------
-  *        PLL_N                                  | 336
-  *-----------------------------------------------------------------------------
-  *        PLL_P                                  | 4
-  *-----------------------------------------------------------------------------
-  *        PLL_Q                                  | 7
-  *-----------------------------------------------------------------------------
-  *        PLLI2S_N                               | NA
-  *-----------------------------------------------------------------------------
-  *        PLLI2S_R                               | NA
-  *-----------------------------------------------------------------------------
-  *        I2S input clock                        | NA
-  *-----------------------------------------------------------------------------
-  *        VDD(V)                                 | 3.3
-  *-----------------------------------------------------------------------------
-  *        Main regulator output voltage          | Scale1 mode
-  *-----------------------------------------------------------------------------
-  *        Flash Latency(WS)                      | 2
-  *-----------------------------------------------------------------------------
-  *        Prefetch Buffer                        | ON
-  *-----------------------------------------------------------------------------
-  *        Instruction cache                      | ON
-  *-----------------------------------------------------------------------------
-  *        Data cache                             | ON
-  *-----------------------------------------------------------------------------
-  *        Require 48MHz for USB OTG FS,          | Disabled
-  *        SDIO and RNG clock                     |
-  *-----------------------------------------------------------------------------
-  *=============================================================================      
   ****************************************************************************** 
   * @attention
   *
@@ -251,7 +157,7 @@
 
 /************************* PLL Parameters *************************************/
 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
-#define PLL_M      25
+#define PLL_M      8
 /* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
 #define PLL_Q      7
 
@@ -261,18 +167,6 @@
 #define PLL_P      2
 #endif /* STM32F40_41xxx */
 
-#if defined (STM32F427_437xx) || defined (STM32F429_439xx)
-#define PLL_N      360
-/* SYSCLK = PLL_VCO / PLL_P */
-#define PLL_P      2
-#endif /* STM32F427_437x || STM32F429_439xx */
-
-#if defined (STM32F401xx)
-#define PLL_N      336
-/* SYSCLK = PLL_VCO / PLL_P */
-#define PLL_P      4
-#endif /* STM32F401xx */
-
 /******************************************************************************/
 
 /**
@@ -295,14 +189,6 @@
   uint32_t SystemCoreClock = 168000000;
 #endif /* STM32F40_41xxx */
 
-#if defined (STM32F427_437xx) || defined (STM32F429_439xx)
-  uint32_t SystemCoreClock = 180000000;
-#endif /* STM32F427_437x || STM32F429_439xx */
-
-#if defined (STM32F401xx)
-  uint32_t SystemCoreClock = 84000000;
-#endif /* STM32F401xx */
-
   __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
 
 /**
@@ -341,6 +227,7 @@ void SystemInit(void)
     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
   #endif
   /* Reset the RCC clock configuration to the default reset state ------------*/
+  RCC_SetHSEValue(HSE_VALUE);
   /* Set HSION bit */
   RCC->CR |= (uint32_t)0x00000001;