/******************************************************************************/
/* Project Name:  main.c                                                      */
/* Last modified: March/08/2005                                               */
/* By:            r62780                                                      */
/******************************************************************************/
/* Description: MC9SC32_FLASH_DOONSTACK - demo                                */
/* Documentation: AN2720/D                                                    */
/* This software is classified as Engineering Sample Software.                */
/******************************************************************************/
/**********************************************************************************************************************
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 ORE 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
the advise or assistance supplied CUSTOMER in connection with product, services or goods supplied under this Agreement.
**********************************************************************************************************************/
/*******************************************************************************
- this sample software was tested on MC9S12C32 Controller Board
- the board includes 8.000MHz crystal
- the board bus frequency 8.000MHz set by PLL
- the mask set number was 1L45J
- the sample software demonstrates FLASH programming as a part of application
- the sample application writes a few words into FLASH locations
- the program is placed inside page 3F (address 0xC000~0xFFFF)
- The page 0x3E is accessible for R/W operations - adressed by:
  1) direct address 0x4000~0x7FFF
  2) page addressing page 0x3E+(0x8000~0xBFFF)
- Flash sector size is 512 bytes
*******************************************************************************/
#include <hidef.h>                          // common defines and macros
#include <mc9s12c32.h>                      // derivative information
#include "doonstack.h"                      // API to the assembly module
#include "flash.h"                          // API to the assembly module
//------------------------------------------------------------------------------
#pragma LINK_INFO DERIVATIVE "mc9s12c32"
//------------------------------------------------------------------------------
unsigned int  *far pui;         // pointer to external memory
unsigned int  uix;
unsigned int  uiy;
unsigned char ucx;
unsigned long addr;
//------------------------------------------------------------------------------
static void PLL_Init(void);
//------------------------------------------------------------------------------
static void PLL_Init(void)
{
  PLLCTL_PLLON = 0;                         // Disable the Phase Lock Loop 
  PLLCTL_CME = 0;                           // Disable Clock monitor 
  PLLCTL_SCME = 0;                          // Self clock mode switched off 
  CLKSEL_PLLSEL = 0;                        // Select clock source from OSCCLK 
  CLKSEL_PLLWAI = 1;                        // PLL stops in wait mode 
  CLKSEL_SYSWAI = 1;                        // Stop system clocks in wait mode 
  CLKSEL_CWAI = 1;                          // Core clock stop in wait mode 
  CLKSEL_PSTP = 1;                          // Osc continues to run in Stop mode (Pseudo Stop) 
  SYNR_SYN = 6;                             // Set the multiplier register for BUSCLK=8 MHz from oscclk=8MHz
  REFDV_REFDV = 6;                          // Set the divider register for BUSCLK=8 MHz from oscclk=8MHz
  PLLCTL_PLLON = 1;                         // Enable the Phase Lock Loop 
  PLLCTL_CME  = 1;                          // Enable Clock monitor 
  while(!CRGFLG_LOCK);                      // Wait till the PLL VCO is within tolerance
  CLKSEL_PLLSEL = 1;                        // Select clock source from PLLCLK
}
//------------------------------------------------------------------------------
void main(void) 
{
  //----------------------------------------
  PLL_Init();                               // init PLL to set 8MHz bus clock from 8MHz OSCCLK
  //----------------------------------------
  DDRB  = 0xFF;                             // an output port
  //----------------------------------------
                                            // initialization of the interrupts
    DisableInterrupts;                      // disable interrupts, it is necessity since FLASH is inaccessible during
                                            // erasing or programming
  //----------------------------------------
		                                        // initialization of COP
    COPCTL = 0x00;                          // disable the COP
  //----------------------------------------
                                            // initialization of FLASH module
    Flash_Init(8000,125);                   // Oscillator clock is 8.000MHz, bus clock is 8MHz => tbus=125ns
  //----------------------------------------
	//erase entire page 0x3E
  //----------------------------------------
  // it can be done either this way 
  for(addr=0x3E8000L;addr<0x3EBFFFL;addr+=0x200L)
    { pui = ((unsigned int *far)(addr));    // create address
      Flash_Erase_Sector(pui);
    }
  // or this way 
  //for(addr=0x4000L;addr<0x7FFFL;addr+=0x200L)
  //  { pui = ((unsigned int *far)(addr));    // create address
  //    Flash_Erase_Sector(pui);
  //  }
  //----------------------------------------
	//write data to entire page 0x3E
  //----------------------------------------
  // it can be done either this way 
  uix = 1;
  for(addr=0x3E8000L;addr<0x3EBFFFL;addr+=2)
      { pui = ((unsigned int *far)(addr));  // create address
        ucx = Flash_Write_Word(pui,uix++);  // write data (an integer is written)
      }
  // or this way 
  //uix = 10;
  //for(addr=0x4000L;addr<0x7FFFL;addr+=2)
  //  { pui = ((unsigned int *far)(addr));    // create address
  //    ucx = Flash_Write_Word(pui,uix++);    // write data (an integer is written)
  //  }
  //----------------------------------------
  //----------------------------------------
	//read and test data from entire page 0x3E
  //----------------------------------------
  PORTB = 0x00;                                 // switch off all diodes
  for(;;)
    {
      // it can be done either this way 
      uix = 1;
      for(addr=0x3E8000L;addr<=0x3EBFFFL;addr+=2)
          { pui = ((unsigned int *far)(addr));  // create address
            uiy = *pui;                         // read written data (an integer is read)
            if(uix != uiy)   	                  // test written data      
              {
                PORTB = 0xFF;                   // signalize error
                for(;;);												// stop on current address
              }
            uix++;
          }
      // or this way 
      uix = 1;
      for(addr=0x4000L;addr<=0x7FFFL;addr+=2)
          { pui = ((unsigned int *far)(addr));  // create address
            uiy = *pui;                         // read written data (an integer is read)
            if(uix != uiy)   	                  // test written data      
              {
                PORTB = 0xFF;                   // signalize error
                for(;;);          							// stop on current address 
              }
            uix++;
          }
          
      PORTB_BIT7 = ~PORTB_BIT7;                 // signalize end of cycle
    }
  //----------------------------------------
}