diff --git a/Makefile b/Makefile
index bb0fa5f9cc1cd754f5716e5ba69777ee29fd331d..507160c724f5490fac05ecbe34ff907f6b92995b 100755
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,13 @@
 PROJECT_NAME=darwin_firmware
 #TARGET_FILES=$(wildcard src/*.c)
 TARGET_FILES=src/cm730_fw.c
+TARGET_FILES+=src/system_stm32f1xx.c
 TARGET_FILES+=src/gpio.c
 TARGET_FILES+=src/ram.c
+TARGET_FILES+=src/time.c
+TARGET_FILES+=src/eeprom.c
+TARGET_FILES+=src/comm.c
+TARGET_FILES+=src/dynamixel_slave_uart_dma.c
 TARGET_FILES+=src/stm32f1xx_hal_msp.c
 TARGET_PROCESSOR=STM32F103RE
 
@@ -15,12 +20,13 @@ include $(HAL_PATH)/select_processor.mk
 
 STM32_STARTUP_FILES_PATH = $(HAL_PATH)/startup_code/
 STM32_LINKER_SCRIPTS_PATH = ./linker_script
+DYNAMIXEL_LIBRARY_PATH=../../STM32_processor/libraries/dynamixel_base
 BUILD_PATH=build
 
 COMPILE_OPTS = -mlittle-endian -mcpu=cortex-m3 -mthumb -mthumb-interwork 
-COMPILE_OPTS += -Wall -g -O2 -fno-common -msoft-float 
+COMPILE_OPTS += -Wall -O2 -fno-common -msoft-float 
 COMPILE_OPTS += -ffreestanding -nostdlib -D$(PROCESSOR_MACRO) 
-INCLUDE_DIRS = -I$(HAL_PATH)/include -I$(HAL_PATH)/include/core -I$(HAL_PATH)/include/devices -I./include
+INCLUDE_DIRS = -I$(HAL_PATH)/include -I$(HAL_PATH)/include/core -I$(HAL_PATH)/include/devices -I$(DYNAMIXEL_LIBRARY_PATH)/include -I./include
 
 TCHAIN_PREFIX=arm-none-eabi-
 
@@ -45,7 +51,6 @@ MAIN_OUT_BIN = $(BUILD_PATH)/$(PROJECT_NAME).bin
 MAIN_OUT_LSS = $(BUILD_PATH)/$(PROJECT_NAME).lss
 
 # add STM32 src files
-TARGET_FILES+=$(HAL_PATH)/src/devices/system_stm32f1xx.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_gpio.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_cortex.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_rcc.c
@@ -53,6 +58,7 @@ TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_pwr.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_tim.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_tim_ex.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_dma.c
+TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_uart.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_flash.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_flash_ex.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal.c
@@ -73,7 +79,7 @@ $(BUILD_PATH)/%.o: $(HAL_PATH)/src/%.c
 	$(CC) -c $(CFLAGS) -o $@ $<
 
 $(MAIN_OUT_ELF): mkdir_build $(DARWIN_OBJS) $(BUID_PATH)/$(STARTUP_FILE:.s=.o) 
-	$(LD) $(LDFLAGS) $(DARWIN_OBJS) $(BUILD_PATH)/$(STARTUP_FILE:.s=.o) --output $@
+	$(LD) $(LDFLAGS) $(DARWIN_OBJS) $(BUILD_PATH)/$(STARTUP_FILE:.s=.o) $(DYNAMIXEL_LIBRARY_PATH)/lib/dynamixel_soft.a --output $@
 
 $(MAIN_OUT_HEX): $(MAIN_OUT_ELF)	
 	$(OBJCP) $(OBJCPFLAGS_HEX) $< $@
diff --git a/include/comm.h b/include/comm.h
index c5e404e9005fd2c665384daab6bcfb129c862a87..cb2d4e6c3d5d0c8fea722384ea6576652641d9fc 100644
--- a/include/comm.h
+++ b/include/comm.h
@@ -1,7 +1,7 @@
 #ifndef _COMM_H
 #define _COMM_H
 
-#include "stm32f10x.h"
+#include "stm32f1xx_hal.h"
 
 // public functions
 void comm_init(void);
diff --git a/include/dynamixel_slave_uart_dma.h b/include/dynamixel_slave_uart_dma.h
index 88b0a66f62b065cb3d223c444eece4df1afcefd7..58dc177a8437339e8636f99a67d744ad0f4d42f3 100755
--- a/include/dynamixel_slave_uart_dma.h
+++ b/include/dynamixel_slave_uart_dma.h
@@ -2,7 +2,7 @@
 #define _DYNAXIXEL_SLAVE_UART_DMA_H
 
 #include "dynamixel.h"
-#include "stm32f10x.h"
+#include "stm32f1xx_hal.h"
 
 // public functions
 void dyn_slave_init(void);
diff --git a/include/eeprom.h b/include/eeprom.h
index f24837912dbf5b76e1d83d7e9dffdb5908d3a9b8..b58e7c9a25826b79f99ac01161b001791d44cd66 100755
--- a/include/eeprom.h
+++ b/include/eeprom.h
@@ -2,21 +2,37 @@
   ******************************************************************************
   * @file    EEPROM_Emulation/inc/eeprom.h 
   * @author  MCD Application Team
-   * @version V1.0.0
-  * @date    10-October-2011
+  * @version V1.0.0
+  * @date    17-December-2014
   * @brief   This file contains all the functions prototypes for the EEPROM 
   *          emulation firmware library.
   ******************************************************************************
   * @attention
   *
-  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
-  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
-  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
-  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
-  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
-  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
-  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
   ******************************************************************************
   */ 
 
@@ -25,27 +41,23 @@
 #define __EEPROM_H
 
 /* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
+#include "stm32f1xx_hal.h"
 
 /* Exported constants --------------------------------------------------------*/
 /* Define the size of the sectors to be used */
-#define PAGE_SIZE               (uint32_t)0x0800  /* Page size = 2KByte */
-
-/* Device voltage range supposed to be [2.7V to 3.6V], the operation will 
-   be done by word  */
-#define VOLTAGE_RANGE           (uint8_t)VoltageRange_3
+#define PAGE_SIZE               (uint32_t)FLASH_PAGE_SIZE  /* Page size */
 
 /* EEPROM start address in Flash */
-#define EEPROM_START_ADDRESS  ((uint32_t)0x08003800) /* EEPROM emulation start address:
-                                                  from sector2 : after 16KByte of used 
-                                                  Flash memory */
+#define EEPROM_START_ADDRESS  ((uint32_t)0x08003800) /* EEPROM emulation start address */
 
 /* Pages 0 and 1 base and end addresses */
 #define PAGE0_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
 #define PAGE0_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))
+#define PAGE0_ID              0x08003800
 
 #define PAGE1_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0800))
-#define PAGE1_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (2 * PAGE_SIZE - 1)))
+#define PAGE1_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + 2*PAGE_SIZE - 1))
+#define PAGE1_ID              0x08004000
 
 /* Used Flash pages for EEPROM emulation */
 #define PAGE0                 ((uint16_t)0x0000)
@@ -77,6 +89,9 @@
 
 #define LAST_EEPROM_OFFSET       ((uint16_t)0x0017)
 
+/* Variables' number */
+#define NB_OF_VAR             ((uint8_t)0x03)
+
 /* Exported types ------------------------------------------------------------*/
 /* Exported macro ------------------------------------------------------------*/
 /* Exported functions ------------------------------------------------------- */
@@ -86,4 +101,4 @@ uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);
 
 #endif /* __EEPROM_H */
 
-/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/include/stm32f1xx_hal_conf.h b/include/stm32f1xx_hal_conf.h
index 4f2e8cfa12169afb99c46d2fe9f6daf6f9a0fe0d..15a6ba69c3a23578bc51d149aa69bf253d0b5159 100755
--- a/include/stm32f1xx_hal_conf.h
+++ b/include/stm32f1xx_hal_conf.h
@@ -80,7 +80,7 @@
 //#define HAL_SPI_MODULE_ENABLED
 //#define HAL_SRAM_MODULE_ENABLED
 #define HAL_TIM_MODULE_ENABLED
-//#define HAL_UART_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
 //#define HAL_USART_MODULE_ENABLED
 //#define HAL_WWDG_MODULE_ENABLED
 
diff --git a/include/time.h b/include/time.h
index b9bd3579c9bfa7fdcc55be122f7cfeb9bd01b4b4..3e495e8a3f3584f6373b5855269940c225ceac9a 100755
--- a/include/time.h
+++ b/include/time.h
@@ -1,11 +1,9 @@
 #ifndef _TIME_H
 #define _TIME_H
 
-#include "stm32f10x.h"
-#include "system_stm32f10x.h"
+#include "stm32f1xx_hal.h"
 
 void time_init(void);
-void delay_ms(__IO uint32_t time);
 void delay_us(uint32_t us);
 
 #endif
diff --git a/src/cm730_fw.c b/src/cm730_fw.c
index 7221b7666fec488ddb9d3447e17c5333eeb36d44..706a3921fe78a6c6aac8d72faf546f777297060c 100755
--- a/src/cm730_fw.c
+++ b/src/cm730_fw.c
@@ -1,45 +1,34 @@
 #include "stm32f1xx_hal.h"
 #include "gpio.h"
-//#include "time.h"
-//#include "eeprom.h"
+#include "time.h"
+#include "eeprom.h"
+#include "ram.h"
+#include "comm.h"
+#include "dynamixel_slave_uart_dma.h"
 //#include "motion_manager.h"
 //#include "action.h"
 //#include "walking.h"
 //#include "joint_motion.h"
 //#include "head_tracking.h"
 //#include "grippers.h"
-//#include "dynamixel_slave_uart_dma.h"
 //#include "dynamixel_master_uart_dma.h"
-//#include "ram.h"
 //#include "imu.h"
 //#include "adc_dma.h"
-//#include "comm.h"
 //#include <math.h>
 
+void SysTick_Handler(void)
+{
+  HAL_IncTick();
+}
+
 int main(void)
 {
-//  uint16_t eeprom_data;
+  uint16_t eeprom_data;
 //  uint16_t period,count=0;
 
-  /* initialize EEPROM */
-//  EE_Init();
-  // initialize the Dynamixel RAM memory space
-//  ram_init();
-  /* initialize the 1ms system timer */
-//  time_init();
-  /* initialize the gpio */
-//  gpio_init();
   /* initialize the dynamixel master interface */
 //  dyn_master_init();
 //  dyn_master_set_timeout(50);
-  /* initialize the dynamixel slave interface*/
-//  dyn_slave_init();
-//  EE_ReadVariable(DEVICE_ID_OFFSET,&eeprom_data);
-//  dyn_slave_set_address((uint8_t)eeprom_data);
-//  EE_ReadVariable(RETURN_DELAY_OFFSET,&eeprom_data);
-//  dyn_slave_set_return_delay((uint8_t)eeprom_data);
-//  EE_ReadVariable(RETURN_LEVEL_OFFSET,&eeprom_data);
-//  dyn_slave_set_return_level((uint8_t)eeprom_data);
   // initialize motion manager
 //  EE_ReadVariable(MM_PERIOD_OFFSET,&eeprom_data);
 //  period=eeprom_data&0x00FF;
@@ -51,20 +40,35 @@ int main(void)
 //  imu_init();
   // initialize adc
 //  adc_init();
-//  gpio_blink_led(LED_5_R,1000);
-//  comm_init();
 
 //  dyn_master_enable_power();
 //  delay_ms(1000);
   
-//  comm_start();
 
-  /* initialize the HAL module */
+//  /* initialize the HAL module */
   HAL_Init();
   /* initialize the GPIO module */
   gpio_init();
+  /* initialize the us delay module */
+  time_init();
+  /* initialize EEPROM */
+  EE_Init();
+  // initialize the Dynamixel RAM memory space
+  ram_init();
+  /* initialize the dynamixel slave interface*/
+  dyn_slave_init();
+  EE_ReadVariable(DEVICE_ID_OFFSET,&eeprom_data);
+  dyn_slave_set_address((uint8_t)eeprom_data);
+  EE_ReadVariable(RETURN_DELAY_OFFSET,&eeprom_data);
+  dyn_slave_set_return_delay((uint8_t)eeprom_data);
+  EE_ReadVariable(RETURN_LEVEL_OFFSET,&eeprom_data);
+  dyn_slave_set_return_level((uint8_t)eeprom_data);
+  // initlaize the communication module
+  comm_init();
+
+  gpio_blink_led(LED_5_R,1000);
 
-  gpio_blink_led(LED_2,1000);
+  comm_start();
   while(1);                             /* main function does not return */
 }
 
diff --git a/src/comm.c b/src/comm.c
index 1e685accb99faf4c3722fe72d132d8b25295df7c..0d0431ae5bd5c7ead5ca61a7e966b3e16966fa84 100644
--- a/src/comm.c
+++ b/src/comm.c
@@ -1,21 +1,21 @@
 #include "comm.h"
 #include "gpio.h"
 #include "ram.h"
-#include "motion_manager.h"
-#include "action.h"
-#include "walking.h"
-#include "joint_motion.h"
-#include "head_tracking.h"
-#include "grippers.h"
+//#include "motion_manager.h"
+//#include "action.h"
+//#include "walking.h"
+//#include "joint_motion.h"
+//#include "head_tracking.h"
+//#include "grippers.h"
 #include "dynamixel_slave_uart_dma.h"
-#include "dynamixel_master_uart_dma.h"
-#include "imu.h"
-#include "adc_dma.h"
+//#include "dynamixel_master_uart_dma.h"
+//#include "imu.h"
+//#include "adc_dma.h"
 
 #define      COMM_TIMER                 TIM7
 #define      COMM_TIMER_IRQn            TIM7_IRQn
 #define      COMM_TIMER_IRQHandler      TIM7_IRQHandler
-#define      COMM_TIMER_CLK             RCC_APB1Periph_TIM7
+#define      COMM_TIMER_ENABLE_CLK      __HAL_RCC_TIM7_CLK_ENABLE()
 
 // private variables
 uint8_t inst_packet[MAX_DATA_LENGTH];
@@ -24,6 +24,8 @@ uint8_t data[MAX_DATA_LENGTH];
 // registered write operation variables
 uint8_t reg_data[MAX_DATA_LENGTH];
 uint8_t reg_address,reg_length,reg_op;
+// Timer handle
+TIM_HandleTypeDef COMM_TIMHandle;
 
 // private functions
 uint8_t read_operation(uint8_t address, uint8_t length, uint8_t *data)
@@ -46,7 +48,7 @@ uint8_t write_operation(uint8_t address,uint8_t length, uint8_t *data)
   uint16_t word_value;
 
   // pre-write operation
-  if(ram_in_range(DARWIN_DXL_POWER,DARWIN_DXL_POWER,address,length))
+/*  if(ram_in_range(DARWIN_DXL_POWER,DARWIN_DXL_POWER,address,length))
   {
     if(data[DARWIN_DXL_POWER-address]&0x01) dyn_master_enable_power();
     else dyn_master_disable_power();
@@ -207,7 +209,7 @@ uint8_t write_operation(uint8_t address,uint8_t length, uint8_t *data)
       grippers_open(RIGHT_GRIPPER);
     else if(data[DARWIN_GRIPPER_CONTROL-address]&0x08)
       grippers_close(RIGHT_GRIPPER);
-  }
+  }*/
   // write eeprom
   for(i=address,j=0;i<LAST_EEPROM_OFFSET && i<(address+length);i++,j++)
     EE_WriteVariable(i,data[j]);
@@ -223,108 +225,114 @@ void COMM_TIMER_IRQHandler(void)
 {
   uint8_t error,length,prev_id,id;
 
-  TIM_ClearITPendingBit(COMM_TIMER,TIM_IT_Update);
-  if(dyn_slave_is_packet_ready())// check if a new instruction packet has been received
+  if(__HAL_TIM_GET_FLAG(&COMM_TIMHandle, TIM_FLAG_UPDATE) != RESET)
   {
-    dyn_slave_get_inst_packet(inst_packet);// get the received packet
-    // check address
-    id=dyn_get_id(inst_packet);
-    if(id==dyn_slave_get_address() || id==DYN_BROADCAST_ID)// the packet is addressed to this device or it is a broadcast
-    {
-      // check the packet checksum
-      if(dyn_check_checksum(inst_packet)==0xFF)// the incomming packet is okay
-      {
-        // process the packet
-        switch(dyn_get_instruction(inst_packet))
-        {
-          case DYN_PING: if(id!=DYN_BROADCAST_ID)
-                           dyn_slave_send_status_packet(DYN_NO_ERROR,0,data);
-                         break;
-          case DYN_READ: error=read_operation(dyn_get_read_address(inst_packet),dyn_get_read_length(inst_packet),data);
-                         if(dyn_slave_get_return_level()!=0 && id!=DYN_BROADCAST_ID)
-                         {
-                           if(error==RAM_SUCCESS)
-                             dyn_slave_send_status_packet(DYN_NO_ERROR,dyn_get_read_length(inst_packet),data);
-                           else
-                             dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
-                         }
-                         break;
-          case DYN_WRITE: length=dyn_get_write_data(inst_packet,data);
-                          error=write_operation(dyn_get_write_address(inst_packet),length,data);
-                          if(dyn_slave_get_return_level()==2 && id!=DYN_BROADCAST_ID)
-                          {
-                            if(error==RAM_SUCCESS)
-                              dyn_slave_send_status_packet(DYN_NO_ERROR,0,data);
-                            else
-                              dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
-                          }
-                          break;
-          case DYN_REG_WRITE: reg_length=dyn_get_reg_write_data(inst_packet,reg_data);
-                              reg_address=dyn_get_reg_write_address(inst_packet);
-                              reg_op=0x01;// signal there is a registered operation pending
-                              if(dyn_slave_get_return_level()==2 && id!=DYN_BROADCAST_ID)
-                                dyn_slave_send_status_packet(DYN_NO_ERROR,0,data);
-                              break;
-          case DYN_ACTION: if(reg_op)
-                           {
-                             error=write_operation(reg_address,reg_length,reg_data);
-                             reg_op=0x00;
-                           }
-                           break;
-          case DYN_RESET: 
-                          break;
-          case DYN_SYNC_READ: dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
-                              break;
-          case DYN_SYNC_WRITE: if(dyn_sync_write_id_present(inst_packet,dyn_slave_get_address()))// the device is addressed
-                               {
-                                 length=dyn_get_sync_write_data(inst_packet,dyn_slave_get_address(),data);
-                                 error=write_operation(dyn_get_sync_write_address(inst_packet),length,data);
-                               }
-                               break;
-          case DYN_BULK_READ: if(dyn_bulk_read_id_present(inst_packet,dyn_slave_get_address(),&prev_id))
-                              {
-                                length=dyn_get_bulk_read_length(inst_packet,dyn_slave_get_address());
-                                error=read_operation(dyn_get_bulk_read_address(inst_packet,dyn_slave_get_address()),length,data);
-                                if(prev_id==0xFF)// first device in the bulk read sequence
-                                {
-                                  if(error==RAM_SUCCESS)
-                                    dyn_slave_send_status_packet(DYN_NO_ERROR,length,data);
-                                  else
-                                    dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
-                                }
-                                else// wait for the previous device in the sequence to send its data
-                                {
-                                  do{
-                                    while(!dyn_slave_is_packet_ready());// wait until a new packet is received
-                                    dyn_slave_get_inst_packet(inst_packet);
-                                  }while(dyn_get_id(inst_packet)!=prev_id);
-                                  if(error==RAM_SUCCESS)
-                                    dyn_slave_send_status_packet(DYN_NO_ERROR,length,data);
-                                  else
-                                    dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
-                                }
-                              } 
-                              break;
-          case DYN_BULK_WRITE: dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
-                               break;
-          default:
-                   break;
-        }
-      }
-      else
-      {
-        // send a checksum error answer
-        if(dyn_get_id(inst_packet)!=DYN_BROADCAST_ID)
-          dyn_slave_send_status_packet(DYN_CHECKSUM_ERROR,0,0x00);
-      }
-    }
-    else// the packet is addressed to another device
+    if(__HAL_TIM_GET_IT_SOURCE(&COMM_TIMHandle, TIM_IT_UPDATE) !=RESET)
     {
-      // send the incomming packet to the dynamixel bus
-      if(dyn_master_resend_inst_packet(inst_packet,status_packet)!=DYN_TIMEOUT)
+      __HAL_TIM_CLEAR_IT(&COMM_TIMHandle, TIM_IT_UPDATE);
+      if(dyn_slave_is_packet_ready())// check if a new instruction packet has been received
       {
-        // send the answer back to the computer
-        dyn_slave_resend_status_packet(status_packet);
+	dyn_slave_get_inst_packet(inst_packet);// get the received packet
+	// check address
+	id=dyn_get_id(inst_packet);
+	if(id==dyn_slave_get_address() || id==DYN_BROADCAST_ID)// the packet is addressed to this device or it is a broadcast
+	{
+	  // check the packet checksum
+	  if(dyn_check_checksum(inst_packet)==0xFF)// the incomming packet is okay
+	  {
+	    // process the packet
+	    switch(dyn_get_instruction(inst_packet))
+	    {
+	      case DYN_PING: if(id!=DYN_BROADCAST_ID)
+			       dyn_slave_send_status_packet(DYN_NO_ERROR,0,data);
+			     break;
+	      case DYN_READ: error=read_operation(dyn_get_read_address(inst_packet),dyn_get_read_length(inst_packet),data);
+			     if(dyn_slave_get_return_level()!=0 && id!=DYN_BROADCAST_ID)
+			     {
+			       if(error==RAM_SUCCESS)
+				 dyn_slave_send_status_packet(DYN_NO_ERROR,dyn_get_read_length(inst_packet),data);
+			       else
+				 dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
+			     }
+			     break;
+	      case DYN_WRITE: length=dyn_get_write_data(inst_packet,data);
+			      error=write_operation(dyn_get_write_address(inst_packet),length,data);
+			      if(dyn_slave_get_return_level()==2 && id!=DYN_BROADCAST_ID)
+			      {
+				if(error==RAM_SUCCESS)
+				  dyn_slave_send_status_packet(DYN_NO_ERROR,0,data);
+				else
+				  dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
+			      }
+			      break;
+	      case DYN_REG_WRITE: reg_length=dyn_get_reg_write_data(inst_packet,reg_data);
+				  reg_address=dyn_get_reg_write_address(inst_packet);
+				  reg_op=0x01;// signal there is a registered operation pending
+				  if(dyn_slave_get_return_level()==2 && id!=DYN_BROADCAST_ID)
+				    dyn_slave_send_status_packet(DYN_NO_ERROR,0,data);
+				  break;
+	      case DYN_ACTION: if(reg_op)
+			       {
+				 error=write_operation(reg_address,reg_length,reg_data);
+				 reg_op=0x00;
+			       }
+			       break;
+	      case DYN_RESET: 
+			       break;
+	      case DYN_SYNC_READ: dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
+				  break;
+	      case DYN_SYNC_WRITE: if(dyn_sync_write_id_present(inst_packet,dyn_slave_get_address()))// the device is addressed
+				   {
+				     length=dyn_get_sync_write_data(inst_packet,dyn_slave_get_address(),data);
+				     error=write_operation(dyn_get_sync_write_address(inst_packet),length,data);
+				   }
+				   break;
+	      case DYN_BULK_READ: if(dyn_bulk_read_id_present(inst_packet,dyn_slave_get_address(),&prev_id))
+				  {
+				    length=dyn_get_bulk_read_length(inst_packet,dyn_slave_get_address());
+				    error=read_operation(dyn_get_bulk_read_address(inst_packet,dyn_slave_get_address()),length,data);
+				    if(prev_id==0xFF)// first device in the bulk read sequence
+				    {
+				      if(error==RAM_SUCCESS)
+					dyn_slave_send_status_packet(DYN_NO_ERROR,length,data);
+				      else
+					dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
+				    }
+				    else// wait for the previous device in the sequence to send its data
+				    {
+				      do{
+					while(!dyn_slave_is_packet_ready());// wait until a new packet is received
+					dyn_slave_get_inst_packet(inst_packet);
+				      }while(dyn_get_id(inst_packet)!=prev_id);
+				      if(error==RAM_SUCCESS)
+					dyn_slave_send_status_packet(DYN_NO_ERROR,length,data);
+				      else
+					dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
+				    }
+				  } 
+				  break;
+	      case DYN_BULK_WRITE: dyn_slave_send_status_packet(DYN_INST_ERROR,0,data);
+				   break;
+	      default:
+				   break;
+	    }
+	  }
+	  else
+	  {
+	    // send a checksum error answer
+	    if(dyn_get_id(inst_packet)!=DYN_BROADCAST_ID)
+	      dyn_slave_send_status_packet(DYN_CHECKSUM_ERROR,0,0x00);
+	  }
+	}
+	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_TIMEOUT)
+	  {
+	    // send the answer back to the computer
+	    dyn_slave_resend_status_packet(status_packet);
+	  }*/
+	}
       }
     }
   }
@@ -333,22 +341,16 @@ void COMM_TIMER_IRQHandler(void)
 // public functions
 void comm_init(void)
 {
-  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
-  NVIC_InitTypeDef NVIC_InitStructure;
-
-  RCC_APB1PeriphClockCmd(COMM_TIMER_CLK,ENABLE);
-
-  TIM_TimeBaseStructure.TIM_Period = 1000;
-  TIM_TimeBaseStructure.TIM_Prescaler = 72;
-  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
-  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
-  TIM_TimeBaseInit(COMM_TIMER,&TIM_TimeBaseStructure);
-
-  NVIC_InitStructure.NVIC_IRQChannel = COMM_TIMER_IRQn;
-  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-  NVIC_Init(&NVIC_InitStructure);
+  COMM_TIMHandle.Instance=COMM_TIMER;
+  COMM_TIMHandle.Init.Period = 1000;
+  COMM_TIMHandle.Init.Prescaler = 72;
+  COMM_TIMHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  COMM_TIMHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
+  HAL_TIM_Base_Init(&COMM_TIMHandle);
+  COMM_TIMER_ENABLE_CLK;
+  // initialize the timer interrupts
+  HAL_NVIC_SetPriority(COMM_TIMER_IRQn, 2, 0);
+  HAL_NVIC_EnableIRQ(COMM_TIMER_IRQn);
 
   /* initialize variables */
   reg_op=0x00;
@@ -356,7 +358,6 @@ void comm_init(void)
 
 void comm_start(void)
 {
-  TIM_Cmd(COMM_TIMER, ENABLE);
-  TIM_ITConfig(COMM_TIMER, TIM_IT_Update, ENABLE);
+  HAL_TIM_Base_Start_IT(&COMM_TIMHandle);
 }
 
diff --git a/src/dynamixel_slave_uart_dma.c b/src/dynamixel_slave_uart_dma.c
index ce0e4aa7513273c91c6726732606a684b5fa5245..e4050ab9b2b39871f96c032ea31b2916973ec218 100755
--- a/src/dynamixel_slave_uart_dma.c
+++ b/src/dynamixel_slave_uart_dma.c
@@ -2,37 +2,24 @@
 #include "gpio.h"
 
 #define     DYN_SLAVE                    USART3
-#define     DYN_SLAVE_CLK                RCC_APB1Periph_USART3
-#define     DYN_SLAVE_CLK_INIT           RCC_APB1PeriphClockCmd
+#define     DYN_SLAVE_ENABLE_CLK         __HAL_RCC_USART3_CLK_ENABLE()
 #define     DYN_SLAVE_IRQn               USART3_IRQn
 #define     DYN_SLAVE_IRQHandler         USART3_IRQHandler
 
-#define     DYN_SLAVE_TX_PIN             GPIO_Pin_10                
+#define     DYN_SLAVE_TX_PIN             GPIO_PIN_10                
 #define     DYN_SLAVE_TX_GPIO_PORT       GPIOB
-#define     DYN_SLAVE_TX_GPIO_CLK        RCC_APB2Periph_GPIOB
-#define     DYN_SLAVE_TX_SOURCE          GPIO_PinSource10
+#define     DYN_SLAVE_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOB_CLK_ENABLE()
 
-#define     DYN_SLAVE_RX_PIN             GPIO_Pin_11
+#define     DYN_SLAVE_RX_PIN             GPIO_PIN_11
 #define     DYN_SLAVE_RX_GPIO_PORT       GPIOB
-#define     DYN_SLAVE_RX_GPIO_CLK        RCC_APB2Periph_GPIOB
-#define     DYN_SLAVE_RX_SOURCE          GPIO_PinSource11
+#define     DYN_SLAVE_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOB_CLK_ENABLE()
 
 /* DMA configuration */
-#define     DYN_SLAVE_DR_ADDRESS         ((uint32_t)USART3 + 0x04) 
 #define     DYN_SLAVE_DMA                DMA1
-#define     DYN_SLAVE_DMA_CLK            RCC_AHBPeriph_DMA1
+#define     DYN_SLAVE_ENABLE_DMA_CLK     __HAL_RCC_DMA1_CLK_ENABLE()
 
 #define     DYN_SLAVE_TX_DMA_CHANNEL     DMA1_Channel2
-#define     DYN_SLAVE_TX_DMA_FLAG_GLIF   DMA1_FLAG_GL2
-#define     DYN_SLAVE_TX_DMA_FLAG_TEIF   DMA1_FLAG_TE2
-#define     DYN_SLAVE_TX_DMA_FLAG_HTIF   DMA1_FLAG_HT2
-#define     DYN_SLAVE_TX_DMA_FLAG_TCIF   DMA1_FLAG_TC2
-
 #define     DYN_SLAVE_RX_DMA_CHANNEL     DMA1_Channel3
-#define     DYN_SLAVE_RX_DMA_FLAG_GLIF   DMA1_FLAG_GL3
-#define     DYN_SLAVE_RX_DMA_FLAG_TEIF   DMA1_FLAG_TE3
-#define     DYN_SLAVE_RX_DMA_FLAG_HTIF   DMA1_FLAG_HT3
-#define     DYN_SLAVE_RX_DMA_FLAG_TCIF   DMA1_FLAG_TC3
 
 #define     DYN_SLAVE_DMA_TX_IRQn        DMA1_Channel2_IRQn
 #define     DYN_SLAVE_DMA_RX_IRQn        DMA1_Channel3_IRQn
@@ -52,9 +39,10 @@ uint8_t dyn_slave_tx_buffer[MAX_BUFFER_LEN];
 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;
+// usart communication device handler
+UART_HandleTypeDef UartHandle;
+DMA_HandleTypeDef hdma_tx;
+DMA_HandleTypeDef hdma_rx;
 
 // private functions
 
@@ -64,68 +52,126 @@ void DYN_SLAVE_IRQHandler(void)
   static uint8_t num_bytes=0;
   uint8_t data;
 
-  if(USART_GetITStatus(DYN_SLAVE, USART_IT_RXNE) != RESET)
+  if(__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET)
   {
-    USART_ClearFlag(DYN_SLAVE,USART_FLAG_RXNE);
-    data=USART_ReceiveData(DYN_SLAVE);
-    switch(num_bytes)
+    if(__HAL_UART_GET_IT_SOURCE(&UartHandle, UART_IT_RXNE) !=RESET)
     {
-      case 0: if(data==0xFF) 
-              {
-                dyn_slave_rx_buffer[num_bytes]=data;
-                num_bytes++;
-              }
-              break;
-      case 1: if(data==0xFF)
-              {
-                dyn_slave_rx_buffer[num_bytes]=data;
-                num_bytes++;
-              }
-              else num_bytes--;
-              break;
-      case 2: if(data!=0xFF) 
-              {
-                dyn_slave_rx_buffer[num_bytes]=data;
-                num_bytes++;
-              }
-              break;
-      case 3: dyn_slave_rx_buffer[num_bytes]=data;
-              num_bytes=0;
-              /* disable USART RX interrupts */
-              USART_ITConfig(DYN_SLAVE,USART_IT_RXNE,DISABLE); 
-              /* enable DMA RX */
-              DMA_SetCurrDataCounter(DYN_SLAVE_RX_DMA_CHANNEL, data);
-              DMA_Cmd(DYN_SLAVE_RX_DMA_CHANNEL,ENABLE);
-              USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, ENABLE);
-              break;
-      default: break;
+      __HAL_UART_CLEAR_FLAG(&UartHandle,UART_FLAG_RXNE);
+      data=(uint8_t)(UartHandle.Instance->DR & (uint8_t)0x00FF);
+      switch(num_bytes)
+      {
+        case 0: if(data==0xFF) 
+                {
+                  dyn_slave_rx_buffer[num_bytes]=data;
+                  num_bytes++;
+                }
+                break;
+        case 1: if(data==0xFF)
+                {
+                  dyn_slave_rx_buffer[num_bytes]=data;
+                  num_bytes++;
+                }
+                else num_bytes--;
+                break;
+        case 2: if(data!=0xFF) 
+                {
+                  dyn_slave_rx_buffer[num_bytes]=data;
+                  num_bytes++;
+                }
+                break;
+        case 3: dyn_slave_rx_buffer[num_bytes]=data;
+                gpio_toggle_led(LED_RX);
+                num_bytes=0;
+                // disable USART RX interrupts 
+                __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
+                // enable DMA RX 
+                HAL_DMA_Start_IT(UartHandle.hdmarx,(uint32_t)&UartHandle.Instance->DR,(uint32_t)&dyn_slave_rx_buffer[4],data);
+                SET_BIT(UartHandle.Instance->CR3, USART_CR3_DMAR);
+                break;
+        default: break;
+      }
     }
   }
-  else if(USART_GetITStatus(DYN_SLAVE, USART_IT_TC) != RESET)
+  else if(__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET)
   {
-    USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC);
-    USART_ITConfig(DYN_SLAVE, USART_IT_TC, DISABLE);
-    dyn_slave_sending_packet=0x00;
+    if(__HAL_UART_GET_IT_SOURCE(&UartHandle, UART_IT_TC) !=RESET)
+    {
+      gpio_toggle_led(LED_3);
+      __HAL_UART_CLEAR_FLAG(&UartHandle,UART_FLAG_TC);
+      __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC);
+      dyn_slave_sending_packet=0x00;
+    }
   }
 }
 
 void DYN_SLAVE_DMA_TX_IRQHandler(void)
 {
-  DMA_Cmd(DYN_SLAVE_TX_DMA_CHANNEL,DISABLE);
-  DMA_ClearFlag(DYN_SLAVE_TX_DMA_FLAG_GLIF);
-  DMA_ClearITPendingBit(DYN_SLAVE_TX_DMA_FLAG_GLIF);
-  USART_ITConfig(DYN_SLAVE, USART_IT_TC, ENABLE);
+  if(__HAL_DMA_GET_FLAG(UartHandle.hdmatx,__HAL_DMA_GET_TC_FLAG_INDEX(UartHandle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(UartHandle.hdmatx, DMA_IT_TC) != RESET)
+    {
+      gpio_toggle_led(LED_2);
+      if((UartHandle.hdmatx->Instance->CCR & DMA_CCR_CIRC) == 0)
+      {
+        /* Disable the transfer complete interrupt */
+        __HAL_DMA_DISABLE_IT(UartHandle.hdmatx, DMA_IT_TC);
+      }
+      /* Clear the transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(UartHandle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(UartHandle.hdmatx));
+      HAL_UART_DMAStop(&UartHandle);
+      __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC);
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(UartHandle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(UartHandle.hdmatx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(UartHandle.hdmatx, DMA_IT_HT) != RESET)
+    {
+      /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
+      if((UartHandle.hdmatx->Instance->CCR & DMA_CCR_CIRC) == 0)
+      {
+        /* Disable the half transfer interrupt */
+        __HAL_DMA_DISABLE_IT(UartHandle.hdmatx, DMA_IT_HT);
+      }
+      /* Clear the half transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(UartHandle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(UartHandle.hdmatx));
+    }
+  }
 }
 
 void DYN_SLAVE_DMA_RX_IRQHandler(void)
 {
-  DMA_Cmd(DYN_SLAVE_RX_DMA_CHANNEL,DISABLE);
-  DMA_ClearFlag(DYN_SLAVE_RX_DMA_FLAG_GLIF);
-  DMA_ClearITPendingBit(DYN_SLAVE_RX_DMA_FLAG_GLIF);
-  USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, DISABLE);
-  // enable USART RX interrupt
-  USART_ITConfig(DYN_SLAVE,USART_IT_RXNE,ENABLE); 
-  dyn_slave_packet_ready=0x01;
+  gpio_toggle_led(LED_4);
+  if(__HAL_DMA_GET_FLAG(UartHandle.hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(UartHandle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(UartHandle.hdmarx, DMA_IT_TC) != RESET)
+    {
+      gpio_toggle_led(LED_TX);
+      if((UartHandle.hdmarx->Instance->CCR & DMA_CCR_CIRC) == 0)
+      {
+        /* Disable the transfer complete interrupt */
+        __HAL_DMA_DISABLE_IT(UartHandle.hdmarx, DMA_IT_TC);
+      }
+      /* Clear the transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(UartHandle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX(UartHandle.hdmarx));
+      HAL_UART_DMAStop(&UartHandle);
+      __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
+      dyn_slave_packet_ready=0x01;
+    }
+  }
+  if(__HAL_DMA_GET_FLAG(UartHandle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(UartHandle.hdmarx)) != RESET)
+  {
+    if(__HAL_DMA_GET_IT_SOURCE(UartHandle.hdmarx, DMA_IT_HT) != RESET)
+    {
+      /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
+      if((UartHandle.hdmarx->Instance->CCR & DMA_CCR_CIRC) == 0)
+      {
+        /* Disable the half transfer interrupt */
+        __HAL_DMA_DISABLE_IT(UartHandle.hdmarx, DMA_IT_HT);
+      }
+      /* Clear the half transfer complete flag */
+      __HAL_DMA_CLEAR_FLAG(UartHandle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(UartHandle.hdmarx));
+    }
+  }
 }
 
 // public functions
@@ -133,24 +179,23 @@ 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_APB1PeriphClockCmd(DYN_SLAVE_TX_GPIO_CLK | DYN_SLAVE_RX_GPIO_CLK, ENABLE);
+  DYN_SLAVE_ENABLE_TX_GPIO_CLK;
+  DYN_SLAVE_ENABLE_RX_GPIO_CLK;
+  DYN_SLAVE_ENABLE_DMA_CLK;
   // configure the GPIO pins
 
   /* Configure USART Tx and Rx as alternate function push-pull */
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-  GPIO_InitStructure.GPIO_Pin = DYN_SLAVE_TX_PIN;
-  GPIO_Init(DYN_SLAVE_TX_GPIO_PORT, &GPIO_InitStructure);
+  GPIO_InitStructure.Pin       = DYN_SLAVE_TX_PIN;
+  GPIO_InitStructure.Mode      = GPIO_MODE_AF_PP;
+  GPIO_InitStructure.Pull      = GPIO_PULLUP;
+  GPIO_InitStructure.Speed     = GPIO_SPEED_HIGH;
+  HAL_GPIO_Init(DYN_SLAVE_TX_GPIO_PORT, &GPIO_InitStructure);
 
-  GPIO_InitStructure.GPIO_Pin = DYN_SLAVE_RX_PIN;
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-  GPIO_Init(DYN_SLAVE_RX_GPIO_PORT, &GPIO_InitStructure);
+  GPIO_InitStructure.Pin       = DYN_SLAVE_RX_PIN;
+  GPIO_InitStructure.Mode      = GPIO_MODE_INPUT;
+  HAL_GPIO_Init(DYN_SLAVE_RX_GPIO_PORT, &GPIO_InitStructure);
 
   // initialize the buffers
   for(i=0;i<MAX_BUFFER_LEN;i++)
@@ -162,102 +207,59 @@ void dyn_slave_init(void)
   dyn_slave_packet_ready=0x00;
   dyn_slave_sending_packet=0x00;
 
-  USART_DeInit(DYN_SLAVE);
-  USART_StructInit(&USART_InitStructure);
-  // configure the serial port
-  USART_InitStructure.USART_BaudRate = 921600;
-  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 = 0;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-  NVIC_Init(&NVIC_InitStructure);
-
-  /* disable all interrupts of the USART */
-  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);
-  /* Clear all USART interrupt flags */
-  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);
-  /* Clear all USART interrupt pending bits */
-  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_SLAVE */
-  USART_Cmd(DYN_SLAVE, ENABLE);
+  UartHandle.Instance          = DYN_SLAVE;
+
+  UartHandle.Init.BaudRate     = 921600;
+  UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;
+  UartHandle.Init.StopBits     = UART_STOPBITS_1;
+  UartHandle.Init.Parity       = UART_PARITY_NONE;
+  UartHandle.Init.Mode         = UART_MODE_TX_RX;
+  UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
+  UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
+  HAL_UART_Init(&UartHandle); 
+  DYN_SLAVE_ENABLE_CLK;
+
+  HAL_NVIC_SetPriority(DYN_SLAVE_IRQn, 0, 0);
+  HAL_NVIC_EnableIRQ(DYN_SLAVE_IRQn);
 
   // configure the DMA channels
-  /* Configure TX DMA */
-  RCC_AHBPeriphClockCmd(DYN_SLAVE_DMA_CLK, ENABLE);
-  DMA_DeInit(DYN_SLAVE_TX_DMA_CHANNEL);
-  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_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_DIR = DMA_DIR_PeripheralDST;
-  DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryBaseAddr = (uint32_t)dyn_slave_tx_buffer;
-  DYN_SLAVE_DMA_TX_InitStructure.DMA_M2M = DMA_M2M_Disable;
-  DMA_Init(DYN_SLAVE_TX_DMA_CHANNEL,&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 = 0;
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-  NVIC_Init(&NVIC_InitStructure);
-  DMA_ITConfig(DYN_SLAVE_TX_DMA_CHANNEL,DMA_IT_TC,ENABLE);
-  DMA_ITConfig(DYN_SLAVE_TX_DMA_CHANNEL,DMA_IT_HT | DMA_IT_TE,DISABLE);
-
-  /* Configure RX DMA */
-  DMA_DeInit(DYN_SLAVE_RX_DMA_CHANNEL);
-  DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&dyn_slave_rx_buffer[4];
-  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_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_DIR = DMA_DIR_PeripheralSRC;
-  DYN_SLAVE_DMA_RX_InitStructure.DMA_M2M = DMA_M2M_Disable;
-  DMA_Init(DYN_SLAVE_RX_DMA_CHANNEL,&DYN_SLAVE_DMA_RX_InitStructure);
-  /* initialize DMA interrupts */
-  NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_DMA_RX_IRQn;
-  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-  NVIC_Init(&NVIC_InitStructure);
-  DMA_ITConfig(DYN_SLAVE_RX_DMA_CHANNEL,DMA_IT_TC,ENABLE);
-  DMA_ITConfig(DYN_SLAVE_RX_DMA_CHANNEL,DMA_IT_HT | DMA_IT_TE,DISABLE);
-
-  /* enable USART RX interrupts */
-  USART_ITConfig(DYN_SLAVE,USART_IT_RXNE,ENABLE); 
+  hdma_tx.Instance                 = DYN_SLAVE_TX_DMA_CHANNEL;
+  hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
+  hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
+  hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
+  hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+  hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+  hdma_tx.Init.Mode                = DMA_NORMAL;
+  hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
+
+  HAL_DMA_Init(&hdma_tx);
+
+  /* Associate the initialized DMA handle to the UART handle */
+  __HAL_LINKDMA(&UartHandle, hdmatx, hdma_tx);
+
+  HAL_NVIC_SetPriority(DYN_SLAVE_DMA_TX_IRQn, 1, 0);
+  HAL_NVIC_EnableIRQ(DYN_SLAVE_DMA_TX_IRQn);
+
+  /* Configure the DMA handler for reception process */
+  hdma_rx.Instance                 = DYN_SLAVE_RX_DMA_CHANNEL;
+  hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+  hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
+  hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
+  hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+  hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
+  hdma_rx.Init.Mode                = DMA_NORMAL;
+  hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
+
+  HAL_DMA_Init(&hdma_rx);
+
+  /* Associate the initialized DMA handle to the the UART handle */
+  __HAL_LINKDMA(&UartHandle, hdmarx, hdma_rx);
+
+  HAL_NVIC_SetPriority(DYN_SLAVE_DMA_RX_IRQn, 1, 1);
+  HAL_NVIC_EnableIRQ(DYN_SLAVE_DMA_RX_IRQn);
+
+  /* enable the rx interrupt */
+  __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
 }
 
 inline void dyn_slave_set_address(uint8_t id)
@@ -306,10 +308,12 @@ void dyn_slave_send_status_packet(uint8_t error,uint8_t length, uint8_t *data)
   // create the status packet
   dyn_init_status_packet(dyn_slave_tx_buffer,dyn_slave_address,error,length,data);
   // set the DMA transfer
-  DMA_SetCurrDataCounter(DYN_SLAVE_TX_DMA_CHANNEL,dyn_get_length(dyn_slave_tx_buffer)+4);
-  DMA_Cmd(DYN_SLAVE_TX_DMA_CHANNEL,ENABLE);
-  USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC);
-  USART_DMACmd(DYN_SLAVE, USART_DMAReq_Tx, ENABLE);
+  HAL_DMA_Start_IT(UartHandle.hdmatx,(uint32_t)dyn_slave_tx_buffer,(uint32_t)&UartHandle.Instance->DR,dyn_get_length(dyn_slave_tx_buffer)+4);
+  /* Clear the TC flag in the SR register by writing 0 to it */
+  __HAL_UART_CLEAR_FLAG(&UartHandle,UART_FLAG_TC);
+  /* Enable the DMA transfer for transmit request by setting the DMAT bit
+     in the UART CR3 register */
+  SET_BIT(UartHandle.Instance->CR3, USART_CR3_DMAT);
   dyn_slave_sending_packet=0x01;
 }
 
@@ -320,9 +324,11 @@ void dyn_slave_resend_status_packet(uint8_t *packet)
   // create the status packet
   dyn_copy_packet(packet,dyn_slave_tx_buffer); 
   // set the DMA transfer
-  DMA_SetCurrDataCounter(DYN_SLAVE_TX_DMA_CHANNEL,dyn_get_length(dyn_slave_tx_buffer)+4);
-  DMA_Cmd(DYN_SLAVE_TX_DMA_CHANNEL,ENABLE);
-  USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC);
-  USART_DMACmd(DYN_SLAVE, USART_DMAReq_Tx, ENABLE);
+  HAL_DMA_Start_IT(UartHandle.hdmatx,(uint32_t)dyn_slave_tx_buffer,(uint32_t)&UartHandle.Instance->DR,dyn_get_length(dyn_slave_tx_buffer)+4);
+  /* Clear the TC flag in the SR register by writing 0 to it */
+  __HAL_UART_CLEAR_FLAG(&UartHandle,UART_FLAG_TC);
+  /* Enable the DMA transfer for transmit request by setting the DMAT bit
+     in the UART CR3 register */
+  SET_BIT(UartHandle.Instance->CR3, USART_CR3_DMAT);
   dyn_slave_sending_packet=0x01;
 }
diff --git a/src/eeprom.c b/src/eeprom.c
index 0477a437945e2a91869fe6f08d94c81c5c4ec9c9..5af13c96a942abdbc9e13c58cc38b72b017a2da5 100755
--- a/src/eeprom.c
+++ b/src/eeprom.c
@@ -3,19 +3,35 @@
   * @file    EEPROM_Emulation/src/eeprom.c 
   * @author  MCD Application Team
   * @version V1.0.0
-  * @date    10-October-2011
+  * @date    17-December-2014
   * @brief   This file provides all the EEPROM emulation firmware functions.
   ******************************************************************************
   * @attention
   *
-  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
-  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
-  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
-  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
-  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
-  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
-  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
   ******************************************************************************
   */ 
 
@@ -42,7 +58,7 @@
 /* Global variable used to store variable value in read sequence */
 uint16_t DataVar = 0;
 
-// EEPROM memory map
+/* Virtual address defined by the user: 0xFFFF value is prohibited */
 uint16_t eeprom_data[] __attribute__ ((section (".eeprom")))={VALID_PAGE,
                                                               0xFFFF,
                                                               DEFAULT_DEVICE_MODEL&0xFF,// model number LSB
@@ -66,10 +82,11 @@ uint16_t eeprom_data[] __attribute__ ((section (".eeprom")))={VALID_PAGE,
 
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
-static FLASH_Status EE_Format(void);
+static HAL_StatusTypeDef EE_Format(void);
 static uint16_t EE_FindValidPage(uint8_t Operation);
 static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
 static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
+static uint16_t EE_VerifyPageFullyErased(uint32_t Address);
 
 /**
   * @brief  Restore the pages to a known good state in case of page's status
@@ -80,208 +97,285 @@ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
   */
 uint16_t EE_Init(void)
 {
-  uint16_t PageStatus0 = 6, PageStatus1 = 6;
-  uint16_t VarIdx = 0;
-  uint16_t EepromStatus = 0, ReadStatus = 0;
+  uint16_t pagestatus0 = 6, pagestatus1 = 6;
+  uint16_t varidx = 0;
+  uint16_t eepromstatus = 0, readstatus = 0;
   int16_t x = -1;
-  uint16_t  FlashStatus;
+  HAL_StatusTypeDef  flashstatus;
+  uint32_t page_error = 0;
+  FLASH_EraseInitTypeDef s_eraseinit;
+
+  /* Unlock the Flash Program Erase controller */
+  HAL_FLASH_Unlock();
 
-  FLASH_Unlock();
   /* Get Page0 status */
-  PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
+  pagestatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
   /* Get Page1 status */
-  PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
+  pagestatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
 
+  /* Fill EraseInit structure*/
+  s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
+  s_eraseinit.PageAddress = PAGE0_ID;
+  s_eraseinit.NbPages     = 1;
+  
   /* Check for invalid header states and repair if necessary */
-  switch (PageStatus0)
+  switch (pagestatus0)
   {
     case ERASED:
-      if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
+      if (pagestatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
       {
-        /* Erase Page0 */
-        FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
-        /* If erase operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
+          /* Erase Page0 */
+        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
         {
-          return FlashStatus;
+          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
+          /* If erase operation was failed, a Flash error code is returned */
+          if (flashstatus != HAL_OK)
+          {
+            return flashstatus;
+          }
         }
       }
-      else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
+      else if (pagestatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
       {
         /* Erase Page0 */
-        FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
-        /* If erase operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
-        {
-          return FlashStatus;
+        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
+        { 
+          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
+          /* If erase operation was failed, a Flash error code is returned */
+          if (flashstatus != HAL_OK)
+          {
+            return flashstatus;
+          }
         }
         /* Mark Page1 as valid */
-        FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE);
+        flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
         /* If program operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
+        if (flashstatus != HAL_OK)
         {
-          return FlashStatus;
+          return flashstatus;
         }
       }
       else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
       {
         /* Erase both Page0 and Page1 and set Page0 as valid page */
-        FlashStatus = EE_Format();
+        flashstatus = EE_Format();
         /* If erase/program operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
+        if (flashstatus != HAL_OK)
         {
-          return FlashStatus;
+          return flashstatus;
         }
       }
       break;
 
     case RECEIVE_DATA:
-      if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
+      if (pagestatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
       {
         /* Transfer data from Page1 to Page0 */
-        for (VarIdx = 0; VarIdx < EEPROM_SIZE; VarIdx++)
+        for (varidx = 0; varidx < NB_OF_VAR; varidx++)
         {
-          if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == eeprom_data[VarIdx])
+          if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == eeprom_data[varidx])
           {
-            x = VarIdx;
+            x = varidx;
           }
-          if (VarIdx != x)
+          if (varidx != x)
           {
             /* Read the last variables' updates */
-            ReadStatus = EE_ReadVariable(eeprom_data[VarIdx], &DataVar);
+            readstatus = EE_ReadVariable(eeprom_data[varidx], &DataVar);
             /* In case variable corresponding to the virtual address was found */
-            if (ReadStatus != 0x1)
+            if (readstatus != 0x1)
             {
               /* Transfer the variable to the Page0 */
-              EepromStatus = EE_VerifyPageFullWriteVariable(eeprom_data[VarIdx], DataVar);
+              eepromstatus = EE_VerifyPageFullWriteVariable(eeprom_data[varidx], DataVar);
               /* If program operation was failed, a Flash error code is returned */
-              if (EepromStatus != FLASH_COMPLETE)
+              if (eepromstatus != HAL_OK)
               {
-                return EepromStatus;
+                return eepromstatus;
               }
             }
           }
         }
         /* Mark Page0 as valid */
-        FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);
+        flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
         /* If program operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
+        if (flashstatus != HAL_OK)
         {
-          return FlashStatus;
+          return flashstatus;
         }
+        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
+        s_eraseinit.PageAddress = PAGE1_ID;
+        s_eraseinit.NbPages     = 1;
         /* Erase Page1 */
-        FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
-        /* If erase operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
-        {
-          return FlashStatus;
+        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
+        { 
+          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
+          /* If erase operation was failed, a Flash error code is returned */
+          if (flashstatus != HAL_OK)
+          {
+            return flashstatus;
+          }
         }
       }
-      else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */
+      else if (pagestatus1 == ERASED) /* Page0 receive, Page1 erased */
       {
+        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
+        s_eraseinit.PageAddress = PAGE1_ID;
+        s_eraseinit.NbPages     = 1;
         /* Erase Page1 */
-        FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
-        /* If erase operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
-        {
-          return FlashStatus;
+        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
+        { 
+          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
+          /* If erase operation was failed, a Flash error code is returned */
+          if (flashstatus != HAL_OK)
+          {
+            return flashstatus;
+          }
         }
         /* Mark Page0 as valid */
-        FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);
+        flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
         /* If program operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
+        if (flashstatus != HAL_OK)
         {
-          return FlashStatus;
+          return flashstatus;
         }
       }
       else /* Invalid state -> format eeprom */
       {
         /* Erase both Page0 and Page1 and set Page0 as valid page */
-        FlashStatus = EE_Format();
+        flashstatus = EE_Format();
         /* If erase/program operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
+        if (flashstatus != HAL_OK)
         {
-          return FlashStatus;
+          return flashstatus;
         }
       }
       break;
 
     case VALID_PAGE:
-      if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
+      if (pagestatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
       {
         /* Erase both Page0 and Page1 and set Page0 as valid page */
-        FlashStatus = EE_Format();
+        flashstatus = EE_Format();
         /* If erase/program operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
+        if (flashstatus != HAL_OK)
         {
-          return FlashStatus;
+          return flashstatus;
         }
       }
-      else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */
+      else if (pagestatus1 == ERASED) /* Page0 valid, Page1 erased */
       {
+        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
+        s_eraseinit.PageAddress = PAGE1_ID;
+        s_eraseinit.NbPages     = 1;
         /* Erase Page1 */
-        FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
-        /* If erase operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
-        {
-          return FlashStatus;
+        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
+        { 
+          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
+          /* If erase operation was failed, a Flash error code is returned */
+          if (flashstatus != HAL_OK)
+          {
+            return flashstatus;
+          }
         }
       }
       else /* Page0 valid, Page1 receive */
       {
         /* Transfer data from Page0 to Page1 */
-        for (VarIdx = 0; VarIdx < EEPROM_SIZE; VarIdx++)
+        for (varidx = 0; varidx < NB_OF_VAR; varidx++)
         {
-          if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == eeprom_data[VarIdx])
+          if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == eeprom_data[varidx])
           {
-            x = VarIdx;
+            x = varidx;
           }
-          if (VarIdx != x)
+          if (varidx != x)
           {
             /* Read the last variables' updates */
-            ReadStatus = EE_ReadVariable(eeprom_data[VarIdx], &DataVar);
+            readstatus = EE_ReadVariable(eeprom_data[varidx], &DataVar);
             /* In case variable corresponding to the virtual address was found */
-            if (ReadStatus != 0x1)
+            if (readstatus != 0x1)
             {
               /* Transfer the variable to the Page1 */
-              EepromStatus = EE_VerifyPageFullWriteVariable(eeprom_data[VarIdx], DataVar);
+              eepromstatus = EE_VerifyPageFullWriteVariable(eeprom_data[varidx], DataVar);
               /* If program operation was failed, a Flash error code is returned */
-              if (EepromStatus != FLASH_COMPLETE)
+              if (eepromstatus != HAL_OK)
               {
-                return EepromStatus;
+                return eepromstatus;
               }
             }
           }
         }
         /* Mark Page1 as valid */
-        FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE);
+        flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);        
         /* If program operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
+        if (flashstatus != HAL_OK)
         {
-          return FlashStatus;
+          return flashstatus;
         }
+        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
+        s_eraseinit.PageAddress = PAGE0_ID;
+        s_eraseinit.NbPages     = 1;
         /* Erase Page0 */
-        FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
-        /* If erase operation was failed, a Flash error code is returned */
-        if (FlashStatus != FLASH_COMPLETE)
-        {
-          return FlashStatus;
+        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
+        { 
+          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
+          /* If erase operation was failed, a Flash error code is returned */
+          if (flashstatus != HAL_OK)
+          {
+            return flashstatus;
+          }
         }
       }
       break;
 
     default:  /* Any other state -> format eeprom */
       /* Erase both Page0 and Page1 and set Page0 as valid page */
-      FlashStatus = EE_Format();
+      flashstatus = EE_Format();
       /* If erase/program operation was failed, a Flash error code is returned */
-      if (FlashStatus != FLASH_COMPLETE)
+      if (flashstatus != HAL_OK)
       {
-        return FlashStatus;
+        return flashstatus;
       }
       break;
   }
 
-  return FLASH_COMPLETE;
+  return HAL_OK;
+}
+
+/**
+  * @brief  Verify if specified page is fully erased.
+  * @param  Address: page address
+  *   This parameter can be one of the following values:
+  *     @arg PAGE0_BASE_ADDRESS: Page0 base address
+  *     @arg PAGE1_BASE_ADDRESS: Page1 base address
+  * @retval page fully erased status:
+  *           - 0: if Page not erased
+  *           - 1: if Page erased
+  */
+uint16_t EE_VerifyPageFullyErased(uint32_t Address)
+{
+  uint32_t readstatus = 1;
+  uint16_t addressvalue = 0x5555;
+    
+  /* Check each active page address starting from end */
+  while (Address <= PAGE0_END_ADDRESS)
+  {
+    /* Get the current location content to be compared with virtual address */
+    addressvalue = (*(__IO uint16_t*)Address);
+
+    /* Compare the read address with the virtual address */
+    if (addressvalue != ERASED)
+    {
+      
+      /* In case variable value is read, reset readstatus flag */
+      readstatus = 0;
+
+      break;
+    }
+    /* Next address location */
+    Address = Address + 4;
+  }
+  
+  /* Return readstatus value: (0: Page not erased, 1: Page erased) */
+  return readstatus;
 }
 
 /**
@@ -296,51 +390,51 @@ uint16_t EE_Init(void)
   */
 uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
 {
-  uint16_t ValidPage = PAGE0;
-  uint16_t AddressValue = 0x5555, ReadStatus = 1;
-  uint32_t Address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS;
+  uint16_t validpage = PAGE0;
+  uint16_t addressvalue = 0x5555, readstatus = 1;
+  uint32_t address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS;
 
   /* Get active Page for read operation */
-  ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
+  validpage = EE_FindValidPage(READ_FROM_VALID_PAGE);
 
   /* Check if there is no valid page */
-  if (ValidPage == NO_VALID_PAGE)
+  if (validpage == NO_VALID_PAGE)
   {
     return  NO_VALID_PAGE;
   }
 
   /* Get the valid Page start Address */
-  PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
+  PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage * PAGE_SIZE));
 
   /* Get the valid Page end Address */
-  Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
+  address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + validpage) * PAGE_SIZE));
 
   /* Check each active page address starting from end */
-  while (Address > (PageStartAddress + 2))
+  while (address > (PageStartAddress + 2))
   {
     /* Get the current location content to be compared with virtual address */
-    AddressValue = (*(__IO uint16_t*)Address);
+    addressvalue = (*(__IO uint16_t*)address);
 
     /* Compare the read address with the virtual address */
-    if (AddressValue == VirtAddress)
+    if (addressvalue == VirtAddress)
     {
       /* Get content of Address-2 which is variable value */
-      *Data = (*(__IO uint16_t*)(Address - 2));
+      *Data = (*(__IO uint16_t*)(address - 2));
 
-      /* In case variable value is read, reset ReadStatus flag */
-      ReadStatus = 0;
+      /* In case variable value is read, reset readstatus flag */
+      readstatus = 0;
 
       break;
     }
     else
     {
       /* Next address location */
-      Address = Address - 4;
+      address = address - 4;
     }
   }
 
-  /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
-  return ReadStatus;
+  /* Return readstatus value: (0: variable exist, 1: variable doesn't exist) */
+  return readstatus;
 }
 
 /**
@@ -377,33 +471,46 @@ uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
   * @retval Status of the last operation (Flash write or erase) done during
   *         EEPROM formating
   */
-static FLASH_Status EE_Format(void)
+static HAL_StatusTypeDef EE_Format(void)
 {
-  FLASH_Status FlashStatus = FLASH_COMPLETE;
+  HAL_StatusTypeDef flashstatus = HAL_OK;
+  uint32_t page_error = 0;
+  FLASH_EraseInitTypeDef s_eraseinit;
 
+  s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
+  s_eraseinit.PageAddress = PAGE0_ID;
+  s_eraseinit.NbPages     = 1;
   /* Erase Page0 */
-  FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
-
-  /* If erase operation was failed, a Flash error code is returned */
-  if (FlashStatus != FLASH_COMPLETE)
+  if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
   {
-    return FlashStatus;
+    flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 
+    /* If erase operation was failed, a Flash error code is returned */
+    if (flashstatus != HAL_OK)
+    {
+      return flashstatus;
+    }
   }
-
   /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
-  FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);
-
+  flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); 
   /* If program operation was failed, a Flash error code is returned */
-  if (FlashStatus != FLASH_COMPLETE)
+  if (flashstatus != HAL_OK)
   {
-    return FlashStatus;
+    return flashstatus;
   }
 
+  s_eraseinit.PageAddress = PAGE1_ID;
   /* Erase Page1 */
-  FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
-
-  /* Return Page1 erase operation status */
-  return FlashStatus;
+  if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
+  {  
+    flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 
+    /* If erase operation was failed, a Flash error code is returned */
+    if (flashstatus != HAL_OK)
+    {
+      return flashstatus;
+    }
+  }
+  
+  return HAL_OK;
 }
 
 /**
@@ -417,22 +524,22 @@ static FLASH_Status EE_Format(void)
   */
 static uint16_t EE_FindValidPage(uint8_t Operation)
 {
-  uint16_t PageStatus0 = 6, PageStatus1 = 6;
+  uint16_t pagestatus0 = 6, pagestatus1 = 6;
 
   /* Get Page0 actual status */
-  PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
+  pagestatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
 
   /* Get Page1 actual status */
-  PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
+  pagestatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
 
   /* Write or read operation */
   switch (Operation)
   {
     case WRITE_IN_VALID_PAGE:   /* ---- Write operation ---- */
-      if (PageStatus1 == VALID_PAGE)
+      if (pagestatus1 == VALID_PAGE)
       {
         /* Page0 receiving data */
-        if (PageStatus0 == RECEIVE_DATA)
+        if (pagestatus0 == RECEIVE_DATA)
         {
           return PAGE0;         /* Page0 valid */
         }
@@ -441,10 +548,10 @@ static uint16_t EE_FindValidPage(uint8_t Operation)
           return PAGE1;         /* Page1 valid */
         }
       }
-      else if (PageStatus0 == VALID_PAGE)
+      else if (pagestatus0 == VALID_PAGE)
       {
         /* Page1 receiving data */
-        if (PageStatus1 == RECEIVE_DATA)
+        if (pagestatus1 == RECEIVE_DATA)
         {
           return PAGE1;         /* Page1 valid */
         }
@@ -459,11 +566,11 @@ static uint16_t EE_FindValidPage(uint8_t Operation)
       }
 
     case READ_FROM_VALID_PAGE:  /* ---- Read operation ---- */
-      if (PageStatus0 == VALID_PAGE)
+      if (pagestatus0 == VALID_PAGE)
       {
         return PAGE0;           /* Page0 valid */
       }
-      else if (PageStatus1 == VALID_PAGE)
+      else if (pagestatus1 == VALID_PAGE)
       {
         return PAGE1;           /* Page1 valid */
       }
@@ -489,49 +596,50 @@ static uint16_t EE_FindValidPage(uint8_t Operation)
   */
 static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data)
 {
-  FLASH_Status FlashStatus = FLASH_COMPLETE;
-  uint16_t ValidPage = PAGE0;
-  uint32_t Address = EEPROM_START_ADDRESS, PageEndAddress = EEPROM_START_ADDRESS+PAGE_SIZE;
+  HAL_StatusTypeDef flashstatus = HAL_OK;
+  uint16_t validpage = PAGE0;
+  uint32_t address = EEPROM_START_ADDRESS, pageendaddress = EEPROM_START_ADDRESS+PAGE_SIZE;
 
   /* Get valid Page for write operation */
-  ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
-
+  validpage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
+  
   /* Check if there is no valid page */
-  if (ValidPage == NO_VALID_PAGE)
+  if (validpage == NO_VALID_PAGE)
   {
     return  NO_VALID_PAGE;
   }
 
-  /* Get the valid Page start Address */
-  Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
+  /* Get the valid Page start address */
+  address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage * PAGE_SIZE));
 
-  /* Get the valid Page end Address */
-  PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
+  /* Get the valid Page end address */
+  pageendaddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((validpage + 1) * PAGE_SIZE));
 
   /* Check each active page address starting from begining */
-  while (Address < PageEndAddress)
+  while (address < pageendaddress)
   {
-    /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
-    if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF)
+    /* Verify if address and address+2 contents are 0xFFFFFFFF */
+    if ((*(__IO uint32_t*)address) == 0xFFFFFFFF)
     {
       /* Set variable data */
-      FlashStatus = FLASH_ProgramHalfWord(Address, Data);
+      flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, Data);       
       /* If program operation was failed, a Flash error code is returned */
-      if (FlashStatus != FLASH_COMPLETE)
+      if (flashstatus != HAL_OK)
       {
-        return FlashStatus;
+        return flashstatus;
       }
       /* Set variable virtual address */
-      FlashStatus = FLASH_ProgramHalfWord(Address + 2, VirtAddress);
+      flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address + 2, VirtAddress);       
       /* Return program operation status */
-      return FlashStatus;
+      return flashstatus;
     }
     else
     {
       /* Next address location */
-      Address = Address + 4;
+      address = address + 4;
     }
   }
+
   /* Return PAGE_FULL in case the valid page is full */
   return PAGE_FULL;
 }
@@ -549,93 +657,103 @@ static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Da
   */
 static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
 {
-  FLASH_Status FlashStatus = FLASH_COMPLETE;
-  uint32_t NewPageAddress = EEPROM_START_ADDRESS;
-  uint32_t OldPageId=0;
-  uint16_t ValidPage = PAGE0, VarIdx = 0;
-  uint16_t EepromStatus = 0, ReadStatus = 0;
+  HAL_StatusTypeDef flashstatus = HAL_OK;
+  uint32_t newpageaddress = EEPROM_START_ADDRESS;
+  uint32_t oldpageid = 0;
+  uint16_t validpage = PAGE0, varidx = 0;
+  uint16_t eepromstatus = 0, readstatus = 0;
+  uint32_t page_error = 0;
+  FLASH_EraseInitTypeDef s_eraseinit;
 
   /* Get active Page for read operation */
-  ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
+  validpage = EE_FindValidPage(READ_FROM_VALID_PAGE);
 
-  if (ValidPage == PAGE1)       /* Page1 valid */
+  if (validpage == PAGE1)       /* Page1 valid */
   {
     /* New page address where variable will be moved to */
-    NewPageAddress = PAGE0_BASE_ADDRESS;
+    newpageaddress = PAGE0_BASE_ADDRESS;
 
     /* Old page ID where variable will be taken from */
-    OldPageId = PAGE1_BASE_ADDRESS;
+    oldpageid = PAGE1_ID;
   }
-  else if (ValidPage == PAGE0)  /* Page0 valid */
+  else if (validpage == PAGE0)  /* Page0 valid */
   {
     /* New page address  where variable will be moved to */
-    NewPageAddress = PAGE1_BASE_ADDRESS;
+    newpageaddress = PAGE1_BASE_ADDRESS;
 
     /* Old page ID where variable will be taken from */
-    OldPageId = PAGE0_BASE_ADDRESS;
+    oldpageid = PAGE0_ID;
   }
   else
   {
     return NO_VALID_PAGE;       /* No valid Page */
   }
+
   /* Set the new Page status to RECEIVE_DATA status */
-  FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA);
+  flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, RECEIVE_DATA);  
   /* If program operation was failed, a Flash error code is returned */
-  if (FlashStatus != FLASH_COMPLETE)
+  if (flashstatus != HAL_OK)
   {
-    return FlashStatus;
+    return flashstatus;
   }
+  
   /* Write the variable passed as parameter in the new active page */
-  EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
+  eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
   /* If program operation was failed, a Flash error code is returned */
-  if (EepromStatus != FLASH_COMPLETE)
+  if (eepromstatus != HAL_OK)
   {
-    return EepromStatus;
+    return eepromstatus;
   }
 
   /* Transfer process: transfer variables from old to the new active page */
-  for (VarIdx = 0; VarIdx < EEPROM_SIZE; VarIdx++)
+  for (varidx = 0; varidx < NB_OF_VAR; varidx++)
   {
-    if (eeprom_data[VarIdx] != VirtAddress)  /* Check each variable except the one passed as parameter */
+    if (eeprom_data[varidx] != VirtAddress)  /* Check each variable except the one passed as parameter */
     {
       /* Read the other last variable updates */
-      ReadStatus = EE_ReadVariable(eeprom_data[VarIdx], &DataVar);
+      readstatus = EE_ReadVariable(eeprom_data[varidx], &DataVar);
       /* In case variable corresponding to the virtual address was found */
-      if (ReadStatus != 0x1)
+      if (readstatus != 0x1)
       {
         /* Transfer the variable to the new active page */
-        EepromStatus = EE_VerifyPageFullWriteVariable(eeprom_data[VarIdx], DataVar);
+        eepromstatus = EE_VerifyPageFullWriteVariable(eeprom_data[varidx], DataVar);
         /* If program operation was failed, a Flash error code is returned */
-        if (EepromStatus != FLASH_COMPLETE)
+        if (eepromstatus != HAL_OK)
         {
-          return EepromStatus;
+          return eepromstatus;
         }
       }
     }
   }
+
+  s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
+  s_eraseinit.PageAddress = oldpageid;
+  s_eraseinit.NbPages     = 1;
   
   /* Erase the old Page: Set old Page status to ERASED status */
-  FlashStatus = FLASH_ErasePage(OldPageId);
+  flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);  
   /* If erase operation was failed, a Flash error code is returned */
-  if (FlashStatus != FLASH_COMPLETE)
+  if (flashstatus != HAL_OK)
   {
-    return FlashStatus;
+    return flashstatus;
   }
 
   /* Set new Page status to VALID_PAGE status */
-  FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE);
+  flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, VALID_PAGE);   
   /* If program operation was failed, a Flash error code is returned */
-  if (FlashStatus != FLASH_COMPLETE)
+  if (flashstatus != HAL_OK)
   {
-    return FlashStatus;
+    return flashstatus;
   }
- 
+  
+  
+
   /* Return last operation flash status */
-  return FlashStatus;
+  return flashstatus;
 }
 
 /**
   * @}
   */ 
 
-/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/gpio.c b/src/gpio.c
index c86e0f8cd1724761082d103d8778b34105331685..1297921809283193b266a12b49e07dc2c8a0e48c 100755
--- a/src/gpio.c
+++ b/src/gpio.c
@@ -94,138 +94,147 @@ void (*mode_pb_callback)(void);
 // IRQ handler functions
 void GPI_EXTI1_IRQHandler(void)
 {
-  HAL_GPIO_EXTI_IRQHandler(START_PB_PIN);
-  HAL_GPIO_EXTI_IRQHandler(MODE_PB_PIN);
-}
-
-void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
-{
-  if(GPIO_Pin==START_PB_PIN && start_pb_callback!=0)
-    start_pb_callback();
-
-  if(GPIO_Pin==MODE_PB_PIN && mode_pb_callback!=0)
-    mode_pb_callback();
+  if(__HAL_GPIO_EXTI_GET_IT(START_PB_PIN) != RESET)
+  {
+    __HAL_GPIO_EXTI_CLEAR_IT(START_PB_PIN);
+    if(start_pb_callback!=0)
+      start_pb_callback();
+  }
+  if(__HAL_GPIO_EXTI_GET_IT(START_PB_PIN) != RESET)
+  {
+    __HAL_GPIO_EXTI_CLEAR_IT(START_PB_PIN);
+    if(mode_pb_callback!=0)
+      mode_pb_callback();
+  }
 }
 
 void GPO_TIMER1_IRQHandler(void)
-{
-  HAL_TIM_IRQHandler(&GPO_TIM1Handle);
-}
-
-void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
 {
   uint32_t capture;
 
-  if(htim->Instance==GPO_TIMER1)
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM1Handle, TIM_FLAG_CC1) != RESET)
   {
-    if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM1Handle, TIM_IT_CC1) !=RESET)
     {
-      capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
-      __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, (capture + led_tx_period));
+      __HAL_TIM_CLEAR_IT(&GPO_TIM1Handle, TIM_IT_CC1);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM1Handle, TIM_CHANNEL_1);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM1Handle, TIM_CHANNEL_1, (capture + led_tx_period));
       HAL_GPIO_TogglePin(LED_TX_GPIO_PORT,LED_TX_PIN);
     }
-    if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
+  }
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM1Handle, TIM_FLAG_CC2) != RESET)
+  {
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM1Handle, TIM_IT_CC2) !=RESET)
     {
-      capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
-      __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_2, (capture + led_rx_period));
-       HAL_GPIO_TogglePin(LED_RX_GPIO_PORT,LED_RX_PIN);
+      __HAL_TIM_CLEAR_IT(&GPO_TIM1Handle, TIM_IT_CC2);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM1Handle, TIM_CHANNEL_2);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM1Handle, TIM_CHANNEL_2, (capture + led_rx_period));
+      HAL_GPIO_TogglePin(LED_RX_GPIO_PORT,LED_RX_PIN);
     }
-    if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
+  }
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM1Handle, TIM_FLAG_CC3) != RESET)
+  {
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM1Handle, TIM_IT_CC3) !=RESET)
     {
-      capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
-      __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_3, (capture + led_2_period));
-       HAL_GPIO_TogglePin(LED_2_GPIO_PORT,LED_2_PIN);
+      __HAL_TIM_CLEAR_IT(&GPO_TIM1Handle, TIM_IT_CC3);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM1Handle, TIM_CHANNEL_3);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM1Handle, TIM_CHANNEL_3, (capture + led_2_period));
+      HAL_GPIO_TogglePin(LED_2_GPIO_PORT,LED_2_PIN);
     }
-    if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
+  }
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM1Handle, TIM_FLAG_CC4) != RESET)
+  {
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM1Handle, TIM_IT_CC4) !=RESET)
     {
-      capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4);
-      __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_4, (capture + led_3_period));
+      __HAL_TIM_CLEAR_IT(&GPO_TIM1Handle, TIM_IT_CC4);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM1Handle, TIM_CHANNEL_4);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM1Handle, TIM_CHANNEL_4, (capture + led_3_period));
       HAL_GPIO_TogglePin(LED_3_GPIO_PORT,LED_3_PIN);
-    } 
+    }
   }
 }
 
-/*void GPO_TIMER2_IRQHandler(void)
+void GPO_TIMER2_IRQHandler(void)
 {
-  uint16_t capture;
+  uint32_t capture;
 
-  if(TIM_GetITStatus(GPO_TIMER2, TIM_IT_CC1)!=RESET)
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM2Handle, TIM_FLAG_CC1) != RESET)
   {
-    TIM_ClearITPendingBit(GPO_TIMER2,TIM_IT_CC1);
-    if(GPIO_ReadOutputDataBit(LED_5_R_GPIO_PORT,LED_5_R_PIN))
-      HAL_GPIO_WritePin(LED_5_R_GPIO_PORT,LED_5_R_PIN);
-    else
-      GPIO_SetBits(LED_5_R_GPIO_PORT,LED_5_R_PIN);
-    capture = TIM_GetCapture1(GPO_TIMER2);
-    TIM_SetCompare1(GPO_TIMER2, capture + led_5_R_period);
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM2Handle, TIM_IT_CC1) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&GPO_TIM2Handle, TIM_IT_CC1);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM2Handle, TIM_CHANNEL_1);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM2Handle, TIM_CHANNEL_1, (capture + led_5_R_period));
+      HAL_GPIO_TogglePin(LED_5_R_GPIO_PORT,LED_5_R_PIN);
+    }
   }
-  if(TIM_GetITStatus(GPO_TIMER2, TIM_IT_CC2)!=RESET)
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM2Handle, TIM_FLAG_CC2) != RESET)
   {
-    TIM_ClearITPendingBit(GPO_TIMER2,TIM_IT_CC2);
-    if(GPIO_ReadOutputDataBit(LED_5_G_GPIO_PORT,LED_5_G_PIN))
-      HAL_GPIO_WritePin(LED_5_G_GPIO_PORT,LED_5_G_PIN);
-    else
-      GPIO_SetBits(LED_5_G_GPIO_PORT,LED_5_G_PIN);
-    capture = TIM_GetCapture2(GPO_TIMER2);
-    TIM_SetCompare2(GPO_TIMER2, capture + led_5_G_period);
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM2Handle, TIM_IT_CC2) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&GPO_TIM2Handle, TIM_IT_CC2);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM2Handle, TIM_CHANNEL_2);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM2Handle, TIM_CHANNEL_2, (capture + led_5_G_period));
+      HAL_GPIO_TogglePin(LED_5_G_GPIO_PORT,LED_5_G_PIN);
+    }
   }
-  if(TIM_GetITStatus(GPO_TIMER2, TIM_IT_CC3)!=RESET)
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM2Handle, TIM_FLAG_CC3) != RESET)
   {
-    TIM_ClearITPendingBit(GPO_TIMER2,TIM_IT_CC3);
-    if(GPIO_ReadOutputDataBit(LED_5_B_GPIO_PORT,LED_5_B_PIN))
-      HAL_GPIO_WritePin(LED_5_B_GPIO_PORT,LED_5_B_PIN);
-    else
-      GPIO_SetBits(LED_5_B_GPIO_PORT,LED_5_B_PIN);
-    capture = TIM_GetCapture3(GPO_TIMER2);
-    TIM_SetCompare3(GPO_TIMER2, capture + led_5_B_period);
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM2Handle, TIM_IT_CC3) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&GPO_TIM2Handle, TIM_IT_CC3);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM2Handle, TIM_CHANNEL_3);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM2Handle, TIM_CHANNEL_3, (capture + led_5_B_period));
+      HAL_GPIO_TogglePin(LED_5_B_GPIO_PORT,LED_5_B_PIN);
+    }
   }
-  if(TIM_GetITStatus(GPO_TIMER2, TIM_IT_CC4)!=RESET)
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM2Handle, TIM_FLAG_CC4) != RESET)
   {
-    TIM_ClearITPendingBit(GPO_TIMER2,TIM_IT_CC4);
-    if(GPIO_ReadOutputDataBit(LED_4_GPIO_PORT,LED_4_PIN))
-      HAL_GPIO_WritePin(LED_4_GPIO_PORT,LED_4_PIN);
-    else
-      GPIO_SetBits(LED_4_GPIO_PORT,LED_4_PIN);
-    capture = TIM_GetCapture4(GPO_TIMER2);
-    TIM_SetCompare4(GPO_TIMER2, capture + led_4_period);
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM2Handle, TIM_IT_CC4) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&GPO_TIM2Handle, TIM_IT_CC4);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM2Handle, TIM_CHANNEL_4);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM2Handle, TIM_CHANNEL_4, (capture + led_4_period));
+      HAL_GPIO_TogglePin(LED_4_GPIO_PORT,LED_4_PIN);
+    }
   }
 }
 
 void GPO_TIMER3_IRQHandler(void)
 {
-  uint16_t capture;
+  uint32_t capture;
 
-  if(TIM_GetITStatus(GPO_TIMER3, TIM_IT_CC1)!=RESET)
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM3Handle, TIM_FLAG_CC1) != RESET)
   {
-    TIM_ClearITPendingBit(GPO_TIMER3,TIM_IT_CC1);
-    if(GPIO_ReadOutputDataBit(LED_6_R_GPIO_PORT,LED_6_R_PIN))
-      HAL_GPIO_WritePin(LED_6_R_GPIO_PORT,LED_6_R_PIN);
-    else
-      GPIO_SetBits(LED_6_R_GPIO_PORT,LED_6_R_PIN);
-    capture = TIM_GetCapture1(GPO_TIMER3);
-    TIM_SetCompare1(GPO_TIMER3, capture + led_6_R_period);
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM3Handle, TIM_IT_CC1) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&GPO_TIM3Handle, TIM_IT_CC1);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM3Handle, TIM_CHANNEL_1);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM3Handle, TIM_CHANNEL_1, (capture + led_6_R_period));
+      HAL_GPIO_TogglePin(LED_6_R_GPIO_PORT,LED_6_R_PIN);
+    }
   }
-  if(TIM_GetITStatus(GPO_TIMER3, TIM_IT_CC2)!=RESET)
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM3Handle, TIM_FLAG_CC2) != RESET)
   {
-    TIM_ClearITPendingBit(GPO_TIMER3,TIM_IT_CC2);
-    if(GPIO_ReadOutputDataBit(LED_6_G_GPIO_PORT,LED_6_G_PIN))
-      HAL_GPIO_WritePin(LED_6_G_GPIO_PORT,LED_6_G_PIN);
-    else
-      GPIO_SetBits(LED_6_G_GPIO_PORT,LED_6_G_PIN);
-    capture = TIM_GetCapture2(GPO_TIMER3);
-    TIM_SetCompare2(GPO_TIMER3, capture + led_6_G_period);
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM3Handle, TIM_IT_CC2) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&GPO_TIM3Handle, TIM_IT_CC2);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM3Handle, TIM_CHANNEL_2);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM3Handle, TIM_CHANNEL_2, (capture + led_6_G_period));
+      HAL_GPIO_TogglePin(LED_6_G_GPIO_PORT,LED_6_G_PIN);
+    }
   }
-  if(TIM_GetITStatus(GPO_TIMER3, TIM_IT_CC3)!=RESET)
+  if(__HAL_TIM_GET_FLAG(&GPO_TIM3Handle, TIM_FLAG_CC3) != RESET)
   {
-    TIM_ClearITPendingBit(GPO_TIMER3,TIM_IT_CC3);
-    if(GPIO_ReadOutputDataBit(LED_6_B_GPIO_PORT,LED_6_B_PIN))
-      HAL_GPIO_WritePin(LED_6_B_GPIO_PORT,LED_6_B_PIN);
-    else
-      GPIO_SetBits(LED_6_B_GPIO_PORT,LED_6_B_PIN);
-    capture = TIM_GetCapture3(GPO_TIMER3);
-    TIM_SetCompare3(GPO_TIMER3, capture + led_6_B_period);
+    if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM3Handle, TIM_IT_CC3) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&GPO_TIM3Handle, TIM_IT_CC3);
+      capture = HAL_TIM_ReadCapturedValue(&GPO_TIM3Handle, TIM_CHANNEL_3);
+      __HAL_TIM_SET_COMPARE(&GPO_TIM3Handle, TIM_CHANNEL_3, (capture + led_6_B_period));
+      HAL_GPIO_TogglePin(LED_6_B_GPIO_PORT,LED_6_B_PIN);
+    }
   }
-}*/
+}
 
 // private functions
 
@@ -248,14 +257,12 @@ void gpio_init(void)
   ENABLE_LED_6_B_GPIO_CLK;
   ENABLE_START_PB_GPIO_CLK;
   ENABLE_MODE_PB_GPIO_CLK;
-  ENABLE_GPO_TIMER1_CLK;
-  ENABLE_GPO_TIMER2_CLK;
-  ENABLE_GPO_TIMER3_CLK;
 
   /* GPIO Configuration */
   GPIO_InitStructure.Pin = LED_RX_PIN;
   GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
+  GPIO_InitStructure.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(LED_RX_GPIO_PORT, &GPIO_InitStructure);
      
   GPIO_InitStructure.Pin = LED_TX_PIN;
@@ -311,10 +318,6 @@ void gpio_init(void)
   start_pb_callback=0;
   mode_pb_callback=0;
 
-  // initialize the timer interrupts
-  HAL_NVIC_SetPriority(GPO_TIMER1_IRQn, 3, 1);
-  HAL_NVIC_EnableIRQ(GPO_TIMER1_IRQn);
-
   /* LED's timer configuration */
   GPO_TIM1Handle.Instance=GPO_TIMER1;
   GPO_TIM1Handle.Init.Period = 0xFFFF;
@@ -322,11 +325,12 @@ void gpio_init(void)
   GPO_TIM1Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
   GPO_TIM1Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
   GPO_TIM1Handle.Init.RepetitionCounter=0;
-  HAL_TIM_OC_Init(&GPO_TIM1Handle);
-
+  HAL_TIM_Base_Init(&GPO_TIM1Handle);
+  ENABLE_GPO_TIMER1_CLK;
   // initialize the timer interrupts
-  HAL_NVIC_SetPriority(GPO_TIMER2_IRQn, 3, 2);
-  HAL_NVIC_EnableIRQ(GPO_TIMER2_IRQn);
+  HAL_NVIC_SetPriority(GPO_TIMER1_IRQn, 3, 1);
+  HAL_NVIC_EnableIRQ(GPO_TIMER1_IRQn);
+  HAL_TIM_OC_Init(&GPO_TIM1Handle);
 
   /* LED's timer configuration */
   GPO_TIM2Handle.Instance=GPO_TIMER2;
@@ -335,11 +339,12 @@ void gpio_init(void)
   GPO_TIM2Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
   GPO_TIM2Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
   GPO_TIM2Handle.Init.RepetitionCounter=0;
-  HAL_TIM_OC_Init(&GPO_TIM2Handle);
-
+  HAL_TIM_Base_Init(&GPO_TIM2Handle);
+  ENABLE_GPO_TIMER2_CLK;
   // initialize the timer interrupts
-  HAL_NVIC_SetPriority(GPO_TIMER3_IRQn, 3, 3);
-  HAL_NVIC_EnableIRQ(GPO_TIMER3_IRQn);
+  HAL_NVIC_SetPriority(GPO_TIMER2_IRQn, 3, 2);
+  HAL_NVIC_EnableIRQ(GPO_TIMER2_IRQn);
+  HAL_TIM_OC_Init(&GPO_TIM2Handle);
 
   /* LED's timer configuration */
   GPO_TIM3Handle.Instance=GPO_TIMER3;
@@ -348,10 +353,15 @@ void gpio_init(void)
   GPO_TIM3Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
   GPO_TIM3Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
   GPO_TIM3Handle.Init.RepetitionCounter=0;
+  HAL_TIM_Base_Init(&GPO_TIM3Handle);
+  ENABLE_GPO_TIMER3_CLK;
+  // initialize the timer interrupts
+  HAL_NVIC_SetPriority(GPO_TIMER3_IRQn, 3, 3);
+  HAL_NVIC_EnableIRQ(GPO_TIMER3_IRQn);
   HAL_TIM_OC_Init(&GPO_TIM3Handle);
 
   /* enable external interrupts */
-  HAL_NVIC_SetPriority(GPI_EXTI1_IRQn, 2, 3);
+  HAL_NVIC_SetPriority(GPI_EXTI1_IRQn, 3, 0);
   HAL_NVIC_EnableIRQ(GPI_EXTI1_IRQn);
 
   // turn off all leds
@@ -533,7 +543,7 @@ void gpio_blink_led(led_t led_id, int16_t period_ms)
       {
         led_2_period=period_ms;
         TIM_OCInitStructure.Pulse = led_2_period;
-        HAL_TIM_OC_ConfigChannel(&GPO_TIM1Handle, &TIM_OCInitStructure,TIM_CHANNEL_3);
+        HAL_TIM_OC_ConfigChannel(&GPO_TIM1Handle, &TIM_OCInitStructure,TIM_CHANNEL_3); 
         HAL_TIM_OC_Start_IT(&GPO_TIM1Handle, TIM_CHANNEL_3);
       }
       else
@@ -550,120 +560,99 @@ void gpio_blink_led(led_t led_id, int16_t period_ms)
       else
         HAL_TIM_OC_Stop_IT(&GPO_TIM1Handle, TIM_CHANNEL_4);
       break;
-/*    case LED_4:
+    case LED_4:
       if(period_ms>1)
       {
         led_4_period=period_ms;
-        TIM_OCInitStructure.TIM_Pulse = led_4_period;
-        TIM_OC4Init(GPO_TIMER2, &TIM_OCInitStructure);
-        TIM_OC4PreloadConfig(GPO_TIMER2, TIM_OCPreload_Disable);
-        capture = TIM_GetCounter(GPO_TIMER2);
-        TIM_SetCompare4(GPO_TIMER2, capture + led_4_period);
-        TIM_ITConfig(GPO_TIMER2, TIM_IT_CC4, ENABLE);
+        TIM_OCInitStructure.Pulse = led_4_period;
+        HAL_TIM_OC_ConfigChannel(&GPO_TIM2Handle, &TIM_OCInitStructure,TIM_CHANNEL_4);
+        HAL_TIM_OC_Start_IT(&GPO_TIM2Handle, TIM_CHANNEL_4);
       }
       else
-        TIM_ITConfig(GPO_TIMER2, TIM_IT_CC4, DISABLE);
+        HAL_TIM_OC_Stop_IT(&GPO_TIM2Handle, TIM_CHANNEL_4);
       break;
     case LED_5_R:
       if(period_ms>1)
       {
         led_5_R_period=period_ms;
-        TIM_OCInitStructure.TIM_Pulse = led_5_R_period;
-        TIM_OC1Init(GPO_TIMER2, &TIM_OCInitStructure);
-        TIM_OC1PreloadConfig(GPO_TIMER2, TIM_OCPreload_Disable);
-        capture = TIM_GetCounter(GPO_TIMER2);
-        TIM_SetCompare1(GPO_TIMER2, capture + led_5_R_period);
-        TIM_ITConfig(GPO_TIMER2, TIM_IT_CC1, ENABLE);
+        TIM_OCInitStructure.Pulse = led_5_R_period;
+        HAL_TIM_OC_ConfigChannel(&GPO_TIM2Handle, &TIM_OCInitStructure,TIM_CHANNEL_1);
+        HAL_TIM_OC_Start_IT(&GPO_TIM2Handle, TIM_CHANNEL_1);
       }
       else
-        TIM_ITConfig(GPO_TIMER2, TIM_IT_CC1, DISABLE);
+        HAL_TIM_OC_Stop_IT(&GPO_TIM2Handle, TIM_CHANNEL_1);
       break;
     case LED_5_G:
       if(period_ms>1)
       {
         led_5_G_period=period_ms;
-        TIM_OCInitStructure.TIM_Pulse = led_5_G_period;
-        TIM_OC2Init(GPO_TIMER2, &TIM_OCInitStructure);
-        TIM_OC2PreloadConfig(GPO_TIMER2, TIM_OCPreload_Disable);
-        capture = TIM_GetCounter(GPO_TIMER2);
-        TIM_SetCompare2(GPO_TIMER2, capture + led_5_G_period);
-        TIM_ITConfig(GPO_TIMER2, TIM_IT_CC2, ENABLE);
+        TIM_OCInitStructure.Pulse = led_5_G_period;
+        HAL_TIM_OC_ConfigChannel(&GPO_TIM2Handle, &TIM_OCInitStructure,TIM_CHANNEL_2);
+        HAL_TIM_OC_Start_IT(&GPO_TIM2Handle, TIM_CHANNEL_2);
       }
       else
-        TIM_ITConfig(GPO_TIMER2, TIM_IT_CC2, DISABLE);
+        HAL_TIM_OC_Stop_IT(&GPO_TIM2Handle, TIM_CHANNEL_2);
       break;
     case LED_5_B:
       if(period_ms>1)
       {
         led_5_B_period=period_ms;
-        TIM_OCInitStructure.TIM_Pulse = led_5_B_period;
-        TIM_OC3Init(GPO_TIMER2, &TIM_OCInitStructure);
-        TIM_OC3PreloadConfig(GPO_TIMER2, TIM_OCPreload_Disable);
-        capture = TIM_GetCounter(GPO_TIMER2);
-        TIM_SetCompare3(GPO_TIMER2, capture + led_5_B_period);
-        TIM_ITConfig(GPO_TIMER2, TIM_IT_CC3, ENABLE);
+        TIM_OCInitStructure.Pulse = led_5_B_period;
+        HAL_TIM_OC_ConfigChannel(&GPO_TIM2Handle, &TIM_OCInitStructure,TIM_CHANNEL_3);
+        HAL_TIM_OC_Start_IT(&GPO_TIM2Handle, TIM_CHANNEL_3);
       }
       else
-        TIM_ITConfig(GPO_TIMER2, TIM_IT_CC3, DISABLE);
+        HAL_TIM_OC_Stop_IT(&GPO_TIM2Handle, TIM_CHANNEL_3);
       break;
     case LED_6_R:
       if(period_ms>1)
       {
         led_6_R_period=period_ms;
-        TIM_OCInitStructure.TIM_Pulse = led_6_R_period;
-        TIM_OC1Init(GPO_TIMER3, &TIM_OCInitStructure);
-        TIM_OC1PreloadConfig(GPO_TIMER3, TIM_OCPreload_Disable);
-        capture = TIM_GetCounter(GPO_TIMER3);
-        TIM_SetCompare1(GPO_TIMER3, capture + led_6_R_period);
-        TIM_ITConfig(GPO_TIMER3, TIM_IT_CC1, ENABLE);
+        TIM_OCInitStructure.Pulse = led_6_R_period;
+        HAL_TIM_OC_ConfigChannel(&GPO_TIM3Handle, &TIM_OCInitStructure,TIM_CHANNEL_1);
+        HAL_TIM_OC_Start_IT(&GPO_TIM3Handle, TIM_CHANNEL_1);
       }
       else
-        TIM_ITConfig(GPO_TIMER3, TIM_IT_CC1, DISABLE);
+        HAL_TIM_OC_Stop_IT(&GPO_TIM3Handle, TIM_CHANNEL_1);
       break;
     case LED_6_G:
       if(period_ms>1)
       {
         led_6_G_period=period_ms;
-        TIM_OCInitStructure.TIM_Pulse = led_6_G_period;
-        TIM_OC2Init(GPO_TIMER3, &TIM_OCInitStructure);
-        TIM_OC2PreloadConfig(GPO_TIMER3, TIM_OCPreload_Disable);
-        capture = TIM_GetCounter(GPO_TIMER3);
-        TIM_SetCompare2(GPO_TIMER3, capture + led_6_G_period);
-        TIM_ITConfig(GPO_TIMER3, TIM_IT_CC2, ENABLE);
+        TIM_OCInitStructure.Pulse = led_6_G_period;
+        HAL_TIM_OC_ConfigChannel(&GPO_TIM3Handle, &TIM_OCInitStructure,TIM_CHANNEL_2);
+        HAL_TIM_OC_Start_IT(&GPO_TIM3Handle, TIM_CHANNEL_2);
       }
       else
-        TIM_ITConfig(GPO_TIMER3, TIM_IT_CC2, DISABLE);
+        HAL_TIM_OC_Stop_IT(&GPO_TIM3Handle, TIM_CHANNEL_2);
       break;
     case LED_6_B:
       if(period_ms>1)
       {
         led_6_B_period=period_ms;
-        TIM_OCInitStructure.TIM_Pulse = led_6_B_period;
-        TIM_OC3Init(GPO_TIMER3, &TIM_OCInitStructure);
-        TIM_OC3PreloadConfig(GPO_TIMER3, TIM_OCPreload_Disable);
-        capture = TIM_GetCounter(GPO_TIMER3);
-        TIM_SetCompare3(GPO_TIMER3, capture + led_6_B_period);
-        TIM_ITConfig(GPO_TIMER3, TIM_IT_CC3, ENABLE);
+        TIM_OCInitStructure.Pulse = led_6_B_period;
+        HAL_TIM_OC_ConfigChannel(&GPO_TIM3Handle, &TIM_OCInitStructure,TIM_CHANNEL_3);
+        HAL_TIM_OC_Start_IT(&GPO_TIM3Handle, TIM_CHANNEL_3);
       }
       else
-        TIM_ITConfig(GPO_TIMER3, TIM_IT_CC3, DISABLE);
-      break;*/
+        HAL_TIM_OC_Stop_IT(&GPO_TIM3Handle, TIM_CHANNEL_3);
+      break;
     default: break;
   }
 }
 
-/*uint8_t gpio_is_pushbutton_pressed(pushbutton_t pb_id)
+uint8_t gpio_is_pushbutton_pressed(pushbutton_t pb_id)
 {
   switch(pb_id)
   {
     case START_PB:
-      if(GPIO_ReadInputDataBit(START_PB_GPIO_PORT,START_PB_PIN)==Bit_SET)
+      if(HAL_GPIO_ReadPin(START_PB_GPIO_PORT,START_PB_PIN)==GPIO_PIN_SET)
         return 0x01;
       else
         return 0x00;
       break;
     case MODE_PB:
-      if(GPIO_ReadInputDataBit(MODE_PB_GPIO_PORT,MODE_PB_PIN)==Bit_SET)
+      if(HAL_GPIO_ReadPin(MODE_PB_GPIO_PORT,MODE_PB_PIN)==GPIO_PIN_SET)
         return 0x01;
       else
         return 0x00;
@@ -684,4 +673,4 @@ void gpio_set_pushbutton_callback(pushbutton_t pb_id,void (*callback)(void))
       mode_pb_callback=callback;
       break;
   }
-}*/
+}
diff --git a/src/ram.c b/src/ram.c
index 521d8f821541cc9b73a081284e91c8f3afe5dfd8..65cf3bc6a3ffc215f9179f2d3f102e573a79d72e 100755
--- a/src/ram.c
+++ b/src/ram.c
@@ -9,7 +9,7 @@ void ram_init(void)
   for(i=0;i<RAM_SIZE;i++)
     ram_data[i]=0x00;
   // read contents from EEPROM to RAM
-/*  if(EE_ReadVariable(DEVICE_MODEL_OFFSET,&eeprom_data)==0)
+  if(EE_ReadVariable(DEVICE_MODEL_OFFSET,&eeprom_data)==0)
     ram_data[DEVICE_MODEL_OFFSET]=(uint8_t)(eeprom_data&0x00FF);
   if(EE_ReadVariable(DEVICE_MODEL_OFFSET+1,&eeprom_data)==0)
     ram_data[DEVICE_MODEL_OFFSET+1]=(uint8_t)(eeprom_data&0x00FF);
@@ -26,7 +26,7 @@ void ram_init(void)
   if(EE_ReadVariable(MM_PERIOD_OFFSET+1,&eeprom_data)==0)
     ram_data[MM_PERIOD_OFFSET+1]=(uint8_t)eeprom_data;
   if(EE_ReadVariable(RETURN_LEVEL_OFFSET,&eeprom_data)==0)
-    ram_data[RETURN_LEVEL_OFFSET]=(uint8_t)eeprom_data;*/
+    ram_data[RETURN_LEVEL_OFFSET]=(uint8_t)eeprom_data;
 }
 
 inline void ram_read_byte(uint8_t address,uint8_t *data)
diff --git a/src/stm32f1xx_hal_msp.c b/src/stm32f1xx_hal_msp.c
index 1997e3bfc43114d24943e1d2686fbf100326b3fa..62b98879c377f6cf49011bb99a52f850e467435b 100755
--- a/src/stm32f1xx_hal_msp.c
+++ b/src/stm32f1xx_hal_msp.c
@@ -79,28 +79,25 @@ void HAL_MspInit(void)
   /* NOTE : This function is generated automatically by MicroXplorer and eventually  
             modified by the user
    */ 
-  RCC_ClkInitTypeDef RCC_ClkInitStruct;
   RCC_OscInitTypeDef RCC_OscInitStruct;
+  RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
-  /* Set Interrupt Group Priority */
-  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);// 4 priorities, 4 subpriorities
+  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
 
   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
-  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;
+  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
   HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
-  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;
+  RCC_ClkInitStruct.ClockType =  (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
-
-  __HAL_RCC_AFIO_CLK_ENABLE();
 }
 
 /**
diff --git a/src/system_stm32f1xx.c b/src/system_stm32f1xx.c
new file mode 100644
index 0000000000000000000000000000000000000000..6014fa957ffbd54063b032a05006869fe577c5e6
--- /dev/null
+++ b/src/system_stm32f1xx.c
@@ -0,0 +1,446 @@
+/**
+  ******************************************************************************
+  * @file    system_stm32f1xx.c
+  * @author  MCD Application Team
+  * @version V4.0.0
+  * @date    16-December-2014
+  * @brief   CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
+  * 
+  * 1.  This file provides two functions and one global variable to be called from 
+  *     user application:
+  *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+  *                      factors, AHB/APBx prescalers and Flash settings). 
+  *                      This function is called at startup just after reset and 
+  *                      before branch to main program. This call is made inside
+  *                      the "startup_stm32f1xx_xx.s" file.
+  *
+  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+  *                                  by the user application to setup the SysTick 
+  *                                  timer or configure other parameters.
+  *                                     
+  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+  *                                 be called whenever the core clock is changed
+  *                                 during program execution.
+  *
+  * 2. After each device reset the HSI (8 MHz) is used as system clock source.
+  *    Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
+  *    configure the system clock before to branch to main program.
+  *
+  * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
+  *    the product used), refer to "HSE_VALUE". 
+  *    When HSE is used as system clock source, directly or through PLL, and you
+  *    are using different crystal you have to adapt the HSE value to your own
+  *    configuration.
+  *        
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup stm32f1xx_system
+  * @{
+  */  
+  
+/** @addtogroup STM32F1xx_System_Private_Includes
+  * @{
+  */
+
+#include "stm32f1xx.h"
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F1xx_System_Private_Defines
+  * @{
+  */
+
+#if !defined  (HSE_VALUE) 
+  #define HSE_VALUE    ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz.
+                                                This value can be provided and adapted by the user application. */
+#endif /* HSE_VALUE */
+
+#if !defined  (HSI_VALUE)
+  #define HSI_VALUE    ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz.
+                                                This value can be provided and adapted by the user application. */
+#endif /* HSI_VALUE */
+
+/*!< Uncomment the following line if you need to use external SRAM  */ 
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+/* #define DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+     Internal SRAM. */ 
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET  0x3000 /*!< Vector Table base offset field. 
+                                  This value must be a multiple of 0x200. */
+
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F1xx_System_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F1xx_System_Private_Variables
+  * @{
+  */
+
+/*******************************************************************************
+*  Clock Definitions
+*******************************************************************************/
+#if defined(STM32F100xB) ||defined(STM32F100xE)
+  uint32_t SystemCoreClock         = 24000000;        /*!< System Clock Frequency (Core Clock) */
+#else /*!< HSI Selected as System Clock source */
+  uint32_t SystemCoreClock         = 72000000;        /*!< System Clock Frequency (Core Clock) */
+#endif
+
+__IO const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
+  * @{
+  */
+
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+#ifdef DATA_IN_ExtSRAM
+  static void SystemInit_ExtMemCtl(void); 
+#endif /* DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F1xx_System_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Setup the microcontroller system
+  *         Initialize the Embedded Flash Interface, the PLL and update the 
+  *         SystemCoreClock variable.
+  * @note   This function should be used only after reset.
+  * @param  None
+  * @retval None
+  */
+void SystemInit (void)
+{
+  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
+  /* Set HSION bit */
+  RCC->CR |= (uint32_t)0x00000001;
+
+  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
+#if !defined(STM32F105xC) && !defined(STM32F107xC)
+  RCC->CFGR &= (uint32_t)0xF8FF0000;
+#else
+  RCC->CFGR &= (uint32_t)0xF0FF0000;
+#endif /* STM32F105xC */   
+  
+  /* Reset HSEON, CSSON and PLLON bits */
+  RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+  /* Reset HSEBYP bit */
+  RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
+  RCC->CFGR &= (uint32_t)0xFF80FFFF;
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+  /* Reset PLL2ON and PLL3ON bits */
+  RCC->CR &= (uint32_t)0xEBFFFFFF;
+
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x00FF0000;
+
+  /* Reset CFGR2 register */
+  RCC->CFGR2 = 0x00000000;
+#elif defined(STM32F100xB) || defined(STM32F100xE)
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x009F0000;
+
+  /* Reset CFGR2 register */
+  RCC->CFGR2 = 0x00000000;      
+#else
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x009F0000;
+#endif /* STM32F105xC */
+    
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+  #ifdef DATA_IN_ExtSRAM
+    SystemInit_ExtMemCtl(); 
+  #endif /* DATA_IN_ExtSRAM */
+#endif 
+
+#ifdef VECT_TAB_SRAM
+  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
+#else
+  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
+#endif 
+}
+
+/**
+  * @brief  Update SystemCoreClock variable according to Clock Register Values.
+  *         The SystemCoreClock variable contains the core clock (HCLK), it can
+  *         be used by the user application to setup the SysTick timer or configure
+  *         other parameters.
+  *           
+  * @note   Each time the core clock (HCLK) changes, this function must be called
+  *         to update SystemCoreClock variable value. Otherwise, any configuration
+  *         based on this variable will be incorrect.         
+  *     
+  * @note   - The system frequency computed by this function is not the real 
+  *           frequency in the chip. It is calculated based on the predefined 
+  *           constant and the selected clock source:
+  *             
+  *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+  *                                              
+  *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+  *                          
+  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 
+  *             or HSI_VALUE(*) multiplied by the PLL factors.
+  *         
+  *         (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
+  *             8 MHz) but the real value may vary depending on the variations
+  *             in voltage and temperature.   
+  *    
+  *         (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
+  *              8 MHz or 25 MHz, depending on the product used), user has to ensure
+  *              that HSE_VALUE is same as the real frequency of the crystal used.
+  *              Otherwise, this function may have wrong result.
+  *                
+  *         - The result of this function could be not correct when using fractional
+  *           value for HSE crystal.
+  * @param  None
+  * @retval None
+  */
+void SystemCoreClockUpdate (void)
+{
+  uint32_t tmp = 0, pllmull = 0, pllsource = 0;
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+  uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
+#endif /* STM32F105xC */
+
+#if defined(STM32F100xB) || defined(STM32F100xE)
+  uint32_t prediv1factor = 0;
+#endif /* STM32F100xB or STM32F100xE */
+    
+  /* Get SYSCLK source -------------------------------------------------------*/
+  tmp = RCC->CFGR & RCC_CFGR_SWS;
+  
+  switch (tmp)
+  {
+    case 0x00:  /* HSI used as system clock */
+      SystemCoreClock = HSI_VALUE;
+      break;
+    case 0x04:  /* HSE used as system clock */
+      SystemCoreClock = HSE_VALUE;
+      break;
+    case 0x08:  /* PLL used as system clock */
+
+      /* Get PLL clock source and multiplication factor ----------------------*/
+      pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
+      pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+      
+#if !defined(STM32F105xC) && !defined(STM32F107xC)      
+      pllmull = ( pllmull >> 18) + 2;
+      
+      if (pllsource == 0x00)
+      {
+        /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+        SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
+      }
+      else
+      {
+ #if defined(STM32F100xB) || defined(STM32F100xE)
+       prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
+       /* HSE oscillator clock selected as PREDIV1 clock entry */
+       SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 
+ #else
+        /* HSE selected as PLL clock entry */
+        if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
+        {/* HSE oscillator clock divided by 2 */
+          SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
+        }
+        else
+        {
+          SystemCoreClock = HSE_VALUE * pllmull;
+        }
+ #endif
+      }
+#else
+      pllmull = pllmull >> 18;
+      
+      if (pllmull != 0x0D)
+      {
+         pllmull += 2;
+      }
+      else
+      { /* PLL multiplication factor = PLL input clock * 6.5 */
+        pllmull = 13 / 2; 
+      }
+            
+      if (pllsource == 0x00)
+      {
+        /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+        SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
+      }
+      else
+      {/* PREDIV1 selected as PLL clock entry */
+        
+        /* Get PREDIV1 clock source and division factor */
+        prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
+        prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
+        
+        if (prediv1source == 0)
+        { 
+          /* HSE oscillator clock selected as PREDIV1 clock entry */
+          SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;          
+        }
+        else
+        {/* PLL2 clock selected as PREDIV1 clock entry */
+          
+          /* Get PREDIV2 division factor and PLL2 multiplication factor */
+          prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
+          pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; 
+          SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                         
+        }
+      }
+#endif /* STM32F105xC */ 
+      break;
+
+    default:
+      SystemCoreClock = HSI_VALUE;
+      break;
+  }
+  
+  /* Compute HCLK clock frequency ----------------*/
+  /* Get HCLK prescaler */
+  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+  /* HCLK clock frequency */
+  SystemCoreClock >>= tmp;  
+}
+
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+/**
+  * @brief  Setup the external memory controller. Called in startup_stm32f1xx.s 
+  *          before jump to __main
+  * @param  None
+  * @retval None
+  */ 
+#ifdef DATA_IN_ExtSRAM
+/**
+  * @brief  Setup the external memory controller. 
+  *         Called in startup_stm32f1xx_xx.s/.c before jump to main.
+  *         This function configures the external SRAM mounted on STM3210E-EVAL
+  *         board (STM32 High density devices). This SRAM will be used as program
+  *         data memory (including heap and stack).
+  * @param  None
+  * @retval None
+  */ 
+void SystemInit_ExtMemCtl(void) 
+{
+  __IO uint32_t tmpreg;
+  /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is 
+    required, then adjust the Register Addresses */
+
+  /* Enable FSMC clock */
+  RCC->AHBENR = 0x00000114;
+
+  /* Delay after an RCC peripheral clock enabling */
+  tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
+  
+  /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
+  RCC->APB2ENR = 0x000001E0;
+  
+  /* Delay after an RCC peripheral clock enabling */
+  tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
+
+  (void)(tmpreg);
+  
+/* ---------------  SRAM Data lines, NOE and NWE configuration ---------------*/
+/*----------------  SRAM Address lines configuration -------------------------*/
+/*----------------  NOE and NWE configuration --------------------------------*/  
+/*----------------  NE3 configuration ----------------------------------------*/
+/*----------------  NBL0, NBL1 configuration ---------------------------------*/
+  
+  GPIOD->CRL = 0x44BB44BB;  
+  GPIOD->CRH = 0xBBBBBBBB;
+
+  GPIOE->CRL = 0xB44444BB;  
+  GPIOE->CRH = 0xBBBBBBBB;
+
+  GPIOF->CRL = 0x44BBBBBB;  
+  GPIOF->CRH = 0xBBBB4444;
+
+  GPIOG->CRL = 0x44BBBBBB;  
+  GPIOG->CRH = 0x444B4B44;
+   
+/*----------------  FSMC Configuration ---------------------------------------*/  
+/*----------------  Enable FSMC Bank1_SRAM Bank ------------------------------*/
+  
+  FSMC_Bank1->BTCR[4] = 0x00001091;
+  FSMC_Bank1->BTCR[5] = 0x00110212;
+}
+#endif /* DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */    
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/time.c b/src/time.c
index e2d6e6b49ee208244184e893fc89551755d14f2c..5b0cbee6b1bfe6fd45f9eec883154d8b826ded73 100755
--- a/src/time.c
+++ b/src/time.c
@@ -1,60 +1,33 @@
 #include "time.h"
 
-static __IO uint32_t timing_delay;
 uint32_t clocks_per_us;
-
-/*******************************************************************************
-* Function Name  : SysTickHandler
-* Description    : This function handles SysTick Handler.
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void SysTick_Handler(void)
-{
-  if(timing_delay!=0)
-    timing_delay--;
-}
+TIM_HandleTypeDef us_timer_Handle;
 
 // public functions
 void time_init(void)
 {
-  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
-
-  // set the time base to 1ms
-  SysTick_Config(SystemCoreClock / 1000);
-  NVIC_SetPriority(SysTick_IRQn,0);
-
-  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
-
-  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
-  TIM_TimeBaseStructure.TIM_Prescaler = 0;
-  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
-  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
-  TIM_TimeBaseStructure.TIM_RepetitionCounter=0x0000;
-  TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
-  TIM_SetCounter(TIM1,0);
-
+  us_timer_Handle.Instance=TIM1;
+  us_timer_Handle.Init.Period = 0xFFFF;
+  us_timer_Handle.Init.Prescaler = 0;
+  us_timer_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  us_timer_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
+  us_timer_Handle.Init.RepetitionCounter=0;
+  HAL_TIM_Base_Init(&us_timer_Handle);
+  __HAL_RCC_TIM1_CLK_ENABLE();
+  __HAL_TIM_SET_COUNTER(&us_timer_Handle,0);
   clocks_per_us=(SystemCoreClock/1000000)+1;
 }
 
-void delay_ms(__IO uint32_t time)
-{
-  timing_delay=time;
-
-  while(timing_delay!=0);
-}
- 
 void delay_us(uint32_t us) // microseconds
 {
   uint32_t clocks,current;
 
   clocks=clocks_per_us*us;
-  TIM_SetCounter(TIM1,0);
-  TIM_Cmd(TIM1, ENABLE);
+  __HAL_TIM_SET_COUNTER(&us_timer_Handle,0);
+  HAL_TIM_Base_Start(&us_timer_Handle);
   do{
-    current=TIM_GetCounter(TIM1);
+    current=__HAL_TIM_GET_COUNTER(&us_timer_Handle);
   }while(current<clocks);
-  TIM_Cmd(TIM1, DISABLE);
+  HAL_TIM_Base_Stop(&us_timer_Handle);
 }