diff --git a/src/fw_downloader/fw_downloader.cpp b/src/fw_downloader/fw_downloader.cpp
index 82ed684111d60fb33a57fc1d6cb77e4828775cec..0387134c8677131678bbef93dfddd54d792f0270 100755
--- a/src/fw_downloader/fw_downloader.cpp
+++ b/src/fw_downloader/fw_downloader.cpp
@@ -25,13 +25,14 @@ void show_help(char *name)
   std::cout << "Usage: " << name << "-d <serial device> -f <firmware file> -p <protocol> [-h]" << std::endl;
   std::cout << "       -d serial_device  Linux serial device used to communicate" << std::endl;
   std::cout << "       -f firmware_file  desired firmware file in Intel Hex format" << std::endl;
-  std::cout << "       -p protocol       Communication protocol to be used (original or new)" << std::endl;
+  std::cout << "       -p protocol       Communication protocol to be used" << std::endl;
   std::cout << "                         devices supported by the original protocol:" << std::endl;
-  std::cout << "                         - ax servo family" << std::endl;
-  std::cout << "                         - rx servo family" << std::endl;
+  std::cout << "                         - ax - for the AX servo family" << std::endl;
+  std::cout << "                         - rx - for the RX servo family" << std::endl;
   std::cout << "                         devices supported by the new protocol:" << std::endl;
-  std::cout << "                         - cm510" << std::endl;
-  std::cout << "                         - mx servo family" << std::endl;
+  std::cout << "                         - cm510 - for the CM510 controller" << std::endl;
+  std::cout << "                         - mx - for the MX servo family" << std::endl;
+  std::cout << "                         - cm730 - for the cm730 controller" << std::endl;
   std::cout << "       -c                clear eeprom memory" << std::endl;
   std::cout << "       -r eeprom_file    read eeprom memory to file" << std::endl;
   std::cout << "       -h                shows this help" << std::endl;
@@ -48,13 +49,17 @@ int main(int argc,char *argv[])
   bool end=false;
   int option;
   std::string opt_device,opt_fw_file,eeprom_file;
+  std::string device; 
   protocol_t protocol;
   // binary file variables
   unsigned char binary_file[MEMORY_MAXSIZE];
   long int downloaded_size=0;
   long int start_address=0;
   long int binary_size=0;
+  long int written_size=0;
+  long int write_size=0;
   int block_size=0,count=0;
+  std::stringstream base_address;
   // bootloader variables
   unsigned char bootloader_data[MEMORY_MAXSIZE];
   bool bootloader_connected=false;
@@ -93,10 +98,16 @@ int main(int argc,char *argv[])
         break;
       case 'p':// select protocol
         std::cout << "Selected protocol: " << optarg << std::endl;
-        if(std::string(optarg)=="original")
+        if(std::string(optarg)=="ax" || std::string(optarg)=="rx")
+        {
           protocol=original_protocol;
-        else if(std::string(optarg)=="new")
-          protocol=new_protocol;
+          device=optarg;
+        }
+        else if(std::string(optarg)=="cm510" || std::string(optarg)=="mx" || std::string(optarg)=="cm730")
+        {
+          protocol=new_protocol; 
+          device=optarg;
+        }
         else
         {
           std::cout << "Unsupported protocol" << std::endl;
@@ -209,59 +220,74 @@ int main(int argc,char *argv[])
             }
           }
           // start the download
-          serial_port.write((unsigned char *)&bootloader_load,1);
-          if(protocol==new_protocol)
-            serial_port.write((unsigned char *)&bootloader_ack,1);
-          end=false;
-          while(!end)
-          {
-            try{
-              if((num_data=serial_port.get_num_data()==0))
-                event_server->wait_all(events,300);
-              num_data=serial_port.get_num_data();
-              serial_port.read(bootloader_data,num_data);
-              bootloader_data[num_data]='\0';
-              printf("%s",bootloader_data);
+          do{
+            base_address.str("");
+            if(device=="cm730" || device=="mx")
+              base_address << "l " << std::hex << 0x08003000 + written_size << std::endl;
+            else
+              base_address << "l" << std::endl;
+            serial_port.write((unsigned char *)base_address.str().c_str(),base_address.str().size()-1);
+            if(protocol==new_protocol)
+              serial_port.write((unsigned char *)&bootloader_ack,1);
+            end=false;
+            while(!end)
+            {
+              try{
+                if((num_data=serial_port.get_num_data()==0))
+                  event_server->wait_all(events,300);
+                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){
+                end=true;
+              }
+            }
+            if((binary_size-written_size)>1024*20)
+              write_size=1024*20;
+            else
+              write_size=binary_size-written_size;
+            // compute the binary file checksum
+            checksum=0;
+            for(i=0;i<write_size;i++)
+              checksum+=binary_file[start_address+i];
+            // send the binary file in 64 byte segments
+            while(downloaded_size < write_size)
+            { 
+              usleep(1000);
+              block_size=write_size-downloaded_size;
+              if(block_size>64)
+                block_size=64;
+              serial_port.write(&binary_file[start_address+downloaded_size],block_size);
+              downloaded_size+=block_size;
+              printf("\rDownloading Firmware (%ld/%ld byte)", downloaded_size, write_size);
               fflush(stdout);
-            }catch(CEventTimeoutException &e){
-              end=true;
             }
-          }
-          // compute the binary file checksum
-          for(i=0;i<binary_size;i++)
-            checksum+=binary_file[start_address+i];
-          // send the binary file in 64 byte segments
-          while(downloaded_size < binary_size)
-          { 
             usleep(1000);
-            block_size=binary_size-downloaded_size;
-            if(block_size>64)
-              block_size=64;
-            serial_port.write(&binary_file[start_address+downloaded_size],block_size);
-            downloaded_size+=block_size;
-            printf("\rDownloading Firmware (%ld/%ld byte)", downloaded_size, binary_size);
-            fflush(stdout);
-          }
-          usleep(1000);
-          // send the checksum
-          serial_port.write(&checksum,1);
-          std::cout << std::endl << "Download complete" << std::endl;
-          end=false;
-          while(!end)
-          {
-            try{
-              if((num_data=serial_port.get_num_data()==0))
-                event_server->wait_all(events,300);
-              // 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
-              end=true;
+            // send the checksum
+            serial_port.write(&checksum,1);
+            end=false;
+            while(!end)
+            {
+              try{
+                if((num_data=serial_port.get_num_data()==0))
+                  event_server->wait_all(events,300);
+                // 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
+                end=true;
+              }
             }
-          }
+            written_size+=write_size;
+            start_address+=write_size;
+            downloaded_size=0;
+          }while(written_size<binary_size);
+          std::cout << std::endl << "Download complete" << std::endl;
         }
       }
       else if(read_eeprom)
@@ -359,22 +385,25 @@ int main(int argc,char *argv[])
         }
       }
       // go to application mode
-      serial_port.write((unsigned char *)&bootloader_app,1);
-      if(protocol==new_protocol)
-        serial_port.write((unsigned char *)&bootloader_ack,1);
-      end=false;
-      while(!end)
+      if(device=="ax")
       {
-        try{
-          event_server->wait_all(events,300);
-          // 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
-          end=true;
+        serial_port.write((unsigned char *)&bootloader_app,1);
+        if(protocol==new_protocol)
+          serial_port.write((unsigned char *)&bootloader_ack,1);
+        end=false;
+        while(!end)
+        {
+          try{
+            event_server->wait_all(events,300);
+            // 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
+            end=true;
+          }
         }
       }
       // start the loaded program