#include "Internal_FCL.h"
#include "r_typedefs.h"
#include "fcl_cfg.h"
#include "r_fcl_types.h"
#include "r_fcl.h"
#include "target.h"
#include "fcl_descriptor.h"
#include "fcl_user.h"

#define FCL_RAM_EXECUTION_AREA_SIZE 0x8000

#if R_FCL_COMPILER == R_FCL_COMP_GHS
    #pragma ghs startdata
    #pragma ghs section bss = ".FCL_RESERVED"
    #define R_FCL_NOINIT
#elif R_FCL_COMPILER == R_FCL_COMP_IAR
    #pragma segment = "FCL_RESERVED"
    #pragma location = "FCL_RESERVED"
    #define R_FCL_NOINIT __no_init
#elif R_FCL_COMPILER == R_FCL_COMP_REC
    #pragma section r0_disp32 "FCL_RESERVED"
    #define R_FCL_NOINIT
#endif

R_FCL_NOINIT uint8_t FCL_Copy_area[FCL_RAM_EXECUTION_AREA_SIZE];

#if R_FCL_COMPILER == R_FCL_COMP_GHS
    #pragma ghs section bss = default
    #pragma ghs enddata
#elif R_FCL_COMPILER == R_FCL_COMP_IAR
    /* location only for one function, so no default required */
#elif R_FCL_COMPILER == R_FCL_COMP_REC
    #pragma section default
#endif

#define REINITIALIZE_BUFFER     for (i = 0; i < sizeof (writeBuffer_u08); i++)          \
                                {                                                       \
                                    writeBuffer_u08[i] = 0xbb;                             \
                                }                                                       \
                                for (i = 0; i < (sizeof (readBuffer_u32) >> 2); i++)    \
                                {                                                       \
                                    readBuffer_u32[i]  = 0xaa;                          \
                                }

r_fcl_request_t     myRequest;
extern r_fcl_descriptor_t sampleApp_fclConfig_enu; /*!< FCL descriptor variable */

r_fcl_request_t     myRequest;
void FCL_Ctrl1 (void)
{
    //r_fcl_request_t     myRequest;
        r_fcl_status_t ret;
#if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER
        r_fcl_request_t mySecRequest;
#endif
    uint8_t             writeBuffer_u08[512];
    uint32_t            readBuffer_u32[8];
    uint16_t            i;

    #if (defined R_FCL_DEVICE_SPECIFIC_INIT)
        R_FCL_DEVICE_SPECIFIC_INIT
    #endif

    ret = R_FCL_Init (&sampleApp_fclConfig_enu);
    if (R_FCL_OK == ret)
    {
        ret = R_FCL_CopySections ();
        /***************************************************************************************************
         * NOTICE!!!: For CC-RH (Renesas compiler)
         *   If you modify sample codes, and then the ".pcconst32" section may be created,
         *   you should also copy the ".pcconst32" section by yourself.
         ***************************************************************************************************/
    }


    REINITIALIZE_BUFFER;

    FCLUser_Open ();

    /* prepare environment */
    myRequest.command_enu = R_FCL_CMD_PREPARE_ENV;
    R_FCL_Execute (&myRequest);
    #if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER
        while (R_FCL_BUSY == myRequest.status_enu)
        {
            R_FCL_Handler ();
        }
    #endif
	if (R_FCL_OK != myRequest.status_enu)
    {
       while(1);// Error_Handle();
    }

    /* get block count */
    myRequest.command_enu   = R_FCL_CMD_GET_BLOCK_CNT;
    myRequest.bufferAdd_u32 = (uint32_t)&readBuffer_u32[0];
    R_FCL_Execute (&myRequest);
	if (R_FCL_OK != myRequest.status_enu)
    {
        while(1);// Error_Handle();//Error_Handle();
    }

    /* get block end address of block 2 */
    REINITIALIZE_BUFFER;
    myRequest.command_enu   = R_FCL_CMD_GET_BLOCK_END_ADDR;
    myRequest.bufferAdd_u32 = (uint32_t)&readBuffer_u32[0];
    myRequest.idx_u32       = 10;                   /* result: 0x5fff */
    R_FCL_Execute (&myRequest);
	if (R_FCL_OK != myRequest.status_enu)
    {
        while(1);// Error_Handle();Error_Handle();
    }

	myRequest.command_enu   =  R_FCL_CMD_DISABLE_LOCKBITS;
    R_FCL_Execute (&myRequest);
	if (R_FCL_OK != myRequest.status_enu)
    {
        while(1);// Error_Handle();Error_Handle();
    }
	
    /* erase block 10 and 11 */
    myRequest.command_enu = R_FCL_CMD_ERASE;
    myRequest.idx_u32     = 10;                   
    myRequest.cnt_u16     = 1;
    R_FCL_Execute (&myRequest);
    #if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER
        while (R_FCL_BUSY == myRequest.status_enu)
        {
           while(1);// Error_Handle(); R_FCL_Handler ();
        }
    #endif
	if (R_FCL_OK != myRequest.status_enu)
    {
       while(1);// Error_Handle(); Error_Handle();
    }

    /* write 512 bytes to address 0x4000 (start of block 2) */
    REINITIALIZE_BUFFER;
    myRequest.command_enu = R_FCL_CMD_WRITE;
    myRequest.bufferAdd_u32 = (uint32_t)&writeBuffer_u08[0];
    myRequest.idx_u32       = 0x20000;
    myRequest.cnt_u16       = 2;                    /* written bytes = 256 * cnt_u16 */
    R_FCL_Execute (&myRequest);
    #if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER
        while (R_FCL_BUSY == myRequest.status_enu)
        {
           while(1);// Error_Handle(); R_FCL_Handler ();
        }
    #endif
	if (R_FCL_OK != myRequest.status_enu)
    {
      while(1);// Error_Handle();  Error_Handle();
    }
    
    writeBuffer_u08[0] = 0u;
    writeBuffer_u08[1] = 0u;
    writeBuffer_u08[2] = 0u;
    writeBuffer_u08[3] = 0u;
    writeBuffer_u08[0] = *(uint8_t*)0x20000;
    writeBuffer_u08[1] = *(uint8_t*)0x20001;
    writeBuffer_u08[2] = *(uint8_t*)0x20002;
    writeBuffer_u08[3] = *(uint8_t*)0x20003;
	
    FCLUser_Close ();
} 


void Internal_FCL_OPEN(void)
{
    //r_fcl_status_t ret;
    //ret = R_FCL_Init (&sampleApp_fclConfig_enu);
    //if (R_FCL_OK == ret) 
    //{ 
    //    ret = R_FCL_CopySections ();
    //    if (R_FCL_OK == ret) 
    //    {
    //     //   FCLUser_Open ();
    //    }
    //}

    r_fcl_status_t ret;
#if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER
        r_fcl_request_t mySecRequest;
#endif
    uint8_t             writeBuffer_u08[512];
    uint32_t            readBuffer_u32[8];
    uint16_t            i;

    #if (defined R_FCL_DEVICE_SPECIFIC_INIT)
        R_FCL_DEVICE_SPECIFIC_INIT
    #endif

    ret = R_FCL_Init (&sampleApp_fclConfig_enu);
    if (R_FCL_OK == ret)
    {
        ret = R_FCL_CopySections ();
        /***************************************************************************************************
         * NOTICE!!!: For CC-RH (Renesas compiler)
         *   If you modify sample codes, and then the ".pcconst32" section may be created,
         *   you should also copy the ".pcconst32" section by yourself.
         ***************************************************************************************************/
    }


    REINITIALIZE_BUFFER;

    FCLUser_Open ();
}

void Internal_FCL_CLOSE(void)
{
    FCLUser_Close ();
}

void Internal_FCL_Init(void)
{
     /* prepare environment */
    myRequest.command_enu = R_FCL_CMD_PREPARE_ENV;
    R_FCL_Execute (&myRequest);
    #if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER
        while (R_FCL_BUSY == myRequest.status_enu)
        {
            R_FCL_Handler ();
        }
    #endif
	if (R_FCL_OK != myRequest.status_enu)
    {
       while(1);// Error_Handle();
    }
}

uint8_t Internal_FCL_Unlock(void)
{
    myRequest.command_enu   =  R_FCL_CMD_DISABLE_LOCKBITS;
    R_FCL_Execute (&myRequest);
	if (R_FCL_OK != myRequest.status_enu)
    {
        while(1);// Error_Handle();Error_Handle();
    }
    return myRequest.command_enu;
}

uint8_t Internal_FCL_Erase(uint32_t blockID)
{
    myRequest.command_enu = R_FCL_CMD_ERASE;
    myRequest.idx_u32     = blockID;                   
    myRequest.cnt_u16     = 1u;
    R_FCL_Execute (&myRequest);
    #if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER
    while (R_FCL_BUSY == myRequest.status_enu)
    {
        while(1);// Error_Handle(); R_FCL_Handler ();
    }
    #endif
    if (R_FCL_OK != myRequest.status_enu)
    {
        while(1);// Error_Handle(); Error_Handle();
    }
    //Internal_FCL_CLOSE();
    return myRequest.command_enu;
}

uint8_t Internal_FCL_Write(uint32_t address, uint8_t pbuf [], uint16_t length)
{
    myRequest.command_enu = R_FCL_CMD_WRITE;
    myRequest.bufferAdd_u32 = (uint32_t)&pbuf[0];
    myRequest.idx_u32       = address;
    myRequest.cnt_u16       = length;                    /* written bytes = 256 * cnt_u16 */
    R_FCL_Execute (&myRequest);
    #if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER
        while (R_FCL_BUSY == myRequest.status_enu)
        {
           while(1);// Error_Handle(); R_FCL_Handler ();
        }
    #endif
	if (R_FCL_OK != myRequest.status_enu)
    {
      while(1);// Error_Handle();  Error_Handle();
    }
    return myRequest.command_enu;
}

uint32_t Internal_FCL_Read32(uint32_t address)
{
    return *((uint32_t*)address);
}


void OptionByte_Handle(void)
{

// 
	uint32_t u32OPData[16U];
	r_fcl_request_t fclRequestCmd;
// 
	myRequest.command_enu = R_FCL_CMD_GET_OPB;
	myRequest.bufferAdd_u32 = (uint32_t)&u32OPData[0];
	R_FCL_Execute(&myRequest);
    if (R_FCL_OK != myRequest.status_enu)
    {
        while(1);// Error_Handle(); Error_Handle();
    }
	if ((u32OPData[0] != 0xBAA7FDCFU)||(u32OPData[1U] != 0xFFFFFDFFU))
	{                 
		u32OPData[0U] = 0xBAA7FDCFU;
		u32OPData[1U] = 0xFFFFFDFFU;
		u32OPData[2U] = 0xFFFFFFFFU;
		u32OPData[3U] = 0xFFFFFFFFU;
		u32OPData[4U] = 0xFFFFFFFFU;
		u32OPData[5U] = 0xFFFFFFFFU;
		u32OPData[6U] = 0xFFFFFFFFU;
		u32OPData[7U] = 0xFFFFFFFFU;
		myRequest.command_enu = R_FCL_CMD_SET_OPB;
		myRequest.bufferAdd_u32 = (uint32_t)&u32OPData[0];
		R_FCL_Execute(&myRequest);
        if (R_FCL_OK != myRequest.status_enu)
        {
            while(1);// Error_Handle(); Error_Handle();
        }
	}
}
