S12XE: XEBI error while addressing over 64KB (IQSTAT ?)

cancel
Showing results for 
Search instead for 
Did you mean: 

S12XE: XEBI error while addressing over 64KB (IQSTAT ?)

Jump to solution
205 Views
Contributor II

Hi,

We are using MC9S12XEP100 with CY7C1041GN (256K x 16) as an external memory.  Everything was working fine, we were able to read from and write to external memory and we also check address and data information using a logic analyzer.

However, when we started writing and reading address above 64KB, problems began. Although we have configured the XEBI registers to work with a 256KB  memory, it is working as if we have configured for a 64KB. So, after the address 0x0FFFF, it returns to 0x0000.

Using a logic analyzer we noticed that address ADDR1 to ADDR5 are being generated as expected. However, PK0/ADDR16/IQSTAT0 to PK2/ADDR18/IQSTAT2 remain 0b000 when the address should be valid.

We think the problem is related to IQSTAT as if we had to set a register to force the uC to use ADDR16 instead of IQSTAT0. But we could not finda a solution.

Does anyone have any ideias?

I have attached part of our source code.

Thanks in advance.

James

 

0 Kudos
1 Solution
148 Views
NXP TechSupport
NXP TechSupport

Hi,

this is the "feature" of the CW coming from the past. The  far pointers really do not work as 24bit bit like it is in new devices. Over/Under_flow of the offset does not change page.  I have solved it in the past in this way when I wanted to have linear space for "array" through more pages:

The memory is connected to CS0\ in the global address space 0x400000 to 0x47FFFF and I use addresses 0x000000~0x7FFFFF.

Copy from the example:

//=============================================================================
// Definitions made to by able to address the memory from address space seen
// from the memory point of view.
// Memory address space 0x00000~0x7FFFFF [512kB] is visible for MCU in GLOBAL
// address space 0x400000~0x47FFFF
//
//=============================================================================
// 512kB SRAM
#define WRITE_BYTE(a,d) *((unsigned char *far)(a+0x400000UL))=d
#define READ_BYTE(a) *((unsigned char *far)(a+0x400000UL))

// 256kWord SRAM
#define WRITE_WORD(a,d) *((unsigned int *far)((a<<1)+0x400000UL))=d
#define READ_WORD(a) *((unsigned int *far)((a<<1)+0x400000UL))

 

// fill entire SRAM byte by byte; seen from SRAM address space
ub = 0;
for(addr = 0; addr < 0x80000UL; addr++) //512 kB
  {
    WRITE_BYTE(addr,ub++); // write RAM address
  }

// fill entire SRAM word by word; seen from SRAM address space; aligned addresses
uw = 0x1111;
for(addr = 0; addr < 0x40000UL; addr++) //256 kWord
  {
    WRITE_WORD(addr,uw++); // write RAM address
  }

Best regards,

Ladislav

View solution in original post

0 Kudos
4 Replies
113 Views
Contributor II

Thank you very much Dr. Ladislav.

0 Kudos
178 Views
NXP TechSupport
NXP TechSupport

Hi,

there are more reason which can affect the behavior. One of them are write one only bits in the MMCCTL register. The bit writing is read-modify-write instruction so you have to write entire byte at once. Next could be you do not use -D__FARDATA setup option in the compiler command line....

I suggest you to look at setup procedure and example described in the
https://community.nxp.com/t5/S12-MagniV-Microcontrollers/S12XD-S12XE-External-BUS-design-Addendum-To...

There is everything described step by step there.

I believe, after reading the document you will be able to find all mistakes in your code.

Best regards,

Ladislav

 

160 Views
Contributor II

Hello, Dr. Ladislav.

Thank you very much for your answer. We fixed MMCCTL and we were already using -D__FARDATA, but the problem persists. We noticed something important. GPAGE is not being incremented automatically by compiler as we increment a variable. We are sure that this is the issue. 

For instance, if we have a variable with an address 0x20FFFF and we increment it goes to 0x200000 instead of reaching 0x210000. We disassembled the code and we notice that CPU is using GPAGE and IX to generate 0x20FFFF external RAM address.

If the address variable is assigned to 0x20FFFE, GPAGE = 0x20 and IX = 0xFFFE (everything OK! external memory is reachable).

If the variable is incremented it goes to 0x20FFFF as expected, GPAGE = 0x20 and IX = 0xFFFF (OK!).

However, if we increment again to 0x210000, GPAGE stays 0x20 (!?) and IX = 0xFFFF.

 

In case my explanation is not good enough, this is a very simple code to illustrate the issue.

  volatile byte *far byteAddress  = (volatile byte *far)0x20FFFF;
  volatile byte *far byteAddress2 = (volatile byte *far)0x210000;

  // This works!  
  byteAddress[0] = 0xAA;
  if (*byteAddress == 0xAA) {
    // OK  <= Enters here
  } else {
    // Not OK
  }
 
  // if we increment byteAddress (byteAddress++) from 0x20FFFF to 0x210000 it goes to 0x200000 (?)
  byteAddress++;
  // This does not work
  byteAddress[0] = 0xBB;
  if (*byteAddress == 0xBB) {
    // OK  
  } else {
    // Not OK <= Enters here       
  }
  
  // if we assign 0x210000, it works
  // This works!  
  byteAddress2[0] = 0xAA;
  if (*byteAddress2 == 0xAA) {
    // OK  <= Enters here
  } else {
    // Not OK
  }
 

 

Why the compiler does not increment GPAGE automatically as it was used to do with PPAGE in S12 compiler?

 

Thanks in advance.

James

0 Kudos
149 Views
NXP TechSupport
NXP TechSupport

Hi,

this is the "feature" of the CW coming from the past. The  far pointers really do not work as 24bit bit like it is in new devices. Over/Under_flow of the offset does not change page.  I have solved it in the past in this way when I wanted to have linear space for "array" through more pages:

The memory is connected to CS0\ in the global address space 0x400000 to 0x47FFFF and I use addresses 0x000000~0x7FFFFF.

Copy from the example:

//=============================================================================
// Definitions made to by able to address the memory from address space seen
// from the memory point of view.
// Memory address space 0x00000~0x7FFFFF [512kB] is visible for MCU in GLOBAL
// address space 0x400000~0x47FFFF
//
//=============================================================================
// 512kB SRAM
#define WRITE_BYTE(a,d) *((unsigned char *far)(a+0x400000UL))=d
#define READ_BYTE(a) *((unsigned char *far)(a+0x400000UL))

// 256kWord SRAM
#define WRITE_WORD(a,d) *((unsigned int *far)((a<<1)+0x400000UL))=d
#define READ_WORD(a) *((unsigned int *far)((a<<1)+0x400000UL))

 

// fill entire SRAM byte by byte; seen from SRAM address space
ub = 0;
for(addr = 0; addr < 0x80000UL; addr++) //512 kB
  {
    WRITE_BYTE(addr,ub++); // write RAM address
  }

// fill entire SRAM word by word; seen from SRAM address space; aligned addresses
uw = 0x1111;
for(addr = 0; addr < 0x40000UL; addr++) //256 kWord
  {
    WRITE_WORD(addr,uw++); // write RAM address
  }

Best regards,

Ladislav

View solution in original post

0 Kudos