#include "r_typedefs.h"
#include "Internal_Flash.h"
#include "Emulated_EEPROM.h"
#include "Emulated_EEPROM_Access.h"
#include "r_fdl_types.h"

/****************************************************************************
 *   !!! The following code should be generated by configuration tool !!!   *
****************************************************************************/
#define   EEPROM_BLOCK0_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_UDS_FLAG_SIZE)
uint32_t g_u32EEPROMBlock0Buffer[EEPROM_BLOCK0_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK1_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_UDS_S27_SIZE)
uint32_t g_u32EEPROMBlock1Buffer[EEPROM_BLOCK1_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK2_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_UDS_S2E0_SIZE)
uint32_t g_u32EEPROMBlock2Buffer[EEPROM_BLOCK2_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK3_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_UDS_S2E_SIZE)
uint32_t g_u32EEPROMBlock3Buffer[EEPROM_BLOCK3_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK4_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_UDS_CONFIG_SIZE)
uint32_t g_u32EEPROMBlock4Buffer[EEPROM_BLOCK4_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK5_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_UDS_DTC_SIZE)
uint32_t g_u32EEPROMBlock5Buffer[EEPROM_BLOCK5_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK6_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_ODO_SIZE)
uint32_t g_u32EEPROMBlock6Buffer[EEPROM_BLOCK6_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK7_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_ODO_STAMP_SIZE)
uint32_t g_u32EEPROMBlock7Buffer[EEPROM_BLOCK7_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK8_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_TRIP_STAMP_SIZE)
uint32_t g_u32EEPROMBlock8Buffer[EEPROM_BLOCK8_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK9_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_SERVICE_INFO_SIZE)
uint32_t g_u32EEPROMBlock9Buffer[EEPROM_BLOCK9_BUFFER_SIZE / 4U];

#define   EEPROM_BLOCK10_BUFFER_SIZE         (EEPROM_BLOCK_CTRL_BYTE_SIZE + EEPROM_BLOCK_EOL_K_LINE_SIZE)
uint32_t g_u32EEPROMBlock10Buffer[EEPROM_BLOCK10_BUFFER_SIZE / 4U];

static const EEPROM_Block_st_t g_stEEPROMBlockTable[] =
{
    /* u32StartAddr   u32EndAddr    u32DataSize                pu32DataBuffer */
    {0xFF200000UL,    0xFF20007FUL, EEPROM_BLOCK0_BUFFER_SIZE, g_u32EEPROMBlock0Buffer,},   /*EEPROM_BLOCK_UDS_FLAG*/
    {0xFF200080UL,    0xFF2000FFUL, EEPROM_BLOCK1_BUFFER_SIZE, g_u32EEPROMBlock1Buffer,},   /*EEPROM_BLOCK_UDS_S27*/
    {0xFF200100UL,    0xFF2002FFUL, EEPROM_BLOCK2_BUFFER_SIZE, g_u32EEPROMBlock2Buffer,},   /*EEPROM_BLOCK_UDS_S2E0*/
    {0xFF200300UL,    0xFF2004FFUL, EEPROM_BLOCK3_BUFFER_SIZE, g_u32EEPROMBlock3Buffer,},   /*EEPROM_BLOCK_UDS_S2E*/
    {0xFF200500UL,    0xFF20057FUL, EEPROM_BLOCK4_BUFFER_SIZE, g_u32EEPROMBlock4Buffer,},   /*EEPROM_BLOCK_UDS_CONFIG*/
    {0xFF200580UL,    0xFF20067FUL, EEPROM_BLOCK5_BUFFER_SIZE, g_u32EEPROMBlock5Buffer,},   /*EEPROM_BLOCK_UDS_DTC*/
    {0xFF200680UL,    0xFF200A7FUL, EEPROM_BLOCK6_BUFFER_SIZE, g_u32EEPROMBlock6Buffer,},   /*EEPROM_BLOCK_ODO*/
    {0xFF200A80UL,    0xFF200F7FUL, EEPROM_BLOCK7_BUFFER_SIZE, g_u32EEPROMBlock7Buffer,},   /*EEPROM_BLOCK_ODO_STAMP*/
    {0xFF200F80UL,    0xFF20377FUL, EEPROM_BLOCK8_BUFFER_SIZE, g_u32EEPROMBlock8Buffer,},   /*EEPROM_BLOCK_TRIP_STAMP*/
    {0xFF203780UL,    0xFF2037FFUL, EEPROM_BLOCK9_BUFFER_SIZE, g_u32EEPROMBlock9Buffer,},   /*EEPROM_BLOCK_SERVICE_INFO*/
    {0xFF203800UL,    0xFF203940UL, EEPROM_BLOCK10_BUFFER_SIZE, g_u32EEPROMBlock10Buffer,}, /*EEPROM_BLOCK_EOL_K_LINE*/
};

/****************************************************************************
 *             !!!          End of code generation          !!!             *
****************************************************************************/

EEPROM_Block_Access_st_t g_stEEPROMBlockAccess[EEPROM_TOTAL_BLOCK_NUM];

void EEPROM_Init(void)
{
    EEPROM_Media_Access_st_t stFlashAccessFunc;

    TYW_FDL_Init();

    stFlashAccessFunc.pfnMemErase    = TYW_FDL_Erase;//Int_Data_Flash_Erase;
    stFlashAccessFunc.pfnMemBlankChk = TYW_FDL_Blank_Check;//Int_Data_Flash_Blank_Check;
    stFlashAccessFunc.pfnMemRead     = TYW_FDL_Flash_Read;//Int_Data_Flash_Read;
    stFlashAccessFunc.pfnMemWrite    = TYW_FDL_Write;//Int_Data_Flash_Write;

    Int_Data_Flash_Register_P_E_Complete_Cb(EEPROM_Mem_Access_Complete_Callback);

    EEPROM_Access_Init( g_stEEPROMBlockTable,
                        g_stEEPROMBlockAccess,
                        &stFlashAccessFunc,
                        EEPROM_TOTAL_BLOCK_NUM);
}

EEPROM_Status_en_t EEPROM_Get_Status(void)
{
    EEPROM_Status_en_t enStatus;

    if (EEPROM_Access_Busy())
    {
        enStatus = EEPROM_STAT_BUSY;
    }
    else
    {
        enStatus = EEPROM_STAT_IDLE;
    }

    return enStatus;
}

EEPROM_Block_Status_en_t EEPROM_Get_Block_Status(uint16_t u16BlockID)
{
    uint8_t u8BlockStatus;
    EEPROM_Block_Status_en_t enStatus;

    u8BlockStatus = EEPROM_Block_Access_Status(u16BlockID);
    if (u8BlockStatus == EEPROM_BLOCK_BLANK)
    {
        enStatus = EEPROM_STAT_BLANK;
    }
    else if (u8BlockStatus == EEPROM_BLOCK_ACTIVE)
    {
        enStatus = EEPROM_STAT_ACTIVE;
    }
    else
    {
        enStatus = EEPROM_STAT_ERROR;
    }

    return enStatus;
}

EEPROM_RW_Result_en_t EEPROM_Read_Data(uint16_t u16BlockID, uint32_t u32Data[], uint16_t u16Len)
{
    uint8_t u8Error;
    EEPROM_RW_Result_en_t enResult;

    u8Error = EEPROM_Read_Block_Data(u16BlockID, u32Data, u16Len);
    if (u8Error)
    {
        enResult = EEPROM_RW_FAIL;
    }
    else
    {
        enResult = EEPROM_RW_PASS;
    }

    return enResult;
}

EEPROM_RW_Result_en_t EEPROM_Write_Data(uint16_t u16BlockID, uint32_t u32Data[], uint16_t u16Len)
{
    uint8_t u8Error;
    EEPROM_RW_Result_en_t enResult;

    u8Error = EEPROM_Write_Block_Data(u16BlockID, u32Data, u16Len);
    if (u8Error)
    {
        enResult = EEPROM_RW_FAIL;
    }
    else
    {
        enResult = EEPROM_RW_PASS;
    }

    return enResult;
}

