Dear sir,
I am using ms9c12xdp512 16 bit mcu.
Now I want to write data to flash. First i need to load the function from flash to RAM. But the function is in the far place. Every time, the content in WB[i] is invalid. Can you help me how to copy far function to ram and make sure it can run in ram(it is near) correctly?
My codes is :
main.c
{
INT8U data[2] = {48, 49};
WriteByte(0xFA, (INT8U*)0xBFFE, data, 2); //failed
}
flash.c
INT8U* writeByte(INT8U page, INT8U* pDes, INT8U* pSou, INT16U len);
static INT16U WB[90];
INT8U*(*WriteByte)(INT8U page, INT8U* pDes, INT8U* pSou, INT16U len);
void FlashInit(){
INT8U i;
INT16U *p;
FCLKDIV = 0x13;
FCNFG=0x00;
while(FCLKDIV_FDIVLD == 0);
FPROT_FPOPEN=1;
FPROT_FPHDIS=1;
FPROT_FPLDIS=1;
p = (INT16U*)writeByte;//0xEF827B is writeByte's absolute address, use this, the content of WB[i] is right;
for(i=0;i<90;i++){
WB[i] = *p++;
}
WriteByte = (INT8U* (*)(INT8U page, INT8U* pDes, INT8U* pSou, INT16U len))WB;
}
INT8U* writeByte(INT8U page, INT8U* pDes, INT8U* pSou, INT16U len){
INT16U i;
INT8U flag, oldPage;
INT16U data,address;
oldPage =PPAGE;
address = (INT16U)pDes;
flag = (INT16U)pDes&1;
while(!(FCLKDIV & 0x80));
while(!(FSTAT & 0x80));
while(FSTAT & 0x30){
FSTAT |= 0x30;
}
while(!(FPROT & 0x80));
PPAGE = page;
page=page&0x0C;
page=page>>2;
FCNFG = 3-page;
for( i =0; i<len;i++){
if(flag){
address = address&0xFFFE;
data = (*pSou++)|0xFF00;
}else{
data = ((*pSou++)<<8)|0x00FF;
}
__DINT;
*(INT16U*)address=data;
FCMD = 0x20;
FSTAT|=0x80;
while( !FSTAT_CBEIF );
while( !FSTAT_CCIF );
__EINT;
if(flag){
address=address+2;
}
flag^=1;
}
PPAGE = oldPage;
return pDes;
}
Thanks.
Hi,
Another approach different for creataing a function directly in RAM by means of CodeWarriror, as was suggested before, is to do it manually - in the cases it required.
I hope and believe the code I prepared a long time ago will help you to understand. (XDP512 - FCNTsInInRAM - LARGEMM-CW41) I think also XDP512 - FCNTsInInternalSRAM - CW45.zip should say the same.
I have to highlight that the function you want to copy from flash to ram must be PIC (position independent code) - I think it is clear if you consider jumps and call - absolute address would be problem....
The code was written in the past for CodeWarrior v4.1.
//==============================================================================
// - The example copies block of the functions from FLASH to Internal RAM
// - The address of RAM where the block will be copied is given by definition
// - Special iRAM space is created inside the SofTec_linker.prm file in order to
// preserve variables used during block copying and auxiliary calculations
// - The pointers to the copied functions are created in order to the functions
// be able to call each other.
// - if the functions, to be copied, have to call some other functions then
// the pointer to the function has to be called.
// - If the block of the functions is independent from Flash functions then it is
// able to work independently from flash.
//==============================================================================
Finally, I suggest you to step your final code to be sure it behaves as expected.
I have added some more project for study purpose.
Best regards,
Ladislav
Thanks for your answers. I had tried "Daniel Martynek " reply. writeByte works normally. But eraseSector is not right. Your project for me is a little hard to understand.
Hi
You can use pragmas, in .c file:
#pragma CODE_SEG __NEAR_SEG MY_RAM
void yourFunction(void) {
}
#pragma CODE_SEG DEFAULT
And then make space for MY_RAM in the linker file Project.prm
/*******************************************************************************/
//RAM = READ_WRITE 0x1400 TO 0x3FFF; // original
RAM = READ_WRITE 0x1400 TO 0x3DFF;
RAM_ROUTINE = READ_WRITE 0x3E00 TO 0x3FFF; // reserve last bytes
/*******************************************************************************/
DEFAULT_RAM INTO RAM;
MY_RAM INTO RAM_ROUTINE;
/*******************************************************************************/
Regards
Daniel
writeByte works now. Thank you very much.
But the function erase by sectors does not work. The writeByte and eraserSector is in the same .c file.
I read this from the datasheet: Fast sector erase and word program operation.
main.c
main.c
{
INT8U data[2] = {48, 49};
writeByte(0xFA, (INT8U*)0xBFFE, data, 2); // worked now
eraserSector(0xFA, 0x8000, 16); //After calling this, it does not work, the data in 0XFABFFE is still there.
}
//erase by sector(1024 bytes)
void eraserSector(INT8U page, INT16U address, INT8U count){
INT16U i;
INT8U d;
INT8U oldPage;
oldPage = PPAGE;
while(!(FCLKDIV & 0x80));
if(PPAGE){
PPAGE = page;
d = page&0x0C;
d = d>>2;
FCNFG = 3-d;
}
for(i=0;i<count;i++, address += 1024){
while(!(FSTAT & 0x80));
while(FSTAT & 0x30){
FSTAT |= 0x30;
}
while(!(FPROT & 0x80));
__DINT;
*(INT16U*)address = 0xFFFF;
FCMD = 0x40;
FSTAT |= 0x80;
while( !FSTAT_CBEIF );
while( !FSTAT_CCIF );
__EINT;
}
PPAGE = oldPage;
}
Waiting for your response.
Thanks.