/*
*
* Copyright (c) 2022 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      Fls.c
  *
  *  \brief    This file contains Fls MCAL driver
  *
  */

 /* ========================================================================== */
 /*                             Include Files                                  */
 /* ========================================================================== */
#include "string.h"
#include "Fls.h"
#include "Fls_Brd_Nor.h"
#include "Fls_NOR_s25fl128sa.h"
#include "Det.h"

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

/* AUTOSAR version information check has to match definition in header file */
#if ((FLS_AR_RELEASE_MAJOR_VERSION != (4U)) || \
    (FLS_AR_RELEASE_MINOR_VERSION != (3U)) ||  \
    (FLS_AR_RELEASE_REVISION_VERSION != (1U)))
    #error "Fls: AUTOSAR Version Numbers of Fls are different!!"
#endif

/* AUTOSAR version information check has to match definition in header file */
#if ((FLS_SW_MAJOR_VERSION != (0U)) || \
    (FLS_SW_MINOR_VERSION != (9U)) ||  \
    (FLS_SW_PATCH_VERSION != (0U)))
    #error "Fls: Software Version Numbers are inconsistent!!"
#endif

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

/* None */

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

#if (STD_ON == FLS_DEV_ERROR_DETECT)
/**
 * Check Flash bank ranges for a valid address
 *
 */
static Std_ReturnType checkValidAddress( Fls_AddressType SourceAddress )
{
    Std_ReturnType retVal = E_NOT_OK;
    uint32 startAddr = 0U;
    if( (SourceAddress >= startAddr) &&
    	(SourceAddress < (startAddr + NOR_SIZE)) )
    {
        retVal = E_OK;
    }
    return retVal;
}
#endif /*#if (STD_ON == FLS_DEV_ERROR_DETECT)*/

/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */

#define FLS_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Fls_MemMap.h"
/** \brief FLS driver object */
Fls_DriverObjType Fls_DrvObj =
{
    .status = MEMIF_UNINIT
};
#define FLS_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Fls_MemMap.h"

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

#define FLS_START_SEC_CODE
#include "Fls_MemMap.h"
/**
 *  \Function Name: Fls_Init
 *
 *  The function Fls_Init shall initialize the FLS module and all 
 *	flash memory relevant registers (hardware) with parameters
 *	provided in the given configuration set
 *
 */
FUNC(void, FLS_CODE) Fls_Init(
        P2CONST(Fls_ConfigType, AUTOMATIC, FLS_CONFIG_DATA) ConfigPtr)
{
    const Fls_ConfigType *CfgPtr = ConfigPtr;

#if (STD_ON == FLS_PRE_COMPILE_VARIANT)
    if (NULL_PTR == ConfigPtr)
    {
      CfgPtr = &FLS_INIT_CONFIG_PC;
    }
#endif  /* (STD_ON == SPI_PRE_COMPILE_VARIANT) */

#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (MEMIF_BUSY == Fls_DrvObj.status)
    {
        (void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_INIT, FLS_E_BUSY);
    }
    else if(NULL_PTR == CfgPtr)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_INIT, FLS_E_PARAM_CONFIG);
    }
    else if ((CfgPtr->maxReadNormalMode == 0U) || ((CfgPtr->maxReadNormalMode % NOR_PAGE_SIZE) != 0U))
    {
        (void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_INIT, FLS_E_PARAM_CONFIG);
    }
    else if ((CfgPtr->maxWriteNormalMode == 0U) || ((CfgPtr->maxWriteNormalMode % NOR_PAGE_SIZE) != 0U))
    {
        (void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_INIT, FLS_E_PARAM_CONFIG);
    }
    else
#endif /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        /* Instantiate a Driver Obj to be used by module */
        Fls_resetDrvObj(&Fls_DrvObj);
        /*Copy the input config parameters to Driver Object */
        Fls_copyConfig(&Fls_DrvObj, CfgPtr);
        Fls_DrvObj.jobResultType = MEMIF_JOB_PENDING;

        /*Init the HW */
        if(Fls_hwUnitInit() == E_OK)
        {
            Fls_DrvObj.jobResultType = MEMIF_JOB_OK;
            Fls_DrvObj.status = MEMIF_IDLE;
        }
    }
    return;
}

/**
 *  \Function Name: Fls_Erase
 *
 *  The function Fls_Erase shall erase one or more complete flash sectors.
 *
 */

FUNC(Std_ReturnType, FLS_CODE) Fls_Erase(
        Fls_AddressType TargetAddress, Fls_LengthType Length)
{
    Std_ReturnType      retVal = (Std_ReturnType) E_OK;

#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (MEMIF_UNINIT == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_ERASE, FLS_E_UNINIT);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if(MEMIF_BUSY == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_ERASE, FLS_E_BUSY);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if (E_NOT_OK == checkValidAddress(TargetAddress))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_ERASE, FLS_E_PARAM_ADDRESS);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if ((Length == 0U) || (E_NOT_OK == checkValidAddress(TargetAddress + Length - 1U)))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_ERASE, FLS_E_PARAM_LENGTH);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else
#endif /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        Fls_DrvObj.status = MEMIF_BUSY;
        Fls_DrvObj.jobResultType = MEMIF_JOB_PENDING;
        Fls_DrvObj.jobType = FLS_JOB_ERASE;

        Fls_DrvObj.flashAddr = TargetAddress;
        Fls_DrvObj.ramAddr = NULL;
        Fls_DrvObj.length = Length + (TargetAddress % NOR_SECTOR_SIZE);
        Fls_DrvObj.transferred = 0;

        Fls_DrvObj.jobChunkSize = NOR_SECTOR_SIZE;
    }

    return retVal;
};

/**
 *  \Function Name: Fls_Read
 *
 *  The function Fls_Read shall read from flash memory.
 *
 */

FUNC(Std_ReturnType, FLS_CODE) Fls_Read(
        Fls_AddressType SourceAddress,
        P2VAR(uint8, AUTOMATIC, FLS_APPL_DATA) TargetAddressPtr,
        Fls_LengthType Length)
{
    Std_ReturnType      retVal = (Std_ReturnType) E_OK;

#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (MEMIF_UNINIT == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_READ, FLS_E_UNINIT);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if(MEMIF_BUSY == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_READ, FLS_E_BUSY);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if(NULL_PTR == TargetAddressPtr)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_READ, FLS_E_PARAM_DATA);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if (E_NOT_OK == checkValidAddress(SourceAddress))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_READ, FLS_E_PARAM_ADDRESS);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if ((Length == 0U) || (E_NOT_OK == checkValidAddress(SourceAddress + Length - 1U)))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_READ, FLS_E_PARAM_LENGTH);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else
#endif /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        Fls_DrvObj.status = MEMIF_BUSY;
        Fls_DrvObj.jobResultType = MEMIF_JOB_PENDING;
        Fls_DrvObj.jobType = FLS_JOB_READ;

        Fls_DrvObj.flashAddr = SourceAddress;
        Fls_DrvObj.ramAddr = (uint8*) TargetAddressPtr;
        Fls_DrvObj.length = Length;
        Fls_DrvObj.transferred = 0;

        Fls_DrvObj.jobChunkSize = Fls_DrvObj.maxReadNormalMode;
#if (STD_ON == FLS_USE_INTERRUPTS)
        Fls_QspiIntEnable((QSPI_INTR_ENABLE_SET_REG_FIRQ_ENA_SET_MASK |
                           QSPI_INTR_ENABLE_SET_REG_WIRQ_ENA_SET_MASK));
#endif
    }

    return retVal;
}

/**
 *  \Function Name: Fls_Write
 *
 *  The function Fls_Write shall write one or more complete flash pages to the 
 *  flash device. 
 *
 */

FUNC(Std_ReturnType, FLS_CODE) Fls_Write(
        Fls_AddressType TargetAddress,
        P2VAR(const uint8, AUTOMATIC, FLS_APPL_DATA) SourceAddressPtr,
        Fls_LengthType Length)
{
    Std_ReturnType      retVal = (Std_ReturnType) E_OK;

#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (MEMIF_UNINIT == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_WRITE, FLS_E_UNINIT);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if(MEMIF_BUSY == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_WRITE, FLS_E_BUSY);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if(NULL_PTR == SourceAddressPtr)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_WRITE, FLS_E_PARAM_DATA);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if (((TargetAddress % NOR_PAGE_SIZE) != 0U) || (E_NOT_OK == checkValidAddress(TargetAddress)))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_WRITE, FLS_E_PARAM_ADDRESS);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if (((Length == 0U) || ((((TargetAddress + Length) % NOR_PAGE_SIZE) != 0U)
    || (E_NOT_OK == checkValidAddress(TargetAddress + Length -1U )))))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_WRITE, FLS_E_PARAM_LENGTH);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else
#endif /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        Fls_DrvObj.jobResultType = MEMIF_JOB_PENDING;
        Fls_DrvObj.status = MEMIF_BUSY;
        Fls_DrvObj.jobType = FLS_JOB_WRITE;

        Fls_DrvObj.flashAddr = TargetAddress;
        Fls_DrvObj.ramAddr = (uint8*)SourceAddressPtr;
        Fls_DrvObj.length = Length;
        Fls_DrvObj.transferred = 0;

        Fls_DrvObj.jobChunkSize = Fls_DrvObj.maxWriteNormalMode;
#if (STD_ON == FLS_USE_INTERRUPTS)
        Fls_QspiIntEnable((QSPI_INTR_ENABLE_SET_REG_FIRQ_ENA_SET_MASK |
                           QSPI_INTR_ENABLE_SET_REG_WIRQ_ENA_SET_MASK));
#endif
    }
    return retVal;

};

/**
 *  \Function Name: Fls_Compare
 *
 *  The function Fls_Compare shall compare the contents of an area of flash 
 *  memory with that of an application data buffer. 
 *
 */

#if ( FLS_COMPARE_API == STD_ON )
FUNC(Std_ReturnType, FLS_CODE) Fls_Compare(
        Fls_AddressType SourceAddress,
        P2VAR(const uint8, AUTOMATIC, FLS_APPL_DATA) TargetAddressPtr,
        Fls_LengthType Length)
{
    Std_ReturnType      retVal = (Std_ReturnType) E_OK;

#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (MEMIF_UNINIT == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_COMPARE, FLS_E_UNINIT);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if(MEMIF_BUSY == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_COMPARE, FLS_E_BUSY);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if(NULL_PTR == TargetAddressPtr)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_COMPARE, FLS_E_PARAM_DATA);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if (E_NOT_OK == checkValidAddress(SourceAddress))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_COMPARE, FLS_E_PARAM_ADDRESS);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if ((Length == 0U) || (E_NOT_OK == checkValidAddress(SourceAddress + Length - 1U)))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_COMPARE, FLS_E_PARAM_LENGTH);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else
#endif /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        Fls_DrvObj.status = MEMIF_BUSY;
        Fls_DrvObj.jobResultType = MEMIF_JOB_PENDING;
        Fls_DrvObj.jobType = FLS_JOB_COMPARE;

        Fls_DrvObj.flashAddr = SourceAddress;
        Fls_DrvObj.ramAddr = (uint8*)TargetAddressPtr;
        Fls_DrvObj.length = Length;
        Fls_DrvObj.transferred = 0;

        Fls_DrvObj.jobChunkSize = Fls_DrvObj.maxReadNormalMode;
    }
    return retVal;
}
#endif

/**
 *  \Function Name: Fls_BlankCheck
 *
 *  The function Fls_BlankCheck shall verify, whether a given memory area  
 *  has been erased. 
 *
 */
#if ( FLS_BLANK_CHECK_API == STD_ON )
FUNC(Std_ReturnType, FLS_CODE) Fls_BlankCheck(
        Fls_AddressType TargetAddress, Fls_LengthType Length)
{
    Std_ReturnType      retVal = (Std_ReturnType) E_OK;

#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (MEMIF_UNINIT == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_BLANK_CHECK, FLS_E_UNINIT);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if(MEMIF_BUSY == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_BLANK_CHECK, FLS_E_BUSY);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if (E_NOT_OK == checkValidAddress(TargetAddress))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_BLANK_CHECK, FLS_E_PARAM_ADDRESS);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else if ((Length == 0U) || (E_NOT_OK == checkValidAddress(TargetAddress + Length - 1U)))
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_BLANK_CHECK, FLS_E_PARAM_LENGTH);
        retVal = (Std_ReturnType) E_NOT_OK;
    }
    else
#endif /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        Fls_DrvObj.status = MEMIF_BUSY;
        Fls_DrvObj.jobResultType = MEMIF_JOB_PENDING;
        Fls_DrvObj.jobType = FLS_JOB_BLANKCHECK;

        Fls_DrvObj.flashAddr = TargetAddress;
        Fls_DrvObj.ramAddr = NULL;
        Fls_DrvObj.length = Length;
        Fls_DrvObj.transferred = 0;

        Fls_DrvObj.jobChunkSize = Fls_DrvObj.maxReadNormalMode;
    }
    return retVal;
}
#endif
/**
 *  \Function Name: Fls_GetStatus
 *
 *  The function Fls_GetStatus shall return the FLS module state synchronously
 *
 */
#if ( STD_ON == FLS_GET_STATUS_API)
FUNC(MemIf_StatusType, FLS_CODE)
        Fls_GetStatus( void )
{
    return Fls_DrvObj.status;
}
#endif

/**
 *  \Function Name: Fls_GetJobResult
 *
 *  The function Fls_GetJobResult shall return the result of the
 *	last job synchronously
 *
 */
#if ( FLS_GET_JOB_RESULT_API == STD_ON )
FUNC(MemIf_JobResultType, FLS_CODE)
        Fls_GetJobResult( void )
{
    MemIf_JobResultType jobResult = MEMIF_JOB_FAILED;
#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (MEMIF_UNINIT == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_GET_JOB_RESULT, FLS_E_UNINIT);
    }
    else
#endif /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        jobResult = Fls_DrvObj.jobResultType;
    }
    return jobResult;
}
#endif
/**
 *  \Function Name: Fls_GetVersionInfo
 *
 *  The function Returns the version information of this module.
 *
 */
#if (STD_ON == FLS_VERSION_INFO_API)
FUNC(Std_ReturnType, FLS_CODE) Fls_GetVersionInfo(
        P2VAR(Std_VersionInfoType, AUTOMATIC, FLS_APPL_DATA) versioninfo)
{
    Std_ReturnType      retVal = (Std_ReturnType) E_OK;

#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (NULL_PTR == versioninfo)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_GET_VERSION_INFO, FLS_E_PARAM_POINTER);
        retVal = E_NOT_OK;
    }
    else
#endif  /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        versioninfo->vendorID         = FLS_VENDOR_ID;
        versioninfo->moduleID         = FLS_MODULE_ID;
        versioninfo->sw_major_version = (uint8) FLS_SW_MAJOR_VERSION;
        versioninfo->sw_minor_version = (uint8) FLS_SW_MINOR_VERSION;
        versioninfo->sw_patch_version = (uint8) FLS_SW_PATCH_VERSION;
    }
    return retVal;
}
#endif  /* #if (STD_ON == FLS_VERSION_INFO_API) */

/**
 *  \Function Name: Fls_MainFunction
 *
 *  The function Fls_MainFunction shall perform the processing
 *	of the flash read, write, erase and compare jobs
 *
 */
FUNC(void, FLS_CODE) Fls_MainFunction(void)
{

#if (STD_ON == FLS_DEV_ERROR_DETECT)
    if (MEMIF_UNINIT == Fls_DrvObj.status)
    {
		(void) Det_ReportError(FLS_MODULE_ID, FLS_INSTANCE_ID, FLS_SID_MAIN_FUNCTION, FLS_E_UNINIT);
    }
    else
#endif  /* #if (STD_ON == FLS_DEV_ERROR_DETECT) */
    {
        if ( Fls_DrvObj.jobResultType == MEMIF_JOB_PENDING)
        {
            switch (Fls_DrvObj.jobType)
            {
                case FLS_JOB_COMPARE:
                    processJobs(FLS_JOB_COMPARE);
                    break;
                case FLS_JOB_ERASE:
                    processJobs(FLS_JOB_ERASE);
                    break;
                case FLS_JOB_READ:
                    processJobs(FLS_JOB_READ);
                    break;
                case FLS_JOB_WRITE:
                    processJobs(FLS_JOB_WRITE);
                    break;
                case FLS_JOB_BLANKCHECK:
                    processJobs(FLS_JOB_BLANKCHECK);
                    break;
                case FLS_JOB_NONE:
                    break;
                default:
                    break;
            } /* switch */
        }   /* if */
        else
        {
            /* If not pending job, then return end notification */
            Fls_DrvObj.Fls_JobEndNotification();
        }
    }
}

#define FLS_STOP_SEC_CODE
#include "Fls_MemMap.h"
