/*====================================================================================================================*/
/* Project      = AUTOSAR Renesas X2x MCAL Components                                                                 */
/* Module       = Spi_CSIX_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:  15/11/2022  : As per ARDAACA-1302
 *                       Spi_CSIXDeInit, Spi_CSIXProcessJob, Spi_CSIXReceiveISR, Spi_CSIXDMACompleteISR: Add 
 *                       Spi_CSIXHWControlCS into Funciton invoked field
 *                       Spi_CSIXTransmitSyncJob: Add Spi_DMAClearInterruptFlag, Spi_DMAGetInterruptFlag 
 *                       into Funciton invoked field
 *                       Spi_CSIXMainFunction_Handling: Add Spi_CSIXDMACompleteISR into Function invoked
 *         10/11/2022  : As per ARDAACA-1266
 *                       Spi_CSIXDeInit: Change Spi_GpConfig to Spi_GpConfigPtr
 *                       Spi_CSIXTransmitSyncJob: Change Spi_GpForstHWUnit to Spi_GpFirstHWUnit in
 *                       Global Variables field
 *                       Spi_CSIXDMACompleteISR: Change LulHWUnitIndex to LulDMAUnitIndex in Input Parameters field
 *                       Spi_CSIXMaskHWUnitInterrupts: Remove Spi_GpConfigPtr in Global variable field 
 *         18/07/2022  : Add QAC message for Spi_CSIXHWControlCS, Changed SPI_DUD_ACT_101 to SPI_DUD_ACT_103
 *         13/07/2022  : Update operator AND for Spi_CSIXHWControlCS
 *         08/07/2022  : Add DummyRead & SYNCP in functions: Spi_CSIXTransmitSyncJob, Spi_CSIXDisableAllInterrupts,
 *                       Spi_CSIXMainFunction_Handling
 * 1.4.3:  21/06/2022  : Added de-active CS when CS as GPIO for Spi_CSIXReceiveISR, Spi_CSIXDMACompleteISR, 
 *                       Spi_CSIXDeInit
 *                       Add active CS when CS as GPIO for Spi_CSIXProcessJob (start transmit)
 *                       Add new function Spi_CSIXHWControlCS to control CS via GPIO
 *         14/04/2022  : Add new QAC message 4399, 4391
 *         10/05/2022  : Remove else do nothing
 * 1.4.1:  09/09/2021  : Change ucCSInfo to usCSInfo and update SW-VERSION to 1.4.1
 * 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)
 *         13/05/2021  : Update to fix coding rule violations.
 * 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.3:  10/06/2020  : Change access size of CSIHnEIE and CSIHnECTL0 from 8bit to 32bit access in Spi_CSIXInit and
 *                       Spi_CSIXDeInit.
 * 1.0.2:  22/05/2020  : Update QAC warning and MISRA-C Rule violation
 * 1.0.1:  23/04/2020  : 1. Update function Spi_CSIXTransmitSynJob to support DMA in level 0.
 *                       2. Update type casting for arguments when calling Spi_DMAStart in 
 *                          Spi_CSIXStartChannelDirectAccessMode
 *         16/04/2020  : 1. Update condition for Level 0 and Level 2 in Spi_CSIXDMACompleteISR.
 *         15/04/2020  : 1. Remove pre-compile option of Spi_CSIXDMACompleteISR to support DMA in level 0.
 * 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_CSIX_LLDriver.h"                                                                                          /* PRQA S 0857 # JV-01 */
#include "rh850_Types.h"
#include "Dem.h"

/***********************************************************************************************************************
**                                                Version Information                                                 **
***********************************************************************************************************************/
/* AUTOSAR release version information */
#define SPI_CSIX_LLDRIVER_C_AR_RELEASE_MAJOR_VERSION    SPI_AR_RELEASE_MAJOR_VERSION_VALUE
#define SPI_CSIX_LLDRIVER_C_AR_RELEASE_MINOR_VERSION    SPI_AR_RELEASE_MINOR_VERSION_VALUE                              /* PRQA S 0791 # JV-01 */
#define SPI_CSIX_LLDRIVER_C_AR_RELEASE_REVISION_VERSION SPI_AR_RELEASE_REVISION_VERSION_VALUE                           /* PRQA S 0791 # JV-01 */

/* File version information */
#define SPI_CSIX_LLDRIVER_C_SW_MAJOR_VERSION            SPI_SW_MAJOR_VERSION_VALUE
#define SPI_CSIX_LLDRIVER_C_SW_MINOR_VERSION            SPI_SW_MINOR_VERSION_VALUE

/***********************************************************************************************************************
**                                                   Version Check                                                    **
***********************************************************************************************************************/
#if (SPI_CSIX_LLDRIVER_AR_RELEASE_MAJOR_VERSION != SPI_CSIX_LLDRIVER_C_AR_RELEASE_MAJOR_VERSION)
#error "Spi_CSIX_LLDriver.c : Mismatch in Release Major Version"
#endif

#if (SPI_CSIX_LLDRIVER_AR_RELEASE_MINOR_VERSION != SPI_CSIX_LLDRIVER_C_AR_RELEASE_MINOR_VERSION)
#error "Spi_CSIX_LLDriver.c : Mismatch in Release Minor Version"
#endif

#if (SPI_CSIX_LLDRIVER_AR_RELEASE_REVISION_VERSION != SPI_CSIX_LLDRIVER_C_AR_RELEASE_REVISION_VERSION)
#error "Spi_CSIX_LLDriver.c : Mismatch in Release Revision Version"
#endif

#if (SPI_CSIX_LLDRIVER_SW_MAJOR_VERSION != SPI_CSIX_LLDRIVER_C_SW_MAJOR_VERSION)
#error "Spi_CSIX_LLDriver.c : Mismatch in Software Major Version"
#endif

#if (SPI_CSIX_LLDRIVER_SW_MINOR_VERSION != SPI_CSIX_LLDRIVER_C_SW_MINOR_VERSION)
#error "Spi_CSIX_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 (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 (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: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: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: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: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:0488)    : Performing pointer arithmetic.                                                               */
/* Rule                : CERTCCM EXP08, MISRA C:2012 Rule-18.4                                                        */
/* JV-01 Justification : This is to get the ID in the data structure in the code.                                     */
/*       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:0314)    : Cast from a pointer to object type to a pointer to void.                                     */
/* Rule                : MISRA C:2012 Dir-1.1                                                                         */
/* JV-01 Justification : This is necessary to set pointer value to DMA register.                                      */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (1:3384)    : Cannot identify wraparound guard for dependent unsigned arithmetic expression.               */
/* Rule                : CERTCCM INT30                                                                                */
/* JV-01 Justification : In order to effectively guard against overflow and wraparound at all stages, the expression  */
/*                       should be split up into individual dynamic operations, with their own guards where applicable*/
/*       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 (2:3678)    : The object referenced by '%1s' is not modified through it, so '%1s' could be declared with   */
/*                       type '%2s'.                                                                                  */
/* Rule                : MISRA C:2012 Rule-8.13                                                                       */
/* JV-01 Justification : This is accepted. It just an advise for  improve safety by reducing the possibility that     */
/*                       the referenced data is unintentionally modified through an unexpected alias and improves     */
/*                       clarity by indicating that the referenced data is not intended to be modified through this   */
/*                       alias or those depending on it                                                               */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (6:2962)    : Apparent: Using value of uninitialized automatic object '%s'.                                */
/* Rule                : CERTCCM EXP33, MISRA C:2012 Rule-9.1                                                         */
/* JV-01 Justification : It will be initialized based on scope of 'if' statements  where at least an 'if' statement   */
/*                       will be executed that will initialize the variable.                                          */
/*       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 (2:0310)    : Casting to different object pointer type.                                                    */
/* Rule                : CERTCCM EXP11, EXP39, MISRA C:2012 Rule-11.3                                                 */
/* JV-01 Justification : For accessing 8-bit and 16-bit PNOT and JPNOT register respectively, the 32-bit pointer is   */
/*                       typecasted.                                                                                  */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (6:3305)    : Pointer cast to stricter alignment.                                                          */
/* Rule                : CERTCCM EXP36, EXP39, MISRA C:2012 Rule-11.3                                                 */
/* JV-01 Justification : Pointer alignment is changed by casting, but it's necessary for embedded programming         */
/*       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.              */
/**********************************************************************************************************************/
/* 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 (4:4399)    : An expression which is the result of a ~ or << operation has been cast to a wider type.      */
/* Rule                : MISRA C:2012 Rule-10.8                                                                       */
/* JV-01 Justification : The result has been ensured by casting to the same Type                                      */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (4:4391)    : A composite expression of 'essentially unsigned' type (%1s) is being cast to a wider         */
/*                       unsigned type, '%2s'.                                                                        */
/* Rule                : MISRA C:2012 Rule-10.8                                                                       */
/* JV-01 Justification : This casting is for the lower operator which requires wider type.                            */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (3:3416)    : Logical operation performed on expression with persistent side effects.                      */
/* Rule                : CERTCCM EXP45                                                                                */
/* JV-01 Justification : Logical operation accesses volatile object which is a register access. All register          */
/*                       addresses are generated with volatile qualifier. There is no impact on the functionality     */
/*                       due to this conditional check for mode change.                                               */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/

/***********************************************************************************************************************
**                                                Function Definitions                                                **
***********************************************************************************************************************/
#if (SPI_CSIH_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_CSIXInit(void);
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXDeInit(void);
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXDisableAllInterrupts(void);
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXProcessJob(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_CSIXTransmitSyncJob(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig);
#endif
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXMaskHWUnitInterrupts(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_CSIXForceStop(const uint32 LulHWUnitIndex);
#endif
#endif
#if (SPI_DMA_CONFIGURED == STD_ON)
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXDMACompleteISR(const uint32 LulDMAUnitIndex);
#endif
#if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXMainFunction_Handling(void);
#endif
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXTurnOff(const uint32 LulHWPhyIndex);

STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXInitializeForJob(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                             const boolean LblCFGxOnly);

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

STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXStartChannelDirectAccessMode(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                                         CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig,
                                         volatile CONSTP2VAR(Spi_HWStatusType, AUTOMATIC, SPI_VAR_NO_INIT) LpHWStat,    /* PRQA S 3432 # JV-01 */
                                         const uint32 LulHWPhyIndex);

STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_LoadTxData(volatile CONSTP2CONST(Spi_DataBufferType, AUTOMATIC, SPI_APPL_DATA) LpData,
                   CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig,
                   volatile CONSTP2VAR(uint32, AUTOMATIC, AUTOMATIC) LpFirstWord                                        /* PRQA S 3432 # JV-01 */
                   #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
                   ,
                   volatile CONSTP2VAR(uint32, AUTOMATIC, SPI_VAR_NO_INIT) LpSecondWord                                 /* PRQA S 3432 # JV-01 */
                   #endif
    );

STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_StoreRxData(volatile CONSTP2VAR(Spi_DataBufferType, AUTOMATIC, SPI_APPL_DATA) LpData,                           /* PRQA S 3432 # JV-01 */
                    CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig,
                    #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
                    const uint16 LusFirstWord,
                    #endif
                    const uint16 LusSecondWord);
#if (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON)
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXHWControlCS(
  CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
  CONST(boolean, AUTOMATIC) LblActivateCS);
#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_GstCSIXFunc =                                                                 /* PRQA S 1531 # JV-01 */
{
  &Spi_CSIXInit,
  &Spi_CSIXDisableAllInterrupts,
  &Spi_CSIXProcessJob,
  #if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_0) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
  &Spi_CSIXTransmitSyncJob,
  #endif
  &Spi_CSIXMaskHWUnitInterrupts,
  #if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_1) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
  #if (SPI_FORCE_CANCEL_API == STD_ON)
  &Spi_CSIXForceStop,
  #endif
  #endif
  #if (SPI_DMA_CONFIGURED == STD_ON)
  &Spi_CSIXDMACompleteISR,
  #endif
  #if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
  &Spi_CSIXMainFunction_Handling,
  #endif
  &Spi_CSIXTurnOff,
  &Spi_CSIXDeInit
};

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

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

#if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
/* Extended data length statuses */
STATIC VAR(Spi_CSIXEDLStatusType, SPI_VAR_NO_INIT) Spi_GaaEDLStatus[SPI_MAX_HWUNIT];
#endif /* (SPI_EXTENDED_DATA_LENGTH == STD_ON) */

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

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

/***********************************************************************************************************************
** Function Name      : Spi_CSIXInit
**
** Service ID         : Not Applicable
**
** Description        : This function initializes all configured CSIH 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_GaaEDLStatus, Spi_GaaCSIHRegs, Spi_GpFirstJob
**
** Function invoked   : Spi_CSIXInitializeForJob, Spi_CSIXDisableAllInterrupts
**
** Registers Used     : CSIHnECTL0, CSIHnEIE, CSIXnCTL0, CSIXnCTL1, CSIXnSTCR0
**
** Reference ID       : SPI_DUD_ACT_041, SPI_DUD_ACT_041_REG001, SPI_DUD_ACT_041_REG002, SPI_DUD_ACT_041_REG003,
** Reference ID       : SPI_DUD_ACT_041_REG004, SPI_DUD_ACT_041_REG005, SPI_DUD_ACT_041_GBL001
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXInit(void)
{
  uint32 LulHWPhyIndex;
  uint32 LulHWUnitIndex;
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig;
  #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
  P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpHWDevConfig;
  #endif
  uint32 LulJobIndex;
  uint32 LulInitialized;

  for (LulHWUnitIndex = 0U; LulHWUnitIndex < Spi_GpConfigPtr->ucNoOfHWUnits; LulHWUnitIndex++)
  {
    #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
    Spi_GaaEDLStatus[LulHWUnitIndex].blTxEDLOngoing = SPI_FALSE;                                                        /* PRQA S 2844 # JV-01 */
    Spi_GaaEDLStatus[LulHWUnitIndex].blRxEDLOngoing = SPI_FALSE;                                                        /* PRQA S 2844 # JV-01 */
    Spi_GaaEDLStatus[LulHWUnitIndex].ulTxEDLSecondWord = 0UL;                                                           /* PRQA S 2844 # JV-01 */
    Spi_GaaEDLStatus[LulHWUnitIndex].usRxEDLFirstWord = 0U;                                                             /* PRQA S 2844 # JV-01 */
    #endif

    LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
    if (SPI_MACRO_CSIH == LpHWInfo->ucMacroIndex)                                                                       /* PRQA S 2814, 2844 # JV-01, JV-01 */
    {
      LulHWPhyIndex = LpHWInfo->ucPhyUnitIndex;
      /* Disable Extended Communication */
      Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ulECTL0 = 0U;                                                               /* PRQA S 2814 # JV-01 */
      /* Enable interrupt requests */
      Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ulEIE = (SPI_CSIH_EICE | SPI_CSIH_EIRE | SPI_CSIH_EIEE | SPI_CSIH_EIJE);
      /* Set default values to registers */
      /* Step 1. Clear PWR */
      Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 &= (uint8)(~SPI_CSIX_PWR);
      /* Step 2. Set TXE, RXE, MBS and PWR at same time */
      Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = SPI_CSIH_CTL0_TURNON;
      /* Step 3. Clear PWR */
      Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = SPI_CSIH_CTL0_TURNOFF;
      /* Clear all status bits */
      Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->usSTCR0 = (uint16)(SPI_CSIX_DCEC | SPI_CSIX_PEC | SPI_CSIX_OVEC);
    } /* else No action required */
  }

  /* Disable all interrupts unconditionally */
  Spi_CSIXDisableAllInterrupts();

  /* Initialize already initialized flags */
  LulInitialized = 0UL;
  /* Scan all jobs and initialize the associated HWUnits */
  for (LulJobIndex = 0U; LulJobIndex < Spi_GpConfigPtr->usNoOfJobs; LulJobIndex++)
  {
    LpJobConfig = &Spi_GpFirstJob[LulJobIndex];
    #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
    LpHWDevConfig = (P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA))LpJobConfig->pHWDevConfig;           /* PRQA S 0316, 2844, 2814 # JV-01, JV-01, JV-01 */
    #endif
    LulHWUnitIndex = LpJobConfig->ucHWUnitIndex;                                                                        /* PRQA S 2814, 2844 # JV-01, JV-01 */
    LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
    if (SPI_MACRO_CSIH == LpHWInfo->ucMacroIndex)                                                                       /* PRQA S 2814, 2844 # JV-01, JV-01 */
    {
      /* Avoid initializing same HW twice */
      if (0UL == (LulInitialized & (1UL << LulHWUnitIndex)))
      {
        #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_ON)
        /*
         * If hardware settings never changed during operation, initialize entire the CSIH unit here.
         * To initialize CFGx for each Jobs, invoke this for each Job even HWUnit is already initialized.
         */
        Spi_CSIXInitializeForJob(LpJobConfig, SPI_FALSE);
        #else
          /* Otherwise, initialize CTL1 with the first Job as default value */
        Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pRegs->ulCTL1 = LpHWDevConfig->ulCSIXCTL1;                            /* PRQA S 2814 # JV-01 */
        #endif
        LulInitialized = LulInitialized | (1UL << LulHWUnitIndex);
      }
      else
      {
        #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_ON)
        /* Initialize CFGx for each Jobs */
        Spi_CSIXInitializeForJob(LpJobConfig, SPI_TRUE);
        #endif
      }
    } /* else No action required */
  }
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXDeInit
**
** Service ID         : Not Applicable
**
** Description        : This function de-initializes all configured CSIH units
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Non-Reentrant
**
** Input Parameters   : None
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : Spi_Init must have been invoked.
**
** Global Variable    : Spi_GpConfigPtr, Spi_GpFirstHWUnit, Spi_GpFirstJob, Spi_GpFirstHWUnit, Spi_GaaCSIHRegs
**
** Function invoked   : Spi_CSIXDisableAllInterrupts, Spi_CSIXHWControlCS
**
** Registers Used     : CSIXnCTL0, CSIXnCTL1, CSIXnCFGx, CSIXnCTL2, CSIHnEIE, CSIXnBRSy, CSIXnSTCR0
**
** Reference ID       : SPI_DUD_ACT_042, SPI_DUD_ACT_042_REG001, SPI_DUD_ACT_042_REG002, SPI_DUD_ACT_042_REG003,
** Reference ID       : SPI_DUD_ACT_042_REG004, SPI_DUD_ACT_042_REG005, SPI_DUD_ACT_042_REG006, SPI_DUD_ACT_042_REG007
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXDeInit(void)
{
  uint32 LulJobIndex;
  uint32 LulHWUnitIndex;
  uint32 LulHwPhyIndex;
  uint32 LulCSIndex;
  uint32 LulBRSIndex;
  uint32 LulInitialized;
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig;

  LulInitialized = 0UL;
  /* Scan all jobs and initialize the associated HWUnits */
  for (LulJobIndex = 0U; LulJobIndex < Spi_GpConfigPtr->usNoOfJobs; LulJobIndex++)
  {
    LpJobConfig = &Spi_GpFirstJob[LulJobIndex];
    LulHWUnitIndex = LpJobConfig->ucHWUnitIndex;                                                                        /* PRQA S 2814, 2844 # JV-01, JV-01 */
    LpHWInfo = &Spi_GpFirstHWUnit[LulHWUnitIndex];
    LulHwPhyIndex = LpHWInfo->ucPhyUnitIndex;                                                                           /* PRQA S 2844, 2814 # JV-01, JV-01 */
    if (SPI_MACRO_CSIH == LpHWInfo->ucMacroIndex)
    {
      /* Avoid initializing same HW twice */
      if (0UL == (LulInitialized & (1UL << LulHWUnitIndex)))
      {
        /* Restore CSIXnCTL0 as the rest default value */
        /* Step 1. Clear PWR */
        Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->ucCTL0 &= (uint8)(~SPI_CSIX_PWR);                                         /* PRQA S 2814 # JV-01 */
        /* Step 2. Clear TXE, RXE, MBS at the same time as setting PWR */
        Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->ucCTL0 = (uint8)(SPI_CSIX_PWR | SPI_CSIX_CTL0_DEFAULT);
        /* Step 3. Clear PWR */
        Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->ucCTL0 = SPI_CSIX_CTL0_DEFAULT;
        /* Restore all used registers as the rest default value */
        Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->ulCTL1 = SPI_CSIX_CTL1_DEFAULT;
        Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->usCTL2 = SPI_CSIX_CTL2_DEFAULT;
        Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->usSTCR0 = (uint16)(SPI_CSIX_DCEC | SPI_CSIX_PEC | SPI_CSIX_OVEC);
        for (LulBRSIndex = 0UL; LulBRSIndex < (uint32)SPI_CSIX_BRS_NUM; LulBRSIndex++)
        {
          Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->aaBRS[LulBRSIndex].usBRS = SPI_CSIX_BRS_DEFAULT;
        }
        Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->ulEIE = SPI_CSIH_EIE_DEFAULT;
        LulInitialized = LulInitialized | (1UL << LulHWUnitIndex);
      } /* else No action required */
      /* Initialize CFGx registers to reset the clock polarity */
      for (LulCSIndex = 0U; LulCSIndex < Spi_GaaCSIHRegs[LulHwPhyIndex].ucNoOfCS; LulCSIndex++)
      {
        if (0U == (LpJobConfig->usCSInfo & (uint16)(1U << LulCSIndex)))                                                 /* PRQA S 4399, 4391 # JV-01, JV-01 */
        {
          Spi_GaaCSIHRegs[LulHwPhyIndex].pRegs->aaCFG[LulCSIndex] = SPI_CSIX_CFG_DEFAULT;
        } /* else No action required */
      }
      #if (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON)
      if (SPI_GPIO_CS == LpJobConfig->enCSType)
      {
        /* Deactivate the chip select */
        Spi_CSIXHWControlCS(LpJobConfig, SPI_FALSE);
      }
      #endif /* (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON) */
    } /* else No action required */
  }
  Spi_CSIXDisableAllInterrupts();
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXInitializeForJob
**
** Service ID         : Not Applicable
**
** Description        : Setup a CSIH 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
**                      LblCFGxOnly - If true, only CFGx registers are configured
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init must have been invoked.
**
** Global Variable    : Spi_GpFirstChannel, Spi_GpFirstHWUnit
**
** Function Invoked   : None
**
** Registers Used     : CSIXnBRSy, CSIXnCTL1, CSIXnCTL2, CSIXnSTCR0, CSIXnCFGx
**
** Reference ID       : SPI_DUD_ACT_043, SPI_DUD_ACT_043_REG001, SPI_DUD_ACT_043_REG002, SPI_DUD_ACT_043_REG003,
** Reference ID       : SPI_DUD_ACT_043_REG004, SPI_DUD_ACT_043_REG005,
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXInitializeForJob(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                             const boolean LblCFGxOnly)
{
  uint32 LulHWPhyIndex;
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  P2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig;
  P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpHWDevConfig;
  uint32 LulCSIndex;
  uint32 LulBRSIndex;
  uint32 LulCFGValue;

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

  /*
   * Get CFGx value from Job(includes baudrate and CS settings) and
   * the first Channel(includes data length and direction)
   */
  LpChConfig = &Spi_GpFirstChannel[LpJobConfig->pChannelList[0]];                                                       /* PRQA S 2824 # JV-01 */
  LpHWDevConfig = (P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA))LpJobConfig->pHWDevConfig;             /* PRQA S 0316 # JV-01 */
  LulCFGValue = LpHWDevConfig->ulCSIXCFG;                                                                               /* PRQA S 2814 # JV-01 */

  /* Setup the first starting bit for transmission */
  if (SPI_TRANSFER_START_LSB == LpChConfig->enTransferStart)                                                            /* PRQA S 2844, 2814 # JV-01, JV-01 */
  {
    LulCFGValue |= SPI_CSIX_DIRL;
  } /* else No action required */

  /* Setup the transfer data length */
  LulCFGValue |= SPI_CSIX_DLS(LpChConfig->ucDataWidth);                                                                 /* PRQA S 3469 # JV-01 */

  /* Setup CFGx registers */
  for (LulCSIndex = 0U; LulCSIndex < Spi_GaaCSIHRegs[LulHWPhyIndex].ucNoOfCS; LulCSIndex++)
  {
    if (0U == (LpJobConfig->usCSInfo & (uint16)(1U << LulCSIndex)))                                                     /* PRQA S 4399, 4391 # JV-01, JV-01 */
    {
      Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->aaCFG[LulCSIndex] = LulCFGValue;                                            /* PRQA S 2814 # JV-01 */
      /* The first CFGx is dominant, and the others are recessive(ignored) */
      LulCFGValue = LulCFGValue | SPI_CSIH_RCB;
    } /* else No action required */
  }

  if (SPI_FALSE == LblCFGxOnly)
  {
    /* Setup CTL1, CTL2 and BRS registers according to Job settings */
    LulBRSIndex = SPI_CSIH_BRSS_GET(LpHWDevConfig->ulCSIXCFG);                                                          /* PRQA S 3469 # JV-01 */
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->aaBRS[LulBRSIndex].usBRS = LpHWDevConfig->usCSIXBRS;
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ulCTL1 = LpHWDevConfig->ulCSIXCTL1;
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->usCTL2 = LpHWDevConfig->usCSIXCTL2;
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->usSTCR0 = (uint16)(SPI_CSIX_DCEC | SPI_CSIX_PEC | SPI_CSIX_OVEC);
  } /* else No action required */
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXInitializeForCh
**
** Service ID         : Not Applicable
**
** Description        : Setup a CSIH 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 must have been invoked.
**
** Global Variable    : Spi_GpFirstHWUnit, Spi_GaaCSIHRegs
**
** Function Invoked   : None
**
** Registers Used     : CSIXnCFGx
**
** Reference ID       : SPI_DUD_ACT_044, SPI_DUD_ACT_044_REG001
***********************************************************************************************************************/
#if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXInitializeForCh(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                            CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpHWDevConfig;
  uint32 LulCFGValue;
  uint32 LulCSIndex;
  uint32 LulCSInfo;

  /* Make CFGx value from Job(includes baudrate and CS settings) and
   * the first Channel(includes data length and direction) */
  LpHWInfo = &Spi_GpFirstHWUnit[LpJobConfig->ucHWUnitIndex];                                                            /* PRQA S 2814 # JV-01 */
  LpHWDevConfig = (P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA))LpJobConfig->pHWDevConfig;             /* PRQA S 0316 # JV-01 */
  LulCFGValue = LpHWDevConfig->ulCSIXCFG;                                                                               /* PRQA S 2814 # JV-01 */

  /* Setup the first starting bit for transmission */
  if (SPI_TRANSFER_START_LSB == LpChConfig->enTransferStart)                                                            /* PRQA S 2814 # JV-01 */
  {
    LulCFGValue |= SPI_CSIX_DIRL;
  } /* else No action required */

  /* Setup the transfer data length */
  LulCFGValue |= SPI_CSIX_DLS(LpChConfig->ucDataWidth);                                                                 /* PRQA S 3469 # JV-01 */

  /* Since only the first CFGx is marked as dominant, it is enough to modify the first CFGx */
  LulCSInfo = LpJobConfig->usCSInfo;
  for (LulCSIndex = 0UL; LulCSIndex < Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].ucNoOfCS; LulCSIndex++)                 /* PRQA S 2844, 2814 # JV-01, JV-01 */
  {
    if (0UL == (LulCSInfo & (1UL << LulCSIndex)))
    {
      Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pRegs->aaCFG[LulCSIndex] = LulCFGValue;                                 /* PRQA S 2814 # JV-01 */
      LulCSInfo = SPI_CSIX_CS_MASK;
    } /* else No action required */
  }
}
#endif /* (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF) */

/***********************************************************************************************************************
** Function Name      : Spi_CSIXProcessJob
**
** 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 must have been invoked.
**
** Global Variable    : Spi_GpFirstChannel, Spi_GpFirstHWUnit, Spi_GaaHWStatus, Spi_GaaCSIHRegs
**
** Function Invoked   : Spi_CSIXInitializeForJob, Spi_CSIXInitializeForCh, Spi_CSIXStartChannelDirectAccessMode, 
**                      Spi_CSIXHWControlCS
**
** Registers Used     : CSIXnCTL0
**
** Reference ID       : SPI_DUD_ACT_048, SPI_DUD_ACT_048_GBL001, SPI_DUD_ACT_048_GBL002, SPI_DUD_ACT_048_GBL003,
** Reference ID       : SPI_DUD_ACT_048_REG001, SPI_DUD_ACT_048_REG002, SPI_DUD_ACT_048_REG003, SPI_DUD_ACT_048_REG004
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXProcessJob(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 */
  P2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig;
  uint32 LulHWPhyIndex;
  uint32 LulChIndex;

  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 CSIH. Otherwise, initialize channel relevant registers only.
   */
  if (SPI_TRUE == LblFirst)
  {
    /* Initialize status and HW according to Job config */
    LpHWStat->ucTxChannelCount = 0U;                                                                                    /* PRQA S 2844 # JV-01 */
    LpHWStat->ucRxChannelCount = 0U;
    LulChIndex = LpJobConfig->pChannelList[0];                                                                          /* PRQA S 2824 # JV-01 */
    LpChConfig = &Spi_GpFirstChannel[LulChIndex];
    #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
    /* Power OFF */
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = SPI_CSIH_CTL0_TURNOFF;                                               /* PRQA S 2814 # JV-01 */
    /* Initialize CSIXn */
    Spi_CSIXInitializeForJob(LpJobConfig, SPI_FALSE);
    #endif
    /* Power ON */
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = SPI_CSIH_CTL0_TURNON;                                                /* PRQA S 2814 # JV-01 */
  } /* if (SPI_TRUE == LblFirst) */
  else
  {
    /* Initialize HW according to Channel config */
    LulChIndex = LpJobConfig->pChannelList[LpHWStat->ucTxChannelCount];
    LpChConfig = &Spi_GpFirstChannel[LulChIndex];
    #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
    /* Power OFF */
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = SPI_CSIH_CTL0_TURNOFF;
    /* Initialize CFGx according to Channel config */
    Spi_CSIXInitializeForCh(LpJobConfig, LpChConfig);
    /* Power ON */
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = SPI_CSIH_CTL0_TURNON;
    #endif
  } /* else (SPI_TRUE == LblFirst) */

  /* Prepare channel buffers */
  #if (SPI_CHANNEL_BUFFERS_ALLOWED == SPI_IBEB)
  if (SPI_BUFFER_TYPE_IB == LpChConfig->enChannelBufferType)                                                            /* PRQA S 2814, 2844 # JV-01, JV-01 */
  #endif
  {
    #if ((SPI_CHANNEL_BUFFERS_ALLOWED == SPI_IB) || (SPI_CHANNEL_BUFFERS_ALLOWED == SPI_IBEB))
    /* Initialize rx/tx pointers to point to IB */
    LpHWStat->pTxPtr = LpChConfig->pTxBuffer;
    LpHWStat->pRxPtr = LpChConfig->pRxBuffer;
    LpHWStat->usRemainedTxCount = LpChConfig->usNoOfBuffers;
    LpHWStat->usRemainedRxCount = 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))
    /* Initialize rx/tx pointers to point to EB */
    LpHWStat->pTxPtr = LpChConfig->pEBData->pSrcPtr;                                                                    /* PRQA S 2814, 2844 # JV-01, JV-01 */
    LpHWStat->pRxPtr = LpChConfig->pEBData->pDestPtr;
    LpHWStat->usRemainedTxCount = LpChConfig->pEBData->usEBLength;
    LpHWStat->usRemainedRxCount = LpChConfig->pEBData->usEBLength;
    #endif
  }
  #if (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON)
  if (SPI_GPIO_CS == LpJobConfig->enCSType)
  {
    /* Activate the chip select */
    Spi_CSIXHWControlCS(LpJobConfig, SPI_TRUE);
  }
  #endif /* (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON) */
  /* Start transmission */
  Spi_CSIXStartChannelDirectAccessMode(LpJobConfig, LpChConfig, LpHWStat, LulHWPhyIndex);
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXStartChannelDirectAccessMode
**
** Service ID         : Not Applicable
**
** Description        : This function writes data to Tx Buffer and starts transmission on DirectAccessMode on CSIH
**
** 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
**                      LpHWStat      - Pointer to the HW status structure
**                      LulHWPhyIndex - Physical index of the HWUnit
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init must have been invoked.
**
** Global Variable    : Spi_GaaEDLStatus, Spi_GulDmaRxData, Spi_GaaCSIHRegs
**
** Function Invoked   : Spi_LoadTxData, Spi_DMAStart, SPI_ENTER_CRITICAL_SECTION, SPI_EXIT_CRITICAL_SECTION
**
** Registers Used     : CSIXnCTL0, CSIXnTX0W
**
** Reference ID       : SPI_DUD_ACT_049, SPI_DUD_ACT_049_CRT001, SPI_DUD_ACT_049_CRT002, SPI_DUD_ACT_049_GBL001,
** Reference ID       : SPI_DUD_ACT_049_GBL002, SPI_DUD_ACT_049_GBL003, SPI_DUD_ACT_049_GBL004, SPI_DUD_ACT_049_REG001,
** Reference ID       : SPI_DUD_ACT_049_REG002
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXStartChannelDirectAccessMode(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                                         CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig,
                                         volatile CONSTP2VAR(Spi_HWStatusType, AUTOMATIC, SPI_VAR_NO_INIT) LpHWStat,    /* PRQA S 3432 # JV-01 */
                                         const uint32 LulHWPhyIndex)
{
  P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpHWDevConfig;
  uint32 LulTxData;
  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
  uint32 LulHWUnitIndex;

  LulHWUnitIndex = LpJobConfig->ucHWUnitIndex;                                                                          /* PRQA S 2814 # JV-01 */
  #endif
  LpHWDevConfig = (P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA))LpJobConfig->pHWDevConfig;             /* PRQA S 0316, 2814 # JV-01, JV-01 */
  /* Set CS field of TX0W retister */
  LulTxData = SPI_CSIH_CS(LpJobConfig->usCSInfo);                                                                       /* PRQA S 3469 # JV-01 */

  /*
   * If the channel has only one data, transmit ISR is not necessary. So set TX0W.EOJ to raise TIJC instead of TIC.
   * Since TIJC is masked for DirectAccessMode, no interruption will occur.
   */
  if ((0UL != (LpHWDevConfig->ulCSIXCTL1 & SPI_CSIH_JE)) &&                                                             /* PRQA S 2814 # JV-01 */
      ((1U == LpHWStat->usRemainedTxCount) &&                                                                           /* PRQA S 2814 # JV-01 */
       ((SPI_FALSE == LpJobConfig->blChannelPropertySame) || (1U == LpJobConfig->ucNoOfChannels))))
  {
    LulTxData = LulTxData | SPI_CSIH_EOJ;
  } /* else No action required */

  /* Prepare TX0W register value(s) */
  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
  Spi_LoadTxData(LpHWStat->pTxPtr, LpChConfig, &LulTxData, &Spi_GaaEDLStatus[LulHWUnitIndex].ulTxEDLSecondWord);        /* PRQA S 2844 # JV-01 */
  #else
  Spi_LoadTxData(LpHWStat->pTxPtr, LpChConfig, &LulTxData);
  #endif
  /* Increment tx pointer according to data width */
  if (NULL_PTR != LpHWStat->pTxPtr)
  {
    LpHWStat->pTxPtr = LpHWStat->pTxPtr + LpChConfig->ucByteSize;                                                       /* PRQA S 0488, 2814 # JV-01, JV-01 */
  } /* else No action required */

  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
  /* Set EDL flag if DataWidth is longer than 16 */
  if (LpChConfig->ucDataWidth > SPI_CSIX_WORD)
  {
    Spi_GaaEDLStatus[LulHWUnitIndex].blTxEDLOngoing = SPI_TRUE;                                                         /* PRQA S 2844 # JV-01 */
    Spi_GaaEDLStatus[LulHWUnitIndex].blRxEDLOngoing = SPI_TRUE;                                                         /* PRQA S 2844 # JV-01 */

    /* DMA is not supported for EDL */
  }
  else
  #endif
  {
    #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
    Spi_GaaEDLStatus[LulHWUnitIndex].blTxEDLOngoing = SPI_FALSE;                                                        /* PRQA S 2844 # JV-01 */
    Spi_GaaEDLStatus[LulHWUnitIndex].blRxEDLOngoing = SPI_FALSE;                                                        /* PRQA S 2844 # JV-01 */
    #endif

    #if (SPI_DMA_CONFIGURED == STD_ON)
    /* Setup DMA for Rx side */
    if (SPI_INVALID_DMAUNIT != LpJobConfig->ucRxDmaIndex)
    {
      if (NULL_PTR != LpHWStat->pRxPtr)
      {
        /* If rx buffer isn't NULL, set pointer to rx buffer to DMA */
        Spi_DMAStart((uint32)LpJobConfig->ucRxDmaIndex,                                                                 /* PRQA S 0404 # JV-01 */
                     (volatile P2CONST(void, AUTOMATIC, SPI_APPL_DATA))LpHWStat->pRxPtr,                                /* PRQA S 0314 # JV-01 */
                     (uint32)LpHWStat->usRemainedRxCount,
                     SPI_DMA_16BIT | SPI_DMA_INCDST | SPI_DMA_INTERRUPT | SPI_DMA_TC(1UL));                             /* PRQA S 3469 # JV-01 */
      }
      else
      {
        /* If rx buffer is NULL, set pointer to the dummy variable to DMA */
        Spi_DMAStart((uint32)LpJobConfig->ucRxDmaIndex,
                     (volatile P2CONST(void, AUTOMATIC, SPI_APPL_DATA)) & Spi_GulDmaRxData,                             /* PRQA S 0314 # JV-01 */
                     (uint32)LpHWStat->usRemainedRxCount, SPI_DMA_16BIT | SPI_DMA_INTERRUPT | SPI_DMA_TC(1UL));         /* PRQA S 3469 # JV-01 */
      }
    } /* else No action required */
    /* Setup DMA for Tx side */
    if ((SPI_INVALID_DMAUNIT != LpJobConfig->ucTxDmaIndex) && (1U < LpHWStat->usRemainedTxCount))
    {
      if (NULL_PTR != LpHWStat->pTxPtr)
      {
        /* If tx buffer isn't NULL, set pointer to tx buffer to DMA */
        Spi_DMAStart((uint32)LpJobConfig->ucTxDmaIndex,                                                                 /* PRQA S 0404 # JV-01 */
                     (volatile P2CONST(void, AUTOMATIC, SPI_APPL_DATA))LpHWStat->pTxPtr,                                /* PRQA S 0314 # JV-01 */
                     (uint32)LpHWStat->usRemainedTxCount - 1UL, SPI_DMA_16BIT | SPI_DMA_INCSRC | SPI_DMA_TC(1UL));      /* PRQA S 3384, 3469 # JV-01, JV-01 */
      }
      else
      {
        /* If tx buffer is NULL, set pointer to the default data to DMA */
        Spi_DMAStart((uint32)LpJobConfig->ucTxDmaIndex,
                     (volatile P2CONST(void, AUTOMATIC, SPI_APPL_DATA)) & LpChConfig->ulDefaultData,                    /* PRQA S 0314 # JV-01 */
                     (uint32)LpHWStat->usRemainedTxCount - 1UL, SPI_DMA_16BIT | SPI_DMA_TC(1UL));                       /* PRQA S 3384, 3469 # JV-01, JV-01 */
      }
    } /* else No action required */
    #endif /* (SPI_DMA_CONFIGURED == STD_ON) */
  }

  LpHWStat->usRemainedTxCount--;                                                                                        /* PRQA S 3387, 3384 # JV-01, JV-01 */

  /* Start transmission */
  /* JOBE bit must be set right after the start of the transmission. To prevent pre-emption, disable interrupt. */
  SPI_ENTER_CRITICAL_SECTION(SPI_INTERRUPT_CONTROL_PROTECTION);
  Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ulTX0W = LulTxData;                                                             /* PRQA S 2844, 2814 # JV-01, JV-01 */
  /* Set CTL0.JOBE bit to suppress TxISR of the last transmission.
     This improvement is applicable for master mode only. */
  if (0UL != (LpHWDevConfig->ulCSIXCTL1 & SPI_CSIH_JE))
  {
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = (uint8)(SPI_CSIH_CTL0_TURNON | SPI_CSIH_JOBE);
  } /* else No action required */
  SPI_EXIT_CRITICAL_SECTION(SPI_INTERRUPT_CONTROL_PROTECTION);
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXTransmitSyncJob
**
** Service ID         : Not Applicable
**
** Description        : This function transmits a Job synchronously. The transmission doesn't stop until the end of a
**                      Job, even though any HW error occurs during a transmission.
**
** 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   : Std_ReturnType (E_OK/E_NOT_OK)
**
** Preconditions      : Spi_Init must have been invoked.
**
** Global Variables   : Spi_GpFirstHWUnit, Spi_GaaHWStatus, Spi_GaaCSIHRegs, Spi_GpConfigPtr, Spi_GaaJobStatus,
**                      Spi_GaaSeqStatus
**
** Function Invoked   : SPI_DEM_REPORT_ERROR,Spi_CSIXProcessJob, Spi_CSIXDMACompleteISR, Spi_CSIXReceiveISR, 
**                      Spi_CSIXTransmitISR, Spi_DMAClearInterruptFlag, Spi_DMAGetInterruptFlag
**
** Registers Used     : EIC(CSIXnTIR), EIC(CSIXnTIC)
**
** Reference ID       : SPI_DUD_ACT_045, SPI_DUD_ACT_045_ERR001, SPI_DUD_ACT_045_GBL001, SPI_DUD_ACT_045_GBL002,
** Reference ID       : SPI_DUD_ACT_045_REG001, SPI_DUD_ACT_045_REG002, SPI_DUD_ACT_045_REG003, SPI_DUD_ACT_045_REG004
***********************************************************************************************************************/
#if ((SPI_LEVEL_DELIVERED == SPI_LEVEL_0) || (SPI_LEVEL_DELIVERED == SPI_LEVEL_2))
STATIC FUNC(Std_ReturnType, SPI_PRIVATE_CODE)
    Spi_CSIXTransmitSyncJob(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_PRIVATE_CONST) LpHWUnitInfo;
  volatile P2VAR(Spi_HWStatusType, AUTOMATIC, SPI_VAR_NO_INIT) LpHWStat;                                                /* PRQA S 3432, 3678 # JV-01, JV-01 */
  uint32 LulHWPhyIndex;
  uint32 LulWaitCount;
  Std_ReturnType LenReturnValue;

  #if (SPI_DMA_CONFIGURED == STD_ON)
  P2CONST(Spi_DmaConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpDmaConfig;
  uint32 LulDmaIntFlag;
  #endif

  LenReturnValue = E_OK;

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

  #if (SPI_DMA_CONFIGURED == STD_ON)
  if (SPI_INVALID_DMAUNIT != LpJobConfig->ucRxDmaIndex)
  {
    LpDmaConfig = &Spi_GpFirstDMAUnit[LpJobConfig->ucRxDmaIndex];
    /* Clear TE interrupt flag */
    Spi_DMAClearInterruptFlag((uint32)LpJobConfig->ucRxDmaIndex);
  } /* else No action required */
  #endif

  /* Just in case, clear EIRF flags before starting transmission */
  RH850_SV_MODE_ICR_AND(16, Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIC, (uint16)(~SPI_EIC_EIRF_MASK));                       /* PRQA S 2814 # JV-01 */
  RH850_SV_MODE_ICR_AND(16, Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIR, (uint16)(~SPI_EIC_EIRF_MASK));

  /* Setup HW for Job and send the first data */
  Spi_CSIXProcessJob(SPI_TRUE, LpJobConfig);

  /* Loop until Job end or any error occurs */
  LulWaitCount = 0U;
  do
  {
    #if (SPI_DMA_CONFIGURED == STD_ON)
    if ((SPI_INVALID_DMAUNIT != LpJobConfig->ucRxDmaIndex) && (SPI_TRUE == LpDmaConfig->blRxSide))                      /* PRQA S 2962, 2814, 2844 # JV-01, JV-01, JV-01 */
    {
      /* Invoke DMA ISR if the IRQ is asserted */
      LulDmaIntFlag = Spi_DMAGetInterruptFlag((uint32)LpJobConfig->ucRxDmaIndex);
      if (0UL != LulDmaIntFlag)
      {
        Spi_CSIXDMACompleteISR((uint32)LpJobConfig->ucRxDmaIndex);
        /* Reset timeout count */
        LulWaitCount = 0U;
      }
      else
      {
        /* Increment timeout count */
        LulWaitCount++;                                                                                                 /* PRQA S 3383 # JV-01 */
      }
    }
    else
    #endif /* (SPI_DMA_CONFIGURED == STD_ON) */
    {
      if (0U != (RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIR) & SPI_EIC_EIRF_MASK))
      {
        /* To emulate the default interrupt priority (CSIXnTIC > CSIXnTIR), check CSIXnTIC again */
        if (0U != (RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIC) & SPI_EIC_EIRF_MASK))
        {
          /* Clear pending interrupt flag */
          RH850_SV_MODE_ICR_AND(16, Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIC, (uint16)(~SPI_EIC_EIRF_MASK));
          /* If tx interruption flag is activated, call TxISR */
          Spi_CSIXTransmitISR((uint32)LpJobConfig->ucHWUnitIndex);
        } /* else No action required */
        /* Clear pending interrupt flag */
        RH850_SV_MODE_ICR_AND(16, Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIR, (uint16)(~SPI_EIC_EIRF_MASK));
        /* If rx interruption flag is activated, call RxISR */
        Spi_CSIXReceiveISR((uint32)LpJobConfig->ucHWUnitIndex);
        /* Reset timeout count */
        LulWaitCount = 0U;
      }
      else
      {
        /* Increment timeout count */
        LulWaitCount++;                                                                                                 /* PRQA S 3383 # JV-01 */
      }

      if (0U != (RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIC) & SPI_EIC_EIRF_MASK))
      {
        /* Clear pending interrupt flag */
        RH850_SV_MODE_ICR_AND(16, Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIC, (uint16)(~SPI_EIC_EIRF_MASK));
        /* If tx interruption flag is activated, call TxISR */
        Spi_CSIXTransmitISR((uint32)LpJobConfig->ucHWUnitIndex);
        /* Reset timeout count */
        LulWaitCount = 0U;
      }
      else
      {
        /* Increment timeout count */
        LulWaitCount++;                                                                                                 /* PRQA S 3383 # JV-01 */
      }
    }

    /* Check timeout */
    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
      Spi_GaaJobStatus[LpHWStat->usOngoingJobIndex].enResult = SPI_JOB_FAILED;                                          /* PRQA S 2844 # JV-01 */
      /* At least one Job failed, set Sequence failed flag */
      Spi_GaaSeqStatus[LpHWStat->ucOngoingSeqIndex].blFailed = SPI_TRUE;
      LenReturnValue = E_NOT_OK;
    } /* else No action required */
    
    /* Do DummyRead & SYNCP */
    RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[0].pICTIR);
    EXECUTE_SYNCP();
  } while ((E_OK == LenReturnValue) && (LpHWStat->ucRxChannelCount < LpJobConfig->ucNoOfChannels));
  
  
  /* If any HW error has been occurred, return E_NOT_OK */
  if (SPI_TRUE == Spi_GaaSeqStatus[LpHWStat->ucOngoingSeqIndex].blFailed)
  {
    LenReturnValue = E_NOT_OK;
  } /* else No action required */

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

/***********************************************************************************************************************
** Function Name      : Spi_LoadTxData
**
** Service ID         : Not Applicable
**
** Description        : This function loads data from the buffer and encode it to send with TX0W register
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant
**
** Input Parameters   : LpData       - Pointer to the buffer to load data from
**                      LpChConfig   - Pointer to the Channel configuration
**
** InOut Parameters   : None
**
** Output Parameters  : LpFirstWord  - Pointer to store the first word of TX0W
**                      LpSecondWord - Pointer to store the second word of TX0W
**                                     This parameter is not used when EDL feature is disabled.
**
** Return parameter   : None
**
** Preconditions      : None
**
** Global Variables   : None
**
** Function Invoked   : None
**
** Registers Used     : None
**
** Reference ID       : SPI_DUD_ACT_046
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_LoadTxData(volatile CONSTP2CONST(Spi_DataBufferType, AUTOMATIC, SPI_APPL_DATA) LpData,
                   CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig,
                   volatile CONSTP2VAR(uint32, AUTOMATIC, AUTOMATIC) LpFirstWord                                        /* PRQA S 3432 # JV-01 */
                  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
                   ,volatile CONSTP2VAR(uint32, AUTOMATIC, SPI_VAR_NO_INIT) LpSecondWord                                /* PRQA S 3432 # JV-01 */
                  #endif
    )
{
  uint32 LulData;

  /* Load data from memory according to the access size */
  if (NULL_PTR == LpData)
  {
    LulData = LpChConfig->ulDefaultData;                                                                                /* PRQA S 2814 # JV-01 */
  }
  else
  {
    switch (LpChConfig->ucByteSize)
    {
    #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
    case sizeof(uint32):
      LulData = *(volatile P2CONST(uint32, AUTOMATIC, SPI_APPL_DATA))LpData;                                            /* PRQA S 0310, 3305 # JV-01, JV-01 */
      break;
    #endif
    case sizeof(uint16):
      LulData = *(volatile P2CONST(uint16, AUTOMATIC, SPI_APPL_DATA))LpData;                                            /* PRQA S 3305, 0310 # JV-01, JV-01 */
      break;
    default:
      LulData = *LpData;
      break;
    }
  }

  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
  if (LpChConfig->ucDataWidth > SPI_CSIX_WORD)
  {
    /* Copy CS and CIRE/EOJ setting to SecondWord from FirstWord */
    *LpSecondWord = *LpFirstWord;                                                                                       /* PRQA S 2814 # JV-01 */
    /* Clear CIRE/EOJ and set EDL of FirstWord */
    *LpFirstWord = (*LpFirstWord & ~(SPI_CSIH_CIRE | SPI_CSIH_EOJ)) | SPI_CSIX_EDL;
    /* Separate 32bit data to two 16bit data */
    if (SPI_TRANSFER_START_LSB == LpChConfig->enTransferStart)
    {
      /*
       * e.g. DataWidth=20, LSB first
       *   [******** ****cccc BBBBbbbb AAAAaaaa]
       *   => 1stTxData: [XXXXXXXX XXXXXXXX BBBBbbbb AAAAaaaa]
       *      2ndTxData: [XXXXXXXX XXXXXXXX ******** ****cccc]
       *   X: Control bits of TX0W
       *   *: Don't care
       */
      *LpFirstWord = *LpFirstWord | ((LulData << SPI_CSIX_WORD) >> SPI_CSIX_WORD);
      *LpSecondWord = *LpSecondWord | (LulData >> SPI_CSIX_WORD);
    }
    else
    {
      /*
       * e.g. DataWidth=20, MSB first
       *   [******** ****cccc BBBBbbbb AAAAaaaa]
       *   => 1stTxData: [XXXXXXXX XXXXXXXX ccccBBBB bbbbAAAA]
       *      2ndTxData: [XXXXXXXX XXXXXXXX ******** ****aaaa]
       *   X: Control bits of TX0W
       *   *: Don't care
       */
      *LpFirstWord = *LpFirstWord | ((LulData << (SPI_UINT32_BITS - LpChConfig->ucDataWidth)) >> SPI_CSIX_WORD);        /* PRQA S 3383 # JV-01 */
      *LpSecondWord = *LpSecondWord | ((LulData << SPI_CSIX_WORD) >> SPI_CSIX_WORD);
    }
  }
  else
  #endif
  {
    /* Merge upper 16bit of FirstWord and lower 16bit of LulData */
    *LpFirstWord = *LpFirstWord | LulData;                                                                              /* PRQA S 2814 # JV-01 */
  }
}

/***********************************************************************************************************************
** Function Name      : Spi_StoreRxData
**
** Service ID         : Not Applicable
**
** Description        : This function merges two word from RX0H register and stores it to the buffer
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant
**
** Input Parameters   : LpChConfig    - Pointer to the Channel configuration
**                      LusFirstWord  - The first word from RX0H register
**                      LusSecondWord - The second word from RX0H register
**                                      This parameter is not used when EDL feature is disabled.
**
** InOut Parameters   : None
**
** Output Parameters  : LpData        - Pointer to the buffer to store data to
**
** Return parameter   : None
**
** Preconditions      : None
**
** Global Variables   : None
**
** Function Invoked   : None
**
** Registers Used     : None
**
** Reference ID       : SPI_DUD_ACT_047
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_StoreRxData(volatile CONSTP2VAR(Spi_DataBufferType, AUTOMATIC, SPI_APPL_DATA) LpData,                           /* PRQA S 3432 # JV-01 */
                    CONSTP2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig,
                    #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
                    const uint16 LusFirstWord,
                    #endif
                    const uint16 LusSecondWord)
{
  uint32 LulData;
  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
  /* Combine 32bit data from two 16bit data */
  if (LpChConfig->ucDataWidth > SPI_CSIX_WORD)                                                                          /* PRQA S 2814 # JV-01 */
  {
    if (SPI_TRANSFER_START_LSB == LpChConfig->enTransferStart)
    {
      /* e.g. DataWidth=20, LSB first
       *   1stRxData: [BBBBbbbb AAAAaaaa]
       *   2ndRxData: [00000000 0000cccc]
       *   => [00000000 0000cccc BBBBbbbbb AAAAaaaa]
       */
      LulData = (uint32)LusFirstWord | ((uint32)LusSecondWord << SPI_CSIX_WORD);
    }
    else
    {
      /* e.g. DataWidth=20, MSB first
       *   1stRxData: [ccccBBBB bbbbAAAA]
       *   2ndRxData: [00000000 0000aaaa]
       *   => [00000000 0000cccc BBBBbbbb AAAAaaaa]
       */
      /* Fill unnecessary bits of 1st and 2nd Data with 0, and merge them */
      LulData = ((uint32)LusFirstWord << (LpChConfig->ucDataWidth - SPI_CSIX_WORD)) | (uint32)LusSecondWord;            /* PRQA S 3383 # JV-01 */
    }
  }
  else
  #endif /* (SPI_EXTENDED_DATA_LENGTH == STD_ON) */
  {
    LulData = (uint32)LusSecondWord;
  }

  /* Store data to memory according to the access size */
  switch (LpChConfig->ucByteSize)                                                                                       /* PRQA S 2814 # JV-01 */
  {
  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
  case sizeof(uint32):
    *(volatile P2VAR(uint32, AUTOMATIC, SPI_APPL_DATA))LpData = LulData;                                                /* PRQA S 0310, 3305, 2814, 3432 # JV-01, JV-01, JV-01, JV-01 */
    break;
  #endif
  case sizeof(uint16):
    *(volatile P2VAR(uint16, AUTOMATIC, SPI_APPL_DATA))LpData = (uint16)LulData;                                        /* PRQA S 3305, 0310, 3432, 2814 # JV-01, JV-01, JV-01, JV-01 */
    break;
  default:
    *LpData = (uint8)LulData;
    break;
  }
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXTransmitISR
**
** Service ID         : Not Applicable
**
** Description        : This is the interrupt service routine for transmission
**                      This ISR is invoked when the following case:
**                      DIRECT_ACCESS_MODE    : every transmission complete
**
** 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 must have been invoked.
**
** Global Variable    : Spi_GpFirstHWUnit, Spi_GaaHWStatus, Spi_GaaEDLStatus, Spi_GaaCSIHRegs, Spi_GpFirstJob,
**                      Spi_GpFirstChannel
**
** Function Invoked   : Spi_LoadTxData
**
** Registers Used     : CSIXnTX0W
**
** Reference ID       : SPI_DUD_ACT_053, SPI_DUD_ACT_053_GBL001, SPI_DUD_ACT_053_GBL002, SPI_DUD_ACT_053_GBL003,
** Reference ID       : SPI_DUD_ACT_053_GBL004, SPI_DUD_ACT_053_GBL005, SPI_DUD_ACT_053_GBL006, SPI_DUD_ACT_053_GBL007,
** Reference ID       : SPI_DUD_ACT_053_REG001, SPI_DUD_ACT_053_REG002
***********************************************************************************************************************/
FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXTransmitISR(const uint32 LulHWUnitIndex)                                           /* PRQA S 1505 # JV-01 */
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  volatile P2VAR(Spi_HWStatusType, AUTOMATIC, SPI_VAR_NO_INIT) LpHWStat;                                                /* PRQA S 3432 # JV-01 */
  P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig;
  P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpHWDevConfig;
  P2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig;
  uint32 LulHWPhyIndex;
  uint32 LulFirstWord;

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

  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
  if (SPI_TRUE == Spi_GaaEDLStatus[LulHWUnitIndex].blTxEDLOngoing)                                                      /* PRQA S 2844 # JV-01 */
  {
    /* If this is the second half of 32bit data, send prepared data */
    Spi_GaaEDLStatus[LulHWUnitIndex].blTxEDLOngoing = SPI_FALSE;                                                        /* PRQA S 2844 # JV-01 */
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ulTX0W = Spi_GaaEDLStatus[LulHWUnitIndex].ulTxEDLSecondWord;                  /* PRQA S 2814 # JV-01 */
  }
  else
  #endif
  {
    LpJobConfig = &Spi_GpFirstJob[LpHWStat->usOngoingJobIndex];                                                         /* PRQA S 0404, 2844 # JV-01, JV-01 */

    /* Check whether a Channel is finished */
    if (0U == LpHWStat->usRemainedTxCount)
    {
      /* When a Channel is finished, increment Channel count */
      LpHWStat->ucTxChannelCount++;                                                                                     /* PRQA S 3383, 3387 # JV-01, JV-01 */

      /*
       * There are remained Channels and all Channel properties are same, setup buffer for the next channel and
       * continue the operation. Otherwise this operation will be done by RxISR.
       */
      if ((LpHWStat->ucTxChannelCount < LpJobConfig->ucNoOfChannels)                                                    /* PRQA S 2844, 2814 # JV-01, JV-01 */
          #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
          && (SPI_TRUE == LpJobConfig->blChannelPropertySame)
          #endif
      )
      {
        LpChConfig = &Spi_GpFirstChannel[LpJobConfig->pChannelList[LpHWStat->ucTxChannelCount]];                        /* PRQA S 0404 # JV-01 */

        #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))
          LpHWStat->pTxPtr = LpChConfig->pTxBuffer;
          LpHWStat->usRemainedTxCount = 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))
          LpHWStat->pTxPtr = LpChConfig->pEBData->pSrcPtr;                                                              /* PRQA S 2814, 2844 # JV-01, JV-01 */
          LpHWStat->usRemainedTxCount = LpChConfig->pEBData->usEBLength;
          #endif
        }
      } /* else No action required */
    } /* if (LpHWStat->usRemainedTxCount == 0U) */

    /* If there is the next data, send it */
    if (LpHWStat->usRemainedTxCount > 0U)
    {
      LpHWDevConfig = (P2CONST(Spi_CSIXDeviceConfigType, AUTOMATIC, SPI_CONFIG_DATA))LpJobConfig->pHWDevConfig;         /* PRQA S 0316 # JV-01 */
      LpChConfig = &Spi_GpFirstChannel[LpJobConfig->pChannelList[LpHWStat->ucTxChannelCount]];                          /* PRQA S 0404 # JV-01 */
      /* Set CS field of TX0W register */
      LulFirstWord = SPI_CSIH_CS(LpJobConfig->usCSInfo);                                                                /* PRQA S 3469 # JV-01 */
      /*
       * If this is the last data, the next transmit ISR is not necessary. So set TX0W.EOJ to raise TIJC instead of TIC.
       * Since TIJC is masked for DirectAccessMode, no interruption will occur.
       */
      if ((0UL != (LpHWDevConfig->ulCSIXCTL1 & SPI_CSIH_JE)) && (1U == LpHWStat->usRemainedTxCount) &&                  /* PRQA S 2814 # JV-01 */
          ((LpHWStat->ucTxChannelCount == (LpJobConfig->ucNoOfChannels - 1U)) ||                                        /* PRQA S 3383 # JV-01 */
           (SPI_FALSE == LpJobConfig->blChannelPropertySame)))
      {
        LulFirstWord = LulFirstWord | SPI_CSIH_EOJ;
      } /* else No action required */
      /* Prepare Tx data from memory */
      #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
      Spi_LoadTxData(LpHWStat->pTxPtr, LpChConfig, &LulFirstWord, &Spi_GaaEDLStatus[LulHWUnitIndex].ulTxEDLSecondWord);
      #else
      Spi_LoadTxData(LpHWStat->pTxPtr, LpChConfig, &LulFirstWord);
      #endif
      /* Increment the data pointer */
      if (NULL_PTR != LpHWStat->pTxPtr)
      {
        LpHWStat->pTxPtr = LpHWStat->pTxPtr + LpChConfig->ucByteSize;                                                   /* PRQA S 0488, 2814, 2844 # JV-01, JV-01, JV-01 */
      } /* else No action required */
      #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
      if (LpChConfig->ucDataWidth > SPI_CSIX_WORD)
      {
        Spi_GaaEDLStatus[LulHWUnitIndex].blTxEDLOngoing = SPI_TRUE;                                                     /* PRQA S 2844 # JV-01 */
      } /* else No action required */
      #endif

      /* Send */
      Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ulTX0W = LulFirstWord;                                                      /* PRQA S 2814 # JV-01 */
      LpHWStat->usRemainedTxCount--;                                                                                    /* PRQA S 3384, 3387 # JV-01, JV-01 */
    } /* if (LpHWStat->usRemainedTxCount > 0U) */
  } /* else (SPI_TRUE == LpHWStat->blTxEDLOngoing) */
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXReceiveISR
**
** Service ID         : Not Applicable
**
** Description        : This is the interrupt service routine for CSIX
**                      This is invoked when the following case:
**                      DIRECT_ACCESS_MODE    : every reception complete
**
** Sync/Async         : Asynchronous
**
** 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 must have been invoked.
**
** Global Variable    : Spi_GpFirstHWUnit, Spi_GaaHWStatus, Spi_GaaEDLStatus, Spi_GaaCSIHRegs, Spi_GpFirstJob,
**                      Spi_GpFirstChannel, Spi_GaaJobStatus, Spi_GaaSeqStatus, Spi_GulActiveHWUnits
**
** Function Invoked   : SPI_DEM_REPORT_ERROR, Spi_StoreRxData, Spi_CSIXProcessJob, Spi_ProcessSequence, 
**                      Spi_TurnOffHWUnit, Spi_CSIXHWControlCS
**
** Registers Used     : CSIHnRX0H, CSIXnSTR0, CSIXnSTCR0
**
** Reference ID       : SPI_DUD_ACT_054, SPI_DUD_ACT_054_ERR001, SPI_DUD_ACT_054_GBL001, SPI_DUD_ACT_054_GBL002,
** Reference ID       : SPI_DUD_ACT_054_GBL003, SPI_DUD_ACT_054_GBL004, SPI_DUD_ACT_054_GBL005, SPI_DUD_ACT_054_GBL006,
** Reference ID       : SPI_DUD_ACT_054_GBL007, SPI_DUD_ACT_054_GBL008, SPI_DUD_ACT_054_GBL009, SPI_DUD_ACT_054_GBL010,
** Reference ID       : SPI_DUD_ACT_054_GBL011, SPI_DUD_ACT_054_GBL012, SPI_DUD_ACT_054_REG001
***********************************************************************************************************************/
FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXReceiveISR(const uint32 LulHWUnitIndex)                                            /* PRQA S 1505 # JV-01 */
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  volatile P2VAR(Spi_HWStatusType, AUTOMATIC, SPI_VAR_NO_INIT) LpHWStat;                                                /* PRQA S 3432 # JV-01 */
  P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig;
  P2CONST(Spi_ChannelConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpChConfig;
  uint32 LulHWPhyIndex;
  uint16 LusSecondWord;

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

  #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
  if (SPI_TRUE == Spi_GaaEDLStatus[LulHWUnitIndex].blRxEDLOngoing)                                                      /* PRQA S 2844 # JV-01 */
  {
    /* If this is the first half of 32bit data, save the received data */
    Spi_GaaEDLStatus[LulHWUnitIndex].blRxEDLOngoing = SPI_FALSE;                                                        /* PRQA S 2844 # JV-01 */
    Spi_GaaEDLStatus[LulHWUnitIndex].usRxEDLFirstWord = Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->usRX0H;                   /* PRQA S 2844, 2814 # JV-01, JV-01 */
  }
  else
  #endif
  {
    LpJobConfig = &Spi_GpFirstJob[LpHWStat->usOngoingJobIndex];                                                         /* PRQA S 0404, 2844 # JV-01, JV-01 */
    LpChConfig = &Spi_GpFirstChannel[LpJobConfig->pChannelList[LpHWStat->ucRxChannelCount]];                            /* PRQA S 0404, 2844, 2814 # JV-01, JV-01, JV-01 */

    /* Receive and store data to memory */
    LusSecondWord = Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->usRX0H;                                                       /* PRQA S 2814 # JV-01 */
    if (NULL_PTR != LpHWStat->pRxPtr)
    {
      #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
      Spi_StoreRxData(LpHWStat->pRxPtr, LpChConfig, Spi_GaaEDLStatus[LulHWUnitIndex].usRxEDLFirstWord, LusSecondWord);
      #else
      Spi_StoreRxData(LpHWStat->pRxPtr, LpChConfig, LusSecondWord);
      #endif
      LpHWStat->pRxPtr = LpHWStat->pRxPtr + LpChConfig->ucByteSize;                                                     /* PRQA S 0488, 2844, 2814 # JV-01, JV-01, JV-01 */
    } /* else No action required */

    #if (SPI_EXTENDED_DATA_LENGTH == STD_ON)
    if (LpChConfig->ucDataWidth > SPI_CSIX_WORD)
    {
      Spi_GaaEDLStatus[LulHWUnitIndex].blRxEDLOngoing = SPI_TRUE;                                                       /* PRQA S 2844 # JV-01 */
    } /* else No action required */
    #endif

    LpHWStat->usRemainedRxCount--;                                                                                      /* PRQA S 3387, 3384 # JV-01, JV-01 */
    /* Check whether a Channel is finished */
    if (0U == LpHWStat->usRemainedRxCount)
    {
      /* Check whether any error has been occurred during a Channel */
      if (0UL != (Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ulSTR0 & (SPI_CSIX_DCE | SPI_CSIX_PE | SPI_CSIX_OVE)))
      {
        #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
        Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->usSTCR0 = (uint16)(SPI_CSIX_DCEC | SPI_CSIX_PEC | SPI_CSIX_OVEC);

        /* 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 */

      LpHWStat->ucRxChannelCount++;                                                                                     /* PRQA S 3387, 3383 # JV-01, JV-01 */
      /* Check whether a Job is finished */
      if (LpHWStat->ucRxChannelCount == LpJobConfig->ucNoOfChannels)
      {
        /* Disable CSIH unit to de-activate CS when the job finishes (SWS_Spi_00263)
         * Disable CSIH unit interrupts associated with job.
         */
        Spi_TurnOffHWUnit(LpJobConfig);
        #if (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON)
        /* Check if job is configured with CS as GPIO */
        if (SPI_GPIO_CS == LpJobConfig->enCSType)
        {
          /* Deactivate the chip select via selected GPIO port pin */
          Spi_CSIXHWControlCS(LpJobConfig, SPI_FALSE);
        }
        #endif /* (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON) */
        /* Set job status as "JOB_OK" when no error */
        if (SPI_JOB_FAILED != Spi_GaaJobStatus[LpHWStat->usOngoingJobIndex].enResult)
        {
          Spi_GaaJobStatus[LpHWStat->usOngoingJobIndex].enResult = SPI_JOB_OK;
        } /* else No action required */
        #if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
        if (0UL != (Spi_GulActiveHWUnits & (1UL << LulHWUnitIndex)))
        {
          /* When SyncTransmit, scheduling is done by Spi_SyncTransmit */
        }
        else
        #endif
        {
          #if (SPI_LEVEL_DELIVERED != SPI_LEVEL_0)
          /* Invoke the upper layer scheduler */
          Spi_ProcessSequence(LulHWUnitIndex);
          #endif
        }
      } /* if (LpHWStat->ucRxChannelCount == LpJobConfig->ucNoOfChannels) */
      else
      {
        #if (SPI_PERSISTENT_HW_CONFIGURATION_ENABLED == STD_OFF)
        if (SPI_FALSE == LpJobConfig->blChannelPropertySame)
        {
          /*
           * If ChannelProperty is not same, TxChannelCount is not updated because TxISR never occur on the last data.
           * Hence update it here.
           */
          LpHWStat->ucTxChannelCount = LpHWStat->ucRxChannelCount;
          /* Start the next Channel */
          Spi_CSIXProcessJob(SPI_FALSE, &Spi_GpFirstJob[LpHWStat->usOngoingJobIndex]);                                  /* PRQA S 0404 # JV-01 */
        }
        else
        #endif
        {
          /*
           * When a channel is completed and all channel properties are same, setup buffer for the next channel and
           * continue the operation. Otherwise, call job scheduler.
           */
          LpChConfig = &Spi_GpFirstChannel[LpJobConfig->pChannelList[LpHWStat->ucRxChannelCount]];                      /* PRQA S 0404 # JV-01 */

          #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))
            LpHWStat->pRxPtr = LpChConfig->pRxBuffer;
            LpHWStat->usRemainedRxCount = 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))
            LpHWStat->pRxPtr = LpChConfig->pEBData->pDestPtr;                                                           /* PRQA S 2814, 2844 # JV-01, JV-01 */
            LpHWStat->usRemainedRxCount = LpChConfig->pEBData->usEBLength;
            #endif
          }
        } /* else (SPI_FALSE == LpJobConfig->blChannelPropertySame) */
      }   /* else (LpHWStat->ucRxChannelCount == LpJobConfig->ucNoOfChannels) */
    }     /* if (0U == LpHWStat->usRemainedRxCount) */
  } /* else (SPI_TRUE == LpHWStat->blRxEDLOngoing) */
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXDMACompleteISR
**
** Service ID         : Not Applicable
**
** Description        : This function is invoked when DMA transfer is completed
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW, Non-Reentrant for same HW
**
** Input Parameters   : LulDMAUnitIndex - Index of HWUnit configuration
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : void
**
** Preconditions      : Spi_Init must have been invoked.
**
** Global Variable    : Spi_GpFirstDMAUnit, Spi_GaaHWStatus, Spi_GpFirstJob, Spi_GpFirstHWUnit, Spi_GaaCSIHRegs,
**                      Spi_GaaJobStatus, Spi_GaaSeqStatus
**
** Function Invoked   : SPI_DEM_REPORT_ERROR, Spi_DMAClearInterruptFlag, Spi_CSIXProcessJob, Spi_ProcessSequence, 
**                      Spi_TurnOffHWUnit, Spi_CSIXHWControlCS
**
** Registers Used     : CSIXnSTR0, CSIXnSTCR0, DMAjCHFCR_n, DMAjCHSTA_n
**
** Reference ID       : SPI_DUD_ACT_055, SPI_DUD_ACT_055_ERR001, SPI_DUD_ACT_055_GBL001, SPI_DUD_ACT_055_GBL002,
** Reference ID       : SPI_DUD_ACT_055_GBL003, SPI_DUD_ACT_055_GBL004, SPI_DUD_ACT_055_GBL005, SPI_DUD_ACT_055_REG001
***********************************************************************************************************************/
#if (SPI_DMA_CONFIGURED == STD_ON)
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXDMACompleteISR(const uint32 LulDMAUnitIndex)
{
  volatile P2VAR(Spi_HWStatusType, AUTOMATIC, SPI_VAR_NO_INIT) LpHWStat;                                                /* PRQA S 3432 # JV-01 */
  P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig;
  uint32 LulHWUnitIndex;
  uint32 LulHWPhyIndex;

  LulHWUnitIndex = Spi_GpFirstDMAUnit[LulDMAUnitIndex].ucSPIHWUnit;
  LpHWStat = &Spi_GaaHWStatus[LulHWUnitIndex];                                                                          /* PRQA S 2934 # JV-01 */
  LpJobConfig = &Spi_GpFirstJob[LpHWStat->usOngoingJobIndex];                                                           /* PRQA S 0404, 2844 # JV-01, JV-01 */
  LulHWPhyIndex = Spi_GpFirstHWUnit[LulHWUnitIndex].ucPhyUnitIndex;

  /* Check whether any error has been occurred during a Channel */
  if (0UL != (Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ulSTR0 & (SPI_CSIX_DCE | SPI_CSIX_PE | SPI_CSIX_OVE)))              /* PRQA S 2814 # JV-01 */
  {
    #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
    Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->usSTCR0 = (uint16)(SPI_CSIX_DCEC | SPI_CSIX_PEC | SPI_CSIX_OVEC);

    /* 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 TE interrupt flag */
  Spi_DMAClearInterruptFlag(LulDMAUnitIndex);

  LpHWStat->ucTxChannelCount++;                                                                                         /* PRQA S 3383, 3387 # JV-01, JV-01 */
  LpHWStat->ucRxChannelCount++;                                                                                         /* PRQA S 3383, 3387 # JV-01, JV-01 */
  if (LpHWStat->ucRxChannelCount == LpJobConfig->ucNoOfChannels)                                                        /* PRQA S 2844, 2814 # JV-01, JV-01 */
  {
    /* Disable CSIH unit to de-activate CS when the job finishes (SWS_Spi_00263)
     * Disable CSIH/DMA uint interrupts associated with job.
     */
    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 */
    #if (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON)
    /* Check if job is configured with CS as GPIO */
    if (SPI_GPIO_CS == LpJobConfig->enCSType)
    {
      /* Deactivate the chip select via selected GPIO port pin */
      Spi_CSIXHWControlCS(LpJobConfig, SPI_FALSE);
    }
    #endif /* (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON) */
    #if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
    if (0UL != (Spi_GulActiveHWUnits & (1UL << LulHWUnitIndex)))
    {
      /* When SyncTransmit, scheduling is done by Spi_SyncTransmit */
    }
    else
    #endif
    {
      #if (SPI_LEVEL_DELIVERED != SPI_LEVEL_0)
      /* Invoke the upper layer scheduler */
      Spi_ProcessSequence(LulHWUnitIndex);
      #endif
    }
  }
  else
  {
    /* Otherwise, process the next Channel */
    Spi_CSIXProcessJob(SPI_FALSE, LpJobConfig);
  }
}
#endif /* (SPI_DMA_CONFIGURED == STD_ON) */

/***********************************************************************************************************************
** Function Name          : Spi_CSIXDisableAllInterrupts
**
** Service ID             : NA
**
** Description            : This service disables interrupts for all CSIX units
**
** Sync/Async             : Synchronous
**
** Re-entrancy            : Non-Reentrant
**
** Input Parameters       : None
**
** InOut Parameters       : None
**
** Output Parameters      : None
**
** Return parameter       : None
**
** Preconditions          : Global variables must be initialized
**
** Global Variable        : Spi_GpConfigPtr, Spi_GpFirstHWUnit, Spi_GaaCSIHRegs
**
** Function invoked       : None
**
** Registers Used         : EIC(CSIXnTIRE), EIC(CSIXnTIR), EIC(CSIXnTIC)
**
** Reference ID           : SPI_DUD_ACT_051, SPI_DUD_ACT_051_REG001, SPI_DUD_ACT_051_REG002, SPI_DUD_ACT_051_REG007,
** Reference ID           : SPI_DUD_ACT_051_REG003, SPI_DUD_ACT_051_REG004, SPI_DUD_ACT_051_REG005,
** Reference ID           : SPI_DUD_ACT_051_REG006
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXDisableAllInterrupts(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_CSIH == LpHWInfo->ucMacroIndex)                                                                       /* PRQA S 2814, 2844 # JV-01, JV-01 */
    {
      /* Disable all interrupts unconditionally */
      RH850_SV_MODE_ICR_OR(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIR, (uint8)SPI_EIC_EIMK_MASK);              /* PRQA S 0751, 2814 # JV-01, JV-01 */
                           
      RH850_SV_MODE_ICR_OR(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC, (uint8)SPI_EIC_EIMK_MASK);              /* PRQA S 0751 # JV-01 */
                           
      RH850_SV_MODE_ICR_OR(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIRE, (uint8)SPI_EIC_EIMK_MASK);             /* PRQA S 0751 # JV-01 */

      /* Clear pending interrupt flags */
      RH850_SV_MODE_ICR_AND(16, (Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC), (uint16)(~SPI_EIC_EIRF_MASK));
      RH850_SV_MODE_ICR_AND(16, (Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIR), (uint16)(~SPI_EIC_EIRF_MASK));
      RH850_SV_MODE_ICR_AND(16, (Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIRE), (uint16)(~SPI_EIC_EIRF_MASK));
      
      /* DummyRead & SYNCP */
      RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[0].pICTIR);
      EXECUTE_SYNCP();
    } /* else No action required */
  }
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXMainFunction_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 must have been invoked.
**
** Global Variable    : Spi_GpConfigPtr, Spi_GpFirstDMAUnit, Spi_GulCancelingHWUnits, Spi_GpFirstHWUnit,
**                      Spi_GulActiveHWUnits, Spi_GetHWUnitStatus, Spi_GaaCSIHRegs
**
** Function Invoked   : Spi_DMAGetInterruptFlag, Spi_CSIXTransmitISR, Spi_CSIXReceiveISR, Spi_CSIXDMACompleteISR
**
** Registers Used     : EIC(CSIXnTIR), EIC(CSIXnTIC)
**
** Reference ID       : SPI_DUD_ACT_052, SPI_DUD_ACT_052_REG001, SPI_DUD_ACT_052_REG002, SPI_DUD_ACT_052_REG003
***********************************************************************************************************************/
#if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXMainFunction_Handling(void)
{
  #if (SPI_DMA_CONFIGURED == STD_ON)
  P2CONST(Spi_DmaConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpDmaConfig;
  uint32 LulDmaIndex;
  uint32 LulTxAssignedToDma;
  uint32 LulRxAssignedToDma;
  uint32 LulDmaIntFlag;
  #endif
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  uint32 LulHWUnitIndex;

  /* Scan DMA completions */
  #if (SPI_DMA_CONFIGURED == STD_ON)
  LulTxAssignedToDma = 0UL;
  LulRxAssignedToDma = 0UL;
  for (LulDmaIndex = 0U; LulDmaIndex < Spi_GpConfigPtr->ucNoOfDMAChannels; LulDmaIndex++)
  {
    LpDmaConfig = &Spi_GpFirstDMAUnit[LulDmaIndex];

    if (SPI_TRUE == LpDmaConfig->blRxSide)                                                                              /* PRQA S 2814, 2844 # JV-01, JV-01 */
    {
      /* Invoke DMA ISR if the IRQ is asserted */
      LulDmaIntFlag = Spi_DMAGetInterruptFlag(LulDmaIndex);
      if (
          #if (SPI_FORCE_CANCEL_API == STD_ON)
          (0UL == (Spi_GulCancelingHWUnits & (1UL << LpDmaConfig->ucSPIHWUnit))) &&
          #endif
          (0UL != LulDmaIntFlag))
      {
        Spi_CSIXDMACompleteISR(LulDmaIndex);
      } /* else No action required */
      /* If the rx side is using DMA, polling of CSIXnTIR is not necessary */
      LulRxAssignedToDma |= (1UL << LpDmaConfig->ucSPIHWUnit);
    }
    else
    {
      /* If the tx side is using DMA, polling of CSIXnTIC is not necessary */
      LulTxAssignedToDma |= (1UL << LpDmaConfig->ucSPIHWUnit);
    }
  }
  #endif

  /* Scan CSIXnTIC and CSIXnTIR */
  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_CSIH == 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
    )
    {
      /* Tx interruption */
      if (
          #if (SPI_DMA_CONFIGURED == STD_ON)
          (0UL == (LulTxAssignedToDma & (1UL << LulHWUnitIndex))) &&
          #endif
          (0U !=
           (RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC) & SPI_EIC_EIRF_MASK)))    /* PRQA S 2814 # JV-01 */
      {
        RH850_SV_MODE_ICR_AND(16, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC, (uint16)(~SPI_EIC_EIRF_MASK));
        Spi_CSIXTransmitISR(LulHWUnitIndex);
      } /* else No action required */

      /* Rx interruption */
      if (
          #if (SPI_DMA_CONFIGURED == STD_ON)
          (0UL == (LulRxAssignedToDma & (1UL << LulHWUnitIndex))) &&
          #endif
          (0U !=
           (RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIR) & SPI_EIC_EIRF_MASK)))
      {
        /* To emulate the default interrupt priority (CSIXnTIC > CSIXnTIR), check CSIXnTIC again */
        if (
            #if (SPI_DMA_CONFIGURED == STD_ON)
            (0UL == (LulTxAssignedToDma & (1UL << LulHWUnitIndex))) &&
            #endif
            (0U !=
             (RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC) & SPI_EIC_EIRF_MASK)))
        {
          RH850_SV_MODE_ICR_AND(16, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC, (uint16)(~SPI_EIC_EIRF_MASK));
          Spi_CSIXTransmitISR(LulHWUnitIndex);
        } /* else No action required */

        RH850_SV_MODE_ICR_AND(16, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIR, (uint16)(~SPI_EIC_EIRF_MASK));
        Spi_CSIXReceiveISR(LulHWUnitIndex);
      } /* else No action required */
    }

    /* Do DummyRead & SYNCP */
    RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[0].pICTIR);
    EXECUTE_SYNCP();
  }
}
#endif /* (SPI_LEVEL_DELIVERED == SPI_LEVEL_2) */

#if ((SPI_LEVEL_DELIVERED != SPI_LEVEL_0) && (SPI_FORCE_CANCEL_API == STD_ON))
/***********************************************************************************************************************
** Function Name      : Spi_CSIXForceStop
**
** Service ID         : Not Applicable
**
** Description        : This function stops a CSIX 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_GaaCSIHRegs, Spi_GpFirstJob, Spi_GaaHWStatus
**
** Function Invoked   : Spi_DMAStop
**
** Registers Used     : CSIXnCTL0, EIC(CSIXnTIR), EIC(CSIXnTIC)
**
** Reference ID       : SPI_DUD_ACT_056, SPI_DUD_ACT_056_REG001, SPI_DUD_ACT_056_REG002, SPI_DUD_ACT_056_REG003
***********************************************************************************************************************/
STATIC FUNC(void, SPI_CODE_FAST) Spi_CSIXForceStop(const uint32 LulHWUnitIndex)
{
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;
  uint32 LulHWPhyIndex;
  #if (SPI_DMA_CONFIGURED == STD_ON)
  P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig;
  #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 CTL0.PWR = 0 */
  Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = SPI_CSIH_CTL0_TURNOFF;                                                 /* PRQA S 2814 # JV-01 */

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

  #if (SPI_DMA_CONFIGURED == STD_ON)
  /* Stop DMA */
  LpJobConfig = &Spi_GpFirstJob[Spi_GaaHWStatus[LulHWUnitIndex].usOngoingJobIndex];                                     /* PRQA S 2844 # JV-01 */
  if (SPI_INVALID_DMAUNIT != LpJobConfig->ucRxDmaIndex)                                                                 /* PRQA S 2814, 2844 # JV-01, JV-01 */
  {
    Spi_DMAStop((uint32)LpJobConfig->ucRxDmaIndex);
  } /* else No action required */
  if (SPI_INVALID_DMAUNIT != LpJobConfig->ucTxDmaIndex)
  {
    Spi_DMAStop((uint32)LpJobConfig->ucTxDmaIndex);
  } /* else No action required */
  #endif /* (SPI_DMA_CONFIGURED == STD_ON) */

  /* Clear pending interrupt flags */
  RH850_SV_MODE_ICR_AND(16, (Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIC), (uint16)(~SPI_EIC_EIRF_MASK));
  RH850_SV_MODE_ICR_AND(16, (Spi_GaaCSIHRegs[LulHWPhyIndex].pICTIR), (uint16)(~SPI_EIC_EIRF_MASK));

  RH850_SV_MODE_ICR_OR(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIR, (uint8)SPI_EIC_EIMK_MASK);                  /* PRQA S 0751 # JV-01 */
  RH850_SV_MODE_ICR_OR(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC, (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_GaaCSIHRegs[LulHWPhyIndex].pICTIC);
  EXECUTE_SYNCP();
}
#endif /* ((SPI_LEVEL_DELIVERED != SPI_LEVEL_0) && (SPI_FORCE_CANCEL_API == STD_ON)) */

/***********************************************************************************************************************
** Function Name      : Spi_CSIXMaskHWUnitInterrupts
**
** Service ID         : NA
**
** Description        : This function manipulates interrupt masks of a HWUnit, including DMA interrupts if available.
**                      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_GpFirstJob, Spi_GaaCSIHRegs
**
** Function invoked   : Spi_DMAMaskHWUnitInterrupts, SPI_ENTER_CRITICAL_SECTION, SPI_EXIT_CRITICAL_SECTION
**
** Registers Used     : EIC(CSIXnTIR), EIC(CSIXnTIC)
**
** Reference ID       : SPI_DUD_ACT_057, SPI_DUD_ACT_057_REG004, SPI_DUD_ACT_057_CRT001, SPI_DUD_ACT_057_REG001,
** Reference ID       : SPI_DUD_ACT_057_REG002, SPI_DUD_ACT_057_REG003, SPI_DUD_ACT_057_CRT002
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE)
    Spi_CSIXMaskHWUnitInterrupts(CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
                                 const boolean LblMask)
{
  uint32 LulHWUnitIndex;
  P2CONST(Spi_HWUnitInfoType, AUTOMATIC, SPI_CONFIG_DATA) LpHWInfo;

  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 registers to avoid modifing EIRF bit */
  if (SPI_TRUE == LblMask)
  {
    #if (SPI_DMA_CONFIGURED == STD_ON)
    if (LpJobConfig->ucRxDmaIndex != SPI_INVALID_DMAUNIT)
    {
      Spi_DMAMaskHWUnitInterrupts((uint32)LpJobConfig->ucRxDmaIndex, SPI_TRUE);
    }
    else
    #endif
    {
      RH850_SV_MODE_ICR_OR(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIR, (uint8)SPI_EIC_EIMK_MASK);              /* PRQA S 2844, 0751, 2814 # JV-01, JV-01, JV-01 */
      RH850_SV_MODE_ICR_OR(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC, (uint8)SPI_EIC_EIMK_MASK);              /* PRQA S 0751 # JV-01 */
    }
  }
  else
  {
    #if (SPI_DMA_CONFIGURED == STD_ON)
    if (LpJobConfig->ucRxDmaIndex != SPI_INVALID_DMAUNIT)
    {
      Spi_DMAMaskHWUnitInterrupts((uint32)LpJobConfig->ucRxDmaIndex, SPI_FALSE);
    }
    else
    #endif
    {
      RH850_SV_MODE_ICR_AND(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIR, (uint8)(~SPI_EIC_EIMK_MASK));          /* PRQA S 0751 # JV-01 */
      RH850_SV_MODE_ICR_AND(8, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC, (uint8)(~SPI_EIC_EIMK_MASK));          /* PRQA S 0751 # JV-01 */
    }
  }
  /* To ensure change of interrupt masks, do dummy read & SYNCP */
  RH850_SV_MODE_REG_READ_ONLY(16, Spi_GaaCSIHRegs[LpHWInfo->ucPhyUnitIndex].pICTIC);
  EXECUTE_SYNCP();
  SPI_EXIT_CRITICAL_SECTION(SPI_INTERRUPT_CONTROL_PROTECTION);
}

/***********************************************************************************************************************
** Function Name      : Spi_CSIXTurnOff
**
** Service ID         : Not Applicable
**
** Description        : This function turn off CSIX
**
** 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_GaaCSIHRegs
**
** Function Invoked   : None
**
** Registers Used     : CSIXnCTL0
**
** Reference ID       : SPI_DUD_ACT_058, SPI_DUD_ACT_058_REG001
***********************************************************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXTurnOff(const uint32 LulHWPhyIndex)
{
  Spi_GaaCSIHRegs[LulHWPhyIndex].pRegs->ucCTL0 = SPI_CSIH_CTL0_TURNOFF;                                                 /* PRQA S 2844, 2814 # JV-01, JV-01 */
}

#if (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON)
/*******************************************************************************
** Function Name      : Spi_CSIXHWControlCS
**
** Service ID         : Not Applicable
**
** Description        : This service performs activation of the Chip Select pin.
**
** Sync/Async         : Synchronous.
**
** Re-entrancy        : Non-Reentrant
**
** Input Parameters   : LpJobConfig - Pointer to Job configuration.
**                      LblActivateCS - Chip select activation is required.
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : None
**
** Global Variable    : None
**
** Function Invoked   : None
**
** Registers Used     : PSRn, JPSRn
**
** Reference ID       : SPI_DUD_ACT_103,
** Reference ID       : SPI_DUD_ACT_103_REG001, SPI_DUD_ACT_103_REG002
** Reference ID       : SPI_DUD_ACT_103_CRT001, SPI_DUD_ACT_103_CRT002
*******************************************************************************/
STATIC FUNC(void, SPI_PRIVATE_CODE) Spi_CSIXHWControlCS(
  CONSTP2CONST(Spi_JobConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpJobConfig,
  CONST(boolean, AUTOMATIC) LblActivateCS)
{
  volatile VAR(uint32, AUTOMATIC) LulLoopCount;
  #if (SPI_CRITICAL_SECTION_PROTECTION == STD_ON)
  SPI_ENTER_CRITICAL_SECTION(SPI_INTERRUPT_CONTROL_PROTECTION);
  #endif
  /* Set or reset port pin depending on chip select polarity and cs act flag */
  if (((SPI_CS_HIGH == LpJobConfig->blCsPolarity) && (SPI_TRUE == LblActivateCS)) ||                                    /* PRQA S 2814 # JV-01 */
    ((SPI_CS_LOW == LpJobConfig->blCsPolarity) && (SPI_FALSE == LblActivateCS)))
  {
    *(LpJobConfig->pPSRReg) = LpJobConfig->ulPortPinMask;                                                               /* PRQA S 2814 # JV-01 */
  }
  else /* If Chip select polarity is configured as active Low */
  {
    *(LpJobConfig->pPSRReg) = LpJobConfig->ulPortPinMask & SPI_PORT_PIN_MASK;
  }

  /* Check whether CS activation is required */
  if (SPI_TRUE == LblActivateCS)
  {
    /* Timing between chip select activated and clock start when writing data */
    LulLoopCount = LpJobConfig->ulClk2CsCount;
    while ((uint32)SPI_ZERO < LulLoopCount)                                                                             /* PRQA S 3416 # JV-01 */
    {
      LulLoopCount--;                                                                                                   /* PRQA S 3387, 3384 # JV-01, JV-01 */
    }
  }
  #if (SPI_CRITICAL_SECTION_PROTECTION == STD_ON)
  SPI_EXIT_CRITICAL_SECTION(SPI_INTERRUPT_CONTROL_PROTECTION);
  #endif
}
#endif /* (SPI_CS_VIA_GPIO_CONFIGURED == STD_ON) */

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

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