/* ======================================================================
 *   Copyright (c) 2022 Texas Instruments Incorporated
 *
 *   All rights reserved. Property of Texas Instruments Incorporated.
 *   Restricted rights to use, duplicate or disclose this code are
 *   granted through contract.
 *
 *   The program may not be used without the written permission
 *   of Texas Instruments Incorporated or against the terms and conditions
 *   stipulated in the agreement under which this program has been
 *   supplied.
 * ==================================================================== */

/**
 *  \file     WdgApp.c
 *
 *  \brief    This file contains the SPI test example for WdgApp
 *
 */

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */

/*LDRA_NOANALYSIS*/
#include "Std_Types.h"
/*LDRA_ANALYSIS*/
#include "Det.h"
#include "Dem.h"
#include "Fls.h"
#include "Fls_Irq.h"
#include "Fls_Brd_Nor.h"
#include "EcuM_Cbk.h"
#include "Mcu.h"
#include "Port_Cfg.h"
#include "Port.h"
/*LDRA_NOANALYSIS*/
#include "string.h"
/*LDRA_ANALYSIS*/
#include "trace.h"

/* Starterware Includes */
#include "sys_vim.h"
#include "app_utils.h"
#include "soc.h"

#include "hw_ctrl_core.h"


/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */

#define ARRAYSIZE(x)                    (sizeof ((x)) / sizeof (x[0]))
#define APP_NAME                        "FLS_APP"
//#define PERF_TEST /* enable flag to log performance data*/

/* ========================================================================== */
/*                         Structures and Enums                               */
/* ========================================================================== */

/* None */

/* ========================================================================== */
/*                 Internal Function Declarations                             */
/* ========================================================================== */

void FlsApp_InterruptConfig(void);
void main_handling_intr();
void main_handling();
/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */

uint32 gTestPassed;
volatile uint32 Fls_JobDoneSuccess;
volatile uint32 Fls_JobDoneError;

#if (STD_ON == FLS_VERSION_INFO_API)
Std_VersionInfoType       VersionInfo;
#endif
#if (STD_OFF == MCU_NO_PLL)
extern CONST(Mcu_ConfigType, MCU_PBCFG) McuModuleConfiguration_0;
#endif

#define DATA_SIZE_TEST 512U
#define DATA_VALUE 0xABU
uint32 offset = 0x000U;
Std_ReturnType retVal = E_OK;
/* Buffer containing the known data that needs to be written to flash */
uint8 txBuf_test[DATA_SIZE_TEST]={0};
/* Buffer containing the received data */
uint8 rxBuf_test[DATA_SIZE_TEST]={0};

/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */

int main(void)
{
    uint16 mss_uart_tx_pin, mss_uart_rx_pin;
    uint32 sys_clk_freq_vclk_const;
    AppUtils_defaultInit();
    Mcu_Init(&McuModuleConfiguration);
    Port_Init(PortConfigSet_0_pt);
    /* Default is AM263x*/
    mss_uart_tx_pin = 13;
    mss_uart_rx_pin = 14;
    
    /* Set up the pinmux for UART tx */
    Port_SetPinMode(mss_uart_tx_pin, PORT_PIN_MODE_LIN0);

    /* Set up the pinmux for UART rx */
    Port_SetPinMode(mss_uart_rx_pin, PORT_PIN_MODE_LIN0);
    Port_SetPinDirection(mss_uart_rx_pin, PORT_PIN_IN);
    /* Initialize interrupt */

    #if (STD_OFF == MCU_NO_PLL)
    if(McuModuleConfiguration_0.Mcu_PllSourceId == MCU_CLKSRC_DPLL)
    {
        sys_clk_freq_vclk_const = (McuModuleConfiguration_0.Mcu_PllConfig[MCU_CLKSRC_DPLL].Mcu_PllClk1.MCU_PLL_HSDIV2 / (2e6)) * 30;
    }
    else
    {
        sys_clk_freq_vclk_const = (McuModuleConfiguration_0.Mcu_PllConfig[MCU_CLKSRC_APLL].Mcu_PllClk1.MCU_PLL_HSDIV0 / (2e6)) * 30;
    }
    Enable_Uart();
    #else
    Enable_Uart();
    #endif
    /* Delay for UART to settle up */
    
    AppUtils_printf("FlsApp: Sample Application - STARTS !!!\n\r");
	
	#if (STD_ON == FLS_USE_INTERRUPTS)
		AppUtils_printf(APP_NAME ": Configuring Interrupt.\n\r");
		FlsApp_InterruptConfig();
	#endif
	#if (STD_ON == FLS_PRE_COMPILE_VARIANT)
		AppUtils_printf(APP_NAME ": Variant - Pre Compile being used !!!\n\r");
		Fls_Init((const Fls_ConfigType *) NULL_PTR);
	#else
		AppUtils_printf(APP_NAME ": Variant - Post Build being used !!!\n\r");
		Fls_Init(&FlsConfigSet);
	#endif
	
#if (STD_ON == FLS_VERSION_INFO_API)
    Fls_GetVersionInfo(&VersionInfo);
    AppUtils_printf("FLS MCAL version info:%d.%d.%d\n\r",
                    VersionInfo.sw_major_version,
                    VersionInfo.sw_minor_version,
                    VersionInfo.sw_patch_version);
    AppUtils_printf("FLS MCAL Module/Driver:%d.%d \n\r",
                    VersionInfo.moduleID,
                    VersionInfo.vendorID);
#endif

/* FLS driver should be free now - check */
#if ( STD_ON == FLS_GET_STATUS_API)
   MemIf_StatusType      status;
   status = Fls_GetStatus();
   if (status != MEMIF_IDLE)
   {
       AppUtils_printf(APP_NAME ": FLS driver is not IDLE!!\n\r");
   }
#endif
   AppUtils_printf(APP_NAME ": DATA SIZE TEST is 0x%X \n\r", DATA_SIZE_TEST);
   AppUtils_printf(APP_NAME ": Offset is 0x%X \n\r", offset);
   
   volatile uint32 idx;
   volatile uint8 *txPtr_test = txBuf_test;
   volatile uint8 *rxPtr_test = rxBuf_test;

   for(idx = 0U; idx < DATA_SIZE_TEST; idx++)
   {
      *txPtr_test++ = DATA_VALUE;
      *rxPtr_test++ = (uint8)0U;
   }
   AppUtils_printf(APP_NAME ": Erasing \n\r");
   while (1U)
   {
       Std_ReturnType job_accepted = Fls_Erase(offset, DATA_SIZE_TEST);
       if (E_OK == job_accepted)
               break;
   }
   main_handling();
#if (STD_OFF == FLS_USE_INTERRUPTS)
	
#if ( STD_ON == FLS_BLANK_CHECK_API)
		AppUtils_printf(APP_NAME ": Blank Checking \n\r");
	while (1U)
	{
       Std_ReturnType job_accepted = Fls_BlankCheck(offset, DATA_SIZE_TEST);
       if (E_OK == job_accepted)
           break;
	}
	main_handling();
#endif /*STD_ON == FLS_BLANK_CHECK_API*/

   AppUtils_printf(APP_NAME ": Writing \n\r");
   while (1U)
   {
       Std_ReturnType job_accepted = Fls_Write(offset, &txBuf_test[0], DATA_SIZE_TEST);
       if (E_OK == job_accepted)
           break;
   }
   main_handling();
   AppUtils_printf(APP_NAME ": Reading \n\r");
   while (1U)
   {
       Std_ReturnType job_accepted = Fls_Read(offset, &rxBuf_test[0], DATA_SIZE_TEST);
       if (E_OK == job_accepted)
           break;
   }
   main_handling();
   
 #if ( STD_ON == FLS_COMPARE_API)
   AppUtils_printf(APP_NAME ": Comparing \n\r");
   while (1U)
   {
       Std_ReturnType job_accepted = Fls_Compare(offset, &txBuf_test[0], DATA_SIZE_TEST);
       if (E_OK == job_accepted)
           break;
   }
   main_handling();
#endif /*STD_ON == FLS_COMPARE_API*/
#endif/*STD_OFF == FLS_USE_INTERRUPTS*/
#if (STD_ON == FLS_USE_INTERRUPTS)
    AppUtils_printf(APP_NAME ": Testing Interrupt Mode! \n\r");
    AppUtils_printf(APP_NAME ": Writing \n\r");
    while (1U)
    {
        Std_ReturnType job_accepted = Fls_Write(offset, &txBuf_test[0], DATA_SIZE_TEST);
        if (E_OK == job_accepted)
            break;
    }
	main_handling_intr();
    AppUtils_printf(APP_NAME ": Reading \n\r");
    while (1U)
    {
        Std_ReturnType job_accepted = Fls_Read(offset, &rxBuf_test[0], DATA_SIZE_TEST);
        if (E_OK == job_accepted)
            break;
    }
    main_handling_intr();
#endif/*STD_ON == FLS_USE_INTERRUPTS*/
	if(retVal == E_OK)
	{
		AppUtils_printf(APP_NAME ": FLS Test passed \n\r");
	}
	else
	{
		AppUtils_printf(APP_NAME ": FLS Test failed \n\r");
	}

    return (0);
}
void FlsApp_InterruptConfig(void)
{
    Vim_IntCfg intCfg;
    intCfg.map = VIM_INTTYPE_IRQ;
    intCfg.type = VIM_INTTRIGTYPE_LEVEL;

    vimInit();
    intCfg.priority = VIM_PRIORITY_4;
    intCfg.intNum = 54U;
    intCfg.handler = Fls_Hdlr;
    vimRegisterInterrupt(&intCfg);
}
void SchM_Enter_Fls_FLS_EXCLUSIVE_AREA_0(void)
{
    AppUtils_SchM_Enter_EXCLUSIVE_AREA_0();
}

void SchM_Exit_Fls_FLS_EXCLUSIVE_AREA_0(void)
{
    AppUtils_SchM_Exit_EXCLUSIVE_AREA_0();
}
void  SchM_Enter_Mcu_MCU_EXCLUSIVE_AREA_0()
{
    AppUtils_SchM_Enter_EXCLUSIVE_AREA_0();
}

void   SchM_Exit_Mcu_MCU_EXCLUSIVE_AREA_0()
{
     AppUtils_SchM_Exit_EXCLUSIVE_AREA_0();
}
void  SchM_Enter_Port_PORT_EXCLUSIVE_AREA_0()
{
    AppUtils_SchM_Enter_EXCLUSIVE_AREA_0();

}

void   SchM_Exit_Port_PORT_EXCLUSIVE_AREA_0()
{

  AppUtils_SchM_Exit_EXCLUSIVE_AREA_0();

}
Std_ReturnType Det_ReportError(uint16 ModuleId,
                               uint8  InstanceId,
                               uint8  ApiId,
                               uint8  ErrorId)
{
    gTestPassed = E_NOT_OK;
    GT_assert(McalAppTrace, FALSE);
    return (E_OK);
}
Std_ReturnType Det_ReportRuntimeError(VAR(uint16, AUTOMATIC) ModuleId,
                                               VAR(uint8, AUTOMATIC) InstanceId,
                                               VAR(uint8, AUTOMATIC) ApiId,
                                               VAR(uint8, AUTOMATIC) ErrorId)
{
    gTestPassed = E_NOT_OK;
    GT_assert(McalAppTrace, FALSE);
    return (E_OK);
}
Std_ReturnType Det_ReportTransientFault(
                                               VAR(uint16, AUTOMATIC) ModuleId,
                                               VAR(uint8, AUTOMATIC) InstanceId,
                                               VAR(uint8, AUTOMATIC) ApiId,
                                               VAR(uint8, AUTOMATIC) FaultId)
{
    gTestPassed = E_NOT_OK;
    GT_assert(McalAppTrace, FALSE);
    return (E_OK);
}
void Fee_JobEndNotification(void)
{
        Fls_JobDoneSuccess = 1U;
}

void Fee_JobErrorNotification(void)
{
        Fls_JobDoneError = 1U;
}
void main_handling()
{
	AppUtils_printf(APP_NAME ": Job Processing in Progress.\n\r");
    while (1U)
    {
        Fls_MainFunction();
        if ( Fls_JobDoneSuccess == 1U)
        {
            AppUtils_printf(APP_NAME ": Job Ends: SUCCESS\n\r");
			retVal = E_OK;
            break;
        }
        if ( Fls_JobDoneError == 1U)
        {
            AppUtils_printf(APP_NAME ": Job Ends: Error\n\r");
			retVal = E_NOT_OK;
            break;
        }
    }

    Fls_JobDoneSuccess = 0U;
    Fls_JobDoneError = 0U;
    return;
}
void main_handling_intr()
{
	AppUtils_printf(APP_NAME ": Job Processing in Progress.\n\r");
    while(1U)
    {
        if ( Fls_JobDoneSuccess == 1U)
        {
			AppUtils_printf(APP_NAME ": Job Ends: SUCCESS\n\r");
			retVal = E_OK;
            break;
        }
        if ( Fls_JobDoneError == 1U)
        {
			AppUtils_printf(APP_NAME ": Job Ends: Error\n\r");
			retVal = E_NOT_OK;
            break;
        }

    }

    Fls_JobDoneSuccess = 0U;
    Fls_JobDoneError = 0U;
    return;
}
