diff --git a/trunk/src/fw_downloader.cpp b/trunk/src/fw_downloader.cpp
index 0d4e7e3c72f4a84c5405b1fdbc0ae10721df14db..f2d89f4b3815a0a1b620f907ce0ae805f63d0830 100755
--- a/trunk/src/fw_downloader.cpp
+++ b/trunk/src/fw_downloader.cpp
@@ -45,16 +45,16 @@ void show_help(char *name) {
 
 int main(int argc,char *argv[])
 {
-  unsigned int baudrate=57600,size,left,addr,start_addr=0x00000000,len;
+  unsigned int baudrate=57600,left,addr,start_addr=0x00000000,len,base,data_len;
   unsigned short int erase_pages=0xFFFF,device_id;
   unsigned char bootloader_ver,buffer[256];
   flash_op operation=flash_none;
   const stm32_dev *device_info;
+  bool verify=false,done=false;
   bool start_exec=false;
   std::string device="";
   std::string filename;
   stm32_cmd commands;
-  bool verify=false;
   off_t offset = 0;
   parser_err error;
   hex_t *hex_file;
@@ -160,14 +160,6 @@ int main(int argc,char *argv[])
           }
           else
             std::cout << "Input file in Intel HEX format" << std::endl;
-	  // write the data into the memory
-          size=hex_size(hex_file);
-	  if (size > device_info->fl_end - device_info->fl_start) 
-          {
-	    std::cout << "File provided larger then available flash space" << std::endl;
-            hex_close(hex_file);
-	    return 1;
-	  }
   
           std::cout << "erasing memory ...";
 	  if(!stm32_erase_memory(0))
@@ -175,33 +167,50 @@ int main(int argc,char *argv[])
           else
           std::cout << " done" << std::endl;
 
-	  addr = device_info->fl_start;
-          std::cout << '\xd';
-	  while(addr < device_info->fl_end && offset < size) 
+	  // write the data into the memory
+          done=hex_get_first_segment(hex_file,&base,&data_len);
+          while(!done)
           {
-	    left = device_info->fl_end - addr;
-	    len = sizeof(buffer) > left ? left : sizeof(buffer);
-	    len = len > size - offset ? size - offset : len;
-
-	    if (hex_read(hex_file, buffer, &len) != PARSER_ERR_OK)
+            if(base<device_info->fl_start)
             {
-              std::cout << "Error reading the hex file" << std::endl;
+              std::cout << "Start address not in FLASH" << std::endl;
               hex_close(hex_file);
-              return 1;
+	      return 1;
             }
-	    if (!stm32_write_memory(addr,len,buffer)) 
+            if((base+data_len)>device_info->fl_end)
             {
-	      std::cout << "Failed to write memory at address 0x" << std::hex << addr << std::endl;
+              std::cout << "End address not in FLASH" << std::endl;
               hex_close(hex_file);
-              return 1;
-	    }
-
-	    addr += len;
-	    offset += len;
+	      return 1;
+            }
+            addr = base;
             std::cout << '\xd';
-            std::cout.width(3);
-            std::cout << "write done: " << (int)((100.0f / size) * offset) << "%";
-            std::cout.flush();
+            while(offset < data_len) 
+            {
+              left = data_len-offset;
+	      len = sizeof(buffer) > left ? left : sizeof(buffer);
+              if (hex_read(hex_file, buffer, &len) != PARSER_ERR_OK)
+              {
+                std::cout << "Error reading the hex file" << std::endl;
+                hex_close(hex_file);
+                return 1;
+              }
+	      if (!stm32_write_memory(addr,len,buffer)) 
+              {
+	        std::cout << "Failed to write memory at address 0x" << std::hex << addr << std::endl;
+                hex_close(hex_file);
+                return 1;
+	      }
+              addr += len;
+	      offset += len;
+              std::cout << '\xd';
+              std::cout.width(3);
+              std::cout << "write done: " << (int)((100.0f / data_len) * offset) << "%";
+              std::cout.flush();
+            }
+            std::cout << std::endl;
+            offset=0;
+            done=hex_get_next_segment(hex_file,&base,&data_len);
 	  }
           hex_close(hex_file);
           std::cout << std::endl;
diff --git a/trunk/src/hex.cpp b/trunk/src/hex.cpp
index aba644431adb90a6f8298ce8f78ccc2b30eb2cb1..f7d4841e0761e60bf31a8f9664be75a727d0e679 100755
--- a/trunk/src/hex.cpp
+++ b/trunk/src/hex.cpp
@@ -4,10 +4,11 @@ hex_t* hex_init()
 {
   hex_t *hex_file=new hex_t;
 
-  hex_file->data_len=0;
-  hex_file->offset=0;
-  hex_file->data=NULL;
-  hex_file->base=0;
+  hex_file->data_len.resize(1);
+  hex_file->offset.resize(1);
+  hex_file->data.resize(1);
+  hex_file->base.resize(1);
+  hex_file->current=0;
 
   return hex_file;
 }
@@ -48,20 +49,31 @@ parser_err hex_open(hex_t *file,const char *filename)
       /* data record */
       case 0:
 	c = address - last_address;
-        tmp_data=new unsigned char[file->data_len + c + reclen];
-        memcpy(tmp_data,file->data,file->data_len);
-        delete[] file->data;
-        file->data=tmp_data;
-
-	/* if there is a gap, set it to 0xff and increment the length */
-	if (c > 0) {
-	  memset(&file->data[file->data_len], 0xff, c);
-	  file->data_len += c;
-	}
+        if(c>0)
+        {
+          // create a new data segment
+          file->data_len.resize(file->data_len.size()+1);
+          file->offset.resize(file->offset.size()+1);
+          file->data.resize(file->data.size()+1);
+          file->base.resize(file->base.size()+1);
+          file->current++;
+          file->data_len[file->current]=0;
+          file->offset[file->current]=0;
+          file->data[file->current]=NULL;
+          file->base[file->current]=(file->base[file->current-1]&0xFFFF0000)+address;
+          file->data[file->current]=new unsigned char[reclen];
+        }
+        else
+        {
+          tmp_data=new unsigned char[file->data_len[file->current] + reclen];
+          memcpy(tmp_data,file->data[file->current],file->data_len[file->current]);
+          delete[] file->data[file->current];
+          file->data[file->current]=tmp_data;
+        }
 
 	last_address = address + reclen;
-	record = &file->data[file->data_len];
-	file->data_len += reclen;
+	record = &((file->data[file->current])[file->data_len[file->current]]);
+	file->data_len[file->current] += reclen;
 	break;
 
 	/* extended segment address record */
@@ -112,52 +124,60 @@ parser_err hex_open(hex_t *file,const char *filename)
       /* EOF */
       case 1:
 	close(fd);
+        file->current=0;
 	return PARSER_ERR_OK;
 
 	/* address record */
       case 2: base = base << 4;
-      case 4: base = ((base & 0xFF000000) >> 24) | ((base & 0x00FF0000) >>  8) | ((base & 0x0000FF00) <<  8) | ((base & 0x000000FF) << 24);
+      case 4: base = ((base & 0xFF000000) >> 24) | ((base & 0x00FF0000) >>  8) | ((base & 0x0000FF00) <<  16) | ((base & 0x000000FF) << 16);
 	      /* Reset last_address since our base changed */
 	      last_address = 0;
 
-	      if (file->base == 0) 
+	      if (file->base[file->current] == 0) 
               {
-	        file->base = base;
+	        file->base[file->current] = base;
 		break;
 	      }
 
+              if((file->base[file->current]+file->data_len[file->current])==base)
+                break;
+
               /* we cant cope with files out of order */
-	      if (base < file->base) 
+	      if (base < file->base[file->current]) 
               {
 	        close(fd);
 	        return PARSER_ERR_INVALID_FILE;
 	      }
 
-	      /* if there is a gap, enlarge and fill with zeros */
-	      unsigned int len = base - file->base;
-	      if (len > file->data_len) 
-              {
-                tmp_data=new unsigned char[len];
-                memcpy(tmp_data,file->data,file->data_len);
-	        memset(&tmp_data[file->data_len], 0, len - file->data_len);
-                file->data_len = len;
-                delete[] file->data;
-                file->data=tmp_data;
-	      }
+              // create a new data segment
+              file->data_len.resize(file->data_len.size()+1);
+              file->offset.resize(file->offset.size()+1);
+              file->data.resize(file->data.size()+1);
+              file->base.resize(file->base.size()+1);
+              file->current++;
+              file->data_len[file->current]=0;
+              file->offset[file->current]=0;
+              file->data[file->current]=NULL;
+              file->base[file->current]=base;
+
 	      break;
     }
   }
 
   close(fd);
+  file->current=0;
   return PARSER_ERR_OK;
 }
 
 parser_err hex_close(hex_t *file) 
 {
+  unsigned int i=0;
+
   if(file)
   {
-    if(file->data!=NULL) 
-      delete[] file->data;
+    for(i=0;i<file->data.size();i++)
+      if(file->data[i]!=NULL) 
+        delete[] file->data[i];
   }
   delete file;
 
@@ -166,16 +186,39 @@ parser_err hex_close(hex_t *file)
 
 unsigned int hex_size(hex_t *file) 
 {
-  return file->data_len;
+  return file->data_len[file->current];
+}
+
+bool hex_get_first_segment(hex_t *file,uint32_t *base,size_t *data_len)
+{
+  file->current=0;
+
+  (*base)=file->base[file->current];
+  (*data_len)=file->data_len[file->current];
+
+  return false;
+}
+
+bool hex_get_next_segment(hex_t *file,uint32_t *base,size_t *data_len)
+{
+  if(file->current<(file->data.size()-1))
+    file->current++;
+  else
+    return true;
+  
+  (*base)=file->base[file->current];
+  (*data_len)=file->data_len[file->current];
+
+  return false;
 }
 
 parser_err hex_read(hex_t *file,unsigned char *data, unsigned int *len) 
 {
-  unsigned int left = file->data_len - file->offset;
+  unsigned int left = file->data_len[file->current] - file->offset[file->current];
   unsigned int get  = left > *len ? *len : left;
 
-  memcpy(data, &file->data[file->offset], get);
-  file->offset += get;
+  memcpy(data, &(file->data[file->current])[file->offset[file->current]], get);
+  file->offset[file->current] += get;
 
   *len = get;
   return PARSER_ERR_OK;
diff --git a/trunk/src/hex.h b/trunk/src/hex.h
index aa98b8799ed8e3d6e9ea1998c1b0e10903b94bbb..d32ed54231244a66f1f1b0b0e8c019905efb2679 100755
--- a/trunk/src/hex.h
+++ b/trunk/src/hex.h
@@ -8,13 +8,16 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
+#include <vector>
 
 #include "parsers.h"
 
 typedef struct {
-  size_t data_len, offset;
-  uint8_t *data;
-  uint8_t base;
+  std::vector<size_t> data_len;
+  std::vector<size_t> offset;
+  std::vector<uint8_t *> data;
+  std::vector<uint32_t> base;
+  int current;
 } hex_t;
 
 
@@ -22,6 +25,8 @@ hex_t* hex_init();
 parser_err hex_open(hex_t *file,const char *filename);
 parser_err hex_close(hex_t *file);
 unsigned int hex_size(hex_t *file); 
+bool hex_get_first_segment(hex_t *file,uint32_t *base,size_t *data_len);
+bool hex_get_next_segment(hex_t *file,uint32_t *base,size_t *data_len);
 parser_err hex_read(hex_t *file,unsigned char *data, unsigned int *len);
 parser_err hex_write(hex_t *file, unsigned char *data, unsigned int len);