/************************************************************************
* (c) Copyright Freescale Semiconductor, Inc 2007, All Rights Reserved  *
************************************************************************/

/************************************************************************
*               EEPROM Emulation Driver for S12XS/S12P                  *
*                                                                       *
*   FILE NAME     :  NormalDemo.c                                       *
*   DATE          :  02.24.2009                                         *
*   AUTHOR        :  Infosys Team, Mysore                               *
*   EMAIL         :  r56611@freescale.com                               *
*************************************************************************/

/****************************** CHANGES *********************************
* 0.0.0a   06.21.2007      Sindhu R01       Draft Version
* 0.0.1    07.13.2007      Sindhu R01       Tested Version
* 0.0.2    08.10.2007      Sindhu R01       Removed assignment of Macro
                                            BDMENABLE
* 0.1.0    06.18.2008      Sindhu R01       Removed Flash configuration
                                            structure and added comments
* 0.2.0    10.27.2008      Sindhu R01       Modified code to demonstrate
                                            using the interrupt based
                                            updated EED driver
* 0.2.1    02.24.2009      Sindhu R01       Modified code to demonstrate
                                            mutiple byte programming.
*************************************************************************/

/************************************************************************
1. Normal flash demo with EEPROM Emulation Driver for S12P
2. Demo 5 high level functions in total:
    FSL_InitEeprom
    FSL_WriteEeprom
    FSL_ReadEeprom
    FSL_DeinitEeprom
    FSL_ReportEepromStatus
*************************************************************************/


#include "ee_emulation.h"
#include "NormalDemo.h"
#include <mc9s12hy64.h>

/************************************************************************
*
*  Function Name    : ErrorTrap
*  Description      :
*  Arguments        : void
*  Return Value     : void
*
*************************************************************************/
void ErrorTrap(void)
{
    while(1)
        {
            ;
        }
}

/*********************************************************************
*
*  Function Name    : CallBackFunc
*  Description      :
*                    .
*  Arguments        : void,
*  Return Value     : void
*
*********************************************************************/
void CallBackFunc(void)
{

}

/*********************************************************************
*
*  Function Name    : ExpectionAll
*  Description      :
*
*  Arguments        : void
*  Return Value     : void
*
**********************************************************************/
#pragma CODE_SEG NON_BANKED
#pragma TRAP_PROC
void SSD_SGF18_NEAR ExceptionAll(void)
{
    while(1)
    {
        ;
    }
}
#pragma CODE_SEG DEFAULT
/*********************************************************************
*
*  Function Name    : INT_init
*  Description      : Initialize MCU interrupt
*
*  Arguments        : void
*  Return Value     : void
*
**********************************************************************/
void SSD_SGF18_NEAR INT_Init(void)
{
    UINT16 index;          /* Index for vector table */
    UINT16 *SSD_SGF18_NEAR vectorTable;   /* Vector table */

    /* Initialize the expection vector table */
    vectorTable = (UINT16 * SSD_SGF18_NEAR)0x3000;

    for(index=0;index < 128;index++)
    {
        vectorTable[index] = (UINT16)ExceptionAll;
    }

    /* Set the interrupt vector with flash interrupt service function */
    vectorTable[0x5C] = (UINT16)FSL_ISR_Handler;

    /* Set the vector table base address to IVBR */
    REG_WRITE((SSD_MCU_REGISTER_BASE + S12X_INT_REGISTER_OFFSET + \
               INT_IVBR_OFFSET),0x30);

    /* Clear I bit in CCR */
    asm{
        CLI
    }
}
/************************************************************************
*
*  Function Name    : main
*  Description      : Entry point for Main().
*  Arguments        : void
*  Return Value     : void
*
*************************************************************************/

void main(void)
{
    UINT16 returnCode;
    UINT16 readAddr;
    UINT16 erasingCycles;
    UINT16 temp[EED_DATA_VALUE_SIZE/EED_MIN_PROG_SIZE] = {0,0,0};
    UINT8 i,j;

    /* If the Macro CALLBACK_ENABLE is TRUE set CallBack */
    #if(CALLBACK_ENABLE == TRUE)
     CallBack = CallBackFunc;
    #endif
    
    /* Enable the MCU interrupt */
    INT_Init();

    /**************************************************************************/
    /* This block of code has been  provided to simulate the condition of first
    time usage of flash for emulation. For continue usage comment this portion
    and run the demo again */

    /* Initialise the Flash clock */
    returnCode = FlashInit();
    if ( EED_OK != returnCode )
    {
        ErrorTrap();
    }

    /* This erases the D-Flash sectors used for EED. The entire emulated EEPROM
       from EED_FLASH_START_ADDRESS to EED_FLASH_END_ADDRESS is erased. */
    asm BGND;                   
    /* User breakpoint1 - the function below will erase the D-flash */  
    returnCode = FSL_DeinitEeprom();
    
    if (EED_OK != returnCode)
    {
        ErrorTrap();
    }

    /* Wait until DeinitEeprom is done */
    while(BUSY == EE_Status)
    {
        FSL_Main();
    }
    /* Check if FSL_Main has completed execution successfully */
    if(FAIL == EE_Status)
    {
        /* Check the gEE_Error for the error code */
        ErrorTrap();
    }

    /*************************************************************************/

    /*************************************************************************
    * Scenario:
    * EED_FLASH_START_ADDRESS               = 0x4400
    * EED_SECTOR_SIZE                       = 0x0100
    * EED_ACTIVE_SECTOR_REQUIRED            = 0x02
    * EED_EXTRA_ACTIVE_SECTORS              = 0x00
    * EED_READY_SECTORS                     = 0x03
    * EED_SECTORS_ALLOTED                   = 0x05
    * EED_FLASH_END_ADDRESS                 = 0x48FF
    * EED_DATA_ID_SIZE                      = 0x02
    * EED_DATA_VALUE_SIZE                   = 0x02
    * EED_CACHETABLE_START_ADDRESS          = 0x3FD0
    * EED_MAX_CACHETABLE_ENTRY              = 0x08
    * EED_EEPROM_SIZE                       = 0x00FA (250d)
    * EED_MAX_RECORD_NUMBER                 = 0x7D (125d)
    *************************************************************************/

    /* This initializes the 2 sectors at location 0x4400 and 0x4500 to 'ACTIVE'
       and the remaining sectors 0x4600, 0x4700 and 0x4800 to 'ALTERNATIVE'.
       If EED_CACHETABLE_ENABLE is ON then the cache table entries are initialized to 0xFFFFFFFF (Address = 0x3FD0) */
       
    asm BGND;                        
    /* User breakpoint 2 - the function below will write FACF0000 to Active sector and FFFF0000 to alternative sectors */  
    returnCode = FSL_InitEeprom();   /* initilise EEPROM */
    /* Hit run to the next software breakpoint, where first record will be written */
    
    if (EED_OK != returnCode)
    {
        ErrorTrap();
    }
    /* Wait until InitEeprom is done */
    while(BUSY == EE_Status)
    {
        FSL_Main();
    }
    /* Check if FSL_Main has completed execution successfully */
    if(FAIL == EE_Status)
    {
        /* Check the gEE_Error for the error code */
        ErrorTrap();
    }

    /* This will write a data record with data ID = 0x01 and data value = 0x10
       in the first'ACTIVE' sector(Address = 0x4400).
       If EED_CACHETABLE_ENABLE is ON then the first cache table entry is modified
       to 0x4404 (Address = 0x3FD0) */
    for( i = 0;i < (EED_DATA_VALUE_SIZE/EED_MIN_PROG_SIZE) ; i++)
    {
        temp[i] = DATA_VALUE;
    }
    asm BGND;                
   /*software breakpoint 3 - the function below will write the first data record and ID*/
                                      
    returnCode = FSL_WriteEeprom(DATA_ID_ONE, temp);    
    if (EED_OK != returnCode)
    {
        ErrorTrap();
    }
    /* Wait until WriteEeprom is done */
    while(BUSY == EE_Status)
    {
        FSL_Main();
    }
    /* Check if FSL_Main has completed execution successfully */
    if(FAIL == EE_Status)
    {
        /* Check the gEE_Error for the error code */
        ErrorTrap();
    }
 
    /* This writes data records such that the entire 'ACTIVE' block is completely filled.
       The next write after the loop will cause a swap */
    
    asm BGND;
     /* software breakpoint 4 - the first record has been written and the function below will write the active sectors*/
     /* It will loop here until all the active sectors are filled*/
     
    for(i = DATA_ID_ONE ;i <= EED_MAX_RECORD_NUMBER; i++)
    {
        for( j = 0;j < (EED_DATA_VALUE_SIZE/EED_MIN_PROG_SIZE) ; j++)
        {
            temp[j] = i + DATA_VALUE;
        }
        returnCode = FSL_WriteEeprom(i, temp);
        if (EED_OK != returnCode)
        {
            ErrorTrap();
        }
        /* Wait until WriteEeprom is done */
        while(BUSY == EE_Status)
        {
            FSL_Main();
        }
        /* Check if FSL_Main has completed execution successfully */
        if(FAIL == EE_Status)
        {
            /* Check the gEE_Error for the error code */
            ErrorTrap();
        }
    }
   
    asm BGND;
     /* software breakpoint 5 - Active sectors filled and the function below will swap first active for an alternative*/
    /* As the 'ACTIVE' sectors are completely filled the following write will cause a swap.
       The 'ALTERNATIVE' sector at 0x4600 will be made 'ACTIVE' and the oldest 'ACITVE' sector at 0x4400 will be erased and made 'ALTERNATIVE'*/
       
    for( i = 0;i < (EED_DATA_VALUE_SIZE/EED_MIN_PROG_SIZE) ; i++)
    {
        temp[i] = DATA_VALUE_TEN;
    }
    returnCode = FSL_WriteEeprom(DATA_ID_TEN, temp);
    if (EED_OK != returnCode)
    {
        ErrorTrap();
    }
    /* Wait until WriteEeprom is done */
    while(BUSY == EE_Status)
    {
        FSL_Main();
    }
    /* Check if FSL_Main has completed execution successfully */
    if(FAIL == EE_Status)
    {
        /* Check the gEE_Error for the error code */
        ErrorTrap();
    }
    
     asm BGND;
     /* software breakpoint 6 - Active sector swapped. The code below will read and then re-program the D-flash. */
    /* This reads the data with Data ID 0x01. The record is read from the cache table if EED_CACHETABLE_ENABLE is ON */
    
    returnCode=FSL_ReadEeprom(DATA_ID_ONE, &readAddr);
    if (EED_OK != returnCode)
    {
       ErrorTrap();
    }
    else
    {
        for( i = 0;i < EED_DATA_VALUE_SIZE ; i+=EED_MIN_PROG_SIZE)
        {
            if((UINT16)(DATA_VALUE+1) == READ_DFLASH16(readAddr + i))
            {
                /* correct value read */
            }
            else
            {
                ErrorTrap();
            }
       }
    }

    /* This reads the data with Data ID 0x10. The record is read from the Flash */
    returnCode=FSL_ReadEeprom(DATA_ID_TEN, &readAddr);
    if (EED_OK != returnCode)
    {
       ErrorTrap();
    }
    else
    {
        for( i = 0;i < EED_DATA_VALUE_SIZE ; i+=EED_MIN_PROG_SIZE)
        {
            if((UINT16)(DATA_VALUE_TEN) == READ_DFLASH16(readAddr + i))
            {
                /* correct value read */
            }
            else
            {
                ErrorTrap();
            }
        }
    }

    /* This returns the erasing cycles of the current Active sector. This returns
       the erasing cycles of sector 0x4600 which is 0x00. */
    returnCode = FSL_ReportEepromStatus(&erasingCycles);
    if (EED_OK != returnCode)
    {
        ErrorTrap();
    }

    /* This erases the D-Flash sectors used for EED. The entire emulated EEPROM
       from EED_FLASH_START_ADDRESS to EED_FLASH_END_ADDRESS is erased. */
    returnCode = FSL_DeinitEeprom();
    if (EED_OK != returnCode)
    {
        ErrorTrap();
    }

    /* Wait until DeinitEeprom is done */
    while(BUSY == EE_Status)
    {
        FSL_Main();
    }
    /* Check if FSL_Main has completed execution successfully */
    if(FAIL == EE_Status)
    {
        /* Check the gEE_Error for the error code */
        ErrorTrap();
    }
    
    while(1) 
    {
      asm NOP;
      asm BGND;
    }
    
}


