/*
*
* Copyright (c) 2019-2020 Texas Instruments Incorporated
*
* All rights reserved not granted herein.
*
* Limited License.
*
* Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
* license under copyrights and patents it now or hereafter owns or controls to make,
* have made, use, import, offer to sell and sell ("Utilize") this software subject to the
* terms herein.  With respect to the foregoing patent license, such license is granted
* solely to the extent that any such patent is necessary to Utilize the software alone.
* The patent license shall not apply to any combinations which include this software,
* other than combinations with devices manufactured by or for TI ("TI Devices").
* No hardware patent is licensed hereunder.
*
* Redistributions must preserve existing copyright notices and reproduce this license
* (including the above copyright notice and the disclaimer and (if applicable) source
* code license limitations below) in the documentation and/or other materials provided
* with the distribution
*
* Redistribution and use in binary form, without modification, are permitted provided
* that the following conditions are met:
*
* *       No reverse engineering, decompilation, or disassembly of this software is
* permitted with respect to any software provided in binary form.
*
* *       any redistribution and use are licensed by TI for use only with TI Devices.
*
* *       Nothing shall obligate TI to provide you with source code for the software
* licensed and provided to you in object code.
*
* If software source code is provided to you, modification and redistribution of the
* source code are permitted provided that the following conditions are met:
*
* *       any redistribution and use of the source code, including any resulting derivative
* works, are licensed by TI for use only with TI Devices.
*
* *       any redistribution and use of any object code compiled from the source code
* and any resulting derivative works, are licensed by TI for use only with TI Devices.
*
* Neither the name of Texas Instruments Incorporated nor the names of its suppliers
*
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* DISCLAIMER.
*
* THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

/**
 *  \file can_profile.h.c
 *
 *  \brief Main file for TI-RTOS build
 */

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>

#include <ti/csl/arch/csl_arch.h>
#include <ti/csl/soc.h>
#include <ti/csl/cslr.h>

#include <ti/osal/osal.h>
#include <ti/osal/TaskP.h>

#include "CanApp_Startup.h"
#include "can_profile.h"
#include "CanIf.h"
#if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200)))
#include <ti/drv/sciclient/sciserver_tirtos.h>
#endif
/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */

/* Test application stack size */
#define APP_TASK_STACK                  (10U * 1024U)
/**< Stack required for the stack */
#define CAN_PROFILE_DEMO_TASK_NAME      ("CAN PROFILE")
/**< Task name */

/* ========================================================================== */
/*                         Structure Declarations                             */
/* ========================================================================== */

/* None */

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

static Void CanApp_TaskFxn(UArg a0, UArg a1);
static void CanApp_Shutdown(void);
sint32 SetupSciServer(void);
/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */
/* application stack */
static uint8_t CanApp_TaskStack[APP_TASK_STACK] __attribute__((aligned(32)));
/**< Stack for the task */
static canAppTaskObj_t  CanApp_TestPrms;
/**< Test parameters */
static HwiP_Handle      CanApp_IsrHndls[CAN_MAX_CONTROLLER];
/**< Stores the ISR handles */
extern SemaphoreP_Handle CanIf_TxConfirmationSemaphore;
/**< TX Confirmation semaphore, would be posted when TX completes */
extern SemaphoreP_Handle CanIf_RxConfirmationSemaphore;
/**< Rx Confirmation semaphore, would be posted when TX completes */
/* ========================================================================== */
/*                            External Variables                              */
/* ========================================================================== */
extern uint32 CanIf_DrvStatus;
/**< CAN IF Driver Status, defined in CanIf.c */

/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */
#if defined NO_BIOS_HOOK_FUNCTION
#define MCU_ATCM_BASE (0x0U)
extern const uint32_t ti_sysbios_family_arm_v7r_keystone3_Hwi_vectors[];
#endif

volatile uint32_t ccs_halt_flag = 0x0;

int main(void)
{

#if defined NO_BIOS_HOOK_FUNCTION
    /* In case we do not have a bios hook function to copy vectors to 0x0 like
       mcuCopyVecs2Exc, then we can use a simple memcpy operation like below to
       copy vecs from the linker specified location i.e
       ti_sysbios_family_arm_v7r_keystone3_Hwi_vectors which is in ATCM to
       0x0 where R5F expects it to be. */
    memcpy((void *)MCU_ATCM_BASE, (void *)&ti_sysbios_family_arm_v7r_keystone3_Hwi_vectors, 0x40);
#endif

    while(ccs_halt_flag);

    Task_Handle task;
    Error_Block eb;
    Task_Params taskParams;
    sint32 ret = CSL_PASS;

#ifdef UART_ENABLED
    AppUtils_Init();
#endif

    /* Initialize SCI Client Server */
    ret = SetupSciServer();
    if(ret != CSL_PASS)
    {
        BIOS_exit(0);
    }
    CanApp_Startup();
    CanApp_PowerAndClkSrc();

    /* Initialize dummy CAN IF */
    CanIf_Init(NULL);

    if (CANIF_DRV_INITIALIZED == CanIf_DrvStatus)
    {
        Error_init(&eb);

        /* Initialize the task params */
        Task_Params_init(&taskParams);
        taskParams.instance->name = CAN_PROFILE_DEMO_TASK_NAME;
        /* Set the task priority higher than the default priority (1) */
        taskParams.priority     = 2;
        taskParams.stack        = CanApp_TaskStack;
        taskParams.stackSize    = sizeof (CanApp_TaskStack);

        task = Task_create(CanApp_TaskFxn, &taskParams, &eb);
        if(NULL == task)
        {
            BIOS_exit(0);
        }
        BIOS_start();    /* does not return */
    }
    else
    {
        AppUtils_Printf(MSG_NORMAL, MSG_APP_NAME
                " Error : CAN IF not initialized !!!\n");
    }

    return(0);
}

static Void CanApp_TaskFxn(UArg a0, UArg a1)
{
    CanApp_PlatformInit();
    Utils_prfInit();

    Utils_prfLoadRegister (TaskP_self(), CAN_PROFILE_DEMO_TASK_NAME);

    CanApp_TestPrms.numTxPackets = APP_NUM_MSG_PER_ITERATION;
    CanApp_TestPrms.numIterations = APP_NUM_ITERATION;

    TaskP_yield();

    CanApp_ProfileTest(&CanApp_TestPrms);

    CanApp_Shutdown();

    Utils_prfLoadUnRegister (TaskP_self());
    Utils_prfDeInit();
    return;
}

/** \brief Application tear down functions */
static void CanApp_Shutdown(void)
{
    uint32 idx;

    for (idx = 0U; idx < CAN_MAX_CONTROLLER; idx++)
    {
        if (NULL != CanApp_IsrHndls[idx])
        {
            if (HwiP_OK != HwiP_delete(CanApp_IsrHndls[idx]))
            {
                AppUtils_Printf(MSG_NORMAL, MSG_APP_NAME
                                " Error!!! Could not De register"
                                " the ISR for instance %d!!!\n", idx);
                break;
            }
        }
    }

    if (NULL != CanIf_TxConfirmationSemaphore)
    {
        SemaphoreP_delete(CanIf_TxConfirmationSemaphore);
        if (NULL != CanIf_RxConfirmationSemaphore)
        {
            SemaphoreP_delete(CanIf_RxConfirmationSemaphore);
        }
    }
    return;
}

#define SCISERVER_COMMON_X509_HEADER_ADDR (0x41cffb00)
sint32 SetupSciServer(void)
{

    sint32 ret = CSL_PASS;
#if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200)))
    Sciserver_TirtosCfgPrms_t appPrms;
    Sciclient_ConfigPrms_t clientPrms;

    /*appPrms.taskPriority[SCISERVER_TASK_USER_LO] = 1;
    appPrms.taskPriority[SCISERVER_TASK_USER_HI] = 4;*/

    /* Sciclient needs to be initialized before Sciserver. Sciserver depends on
     * Sciclient API to execute message forwarding */
    /*ret = Sciclient_configPrmsInit(&clientPrms);*/
    if (ret == CSL_PASS)
    {
        /*ret = Sciclient_init(&clientPrms);*/
         ret = Sciclient_configPrmsInit(&clientPrms);
    }

    if (ret == CSL_PASS)
    {
        /*ret = Sciserver_tirtosInit(&appPrms);*/
        ret = Sciclient_boardCfgParseHeader(
            (uint8_t *)SCISERVER_COMMON_X509_HEADER_ADDR,
            &clientPrms.inPmPrms, &clientPrms.inRmPrms);
    }

    if (ret == CSL_PASS)
    {
        /*AppUtils_Printf(MSG_NORMAL, "Starting Sciserver..... PASSED\n");*/
        ret = Sciclient_init(&clientPrms);
    }
    /*else*/

    ret = Sciserver_tirtosInitPrms_Init(&appPrms);

    appPrms.taskPriority[SCISERVER_TASK_USER_LO] = 4;
    appPrms.taskPriority[SCISERVER_TASK_USER_HI] = 5;

    if (ret == CSL_PASS)
    {
        /*AppUtils_Printf(MSG_NORMAL, "Starting Sciserver..... FAILED\n");*/
         ret = Sciserver_tirtosInit(&appPrms);
    }

#endif
    return ret;
}
