#include "Internal_EEPROM.h"
#include "R_TypeDefs.h"
#include "R_FDL.h"
#include "FDL_Descriptor.h"
#include "R_EEL.h"
#include "EEL_Descriptor.h"
#include "target.h"
#include "fdl_user.h"
#include "rh850_macros.h"
r_eel_status_t reqStat;

// demo code
    // for ( int i = 1; i < 65; i++ )
    // {

    //     for ( int i = 0; i < 128; i++ )
    //     {
    //         read [ i ]  = 0;
    //         write [ i ] = i;
    //     }
    //     Internal_EEL_Write(i, write, 64);
    //     Internal_EEL_Read(i, read, 64);
    // }


extern r_eel_status_t EX_EE_INIT(void);
extern void SampleApp_EEL_HdrLoop( r_eel_request_t *req );
extern void SampleApp_EEL_ErrorHdr( r_eel_status_t stat );

void Internal_EEPROM_OPEN(void)
{
    FDL_Open( );
}

void Internal_EEPROM_CLOSE(void)
{
    FDL_Close( );
}

void Internal_EEL_Init(void)
{
    r_eel_request_t       myReq;
    r_eel_driver_status_t driverStatus;
    uint32_t              i;
    reqStat = EX_EE_INIT( );
    if ( R_EEL_ERR_POOL_INCONSISTENT == reqStat )
    {
        myReq.command_enu = R_EEL_CMD_FORMAT;
        R_EEL_Execute(&myReq);
        SampleApp_EEL_HdrLoop(&myReq);

        /* Format procedure ends with EEL re-init */
        reqStat = EX_EE_INIT( );
    }
    SampleApp_EEL_ErrorHdr(reqStat);
    /* ------------------------------------------------------------------------------------------
        Wait for fully operational and access unlock
       ------------------------------------------------------------------------------------------ */
    do
    {
        R_EEL_Handler( );
        R_EEL_GetDriverStatus(&driverStatus);
    }
    /* Wait until the system is completely up and running (or error) */
    while ( R_EEL_OPERATION_STARTUP == driverStatus.operationStatus_enu );
}

r_eel_status_t Internal_EEL_Write(uint16_t blockID, uint8_t pbuf [], uint32_t length)
{
    r_eel_request_t myReq;
    disable_interrupt();
    Internal_EEPROM_OPEN();
    Internal_EEL_Init();
    myReq.address_pu08   = ( uint8_t * )(&pbuf [ 0 ]);
    myReq.identifier_u16 = blockID;
    myReq.command_enu    = R_EEL_CMD_WRITE;
    R_EEL_Execute(&myReq);
    SampleApp_EEL_HdrLoop(&myReq);
    Internal_EEL_DEINIT();
    Internal_EEPROM_CLOSE();
    enable_interrupt();
    return myReq.status_enu;
}

r_eel_status_t Internal_EEL_Read(uint8_t blockID, uint8_t pbuf [], uint32_t length)
{
    r_eel_request_t myReq;
    disable_interrupt();
    Internal_EEPROM_OPEN();
    Internal_EEL_Init();
    myReq.address_pu08   = ( uint8_t * )(&pbuf [ 0 ]);
    myReq.identifier_u16 = blockID;
    myReq.length_u16     = length;
    myReq.offset_u16     = 0x00u;
    myReq.command_enu    = R_EEL_CMD_READ;
    R_EEL_Execute(&myReq);
    SampleApp_EEL_HdrLoop(&myReq);
    Internal_EEL_DEINIT();
    Internal_EEPROM_CLOSE();
    enable_interrupt();
    return myReq.status_enu;
}

void Internal_EEL_DEINIT(void)
{
    r_eel_driver_status_t driverStatus;

    reqStat = R_EEL_ShutDown( );
    SampleApp_EEL_ErrorHdr(reqStat);

    do
    {
        R_EEL_Handler( );
        R_EEL_GetDriverStatus(&driverStatus);
    } while ( R_EEL_OPERATION_PASSIVE != driverStatus.operationStatus_enu );

    /* Error check of startup processing (with and without Format) */
    SampleApp_EEL_ErrorHdr(driverStatus.backgroundStatus_enu);
}
