
// clock configuration
#define DEVICE_SETCLOCK_CFG         (SYSCTL_OSCSRC_XTAL | SYSCTL_IMULT(8) | \
                                     SYSCTL_FMULT_0 | SYSCTL_SYSDIV(1) |    \
                                     SYSCTL_PLL_ENABLE)
									 
// flash frequency and wait states
#define SYSCLK_FREQ_MHz				192
#define FLASH_WAITSTATES            3

// 
// Hardware inizializion
//
void HW_Init(void)
{
    bool    clockRunning;

    clockRunning = false;
	
    SysCtl_disableWatchdog();
	SysCtl_setWatchdogPrescaler(SYSCTL_WD_PRESCALE_64);

    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t) &RamfuncsLoadSize);
    Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, FLASH_WAITSTATES);

    // initialize clock
    while (!clockRunning)
    {
        clockRunning = SysCtl_setClock(DEVICE_SETCLOCK_CFG);

        if (!clockRunning)
        {
            ASSERT(0);
            SysCtl_resetMCD();
        }
    }

    ASSERT(SysCtl_getClock(OSCSRC_FREQ) == SYSCLK_FREQ);

	// other initializations...
}

//
//	Flash API initialization
//
void FlashProg_Init(void)
{
    Fapi_StatusType     fapiSts;

    // si inzializzano le informazioni locali al modulo
    memset(&info, 0, sizeof(info));

    // Give pump ownership to FMC0(Bank0)
    PUMPREQUEST = 0x5A5A0002;

    fapiSts = Fapi_initializeAPI(F021_CPU0_W0_BASE_ADDRESS, SYSCLK_FREQ_MHz);

    if (fapiSts == Fapi_Status_Success)
    {
        fapiSts = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    }

    ASSERT(fapiSts == Fapi_Status_Success);
}

//
//	ECC calculation and write
//
short FlashProg_WriteEcc(uint32_t addr)
{
    uint64_t                data;
    uint16_t                ecc;
    Fapi_StatusType         fapiSts;
    Fapi_FlashStatusType    fapiFlashSts;
    int16_t                 rv;

    data = *(uint64_t *) addr;

    ecc = Fapi_calculateEcc((addr << 1), data);

    SysCtl_disableWatchdog();

    fapiSts = Fapi_issueProgrammingCommand((uint32_t *) addr, NULL, 0, &ecc, 1, Fapi_EccOnly);

    while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

    SysCtl_enableWatchdog();

    if (fapiSts == Fapi_Status_Success)
    {
        fapiFlashSts = Fapi_getFsmStatus();

        rv = 0;
    }

    ASSERT(fapiFlashSts == 0);
    ASSERT(fapiSts == Fapi_Status_Success);
    return rv;
}

//
//	Routine to calculate and program ECC on the entire code address space
//
static short CalculateAndWriteEcc(void)
{
    uint32_t        addr;
    int16_t         rv;

    addr = 0x88000;
    rv = 0;

    while ((addr <=  0x97FFF) && (rv == 0))
    {
        rv = FlashProg_WriteEcc(addr);

        addr = addr + 4;
    }

    return rv;
}

