//###########################################################################
// FILE:   flash_programming_cpu01.c
// TITLE:  Flash Programming Example for F2837xS.
//
//! \addtogroup cpu01_example_list
//! <h1> Flash Programming </h1>
//!
//! This example demonstrates F021 Flash API usage to program 
//! Flash Bank 0 on F2837xS.
//
//###########################################################################
// $TI Release: F2837xS Support Library v180 $
// $Release Date: Fri Nov  6 16:27:58 CST 2015 $
// $Copyright: Copyright (C) 2014-2015 Texas Instruments Incorporated -
//             http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################

#include "F28x_Project.h"     // Device Headerfile and Examples Include File

#include <string.h>

//Include Flash API example header file
#include "flash_programming_c28.h"

//*****************************************************************************
// FILE Flash API include file
//*****************************************************************************
#include "F021_F2837xD_C28x.h"

//Data/Program Buffer used for testing the flash API functions
//#define  WORDS_IN_FLASH_BUFFER    0xFF  // Programming data buffer, words
#define  WORDS_IN_FLASH_BUFFER    0x1F  // Programming data buffer, words
#define PUMPREQUEST *(unsigned long*)(0x00050024)


//#define Flash_Start_Addree

//uint16   Buffer[WORDS_IN_FLASH_BUFFER + 1];
//uint32   *Buffer32 = (uint32 *)Buffer;

//uint8  Reci_Buffer[WORDS_IN_FLASH_BUFFER + 1];
//uint16   *Reci_Buffer32;

//*****************************************************************************
// Prototype of the functions used in this example
//*****************************************************************************
void Example_Error(Fapi_StatusType status);
void Example_Done(void);
void Example_CallFlashAPI(void);


#pragma CODE_SECTION(Flash_Read, "ramfuncs");
void Flash_Read(uint16 *Reci_Buffer)
{
	uint8 i;

	uint16 *Reci_Buffer32=(uint16 *)Bzero_SectorAB_start;


	//uint16 Reci_Data;

	for(i=0;i<=WORDS_IN_FLASH_BUFFER;i++){
		//Reci_Data=*(Reci_Buffer32+i);
		//*(Reci_Buffer+i)=Reci_Data;
		*(Reci_Buffer++)=*(Reci_Buffer32++);
	}
}

//*****************************************************************************
//  Example_CallFlashAPI
//
//  This function will interface to the flash API.
//  Flash API functions used in this function are executed from RAM
//*****************************************************************************
#pragma CODE_SECTION(Flash_Write, "ramfuncs");
void Flash_Write(Uint16 *Buffer)
{
    uint32 u32Index = 0;
    uint16 i = 0;

    uint32   *Buffer32 = (uint32 *)Buffer;

    Fapi_StatusType            oReturnCheck;
    volatile Fapi_FlashStatusType       oFlashStatus;
    Fapi_FlashStatusWordType   oFlashStatusWord;


    EALLOW;

    // Disable ECC.  ECC does not have to be disabled to do FSM operations like
    // program and erase.
    // However, on Sonata Rev. 0 silicon, due to an OTP ECC errata,
    // disable ECC to avoid ECC errors while using Flash API functions that
    // read TI-OTP

    PUMPREQUEST = 0x5A5A0001;

    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    // Note that the FMC1 register base address is passed as the parameter
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_W1_BASE_ADDRESS, 200);

    if(oReturnCheck != Fapi_Status_Success)
    {
        //
        // Check Flash API documentation for possible errors
        //
        Example_Error(oReturnCheck);
    }

    //
    // Fapi_setActiveFlashBank function sets the Flash bank1 and FMC1 for
    // further Flash operations to be performed on the bank1.
    // Note that the parameter passed is Fapi_FlashBank1 since FMC0 register
    // base address is passed to Fapi_initializeAPI()
    //
  /*  oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank1);
    if(oReturnCheck != Fapi_Status_Success)
    {
        //
        // Check Flash API documentation for possible errors
        //
        Example_Error(oReturnCheck);
    }
*/


    //
    // Erase Sector Z
    //
    oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
                                                 (uint32 *)Bzero_SectorAB_start);

    //
    // Wait until FSM is done with erase sector operation
    //
    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}

    //
    // Verify that SectorP is erased.  The Erase step itself does a verify as
    // it goes.  This verify is a 2nd verification that can be done.
    //
    oReturnCheck = Fapi_doBlankCheck((uint32 *)Bzero_SectorAB_start,
    								 Bzero_16KSector_u32length,
                                     &oFlashStatusWord);

    if(oReturnCheck != Fapi_Status_Success)
    {
        //
        // Check Flash API documentation for possible errors
        // If Erase command fails, use Fapi_getFsmStatus() function
        // to get the FMSTAT register contents
        // to see if any of the EV bit, ESUSP bit, CSTAT bit or VOLTSTAT
        // bit is set (Refer to API documentation for more details)
        //
        Example_Error(oReturnCheck);
    }



    EALLOW;
    Flash1EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
 //   EDIS;

    EALLOW;


    for(i=0, u32Index = Bzero_SectorAB_start;
       (u32Index < (Bzero_SectorAB_start + WORDS_IN_FLASH_BUFFER))
       && (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
        oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,Buffer+i,
                       8,
                       0,
                       0,
					   Fapi_DataOnly);

        while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

        if(oReturnCheck != Fapi_Status_Success)
        {
        // Check Flash API documentation for possible errors
        Example_Error(oReturnCheck);
        }

        // Read FMSTAT register contents to know the status of FSM after
        // program command for any debug
        oFlashStatus = Fapi_getFsmStatus();

        // Verify the values programmed.  The Program step itself does a verify
        // as it goes.  This verify is a 2nd verification that can be done.
        oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
                       4,
                       Buffer32+(i/2),
                       &oFlashStatusWord);
        if(oReturnCheck != Fapi_Status_Success)
        {
            // Check Flash API documentation for possible errors
            Example_Error(oReturnCheck);
        }
    }



    // Enable ECC
    Flash1EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;

    PUMPREQUEST = 0x5A5A0000;

    EDIS;

    EDIS;

    // Example is done here
    //Example_Done();
}

//******************************************************************************
// For this example, if an error is found just stop here
//******************************************************************************
#pragma CODE_SECTION(Example_Error,"ramfuncs");
void Example_Error(Fapi_StatusType status)
{
    //  Error code will be in the status parameter
        __asm("    ESTOP0");
}

//******************************************************************************
//  For this example, once we are done just stop here
//******************************************************************************
#pragma CODE_SECTION(Example_Done,"ramfuncs");
void Example_Done(void)
{
    __asm("    ESTOP0");
}
