how to use the internal extended flash eeprom of the chip of mc68hc912dg128ccpv?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

how to use the internal extended flash eeprom of the chip of mc68hc912dg128ccpv?

Jump to solution
1,066 Views
mengzhang
Contributor II

Several days before,i have contacted the freescale fae to seek for some methods to manipulate the external dual-port ram.

We have accomplished this goal by receiving a demo code.

Our's chip of mc68hc912dg128ccpv has a 128K bytes of flash eeprom,we are not sure of whether this 128K bytes flash eeprom is read-only or read-write?

because we may have a code of 100K bytes,maybe 50K bytes of them need to operate to  read and write,i think ram(0x2000-0x3FFF) is not adequate.

So i program a code below,in this code, i want to set page3,page4,page5 to be internal expended ram space to make the data can be read and write,just leave page0,page1,page2 to be internal rom to. be read only.

 

some code below in project.prm:

SEGMENTS

    RAM            = READ_WRITE 0x2000 TO 0x3FFF;

    /* unbanked FLASH ROM */

    FLASH_PAGEC000 = READ_ONLY  0xC000 TO 0xFEFF;  

    /* banked EXTERNAL FLASH RAM */

    FLASH_PAGE4000 = READ_WRITE  0x4000 TO 0x7FFF;        //set 4000-7FFF to be external ram

    /* banked FLASH RAM */

    FLASH_PPAGE3   = READ_WRITE 0x38000 TO 0x3BFFF;       //set page3,4,5 to be internal ram     

    FLASH_PPAGE4   = READ_WRITE 0x48000 TO 0x4BFFF;             

    FLASH_PPAGE5   = READ_WRITE 0x58000 TO 0x5BFFF;

    /* banked FLASH ROM */

    FLASH_PPAGE0   = READ_ONLY 0x08000 TO 0x0BFFF;        //set page0,1,2 to be internal rom

    FLASH_PPAGE1   = READ_ONLY 0x18000 TO 0x1BFFF;

    FLASH_PPAGE2   = READ_ONLY 0x28000 TO 0x2BFFF;

    EEPROM         = READ_WRITE 0x0800 TO 0x0FFF;

END

PLACEMENT

    _PRESTART,                  

    STARTUP,                    

    ROM_VAR,                 

    STRINGS,                    

    VIRTUAL_TABLE_SEGMENT,      

    NON_BANKED,                

    COPY                         INTO FLASH_PAGEC000/*, FLASH_PAGE4000*/;      //original ram

    DEFAULT_ROM                  INTO FLASH_PPAGE0, FLASH_PPAGE1, FLASH_PPAGE2;

    SSTACK,              

    DEFAULT_RAM                  INTO RAM;

    /* set banked EXTERNAL FLASH RAM */

    MY_EX_RAM_PG               INTO  FLASH_PAGE4000;       //external ram

.........................................

 

a part of the code in main.c:

#pragma DATA_SEG   MY_EX_RAM_PG                            //set dataRAM array in external ram

uchar dataRAM[0x4000];

#pragma DATA_SEG __PPAGE_SEG  FLASH_PPAGE3                 //set ram01 array in  page3 

uchar  RAM01[0x4000];

#pragma DATA_SEG __PPAGE_SEG  FLASH_PPAGE4                 //set ram02 array in  page4

uchar  RAM02[0x4000];

#pragma DATA_SEG __PPAGE_SEG  FLASH_PPAGE5                 //set ram03 array in  page5

uchar  RAM03[0x4000];

#pragma DATA_SEG  DEFAULT

    some code has been omit.......

    RAM01[0] = 0x0A;                                       //i want to use this array RAM01[0]

...............................

 

compiler tell me the mistakes as follows:

Link Error   : L1102: Out of allocation space in segment RAM at address 0x2101

Link Error   : Link failed

 

i have set the option :PPAGE is used for banking.

so i do not know how to set the internal expended ram,and rom. how to use anything in page3 or page2?how to use RAM02[ xx] array?

we can see the code in demo code:

pragma CONST_SEG __PPAGE_SEG MY_EX_RAM_PG0A

UBYTE dataROM_02[0x4000];

how to visit datarom_02[0]? read-only?

Labels (1)
0 Kudos
1 Solution
893 Views
RadekS
NXP Employee
NXP Employee

Hi Meng,

It seems that there missing some line for PLACEMENT area.

You cannot use segment name (like FLASH_PPAGE3) directly in #pragma DATA_SEG command.

You can use something like:

/* set banked EXTERNAL FLASH RAM */

MY_EX_RAM_PG              INTO  FLASH_PAGE4000;      //external ram

MY_EX_RAM_PG00         INTO     FLASH_PPAGE3;                    /*first 16kB of external SRAM*/

MY_EX_RAM_PG01        INTO      FLASH_PPAGE4;                    /*second 16kB of external SRAM*/

MY_EX_RAM_PG02        INTO      FLASH_PPAGE5;                    /* third 16kB of external SRAM */

.........................................

and part of the code in main.c:

#pragma DATA_SEG MY_EX_RAM_PG //set dataRAM array in external ram

uchar dataRAM[0x4000];

#pragma DATA_SEG __PPAGE_SEG MY_EX_RAM_PG00 //set ram01 array in  page3

uchar  RAM01[0x4000];

#pragma DATA_SEG __PPAGE_SEG MY_EX_RAM_PG01 //set ram02 array in  page4

uchar  RAM02[0x4000];

#pragma DATA_SEG __PPAGE_SEG MY_EX_RAM_PG02 //set ram03 array in  page5

uchar  RAM03[0x4000];

#pragma DATA_SEG DEFAULT

    some code has been omit.......

RAM01[0] = 0x0A; //i want to use this array RAM01[0]

Other option is concatenate paged RAM into one block:

/* set banked EXTERNAL FLASH RAM */

MY_EX_RAM_PG              INTO  FLASH_PAGE4000;      //external ram

MY_EX_RAM_PG35  INTO FLASH_PPAGE3, FLASH_PPAGE4, FLASH_PPAGE5;

.........................................

and part of the code in main.c:

#pragma DATA_SEG MY_EX_RAM_PG //set dataRAM array in external ram

uchar dataRAM[0x4000];

#pragma DATA_SEG __PPAGE_SEG MY_EX_RAM_PG35 //set ram01 array in  page3,4,5

uchar  RAM01[0x4000];

uchar  RAM02[0x4000];

uchar  RAM03[0x4000];

#pragma DATA_SEG DEFAULT

BTW: naming RAM segment as FLASH_PPAGE3 is very confusing.

I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

EDIT: I forgot to add "INTO" in proposed modification PLACEMENT area. Fixed.

View solution in original post

0 Kudos
7 Replies
894 Views
RadekS
NXP Employee
NXP Employee

Hi Meng,

It seems that there missing some line for PLACEMENT area.

You cannot use segment name (like FLASH_PPAGE3) directly in #pragma DATA_SEG command.

You can use something like:

/* set banked EXTERNAL FLASH RAM */

MY_EX_RAM_PG              INTO  FLASH_PAGE4000;      //external ram

MY_EX_RAM_PG00         INTO     FLASH_PPAGE3;                    /*first 16kB of external SRAM*/

MY_EX_RAM_PG01        INTO      FLASH_PPAGE4;                    /*second 16kB of external SRAM*/

MY_EX_RAM_PG02        INTO      FLASH_PPAGE5;                    /* third 16kB of external SRAM */

.........................................

and part of the code in main.c:

#pragma DATA_SEG MY_EX_RAM_PG //set dataRAM array in external ram

uchar dataRAM[0x4000];

#pragma DATA_SEG __PPAGE_SEG MY_EX_RAM_PG00 //set ram01 array in  page3

uchar  RAM01[0x4000];

#pragma DATA_SEG __PPAGE_SEG MY_EX_RAM_PG01 //set ram02 array in  page4

uchar  RAM02[0x4000];

#pragma DATA_SEG __PPAGE_SEG MY_EX_RAM_PG02 //set ram03 array in  page5

uchar  RAM03[0x4000];

#pragma DATA_SEG DEFAULT

    some code has been omit.......

RAM01[0] = 0x0A; //i want to use this array RAM01[0]

Other option is concatenate paged RAM into one block:

/* set banked EXTERNAL FLASH RAM */

MY_EX_RAM_PG              INTO  FLASH_PAGE4000;      //external ram

MY_EX_RAM_PG35  INTO FLASH_PPAGE3, FLASH_PPAGE4, FLASH_PPAGE5;

.........................................

and part of the code in main.c:

#pragma DATA_SEG MY_EX_RAM_PG //set dataRAM array in external ram

uchar dataRAM[0x4000];

#pragma DATA_SEG __PPAGE_SEG MY_EX_RAM_PG35 //set ram01 array in  page3,4,5

uchar  RAM01[0x4000];

uchar  RAM02[0x4000];

uchar  RAM03[0x4000];

#pragma DATA_SEG DEFAULT

BTW: naming RAM segment as FLASH_PPAGE3 is very confusing.

I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

EDIT: I forgot to add "INTO" in proposed modification PLACEMENT area. Fixed.

0 Kudos
893 Views
mengzhang
Contributor II

can you tell me how to visit  RAM01[0] for example?

i tryed to visit the RAM01[0] directly.

if(RAM01[0] == 0 )

............

i can not get the right value in RAM01[0], so i think my method is not accurate

by the way, is it necessary to set the option of PPAGE is used in paging in code generation?

0 Kudos
893 Views
RadekS
NXP Employee
NXP Employee

I do not see any problem in using of “if(RAM01[0] == 0 ) …” code.

In fact, you don’t need use paging for external bus. hc12dg128c has high flexible memory map option. Registers RAM, EEPROM and Flash could be enabled/disabled in memory map and Registers, RAM, EEPROM could be moved in memory map.

If conflicts occur when mapping resources, the register block will take precedence over the other resources; RAM or EEPROM addresses occupied by the register block will not be available for storage. The following table shows resource mapping precedence:

Precedence        Resource

1                            BDM ROM (if active)

2                            Register Space

3                            RAM

4                            EEPROM

5                            On-Chip Flash EEPROM

6                            External Memory

So, all unused area in memory map could be used for access into External memory without paging.

You can for example disable whole flash or just $4000 to $7FFF part from them. In that case External memory could be accessible in this memory range.

There depends on your external memory, physical connection of address lines (PK lines),…

Paging mechanism is way how to address wider resources than limited internal 64kB address space. This is valid for Internal Flash and also External bus.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
893 Views
mengzhang
Contributor II

thank you my buddy.

maybe my description of our application of dg128 is not clear.

I am succeed in operating the external ram,and set 0x4000-7FFF to be the external space. I can read and write theexternal space.

besides,we need to set a space to put const data inside,these data is frame data of can bus protocol.so i want to put these data in one or two PAGEs,for example.

#pragma code_SEG __PPAGE_SEG MY_EX_ROM_PG00

uchar ROM01[0x4000];

#pragma DATA_SEG DEFAULT

MY_EX_ROM_PG00 is READ only inproject.prm

can I READ ROM01[0] directly?without any setting?

btw, i also want to set ram01[0x4000] in another PAGE. that can be READ and write.

so I do not know how to set and visit.

在 2015-06-24 22:25:47,RadekS <admin@community.freescale.com> 写道:

|

|

|

|

how to use the internal extended flash eeprom of the chip of mc68hc912dg128ccpv?

reply from RadekS in S12 / MagniV Microcontrollers - View the full discussion

I do not see any problem in using of “if(RAM01[0] == 0 ) …” code.

In fact, you don’t need use paging for external bus. hc12dg128c has high flexible memory map option. Registers RAM, EEPROM and Flash could be enabled/disabled in memory map and Registers, RAM, EEPROM could be moved in memory map.

If conflicts occur when mapping resources, the register block will take precedence over the other resources; RAM or EEPROM addresses occupied by the register block will not be available for storage. The following table shows resource mapping precedence:

Precedence Resource

1 BDM ROM (if active)

2 Register Space

3 RAM

4 EEPROM

5 On-Chip Flash EEPROM

6 External Memory

So, all unused area in memory map could be used for access into External memory without paging.

You can for example disable whole flash or just $4000 to $7FFF part from them. In that case External memory could be accessible in this memory range.

There depends on your external memory, physical connection of address lines (PK lines),…

Paging mechanism is way how to address wider resources than limited internal 64kB address space. This is valid for Internal Flash and also External bus.

I hope it helps you.

Have a great day,

RadekS

0 Kudos
893 Views
kef2
Senior Contributor IV

meng zhang,

I assume you are using CW5.1 for developing. If so, then to be able to access paged data directly, you need to add -DDG128 to compiler command line string and remove -CpPPAGE=xx if you added it already. You asked about -CpPPAGE in another thread, and no, you can't use this option. -CpPPAGE tells compiler that compiler can switch PPAGE at any time to access paged data. You can't allow this in normal banked application. (-CpPPAGE is useful only for small memory model applications. So if you have small amount of code and could limit yourself to small memory model, you could use this option to have fast paged data access times.) For banked memory model and paged data accesses you are limited to -DDG128, which will tell datapage.c code that you are using 912DG128 or 912DT128 device, and compiler will call datapage.c routines to access paged data.

  • #pragma code_SEG __PPAGE_SEG MY_EX_ROM_PG00
  • uchar ROM01[0x4000];
  • #pragma DATA_SEG DEFAULT

XXX_SEG is restricted to CODE_SEG (executable code), DATA_SEG (r/w data like uchar ROM01[]), CONST_SEG (r/o data like const uchar ROM01[]), etc.

So in your snippet there are at least two bugs. Unknown "code_SEG", and mismatch of two xxx_SEG 's. First pragma tells compiler/linker to put everything to different placement. Second pragma tells to restore default placement. Both xxx_SEG's should be the same.

Having code_SEG replaced with DATA_SEG, and -DDG128 added to compiler command line, you should be able to access ROM01[] directly like var=ROM01[100];

But...! If you are going to access ROM01 in different *.c file, you need to share ROM01 declaration with the same #pragma's, else compiling different file, compiler won't know that ROM01 is paged and won't make proper datapage.c calls.

If you are going to access ROM01 from interrupt handlers, you need to save and restore PPAGE register in your ISR's, which access ROM01.

Regarding "using flash as RAM." I think you meant how to be able to write to flash memory? Well, IMO your device choice is wrong. Old 912DG128 has huge minimum flash erase size of 32kB. That's two P-pages. Erasing anything at P-page 0, will erase whole P-pages 0 and 1. There are four eraseable areas (flash arrays), P-pages 0-1, 2-3, 4-5 and 6-7. Is 32kB minimum erase size OK for your app? If yes, then go ahead reading Section 8. Flash Memory. Flash erase and program procedures are explained there in details. If you didn't know, newer S12(X) have minimum flash erase size like 0.5kB or 1kB, which makes them more friendly to save some data in flash.

Edward

893 Views
mengzhang
Contributor II

thank you for your reply.

i need to think it more carefully,something you mentioned can not be seen on the datasheet,so i think it is hard to link them together.

so i have succeed in reading a byte data on any pages i want to manipulated.so i think you give more information that i needed.

0 Kudos
893 Views
RadekS
NXP Employee
NXP Employee

Hi Edward,

Thank you for your answer, analyze and important recommendations.

There are just additionally information about PAGEs and interrupts:

When interrupts occurs CPU code store core registers to stack a execute interrupt routine. However page registers are not stored automatically (your MCU has just PPAGE). If you use PPAGE also for any access to Flash data/code, you should handle PPAGE register value (store/restore) in your interrupt routine(s).

There are several ways how to do it:

  1. You can use command #pragma TRAP_PROC SAVE_ALL_REGS for every interrupt routine or only for interrupt routines, where your code modify page registers (this command is valid only for one followed interrupt routine). This command store/restore all page registers at begin/end of dedicated interrupt routine.
  2. You can use compiler option -CpPPAGE=0xFF. This will store/restore PPAGE register at begin/end of every interrupt routine.
  3. You can do it manually only for interrupt routines, where your code modify page registers. Like:

Unsigned char Temp;

Temp=PPAGE;

//your code

PPAGE=Temp;

This option is most flexible, but it presents higher load for programmer (he must know what he doing).

Of course, any store/restore of page registers presents additional load for CPU (several CPU cycles per PAGE).


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------