/*******************************************************************************
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
********************************************************************************
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, EXPRESSED, IMPLIED OR STATUTORY INCLUDING, 
BUT NOT LIMITED TO, IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR 
A PARTICULAR PURPOSE ON ANY HARDWARE, SOFTWARE OR ADVISE SUPPLIED TO THE PROJECT
BY FREESCALE, AND OR NAY 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 an advise
or assistance supplied CUSTOMER in connection with product, services or goods 
supplied under this Agreement.
********************************************************************************
* File      main.c
* Owner     B34874
* Version   1.2
* Date      Aug-20-2015
* Classification   General Business Information
* Brief     Flash Erase/Write
********************************************************************************
* Detailed Description:
*
* The example present writing to the FLASH,
* The page 0E is used to be E/W so the line:
*      PAGE_0E       = READ_ONLY   0x0E8000 TO 0x0EBFFF;
* is removed from prm file to be not used bu compiler for code.
*
* Global address MUST be used for writing the flash. Logical address space
*      0x0E8000 TO 0x0EBFFF corresponds to global address space 0x38000~0x3BFFF
*
* Note that reding by means of global address is not possible. In this case only
* logical address can be used.
*
* The space 0x0E8000 TO 0x0EBFFF is removed from memory space to be not used by
* compiler for code placement. See marked lines in the prm file to see changes
*
* Only global address is accepted for writing. 
* Reading is possible from ppage or local addresses only.
*     
* - tested on: TWR-S12G240
* - OSCCLK = 8MHz oscillator, BUSCLK = 24MHz set by means of PLL in PEE mode
* - Reference to documentation: MC9S12GRMV1 Rev.1.25
********************************************************************************
Revision History:
Version  Date         Author  Description of Changes
1.0      Feb-09-2012  R62780  Initial version
1.1      Aug-20-2012  B34874  Modification
1.2      Aug-20-2015  B34874  Modification in RAM code - two options
*******************************************************************************/

#include <hidef.h>        /* common defines and macros */
#include "derivative.h"   /* derivative-specific definitions */
#include "flash_S12G.h"   /* flash code */

/*******************************************************************************
* Local module variables
*******************************************************************************/
//static unsigned int addr;
static unsigned long int addrl;
static unsigned int buffer[4];   
static volatile unsigned char err;  

/*******************************************************************************
Function Name : PLL_LockIsr
Notes         : The interrupt function used (if necessary) if the PLL lock 
                status has changed
*******************************************************************************/
#pragma CODE_SEG NON_BANKED
interrupt 28 void PLL_LockIsr(void)
{
  if(CPMUFLG_LOCK == 0)  {    /*do something here*/  }
  else                   {    /*do something here*/  }
}
#pragma CODE_SEG DEFAULT

/*******************************************************************************
Function Name : setPEEmodeBUSCLK
*******************************************************************************/
void SetPEEmodeBUSCLK(unsigned char _synr, unsigned char _refdv, unsigned char _postdiv)
{
 CPMUSYNR    = _synr;
 CPMUREFDIV  = _refdv;
 CPMUPOSTDIV = _postdiv;   
  
 CPMUOSC_OSCE = 1; //enable external oscillator OSCE
    
 while(!CPMUFLG_UPOSC)
  {
    //_FEED_COP(); // feed the dog if enabled
  };    
 while(!CPMUFLG_LOCK)
  {
    //_FEED_COP(); // feed the dog if enabled
  };    
}
/*******************************************************************************
Function Name : main
*******************************************************************************/


void main(void) {
  
unsigned int data=1;
 
 //.........................................
 SetPEEmodeBUSCLK(0x02, 0x80, 0x00); // 24MHz BUSCLK from 8 MHZ oscclk, PEE mode
 //.........................................
 ECLKCTL_NECLK = 0; // BUSCLK visible at PB0/PS7(it depends on package)
 //.........................................
 DDRAB = 0xFFFF;    // an output ports only for debug purposes

 //.........................................
 //fill data buffer
 //.........................................

 buffer[0] = 0xAAAA;
 buffer[1] = 0xBBBB;
 buffer[2] = 0xCCCC;
 buffer[3] = 0xDDDD;

 //.........................................
 // init flash clock
 //.........................................

 PFLASH_Init(0x18);// 24MHz busclk

 //.........................................
 // Functions accept global address only.
 // Local and logical addresses can be converted to global address by 
 // "Local2Global" function the size of sectors is 512 bytes = 64 phrases
 //.........................................
 // check given flash is erased sector by sector, if it does not erase it ---
 // both following address accesses can be used 
 // ppage address of sector 0x0E8000 ~ 0x0EBFFF
 // global address 0x38000 ~ 0x3BFFF
 //.........................................

 // Note:
 // In order to see changes in the memory during debugging you should adjust
 // memory setup in the debugger:
 // menu/target(Multilink, Softec,...) -> Debugging Memory Map -> select
 // corresponding part of memory -> press Modify/Details -> select
 // "refresh memory when halting"

 
 for(addrl=0x0E8000UL; addrl<=0x0EBFFFUL; addrl+=512) // entire ppage
   {
    if(PFLASH_Erase_Verify_Section(Local2Global(addrl),64) == NON_ERASED)
     {
        err = PFLASH_Erase_Sector(Local2Global(addrl));
     }
   }

 //.........................................
 // write the flash
 //.........................................

 for(addrl=0x0E8000UL; addrl<=0x0EBFFFUL; addrl+=8)
   {
     err = PFLASH_Program(Local2Global(addrl), buffer); 
   }

 //.........................................
 // read the flash
 //.........................................

 for(addrl=0x0E8000UL; addrl<=0x0EBFFFUL; addrl+=2)
   {
     PORTAB = PFLASH_Read_Word(addrl); 
     //if you want to use long addresse you have to set PPAGE for paging:
     //Alt F7->Compiler for HC12->Option->Code Generation-> select PPAGE register
     //for paging and in the cell which appears below write 0x15
     // (the text -CpPPAGE=0x15 should appear in the compiler line arguments 
     //after this setup)
     
   }
  
 //.........................................
 //do the same using global address
 //.........................................

 for(addrl=0x038000UL; addrl<=0x03BFFFUL; addrl+=512)
   {
    if(PFLASH_Erase_Verify_Section(addrl,64) == NON_ERASED)
     {
        err = PFLASH_Erase_Sector(addrl);
     }
   }
 
 for(addrl=0x038000UL; addrl<=0x03BFFFUL; addrl+=8)
   {
     err = PFLASH_Program(addrl, buffer); 
   }
 
 // reading by global address is not possible so ppage or local address must be used
 for(addrl=0x0E8000UL; addrl<=0x0EBFFFUL; addrl+=2)
   {
     PORTAB = PFLASH_Read_Word(addrl);
   }
   


  for(;;) {
  //  _FEED_COP(); /* feed the dog if enabled */
  } /* loop forever */
  /* please make sure that you never leave main */
}
