problem about flash programing on 9S12XDT256! Thanks all!

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

problem about flash programing on 9S12XDT256! Thanks all!

721 Views
jeffzxg
Contributor I

hi:

       I wrote a flash driver like this:

In FlashDrv.c

     

#pragma CONST_SEG __GPAGE_SEG SYS_InfoFlash
    volatile const uint16  FLASHDrv_dataTestUB; //定义在这里,用于占位   
#pragma CONST_SEG DEFAULT


void  FLASHDrv_Init(void)
{
    if(FCLKDIV_FDIVLD == 0)
    {
        FCLKDIV = 39;
    }
}

uint8  FLASHDrv_ProgramOneWord(uint16 * __far addrFLASHPUW , uint16 dataProgramUW)
{
   if(FSTAT_ACCERR == 1)
   {
      FSTAT = 0x10;
   }
   if(FSTAT_PVIOL == 1)
   {
        FSTAT = 0x20;
   }

   while (!FSTAT_CBEIF)

   FSTAT = 0x30;
   *addrFLASHPUW = dataProgramUW;
   FCMD = 0x20;
   FSTAT = FSTAT | 0x80;
   while (!FSTAT_CCIF)
   {
      if ((FSTAT_ACCERR == 1) || (FSTAT_PVIOL == 1))
      {
          return 0;
      }
   }
      return  1;
}

uint8  FLASHDrv_SectorErase(uint16 * __far addrFLASHPUW)
{
    if (FSTAT_ACCERR == 1)
  {
      FSTAT = 0x10;
  }
  if (FSTAT_PVIOL == 1)
  {
      FSTAT = 0x20;
  }
  
  while (!FSTAT_CBEIF)
  
  FSTAT = 0x30;
  *addrFLASHPUW = 0xffff;
  FCMD = 0x40;
  FSTAT = FSTAT | 0x80;
  while (!FSTAT_CCIF)
  {
     if ((FSTAT_ACCERR == 1) || (FSTAT_PVIOL == 1))
     {
        return 0;
     }
  }
  return 1;
}


uint8  FLASHDrv_MassWrite(uint16 * __far addrFLASHPUW, uint16 numByteUW, uint16 * __far addrDataPUW)
{
    uint16  numCycleCntUW;
    uint16 *__far  addrFlashArrayPUW = addrFLASHPUW;
    uint16 *__far  addrDataArrayPUW = addrDataPUW;
    uint16 numDataUW = *addrDataArrayPUW;
    uint8  numReturn = 1;
   
    if((((uint32)addrFLASHPUW%1024)==0)&&(numByteUW>0)) 

    {
        if(FLASHDrv_SectorErase(addrFLASHPUW))

        {
            if(numByteUW <= 2)
            {
                if(FLASHDrv_ProgramOneWord(addrFlashArrayPUW , numDataUW))
                    numReturn = 1;
                else
                    numReturn = 0;   
            }
            else
            {
                for(numCycleCntUW=2;numCycleCntUW<=numByteUW:smileywink:
                {
                    numCycleCntUW += 2;
                    if(FLASHDrv_ProgramOneWord(addrFlashArrayPUW , numDataUW))
                    {
                        addrFlashArrayPUW++;
                        addrDataArrayPUW++;
                        numDataUW = *addrDataArrayPUW;
                    }
                    else
                    {
                        numReturn = 0;
                        break;
                    }    
                }
            }
        }
        else
        {
            numReturn = 0;
        }       
    }   
    return  numReturn;   
}

 

In prm file

 

SYS_InfoFlash     INTO  PAGE_FC;

 

In main.c

 

typedef struct
{
    uint16   a;
    uint8    b;
    sint16   c;
    uint16   d;
    uint16   e;
    uint8    f;
    uint8    g;
    uint32   h;
   
}flashteststruct;

flashteststruct     flashtest;
flashteststruct     flashtest2;

 
void main(void)

    FLASHDrv_Init();
   
    flashtest.a = 1;
    flashtest.b = 3;
    flashtest.c = 0xfa03;
    flashtest.d = 0xc005;
    flashtest.e = 0xe043;
    flashtest.f = 0xbb;
    flashtest.g = 0xdc;
    flashtest.h = 0x1fa45;
           
    FLASHDrv_MassWrite((uint16 *__far)&FLASHDrv_dataTestUB,sizeof(flashteststruct), (uint16 *__far)&flashtest);
    FLASHDrv_MassRead((uint8 *__far)&FLASHDrv_dataTestUB,sizeof(flashteststruct), (uint8 *__far)&flashtest2);

    for(;:smileywink:
    {

    }

 

my problem is when  i run this program , the program can not run into for(;:smileywink: loop , the program is error, but when i allocate

SYS_InfoFlash     INTO  PAGE_E2; in prm file, the program run ok. i debuged this program in step mode, i found function FLASHDrv_MassWrite((uint16 *__far)&FLASHDrv_dataTestUB,sizeof(flashteststruct), (uint16 *__far)&flashtest) can't run correctly when i allocate SYS_InfoFlash     INTO  PAGE_FC. the program error is in function if(FLASHDrv_SectorErase(addrFLASHPUW)) .

        another problem is when i changeed function uint8  FLASHDrv_SectorErase(uint16 * __far addrFLASHPUW) into

uint8  FLASHDrv_SectorErase(uint8 * __far addrFLASHPUW), no matter i allocate SYS_InfoFlash     INTO  PAGE_FC or

allocate SYS_InfoFlash     INTO  PAGE_E2,  in two cases , the program all run correctly.

       can anyone help me about this program,
                                                                  thanks!

Labels (1)
0 Kudos
Reply
1 Reply

493 Views
kef
Specialist I

First of all this is wrong:

   FSTAT = FSTAT | 0x80;

^^ this is attempt to clear not only CBEIF flag, but also all other FSTAT flags, which are set at the time CPU reads FSTAT.

 

You flash routines, or atlest part of them from the moment you clear CBEIF until CCIF is set, should execute from always available memory like RAM. Flash array is not readable while it is being erased or programmed. XDT256 has more then one flash bank and this explains why your routines work from one page and don't work from another. Why wrong attempt to use 8-bit writes to flash array didn't hand or reset MCU is also clear (uint8  FLASHDrv_SectorErase(uint8 * __far addrFLASHPUW). Doing so is banned by flash memory controller. You should see some error flags set.

 

So either program/erase flash from different flash array or EEPROM, or run you routines or above mentioned part of them from RAM. Don't forget to disable interrupts if vectors or interrupt handlers are placed in array that you are going to program/erase.

This thread explains how you could put your routine to RAM:

https://community.freescale.com/thread/96286

0 Kudos
Reply