Carl Norman

Flash page write in GP32, Codewarrior 5.7

Discussion created by Carl Norman on Aug 9, 2007
Latest reply on Feb 21, 2008 by edgar andres marin vega
Hi all,

Just after some ideas i have spent a couple of hours without making and progress with my flash erase / write routines for GP32 (68HC908GP32)...

I cannot work out why the processor is resetting when i call the WriteFlashRow(); function. Erase works. COP is disabled, routines are running from RAM, i believe i have all the right timing (i think), based on the data sheet... Seems to work in the simulator, and the erase routines appear to work as the bytes are erased when i upload the module (FB01, FB02)..

This code was chopped down, so some basic things may have been deleted, im also open to comments on better ways to do things as i am new to C, comming from assembly background

**************************************
FLASH.C
**************************************

#include "derivative.h"
#include "FlashRoutines.h"


#pragma CONST_SEG UserFlashData
const far byte FB01 = 0xC1;
const far byte FB02 = 0xC3;
#pragma CONST_SEG DEFAULT

//Flash block protect register set
const byte xFLBPR @ 0xFF7E = 0xFF;  // NOTHING IS PROTECTED!

//xFLCR (Flash Control Register) This is not setup properly in the the header file for addressing far bytes
byte xFLCR @ 0xFE08;          // NOTHING IS PROTECTED!
#define PGM   1               // Mask bits for FLCR
#define ERASE 2
#define MASS  4
#define HVEN  8

/*************************************************************************/
/****           Erase a Block of FLASH Memory Subroutine           *****/
/*************************************************************************/
// This routine copies all the flash routines to ram as defined in
// the PRM  file
// Add this to the last SEGMENTS entry in the .PRM file
// ROM_IMAGE = READ_ONLY 0xF000 TO 0xF2FF RELOCATE_TO 0x0200;
// Add this line to the last entry under PLACMENT
// ToCopyToRAM                         INTO  ROM_IMAGE;
// For more information see TN228 from freescale, or search on "SEGMENTS"
// or "RELOCATE_TO" in the code warrior help files.
/*************************************************************************/
void CopyInRAM(void) {
  char *srcPtr, *dstPtr;
  int count;
    srcPtr = (byte *)Start_Copy_In_RAM;
    dstPtr = (byte *)&EraseRoutine;                     //Must be address of first routines
      for (count = 0; count < (int) Size_Copy_In_RAM; count++, dstPtr++, srcPtr++) {
        *dstPtr = *srcPtr;
      }
}


//WARNING: These function MUST be loaded into RAM before calling using
// CopyInRAM();  //Call prior to calling function in 'ToCopyToRAM'
#pragma CODE_SEG ToCopyToRAM
/*************************************************************************/
/****           Erase a Block of FLASH Memory Subroutine           *****/
/*************************************************************************/
/* This routine erases a block of FLASH of the size specified in the      */
/* FLASH Control Registers and at the location specified by FLASH_addr.  */
/* FLASH_addr is any address within the block to be erased.  The routine */
/* follows the basic 9 step sequence of the FLASH erase operation.       */
/*                                                    */
/* Initializations required:                                 */
/*    Set charge pump clock and block erase size in xFLCR and xFLCR2;     */
/*    FLASH_addr set                                       */
/* Values returned:                                     */
/*    none                                               */
/*************************************************************************/
void EraseRoutine (byte *FlashRow)  //WARNING: This name is part of CopyInRAM, do not add code above this
{
  //This may need to be done in one line
 
  xFLCR |= ERASE;               // Step 1 - Set erase and clear MASS erase
  xFLCR &= (~MASS);             // MASS and xFLCR is actually xFLCR GP32 header is WRONG

    __asm lda xFLBPR;                  // Step 2 - read from Flash block protect register
   
    *FlashRow = 0xFF;                  // Step 3 - Write to any FLASH
   
  Delay(t10uS);                 // Step 4 - Delay 10uS

  xFLCR |= HVEN;                // Step 5 - Set the HVEN bit

  Delay(t1mS);                  // Step 6 - Wait 1mS

  xFLCR &= (~ERASE);            // Step 7 - Clear the ERASE bit

  Delay(t5uS);                  // Step 8 - Wait min 5uS

  xFLCR &= (~HVEN);             // Step 9 - Clear the HVEN bit
}
/*************************************************************************/
/****                        Flash Write Row                         *****/
/*************************************************************************/
//Pass a pointer to the data in RAM to write, called pRAMData
//Pass a pointer to the Flash row to write to
//Warning, this WILL write the hole row i.e. 64 bytes, you must point to the START of a row!
void WriteFlashRow(byte* pRAMData, byte* pFlashData){

    byte* pFlashFirstByte = pFlashData;       //Need to save this so we know when the row is programmed
   
    xFLCR |= PGM;                          //Step 1 - Set PGM bit

  __asm lda xFLBPR;                 // Step 2 - read from Flash block protect register

    *pFlashFirstByte = 0xFF;              //Step 3 - Write to any address in the flash range we are about to write data to

    Delay(t10uS);                            //Step 4 - Wait for time tNVS

    xFLCR |= HVEN;                          //Step 5 - Set the HVEN enable

    Delay(t5uS);                            //Step 6 - Wait for time

    //Step 7/8/9 - Write data to flash, delay 30uS, for entire row 0x40 bytes
    while(pFlashData != (pFlashFirstByte+63)){
        *pFlashData++ = *pRAMData++;
        Delay(t10uS);         //Tprog MAX is 40uS, allowing for the delay in the loop, this works out to ~36uS
    }

    xFLCR &= (~PGM);            //Step 10 - Clear PGM bit

    Delay(t5uS);              //Step 11 - Delay for tNVH

    xFLCR &= (~HVEN);                  //Step 12 - Clear HVEN
}
/*************************************************************************/
/****                        Delay Routine                           *****/
/*************************************************************************/
/* This routine delays for a variable amount of time depending on the      */
/* value passed into the routine as variable A.                     */
/* Delay time = (12 + (5 + (11+72+11)*A + 11) + 8) / Bus Freq         */
/* This equation includes the bus cycles from calling the delay routine  */
/* until hitting the next line of code. This allows the user to           */
/* accurately predict the delay between two steps in the code.           */
/*                                                 */
/* Initializations required:                                   */
/*    Pass in variable A = Delay Value                               */
/* Values returned:                                       */
/*    None                                             */
/*************************************************************************/
void Delay (byte A)
{
    unsigned char    count;

    while (A!=0) {
        for (count=0x03;count!=0;count--);
        A--;
    }

    return;
}
#pragma CODE_SEG DEFAULT;              //WARNING: Do no add code to be ran from RAM below here       


Message Edited by CarlFST60L_2nd on 2007-08-09 09:11 AM

Outcomes