/******************************************************************************
* 		                                         COPYRIGHT (c) Freescale 2005   
* FILE NAME: S12XE_FTM.C                                                      
*                                                                           
* PURPOSE: S12XE Flash Routines      											 
*                                                                           
*                                                                          
* DOCUMENTATION SOURCE: CodeWarrior                                          
*                                                                           
* TARGET DEVICE: S12XE                                                
*                                                                           
* MEMORY USAGE(bytes)  RAM:         ROM:                                    
*                                                                           
* INCLUDE FILES: s12x_FTM.h, target.h                                               
*                                                                           
* FUNCTIONS :                                                      
*                                                    
* Tasks	 :  none                                                  			 
* Hooks   :	 none                                                            
* ISRs	 :	 none                                                                
*                                                                          
* COMPILER: Metrowerks                     
*                                                                           
* DESCRIPTION: Routines to program S12X FTM.                                              
*                                                                           
* NOTES
* -----
* Routines use Global pointers to access flash arrays.
*                                                                           
* UPDATE HISTORY                                                            
* REV      AUTHOR      DATE         DESCRIPTION OF CHANGE                    
* ---      ------      ---------    ---------------------                   
* 1.0      r32151      03/03/05     Initial coding                                        
*
***************************************************************************/
/*=========================================================================
Freescale reserves the right to make changes without further notice to any 
product herein to improve reliability, function, or design. Freescale does 
not assume any liability arising out of the application or use of any      
product, circuit, or software described herein; neither does it convey     
any license under its patent rights nor the rights of others. Freescale    
products are not designed, intended, or authorized for use as components   
in systems intended for surgical implant into the body, or other           
applications intended to support life, or for any other application in 
which the failure of the Freescale product could create a situation where 
personal injury or death may occur. Should Buyer purchase or use Freescale 
products for any such intended or unauthorized application, Buyer shall 
indemnify and hold Freescale and its officers, employees, subsidiaries, 
affiliates, and distributors harmless against all claims costs, damages, 
and expenses, and reasonable attorney fees arising out of, directly or 
indirectly, any claim of personal injury or death associated with such 
unintended or unauthorized use, even if such claim alleges that Freescale  
was negligent regarding the design or manufacture of the part. Freescale   
and the Freescale logo* are registered trademarks of Freescale Ltd.        
**************************************************************************/

/************************* Include Files *************************************/
#include "target.h"  /* includes device peripheral declarations */
#include "S12XE_Flash.h"
#include "far_ptr.h"
#include "s12x_peripherals.h"
/************************* typedefs ******************************************/

/************************* function prototypes *******************************/
/* in S12X_FTM.h */
/************************* #defines ******************************************/
/* in S12X_FTM.h */

/************************* Constants *****************************************/
#pragma CONST_SEG DEFAULT
/************************* Global Variables **********************************/
#pragma DATA_SEG DEFAULT
/************************* Functions *****************************************/
#pragma CODE_SEG DEFAULT 

/******************************************************************************
Function Name	:	ConfigFCLKDIV
Engineer		   :	r27624
Date			   :	17/9/2001
Arguments		:	none
Return			:	none
Notes				:	This function configures the Flash clock prescaler.

						!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
						! ENSURE THAT THE CRYSTAL AND BUS FREQUENCY DEFINES IN !
						! TARGET.H, OSCCLK_FREQ_KHZ AND BUSCLK_FREQ_KHZ, ARE   !
						! CORRECT AS THESE ARE USED BY THE FCLK_PRESCALER 		 !
						! MACRO AND MAY DAMAGE THE FLASH IF INCORRECT          ! 
						!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!        

******************************************************************************/
void
ConfigFCLKDIV(void)
{
	if(FTM.fclkdiv.bit.fdivld == 0)
	{															/* configure Flash clock prescaler */
		FTM.fclkdiv.byte  = (UINT8)FCLK_PRESCALER; 
	}
	return;
}

/******************************************************************************
Function Name	:	LaunchFlashCommand
Engineer		:	r32151
Date			:	15/11/05
Arguments	:	
Return		:
Notes			:	This function does not check if the Flash is erased.
               This function does not explicitly verify that the data has been 
					sucessfully programmed.
					This function must be located in RAM or a flash block not 
					being programmed.
******************************************************************************/
tU08
LaunchFlashCommand(char params, tU08 command, tU08 ccob0, tU16 ccob1, tU16 ccob2, tU16 ccob3, tU16 ccob4, tU16 ccob5)
{
	if(FTM.fstat.bit.ccif == 1)
	{																	
														      /* Clear any error flags*/	
	   FTM.fstat.byte = (FPVIOL | ACCERR); 

              /* Write the command id / ccob0 */
		FTM.fccobix.byte = 0;
		FTM.fccob.byte.hi = command;
		FTM.fccob.byte.lo = ccob0;

      if(++FTM.fccobix.byte != params) {
         FTM.fccob.word = ccob1; 			/* Write next data word to CCOB buffer. */ 
         if(++FTM.fccobix.byte != params) {
  		      FTM.fccob.word = ccob2; 			/* Write next data word to CCOB buffer. */
            if(++FTM.fccobix.byte != params) {
   		      FTM.fccob.word = ccob3; 			/* Write next data word to CCOB buffer. */
               if(++FTM.fccobix.byte != params) {
      		      FTM.fccob.word = ccob4; 			/* Write next data word to CCOB buffer. */
                  if(++FTM.fccobix.byte != params) 
         		      FTM.fccob.word = ccob5; 			/* Write next data word to CCOB buffer. */
               } 											
            }  
	      }
      }
	   FTM.fccobix.byte = params-1;				
					
					/* Clear command buffer empty flag by writing a 1 to it */
		FTM.fstat.byte = CCIF;
      while (!FTM.fstat.bit.ccif) {					/* wait for the command to complete */
      } 
   	    /* Return status. */
   	return(FTM.fstat.byte);										/* programmed OK */
	} 
	else 
	{
	   return(FLASH_BUSY);								/* state machine busy */
	}
}

/******************************************************************************
Function Name	:	ProgramP_FlashPhraseAtPtr
Engineer		:	r32151
Date			:	15/12/06
Arguments	:	*__far progAdr		Global pointer to the Flash location to be 
                                 programmed - must be on a /8 boundary
					* data            16-bit data to be programmed

Notes			:	This function must be located in RAM or a flash block not 
					being programmed.
******************************************************************************/
tU08
ProgramP_FlashPhraseAtPtr(tU16 *__far progAdr, tU16 *data)
{
													      /* Clear any error flags*/	
   FTM.fstat.byte = (FPVIOL | ACCERR); 

           /* Write the program command and the GPAGE part */
	FTM.fccobix.byte = 0;
	FTM.fccob.byte.hi = PROGRAM_P_FLASH;
	FTM.fccob.byte.lo = WP_PAGE(progAdr);
				/* Write the 16-bit address part of phrase */
	FTM.fccobix.byte++;
	FTM.fccob.word = WP_ADDR(progAdr); 

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data;  						/* Write next data word to CCOB buffer. */
															/* Clear command buffer empty flag by writing a 1 to it
															   This launches the command. */
	FTM.fstat.byte = CCIF;
   while (!FTM.fstat.bit.ccif) {					/* wait for the command to complete */
   } 

   return(FTM.fstat.byte);							/* return status */
}

/******************************************************************************
Function Name	:	ProgramP_FlashPhrase
Engineer		:	r32151
Date			:	15/12/06
Arguments	:	gpage		GPAGE of phrase to be programmed 
               addr     16-bit part of global addreess of phrase to be 
                        programmed - must be on a /8 boundary
					* data            16-bit data to be programmed
Notes			:	This function must be located in RAM or a flash block not 
					being programmed.
******************************************************************************/
tU08
ProgramP_FlashPhrase(tU08 gpage, tU16 addr, tU16 *data)
{
													      /* Clear any error flags*/	
   FTM.fstat.byte = (FPVIOL | ACCERR); 

           /* Write the program command and the GPAGE part */
	FTM.fccobix.byte = 0;
	FTM.fccob.byte.hi = PROGRAM_P_FLASH;
	FTM.fccob.byte.lo = gpage;
				/* Write the 16-bit address part of phrase */
	FTM.fccobix.byte++;
	FTM.fccob.word = addr; 

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data;  						/* Write next data word to CCOB buffer. */
															/* Clear command buffer empty flag by writing a 1 to it
															   This launches the command. */
	FTM.fstat.byte = CCIF;
   while (!FTM.fstat.bit.ccif) {					/* wait for the command to complete */
   } 

   return(FTM.fstat.byte);							/* return status */
}

/******************************************************************************
Function Name	:	LoadP_FlashPhraseData
Engineer		:	r32151
Date			:	15/12/06
Arguments	:	gpage		GPAGE of phrase to be programmed 
               addr     16-bit part of global addreess of phrase to be 
                        programmed - must be on a /8 boundary
					* data            16-bit data to be programmed
Notes			:	This function must be located in RAM or a flash block not 
					being programmed.
******************************************************************************/
tU08
LoadP_FlashPhraseData(tU08 gpage, tU16 addr, tU16 *data)
{
													      /* Clear any error flags*/	
   FTM.fstat.byte = (FPVIOL | ACCERR); 

           /* Write the program command and the GPAGE part */
	FTM.fccobix.byte = 0;
	FTM.fccob.byte.hi = LOAD_DATA_FIELD;
	FTM.fccob.byte.lo = gpage;
				/* Write the 16-bit address part of phrase */
	FTM.fccobix.byte++;
	FTM.fccob.word = addr; 

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data++;						/* Write next data word to CCOB buffer. */

	FTM.fccobix.byte++;
   FTM.fccob.word = *data;  						/* Write next data word to CCOB buffer. */
															/* Clear command buffer empty flag by writing a 1 to it
															   This launches the command. */
	FTM.fstat.byte = CCIF;
   while (!FTM.fstat.bit.ccif) {					/* wait for the command to complete */
   } 

   return(FTM.fstat.byte);							/* return status */
}
