Skip to content
Snippets Groups Projects
memory.c 5.62 KiB
#include "memory.h"
#include "mem_module.h"

/* 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;

  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;
}

/* public functions */
void mem_init(TMemory *memory)
{
  unsigned char i;

  memory->num_mem_modules=0;
  for(i=0;i<MAX_NUM_MEM_MODULES;i++)
    memory->mem_modules[i]=0x00000000;
  memory->eeprom_write_data=0x00000000;
  memory->eeprom_read_data=0x00000000;
}

void mem_initialize_data(TMemory *memory)
{
  TMemModule *mem_module;
  unsigned short data;
  unsigned short int i,j;
  unsigned char eeprom_data[EEPROM_SIZE];

  if(memory->eeprom_read_data!=0x00000000)
  {
    for(i=0;i<EEPROM_SIZE;i++)
    {
      memory->eeprom_read_data(i,&data);
      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_module->write_cmd!=0x00000000)
           mem_module->write_cmd(0x0000,EEPROM_SIZE,eeprom_data);
        }
      }
    }
  }
}

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;
        }
      }
    }
    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;

  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_module->write_cmd!=0x00000000)
          mem_module->write_cmd(start_address,length,data);
      }
    }
    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_module->write_cmd!=0x00000000)
          mem_module->write_cmd(start_address,length,data);
        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]);
      }
    }
  }
}

void mem_do_read(TMemory *memory,unsigned short int start_address,unsigned short int length,unsigned char *data)
{
  TMemModule *mem_module;
  unsigned char i,j;

  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_module->read_cmd!=0x00000000)
          mem_module->read_cmd(start_address,length,data);
      }
    }
    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_module->read_cmd!=0x00000000)
          mem_module->read_cmd(start_address,length,data);
      }
    }
  }
}