copy far function from flash to RAM

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

copy far function from flash to RAM

954 Views
liuweiwei
Contributor I

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.

0 Kudos
4 Replies

621 Views
lama
NXP TechSupport
NXP TechSupport

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

0 Kudos

621 Views
liuweiwei
Contributor I

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.

0 Kudos

621 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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

621 Views
liuweiwei
Contributor I

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.

0 Kudos