/****************************************************************************************************/
/**
Copyright (c) 2008 Freescale Semiconductor
Freescale Confidential Proprietary
\file       S08_Flash.c
\brief      
\author     Freescale Semiconductor
\author     Guadalajara Applications Laboratory RTAC Americas
\author     
\version    1.0
\date       September/2008
*/
/****************************************************************************************************/
/*                                                                                                  */
/* All software, source code, included documentation, and any implied know-how are property of      */
/* Freescale Semiconductor and therefore considered CONFIDENTIAL INFORMATION.                       */
/* This confidential information is disclosed FOR DEMONSTRATION PURPOSES ONLY.                      */
/*                                                                                                  */
/* All Confidential Information remains the property of Freescale Semiconductor and will not be     */
/* copied or reproduced without the express written permission of the Discloser, except for copies  */
/* that are absolutely necessary in order to fulfill the Purpose.                                   */
/*                                                                                                  */
/* Services performed by FREESCALE in this matter are performed AS IS and without any warranty.     */
/* CUSTOMER retains the final decision relative to the total design and functionality of the end    */
/* product.                                                                                         */
/* FREESCALE neither guarantees nor will be held liable by CUSTOMER for the success of this project.*/
/*                                                                                                  */
/* FREESCALE disclaims all warranties, express, implied or statutory including, but not limited to, */
/* implied warranty of merchantability or fitness for a particular purpose on any hardware,         */
/* software ore advise supplied to the project by FREESCALE, and or any product resulting from      */
/* FREESCALE services.                                                                              */
/* In no event shall FREESCALE be liable for incidental or consequential damages arising out of     */
/* this agreement. CUSTOMER agrees to hold FREESCALE harmless against any and all claims demands or */
/* actions by anyone on account of any damage,or injury, whether commercial, contractual, or        */
/* tortuous, rising directly or indirectly as a result of the advise or assistance supplied CUSTOMER*/ 
/* in connectionwith product, services or goods supplied under this Agreement.                      */
/*                                                                                                  */
/****************************************************************************************************/

/*****************************************************************************************************
* Include files
*****************************************************************************************************/
#include "S08_Flash.h"

/*****************************************************************************************************
* Declaration of module wide FUNCTIONs - NOT for use in other modules
*****************************************************************************************************/

/*****************************************************************************************************
* Declaration of module wide TYPEs - NOT for use in other modules
*****************************************************************************************************/

/*****************************************************************************************************
* Definition of module wide VARIABLEs - NOT for use in other modules
*****************************************************************************************************/

/*****************************************************************************************************
* Definition of module wide (CONST-) CONSTANTs - NOT for use in other modules
*****************************************************************************************************/

/*****************************************************************************************************
* Code of project wide FUNCTIONS
*****************************************************************************************************/
/**
* \brief    Flash Initialization Function. Clear the ACCERR and PVIOL Flags and initializes the Flash Clock Divider
* \author   Rafael Peralez
* \param    void
* \return   void
* \todo     Make sure to have the right definition for BUS_CLOCK before compiling the project
*/
#pragma CODE_SEG DEFAULT
void FlashInit(void)
{
  /* Check if the Flash Clock is already written */
  if (!(FCDIV_FDIVLD))
  {
    if (FSTAT&(FSTAT_FACCERR_MASK | FSTAT_FPVIOL_MASK))
    {
        FSTAT |= (FSTAT_FACCERR_MASK | FSTAT_FPVIOL_MASK);
    }
    FCDIV = FLASH_CLOCK;
  }
}

/**
* \brief    Function to erase, write and burst write the Flash Memory. 
* \author   Rafael Peralez
* \param    FlashAddress Address that will be written
* \param    FlashDataCounter Amount of bytes to be written. Used only for burst commands
* \param    pFlashDataPtr Pointer where the information to be written is. Used for Write and Burst Only
* \param    FlashCommand  Command to be executed. This parameter allows to use the same function for all the routines
* \return   FLASH_ERROR - FLASH_OK
* \todo     This function needs to be copied to RAM before calling it. Read Technical Note 228 for this purpose
*/
#pragma CODE_SEG FLASH_ROUTINES
unsigned char Flash_Cmd(unsigned int FlashAddress, unsigned char FlashDataCounter, unsigned char* pFlashDataPtr, unsigned char FlashCommand)
{
    /* Check to see if FACCERR or PVIOL is set */
    //if (FSTAT&(FSTAT_FACCERR_MASK | FSTAT_FPVIOL_MASK))  
    {         
        /* Clear Flags if set*/
        FSTAT |= FSTAT_FACCERR_MASK | FSTAT_FPVIOL_MASK;  
    }

    do
    {
        /* Wait for the Last Busrt Command to complete */
        while(!(FSTAT_FCBEF));
        
        /* Write Data into Flash*/
        (*((volatile unsigned char *)(FlashAddress++))) = *pFlashDataPtr;
        pFlashDataPtr++;
        /* Write Command */
        FCMD = FlashCommand;
        
        /* Put FCBEF at 1 */
        FSTAT = 0x80;
        
        /* Wait at least 4 cycles to read the Error Flags */
        _asm NOP;
        _asm NOP;
        _asm NOP;
        _asm NOP;
        
        /* Check if Flash Access Error or Protection Violation Error are Set */
        if (FSTAT & (FSTAT_FACCERR_MASK | FSTAT_FPVIOL_MASK))
        {     
          /* If so, finish the function returning 1 to indicate error */
          return (FLASH_ERROR);
        }
    }while (--FlashDataCounter);
    /* wait for the last command to complete */
    while (!(FSTAT_FCCF));
    /* Return zero to indicate that the function executed Ok */
    return (FLASH_OK);
}

