/***********************************************************************************************************************
 * File Name    : hal_entry.c
 * Description  : Contains data structures and functions used in hal_entry.c.
 **********************************************************************************************************************/
/***********************************************************************************************************************
 * DISCLAIMER
 * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
 * other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
 * applicable laws, including copyright laws.
 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
 * EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
 * SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
 * SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
 * this software. By using this software, you agree to the additional terms and conditions found by accessing the
 * following link:
 * http://www.renesas.com/disclaimer
 *
 * Copyright (C) 2020 Renesas Electronics Corporation. All rights reserved.
 ***********************************************************************************************************************/

#include "common_utils.h"
#include "vee_flash_ep.h"

/*******************************************************************************************************************//**
 * @addtogroup vee_flash_ep
 * @{
 **********************************************************************************************************************/

FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

/* Private Function Declaration */
static void write_operation(void);
static void read_operation(void);

/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    fsp_err_t err                         = FSP_SUCCESS;
    fsp_pack_version_t version            = {RESET_VALUE};
    uint8_t read_data                     = RESET_VALUE;

    /* version get API for FLEX pack information */
    R_FSP_VersionGet(&version);

    /* Example Project information printed on the Console */
    APP_PRINT(BANNER_INFO, EP_VERSION, version.version_id_b.major, version.version_id_b.minor, version.version_id_b.patch );
    APP_PRINT(EP_INFO);

    /* Initialize the RM_VEE_FLASH driver module.*/
    err = vee_flash_init();
    if (FSP_SUCCESS != err)
    {
        APP_ERR_PRINT ("\r\n** VEE_FLASH INIT FAILED **\r\n");
        APP_ERR_TRAP(err);
    }

    /* Print Menu option of vee flash operation.*/
    APP_PRINT(VEE_FLASH_MENU);

    while(true)
    {
        /* Conversion from input string to integer value */
        read_data = process_input_data();
        switch (read_data)
        {
            /* Perform VEEPROM write operation.*/
            case WRITE :
            {
                write_operation();
                break;
            }

            /* Perform VEEPROM read operation.*/
            case READ :
            {
                read_operation();
                break;
            }

            /* Perform VEEPROM format operation.*/
            case FORMAT :
            {
                err = vee_format_operation();
                handle_error(err, "\r\n** Format Operation Failed **\r\n");
                break;
            }

            /* Perform VEEPROM StatusGet operation.*/
            case STATUS :
            {
                err = vee_status_get_operation();
                handle_error(err, "\r\n** StatusGet Operation Failed **\r\n");
                break;
            }

            /* Perform VEEPROM Refresh operation.*/
            case REFRESH :
            {
                err = vee_refresh_operation();
                handle_error(err, "\r\n** Refresh Operation Failed **\r\n");
                break;
            }

            default:
            {
                APP_PRINT("\r\nInvalid Menu Option Selected\r\n");
                break;
            }
        }
        /* Reset buffer*/
        read_data = RESET_VALUE;
        /* Print Main Menu option of vee flash operation.*/
        APP_PRINT(VEE_FLASH_MENU);
    }
}


/*******************************************************************************************************************//**
 * This function is called at various points during the startup process.  This implementation uses the event that is
 * called right before main() to set up the pins.
 *
 * @param[in]  event    Where at in the start up process the code is currently at
 **********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event) {
    if (BSP_WARM_START_RESET == event) {
#if BSP_FEATURE_FLASH_LP_VERSION != 0

        /* Enable reading from data flash. */
        R_FACI_LP->DFLCTL = 1U;

        /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event) {
        /* C runtime environment and system clocks are setup. */

        /* Configure pins. */
        R_IOPORT_Open(&g_ioport_ctrl, &g_bsp_pin_cfg);
    }
}

/*******************************************************************************************************************//**
 *  @brief       Performs write operation on vee flash.
 *  @param[IN]   None
 *  @retval      None
 **********************************************************************************************************************/
static void write_operation(void)
{
    fsp_err_t err                = FSP_SUCCESS;
    uint8_t read_data            = RESET_VALUE;
    /* Record data to write on different Record ID's.*/
    uint8_t data_1[DATA_SIZE]  = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11};
    char    data_2[DATA_SIZE]  = {'R', 'E', 'A', 'E', 'P', 'V', 'E', 'E', 'P', 'R', 'O', 'M'};
    float   data_3[DATA_SIZE]  = {0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f};
    adxl_t  data_4             =
    {
     .x_data = 100,
     .y_data = 150,
     .z_data = 190,
     .xy_data = 60
    };

    /* Print Sub Menu option of vee flash write operation.*/
    APP_PRINT(VEE_FLASH_WRITE_MENU);
    /* Process input only when User has provided one */
    read_data = process_input_data();
    switch (read_data)
    {
        case WRITE_READ_ID_1:
        {
            /* Write the Integer data to a Virtual EEPROM Record_ID1. */
            err = vee_write_operation(REC_ID_1, data_1, sizeof(data_1));
            handle_error(err, "\r\n** vee write operation failed for Record_ID1 **\r\n");
            APP_PRINT("\r\nInteger data is written successfully on Record_ID1.\r\n");
            break;
        }

        case WRITE_READ_ID_2:
        {
            /* Write the Char data to a Virtual EEPROM Record_ID2. */
            err = vee_write_operation(REC_ID_2, data_2, sizeof(data_2));
            handle_error(err, "\r\n** vee write operation failed for Record_ID2 **\r\n");
            APP_PRINT("\r\nChar data is written successfully on Record_ID2.\r\n");
            break;
        }

        case WRITE_READ_ID_3:
        {
            /* Write the float data to a Virtual EEPROM Record_ID3. */
            err = vee_write_operation(REC_ID_3, data_3, sizeof(data_3));
            handle_error(err, "\r\n** vee write operation failed for Record_ID3 **\r\n");
            APP_PRINT("\r\nFloat data is written successfully on Record_ID3.\r\n");
            break;
        }

        case WRITE_READ_ID_4:
        {
            /* Write the structure data to a Virtual EEPROM Record_ID4. */
            err = vee_write_operation(REC_ID_4, &data_4, sizeof(data_4));
            handle_error(err, "\r\n** vee write operation failed for Record_ID4 **\r\n");
            APP_PRINT("\r\nStructure data is written successfully on Record_ID4.\r\n");
            break;
        }

        default :
        {
            /* do nothing.*/
            break;
        }
    }
    APP_PRINT("vee_flash is in ready state.\r\n");
}

/*******************************************************************************************************************//**
 *  @brief       Performs read operation from vee flash.
 *  @param[IN]   None
 *  @retval      None
 **********************************************************************************************************************/
static void read_operation(void)
{
    fsp_err_t err                = FSP_SUCCESS;
    uint8_t read_data            = RESET_VALUE;

    /* Print Sub Menu option of vee flash read operation.*/
    APP_PRINT(VEE_FLASH_READ_MENU);
    /* Process input only when User has provided one */
    read_data = process_input_data();
    switch (read_data)
    {
        case WRITE_READ_ID_1:
        {
            /* Read data from Record_ID1*/
            err = vee_read_operation(REC_ID_1);
            if ((FSP_SUCCESS != err) && (FSP_ERR_NOT_FOUND != err))
            {
                handle_error(err, "\r\n** vee read operation failed for Record_ID1 **\r\n");
            }
            break;
        }

        case WRITE_READ_ID_2:
        {
            /* Read data from Record_ID2*/
            err = vee_read_operation(REC_ID_2);
            if ((FSP_SUCCESS != err) && (FSP_ERR_NOT_FOUND != err))
            {
                handle_error(err, "\r\n** vee read operation failed for Record_ID2 **\r\n");
            }
            break;
        }

        case WRITE_READ_ID_3:
        {
            /* Read data from Record_ID3*/
            err = vee_read_operation(REC_ID_3);
            if ((FSP_SUCCESS != err) && (FSP_ERR_NOT_FOUND != err))
            {
                handle_error(err, "\r\n** vee read operation failed for Record_ID3 **\r\n");
            }
            break;
        }

        case WRITE_READ_ID_4:
        {
            /* Read data from Record_ID4*/
            err = vee_read_operation(REC_ID_4);
            if ((FSP_SUCCESS != err) && (FSP_ERR_NOT_FOUND != err))
            {
                handle_error(err, "\r\n** vee read operation failed for Record_ID4 **\r\n");
            }
            break;
        }

        default :
        {
            /* do nothing.*/
            break;
        }
    }
}

/*******************************************************************************************************************//**
 * @} (end addtogroup vee_flash_ep)
 **********************************************************************************************************************/
