diff --git a/comm/Makefile b/comm/Makefile
index 8c84d8c5cef07a85160a53ebd926f58c3aa5fa1e..fe16a009f9651ec009b53fdff944a01cb76708b8 100755
--- a/comm/Makefile
+++ b/comm/Makefile
@@ -3,6 +3,7 @@
 
 COMPILE_OPTS = -mlittle-endian -mthumb -mthumb-interwork
 COMPILE_OPTS += -Wall -O2 -fno-common
+#COMPILE_OPTS += -Wall -g -fno-common
 COMPILE_OPTS += -ffreestanding -nostdlib
 
 COMPILE_OPTS_M4_FPU = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mcpu=cortex-m4
diff --git a/memory/Makefile b/memory/Makefile
index 5acf059ad88e32dd3f13880565cd1dfa31fed021..8c10981525a8f64771fb427596b3e8be3729e841 100755
--- a/memory/Makefile
+++ b/memory/Makefile
@@ -2,8 +2,8 @@
 # modified by zerom for WinARM 8/2010
 
 COMPILE_OPTS = -mlittle-endian -mthumb -mthumb-interwork
-COMPILE_OPTS += -Wall -O2 -fno-common
-#COMPILE_OPTS += -Wall -g -fno-common
+#COMPILE_OPTS += -Wall -O2 -fno-common
+COMPILE_OPTS += -Wall -g -fno-common
 COMPILE_OPTS += -ffreestanding -nostdlib
 
 COMPILE_OPTS_M4_FPU = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mcpu=cortex-m4
diff --git a/memory/include/mem_module.h b/memory/include/mem_module.h
index f11445d7b8c5691470d420bccb24ba09ddb8180a..50c085ea6a9a2ebf4c3a074079301f49705e4784 100644
--- a/memory/include/mem_module.h
+++ b/memory/include/mem_module.h
@@ -20,7 +20,7 @@ typedef struct
 }TMemModule;
 
 void mem_module_init(TMemModule *module);
-void mem_module_add_ram_segment(TMemModule *module,unsigned short int start_address, unsigned short int length);
-void mem_module_add_eeprom_segment(TMemModule *module,unsigned short int start_address, unsigned short int length);
+unsigned char mem_module_add_ram_segment(TMemModule *module,unsigned short int start_address, unsigned short int length);
+unsigned char mem_module_add_eeprom_segment(TMemModule *module,unsigned short int start_address, unsigned short int length);
 
 #endif
diff --git a/memory/include/memory.h b/memory/include/memory.h
index 6bfa88711d742bc6be3cd4b0da8fffec17c819ec..21214c5b272a3b2f3beb7dcca18f8939bb361db6 100644
--- a/memory/include/memory.h
+++ b/memory/include/memory.h
@@ -4,20 +4,20 @@
 #include "mem_module.h"
 
 #define MAX_NUM_MEM_MODULES       16
-#define EEPROM_SIZE               256
-#define RAM_SIZE                  4096
+#define EEPROM_SIZE               32
+#define RAM_SIZE                  256
 
 typedef struct
 {
   unsigned char num_mem_modules;
   TMemModule *mem_modules[MAX_NUM_MEM_MODULES];
-  unsigned char (*eeprom_write_data)(unsigned short int address,unsigned short int data);
-  unsigned char (*eeprom_read_data)(unsigned short int address,unsigned short int *data);
+  unsigned short int (*eeprom_write_data)(unsigned short int address,unsigned short int data);
+  unsigned short int (*eeprom_read_data)(unsigned short int address,unsigned short int *data);
 }TMemory;
 
 void mem_init(TMemory *memory);
 void mem_initialize_data(TMemory *memory);
-void mem_add_module(TMemory *memory, TMemModule *module);
+unsigned char mem_add_module(TMemory *memory, TMemModule *module);
 void mem_do_write(TMemory *memory,unsigned short int start_address,unsigned short int length,unsigned char *data);
 void mem_do_read(TMemory *memory,unsigned short int start_address,unsigned short int length,unsigned char *data);
 
diff --git a/memory/src/mem_module.c b/memory/src/mem_module.c
index 61d875b3d31b1fce7d1ea2773f4ca8c66ac7f471..cf158d18dbc8dee96ea47d60c519f3e5c8f23d10 100644
--- a/memory/src/mem_module.c
+++ b/memory/src/mem_module.c
@@ -1,5 +1,7 @@
 #include "mem_module.h"
 
+extern unsigned char mem_in_window(unsigned short int mem_start_address,unsigned short int mem_length,unsigned short int start_address,unsigned short int length);
+
 void mem_module_init(TMemModule *module)
 {
   unsigned char i;
@@ -17,23 +19,59 @@ void mem_module_init(TMemModule *module)
   module->read_cmd=0x00000000;
 }
 
-void mem_module_add_ram_segment(TMemModule *module,unsigned short int start_address, unsigned short int length)
+unsigned char mem_module_add_ram_segment(TMemModule *module,unsigned short int start_address, unsigned short int length)
 {
+  TMemSegment *current_segment;
+  unsigned char current_seg;
+ 
   if(module->num_ram_segments<MAX_NUM_SEGMENTS-1)
   {
+    for(current_seg=0;current_seg<module->num_ram_segments;current_seg++)
+    {
+      current_segment=&module->ram_segments[current_seg];
+      if(mem_in_window(current_segment->start_address,current_segment->length,start_address,length))
+        return 0x00;
+    }
+    for(current_seg=0;current_seg<module->num_eeprom_segments;current_seg++)
+    {
+      current_segment=&module->eeprom_segments[current_seg];
+      if(mem_in_window(current_segment->start_address,current_segment->length,start_address,length))
+        return 0x00;
+    }
     module->ram_segments[module->num_ram_segments].start_address=start_address;
     module->ram_segments[module->num_ram_segments].length=length;
     module->num_ram_segments++;
+    return 0x01;
   }
+  else
+    return 0x00;
 }
 
-void mem_module_add_eeprom_segment(TMemModule *module,unsigned short int start_address, unsigned short int length)
+unsigned char mem_module_add_eeprom_segment(TMemModule *module,unsigned short int start_address, unsigned short int length)
 {
+  TMemSegment *current_segment;
+  unsigned char current_seg;
+ 
   if(module->num_eeprom_segments<MAX_NUM_SEGMENTS-1)
   {
+    for(current_seg=0;current_seg<module->num_ram_segments;current_seg++)
+    {
+      current_segment=&module->ram_segments[current_seg];
+      if(mem_in_window(current_segment->start_address,current_segment->length,start_address,length))
+        return 0x00;
+    }
+    for(current_seg=0;current_seg<module->num_eeprom_segments;current_seg++)
+    {
+      current_segment=&module->eeprom_segments[current_seg];
+      if(mem_in_window(current_segment->start_address,current_segment->length,start_address,length))
+        return 0x00;
+    }
     module->eeprom_segments[module->num_eeprom_segments].start_address=start_address;
     module->eeprom_segments[module->num_eeprom_segments].length=length;
     module->num_eeprom_segments++;
+    return 0x01;
   }
+  else
+    return 0x00;
 }
 
diff --git a/memory/src/memory.c b/memory/src/memory.c
index 359c276c05ae48367d909c25299a735b7e933b7b..c2b2a70def0e0538ab847145e2062ed0f1e33f91 100644
--- a/memory/src/memory.c
+++ b/memory/src/memory.c
@@ -1,16 +1,20 @@
 #include "memory.h"
 #include "mem_module.h"
 
+/* private variables */
+unsigned char memory_total_eeprom;
+unsigned char memory_total_ram;
+
 /* private functions */
 unsigned char mem_in_window(unsigned short int mem_start_address,unsigned short int mem_length,unsigned short int start_address,unsigned short int length)
 {
-  unsigned short int end_mem=mem_start_address+mem_length;
-  unsigned short int end_address=start_address+length;
+  unsigned short int end_mem=mem_start_address+mem_length-1;
+  unsigned short int end_address=start_address+length-1;
 
-  if((mem_start_address>=start_address && mem_start_address<end_address) || 
-     (end_mem>=start_address && end_mem<end_address) ||
-     (start_address>=mem_start_address && start_address<end_mem) || 
-     (end_address>=mem_start_address && end_address<end_mem))
+  if((mem_start_address>=start_address && mem_start_address<=end_address) || 
+     (end_mem>=start_address && end_mem<=end_address) ||
+     (start_address>=mem_start_address && start_address<=end_mem) || 
+     (end_address>=mem_start_address && end_address<=end_mem))
     return 0x01;
   else
     return 0x00;
@@ -26,6 +30,10 @@ void mem_init(TMemory *memory)
     memory->mem_modules[i]=0x00000000;
   memory->eeprom_write_data=0x00000000;
   memory->eeprom_read_data=0x00000000;
+
+  /* initialize internal variables */
+  memory_total_eeprom=0;
+  memory_total_ram=0;
 }
 
 void mem_initialize_data(TMemory *memory)
@@ -34,63 +42,160 @@ void mem_initialize_data(TMemory *memory)
   unsigned short data;
   unsigned short int i,j;
   unsigned char eeprom_data[EEPROM_SIZE];
+  unsigned short int actual_address,actual_length;
 
   if(memory->eeprom_read_data!=0x00000000)
   {
     for(i=0;i<EEPROM_SIZE;i++)
     {
-      memory->eeprom_read_data(i,&data);
-      eeprom_data[i]=data&0x00FF;
+      if(memory->eeprom_read_data(i,&data))
+        eeprom_data[i]=0x00;
+      else
+        eeprom_data[i]=data&0x00FF;
     }
     for(i=0;i<memory->num_mem_modules;i++)
     {
       mem_module=memory->mem_modules[i];
       for(j=0;j<mem_module->num_eeprom_segments;j++)
       {
-        if(mem_in_window(mem_module->eeprom_segments[j].start_address,mem_module->eeprom_segments[i].length,0x0000,EEPROM_SIZE))
+        if(mem_in_window(mem_module->eeprom_segments[j].start_address,mem_module->eeprom_segments[j].length,0x0000,EEPROM_SIZE))
         {
           if(mem_module->write_cmd!=0x00000000)
-           mem_module->write_cmd(0x0000,EEPROM_SIZE,eeprom_data);
+          {
+            actual_address=mem_module->eeprom_segments[j].start_address;
+            actual_length=EEPROM_SIZE-mem_module->eeprom_segments[j].start_address;
+            if((actual_address+actual_length)>(mem_module->eeprom_segments[j].start_address+mem_module->eeprom_segments[j].length))
+              actual_length-=((actual_address+actual_length)-(mem_module->eeprom_segments[j].start_address+mem_module->eeprom_segments[j].length));
+            mem_module->write_cmd(actual_address,actual_length,&eeprom_data[actual_address]);
+          }
         }
       }
     }
   }
 }
 
-void mem_add_module(TMemory *memory, TMemModule *module)
+unsigned char mem_add_module(TMemory *memory, TMemModule *module)
 {
+  TMemModule *current_module;
+  TMemSegment *current_segment,*new_segment;
+  unsigned char current_mod,current_seg,new_seg;
+
   if(memory->num_mem_modules<MAX_NUM_MEM_MODULES-1)
   {
+    /* check segments do not intersect */
+    for(current_mod=0;current_mod<memory->num_mem_modules;current_mod++)
+    {
+      current_module=memory->mem_modules[current_mod];
+      for(current_seg=0;current_seg<current_module->num_ram_segments;current_seg++)
+      {
+        current_segment=&current_module->ram_segments[current_seg];
+        for(new_seg=0;new_seg<module->num_ram_segments;new_seg++)
+        {
+          new_segment=&module->ram_segments[new_seg];
+          if(mem_in_window(current_segment->start_address,current_segment->length,new_segment->start_address,new_segment->length))
+            return 0x00;
+        }
+        for(new_seg=0;new_seg<module->num_eeprom_segments;new_seg++)
+        {
+          new_segment=&module->eeprom_segments[new_seg];
+          if(mem_in_window(current_segment->start_address,current_segment->length,new_segment->start_address,new_segment->length))
+            return 0x00;
+        }
+      }
+      for(current_seg=0;current_seg<current_module->num_eeprom_segments;current_seg++)
+      {
+        current_segment=&current_module->eeprom_segments[current_seg];
+        for(new_seg=0;new_seg<module->num_ram_segments;new_seg++)
+        {
+          new_segment=&module->ram_segments[new_seg];
+          if(mem_in_window(current_segment->start_address,current_segment->length,new_segment->start_address,new_segment->length))
+            return 0x00;
+        }
+        for(new_seg=0;new_seg<module->num_eeprom_segments;new_seg++)
+        {
+          new_segment=&module->eeprom_segments[new_seg];
+          if(mem_in_window(current_segment->start_address,current_segment->length,new_segment->start_address,new_segment->length))
+            return 0x00;
+        }
+      }
+    }
+    // check available memory
+    for(new_seg=0;new_seg<module->num_ram_segments;new_seg++)
+    {
+      memory_total_ram+=module->ram_segments[new_seg].length;
+      if(memory_total_ram>RAM_SIZE)
+        return 0x00;
+    }
+    for(new_seg=0;new_seg<module->num_eeprom_segments;new_seg++)
+    {
+      memory_total_eeprom+=module->eeprom_segments[new_seg].length;
+      if(memory_total_eeprom>EEPROM_SIZE)
+        return 0x00;
+      memory_total_ram+=module->eeprom_segments[new_seg].length;
+      if(memory_total_ram>RAM_SIZE)
+        return 0x00;
+    }
+
     memory->mem_modules[memory->num_mem_modules]=module;
     memory->num_mem_modules++;
+    return 0x01;
   }
+  else
+    return 0x00;
 }
 
 void mem_do_write(TMemory *memory,unsigned short int start_address,unsigned short int length,unsigned char *data)
 {
   TMemModule *mem_module;
   unsigned char i,j,k;
+  unsigned short int actual_address,actual_length;
 
   for(i=0;i<memory->num_mem_modules;i++)
   {
     mem_module=memory->mem_modules[i];
     for(j=0;j<mem_module->num_ram_segments;j++)
     {
-      if(mem_in_window(mem_module->ram_segments[j].start_address,mem_module->ram_segments[i].length,start_address,length))
+      if(mem_in_window(mem_module->ram_segments[j].start_address,mem_module->ram_segments[j].length,start_address,length))
       {
         if(mem_module->write_cmd!=0x00000000)
-          mem_module->write_cmd(start_address,length,data);
+        {
+          if(start_address<mem_module->ram_segments[j].start_address)
+          {
+            actual_address=mem_module->ram_segments[j].start_address;
+            actual_length=length-(mem_module->ram_segments[j].start_address-start_address);
+          }
+          else
+          {
+            actual_address=start_address;
+            actual_length=length;
+          }
+          if((actual_address+actual_length)>(mem_module->ram_segments[j].start_address+mem_module->ram_segments[j].length))
+            actual_length-=((actual_address+actual_length)-(mem_module->ram_segments[j].start_address+mem_module->ram_segments[j].length));
+          mem_module->write_cmd(actual_address,actual_length,&data[actual_address-start_address]);
+        }
       }
     }
     for(j=0;j<mem_module->num_eeprom_segments;j++)
     {
-      if(mem_in_window(mem_module->eeprom_segments[j].start_address,mem_module->eeprom_segments[i].length,start_address,length))
+      if(mem_in_window(mem_module->eeprom_segments[j].start_address,mem_module->eeprom_segments[j].length,start_address,length))
       {
+        if(start_address<mem_module->eeprom_segments[j].start_address)
+        {
+          actual_address=mem_module->eeprom_segments[j].start_address;
+          actual_length=length-(mem_module->eeprom_segments[j].start_address-start_address);
+        }
+        else
+        {
+          actual_address=start_address;
+          actual_length=length;
+        }
+        if((actual_address+actual_length)>(mem_module->eeprom_segments[j].start_address+mem_module->eeprom_segments[j].length))
+          actual_length-=((actual_address+actual_length)-(mem_module->eeprom_segments[j].start_address+mem_module->eeprom_segments[j].length));
         if(mem_module->write_cmd!=0x00000000)
-          mem_module->write_cmd(start_address,length,data);
+          mem_module->write_cmd(actual_address,actual_length,&data[actual_address-start_address]);
         if(memory->eeprom_write_data!=0x00000000)
-          for(k=start_address;k<EEPROM_SIZE || k<start_address+length;k++)
-            memory->eeprom_write_data(k,data[start_address-mem_module->eeprom_segments[j].start_address]);
+          for(k=actual_address;k<(actual_address+actual_length);k++)
+            memory->eeprom_write_data(k,data[k-start_address]);
       }
     }
   }
@@ -100,24 +205,53 @@ void mem_do_read(TMemory *memory,unsigned short int start_address,unsigned short
 {
   TMemModule *mem_module;
   unsigned char i,j;
+  unsigned short int actual_address,actual_length;
 
   for(i=0;i<memory->num_mem_modules;i++)
   {
     mem_module=memory->mem_modules[i];
     for(j=0;j<mem_module->num_ram_segments;j++)
     {
-      if(mem_in_window(mem_module->ram_segments[j].start_address,mem_module->ram_segments[i].length,start_address,length))
+      if(mem_in_window(mem_module->ram_segments[j].start_address,mem_module->ram_segments[j].length,start_address,length))
       {
         if(mem_module->read_cmd!=0x00000000)
-          mem_module->read_cmd(start_address,length,data);
+        {
+          if(start_address<mem_module->ram_segments[j].start_address)
+          {
+            actual_address=mem_module->ram_segments[j].start_address;
+            actual_length=length-(mem_module->ram_segments[j].start_address-start_address);
+          }
+          else
+          {
+            actual_address=start_address;
+            actual_length=length;
+          }
+          if((actual_address+actual_length)>(mem_module->ram_segments[j].start_address+mem_module->ram_segments[j].length))
+            actual_length-=((actual_address+actual_length)-(mem_module->ram_segments[j].start_address+mem_module->ram_segments[j].length));
+          mem_module->read_cmd(actual_address,actual_length,&data[actual_address-start_address]);
+        }
       }
     }
     for(j=0;j<mem_module->num_eeprom_segments;j++)
     {
-      if(mem_in_window(mem_module->eeprom_segments[j].start_address,mem_module->eeprom_segments[i].length,start_address,length))
+      if(mem_in_window(mem_module->eeprom_segments[j].start_address,mem_module->eeprom_segments[j].length,start_address,length))
       {
         if(mem_module->read_cmd!=0x00000000)
-          mem_module->read_cmd(start_address,length,data);
+        {
+          if(start_address<mem_module->eeprom_segments[j].start_address)
+          {
+            actual_address=mem_module->eeprom_segments[j].start_address;
+            actual_length=length-(mem_module->eeprom_segments[j].start_address-start_address);
+          }
+          else
+          {
+            actual_address=start_address;
+            actual_length=length;
+          }
+          if((actual_address+actual_length)>(mem_module->eeprom_segments[j].start_address+mem_module->eeprom_segments[j].length))
+            actual_length-=((actual_address+actual_length)-(mem_module->eeprom_segments[j].start_address+mem_module->eeprom_segments[j].length));
+          mem_module->read_cmd(actual_address,actual_length,&data[actual_address-start_address]);
+        }
       }
     }
   }
diff --git a/memory/test/memory_test.c b/memory/test/memory_test.c
index 20d7efc7d142f65a02f2728bc5f8b6ba0721a26a..8e438607c3332c703fd115570adbf9e91696376f 100644
--- a/memory/test/memory_test.c
+++ b/memory/test/memory_test.c
@@ -1,5 +1,6 @@
 #include "mem_module.h"
 #include "memory.h"
+#include <stdio.h>
 
 void module1_init_mem(unsigned char init_eeprom)
 {
@@ -45,12 +46,26 @@ int main(void)
   module2.read_cmd=module2_read_cmd;
   mem_init(&memory);
   
-  mem_module_add_ram_segment(&module1,0x0000,0x0005);
-  mem_module_add_ram_segment(&module1,0x0055,0x000A);
-  mem_module_add_eeprom_segment(&module1,0x0100,0x0020);
-  mem_add_module(&memory,&module1);
-
-  mem_module_add_ram_segment(&module2,0x0200,0x0005);
-  mem_module_add_eeprom_segment(&module2,0x0180,0x0020);
-  mem_add_module(&memory,&module2);
+  if(!mem_module_add_ram_segment(&module1,0x0000,0x0005))
+    printf("Impossible to add segment\n");
+  if(!mem_module_add_ram_segment(&module1,0x0055,0x000A))
+    printf("Impossible to add segment\n");
+  if(!mem_module_add_eeprom_segment(&module1,0x0100,0x0020))
+    printf("Impossible to add segment\n");
+  if(!mem_add_module(&memory,&module1))
+    printf("Impossible to add module\n");
+
+  if(!mem_module_add_ram_segment(&module2,0x0200,0x0005))
+    printf("Impossible to add segment\n");
+  if(!mem_module_add_eeprom_segment(&module2,0x0180,0x0020))
+    printf("Impossible to add segment\n");
+  if(!mem_add_module(&memory,&module2))
+    printf("Impossible to add module\n");
+
+  if(!mem_module_add_ram_segment(&module2,0x050,0x000A))
+    printf("Impossible to add segment\n");
+  if(!mem_module_add_eeprom_segment(&module2,0x0180,0x0030))
+    printf("Impossible to add segment\n");
+  if(!mem_add_module(&memory,&module2))
+    printf("Impossible to add module\n");
 }
diff --git a/utils/Makefile b/utils/Makefile
index 163e4321bb6be6f35256b61bfb8f8c5a47ed1341..6419a0740cbe63bb280980663436e971591adfda 100755
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -3,6 +3,7 @@
 
 COMPILE_OPTS = -mlittle-endian -mthumb -mthumb-interwork
 COMPILE_OPTS += -Wall -O2 -fno-common
+#COMPILE_OPTS += -Wall -g -fno-common
 COMPILE_OPTS += -ffreestanding -nostdlib
 
 COMPILE_OPTS_M4_FPU = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mcpu=cortex-m4