
/******************************************************************************/
/* Williams Advanced Engineering Limited                     Copyright(C) 2021*/
/* Grove                                                  All rights reserved */
/*                                                                            */
/******************************************************************************/


#include "Std_Types.h"
#include "DcmAppl.h"
#include "NvM.h"
#include "MemIf.h"
#include "Dcm_Lcfg_DspUds.h"
#include "FBL_BootMPrv.h"
#include "FBL_DataMCfg.h"
#include "Ios_ExtFlashNvM.h"


// Removing of compiler warnings and errors because of type re-declaration between hal_stdtypes.h and Std_Types.h
#define _BOOLEAN_DECLARED
#define _UINT8_DECLARED
#define _UINT16_DECLARED
#define _UINT32_DECLARED
#define _UINT64_DECLARED
#define _SINT8_DECLARED
#define _SINT16_DECLARED
#define _SINT32_DECLARED
#define _SINT64_DECLARED
#define _FLOAT32_DECLARED
#define _FLOAT64_DECLARED
#define _STD_RETURN_TYPE_DECLARED
#define _STDVERSION_DECLARED

//#include "ti_fee.h"
#include "Ios_Flash.h"
#include "Ios_CheckBootLoaderSignature.h"

/****************************************************************************************/
/* Extern imported functions                                                            */
/****************************************************************************************/

extern void Fbl_DataM_MainFunction(void);
//extern TI_FeeModuleStatusType MemIf_GetStatus(uint8 DeviceIndex);
//#define MemIf_GetStatus(DeviceIndex)  TI_Fee_GetStatus(DeviceIndex)

/****************************************************************************************/

Std_ReturnType DcmAppl_Dcm_ProcessRequestDownload(
        Dcm_OpStatusType OpStatus,
        uint8 DataFormatIdentifier,
        uint32 MemoryAddress,
        uint32 MemorySize,
        uint32 * BlockLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{
    Std_ReturnType retVal_u8;
    retVal_u8 = E_OK;
    *BlockLength = 226; //Align to 32 bytes on value -2 ie 224.
    /*TESTCODE-START
    retVal_u8 = DcmTest_DcmAppl_Dcm_ProcessRequestDownload(OpStatus,DataFormatIdentifier,MemoryAddress,MemorySize,BlockLength,ErrorCode);
    TESTCODE-END*/
    (void)OpStatus;
    (void)DataFormatIdentifier;
    (void)MemoryAddress;
    (void)MemorySize;
    (void)ErrorCode;

    //wcu_printf("%d - %d - 0x%X - %d \n", OpStatus, DataFormatIdentifier, MemoryAddress, MemorySize);

    return retVal_u8;
}

/*************** Routine ID 200 ***************/
// Erase and Initialize Data Flash
Std_ReturnType DcmDspStartRoutineFnc_0200(Dcm_OpStatusType OpStatus, uint8 * dataOut1, Dcm_NegativeResponseCodeType * ErrorCode)
{
    ExtFlashJobStatusType tCurrentNvMEraseJobStatus = fnIosExtFlsJobGetCurrentJobStatus();

    //dataOut1 0: start failed; not in progress 1: start successful; in progress 2: start failed; already running 3-255: reserved
    if((tCurrentNvMEraseJobStatus == ExtFlsJobStdby) || (tCurrentNvMEraseJobStatus == ExtFlsJobCompleteOK) || (tCurrentNvMEraseJobStatus == ExtFlsJobFailed))
    {
        fnIosExtFlsJobSetRqst(ExtFlsJobReqEraseNvM);
        fnIosExtFlsJobResetCurrentJobStatus();
        *dataOut1 = 0x01; //1: start successful; in progress
    }
    else
    {
        if( (tCurrentNvMEraseJobStatus > ExtFlsJobCompleteOK) && (tCurrentNvMEraseJobStatus <= ExtFlsJobReInitMemoryStack))
        {
            *dataOut1 = 0x02; // 2: start failed; already running
        }
        else
        {
            *dataOut1 = 0x00; //0: start failed; not in progress
        }
    }
    *ErrorCode = E_OK;

    return E_OK;
}

Std_ReturnType DcmDspRequestRoutineResultsFnc_0200(Dcm_OpStatusType OpStatus, uint8 * dataOut1, Dcm_NegativeResponseCodeType * ErrorCode)
{

    //0: erase not complete; not in progress 1: erase not complete; in progress 2: erase complete; succeeded 3: erase complete; failed4-255: reserved -

    ExtFlashJobStatusType tCurrentNvMEraseJobStatus = fnIosExtFlsJobGetCurrentJobStatus();
    ExtFlashJobType tCurrentNvMEraseJobRequest = fnIosExtFlsJobGetRqst();

    if(tCurrentNvMEraseJobRequest == ExtFlsJobReqNone)
    {
        if(tCurrentNvMEraseJobStatus == ExtFlsJobStdby)
        {
            *dataOut1 = 0x00; // 0: erase not complete; not in progress
        }
        else if(tCurrentNvMEraseJobStatus == ExtFlsJobCompleteOK)
        {
            *dataOut1 = 0x02; // 2: erase complete; succeeded
            fnIosExtFlsJobResetCurrentJobStatus();

        }
        else if ((tCurrentNvMEraseJobStatus >=ExtFlsJobInit) && ((tCurrentNvMEraseJobStatus <= ExtFlsJobReInitMemoryStack)))
        {
            *dataOut1 = 0x01; //1: erase not complete; in progress
            fnIosExtFlsJobResetCurrentJobStatus();
        }
        else if(tCurrentNvMEraseJobStatus == ExtFlsJobFailed)
        {
            *dataOut1 = 0x03; // 3: erase complete; failed
            fnIosExtFlsJobResetCurrentJobStatus();
        }
        else
        {
            //Should not go in.
            *dataOut1 = 0x03; // 3: erase complete; failed
            fnIosExtFlsJobResetCurrentJobStatus();
        }
    }
    else
    {
//        if(tCurrentNvMEraseJobStatus == ExtFlsJobStdby)
//        {
//            *dataOut1 = 0x00; // 0: erase not complete; not in progress
//        }
//        else
        if(tCurrentNvMEraseJobStatus == ExtFlsJobCompleteOK)
        {
            *dataOut1 = 0x02; // 2: erase complete; succeeded
            fnIosExtFlsJobResetCurrentJobStatus();

        }
        else if ((tCurrentNvMEraseJobStatus >=ExtFlsJobInit) && (tCurrentNvMEraseJobStatus <= ExtFlsJobReInitMemoryStack))
        {
            *dataOut1 = 0x01; //1: erase not complete; in progress

        }
        else if(tCurrentNvMEraseJobStatus == ExtFlsJobFailed)
        {
            *dataOut1 = 0x03; // 3: erase complete; failed
            fnIosExtFlsJobResetCurrentJobStatus();
        }
        else
        {
            *dataOut1 = 0x01; //1: erase not complete; in progress
        }
    }
    *ErrorCode = E_OK;

    return E_OK;

}

/*************** Routine ID 201 ***************/
// Erase and Initialise calibration section in Flash
Std_ReturnType DcmDspStartRoutineFnc_0201(
        const uint8 * dataIn1,
        Dcm_OpStatusType OpStatus,
        uint8 * dataOut1,
        uint16 CurrentDataLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{

    FlashJobStatusType tCurrentFlsJobStatus = fnIosFlsJobGetCurrentJobStatus();

    //dataIn1 == Calibration ID - Can be NULL or 0 only
    //dataOut1 == 0: start failed; not in progress 1: start successful; in progress 2: start failed; already running3-255: reserved

// Simplification - just app + cal region combined
//    if(dataIn1 == NULL)
//    {
//        if(tCurrentFlsJobStatus == FlsJobComplete)
//        {
//            //fnIosFlsJobResetCurrentJobStatus();
//            fnIosFlsJobSetRqst(FlsJobReqEraseCal);
//            *dataOut1 = 0x01; // Start Successful
//        }
//        else if((tCurrentFlsJobStatus > FlsJobComplete) && (tCurrentFlsJobStatus <= FlsJobEraseBlanckCheck))
//        {
//            *dataOut1 = 0x02; // Already running
//        }
//        else
//        {
//            *dataOut1 = 0x00; // Start Failed
//        }
//        *ErrorCode = E_OK;
//    }
//    else if((dataIn1 != NULL) && (*dataIn1 == 0))
//    {
//        if(tCurrentFlsJobStatus == FlsJobComplete)
//        {
//            fnIosFlsJobSetRqst(FlsJobReqEraseCal);
//            *dataOut1 = 0x01; // Start Successful
//        }
//        else if ((tCurrentFlsJobStatus > FlsJobComplete) && (tCurrentFlsJobStatus <= FlsJobEraseBlanckCheck))
//        {
//            *dataOut1 = 0x02; // Already running
//        }
//        else
//        {
//            *dataOut1 = 0x00; // Start Failed
//        }
//        *ErrorCode = E_OK;
//    }
//    else
//    {
//        *dataOut1 = 0x00; // Start Failed
//        *ErrorCode = E_NOT_OK;
//    }

    *dataOut1 = 0x00; // Start Failed
    *ErrorCode = 0x12; //Not Supported

    return E_NOT_OK;
}

Std_ReturnType DcmDspRequestRoutineResultsFnc_0201(
        const uint8 * dataIn1,
        Dcm_OpStatusType OpStatus,
        uint8 * dataOut1,
        uint16 CurrentDataLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{

    FlashJobStatusType tCurrentFlsJobStatus = fnIosFlsJobGetCurrentJobStatus();
    FlashJobType    tCurrentFlsJob = fnIosFlsJobGetRqst();

    //dataOut1 : 0: erase not complete; not in progress 1: erase not complete; in progress 2: erase complete; succeeded 3: erase complete; failed 4-255: reserved -

// Simplification - just app + cal region combined
//    if(tCurrentFlsJob == FlsJobReqNone)
//    {
//        *dataOut1 = 0x00; // erase not complete; not in progress
//    }
//    else
//    {
//        if((tCurrentFlsJobStatus == FlsJobComplete))
//        {
//            *dataOut1 = 0x02; //  erase complete; succeeded
//        }
//        else if ((tCurrentFlsJobStatus > FlsJobComplete) && (tCurrentFlsJobStatus <= FlsJobEraseBlanckCheck))
//        {
//            *dataOut1 = 0x01; // 1: erase not complete; in progress
//        }
//        else
//        {
//            *dataOut1 = 0x03; // 3: erase complete; failed
//        }
//    }
//
//    *ErrorCode = E_OK;

    *ErrorCode = 0x12; //Not Supported

    return E_NOT_OK;
}

/*************** Routine ID 210 ***************/
// Verify Application Integrity
Std_ReturnType DcmDspStartRoutineFnc_0210(
        const uint8 * dataIn1,
        Dcm_OpStatusType OpStatus,
        uint8 * dataOut1,
        uint16 CurrentDataLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{

    //dataOut1 0: start failed; verification not in progress 1: start successful; verification in progress 2: start failed; verification already running 3: start failed; verification for a different image region is already running4-255: reserved

    IntegrityVerificationJobStatusType tCurrentVerifJobStatus = fnIosGetCurrentVerifyJobStatus();

    if(dataIn1 == NULL)
    {
        if(tCurrentVerifJobStatus == VerifyJobComplete)
        {
            fnIosSetVerifySectionIntegrityRqst(VerifyAppAndCalSecIntegrity);
            *dataOut1 = 0x01; // Start Successful
        }
        else if((tCurrentVerifJobStatus > VerifyJobComplete) && (tCurrentVerifJobStatus <= VerifyJobInProgress))
        {
            *dataOut1 = 0x02; // Already running
        }
        else
        {
            *dataOut1 = 0x00; // Start Failed
        }
        *ErrorCode = E_OK;
    }
    else if((dataIn1 != NULL) && (*dataIn1 == 0))
    {
        if(tCurrentVerifJobStatus == VerifyJobComplete)
        {
            fnIosSetVerifySectionIntegrityRqst(VerifyAppAndCalSecIntegrity);
            *dataOut1 = 0x01; // Start Successful
        }
        else if((tCurrentVerifJobStatus > VerifyJobComplete) && (tCurrentVerifJobStatus <= VerifyJobInProgress))
        {
            *dataOut1 = 0x02; // Already running
        }
        else
        {
            *dataOut1 = 0x00; // Start Failed
        }
        *ErrorCode = E_OK;
    }
    else
    {
        *dataOut1 = 0x00; // Start Failed
        *ErrorCode = E_NOT_OK;
    }
    return E_OK;
}


Std_ReturnType DcmDspRequestRoutineResultsFnc_0210(
        const uint8 * dataIn1,
        Dcm_OpStatusType OpStatus,
        uint8 * dataOut1,
        uint8 * dataOut2,
        uint16 CurrentDataLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{

    //Check application and cal integrity job status
    IntegrityVerificationJobStatusType  tCurrentVerifJobStatus = fnIosGetCurrentVerifyJobStatus();
    IntegrityVerificationJobType        tCurrentVerifyJob = fnIosGetCurrentVerifyRqst();

    // Flag for NVM for fast boot
    //Fbl_BootM_ApplicationRegionValidStateType flag;

    //dataOut1 : 0: verification not complete; not in progress 1: verification not complete; in progress 2: verification complete
    //dataOut2 :  0: indeterminate 1: application verification passed 2: application checksum verification failed

    if(dataIn1 == NULL)
    {
        if((tCurrentVerifyJob == VerifyJobReqstNone) && ((VerifStatus_Undetermined == fnIosGetAppSecVerificationStatus()) || (VerifStatus_Undetermined == fnIosGetCalSecVerificationStatus())))
        {
            *dataOut1 = 0x00; // 0: verification not complete; not in progress
            *dataOut2 = 0x00; // 0: indeterminate
        }
        else
        {
            if((tCurrentVerifyJob == VerifyJobComplete))
            {
                *dataOut1 = 0x02; // 2: verification complete
                if((VerifStatus_Passed == fnIosGetAppSecVerificationStatus()) && \
                   (VerifStatus_Passed == fnIosGetCalSecVerificationStatus()))/* && \
                   (VerifStatus_Passed == tAppCompatibitility)                && \
                   (VerifStatus_Passed == tCalCompatibitility))*/
                {
                    // Set flag in NVM for fast boot - Part of the verification routine
//                    flag = FBL_BOOTM_APPLICATION_REGION_VALID;
//                    Fbl_DataM_NvmApplicationValidFlagWriteFunc((uint8*) &flag);

                    *dataOut2 = 0x01;
                }
                else
                {
                    *dataOut2 = 0x02;
                }
            }
            else if ((tCurrentVerifyJob > VerifyJobComplete) && (tCurrentVerifyJob <= VerifyJobInProgress))
            {
                *dataOut1 = 0x01; // 1: verification not complete; in progress
                *dataOut2 = 0x00; // 0: indeterminate
            }
            else
            {
                *dataOut1 = 0x00; // 0: verification not complete; not in progress
                *dataOut2 = 0x00; // 0: indeterminate
            }
        }
        *ErrorCode = E_OK;
    }
    else if((dataIn1 != NULL) && (*dataIn1 == 0))
    {
        if((tCurrentVerifyJob == VerifyJobReqstNone) && (VerifStatus_Undetermined == fnIosGetAppSecVerificationStatus()))
        {
            *dataOut1 = 0x00; // 0: verification not complete; not in progress
            *dataOut2 = 0x00; // 0: indeterminate
        }
        else
        {
            if((tCurrentVerifyJob == VerifyJobComplete))
            {

                *dataOut1 = 0x02; // 2: verification complete

                if((VerifStatus_Passed == fnIosGetAppSecVerificationStatus()) && \
                   (VerifStatus_Passed == fnIosGetCalSecVerificationStatus()))/* && \
                   (VerifStatus_Passed ==tAppCompatibitility)                 && \
                   (VerifStatus_Passed == tCalCompatibitility))*/
                {
                    // Set flag in NVM for fast boot - part of the verification routine
//                    flag = FBL_BOOTM_APPLICATION_REGION_VALID;
//                    Fbl_DataM_NvmApplicationValidFlagWriteFunc((uint8*) &flag);
                    *dataOut2 = 0x01;
                }
                else
                {
                    *dataOut2 = 0x02;
                }
            }
            else if ((tCurrentVerifyJob > VerifyJobComplete) && (tCurrentVerifyJob <= VerifyJobInProgress))
            {
                *dataOut1 = 0x01; // 1: verification not complete; in progress
                *dataOut2 = 0x00; // 0: indeterminate
            }
            else
            {
                *dataOut1 = 0x00; // 0: verification not complete; not in progress
                *dataOut2 = 0x00; // 0: indeterminate
            }
        }
        *ErrorCode = E_OK;
    }
    else
    {
        *ErrorCode = E_NOT_OK;
    }

	return E_OK;
}

/*************** Routine ID 212 ***************/
// Verify Calibration Integrity
Std_ReturnType DcmDspStartRoutineFnc_0212(
        const uint8 * dataIn1,
        Dcm_OpStatusType OpStatus,
        uint8 * dataOut1,
        uint16 CurrentDataLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{

    //dataOut1 0: start failed; verification not in progress 1: start successful; verification in progress 2: start failed; verification already running 3: start failed; verification for a different image region is already running4-255: reserved

//    IntegrityVerificationJobStatusType tCurrentVerifJobStatus = fnIosGetCurrentVerifyJobStatus();
//
//    if(dataIn1 == NULL)
//    {
//        if(tCurrentVerifJobStatus == VerifyJobComplete)
//        {
//            fnIosSetVerifySectionIntegrityRqst(VerifyCalSecIntegrity);
//            *dataOut1 = 0x01; // Start Successful
//        }
//        else if((tCurrentVerifJobStatus > VerifyJobComplete) && (tCurrentVerifJobStatus <= VerifyJobInProgress))
//        {
//            *dataOut1 = 0x02; // Already running
//        }
//        else
//        {
//            *dataOut1 = 0x00; // Start Failed
//        }
//        *ErrorCode = E_OK;
//    }
//    else if((dataIn1 != NULL) && (*dataIn1 == 0))
//    {
//        if(tCurrentVerifJobStatus == VerifyJobComplete)
//        {
//            fnIosSetVerifySectionIntegrityRqst(VerifyCalSecIntegrity);
//            *dataOut1 = 0x01; // Start Successful
//        }
//        else if((tCurrentVerifJobStatus > VerifyJobComplete) && (tCurrentVerifJobStatus <= VerifyJobInProgress))
//        {
//            *dataOut1 = 0x02; // Already running
//        }
//        else
//        {
//            *dataOut1 = 0x00; // Start Failed
//        }
//        *ErrorCode = E_OK;
//    }
//    else
//    {
//        *dataOut1 = 0x00; // Start Failed
//        *ErrorCode = E_NOT_OK;
//    }

    *dataOut1 = 0x00; // Start Failed
    *ErrorCode = 0x10; //Not Supported

    return E_NOT_OK;
}

Std_ReturnType DcmDspRequestRoutineResultsFnc_0212(
        const uint8 * dataIn1,
        Dcm_OpStatusType OpStatus,
        uint8 * dataOut1,
        uint8 * dataOut2,
        uint16 CurrentDataLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{

//    IntegrityVerificationJobStatusType  tCurrentVerifJobStatus = fnIosGetCurrentVerifyJobStatus();
//    IntegrityVerificationJobType        tCurrentVerifyJob = fnIosGetCurrentVerifyRqst();
//
//
//    //dataOut1 : 0: verification not complete; not in progress 1: verification not complete; in progress 2: verification complete
//    //dataOut2 :  0: indeterminate 1: application verification passed 2: application checksum verification failed
//
//    if(dataIn1 == NULL)
//    {
//        if((tCurrentVerifyJob == VerifyJobReqstNone) && (VerifStatus_Undetermined == fnIosGetCalSecVerificationStatus()))
//        {
//            *dataOut1 = 0x00; // 0: verification not complete; not in progress
//            *dataOut2 = 0x00; // 0: indeterminate
//        }
//        else
//        {
//            if((tCurrentVerifyJob == VerifyJobComplete))
//            {
//                *dataOut1 = 0x02; // 2: verification complete
//                *dataOut2 = fnIosGetCalSecVerificationStatus();
//            }
//            else if ((tCurrentVerifyJob > VerifyJobComplete) && (tCurrentVerifyJob <= VerifyJobInProgress))
//            {
//                *dataOut1 = 0x01; // 1: verification not complete; in progress
//                *dataOut2 = 0x00; // 0: indeterminate
//            }
//            else
//            {
//                *dataOut1 = 0x00; // 0: verification not complete; not in progress
//                *dataOut2 = 0x00; // 0: indeterminate
//            }
//        }
//        *ErrorCode = E_OK;
//    }
//    else if((dataIn1 != NULL) && (*dataIn1 == 0))
//    {
//        if((tCurrentVerifyJob == VerifyJobReqstNone) && (VerifStatus_Undetermined == fnIosGetCalSecVerificationStatus()))
//        {
//            *dataOut1 = 0x00; // 0: verification not complete; not in progress
//            *dataOut2 = 0x00; // 0: indeterminate
//        }
//        else
//        {
//            if((tCurrentVerifyJob == VerifyJobComplete))
//            {
//                *dataOut1 = 0x02; // 2: verification complete
//                *dataOut2 = fnIosGetCalSecVerificationStatus();
//            }
//            else if ((tCurrentVerifyJob > VerifyJobComplete) && (tCurrentVerifyJob <= VerifyJobInProgress))
//            {
//                *dataOut1 = 0x01; // 1: verification not complete; in progress
//                *dataOut2 = 0x00; // 0: indeterminate
//            }
//            else
//            {
//                *dataOut1 = 0x00; // 0: verification not complete; not in progress
//                *dataOut2 = 0x00; // 0: indeterminate
//            }
//        }
//        *ErrorCode = E_OK;
//    }
//    else
//    {
//        *ErrorCode = E_NOT_OK;
//    }

    *dataOut1 = 0x00; // verification not complete; not in progress
    *dataOut2 = 0x00; // 0: indeterminate
    *ErrorCode = 0x12; //Not Supported

    return E_NOT_OK;
}

/*************** Routine ID FF00 ***************/
// Erase and Initialize Application Flash
Std_ReturnType DcmDspStartRoutineFnc_FF00(const uint8 * dataIn1, Dcm_OpStatusType OpStatus, uint8 * dataOut1, uint16 CurrentDataLength, Dcm_NegativeResponseCodeType * ErrorCode)
{

    FlashJobStatusType tCurrentFlsJobStatus = fnIosFlsJobGetCurrentJobStatus();
    Fbl_BootM_ApplicationRegionValidStateType flag=0;
    uint32 uAppUpdateCntr=0;
    NvM_Rb_StatusType NvM_WriteAllStatusflag= NVM_RB_STATUS_IDLE;
    MemIf_StatusType Status;
    //TI_FeeModuleStatusType Status = IDLE;

    //dataIn1 == Calibration ID - Can be NULL or 0 only
    //dataOut1 == 0: start failed; not in progress 1: start successful; in progress 2: start failed; already running3-255: reserved

    if((0 == CurrentDataLength) || ((0 != CurrentDataLength) && (*dataIn1 == 0)))
    {
        if(tCurrentFlsJobStatus == FlsJobComplete)
        {
            //Set job request to erase flash
            fnIosFlsJobSetRqst(FlsJobReqEraseAppAndCal);

            // Reset all verification status
            fnIosResetAllVerificationStatus();

            // Reset flag in NVM for fast boot
//            Fbl_DataM_NvmApplicationValidFlagWriteFunc((uint8*) &flag);
//            if((FBL_BOOTM_APPLICATION_REGION_VALID == flag) || ((FBL_BOOTM_APPLICATION_REGION_INVALID != flag) && (FBL_BOOTM_APPLICATION_REGION_VALID != flag)))
//            {
                flag = FBL_BOOTM_APPLICATION_REGION_INVALID;
                Fbl_DataM_NvmApplicationValidFlagWriteFunc((uint8*) &flag);
//            }

            //Update application update counter
            Fbl_DataM_NvmApplicationUpdateCounterReadFunc((uint8*) &uAppUpdateCntr);
            uAppUpdateCntr++;
            Fbl_DataM_NvmApplicationUpdateCounterWriteFunc((uint8*) &uAppUpdateCntr);

            // Removed waiting loop for storage as external NVM is slower than internal
            // this causes delays in the sequence that can trip up the tool
            // The storage of teh update counter is to be done the same way as other data
//            /* Force Non-volatile memory write */
//            do
//            {
//                /* Execute */
//                Fbl_DataM_MainFunction();
//                NvM_MainFunction();
//                //TI_Fee_MainFunction();
//                (void)MemIf_Rb_MainFunction();
//                (void)NvM_Rb_GetStatus(&NvM_WriteAllStatusflag);
//                Status = MemIf_Rb_GetStatus();
//            } while ((NvM_WriteAllStatusflag == NVM_RB_STATUS_BUSY)|| (Status == MEMIF_BUSY) || (Fbl_DataM_NvmAllBlocksArePersisted() == FALSE));


            *dataOut1 = 0x01; // Start Successful
        }
        else if((tCurrentFlsJobStatus > FlsJobComplete) && (tCurrentFlsJobStatus <= FlsJobEraseBlanckCheck))
        {
            *dataOut1 = 0x02; // Already running
        }
        else
        {
            *dataOut1 = 0x00; // Start Failed
        }
        *ErrorCode = E_OK;
    }
    else
    {
        *dataOut1 = 0x00; // Start Failed
        *ErrorCode = E_NOT_OK;
    }

    return E_OK;
}

Std_ReturnType DcmDspRequestRoutineResultsFnc_FF00(const uint8 * dataIn1, Dcm_OpStatusType OpStatus, uint8 * dataOut1, uint16 CurrentDataLength, Dcm_NegativeResponseCodeType * ErrorCode)
{

    FlashJobStatusType tCurrentFlsJobStatus = fnIosFlsJobGetCurrentJobStatus();
    FlashJobType    tCurrentFlsJob = fnIosFlsJobGetRqst();
    static uint8 bDelay = 2;

    //dataOut1 : 0: erase not complete; not in progress 1: erase not complete; in progress 2: erase complete; succeeded 3: erase complete; failed 4-255: reserved -

    if((0 == CurrentDataLength) || ((0 != CurrentDataLength) && (*dataIn1 == 0)))
    {
        if(tCurrentFlsJob == FlsJobReqNone)
        {
            if((tCurrentFlsJobStatus == FlsJobComplete))
            {
                *dataOut1 = 0x02; //  erase complete; succeeded
                bDelay = 5;
            }
            else if(tCurrentFlsJobStatus == FlsJobFailed)
            {
                *dataOut1 = 0x03; // 3: erase complete; failed
                bDelay = 5;
            }
            else
            {
                *dataOut1 = 0x00; // erase not complete; not in progress
                bDelay = 5;
            }
        }
        else
        {
            // As the tool can be quicker to interrogate the ECU than the 10ms task to pick up the request, send pending answer for X iterations
            if(bDelay > 0)
            {
                *dataOut1 = 0x01; // 1: erase not complete; in progress

                if(tCurrentFlsJobStatus == FlsJobFailed)
                {
                    bDelay = 0;
                }
                else
                {
                    bDelay--;
                }
            }
            else
            {
                if ((tCurrentFlsJobStatus > FlsJobComplete) && (tCurrentFlsJobStatus <= FlsJobEraseBlanckCheck))
                {
                    *dataOut1 = 0x01; // 1: erase not complete; in progress
                }
                else
                {
                    *dataOut1 = 0x03; // 3: erase complete; failed
                }
                bDelay = 0;
            }
        }

        *ErrorCode = E_OK;
    }
    else // request format is wrong
    {
        *dataOut1 = 0x00; *dataOut1 = 0x00; // erase not complete; not in progress
        *ErrorCode = E_NOT_OK;
    }

    return E_OK;
}


/*************** Routine ID 0211 ***************/
// Verify Application Compatibility
Std_ReturnType DcmDspStartRoutineFnc_0211(
        const uint8 * dataIn1,
        Dcm_OpStatusType OpStatus,
        uint8 * dataOut1,
        uint16 CurrentDataLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{

//    Start Routine: Output Bytes - 1 - 1 - 1 - 1 -
//     -  -  -  -  -
//     -  - Bit Index - Description -  -
//     -  - 0 - Component ID verification result -  -
//     -  - 1 - Application ID verification result -  -
//     -  -  -  -  -
//    Start Routine: Output Format -  - 2 - Image region type verification result -  -
//    Start Routine: Output Format -  - where possible result values are:0: passed1: failed

    // Check application and cal compatibility
    SecVerificationStatusType tAppCompatibitility = fnIosGetApplicationCompatibilityStatus();
    SecVerificationStatusType tCalCompatibitility = fnIosGetCalibrationCompatibilityStatus();


    if((VerifStatus_Passed ==tAppCompatibitility) && (VerifStatus_Passed == tCalCompatibitility))
    {
        *dataOut1 = 0x00;  // pass
    }
    else
    {
        *dataOut1 = 0x01;  // fail
    }
	*ErrorCode = E_OK;
	return E_OK;
}



/*************** Routine ID 0213 ***************/
// Verify Calibration Compatibility
Std_ReturnType DcmDspStartRoutineFnc_0213(
        const uint8 * dataIn1,
        Dcm_OpStatusType OpStatus,
        uint8 * dataOut1,
        uint16 CurrentDataLength,
        Dcm_NegativeResponseCodeType * ErrorCode)
{

//    Start Routine: Output Bytes - 1 - 1 - 1 -
//    Start Routine: Output Format -  -  -  -
//    Start Routine: Output Format - Bit Index - Description -  -
//    Start Routine: Output Format - 0 - Component ID verification result -  -
//    Start Routine: Output Format - 1 - Calibration ID verification result -  -
//    Start Routine: Output Format - 2 - Image region type verification result -  -
//    Start Routine: Output Format - where possible result values are:0: passed1: failed

	*dataOut1 = 0x01; //failed
	*ErrorCode = 0x10; //Not Supported
	return E_NOT_OK;
}




