mc9s12xdt256 - Eeprom local and global access

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

mc9s12xdt256 - Eeprom local and global access

1,546件の閲覧回数
hpdwally
Contributor II
I have been fighting access to my 4k eeprom on my latest project. The access is sporadic and often the values I write into the address space, do not return when uses pointers.

PRM Link

EEPROM        = READ_ONLY     0xF000 TO   0xFFFF;
//when I do this, nothing shows up in that space on a near pointer call. Yet I still can see it on 0x13F000

I usually call in this manor
cks_rom = ((short)*(short *far)(ram_base));
//where ram_base is 0x13F000

or
cks_rom = ((short)*(short *near)(ram_base));
//where ram_base is 0xF000

The first one works some of the time, the second one never will.

void EEPROM_WRITE(int dt0, int dt1, int addr)
{
  addr= (addr & 0x0FFF)/2;
 

  while(ESTAT_CBEIF==0); 
  if(ESTAT_PVIOL ==1) ESTAT_PVIOL=0;
  if(ESTAT_ACCERR ==1) ESTAT_ACCERR=0;
  EADDRHI = (byte)(addr>>8);
  EADDRLO = (byte)(addr & 0xFF); 
  EDATAHI = (byte)(dt0>>8);
  EDATALO = (byte)(dt0 & 0xFF);
  ECMD = 0x60;
  ESTAT_CBEIF =1;
  while(ESTAT_CBEIF==0);
  while(ESTAT_CCIF==0);

 
  addr+= 1;

  while(ESTAT_CBEIF==0); 
  if(ESTAT_PVIOL ==1) ESTAT_PVIOL=0;
  if(ESTAT_ACCERR ==1) ESTAT_ACCERR=0;
  EADDRHI = (byte)(addr>>8);
  EADDRLO = (byte)(addr & 0xFF); 
  EDATAHI = (byte)(dt1>>8);
  EDATALO = (byte)(dt1 & 0xFF);
  ECMD = 0x20;
  ESTAT_CBEIF =1;
  while(ESTAT_CBEIF==0);
  // EPROT_EPOPEN = 0;
 
}

I would love to make 16bit pointer calls to get read access in logical, things haven't worked out for me yet ...
ラベル(1)
0 件の賞賛
返信
1 返信

727件の閲覧回数
CompilerGuru
NXP Employee
NXP Employee
> EEPROM        = READ_ONLY     0xF000 TO   0xFFFF;

The linker uses paged addresses, and 0xF000 TO 0xFFFF are paged flash addresses, not EEPROM.
Using EEPROM should not require any special access macros if the prm file is properly setup.
Note that the F000..0xFFFF normally has to be used for FLASH (as it is intended) as this area contains the vectors. So it really is not available for anything else.

So either use paged EEPROM addresses (recommended) as it is done in all the default prm files:

Code:
/* non-paged EEPROM */      EEPROM        = READ_ONLY     0x0C00 TO   0x0FFF;/* paged EEPROM                     0x0800 TO   0x0BFF; addressed through EPAGE */....      EEPROM_1F     = READ_ONLY   0x1F0800 TO 0x1F0BFF;      EEPROM_FE     = READ_ONLY   0xFE0800 TO 0xFE0BFF;/*    EEPROM_FF     = READ_ONLY   0xFF0800 TO 0xFF0BFF; intentionally not defined: equivalent to EEPROM */

 or use global addresses (only recommended if large >1k objects are in EEPROM)

> EEPROM_FE        = READ_ONLY     0x13F800'G TO   0x13FBFF'G;

Note that even when using global addresses, you have to split up the EEPROM into 1k pages if you are accessing its content via EEPAGE mechanism (or unpaged), otherwise the linker will place objects across page boundaries so it will fail at runtime.
The only time I would suggest to use global addresses is with a few large (>=1k) objects, then those wont be accessible via single EEPAGE (__eptr pointers) anyway and would have to be accessed using the GPAGE register.

When placing variables into EEPROM above, using 16 bit __near pointers should work fine. When placing variables into any other EEPROM page segment, using __eptr (__EPAGE_SEG section qualifier) is most efficient, using __far (__GPAGE_SEG section qualifier) works too.

Daniel

0 件の賞賛
返信