/**********************************************************************************************************************
    Program Name    : Sample program for EEPROM Emulation Software (EES)
    
    File Name       : sample_control_ees.c
    Program Version : V1.00.00
    Device(s)       : microcontroller
    Description     : Sample program for EES
**********************************************************************************************************************/

/**********************************************************************************************************************
 Includes   <System Includes> , "Project Includes"
 *********************************************************************************************************************/
#include "r_ees_api.h"

#include "sample_control_ees.h"
#include "sample_ees_defines.h"
#include "sample_config.h"
#include "r_ees_user_types.h"
#include "stdio.h"

/**********************************************************************************************************************
 Exported global variables
 *********************************************************************************************************************/

/**********************************************************************************************************************
 Static global variables
 *********************************************************************************************************************/
#define  SAMPLE_START_SECTION_SMP_VAR
#include "sample_ees_memmap.h"
/* Write buffer for EES variables */
/* The number of array elements depends on the maximum size of EES variables */
__near uint8_t sg_ar_u08_write_data[255u];
#define  SAMPLE_END_SECTION_SMP_VAR
#include "sample_ees_memmap.h"

#define  SAMPLE_START_SECTION_SMP_VAR
#include "sample_ees_memmap.h"
/* Read buffer for EES variables */
/* The number of array elements depends on the maximum size of EES variables */
__near uint8_t sg_ar_u08_read_data[255u];
#define  SAMPLE_END_SECTION_SMP_VAR
#include "sample_ees_memmap.h"

#define  SAMPLE_START_SECTION_SMP_VAR
#include "sample_ees_memmap.h"
static __near st_ees_request_t sg_st_ees_request;
#define  SAMPLE_END_SECTION_SMP_VAR
#include "sample_ees_memmap.h"
#include "r_ees_descriptor.h"

extern const uint8_t g_ar_u08_ees_descriptor[R_EES_VALUE_U08_VAR_NO + 2u];

uint8_t Write_Data(uint8_t Type_ID,uint8_t * DataBuff,uint8_t DataNum)
{
    e_ees_ret_status_t l_e_ees_ret_value;
    uint8_t ret = 0xFFU;
    
    do
    {
        /* Set parameters for WRITE command */
        sg_st_ees_request.np_u08_address = DataBuff;
        sg_st_ees_request.u08_identifier = Type_ID;
        sg_st_ees_request.e_command      = R_EES_ENUM_CMD_WRITE;
        
        R_EES_Execute(&sg_st_ees_request);/* Execute WRITE command */
        while (R_EES_ENUM_RET_STS_BUSY == sg_st_ees_request.e_status)/* Wait for the end of running command */
        {
            R_EES_Handler();/* It is possible to write the program for detecting timeout here as necessity requires */
        }
        
        l_e_ees_ret_value = sg_st_ees_request.e_status;
        
        /* Check returned status of the command */
        if (R_EES_ENUM_RET_STS_OK == l_e_ees_ret_value)
        {
            ret = 0;/* WRITE command was finished successfully */
        }
        else if (R_EES_ENUM_RET_ERR_POOL_FULL == l_e_ees_ret_value)
        {
            /******************************************************************************************************
             * REFRESH
             *****************************************************************************************************/
            sg_st_ees_request.e_command = R_EES_ENUM_CMD_REFRESH;/* Set parameters for REFRESH command */
            R_EES_Execute(&sg_st_ees_request);/* Execute REFRESH command */
            while (R_EES_ENUM_RET_STS_BUSY == sg_st_ees_request.e_status)/* Wait for the end of running command */
            {
                R_EES_Handler(); /* It is possible to write the program for detecting timeout here as necessity requires */
            }
            
            l_e_ees_ret_value = sg_st_ees_request.e_status;
            
            /* Check returned status of the command */
            if (R_EES_ENUM_RET_STS_OK != l_e_ees_ret_value)
            {
                ret = 2;/* REFRESH error handling */
            }
        }
        else
        {
            ret = 1;/* WRITE error handling */
        }
    } 
    while (R_EES_ENUM_CMD_REFRESH == sg_st_ees_request.e_command);
        
    return ret;
}


uint8_t Read_Data(uint8_t Type_ID,uint8_t * DataBuff,uint8_t DataNum)
{
    e_ees_ret_status_t l_e_ees_ret_value;
    uint8_t ret = 0xFFU;
    
    /* Set parameters for READ command */
    sg_st_ees_request.np_u08_address = DataBuff;
    sg_st_ees_request.u08_identifier = Type_ID;
    sg_st_ees_request.e_command      = R_EES_ENUM_CMD_READ;
    
    R_EES_Execute(&sg_st_ees_request);/* Execute READ command */
    
    while (R_EES_ENUM_RET_STS_BUSY == sg_st_ees_request.e_status)/* Wait for the end of running command */
    {
        R_EES_Handler();/* It is possible to write the program for detecting timeout here as necessity requires */
    }
    
    l_e_ees_ret_value = sg_st_ees_request.e_status;
    
    if (R_EES_ENUM_RET_STS_OK == l_e_ees_ret_value)
    {
        ret = 0;/* READ command was finished successfully */
    }
    else
    {
        ret = 1;/* READ error handling */
    }
    
    return ret;
}


/**********************************************************************************************************************
 * Function name : Sample_EES_Control
 *********************************************************************************************************************/
#define  SAMPLE_START_SECTION_SMP_EES
#include "sample_ees_memmap.h"
/*********************************************************************************************************************/
/**
 *  Sample function for EES control.
 *  
 *  @param[in]      -
 *  @return         Execution result status
 *                  - R_EES_ENUM_RET_STS_OK                : No error occurred
 *                  - R_EES_ENUM_RET_STS_BUSY              : Request is under processing
 *                  - R_EES_ENUM_RET_ERR_CONFIGURATION     : Invalid EES configuration
 *                  - R_EES_ENUM_RET_ERR_INITIALIZATION    : R_EES_Init, R_EES_Open missing
 *                  - R_EES_ENUM_RET_ERR_ACCESS_LOCKED     : STARTUP missing or fatal operation error
 *                  - R_EES_ENUM_RET_ERR_PARAMETER         : Wrong parameter (wrong command or identifier)
 *                  - R_EES_ENUM_RET_ERR_WEAK              : Weak error in the active block
 *                  - R_EES_ENUM_RET_ERR_REJECTED          : Another request already under processing
 *                  - R_EES_ENUM_RET_ERR_NO_INSTANCE       : No instance found (variable never written)
 *                  - R_EES_ENUM_RET_ERR_POOL_FULL         : No space for writing data
 *                  - R_EES_ENUM_RET_ERR_POOL_INCONSISTENT : No active block found within EES pool
 *                  - R_EES_ENUM_RET_ERR_POOL_EXHAUSTED    : EES pool is too small for correct operation
 *                  - R_EES_ENUM_RET_ERR_INTERNAL          : Internal error
 *                  - R_EES_ENUM_RET_ERR_FLASH_SEQ         : Flash sequencer error
 *
 */
/*********************************************************************************************************************/
R_EES_FAR_FUNC void Sample_EES_Control(void)
{
    /* Local variable definitions */
    uint32_t i;
    e_ees_ret_status_t l_e_ees_ret_value;
    bool               l_b_sam_error_flag;
    uint16_t           l_u16_count;
    
    /* Set local variables */
    l_e_ees_ret_value  = R_EES_ENUM_RET_STS_OK;
    l_b_sam_error_flag = false;
    
    /******************************************************************************************************************
     * Initialize EES
     *****************************************************************************************************************/
    l_e_ees_ret_value = R_EES_Init(SAMPLE_VALUE_U08_CPU_FREQUENCY);
    if (R_EES_ENUM_RET_STS_OK == l_e_ees_ret_value)
    {
        /* EES was initialized successfully */
        /* No operation */
    }
    else
    {
        /* Error handling */
        l_b_sam_error_flag = true;
    }
    
    /******************************************************************************************************************
     * Open EES
     *****************************************************************************************************************/
    if (true != l_b_sam_error_flag)
    {
        l_e_ees_ret_value = R_EES_Open();
        if (R_EES_ENUM_RET_STS_OK == l_e_ees_ret_value)
        {
            /* EES was opened successfully */
            /* No operation */
        }
        else
        {
            /* Error handling */
            l_b_sam_error_flag = true;
        }
    }
    else
    {
        /* No operation */
    }
    
    /* Initialize EES requester */
    sg_st_ees_request.np_u08_address = &sg_ar_u08_write_data[0];
    sg_st_ees_request.u08_identifier = SAMPLE_VALUE_U08_INIT_VARIABLE;
    sg_st_ees_request.e_command      = R_EES_ENUM_CMD_UNDEFINED;
    
    /******************************************************************************************************************
     * STARTUP
     *****************************************************************************************************************/
    if (true != l_b_sam_error_flag)
    {
        do
        {
            /* Set parameters for STARTUP command */
            sg_st_ees_request.e_command = R_EES_ENUM_CMD_STARTUP;
            
            /* Execute STARTUP command */
            R_EES_Execute(&sg_st_ees_request);
            
            /* Wait for the end of running command */
            while (R_EES_ENUM_RET_STS_BUSY == sg_st_ees_request.e_status)
            {
                /* It is possible to write the program for detecting timeout here as necessity requires */
                R_EES_Handler();
            }
            
            l_e_ees_ret_value = sg_st_ees_request.e_status;
            
            /* Check returned status of the command */
            if (R_EES_ENUM_RET_STS_OK == l_e_ees_ret_value)
            {
                /* STARTUP command was finished successfully */
                /* No operation */
            }
            else if (R_EES_ENUM_RET_ERR_POOL_INCONSISTENT == l_e_ees_ret_value)
            {
                /******************************************************************************************************
                 * FORMAT
                 *****************************************************************************************************/
                /* Set parameters for FORMAT command */
                sg_st_ees_request.e_command = R_EES_ENUM_CMD_FORMAT;
                
                /* Execute FORMAT command */
                R_EES_Execute(&sg_st_ees_request);
                
                /* Wait for the end of running command */
                while (R_EES_ENUM_RET_STS_BUSY == sg_st_ees_request.e_status)
                {
                    /* It is possible to write the program for detecting timeout here as necessity requires */
                    R_EES_Handler();
                }
                
                l_e_ees_ret_value = sg_st_ees_request.e_status;
                
                /* Check returned status of the command */
                if (R_EES_ENUM_RET_STS_OK == l_e_ees_ret_value)
                {
                    /* FORMAT command was finished successfully */
                    /* No operation */
                }
                else
                {
                    /* FORMAT error handling */
                    l_b_sam_error_flag = true;
                }
            }
            else
            {
                /* STARTUP error handling */
                /* If R_EES_ENUM_RET_ERR_WEAK is returned, then REFRESH command should be executed */
                l_b_sam_error_flag = true;
            }
        } while ((R_EES_ENUM_CMD_FORMAT == sg_st_ees_request.e_command)
                 && (true != l_b_sam_error_flag));
    }
    else
    {
        /* No operation */
    }
    
    /******************************************************************************************************************
     * WRITE
     *****************************************************************************************************************/
    if (true != l_b_sam_error_flag)
    {
        /*初始化数据*/
        for (l_u16_count = 0u; l_u16_count < sizeof(sg_ar_u08_write_data); l_u16_count++)
            sg_ar_u08_write_data[l_u16_count] = 0xff - l_u16_count;
        
        for(i = 1;i <= R_EES_VALUE_U08_VAR_NO;i++)
        {
            if(Write_Data(i , sg_ar_u08_write_data , g_ar_u08_ees_descriptor[i]))
            {
                l_b_sam_error_flag = true;
            }
        }
    }
    else
    {
        /* No operation */
    }
    
    /******************************************************************************************************************
     * READ
     *****************************************************************************************************************/
    if (true != l_b_sam_error_flag)
    {
        for(i = 1;i <= R_EES_VALUE_U08_VAR_NO;i++)
        {
            if(Read_Data(i , sg_ar_u08_read_data , g_ar_u08_ees_descriptor[i]))
            {
                l_b_sam_error_flag = true;
            }
            
            for (l_u16_count = 0u; l_u16_count < g_ar_u08_ees_descriptor[i]; l_u16_count++)/* Compare read data with source data */
            {
                if (sg_ar_u08_write_data[l_u16_count] !=  sg_ar_u08_read_data[l_u16_count])
                {
                    l_b_sam_error_flag = true;/* Mismatch data error handling */
                    break;
                }
            }
        }
    }
    
    /******************************************************************************************************************
     * SHUTDOWN
     *****************************************************************************************************************/
    if (true != l_b_sam_error_flag)
    {
        /* Set parameters for SHUTDOWN command */
        sg_st_ees_request.e_command = R_EES_ENUM_CMD_SHUTDOWN;
        
        /* Execute SHUTDOWN command */
        R_EES_Execute(&sg_st_ees_request);
        
        /* When another command is running, call R_EES_Handler and retry SHUTDOWN command */
        while (R_EES_ENUM_RET_ERR_REJECTED == sg_st_ees_request.e_status)
        {
            /* It is possible to write the program for detecting timeout here as necessity requires */
            R_EES_Handler();
            R_EES_Execute(&sg_st_ees_request);
        }
        
        l_e_ees_ret_value = sg_st_ees_request.e_status;
        
        /* Check returned status of the command */
        if (R_EES_ENUM_RET_STS_OK == l_e_ees_ret_value)
        {
            /* SHUTDOWN command was finished successfully */
            /* No operation */
        }
        else
        {
            /* SHUTDOWN error handling */
            l_b_sam_error_flag = true;
        }
    }
    
    /******************************************************************************************************************
     * Close EES
     *****************************************************************************************************************/
    if (true != l_b_sam_error_flag)
    {
        l_e_ees_ret_value = R_EES_Close();
        if (R_EES_ENUM_RET_STS_OK == l_e_ees_ret_value)
        {
            /* EES was closed successfully */
            /* No operation */
        }
        else
        {
            /* Error handling, but never occurs */
            l_b_sam_error_flag = true;
        }
    }
    else
    {
        /* No operation */
    }
    
    if(l_e_ees_ret_value || l_b_sam_error_flag)
        printf("test err\r\n");
    else
        printf("test ok\r\n");
    
//    return(l_e_ees_ret_value);
}

#define  SAMPLE_END_SECTION_SMP_EES
#include "sample_ees_memmap.h"
/**********************************************************************************************************************
 End of function Sample_EES_Control
 *********************************************************************************************************************/
