/*====================================================================================================================*/
/* Project      = AUTOSAR Renesas X2x MCAL Components                                                                 */
/* Module       = Spi_HSPI_LLDriver.c                                                                                 */
/* SW-VERSION   = 1.5.0                                                                                               */
/*====================================================================================================================*/
/*                                                     COPYRIGHT                                                      */
/*====================================================================================================================*/
/* (c) 2020-2022 Renesas Electronics Corporation. All rights reserved.                                                */
/*====================================================================================================================*/
/* Purpose:                                                                                                           */
/* This file contains Low level driver function definitions of the SPI Driver                                         */
/*====================================================================================================================*/
/*                                                                                                                    */
/* Unless otherwise agreed upon in writing between your company and Renesas Electronics Corporation the following     */
/* shall apply!                                                                                                       */
/*                                                                                                                    */
/* Warranty Disclaimer                                                                                                */
/*                                                                                                                    */
/* There is no warranty of any kind whatsoever granted by Renesas. Any warranty is expressly disclaimed and excluded  */
/* by Renesas, either expressed or implied, including but not limited to those for non-infringement of intellectual   */
/* property, merchantability and/or fitness for the particular purpose.                                               */
/*                                                                                                                    */
/* Renesas shall not have any obligation to maintain, service or provide bug fixes for the supplied Product(s) and/or */
/* the Application.                                                                                                   */
/*                                                                                                                    */
/* Each User is solely responsible for determining the appropriateness of using the Product(s) and assumes all risks  */
/* associated with its exercise of rights under this Agreement, including, but not limited to the risks and costs of  */
/* program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and             */
/* unavailability or interruption of operations.                                                                      */
/*                                                                                                                    */
/* Limitation of Liability                                                                                            */
/*                                                                                                                    */
/* In no event shall Renesas be liable to the User for any incidental, consequential, indirect, or punitive damage    */
/* (including but not limited to lost profits) regardless of whether such liability is based on breach of contract,   */
/* tort, strict liability, breach of warranties, failure of essential purpose or otherwise and even if advised of the */
/* possibility of such damages. Renesas shall not be liable for any services or products provided by third party      */
/* vendors, developers or consultants identified or referred to the User by Renesas in connection with the Product(s) */
/* and/or the Application.                                                                                            */
/*                                                                                                                    */
/*====================================================================================================================*/
/* Environment:                                                                                                       */
/*              Devices:        X2x                                                                                   */
/*====================================================================================================================*/

/***********************************************************************************************************************
**                                              Revision Control History                                              **
***********************************************************************************************************************/
/* 1.4.4:  10/11/2022  : As per ARDAACA-1266
 *                       Spi_HSPIMainFunction_Handling: Remove Spi_GulCancelHWUnits, Spi_GetHWUnitStatus in
 *                       Global Variable field
 * 1.4.3:  08/04/2022  : Remove redundant Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSSCTL inside 
 *                       SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_ON in Spi_HSPIForceStop
 *         10/05/2022  : Remove else do nothing
 *                       Add QAC message
 * 1.3.2:  04/09/2021  : Replace the inclusion of Spi_MemMap.h with Spi_Mapping.h
 *                       Update precondition for calling SPI_DEM_REPORT_ERROR
 * 1.3.1:  02/07/2021  : Add QAC message 9.5.0
 *                       Format source code to 120 characters
 *                       Improve Violation tag (remove START/END) 
 * 1.2.0:  30/07/2020  : Release
 *         28/07/2020  : Add QAC 9.3.1 comment.
 * 1.1.0:  19/06/2020  : Release
 * 1.0.2:  21/05/2020  : Update QAC warning and MISRA-C Rule violation
 * 1.0.1:  19/05/2020  : Move DMA pre-compile with out pre-compile check for
 *                       Level1 and Level2 to support DMA at Level0
 * 1.0.0:  24/03/2020  : Initial Version
 */
/**********************************************************************************************************************/

/***********************************************************************************************************************
**                                                  Include Section                                                   **
***********************************************************************************************************************/
#include "Spi.h"                                                                                                        /* PRQA S 0857 # JV-01 */
#include "Spi_Ram.h"
#include "Spi_Irq.h"
#include "Spi_HSPI_LLDriver.h"                                                                                          /* PRQA S 0857 # JV-01 */
#include "rh850_Types.h"                                                                                                /* PRQA S 0857 # JV-01 */
#include "Dem.h"

/***********************************************************************************************************************
**                                                Version Information                                                 **
***********************************************************************************************************************/
/* AUTOSAR release version information */
#define SPI_HSPI_LLDRIVER_C_AR_RELEASE_MAJOR_VERSION    SPI_AR_RELEASE_MAJOR_VERSION_VALUE
#define SPI_HSPI_LLDRIVER_C_AR_RELEASE_MINOR_VERSION    SPI_AR_RELEASE_MINOR_VERSION_VALUE                              /* PRQA S 0791 # JV-01 */
#define SPI_HSPI_LLDRIVER_C_AR_RELEASE_REVISION_VERSION SPI_AR_RELEASE_REVISION_VERSION_VALUE                           /* PRQA S 0791 # JV-01 */

/* File version information */
#define SPI_HSPI_LLDRIVER_C_SW_MAJOR_VERSION            SPI_SW_MAJOR_VERSION_VALUE
#define SPI_HSPI_LLDRIVER_C_SW_MINOR_VERSION            SPI_SW_MINOR_VERSION_VALUE

/***********************************************************************************************************************
**                                                   Version Check                                                    **
***********************************************************************************************************************/
#if (SPI_HSPI_LLDRIVER_AR_RELEASE_MAJOR_VERSION != SPI_HSPI_LLDRIVER_C_AR_RELEASE_MAJOR_VERSION)
#error "Spi_HSPI_LLDriver.c : Mismatch in Release Major Version"
#endif

#if (SPI_HSPI_LLDRIVER_AR_RELEASE_MINOR_VERSION != SPI_HSPI_LLDRIVER_C_AR_RELEASE_MINOR_VERSION)
#error "Spi_HSPI_LLDriver.c : Mismatch in Release Minor Version"
#endif

#if (SPI_HSPI_LLDRIVER_AR_RELEASE_REVISION_VERSION != SPI_HSPI_LLDRIVER_C_AR_RELEASE_REVISION_VERSION)
#error "Spi_HSPI_LLDriver.c : Mismatch in Release Revision Version"
#endif

#if (SPI_HSPI_LLDRIVER_SW_MAJOR_VERSION != SPI_HSPI_LLDRIVER_C_SW_MAJOR_VERSION)
#error "Spi_HSPI_LLDriver.c : Mismatch in Software Major Version"
#endif

#if (SPI_HSPI_LLDRIVER_SW_MINOR_VERSION != SPI_HSPI_LLDRIVER_C_SW_MINOR_VERSION)
#error "Spi_HSPI_LLDriver.c : Mismatch in Software Minor Version"
#endif

/***********************************************************************************************************************
**                                               Coding Rule Violations                                               **
***********************************************************************************************************************/
/* Message (2:0857)    : Number of macro definitions exceeds 1024 - program does not conform strictly to ISO:C90.     */
/* Rule                : MISRA C:2012 Dir-1.1                                                                         */
/* JV-01 Justification : The number of macro depend on module code size. There is no issue when number of macro is    */
/*                       over 1024                                                                                    */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (7:0791)    : Macro identifier does not differ from other macro identifier(s) (e.g. '%s') within the       */
/*                       specified number of significant characters.                                                  */
/* Rule                : CERTCCM DCL23, MISRA C:2012 Rule-5.4                                                         */
/* JV-01 Justification : This macro identifier is following AUTOSAR standard rule (Symbolic Name or Published         */
/*                       Macro's name), so this is accepted.                                                          */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (4:5087)    : Use of #include directive after code fragment.                                               */
/* Rule                : MISRA C:2012 Rule-20.1                                                                       */
/* JV-01 Justification : This is done as per Memory Requirement, (MEMMAP003 - Specification of Memory Mapping).       */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (1:1531)    : The object '%1s' is referenced in only one translation unit - but not the one in which it    */
/*                       is defined.                                                                                  */
/* Rule                : CERTCCM DCL15, DCL19, MISRA C:2012 Rule-8.7                                                  */
/* JV-01 Justification : Followed coding rules, the objects (global variable/const) is define in separated source     */
/*                       file, so this could be accepted                                                              */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2814)    : Possible: Dereference of NULL pointer.                                                       */
/* Rule                : CERTCCM EXP34                                                                                */
/* JV-01 Justification : This is accepted, due to the implementation is following hardware specification.             */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2844)    : Possible: Dereference of an invalid pointer value.                                           */
/* Rule                : CERTCCM ARR30                                                                                */
/* JV-01 Justification : It is specific for device register accessing and confirmed has no issue in software behavior.*/
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0316)    : Cast from a pointer to void to a pointer to object type.                                     */
/* Rule                : MISRA C:2012 Rule-11.5                                                                       */
/* JV-01 Justification : A cast should not be performed between a pointer to object type and a different pointer to   */
/*                       object type.                                                                                 */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2824)    : Possible: Arithmetic operation on NULL pointer.                                              */
/* Rule                : CERTCCM EXP34                                                                                */
/* JV-01 Justification : This is accepted, due to the implementation is following hardware specification.             */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:3469)    : This usage of a function-like macro looks like it could be replaced by an equivalent         */
/*                       function call.                                                                               */
/* Rule                : MISRA C:2012 Dir-4.9                                                                         */
/* JV-01 Justification : This message indicates that a candidate macro may be suitable for replacement by a           */
/*                       function, based on an actual call-site and the arguments passed to it there. (Other uses of  */
/*                       the macro may not necessarily be suitable for replacement.)                                  */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:3432)    : Simple macro argument expression is not parenthesized.                                       */
/* Rule                : MISRA C:2012 Rule-20.7                                                                       */
/* JV-01 Justification : Compiler keyword (macro) is defined and used followed AUTOSAR standard rule. It is accepted. */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2934)    : Possible: Computing an invalid pointer value.                                                */
/* Rule                : CERTCCM ARR30, ARR37, ARR38, EXP08                                                           */
/* JV-01 Justification : This message prevent existing of an out of range pointer                                     */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0303)    : Cast between a pointer to volatile object and an integral type.                              */
/* Rule                : CERTCCM INT36, MISRA C:2012 Rule-11.4                                                        */
/* JV-01 Justification : Typecasting is done as per the register size, to access hardware registers.                  */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0306)    : Cast between a pointer to object and an integral type.                                       */
/* Rule                : CERTCCM INT36, MISRA C:2012 Rule-11.4                                                        */
/* JV-01 Justification : Typecasting is done as per the register size, to access hardware registers.                  */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (1:3383)    : Cannot identify wraparound guard for unsigned arithmetic expression.                         */
/* Rule                : CERTCCM INT30                                                                                */
/* JV-01 Justification : It can still result in values that are out of range for the intended use, as intuitive       */
/*                       "invariants" may not hold                                                                    */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (3:3387)    : A full expression containing an increment (++) or decrement (--) operator should have no     */
/*                       potential side effects other than that caused by the increment or decrement operator.        */
/* Rule                : MISRA C:2012 Rule-13.3                                                                       */
/* JV-01 Justification : An increment/decrement is created a side affect. In this case it's accessing a volatile      */
/*                       object. This can be accepted.                                                                */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (7:0404)    : More than one read access to volatile objects between sequence points.                       */
/* Rule                : CERTCCM EXP10, EXP30, MISRA C:2012 Rule-1.3, Rule-13.2                                       */
/* JV-01 Justification : This is to get element in array of struct, volatile of counter variable of 'for' loop is     */
/*                       used to ensure no optimization. It is accepted                                               */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0751)    : Casting to char pointer type.                                                                */
/* Rule                : CERTCCM EXP11, EXP39                                                                         */
/* JV-01 Justification : Using void due to specific requirement of input parameter. So, this can be skipped           */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (1:1505)    : The function '%1s' is only referenced in the translation unit where it is defined.           */
/* Rule                : CERTCCM DCL19, MISRA C:2012 Rule-8.7                                                         */
/* JV-01 Justification : This is accepted, due to following coding rule, internal function can be defined in other C  */
/*                       source files                                                                                 */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/

/***********************************************************************************************************************
**                                                Function Definitions                                                **
***********************************************************************************************************************/
#if (SPI_HSPI_CONFIGURED == STD_ON)

#define SPI_START_SEC_PRIVATE_CODE
#include "Spi_Mapping.h"

/* Prototypes for functions used in this file only */
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIInit(void);
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIDeInit(void);
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIDisableAllInterrupts(void);
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_HSPIProcessJob(const boolean LblFirst, CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig);
#if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_0) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
STATIC FUNC(Std_ReturnType, SPI_PRIVATE_CODE)
    Spi_HSPITransmitSyncJob(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig);
#endif
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_HSPIMaskHWUnitInterrupts(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                                 const boolean LblMask);
#if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_1) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
#if (SPI_FORCE_CANCEL_API == STD_ON)
STATIC FUNC(void, SPI_CODE_FAST) Spi_HSPIForceStop(const uint32 LulHWUnitIndex);
#endif
#endif
#if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIMainFunction_Handling(void);
#endif
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPITurnOff(const uint32 LulHWPhyIndex);

STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_HSPIInitializeForJob(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig);
#if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_HSPIInitializeForCh(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                            CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig);
#endif

#define SPI_STOP_SEC_PRIVATE_CODE
#include "Spi_Mapping.h"                                                                                                /* PRQA S 5087 # JV-01 */

/***********************************************************************************************************************
**                                                    Global Data                                                     **
***********************************************************************************************************************/

#define SPI_START_SEC_CONST_UNSPECIFIED
#include "Spi_Mapping.h"                                                                                                /* PRQA S 5087 # JV-01 */

/* HW-dependent function pointer table */
CONST(Spi_HwFuncTableType, SPI_CONST) Spi_GstHSPIFunc =                                                                 /* PRQA S 1531 # JV-01 */
{
  &Spi_HSPIInit,
  &Spi_HSPIDisableAllInterrupts,
  &Spi_HSPIProcessJob,
  #if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_0) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
  &Spi_HSPITransmitSyncJob,
  #endif
  &Spi_HSPIMaskHWUnitInterrupts,
  #if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_1) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
  #if (SPI_FORCE_CANCEL_API == STD_ON)
  &Spi_HSPIForceStop,
  #endif
  #endif
  #if (SPI_DMA_CONFIGURED == STD_ON)
  NULL_PTR,
  #endif
  #if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
  &Spi_HSPIMainFunction_Handling,
  #endif
  &Spi_HSPITurnOff,
  &Spi_HSPIDeInit
};

#define SPI_STOP_SEC_CONST_UNSPECIFIED
#include "Spi_Mapping.h"                                                                                                /* PRQA S 5087 # JV-01 */

#if (SPI_MAX_HSPI_CHANNEL_BUFFER_SIZE > 0U)
#define SPI_START_SEC_VAR_NO_INIT_64
#include "Spi_Mapping.h"                                                                                                /* PRQA S 5087 # JV-01 */
/* Channel buffer for HS-SPI.
This buffer should be aligned to 8byte regardless access size */
volatile VAR(uint32, SPI_VAR_NO_INIT) Spi_GaaHSPIChannelBuffer[SPI_MAX_HSPI_CHANNEL_BUFFER_SIZE / sizeof(uint32)];
#define SPI_STOP_SEC_VAR_NO_INIT_64
#include "Spi_Mapping.h"                                                                                                /* PRQA S 5087 # JV-01 */
#endif

#define SPI_START_SEC_PRIVATE_CODE
#include "Spi_Mapping.h"                                                                                                /* PRQA S 5087 # JV-01 */

/***********************************************************************************************************************
** Function Name      : Spi_HSPIInit
**
** Service ID         : Not Applicable
**
** Description        : This function initializes all configured HSPI units
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Non-Reentrant
**
** Input Parameters   : None
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : Global variables must have been initialized
**
** Global Variable    : Spi_GpConfigPtr, Spi_GpFirstJob, Spi_GpFirstHWUnit, Spi_GaaHSPIChannelBuffer, Spi_GaaHSPIRegs
**
** Function invoked   : Spi_HSPIDisableAllInterrupts, Spi_HSPIInitializeForJob
**
** Registers Used     : HSPInSRST, HSPInIREN
**
** Reference ID       : SPI_DUD_ACT_087, SPI_DUD_ACT_087_REG001, SPI_DUD_ACT_087_REG002, SPI_DUD_ACT_087_GBL001
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIInit(void)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig;
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWUnitInfo;
  uint32 LulHWPhyIndex;
  uint32 LulHWUnitIndex;
  uint32 LulInitialized;
  uint32 LulJobIndex;

  #if (SPI_MAX_HSPI_CHANNEL_BUFFER_SIZE > 0U)
  uint32 LulIndex;
  /* Init HSPI global channel bufffer */
  for (LulIndex = 0U; LulIndex < ((uint32)SPI_MAX_HSPI_CHANNEL_BUFFER_SIZE / (uint32)sizeof(uint32)); LulIndex++)
  {
    Spi_GaaHSPIChannelBuffer[LulIndex] = 0UL;
  }
  #endif

  for (LulHWUnitIndex = 0U; LulHWUnitIndex < Spi_GpConfigPtr->ucNoOfHWUnits; LulHWUnitIndex++)
  {
    LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
    if (SPI_MACRO_HSPI == LpHWInfo->ucMacroIndex)                                                                       /* PRQA S 2814, 2844 # JV-01, JV-01 */
    {
      LulHWPhyIndex = LpHWInfo->ucPhyUnitIndex;
      /* Reset HS-SPI */
      Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSRST = SPI_HSPI_SRST;                                                     /* PRQA S 2814 # JV-01 */
      /* Dummy read to wait reset completion */
      Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSRST;
      /* Enable all interrupts except parity error on HS-SPI unit.
         Parity error is detected by polling at the end of each Channel. */
      Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIREN = SPI_HSPI_BEE | SPI_HSPI_ROVFEE | SPI_HSPI_TUDREE | SPI_HSPI_CENDE;
    } /* else No action required */
  } /* End of while (LulHWUnit < SPI_MAX_HW_DETAILS) */

  /* Disable all interrupts in case of any condition before init */
  Spi_HSPIDisableAllInterrupts();

  /* To configure the idle state of SSLn and SPCK pins, initialize HWs according the first Job which is assigned
     to the HW */
  LulInitialized = 0UL;
  for (LulJobIndex = 0U; LulJobIndex < Spi_GpConfigPtr->usNoOfJobs; LulJobIndex++)
  {
    LpJobConfig = &Spi_GpFirstJob[LulJobIndex];
    LulHWUnitIndex = LpJobConfig->ucHWUnitIndex;                                                                        /* PRQA S 2844, 2814 # JV-01, JV-01 */
    LpHWUnitInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
    /* Avoid initializing same HW twice */
    if ((SPI_MACRO_HSPI == LpHWUnitInfo->ucMacroIndex) && (0UL == (LulInitialized & (1UL << LulHWUnitIndex))))          /* PRQA S 2814, 2844 # JV-01, JV-01 */
    {
      Spi_HSPIInitializeForJob(LpJobConfig);
      LulInitialized = LulInitialized | (1UL << LulHWUnitIndex);
    } /* else No action required */
  }
}

/***********************************************************************************************************************
** Function Name      : Spi_HSPIDeInit
**
** Service ID         : Not Applicable
**
** Description        : This function de-initializes all configured HSPI units
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Non-Reentrant
**
** Input Parameters   : None
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpConfigPtr, Spi_GpFirstHWUnit, Spi_GaaHSPIRegs
**
** Function invoked   : Spi_HSPIDisableAllInterrupts
**
** Registers Used     : HSPInSRST
**
** Reference ID       : SPI_DUD_ACT_088, SPI_DUD_ACT_088_REG001
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIDeInit(void)
{
  uint32 LulHWUnitIndex;
  uint32 LulHWPhyIndex;

  for (LulHWUnitIndex = 0U; LulHWUnitIndex < Spi_GpConfigPtr->ucNoOfHWUnits; LulHWUnitIndex++)
  {
    if (SPI_MACRO_HSPI == Spi_GpFirstHWUnit[LulHWUnitIndex].ucMacroIndex)
    {
      LulHWPhyIndex = Spi_GpFirstHWUnit[LulHWUnitIndex].ucPhyUnitIndex;
      /* Reset HS-SPI */
      Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSRST = SPI_HSPI_SRST;                                                     /* PRQA S 2814 # JV-01 */
    } /* else No action required */
  }

  /* Disable all interrupts */
  Spi_HSPIDisableAllInterrupts();
}

/***********************************************************************************************************************
** Function Name      : Spi_HSPIInitializeForJob
**
** Service ID         : Not Applicable
**
** Description        : Setup a HSPI unit according to Job and the first channel
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW, Non-Reentrant for same HW
**
** Input Parameters   : LpJobConfig - Pointer to the Job configuration
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpFirstChannel, Spi_GpFirstHWUnit, Spi_GaaHSPIRegs
**
** Function Invoked   : None
**
** Registers Used     : HSPInMD, HSPInCTL, HSPInCDIV, HSPInSSCTL, HSPInSCKDLY, HSPInSSNDLY, HSPInNFMDLY, HSPInSPLDLY
**
** Reference ID       : SPI_DUD_ACT_089, SPI_DUD_ACT_089_REG001, SPI_DUD_ACT_089_REG002, SPI_DUD_ACT_089_REG003,
** Reference ID       : SPI_DUD_ACT_089_REG004, SPI_DUD_ACT_089_REG005, SPI_DUD_ACT_089_REG006, SPI_DUD_ACT_089_REG007,
** Reference ID       : SPI_DUD_ACT_089_REG008
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_HSPIInitializeForJob(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig)
{
  uint32 LulHWPhyIndex;
  uint32 LulCTLValue;
  P2CONST(Spi_HSPIDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpHWDevConfig;
  P2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig;

  /* Get HW-dependent Job configuration */
  LpHWDevConfig = (P2CONST(Spi_HSPIDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA))LpJobConfig->pHWDevConfig;             /* PRQA S 0316, 2814 # JV-01, JV-01 */
  /* Get Channel config of the first Channel in a Job */
  LpChConfig = &Spi_GpFirstChannel[LpJobConfig->pChannelList[0]];                                                       /* PRQA S 2824 # JV-01 */

  LulHWPhyIndex = Spi_GpFirstHWUnit[LpJobConfig->ucHWUnitIndex].ucPhyUnitIndex;

  /* Merge Job common settings and channel specific settings and set it*/
  LulCTLValue = LpHWDevConfig->ulHSPICTL;                                                                               /* PRQA S 2814 # JV-01 */
  if (SPI_TRANSFER_START_LSB == LpChConfig->enTransferStart)                                                            /* PRQA S 2814, 2844 # JV-01, JV-01 */
  {
    LulCTLValue |= SPI_HSPI_LSBEN_LSB;
  } /* else No action required */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulMD = LpHWDevConfig->ulHSPIMD | SPI_HSPI_FLEN(LpChConfig->ucDataWidth);        /* PRQA S 2814, 3469 # JV-01, JV-01 */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCTL = LulCTLValue;
  /* Baudrate */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCDIV = (uint32)LpHWDevConfig->ucHSPICDIV;
  /* Clock polarity */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSSCTL = (uint32)LpHWDevConfig->ucHSPISSCTL;
  /* CS timing settings */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSCKDLY = (uint32)LpHWDevConfig->ucHSPISCKDLY;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSSNDLY = (uint32)LpHWDevConfig->ucHSPISSNDLY;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulNFMDLY = (uint32)LpHWDevConfig->ucHSPINFMDLY;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSPLDLY = (uint32)LpHWDevConfig->usHSPISPLDLY;
}

/***********************************************************************************************************************
** Function Name      : Spi_HSPIInitializeForCh
**
** Service ID         : Not Applicable
**
** Description        : Setup a HSPI unit according to Channel configuration
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW, Non-Reentrant for same HW
**
** Input Parameters   : LpJobConfig    - Pointer to the Job configuration
**                      LpChConfig     - Pointer to the Channel configuration
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpFirstHWUnit, Spi_GaaHSPIRegs
**
** Function Invoked   : None
**
** Registers Used     : HSPInMD, HSPInCTL
**
** Reference ID       : SPI_DUD_ACT_090, SPI_DUD_ACT_090_REG001, SPI_DUD_ACT_090_REG002
***********************************************************************************************************************/
#if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_HSPIInitializeForCh(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                            CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig)
{
  P2CONST(Spi_HSPIDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpHWDevConfig;
  uint32 LulHWPhyIndex;
  uint32 LulCTLValue;

  LpHWDevConfig = (P2CONST(Spi_HSPIDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA))LpJobConfig->pHWDevConfig;             /* PRQA S 0316, 2814 # JV-01, JV-01 */
  LulHWPhyIndex = Spi_GpFirstHWUnit[LpJobConfig->ucHWUnitIndex].ucPhyUnitIndex;

  /* Merge Job common settings and channel specific settings and set it*/
  LulCTLValue = LpHWDevConfig->ulHSPICTL;                                                                               /* PRQA S 2814 # JV-01 */
  if (SPI_TRANSFER_START_LSB == LpChConfig->enTransferStart)                                                            /* PRQA S 2814 # JV-01 */
  {
    LulCTLValue |= SPI_HSPI_LSBEN_LSB;
  } /* else No action required */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulMD = LpHWDevConfig->ulHSPIMD | SPI_HSPI_FLEN(LpChConfig->ucDataWidth);        /* PRQA S 2814, 3469 # JV-01, JV-01 */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCTL = LulCTLValue;
}
#endif /* (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF) */

/***********************************************************************************************************************
** Function Name      : Spi_HSPIProcessJob
**
** Service ID         : Not Applicable
**
** Description        : This function perform scheduling under Job layer
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW, Non-Reentrant for same HW
**
** Input Parameters   : LblFirst    - This is the first call for the Job
**                      LpJobConfig - Pointer to the Job configuration
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpFirstChannel, Spi_GpFirstHWUnit, Spi_GaaHWStatus, Spi_GaaHSPIRegs
**
** Function Invoked   : Spi_HSPIInitializeForJob, Spi_HSPIInitializeForCh
**
** Registers Used     : HSPInCKEN, HSPInTSAR, HSPInRDAR, HSPInCFSET, HSPInEN
**
** Reference ID       : SPI_DUD_ACT_092, SPI_DUD_ACT_092_GBL001, SPI_DUD_ACT_092_REG001, SPI_DUD_ACT_092_REG002,
** Reference ID       : SPI_DUD_ACT_092_REG003, SPI_DUD_ACT_092_REG004, SPI_DUD_ACT_092_REG005, SPI_DUD_ACT_092_REG006,
** Reference ID       : SPI_DUD_ACT_092_REG007, SPI_DUD_ACT_092_REG008
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_HSPIProcessJob(const boolean LblFirst, CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  volatile P2VAR(Spi_HWStatusType, AUTOMATIC, SPI_VAR_NO_INIT) LpHWStat;                                                /* PRQA S 3432 # JV-01 */
  uint32 LulHWPhyIndex;
  uint32 LulChIndex;
  P2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig;

  LpHWInfo = &Spi_GpFirstHWUnit[LpJobConfig->ucHWUnitIndex];                                                            /* PRQA S 2814 # JV-01 */
  LpHWStat = &Spi_GaaHWStatus[LpJobConfig->ucHWUnitIndex];                                                              /* PRQA S 2934 # JV-01 */
  LulHWPhyIndex = LpHWInfo->ucPhyUnitIndex;                                                                             /* PRQA S 2814, 2844 # JV-01, JV-01 */

  /*
   * If this is the start of Job, initialize entire HS-SPI.
   * Else, initialize channel relevant registers only.
   */
  if (SPI_TRUE == LblFirst)
  {
    /* Turn on IP */
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCKEN = SPI_HSPI_CKEN;                                                       /* PRQA S 2814 # JV-01 */

    LpHWStat->ucTxChannelCount = 0U;                                                                                    /* PRQA S 2844 # JV-01 */
    LulChIndex = LpJobConfig->pChannelList[0];                                                                          /* PRQA S 2824 # JV-01 */
    LpChConfig = &Spi_GpFirstChannel[LulChIndex];
    /* Initialize HW for Job */
    #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
    Spi_HSPIInitializeForJob(LpJobConfig);
    #endif
  }
  else
  {
    LulChIndex = LpJobConfig->pChannelList[LpHWStat->ucTxChannelCount];
    LpChConfig = &Spi_GpFirstChannel[LulChIndex];
    #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
    if (SPI_FALSE == LpJobConfig->blChannelPropertySame)
    {
      /* If settings is different from the previous channel, initialize HW for Ch */
      Spi_HSPIInitializeForCh(LpJobConfig, LpChConfig);
    } /* else No action required */
    #endif
  }

  /* Set buffer addresses and length to the DMA */
  #if (SPI_CHANNEL_BUFFERS_ALLOWED == SPI_IBEB)
  if (SPI_BUFFER_TYPE_IB == LpChConfig->enChannelBufferType)                                                            /* PRQA S 2844, 2814 # JV-01, JV-01 */
  #endif
  {
    #if ((SPI_CHANNEL_BUFFERS_ALLOWED == SPI_IB) || (SPI_CHANNEL_BUFFERS_ALLOWED == SPI_IBEB))
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulTSAR = (uint32)LpChConfig->pTxBuffer;                                       /* PRQA S 0303 # JV-01 */
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulRDAR = (uint32)LpChConfig->pRxBuffer;                                       /* PRQA S 0303 # JV-01 */
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCFSET = LpChConfig->usNoOfBuffers;
    #endif
  }
  #if (SPI_CHANNEL_BUFFERS_ALLOWED == SPI_IBEB)
  else
  #endif
  {
    #if ((SPI_CHANNEL_BUFFERS_ALLOWED == SPI_EB) || (SPI_CHANNEL_BUFFERS_ALLOWED == SPI_IBEB))
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulTSAR = (uint32)LpChConfig->pEBData->pSrcPtr;                                /* PRQA S 0306, 2814, 2844 # JV-01, JV-01, JV-01 */
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulRDAR = (uint32)LpChConfig->pEBData->pDestPtr;                               /* PRQA S 0306 # JV-01 */
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCFSET = LpChConfig->pEBData->usEBLength;
    #endif
  }

  /* Start transmission */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulEN = SPI_HSPI_EN;
}

/***********************************************************************************************************************
** Function Name      : Spi_HSPITransmitSyncJob
**
** Service ID         : Not Applicable
**
** Description        : This service is used for transmitting the sequences synchronously
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW, Non-Reentrant for same HW
**
** Input Parameters   : LpJobConfig - Poiner to the Job configuration
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : Std_ReturnType (E_OK/E_NOT_OK)
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variables   : Spi_GpFirstHWUnit, Spi_GaaHWStatus, Spi_GaaHSPIRegs, Spi_GpConfigPtr, Spi_GaaJobStatus,
**                      Spi_GaaSeqStatus
**
** Function Invoked   : SPI_DEM_REPORT_ERROR, Spi_HSPIProcessJob, Spi_HSPITurnOff
**
** Registers Used     : HSPInIRST, HSPInIRCL, HSPInEN
**
** Reference ID       : SPI_DUD_ACT_091, SPI_DUD_ACT_091_ERR001, SPI_DUD_ACT_091_ERR002, SPI_DUD_ACT_091_ERR003,
** Reference ID       : SPI_DUD_ACT_091_GBL001, SPI_DUD_ACT_091_GBL002, SPI_DUD_ACT_091_GBL003, SPI_DUD_ACT_091_GBL004,
** Reference ID       : SPI_DUD_ACT_091_GBL005, SPI_DUD_ACT_091_REG001, SPI_DUD_ACT_091_REG002
***********************************************************************************************************************/
#if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_0) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
STATIC FUNC(Std_ReturnType, SPI_PRIVATE_CODE)
    Spi_HSPITransmitSyncJob(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_PRIVATE_CONST) LpHWUnitInfo;
  uint32 LulHWPhyIndex;
  boolean LblIsFirstCh;
  uint32 LulWaitCount;
  uint32 LulJobIndex;
  uint32 LulChIndex;
  Std_ReturnType LucReturnValue;
  LucReturnValue = E_OK;

  /* Get the base address of the HW Unit */
  LpHWUnitInfo = &Spi_GpFirstHWUnit[LpJobConfig->ucHWUnitIndex];                                                        /* PRQA S 2814 # JV-01 */
  /* Get the main user base address */
  LulHWPhyIndex = LpHWUnitInfo->ucPhyUnitIndex;                                                                         /* PRQA S 2844, 2814 # JV-01, JV-01 */

  /* Get Job index */
  LulJobIndex = Spi_GaaHWStatus[LpJobConfig->ucHWUnitIndex].usOngoingJobIndex;                                          /* PRQA S 2844 # JV-01 */

  /* Loop for each channel */
  LulChIndex = 0U;
  LblIsFirstCh = SPI_TRUE;
  do
  {
    /* Setup HW for Job and send the first data */
    Spi_HSPIProcessJob(LblIsFirstCh, LpJobConfig);
    LblIsFirstCh = SPI_FALSE;

    /* Wait until transmit completion or any error except parity error */
    LulWaitCount = 0UL;
    while ((0UL == (Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIRST &                                                      /* PRQA S 2814 # JV-01 */
                    (SPI_HSPI_BEF | SPI_HSPI_ROVFEF | SPI_HSPI_TUDREF | SPI_HSPI_CENDF))) && (E_OK == LucReturnValue))
    {
      LulWaitCount++;                                                                                                   /* PRQA S 3383 # JV-01 */
      if (Spi_GpConfigPtr->ulTimeoutCount <= LulWaitCount)
      {
        #if (STD_ON == SPI_E_DATA_TX_TIMEOUT_FAILURE_CONFIGURED)
        SPI_DEM_REPORT_ERROR(SPI_E_DATA_TX_TIMEOUT_FAILURE, DEM_EVENT_STATUS_FAILED);                                   /* PRQA S 3469 # JV-01 */
        #endif
        /* Update Job status as FAILED */
        Spi_GaaJobStatus[LulJobIndex].enResult = SPI_JOB_FAILED;                                                        /* PRQA S 2844 # JV-01 */
        /* A least one Job failed, set Sequence failed flag */
        Spi_GaaSeqStatus[Spi_GaaHWStatus[LpJobConfig->ucHWUnitIndex].ucOngoingSeqIndex].blFailed = SPI_TRUE;            /* PRQA S 2844 # JV-01 */
        LucReturnValue = E_NOT_OK;
      } /* else No action required */
    }
    /* If any error occured, invoke error handler */
    if (0UL != (Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIRST &
                (SPI_HSPI_BEF | SPI_HSPI_PEF | SPI_HSPI_ROVFEF | SPI_HSPI_TUDREF)))
    {
      /* Report DEM */
      if (0UL != (Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIRST & (SPI_HSPI_BEF | SPI_HSPI_ROVFEF | SPI_HSPI_TUDREF)))
      {
        #if (STD_ON == SPI_E_DMA_ERROR_CONFIGURED)
        SPI_DEM_REPORT_ERROR(SPI_E_DMA_ERROR, DEM_EVENT_STATUS_FAILED);                                                 /* PRQA S 3469 # JV-01 */
        #endif
        /* If any of DMA relevant errors occur, abort immediately */
        LucReturnValue = E_NOT_OK;
      }
      else
      {
        #if (STD_ON == SPI_E_HARDWARE_ERROR_CONFIGURED)
        SPI_DEM_REPORT_ERROR(SPI_E_HARDWARE_ERROR, DEM_EVENT_STATUS_FAILED);                                            /* PRQA S 3469 # JV-01 */
        #endif
        /* Even if the parity error occurs, continue the tranmission */
      }
      /* Update Job status as FAILED */
      Spi_GaaJobStatus[LulJobIndex].enResult = SPI_JOB_FAILED;                                                          /* PRQA S 2844 # JV-01 */
    } /* else No action required */

    /* Clear all interrupt flags */
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIRCL =
        SPI_HSPI_BEC | SPI_HSPI_PEC | SPI_HSPI_ROVFEC | SPI_HSPI_TUDREC | SPI_HSPI_CSTAC | SPI_HSPI_CENDC;

    /* Clear Communication Eanble flag */
    Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulEN = 0UL;

    /* Increment Channel count in a Job */
    Spi_GaaHWStatus[LpJobConfig->ucHWUnitIndex].ucTxChannelCount++;                                                     /* PRQA S 2844, 3387, 3383 # JV-01, JV-01, JV-01 */

    LulChIndex++;                                                                                                       /* PRQA S 3383 # JV-01 */
  } while ((E_OK == LucReturnValue) && (LulChIndex < LpJobConfig->ucNoOfChannels));

  /* Update Job Status */
  if (SPI_JOB_FAILED != Spi_GaaJobStatus[LulJobIndex].enResult)                                                         /* PRQA S 2844 # JV-01 */
  {
    Spi_GaaJobStatus[LulJobIndex].enResult = SPI_JOB_OK;                                                                /* PRQA S 2844 # JV-01 */
  }
  else
  {
    /* If any error has been occurred, return E_NOT_OK */
    LucReturnValue = E_NOT_OK;
  }

  /* Turn off HSPI to de-active CS */
  Spi_HSPITurnOff(LulHWPhyIndex);

  return (LucReturnValue);
}
#endif /* ((SPI_LEVEL_DELIVERED == SPI_LEVEL_0) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)) */

/***********************************************************************************************************************
** Function Name      : Spi_HSPIComEndISR
**
** Service ID         : Not Applicable
**
** Description        : This is the interrupt service routine for transmission completion
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW, Non-Reentrant for same HW
**
** Input Parameters   : LulHWUnitIndex - Index of HWUnit configuration
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpFirstJob, Spi_GpFirstHWUnit, Spi_GaaHWStatus, Spi_GaaJobStatus, Spi_GaaHSPIRegs,
**                      Spi_GaaSeqStatus
**
** Function Invoked   : SPI_DEM_REPORT_ERROR, Spi_ProcessSequence, Spi_HSPIProcessJob, Spi_TurnOffHWUnit 
**
** Registers Used     : HSPInEN, HSPInIRCL, HSPInIRST
**
** Reference ID       : SPI_DUD_ACT_096, SPI_DUD_ACT_096_ERR001, SPI_DUD_ACT_096_GBL001, SPI_DUD_ACT_096_GBL002,
** Reference ID       : SPI_DUD_ACT_096_GBL003, SPI_DUD_ACT_096_GBL004, SPI_DUD_ACT_096_REG001, SPI_DUD_ACT_096_REG002
***********************************************************************************************************************/
#if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_1) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIComEndISR(const uint32 LulHWUnitIndex)                                             /* PRQA S 1505 # JV-01 */
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig;
  volatile P2VAR(Spi_HWStatusType, AUTOMATIC, SPI_VAR_NO_INIT) LpHWStat;                                                /* PRQA S 3432 # JV-01 */
  uint32 LulHWPhyIndex;

  LpHWStat = &Spi_GaaHWStatus[LulHWUnitIndex];                                                                          /* PRQA S 2934 # JV-01 */
  LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
  LpJobConfig = &Spi_GpFirstJob[LpHWStat->usOngoingJobIndex];                                                           /* PRQA S 0404, 2844 # JV-01, JV-01 */

  /* Get the main base address */
  LulHWPhyIndex = LpHWInfo->ucPhyUnitIndex;                                                                             /* PRQA S 2844, 2814 # JV-01, JV-01 */

  /* Check whether parity error has occurred */
  if (0UL != (Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIRST & SPI_HSPI_PEF))                                             /* PRQA S 2814 # JV-01 */
  {
    /* Report DEM */
    #if (STD_ON == SPI_E_HARDWARE_ERROR_CONFIGURED)
    SPI_DEM_REPORT_ERROR(SPI_E_HARDWARE_ERROR, DEM_EVENT_STATUS_FAILED);                                                /* PRQA S 3469 # JV-01 */
    #endif

    /* Update Job result as FAILED */
    Spi_GaaJobStatus[Spi_GaaHWStatus[LulHWUnitIndex].usOngoingJobIndex].enResult = SPI_JOB_FAILED;                      /* PRQA S 2844 # JV-01 */
    /* A least one Job failed, set Sequence failed flag */
    Spi_GaaSeqStatus[Spi_GaaHWStatus[LulHWUnitIndex].ucOngoingSeqIndex].blFailed = SPI_TRUE;
  } /* else No action required */

  /* Clear all interrupt flags */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIRCL =
      SPI_HSPI_BEC | SPI_HSPI_PEC | SPI_HSPI_ROVFEC | SPI_HSPI_TUDREC | SPI_HSPI_CSTAC | SPI_HSPI_CENDC;

  /* Clear Communication Enable flag */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulEN = 0UL;

  LpHWStat->ucTxChannelCount++;                                                                                         /* PRQA S 3387, 3383 # JV-01, JV-01 */
  if (LpJobConfig->ucNoOfChannels == LpHWStat->ucTxChannelCount)                                                        /* PRQA S 2844, 2814 # JV-01, JV-01 */
  {
    /* Disable HSPI unit to de-activate CS when the job finishes (SWS_Spi_00263) */
    Spi_TurnOffHWUnit(LpJobConfig);
    /* Update Job status */
    if (SPI_JOB_FAILED != Spi_GaaJobStatus[LpHWStat->usOngoingJobIndex].enResult)
    {
      Spi_GaaJobStatus[LpHWStat->usOngoingJobIndex].enResult = SPI_JOB_OK;
    } /* else No action required */
    /* Invoke the upper layer scheduler */
    Spi_ProcessSequence(LulHWUnitIndex);
  }
  else
  {
    Spi_HSPIProcessJob(SPI_FALSE, LpJobConfig);
  }
}
#endif /* ((SPI_LEVEL_DELIVERED == SPI_LEVEL_1) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)) */

/***********************************************************************************************************************
** Function Name      : Spi_HSPIErrorISR
**
** Service ID         : Not Applicable
**
** Description        : This is the interrupt service routine for Error, invoked when any of the following error occur:
**                      - BEF (H-BUS Error)
**                      - ROVFEF (Reception Overflow Error)
**                      - TOUDREF (Transmission Uderrun Error)
**                      Parity error doesn't raise the interrupt, it is checked when the communication completes.
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW, Non-Reentrant for same HW
**
** Input Parameters   : LulHWUnitIndex - Index of HWUnit configuration
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpFirstHWUnit, Spi_GaaHSPIRegs, Spi_GaaJobStatus, Spi_GaaHWStatus, Spi_GaaSeqStatus
**
** Function Invoked   : SPI_DEM_REPORT_ERROR
**
** Registers Used     : HSPInIRCL
**
** Reference ID       : SPI_DUD_ACT_097, SPI_DUD_ACT_097_ERR001, SPI_DUD_ACT_097_GBL001, SPI_DUD_ACT_097_GBL002,
** Reference ID       : SPI_DUD_ACT_097_REG001
***********************************************************************************************************************/
#if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_1) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
FUNC(void, SPI_CODE_FAST) Spi_HSPIErrorISR(const uint32 LulHWUnitIndex)                                                 /* PRQA S 1505 # JV-01 */
{
  uint32 LulHWPhyIndex;

  LulHWPhyIndex = Spi_GpFirstHWUnit[LulHWUnitIndex].ucPhyUnitIndex;

  /* Report DEM */
  #if (STD_ON == SPI_E_DMA_ERROR_CONFIGURED)
  SPI_DEM_REPORT_ERROR(SPI_E_DMA_ERROR, DEM_EVENT_STATUS_FAILED);                                                       /* PRQA S 3469 # JV-01 */
  #endif

  /* Clear all error flags */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIRCL = SPI_HSPI_BEC | SPI_HSPI_PEC | SPI_HSPI_ROVFEC | SPI_HSPI_TUDREC;       /* PRQA S 2814 # JV-01 */

  /* Update Job result as FAILED */
  Spi_GaaJobStatus[Spi_GaaHWStatus[LulHWUnitIndex].usOngoingJobIndex].enResult = SPI_JOB_FAILED;                        /* PRQA S 2844 # JV-01 */

  /* A least one Job failed, set Sequence failed flag */
  Spi_GaaSeqStatus[Spi_GaaHWStatus[LulHWUnitIndex].ucOngoingSeqIndex].blFailed = SPI_TRUE;

  /* If any error except parity error occurs, CEND interrupt never happen.
     So if one of these errors occurred, SPI driver can't be recovered automatically. */

}
#endif /* ((SPI_LEVEL_DELIVERED == SPI_LEVEL_1) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)) */

/***********************************************************************************************************************
** Function Name          : Spi_HSPIDisableAllInterrupts
**
** Service ID             : NA
**
** Description            : This service disables interrupts for all HSPI units
**
** Sync/Async             : Synchronous
**
** Re-entrancy            : Non-Reentrant
**
** Input Parameters       : None
**
** InOut Parameters       : None
**
** Output Parameters      : None
**
** Return parameter       : None
**
** Preconditions          : Global variables must have been initialized
**
** Global Variable        : Spi_GpConfigPtr, Spi_GpFirstHWUnit, Spi_GaaHSPIRegs
**
** Function invoked       : None
**
** Registers Used         : EIC(HSPInCEND), EIC(HSPInERR), EIC(HSPInBERR)
**
** Reference ID           : SPI_DUD_ACT_094, SPI_DUD_ACT_094_REG001, SPI_DUD_ACT_094_REG002, SPI_DUD_ACT_094_REG003,
** Reference ID           : SPI_DUD_ACT_094_REG004, SPI_DUD_ACT_094_REG005, SPI_DUD_ACT_094_REG006
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIDisableAllInterrupts(void)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  uint32 LulHWUnitIndex;

  for (LulHWUnitIndex = 0U; LulHWUnitIndex < Spi_GpConfigPtr->ucNoOfHWUnits; LulHWUnitIndex++)
  {
    LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
    if (SPI_MACRO_HSPI == LpHWInfo->ucMacroIndex)                                                                       /* PRQA S 2814, 2844 # JV-01, JV-01 */
    {
      /* Disable interrupts */
      RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICCEND, (uint8)SPI_EIC_EIMK_MASK);             /* PRQA S 2814, 0751 # JV-01, JV-01 */
      RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICERR, (uint8)SPI_EIC_EIMK_MASK);              /* PRQA S 0751 # JV-01 */
      RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICBERR, (uint8)SPI_EIC_EIMK_MASK);             /* PRQA S 0751 # JV-01 */
      /* Clear pending interrupts */
      RH850_SV_MODE_ICR_AND(16, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICCEND, (uint16)(~SPI_EIC_EIRF_MASK));
      RH850_SV_MODE_ICR_AND(16, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICERR, (uint16)(~SPI_EIC_EIRF_MASK));
      RH850_SV_MODE_ICR_AND(16, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICBERR, (uint16)(~SPI_EIC_EIRF_MASK));
    } /* else No action required */
  }
  /* DummyRead & SYNCP */
  RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaHSPIRegs[0].pICCEND);
  EXECUTE_SYNCP();
}

/***********************************************************************************************************************
** Function Name      : Spi_HSPIMainFunction_Handling
**
** Service ID         : Not Applicable
**
** Description        : This function performs the polling operation
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Non-Reentrant
**
** Input Parameters   : None
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpConfigPtr, Spi_GpFirstHWUnit, Spi_GulCancelingHWUnits,
**                      Spi_GulActiveHWUnits, Spi_GaaHSPIRegs
**
** Function Invoked   : Spi_HSPIErrorISR, Spi_HSPIComEndISR
**
** Registers Used     : HSPInIRST
**
** Reference ID       : SPI_DUD_ACT_095
***********************************************************************************************************************/
#if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPIMainFunction_Handling(void)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  uint32 LulHWUnitIndex;
  uint32 LulIRSTRegValue;

  for (LulHWUnitIndex = 0U; LulHWUnitIndex < Spi_GpConfigPtr->ucNoOfHWUnits; LulHWUnitIndex++)
  {
    LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
    /*
    Spi_GulCancelingHWUnits is modified by Spi_ForceCancel, but no critical section is required here for this variable.
    Because:
    - Spi_ForceCancel is modified in the interrupt disabled section.
    - Spi_ForceCancel can't be invoked in any higher priority task than
    Spi_MainFunction_Handling, so Spi_GulCancelHWUnits is never changed while this function is executing.
    */

    /*
    Spi_GulActiveHWUnits is modified by Spi_SyncTransmit, Spi_AsyncTransmit.
    - In case of Spi_SyncTransmit, It should not be invoked in any higher priority task than Spi_MainFunction_Handling
    for a sequence associated with on-going HW unit. Calling the API Spi_GetHWUnitStatus to check whether HW unit is
    on-going or not.
    - In case of Spi_AsyncTransmit, sequence pending state is checked before modifying Spi_GulActiveHWUnits.
    Therefore re-entrancy between Spi_AsyncTransmit and Spi_MainFunction_Handling are not affected.
    */
    if ((SPI_MACRO_HSPI == LpHWInfo->ucMacroIndex)                                                                      /* PRQA S 2844, 2814 # JV-01, JV-01 */
        #if (SPI_AR_VERSION == SPI_AR_422_VERSION)
        && (SPI_FALSE == LpHWInfo->blSynchronous)
        #elif (SPI_AR_VERSION == SPI_AR_431_VERSION)
        && (0UL == (Spi_GulActiveHWUnits & (1UL << LulHWUnitIndex)))
        #endif
        #if (SPI_FORCE_CANCEL_API == STD_ON)
        && (0UL == (Spi_GulCancelingHWUnits & (1UL << LulHWUnitIndex)))
        #endif
    )
    {
      /*
        When the error bits and the complete bit are set at same time, the error bits must be handled before the
        complete bit. To prevent IRST register value be changed during polling, copy it to the local variable.
      */
      LulIRSTRegValue = Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pRegs->ulIRST;                                        /* PRQA S 2814 # JV-01 */

      /* Check error falgs except parity error */
      if (0UL != (LulIRSTRegValue & (SPI_HSPI_BEF | SPI_HSPI_ROVFEF | SPI_HSPI_TUDREF)))
      {
        Spi_HSPIErrorISR(LulHWUnitIndex);
      } /* else No action required */

      /* Check transmission complete */
      if (0UL != (LulIRSTRegValue & SPI_HSPI_CENDF))
      {
        Spi_HSPIComEndISR(LulHWUnitIndex);
      } /* else No action required */
    }
  }
}
#endif /* (SPI_LEVEL_DELIVERED == SPI_LEVEL_2) */

#if ((SPI_LEVEL_DELIVERED != SPI_LEVEL_0) && (SPI_FORCE_CANCEL_API == STD_ON))
/***********************************************************************************************************************
** Function Name      : Spi_HSPIForceStop
**
** Service ID         : Not Applicable
**
** Description        : This function stops a HS-SPI unit unconditionally
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HWUnit. Non-Reentrant for same HWUnit
**
** Input Parameters   : LulHWUnitIndex - Index of HW to be stopped
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : The interrupts of target HWUnit are disabled
**
** Global Variable    : Spi_GpFirstHWUnit, Spi_GaaHSPIRegs, Spi_GpConfigPtr
**
** Function Invoked   : None
**
** Registers Used     : HSPInEN, HSPInACTST, HSPInMD, HSPInCTL, HSPInSSCTL, HSPInIREN, HSPInCDIV, HSPInSCKDLY,
**                      HSPInSSNDLY, HSPInNFMDLY, HSPInSPLDLY, HSPInSRST,
**                      EIC(HSPInCEND), EIC(HSPInERR), EIC(HSPInBERR)
**
** Reference ID       : SPI_DUD_ACT_098, SPI_DUD_ACT_098_REG001, SPI_DUD_ACT_098_REG002, SPI_DUD_ACT_098_REG003,
** Reference ID       : SPI_DUD_ACT_098_REG004, SPI_DUD_ACT_098_REG005, SPI_DUD_ACT_098_REG006, SPI_DUD_ACT_098_REG007,
** Reference ID       : SPI_DUD_ACT_098_REG008, SPI_DUD_ACT_098_REG009
***********************************************************************************************************************/
STATIC FUNC(void, SPI_CODE_FAST) Spi_HSPIForceStop(const uint32 LulHWUnitIndex)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  uint32 LulHWPhyIndex;
  uint32 LulCount;
  uint32 LulMDRegValue;
  uint32 LulCTLRegValue;
  uint32 LulSSCTLRegValue;
  uint32 LulIRENRegValue;
  #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_ON)
  uint32 LulCDIVRegValue;
  uint32 LulSCKDLYRegValue;
  uint32 LulSSNDLYRegValue;
  uint32 LulNFMDLYRegValue;
  uint32 LulSPLDLYRegValue;
  #endif

  /* Get pointers and index relevant to HW */
  LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
  LulHWPhyIndex = LpHWInfo->ucPhyUnitIndex;                                                                             /* PRQA S 2814, 2844 # JV-01, JV-01 */

  /* Stop SPI unit by HSPInEN.HSPInEN = 0 */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulEN = 0UL;                                                                     /* PRQA S 2814 # JV-01 */

  /* Wait until the operation status becomes non-active. This loop never cause timeout unless a HW malfunctions. */
  LulCount = 0UL;
  while ((LulCount < Spi_GpConfigPtr->ulTimeoutCount) &&
         (0UL != (Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulACTST & SPI_HSPI_ACTF)))
  {
    LulCount++;
  }

  /* Backup regisers which are initialized by software reset */
  LulMDRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulMD;
  LulCTLRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCTL;
  LulSSCTLRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSSCTL;
  LulIRENRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIREN;
  #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_ON)
  LulCDIVRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCDIV;
  LulSCKDLYRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSCKDLY;
  LulSSNDLYRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSSNDLY;
  LulNFMDLYRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulNFMDLY;
  LulSPLDLYRegValue = Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSPLDLY;
  #endif

  /* Perform software reset */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSRST = SPI_HSPI_SRST;

  /* Dummy read to wait reset completion */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSRST;

  /* Restore registers after software reset */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulMD = LulMDRegValue;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCTL = LulCTLRegValue;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSSCTL = LulSSCTLRegValue;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulIREN = LulIRENRegValue;
  #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_ON)
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCDIV = LulCDIVRegValue;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSCKDLY = LulSCKDLYRegValue;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSSNDLY = LulSSNDLYRegValue;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulNFMDLY = LulNFMDLYRegValue;
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulSPLDLY = LulSPLDLYRegValue;
  #endif

  /* To ensure SPI unit was stopped, do dummy read & SYNCP */
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulEN;
  EXECUTE_SYNCP();

  /* Clear pending interrupt flags */
  RH850_SV_MODE_ICR_AND(16, (Spi_GaaHSPIRegs[LulHWPhyIndex].pICCEND), (uint16)(~SPI_EIC_EIRF_MASK));
  RH850_SV_MODE_ICR_AND(16, (Spi_GaaHSPIRegs[LulHWPhyIndex].pICERR), (uint16)(~SPI_EIC_EIRF_MASK));
  RH850_SV_MODE_ICR_AND(16, (Spi_GaaHSPIRegs[LulHWPhyIndex].pICBERR), (uint16)(~SPI_EIC_EIRF_MASK));

  RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICCEND, (uint8)SPI_EIC_EIMK_MASK);                 /* PRQA S 0751 # JV-01 */
  RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICERR, (uint8)SPI_EIC_EIMK_MASK);                  /* PRQA S 0751 # JV-01 */
  RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICBERR, (uint8)SPI_EIC_EIMK_MASK);                 /* PRQA S 0751 # JV-01 */

  /* To ensure interrupt requests were cleared, do dummy read & SYNCP */
  RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaHSPIRegs[LulHWPhyIndex].pICCEND);
  EXECUTE_SYNCP();
}
#endif /* ((SPI_LEVEL_DELIVERED != SPI_LEVEL_0) && (SPI_FORCE_CANCEL_API == STD_ON)) */

/***********************************************************************************************************************
** Function Name      : Spi_HSPIMaskHWUnitInterrupts
**
** Service ID         : NA
**
** Description        : This function manipulates interrupt masks of a HWUnit
**                      This function modifies EIMK bit only, EIRF bit is not affected.
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HWUnit
**                      Non-Reentrant for same HWUnit
**
** Input Parameters   : LpJobConfig    - Pointer to the Job configuration
**                      LblMask        - TRUE: set mask FALSE: reset mask
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : Global variables must be initialized
**
** Global Variable    : Spi_GpFirstHWUnit, Spi_GaaHSPIRegs
**
** Function invoked   : SPI_ENTER_CRITICAL_SECTION, SPI_EXIT_CRITICAL_SECTION
**
** Registers Used     : EIC(HSPInCEND), EIC(HSPInERR), EIC(HSPInBERR)
**
** Reference ID       : SPI_DUD_ACT_099, SPI_DUD_ACT_099_REG001, SPI_DUD_ACT_099_REG002, SPI_DUD_ACT_099_REG003,
** Reference ID       : SPI_DUD_ACT_099_REG004, SPI_DUD_ACT_099_REG005, SPI_DUD_ACT_099_REG006, SPI_DUD_ACT_099_CRT001,
** Reference ID       : SPI_DUD_ACT_099_CRT002
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_HSPIMaskHWUnitInterrupts(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                                 const boolean LblMask)
{
  uint32 LulHWUnitIndex;
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  /* Get HW unit index */
  LulHWUnitIndex = LpJobConfig->ucHWUnitIndex;                                                                          /* PRQA S 2814 # JV-01 */
  LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];

  /* INTERRUPT_PROTECTION is required to avoid ISR occur while EIMK is being set */
  SPI_ENTER_CRITICAL_SECTION(SPI_INTERRUPT_CONTROL_PROTECTION);
  /* Write the lower byte of EIC register to avoid modifing EIRF bit */
  if (SPI_TRUE == LblMask)
  {
    RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICCEND, (uint8)SPI_EIC_EIMK_MASK);               /* PRQA S 2814, 0751, 2844 # JV-01, JV-01, JV-01 */
    RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICERR, (uint8)SPI_EIC_EIMK_MASK);                /* PRQA S 0751 # JV-01 */
    RH850_SV_MODE_ICR_OR(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICBERR, (uint8)SPI_EIC_EIMK_MASK);               /* PRQA S 0751 # JV-01 */
  }
  else
  {
    RH850_SV_MODE_ICR_AND(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICCEND, (uint8)(~SPI_EIC_EIMK_MASK));           /* PRQA S 0751 # JV-01 */
    RH850_SV_MODE_ICR_AND(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICERR, (uint8)(~SPI_EIC_EIMK_MASK));            /* PRQA S 0751 # JV-01 */
    RH850_SV_MODE_ICR_AND(8, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICBERR, (uint8)(~SPI_EIC_EIMK_MASK));           /* PRQA S 0751 # JV-01 */
  }
  /* To ensure interrupt masks were set, do dummy read & SYNCP */
  RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaHSPIRegs[LpHWInfo->ucPhyUnitIndex].pICCEND);
  EXECUTE_SYNCP();
  SPI_EXIT_CRITICAL_SECTION(SPI_INTERRUPT_CONTROL_PROTECTION);
}

/***********************************************************************************************************************
** Function Name      : Spi_HSPITurnOff
**
** Service ID         : Not Applicable
**
** Description        : This function turn off HSPI
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant
**
** Input Parameters   : LulHWPhyIndex - Physical index of the HWUnit
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : None
**
** Global Variable    : Spi_GaaHSPIRegs
**
** Function Invoked   : None
**
** Registers Used     : HSPInCKEN
**
** Reference ID       : SPI_DUD_ACT_100, SPI_DUD_ACT_100_REG001
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_HSPITurnOff(const uint32 LulHWPhyIndex)
{
  Spi_GaaHSPIRegs[LulHWPhyIndex].pRegs->ulCKEN = 0UL;                                                                   /* PRQA S 2844, 2814 # JV-01, JV-01 */
}

#define SPI_STOP_SEC_PRIVATE_CODE
#include "Spi_Mapping.h"                                                                                                /* PRQA S 5087 # JV-01 */

#endif /* (SPI_HSPI_CONFIGURED == STD_ON) */
/***********************************************************************************************************************
**                                                    End of File                                                     **
***********************************************************************************************************************/
