/*******************************************************************************
** Copyright (c) 2022 KPTL
**
** This software is the property of KPTL.
** It can not be used, duplicated and/or distributed without the express
** permission of KPTL.
**
** -----------------------------------------------------------------------------
** File Name    : FlashToRam.c
** Module Name  : Flash-to-RAM BSW Source File
** -----------------------------------------------------------------------------
**
** Description : To implement routines that load code that operates on Flash
**               into RAM memory
**
** This file must exclusively contain information needed to
** use this component.
**
********************************************************************************
** R E V I S I O N  H I S T O R Y
********************************************************************************
** V01.00 24/02/2022    Initial Creation
********************************************************************************/
#include <string.h>

#include "system.h"
#include "sys_core.h"

#include "SysUtil.h"

#include "FlashIntf.h"
#include "FlashIntf_Cfg.h"
#include "FlashToRam.h"


#ifdef FLASH_MOVE_TO_RAM

extern uint32_t RamfuncsLoadStart;
extern uint32_t RamfuncsLoadSize;
extern uint32_t RamfuncsRunStart;

void FlashToRam_CopyCode(void)
{
	/* Copy functions from Flash To RAM */
	memcpy((void *)&RamfuncsRunStart, (const void *)&RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

	/* Ensure pipeline consistency (recommended) */
    /* Flush the processor pipeline */
    SysUtil_flushPipeline();

	/* Disable Interrupts */
	_disable_IRQ_interrupt_();

	/* Set the fallback power mode for the Flash Banks */
	flashWREG->FBFALLBACK = ((flashWREG->FBFALLBACK & FLASH_FBFALLBACK_MASK) | FLASH_FBFALLBACK);

	/* Set the Flash Charge Pump Fallback Power Mode */
	flashWREG->FPAC1 = ((flashWREG->FPAC1 & FLASH_FPAC1_MASK) | FLASH_FPAC1);

	/* Disable pipeline mode and address setup wait state and set wait states for Flash Operation */
	flashWREG->FRDCNTL = ((flashWREG->FRDCNTL & FLASH_FRDCNTL_MASK) | ((uint32_t)FLASH_RWAIT << FLASH_RWAIT_SHIFT));

	/* Set wait states for FEE Operation */
	flashWREG->FSMWRENA = 0x5U;
	flashWREG->EEPROMCONFIG = ((flashWREG->EEPROMCONFIG & FLASH_EEPROMCONFIG_MASK) | ((uint32_t)FLASH_EWAIT << FLASH_EWAIT_SHIFT));
	flashWREG->FSMWRENA = 0x2U;

	/* Enable pipeline mode and and address setup wait state for Flash Operation */
	flashWREG->FRDCNTL |= FLASH_FRDCNTL;

	/* Enable Interrupts */
	_enable_interrupt_();
}

void SysUtil_flushPipeline(void)
{
    __asm(" dsb");      // Data Synchronization Barrier
    __asm(" isb");      // Instruction Synchronization Barrier
}
#endif
