/**
*   @file    Fls_IPW.c
*   @version 1.0.0
*
*   @brief   AUTOSAR Fls - AUTOSAR Module Flash Driver.
*   @details Fls IP wrapper related functions.
*
*   @addtogroup FLS
*   @{
*/
/*==================================================================================================
*   Project              : AUTOSAR 4.3 MCAL
*   Platform             : PA
*   Peripheral           : IPV_FLASHV2
*   Dependencies         : none
*
*   Autosar Version      : 4.3.1
*   Autosar Revision     : ASR_REL_4_3_REV_0001
*   Autosar Conf.Variant :
*   SW Version           : 1.0.0
*   Build Version        : MPC5777C_MCAL_1_0_0_RTM_ASR_REL_4_3_REV_0001_20190315
*
*   (c) Copyright 2006-2016 Freescale Semiconductor, Inc. 
*       Copyright 2017-2019 NXP
*   All Rights Reserved.
==================================================================================================*/
/*==================================================================================================
==================================================================================================*/

#ifdef __cplusplus
extern "C"{
#endif

/**
* @page misra_violations MISRA-C:2012 violations
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.1, External identifiers shall be distinct.
* Identifiers (internal and external) shall not rely on the significance of more than 31 characters. 
* The used compilers use more than 31 chars for identifiers.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.2, Identifiers declared in the same scope and namespace shall be distinct.
* This violation is due to the requirement that requests to have a file version check.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.4, Macro identifiers shall be distinct.
* This violation is due to the requirement that requests to have a file version check.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.5, Identifiers shall be distinct from macro names.
* This violation is due to the requirement that requests to have a file version check.
*
* @section Fls_IPW_c_REF_1
* Violates MISRA 2012 Required Directive 4.10, Precautions shall be taken in order to prevent the contents of a header file being included more than once.
* This violation is not fixed since the inclusion of <MA>_MemMap.h is as per AUTOSAR requirement [SWS_MemMap_00003].
*
* @section Fls_IPW_c_REF_3
* Violates MISRA 2012 Advisory Rule 20.1, Include directives should only be preceded by preprocessor directives or comments.
* <MA>_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR.
*/

/*==================================================================================================
                                         INCLUDE FILES
 1) system and project includes
 2) needed interfaces from external units
 3) internal and external interfaces from this unit
==================================================================================================*/
#include "Fls.h"
#include "Fls_IPW.h"
#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)
#include "Fls_Flash.h"
#endif

#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)
#if (FLS_INTERNAL_SECTORS_CONFIGURED == STD_ON)
#include "Det.h"
#endif  /*#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)*/
#endif  /*#if (FLS_INTERNAL_SECTORS_CONFIGURED == STD_ON)*/

/*==================================================================================================
*                              SOURCE FILE VERSION INFORMATION
==================================================================================================*/
#define FLS_IPW_VENDOR_ID_C                           43
#define FLS_IPW_AR_RELEASE_MAJOR_VERSION_C            4
#define FLS_IPW_AR_RELEASE_MINOR_VERSION_C            3
#define FLS_IPW_AR_RELEASE_REVISION_VERSION_C         1
#define FLS_IPW_SW_MAJOR_VERSION_C                    1
#define FLS_IPW_SW_MINOR_VERSION_C                    0
#define FLS_IPW_SW_PATCH_VERSION_C                    0

/*==================================================================================================
*                                     FILE VERSION CHECKS
==================================================================================================*/
/* Check if current file and Fls header file are of the same vendor */
#if (FLS_IPW_VENDOR_ID_C != FLS_VENDOR_ID)
    #error "Fls_IPW.c and Fls.h have different vendor ids"
#endif
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and Fls header file are of the same Autosar version */
    #if ((FLS_IPW_AR_RELEASE_MAJOR_VERSION_C    != FLS_AR_RELEASE_MAJOR_VERSION) || \
         (FLS_IPW_AR_RELEASE_MINOR_VERSION_C    != FLS_AR_RELEASE_MINOR_VERSION) \
        )
        #error "AutoSar Version Numbers of Fls_IPW.c and Fls.h are different"
    #endif
#endif
/* Check if current file and Fls header file are of the same Software version */
#if ((FLS_IPW_SW_MAJOR_VERSION_C != FLS_SW_MAJOR_VERSION) || \
     (FLS_IPW_SW_MINOR_VERSION_C != FLS_SW_MINOR_VERSION) || \
     (FLS_IPW_SW_PATCH_VERSION_C != FLS_SW_PATCH_VERSION) \
    )
    #error "Software Version Numbers of Fls_IPW.c and Fls.h are different"
#endif


/* Check if current file and Fls_IPW.h header file have the same Vendor ID */
#if (FLS_IPW_VENDOR_ID_C != FLS_IPW_VENDOR_ID_H)
    #error "Fls_IPW.c and Fls_IPW.h have different vendor ids"
#endif
/* Check if current file and Fls_IPW.h header file are of the same Software version */
#if ((FLS_IPW_SW_MAJOR_VERSION_C != FLS_IPW_SW_MAJOR_VERSION_H) || \
     (FLS_IPW_SW_MINOR_VERSION_C != FLS_IPW_SW_MINOR_VERSION_H) || \
     (FLS_IPW_SW_PATCH_VERSION_C != FLS_IPW_SW_PATCH_VERSION_H) \
    )
    #error "Software Version Numbers of Fls_IPW.c and Fls_IPW.h are different"
#endif
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and Fls_IPW.h header file are of the same Autosar version */
    #if ((FLS_IPW_AR_RELEASE_MAJOR_VERSION_C    != FLS_IPW_AR_RELEASE_MAJOR_VERSION_H) || \
         (FLS_IPW_AR_RELEASE_MINOR_VERSION_C    != FLS_IPW_AR_RELEASE_MINOR_VERSION_H) ||  \
         (FLS_IPW_AR_RELEASE_REVISION_VERSION_C    != FLS_IPW_AR_RELEASE_REVISION_VERSION_H) \
        )
        #error "AutoSar Version Numbers of Fls_IPW.c and Fls_IPW.h are different"
    #endif
#endif


#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)
/* Check if current file and Fls_Flash header file are of the same vendor */
#if (FLS_IPW_VENDOR_ID_C != FLS_FLASH_VENDOR_ID)
    #error "Fls_IPW.c and Fls_Flash.h have different vendor ids"
#endif
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and Fls_Flash header file are of the same Autosar version */
    #if ((FLS_IPW_AR_RELEASE_MAJOR_VERSION_C    != FLS_FLASH_AR_RELEASE_MAJOR_VERSION) || \
         (FLS_IPW_AR_RELEASE_MINOR_VERSION_C    != FLS_FLASH_AR_RELEASE_MINOR_VERSION) \
        )
        #error "AutoSar Version Numbers of Fls_IPW.c and Fls_Flash.h are different"
    #endif
#endif
/* Check if current file and Fls_Flash header file are of the same Software version */
#if ((FLS_IPW_SW_MAJOR_VERSION_C != FLS_FLASH_SW_MAJOR_VERSION) || \
     (FLS_IPW_SW_MINOR_VERSION_C != FLS_FLASH_SW_MINOR_VERSION) || \
     (FLS_IPW_SW_PATCH_VERSION_C != FLS_FLASH_SW_PATCH_VERSION) \
    )
    #error "Software Version Numbers of Fls_IPW.c and Fls_Flash.h are different"
#endif
#endif


#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)
#if (FLS_INTERNAL_SECTORS_CONFIGURED == STD_ON)
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if current file and Det header file are of the same Autosar version */
    #if ((FLS_IPW_AR_RELEASE_MAJOR_VERSION_C != DET_AR_RELEASE_MAJOR_VERSION) || \
         (FLS_IPW_AR_RELEASE_MINOR_VERSION_C != DET_AR_RELEASE_MINOR_VERSION) \
        )
        #error "AutoSar Version Numbers of Fls_IPW.c and Det.h are different"
    #endif
#endif
#endif  /*#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)*/
#endif  /*#if (FLS_INTERNAL_SECTORS_CONFIGURED == STD_ON)*/


/*==================================================================================================
                                   LOCAL FUNCTION PROTOTYPES
==================================================================================================*/

/*==================================================================================================
                                       GLOBAL VARIABLES
==================================================================================================*/


/*==================================================================================================
                                       LOCAL CONSTANTS
==================================================================================================*/

/*==================================================================================================
                                       LOCAL VARIABLES
==================================================================================================*/

/*==================================================================================================
                                       LOCAL FUNCTIONS
==================================================================================================*/
#define FLS_START_SEC_CODE
/* @violates @ref Fls_IPW_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once */
#include "Fls_MemMap.h"

/*

*/
FUNC(void, FLS_CODE) Fls_IPW_Init(void)
{
    /* Initialize flash hardware 
       NOTE: The variable 'Fls_eLLDJobResult' will be updated in the below function*/
#if (FLS_INTERNAL_FLASH_AVAILABLE == STD_ON)
#if (FLS_INTERNAL_SECTORS_CONFIGURED == STD_ON)     
    Fls_Flash_Init();
#endif
#endif

}

FUNC(void, FLS_CODE) Fls_IPW_AbortSuspended(void)
{
#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)
#if (FLS_INTERNAL_SECTORS_CONFIGURED == STD_ON)
VAR(boolean, AUTOMATIC) bIsInternalSectorAvaible = (boolean)FALSE;
VAR(uint32, AUTOMATIC) u32SectorIndexIter = 0UL;

    /* Check if there is any internal Flash sector in current operation */
    for(u32SectorIndexIter = Fls_u32JobSectorIt; u32SectorIndexIter <= Fls_u32JobSectorEnd; u32SectorIndexIter++  )
    {
        if( FLS_CH_INTERN ==(*(Fls_pConfigPtr->paHwCh))[u32SectorIndexIter])
        {
            bIsInternalSectorAvaible = (boolean)TRUE;
            break;
        }
    }
    /* There is internal Flash sector in current operation */
    if((boolean)TRUE == bIsInternalSectorAvaible)
    {
        if( FLASH_E_FAILED == Fls_Flash_AbortSuspended(FLS_MAINFUNCTION_ID))
        {
            Fls_eLLDJob = FLASH_JOB_NONE;
            Fls_eLLDJobResult = MEMIF_JOB_FAILED;
        } 
    }    
#endif
#endif

}
#if (FLS_CANCEL_API == STD_ON )
/*

*/
FUNC(void, FLS_CODE) Fls_IPW_Cancel(void)
{    
    if(MEMIF_JOB_PENDING == Fls_eLLDJobResult )
    {    
        #if (FLS_INTERNAL_FLASH_AVAILABLE == STD_ON)
        #if (FLS_INTERNAL_SECTORS_CONFIGURED == STD_ON)     
            Fls_Flash_Cancel();
        #endif
        #endif

    }
    else
    {
        /* no hardware job (asynchronous) is pending, do nothing */ 

        /* Mark the internal job as failed.*/
        Fls_eLLDJob = FLASH_JOB_NONE;
        Fls_eLLDIrqJob = FLASH_IRQ_JOB_NONE;
        Fls_eLLDJobResult = MEMIF_JOB_CANCELED;    
    }

}
#endif


/**
* @brief          Process ongoing erase or write hardware job.
* @details        In case Async Operation is ongoing this function will complete the following job:
*                 - Erase
*                 - Erase on Interleaved sectors
*                 - Write
*                 - Erase blank Check
*                 .
*
* @implements     Fls_IPW_LLDMainFunction_Activity
*
* @note           Dem_ReportErrorStatus(Fls_pConfigPtr->Fls_E_EraseFailedCfg.id, DEM_EVENT_STATUS_FAILED)
*                 when erase operation failed due to hardware error.
*                 Dem_ReportErrorStatus(Fls_pConfigPtr->Fls_E_WriteFailedCfg.id, DEM_EVENT_STATUS_FAILED)
*                 when write operation failed due to hardware error
*/
FUNC( void, FLS_CODE ) Fls_IPW_LLDMainFunction( void )
{
    VAR(Fls_HwChType, AUTOMATIC) eHwCh;

    /* Get channel type(INTERNAL, EXTERNAL_A1, A2,...) to determine the HW IP used(internal or external flash). */
    eHwCh = (*(Fls_pConfigPtr->paHwCh))[Fls_u32JobSectorIt];
      
    if(MEMIF_JOB_PENDING == Fls_eLLDJobResult)
    {
        /* some hardware job (asynchronous) is pending */
        if (FLASH_JOB_ERASE == Fls_eLLDJob )
        {
            /* Decide the IP used: internal flash or external QSPI */
        #if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)     
        #if (STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)     
            if(FLS_CH_INTERN == eHwCh)
            {
                Fls_Flash_MainFunctionErase();
            }
        #endif
        #endif
        }
        /* Write hardware job (asynchronous) is pending */        
        else if (FLASH_JOB_WRITE == Fls_eLLDJob )
        {
            /* Decide the IP used: internal flash or external QSPI */
        #if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)     
        #if (STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)     
            if(FLS_CH_INTERN == eHwCh)
            {
                Fls_Flash_MainFunctionWrite();
            }
        #endif
        #endif
        }
    #if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
        else if ( FLASH_JOB_ERASE_BLANK_CHECK == Fls_eLLDJob )
        {
            /* Decide the IP used: internal flash or external QSPI */
        #if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)     
        #if (STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)      
            if(FLS_CH_INTERN == eHwCh)
            {
                Fls_Flash_MainFunctionEraseBlankCheck();
            }
        #endif
        #endif      
        }
    #endif 
        /* Write interleaved hardware job (asynchronous) is pending */
        else if (FLASH_JOB_NONE == Fls_eLLDJob)
        {
            /* Do nothing */
        }
        else
        {
            /* Do nothing - should not happen in Fully Trusted Environment;
               'else' clause added to fulfil MISRA Rule 14.10 */
        }

    }
    else
    {
        /* no hardware job (asynchronous) is pending, do nothing */
    }
}


/*

*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_IPW_SectorRead
(
    CONST(Fls_AddressType, AUTOMATIC) u32SectorOffset,
    CONST(Fls_AddressType, AUTOMATIC) u32Length,
    P2VAR(uint8, AUTOMATIC, FLS_APPL_DATA) pJobDataDestPtr
)
{
    VAR( Fls_LLDReturnType, AUTOMATIC ) eLldRetVal = FLASH_E_FAILED;
    VAR(Fls_HwChType, AUTOMATIC) eHwCh;
    
    /* Get channel type(INTERNAL, QSPI,...) to determine the HW IP used(internal or external flash). */
    eHwCh = (*(Fls_pConfigPtr->paHwCh))[Fls_u32JobSectorIt];
    
    /* Decide the IP used: internal flash or external QSPI */

#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)     
#if (STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)    
    if(FLS_CH_INTERN == eHwCh)
    {
        eLldRetVal = Fls_Flash_SectorRead( Fls_u32JobSectorIt, u32SectorOffset, u32Length, pJobDataDestPtr );
    }
#endif
#endif
    
    return eLldRetVal;
}
#if(( FLS_COMPARE_API == STD_ON ) || ( FLS_BLANK_CHECK_API == STD_ON ))
/**
* @brief          IP wrapper sector compare function.
* @details        Route the compare job to appropriate low level IP function. 
*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_IPW_SectorCompare
(
    CONST(Fls_AddressType, AUTOMATIC) u32SectorOffset,
    CONST(Fls_AddressType, AUTOMATIC) u32Length,
    P2CONST(uint8, AUTOMATIC, FLS_APPL_CONST) pJobDataSrcPtr
)
{
    VAR( Fls_LLDReturnType, AUTOMATIC ) eLldRetVal = FLASH_E_FAILED;
    VAR(Fls_HwChType, AUTOMATIC) eHwCh;
    
    /* Get channel type(INTERNAL, QSPI,...) to determine the HW IP used(internal or external flash). */
    eHwCh = (*(Fls_pConfigPtr->paHwCh))[Fls_u32JobSectorIt];
    
    /* Decide the IP used: internal flash or external QSPI */
#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)     
#if (STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)     
    if(FLS_CH_INTERN == eHwCh)
    {
        eLldRetVal = Fls_Flash_SectorCompare( Fls_u32JobSectorIt, u32SectorOffset, u32Length, pJobDataSrcPtr );
    }
#endif
#endif
    
    return eLldRetVal;
}
#endif /* ( FLS_COMPARE_API == STD_ON ) || (FLS_BLANK_CHECK_API == STD_ON) */

/**
* @brief          IP wrapper sector erase function.
* @details        Route the erase job to appropriate low level IP function. 
*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_IPW_SectorErase
(
#if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
    CONST( Fls_LengthType, AUTOMATIC ) u32PhysicalSectorSize,
#endif
    CONST( boolean, AUTOMATIC ) bAsynch
)
{
    VAR( Fls_LLDReturnType, AUTOMATIC ) eLldRetVal = FLASH_E_FAILED;
    VAR(Fls_HwChType, AUTOMATIC) eHwCh;
        
    /* Get channel type(INTERNAL, QSPI,...) to determine the HW IP used(internal or external flash). */
    eHwCh = (*(Fls_pConfigPtr->paHwCh))[Fls_u32JobSectorIt];
    
    /* Decide the IP used: internal flash or external QSPI */
#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)     
#if (STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)     
    if(FLS_CH_INTERN == eHwCh)
    {        
        /* Call Low-Level driver to erase one internal sector with 
            the Fls_u32JobSectorIt sector index */    
    #if( FLS_ERASE_VERIFICATION_ENABLED == STD_ON )
        eLldRetVal = Fls_Flash_SectorErase( Fls_u32JobSectorIt, u32PhysicalSectorSize, bAsynch );        
    #else
        eLldRetVal = Fls_Flash_SectorErase( Fls_u32JobSectorIt, bAsynch );
    #endif
    }
#endif
#endif
    
    return eLldRetVal;
}

/**
* @brief          IP wrapper sector write function.
* @details        Route the write job to appropriate low level IP function. 
*/
FUNC( Fls_LLDReturnType, FLS_CODE ) Fls_IPW_SectorWrite
(
    CONST(Fls_AddressType, AUTOMATIC) u32SectorOffset,
    CONST(Fls_AddressType, AUTOMATIC) u32Length,
    P2CONST(uint8, AUTOMATIC, FLS_APPL_CONST) pJobDataSrcPtr,
    CONST( boolean, AUTOMATIC ) bAsynch
)
{    
    VAR( Fls_LLDReturnType, AUTOMATIC ) eLldRetVal = FLASH_E_FAILED;
    VAR(Fls_HwChType, AUTOMATIC) eHwCh;
    
    /* Get channel type(INTERNAL, QSPI,...) to determine the HW IP used(internal or external flash). */
    eHwCh = (*(Fls_pConfigPtr->paHwCh))[Fls_u32JobSectorIt];
    
    /* Decide the IP used: internal flash or external QSPI */
#if (STD_ON == FLS_INTERNAL_FLASH_AVAILABLE)     
#if (STD_ON == FLS_INTERNAL_SECTORS_CONFIGURED)     
    if(FLS_CH_INTERN == eHwCh)  
    {
        eLldRetVal = Fls_Flash_SectorWrite( Fls_u32JobSectorIt, u32SectorOffset, u32Length, pJobDataSrcPtr, bAsynch ); 
    }
#endif
#endif
    
    return eLldRetVal;
}

#define FLS_STOP_SEC_CODE
/*
* @violates @ref Fls_IPW_c_REF_1 Precautions shall be taken in order to prevent the contents of a header file being included more than once
* @violates @ref Fls_IPW_c_REF_3 Include directives should only be preceded by preprocessor directives or comments 
*/
#include "Fls_MemMap.h"

#ifdef __cplusplus
}
#endif



