diff --git a/src/fw_downloader/fw_downloader.cpp b/src/fw_downloader/fw_downloader.cpp
index 39eb7e3ea81bba88c15f16b015f297f56ed56b19..a89ef02db34fd11fe61b1793d4c39662dee75b77 100755
--- a/src/fw_downloader/fw_downloader.cpp
+++ b/src/fw_downloader/fw_downloader.cpp
@@ -11,7 +11,7 @@
 
 const unsigned char bootloader_ping='#';
 const unsigned char bootloader_ack[]="\n";
-const unsigned char bootloader_load_hex[]="l\n";
+const unsigned char bootloader_load_hex[]="l 0x08003000\n";
 const unsigned char bootloader_load_motion[]="l 0x08060000\n";
 const unsigned char bootloader_go[]="\ngo\n";
 
@@ -41,14 +41,15 @@ int main(int argc,char *argv[])
   std::string opt_device,opt_fw_file,opt_motion_file,servo_model;
   // binary file variables
   unsigned char binary_file[MEMORY_MAXSIZE];
-  long int downloaded_size=0;
+  long int downloaded_size=0,downloaded_block_size=0;
   long int start_address=0;
   long int binary_size=0;
-  int block_size=0,count=0;
+  int block_size=0,count=0,small_block_size=0;
   // bootloader variables
   unsigned char bootloader_data[MEMORY_MAXSIZE];
-  bool bootloader_connected=false;
+  bool bootloader_connected=false,error=false;
   unsigned char checksum=0x00;
+  char load_hex_address[32];
   // motion file variables
   FILE *motion_fd;
 
@@ -58,6 +59,9 @@ int main(int argc,char *argv[])
   serial_config.parity=none;
   serial_config.stop_bits=1;
 
+  for(i=0;i<MEMORY_MAXSIZE;i++)
+    binary_file[i]=0xFF;
+
   // parse the input arguments
   do{
     opt_status=getopt_long_only(argc,argv,"",long_options,&opt_index);
@@ -192,7 +196,7 @@ int main(int argc,char *argv[])
         while(!end)
         {
           try{
-            event_server->wait_all(events,1000);
+            event_server->wait_all(events,3000);
             num_data=serial_port.get_num_data();
             serial_port.read(bootloader_data,num_data);
             bootloader_data[num_data]='\0';
@@ -206,14 +210,11 @@ int main(int argc,char *argv[])
         sleep(1);
         end=false;
         // start the download
-//        if(opt_fw_file.size()!=0)
-          serial_port.write((unsigned char *)bootloader_load_hex,1);
-//        else
-//          serial_port.write((unsigned char *)bootloader_load_motion,13);
+        serial_port.write((unsigned char *)bootloader_load_hex,13);
         while(!end)
         {
           try{
-            event_server->wait_all(events,1000);
+            event_server->wait_all(events,3000);
             num_data=serial_port.get_num_data();
             serial_port.read(bootloader_data,num_data);
             bootloader_data[num_data]='\0';
@@ -225,7 +226,7 @@ int main(int argc,char *argv[])
           }
         }
         sleep(1);
-        if(servo_model=="mx28")
+/*        if(servo_model=="mx28")
         {
           end=false;
           serial_port.write((unsigned char *)bootloader_ack, 1);
@@ -244,8 +245,106 @@ int main(int argc,char *argv[])
             }
           }
           sleep(1);
-        }
-        end=false;
+        }*/
+/*        end=false;
+        while(downloaded_size < binary_size)
+        {
+          sleep(1);
+          end=false;
+          sprintf(load_hex_address,"l 0x%08x\n",(int)(0x08000000+start_address+downloaded_size));
+          serial_port.write((unsigned char *)load_hex_address, strlen(load_hex_address));
+          while(!end)
+          {
+            try{
+              event_server->wait_all(events,1000);
+              error=true;
+              num_data=serial_port.get_num_data();
+              serial_port.read(bootloader_data,num_data);
+              bootloader_data[num_data]='\0';
+              printf("%s",bootloader_data);
+              fflush(stdout);
+            }catch(CEventTimeoutException &e){
+              // the flash has been properly erased
+              if(error)
+              {
+                serial_port.close();
+                return 0;
+              }
+              else
+                end=true;
+            }
+          }
+          sleep(1);
+          if(servo_model=="mx28")
+          {
+            error=false;
+            end=false;
+            serial_port.write((unsigned char *)bootloader_ack, 1);
+            while(!end)
+            {
+              try{
+                event_server->wait_all(events,3000);
+                num_data=serial_port.get_num_data();
+                serial_port.read(bootloader_data,num_data);
+                bootloader_data[num_data]='\0';
+                printf("%s",bootloader_data);
+                fflush(stdout);
+              }catch(CEventTimeoutException &e){
+                // the flash has been properly erased
+                if(error)
+                {
+                  serial_port.close();
+                  return 0;
+                }
+                else
+                  end=true;
+              }
+            }
+            sleep(1);
+          }
+          block_size=binary_size-downloaded_size;
+          if(block_size>64*1024)
+            block_size=64*1024;
+          // compute the binary file checksum
+          checksum=0;
+          for(i=0;i<block_size;i++)
+            checksum+=binary_file[start_address+downloaded_size+i];
+          downloaded_block_size=0;
+          while(downloaded_block_size < block_size)
+          {
+            usleep(1000);
+            small_block_size=block_size-downloaded_block_size;
+            if(small_block_size>64)
+              small_block_size=64;
+            serial_port.write(&binary_file[start_address+downloaded_size+downloaded_block_size],small_block_size);
+            downloaded_block_size+=small_block_size;
+            printf("\rDownloading Firmware (%ld/%ld byte)", downloaded_block_size, block_size);
+          }
+          downloaded_size+=block_size;
+          serial_port.write(&checksum,1);
+          sleep(1);
+          end=false;
+          while(!end)
+          {
+            try{
+              event_server->wait_all(events,3000);
+              // there has been an error
+              num_data=serial_port.get_num_data();
+              serial_port.read(bootloader_data,num_data);
+              bootloader_data[num_data]='\0';
+              printf("%s",bootloader_data);
+            }catch(CEventTimeoutException &e){
+              // no error to report
+              if(error)
+              {
+                serial_port.close();
+                return 0;
+              }
+              else
+                end=true;
+            }
+          }
+        }*/
         // compute the binary file checksum
         for(i=0;i<binary_size;i++)
           checksum+=binary_file[start_address+i];
diff --git a/src/fw_downloader/hex2bin.cpp b/src/fw_downloader/hex2bin.cpp
index 256e190ec2a093f1628eaface2a820eae1c7080c..f556c72d674e820725cd952a64e9923f9696b04f 100755
--- a/src/fw_downloader/hex2bin.cpp
+++ b/src/fw_downloader/hex2bin.cpp
@@ -82,9 +82,8 @@ bool hex2bin(char *hexFile, unsigned char *pBinBuffer, long *StartAddress, long
       case 0:
 	Address = First_Word;
 	Phys_Addr = ((Segment << 4) & ADDRESS_MASK) + Address + Ext_Addr;
-
 	/* Check that the physical address stays in the buffer's range. */
-	if ((Phys_Addr + Nb_Bytes) <= MEMORY_MAXSIZE -1)
+	if ((Phys_Addr + Nb_Bytes) <= MEMORY_MAXSIZE )//-1)
 	{
 	  /* Set the lowest address as base pointer. */
 	  if(Lowest_Address > Phys_Addr)
diff --git a/src/fw_downloader/hex2bin.h b/src/fw_downloader/hex2bin.h
index d51e0eefdc1abba7876491eac622130f6315f074..f486e96e1df0f5568cae8e512a624bf45914c660 100755
--- a/src/fw_downloader/hex2bin.h
+++ b/src/fw_downloader/hex2bin.h
@@ -5,7 +5,7 @@
 extern "C" {
 #endif
 
-#define MEMORY_MAXSIZE		256*1024		/* size in bytes */
+#define MEMORY_MAXSIZE		512*1024		/* size in bytes */
 bool hex2bin(char *hexFile, unsigned char *pBinBuffer, long *StartAddress, long *pBufSize);
 
 #ifdef __cplusplus
diff --git a/src/robotis_bin_file/CMakeLists.txt b/src/robotis_bin_file/CMakeLists.txt
index 772e4c9d97c4a6b1480859d30ed7ec768b329789..63160c67298e2298a8fb9d3f496ed0e8897e4ee8 100644
--- a/src/robotis_bin_file/CMakeLists.txt
+++ b/src/robotis_bin_file/CMakeLists.txt
@@ -3,15 +3,16 @@ SET(sources robotis_bin_parser.cpp)
 # application header files
 SET(headers robotis_bin_parser.h)
 # locate the necessary dependencies
-FIND_PACKAGE(robotis_mtn REQUIRED)
 
 # add the necessary include directories
 INCLUDE_DIRECTORIES(.)
-INCLUDE_DIRECTORIES(${robotis_mtn_INCLUDE_DIR})
+include_directories(../robotis_mtn)
+
 # create the shared library
 ADD_LIBRARY(robotis_bin_parser SHARED ${sources})
 
-TARGET_LINK_LIBRARIES(robotis_bin_parser ${robotis_mtn_LIBRARY})
+target_link_libraries(robotis_bin_parser robotis_mtn)
+
 # link necessary libraries
 INSTALL(TARGETS robotis_bin_parser
         RUNTIME DESTINATION bin
diff --git a/src/robotis_mtn_file/CMakeLists.txt b/src/robotis_mtn_file/CMakeLists.txt
index 2be43f12d2f251fd780ec02326289ae5cf8fef73..6004dc34912f75f4d6d91a88296a697318989d4d 100644
--- a/src/robotis_mtn_file/CMakeLists.txt
+++ b/src/robotis_mtn_file/CMakeLists.txt
@@ -1,7 +1,6 @@
 # Create target for the parser
 FIND_PACKAGE(BISON REQUIRED)
 FIND_PACKAGE(FLEX REQUIRED)
-FIND_PACKAGE(robotis_mtn REQUIRED)
 
 SET(BisonOutput mtn_parser.cpp)
 IF(BISON_FOUND)
@@ -30,12 +29,12 @@ SET(sources mtn_file_parser.cpp)
 SET(headers mtn_file_parser.hpp mtn_file_scanner.hpp)
 
 include_directories(.)
-include_directories(${robotis_mtn_INCLUDE_DIR})
+include_directories(../robotis_mtn)
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 add_library(robotis_mtn_parser SHARED ${BisonOutput} ${FlexOutput} ${sources})
 
-target_link_libraries(robotis_mtn_parser ${robotis_mtn_LIBRARY})
+target_link_libraries(robotis_mtn_parser robotis_mtn)
 
 INSTALL(TARGETS robotis_mtn_parser
         RUNTIME DESTINATION bin