Hi,
I am new to freescale controllers currently working with MC9S12XF512, I am trying to implement flash driver for this controller, whereas from the discussions in the forum i have already seen many code snippets related to flash driver for other controllers. However I felt there are many registers which are different in this particular controller when compared to the others.
I need some help in configuring the related registers for Flash driver.
Thank you.
With Regards,
Sravani T
解決済! 解決策の投稿を見る。
Hi,
In attachment you could find simple example code for P-Flash at S12XF.
From other S12 families, most similar should be in your case S12XE family.
Please modify memory ranges according your MCU derivative.
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!
-----------------------------------------------------------------------------------------------------------------------
Hi,
In attachment you could find simple example code for P-Flash at S12XF.
From other S12 families, most similar should be in your case S12XE family.
Please modify memory ranges according your MCU derivative.
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!
-----------------------------------------------------------------------------------------------------------------------
Hi RadekS,
Thank you for the reply.
Really the code helped me a lot to understand the register settings.
Only one thing which I am not clear about, in the code shared is the below piece of code:
//==============================================================================
//PFLASH Send_Command
//==============================================================================
//this function is stored in nonbanked RAM memory. Must be called by JSR
//in C language:
// {
// FSTAT_CCIF = 1; //launch command
// while(FSTAT_CCIF == 0); //wait for done
// }
static unsigned char Send_Command[]=
{
0x1C, 0x01, 0x06, 0x80, 0x1F, 0x01, 0x06, 0x80, 0xFB, 0x3D
};
In few functions it has been written as:
asm JSR Send_Command;
stating to jump to the subroutine Send_Command and which has so many values in the above mentioned code, and also few lines which are commented which mentioned
//this function is stored in nonbanked RAM memory. Must be called by JSR
//in C language:
// {
// FSTAT_CCIF = 1; //launch command
// while(FSTAT_CCIF == 0); //wait for done
// }
Did the above piece of code is equivalent to the Send_Command[]?
I am not able to figure out the values in Send_Command. Will it be appropriate to use the commented to code instead of calling Send_Command.
could you please help me in understanding this.
Thank you.
With Regards,
Sravani T
Hi,
Yes, exactly.
Send_Command array contains code for write into CCIF bit and while loop where we waiting for this bit (waiting for flash command finish).
You can simply write your code in C, disassembly it and rewrite directly machine code into such array.
The last 0x3D value is just additional instruction for return for jump.
There is also second option how to move code into RAM and execute it there (probably more user friendly way). We could use #pragmas. For example:
#pragma CODE_SEG DEFAULT_RAM
void Send_Command (void)
{
DisableInterrupts;
FSTAT_CCIF = 1; //launch command
while(FSTAT_CCIF == 0); //wait for done
EnableInterrupts;
}
#pragma CODE_SEG DEFAULT
And we could use this function directly instead assembler JSR instruction. For example:
Send_Command(); instead of asm JSR Send_Command;
I added here disable and enable interrupt instruction for case where our interrupt routines are located in flash. So, interrupt routines will have to wait for finish flash critical section.
Similar way, we could simply add here also watchdog update (into while loop),…
Reason for moving part of code into RAM and execute it from there is fact, that we cannot simultaneously write or erase the same flash block from which we currently read and execute code. So, we have to use different flash block for flash routines or rather just move critical section into RAM. Solution with RAM will allow us to write/erase any part of flash.
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!
-----------------------------------------------------------------------------------------------------------------------
Hi,
Thank you for the clarification.
when I used asm JSR Send_Command; I could see in memory map file under - VARIABLES section, which clearly
- VARIABLES
Send_Command 2100 A 10 4 .data
under copydown section:
*********************************************************************************************
COPYDOWN SECTION
---------------------------------------------------------------------------------------------
------- ROM-ADDRESS: 0xC0B1 ---- SIZE 4 ---
Filling bytes inserted
000A2100
------- ROM-ADDRESS: 0xC0B5 ---- RAM-ADDRESS: 0x2100 ---- SIZE 10 ---
Name of initialized Object : Send_Command
1C0106801F 010680FB3D
------- ROM-ADDRESS: 0xC0BF ---- SIZE 2 ---
Filling bytes inserted
0000
*********************************************************************************************
by this I understood that Send_Command is stored in RAM.
but when i replaced Send_Command array with the c function which you have provided with pragma,
i could see in map file:
- PROCEDURES:
Send_Command FE8000 E 14 4 .text
by the address i understood that it is stored in Flash PAGE_FE.
so send_command is not in RAM. how can i make sure that any function to be moved into RAM.
please let me know.
Thank you.
With Regards,
Sravani T
Hi Sravani,
You are right, #pragma CODE_SEG DEFAULT_RAM does not work correctly. DEFAULT_RAM is one of predefined segments and linker do not want use it. In fact I used before #pragma CODE_SEG RAM and that worked fine, but description in linker file still point to flash. So, I am not sure now…
However you could create your own RAM location. For example:
#pragma CODE_SEG MY_RAM
void Send_Command1 (void)
{
DisableInterrupts;
FSTAT_CCIF = 1; //launch command
while(FSTAT_CCIF == 0); //wait for done
EnableInterrupts;
}
#pragma CODE_SEG DEFAULT
and define MY_RAM in prm file. For example:
SEGMENTS
…
//RAM = READ_WRITE 0x2000 TO 0x3FFF;
RAM = READ_WRITE 0x2000 TO 0x3EFF;
RAM1 = READ_WRITE 0x3F00 TO 0x3FFF;
…
PLACEMENT
…
MY_RAM INTO RAM1;
…
After that I could see it in map file as RAM content:
MODULE: -- main.c.o --
- PROCEDURES:
…
Send_Command1 3F00 E 14 2 MY_RAM
and
*********************************************************************************************
COPYDOWN SECTION
------- ROM-ADDRESS: 0xC0C7 ---- RAM-ADDRESS: 0x3F00 ---- SIZE 14 ---
Name of initialized Object : Send_Command1
14101C0106 801F010680 FB10EF0A
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!
-----------------------------------------------------------------------------------------------------------------------
Hi RadekS,
Thank you for the information and it worked. One more help I need, as in the provided code i could see only using PFLASH blocks and there is an function "Convert_Ppage2Global". however here i wanted to try for DFlash also where the EPage $800 to $BFF (global start address is 0x10_0000 end address is 0x10_7FFF)
could you please share, if you have any logic to convert Epage2Global.
Thank you.
With Regards,
Sravani T
Hi Sravani,
You could use function which converts D-Flash address similar way. For example:
//==============================================================================
//Convert_Dpage2Global
//==============================================================================
unsigned long int Convert_Dpage2Global(unsigned long int Addr)
{
Addr = ((Addr>>6) & 0x00007C00UL) | (Addr & 0x000003FFUL) | 0x00100000;
return(Addr);
}
In attachment you can find memory map in excel format for your orientation.
Note: memory map was created for S12XE family; however memory mapping for S12XF family should be the same.