diff --git a/trunk/src/fw_downloader.cpp b/trunk/src/fw_downloader.cpp
index 85ed7fee8e6d64ae4631867ec4b83cf996b51cad..06e92904aa89f4a685d7135f707c774542101fee 100755
--- a/trunk/src/fw_downloader.cpp
+++ b/trunk/src/fw_downloader.cpp
@@ -46,9 +46,9 @@ void show_help(char *name) {
 
 int main(int argc,char *argv[])
 {
-  unsigned int baudrate=57600,left,addr,start_addr=0x00000000,len,base;
+  unsigned int baudrate=57600,left,addr,start_addr=0x00000000,len,base,i;
   size_t data_len;
-  unsigned short int erase_pages=0xFFFF,device_id;
+  unsigned short int erase_pages=0x0000,device_id;
   unsigned char bootloader_ver,buffer[256];
   flash_op operation=flash_none;
   const stm32_bl *bootloader_info;
@@ -163,7 +163,15 @@ int main(int argc,char *argv[])
         case flash_none:
           break;
         case flash_erase:
-          stm32_erase_memory(erase_pages);
+          if(device_id==0x417 || device_id==0x416 || device_id==0x429 || device_id==0x427 || device_id==0x436 || device_id==0x437)
+          {
+            // mass erase not supported
+            if(erase_pages==0)
+              erase_pages=0X01FF;
+            stm32_erase_memory(erase_pages);
+          }
+          else
+            stm32_erase_memory(erase_pages);
           break;
         case flash_read:
           break;
@@ -185,11 +193,26 @@ int main(int argc,char *argv[])
           }
           else
             std::cout << "Input file in Intel HEX format" << std::endl;
-  
           std::cout << "erasing memory ...";
-	  if(!stm32_erase_memory(0))
-            std::cout << " failed" << std::endl;
+          if(device_id==0x417 || device_id==0x416 || device_id==0x429 || device_id==0x427 || device_id==0x436 || device_id==0x437)
+          {
+            // mass erase not supported
+            if(erase_pages==0)
+              erase_pages=0X01FF;
+            if(!stm32_erase_memory(erase_pages))
+            {
+              std::cout << " failed" << std::endl;
+              return 1;
+            }
+          }
           else
+          {
+            if(!stm32_erase_memory(erase_pages))
+            {
+              std::cout << " failed" << std::endl;
+              return 1;
+            }
+          }
           std::cout << " done" << std::endl;
 
 	  // write the data into the memory
diff --git a/trunk/src/stm32.cpp b/trunk/src/stm32.cpp
index 3489f31a66a76a4dbdd6968fc5b4dab091aaaec2..12e8294bcffaedd5870fb0068dc9a6619e2e5205 100755
--- a/trunk/src/stm32.cpp
+++ b/trunk/src/stm32.cpp
@@ -699,7 +699,7 @@ bool stm32_read_memory(unsigned int address,unsigned int length,unsigned char *d
   return true;
 }
 
-bool stm32_start_exec(unsigned char address)
+bool stm32_start_exec(unsigned int address)
 {
   unsigned char cmd[5],answer;
   unsigned char cs=0;
@@ -871,9 +871,10 @@ bool stm32_write_memory(unsigned int address, unsigned int length, unsigned char
   return true;
 }
 
-bool stm32_erase_memory(unsigned short int num_pages, unsigned short int *pages)
+bool stm32_erase_memory(unsigned short int num_pages)
 {
   unsigned char cmd[3],answer=STM32_NACK,*data;
+  unsigned short int *pages;
   int written,num,i;
 
   // send the erase command
@@ -940,21 +941,22 @@ bool stm32_erase_memory(unsigned short int num_pages, unsigned short int *pages)
   {
     if(commands.er==0x44)
     {
-      unsigned short int cs=0x0000;
+      unsigned char cs=0x00;
 
-      data=new unsigned char[(num_pages+1)*2];
-      data[0]=num_pages>>8;
+      data=new unsigned char[(num_pages+1)*2+1];
+      data[0]=(num_pages-1)>>8;
       cs^=data[0];
-      data[1]=num_pages&0x00FF;
+      data[1]=(num_pages-1)&0x00FF;
       cs^=data[1];
       for(i=0;i<num_pages;i++)
       {
-        data[i*2+2]=pages[i]>>8;
+        data[i*2+2]=(i>>8)&0x00FF;
         cs^=data[i*2+2];
-        data[i*2+3]=pages[i]&0x00FF;
+        data[i*2+3]=i&0x00FF;
         cs^=data[i*2+3];
       }
-      if((written=serial.write(data,(num_pages+1)*2))!=(num_pages+1)*2)
+      data[i*2+2]=cs;
+      if((written=serial.write(data,((num_pages+1)*2)+1))!=(num_pages+1)*2+1)
       {
         std::cout << "Error while sending the command " << commands.er << std::endl;
         delete[] data;
@@ -965,15 +967,16 @@ bool stm32_erase_memory(unsigned short int num_pages, unsigned short int *pages)
     {
       unsigned char cs=0x00;
 
-      data=new unsigned char[num_pages+1];
-      data[0]=num_pages&0x00FF;
+      data=new unsigned char[num_pages+2];
+      data[0]=(num_pages-1)&0x00FF;
       cs^=data[0];
       for(i=0;i<num_pages;i++)
       {
-        data[i+1]=pages[i]&0x00FF;
+        data[i+1]=i&0x00FF;
         cs^=data[i+1];
       }
-      if((written=serial.write(data,num_pages+1))!=num_pages+1)
+      data[i+1]=cs;
+      if((written=serial.write(data,num_pages+2))!=num_pages+2)
       {
         std::cout << "Error while sending the command " << commands.er << std::endl;
         delete[] data;
@@ -1007,8 +1010,53 @@ bool stm32_write_protect(int num_sectors, unsigned short int *sectors)
   return true;
 }
 
-bool stm32_write_unprotect(int num_sectors, unsigned short int *sectors)
+bool stm32_write_unprotect(void)
 {
+  unsigned char cmd[2],answer=STM32_NACK;
+  int written,num;
+
+  // send the erase command
+  cmd[0]=commands.uw;
+  cmd[1]=commands.uw ^ 0xFF;
+  if((written=serial.write(cmd,2))!=2)
+  {
+    std::cout << "Error while sending the command " << commands.er << std::endl;
+    return false;
+  }
+  // wait for the response
+  try{
+    event_server->wait_all(events,2000);
+    num=serial.get_num_data();
+    serial.read(&answer,1);
+    num--;
+    if(answer==STM32_NACK)
+    {
+      std::cout << "Device answered NACK" << std::endl;
+      return false;
+    }
+  }catch(CException &e){
+    std::cout << "Device did not respond in time" << std::endl;
+    return false;
+  }
+  try{
+    if(num==0)
+    {
+      event_server->wait_all(events,2000);
+      num=serial.get_num_data();
+    }
+    serial.read(&answer,1);
+    num--;
+    if(answer==STM32_NACK)
+    {
+      std::cout << "Device answered NACK" << std::endl;
+      return false;
+    }
+  }catch(CException &e){
+    std::cout << "Device did not respond in time" << std::endl;
+    return false;
+  }
+
+
   return true;
 }
 
diff --git a/trunk/src/stm32.h b/trunk/src/stm32.h
index 36b03f5d4757815e4e399636f952d4501ab46ded..3fe6ce6c3bdf95127f701243d245eb4bb585c445 100755
--- a/trunk/src/stm32.h
+++ b/trunk/src/stm32.h
@@ -50,11 +50,11 @@ bool stm32_get_chip_id(unsigned short int *pid);
 bool stm32_get_chip_info(const stm32_bl **info);
 bool stm32_get_device_info(std::string &device_name,const stm32_dev **info);
 bool stm32_read_memory(unsigned int address,unsigned int length,unsigned char *data);
-bool stm32_start_exec(unsigned char address);
+bool stm32_start_exec(unsigned int address);
 bool stm32_write_memory(unsigned int address, unsigned int length, unsigned char *data);
-bool stm32_erase_memory(unsigned short num_pages, unsigned short int *pages=NULL);
-bool stm32_write_protect(int num_sectors, unsigned short int *sectors);
-bool stm32_write_unprotect(int num_sectors, unsigned short int *sectors);
+bool stm32_erase_memory(unsigned short num_pages);
+bool stm32_write_protect(void);
+bool stm32_write_unprotect(void);
 bool stm32_read_protect(int num_sectors, unsigned short int *sectors);
 bool stm32_read_unprotect(int num_sectors, unsigned short int *sectors);