/*====================================================================================================================*/
/* Project      = AUTOSAR Renesas X2x MCAL Components                                                                 */
/* Module       = Spi_sDMAC_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:  11/11/2022  : As per ARDAACA-1266:
 *                       Spi_DMAInit: Remove Spi_GaaCSIHRegs, Spi_GaaMSPIRegs in Global variable field
 *                       As per ARDAACA-1265:
 *                       Spi_DMAGetInterruptFlag: Change the Return parameter from interrupt flag to uint32
 *                       in description field
 *         08/07/2022  : Add DummyRead & SYNCP in functions: Spi_DMAMaskHWUnitInterrupts
 * 1.4.3:  10/05/2022  : Remove else do nothing
 * 1.3.2:  06/09/2021  : Update QAC contents
 *         04/09/2021  : Replace the inclusion of Spi_MemMap.h with Spi_Mapping.h
 * 1.3.1:  02/07/2021  : Add QAC message 9.5.0
 *                       Format source code to 120 characters
 *                       Improve Violation tag (remove START/END) 
 *         19/05/2021  : Update QAC contents.
 * 1.2.0:  30/07/2020  : Release
 *         28/07/2020  : Add QAC 9.3.1 comment.
 * 1.1.0:  19/06/2020  : Release
 * 1.0.2:  22/05/2020  : Update QAC message and MISRA-C Rule violation.
 * 1.0.1:  27/04/2020  : The following changes are made:
 *                       1. Remove interrupt enable and add TE interrupt flag in Spi_DMAInit.
 * 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 "rh850_Types.h"

/***********************************************************************************************************************
**                                                Version Information                                                 **
***********************************************************************************************************************/
/* AUTOSAR release version information */
#define SPI_SDMAC_LLDRIVER_C_AR_RELEASE_MAJOR_VERSION    SPI_AR_RELEASE_MAJOR_VERSION_VALUE
#define SPI_SDMAC_LLDRIVER_C_AR_RELEASE_MINOR_VERSION    SPI_AR_RELEASE_MINOR_VERSION_VALUE                             /* PRQA S 0791 # JV-01 */
#define SPI_SDMAC_LLDRIVER_C_AR_RELEASE_REVISION_VERSION SPI_AR_RELEASE_REVISION_VERSION_VALUE                          /* PRQA S 0791 # JV-01 */

/* File version information */
#define SPI_SDMAC_LLDRIVER_C_SW_MAJOR_VERSION            SPI_SW_MAJOR_VERSION_VALUE                                     /* PRQA S 0857 # JV-01 */
#define SPI_SDMAC_LLDRIVER_C_SW_MINOR_VERSION            SPI_SW_MINOR_VERSION_VALUE

/***********************************************************************************************************************
**                                                   Version Check                                                    **
***********************************************************************************************************************/
#if (SPI_SDMAC_LLDRIVER_AR_RELEASE_MAJOR_VERSION != SPI_SDMAC_LLDRIVER_C_AR_RELEASE_MAJOR_VERSION)
#error "Spi_sDMAC_LLDriver.c : Mismatch in Release Major Version"
#endif

#if (SPI_SDMAC_LLDRIVER_AR_RELEASE_MINOR_VERSION != SPI_SDMAC_LLDRIVER_C_AR_RELEASE_MINOR_VERSION)
#error "Spi_sDMAC_LLDriver.c : Mismatch in Release Minor Version"
#endif

#if (SPI_SDMAC_LLDRIVER_AR_RELEASE_REVISION_VERSION != SPI_SDMAC_LLDRIVER_C_AR_RELEASE_REVISION_VERSION)
#error "Spi_sDMAC_LLDriver.c : Mismatch in Release Revision Version"
#endif

#if (SPI_SDMAC_LLDRIVER_SW_MAJOR_VERSION != SPI_SDMAC_LLDRIVER_C_SW_MAJOR_VERSION)
#error "Spi_sDMAC_LLDriver.c : Mismatch in Software Major Version"
#endif

#if (SPI_SDMAC_LLDRIVER_SW_MINOR_VERSION != SPI_SDMAC_LLDRIVER_C_SW_MINOR_VERSION)
#error "Spi_sDMAC_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 (1:1532)    : The function '%1s' is only referenced in one translation unit - but not the one in which it  */
/*                       is defined.                                                                                  */
/* Rule                : CERTCCM DCL19, MISRA C:2012 Rule-8.7                                                         */
/* 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:2814)    : Possible: Dereference of NULL pointer.                                                       */
/* Rule                : CERTCCM EXP34                                                                                */
/* JV-01 Justification : This is accepted, due to the implementation is following hardware specification.             */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2844)    : Possible: Dereference of an invalid pointer value.                                           */
/* Rule                : CERTCCM ARR30                                                                                */
/* JV-01 Justification : It is specific for device register accessing and confirmed has no issue in software behavior.*/
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2: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: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:2985)    : This operation is redundant. The value of the result is always that of the left-hand operand.*/
/* Rule                : CERTCCM MSC07, MSC13, MISRA C:2012 Rule-2.2                                                  */
/* JV-01 Justification : For readability, setting to registers will used redundant macros and is based on hardware    */
/*                       user's manual                                                                                */
/*       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 (7:0326)    : Cast between a pointer to void and an integral type.                                         */
/* Rule                : CERTCCM EXP36, INT36, MISRA C:2012 Rule-11.6                                                 */
/* 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 (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.              */
/**********************************************************************************************************************/
/* Message (2:3464)    : Argument to macro '%s' contains a side effect that will be evaluated more than once.         */
/* Rule                : CERTCCM PRE31                                                                                */
/* JV-01 Justification : This message is only emitted for expressions expanded from argument tokens written out at    */
/*                       the top level, that did not themselves originate from a macro expansion.                     */
/*       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.              */
/**********************************************************************************************************************/

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

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

#define SPI_START_SEC_PRIVATE_CODE
#include "Spi_Mapping.h"

/***********************************************************************************************************************
** Function Name      : Spi_DMAInit
**
** Service ID         : Not Applicable
**
** Description        : This function initializes all configured DMA units
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Non-Reentrant
**
** Input Parameters   : None
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : None
**
** Global Variable    : Spi_GpConfigPtr, Spi_GpFirstHWUnit, Spi_GpFirstDMAUnit
**
** Function invoked   : Spi_DMAClearInterruptFlag
**
** Registers Used     : DMACSELj_m, MSPInTXDAm, MSPInRXDAm, CSIXnRX0H, CSIXnTX0H, DMAjSGCR_n, DMAjCHSTP_n,
**                      DMAjCHCR_n, DMAjCHFCR_n, DMAjRS_n, DMAjBUFCR_n, DMAjSAR_n, DMAjDAR_n, EIC(SDMACjCHn)
**
** Reference ID       : SPI_DUD_ACT_080, SPI_DUD_ACT_080_REG001, SPI_DUD_ACT_080_REG002, SPI_DUD_ACT_080_REG003,
** Reference ID       : SPI_DUD_ACT_080_REG004, SPI_DUD_ACT_080_REG005, SPI_DUD_ACT_080_REG006, SPI_DUD_ACT_080_REG007
***********************************************************************************************************************/
FUNC(void, SPI_PRIVATE_CODE) Spi_DMAInit(void)                                                                          /* PRQA S 1532 # JV-01 */
{
  uint32 LulDmaIndex;
  uint32 LulCSEL;
  P2CONST(Spi_DmaConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpDmaConfig;

  for (LulDmaIndex = 0UL; LulDmaIndex < Spi_GpConfigPtr->ucNoOfDMAChannels; LulDmaIndex++)
  {
    LpDmaConfig = &Spi_GpFirstDMAUnit[LulDmaIndex];
    /* Stop DMA and clear all flags */
    LpDmaConfig->pDmaRegs->ulCHFCR =                                                                                    /* PRQA S 2814, 2844 # JV-01, JV-01 */
        (uint32)(SPI_DMA_OVF | SPI_DMA_DRQ | SPI_DMA_DPE | SPI_DMA_CAE | SPI_DMA_DSE | SPI_DMA_TE | SPI_DMA_DE);
    /* Set/Reset TriggerGroup bit */
    LulCSEL = LpDmaConfig->pDMACSEL[SPI_DMA_SEL_INDEX(LpDmaConfig->ucTriggerNumber)];                                   /* PRQA S 2824, 3469 # JV-01, JV-01 */
    LulCSEL &= ~(1UL << SPI_DMA_SEL_SHIFT(LpDmaConfig->ucTriggerNumber));                                               /* PRQA S 3469 # JV-01 */
    LulCSEL |= ((uint32)LpDmaConfig->ucTriggerGroup << SPI_DMA_SEL_SHIFT(LpDmaConfig->ucTriggerNumber));                /* PRQA S 3469 # JV-01 */
    LpDmaConfig->pDMACSEL[SPI_DMA_SEL_INDEX(LpDmaConfig->ucTriggerNumber)] = LulCSEL;                                   /* PRQA S 3469 # JV-01 */
    /* Set trigger number */
    LpDmaConfig->pDmaRegs->ulRS = SPI_DMA_RS(LpDmaConfig->ucTriggerNumber);                                             /* PRQA S 3469 # JV-01 */
    /* Set pre-fetch buffer length as default (128) */
    LpDmaConfig->pDmaRegs->ulBUFCR = SPI_DMA_ULB_DEFAULT;
    /* Scatter/Gather features are not used */
    LpDmaConfig->pDmaRegs->ulSGCR = 0UL;
    /* Reset STP bit */
    LpDmaConfig->pDmaRegs->usCHSTP = 0U;
    /* Set source/destination address of register side */
    if (SPI_TRUE == LpDmaConfig->blRxSide)
    {
      LpDmaConfig->pDmaRegs->ulSAR = LpDmaConfig->ulRegAddress;
      /* Clear TE interrupt flag */
      Spi_DMAClearInterruptFlag(LulDmaIndex);
    }
    else
    {
      LpDmaConfig->pDmaRegs->ulDAR = LpDmaConfig->ulRegAddress;
    }
    /* Set interrupt mask */
    RH850_SV_MODE_ICR_OR(8, LpDmaConfig->pICDma, (uint8)SPI_EIC_EIMK_MASK);                                             /* PRQA S 0751, 2814 # JV-01, JV-01 */
  }
  /* Dummy read & SYNCP */
  if (0U < Spi_GpConfigPtr->ucNoOfDMAChannels)
  {
    LpDmaConfig = &Spi_GpFirstDMAUnit[0];
    LpDmaConfig->pDmaRegs->usCHCR;                                                                                      /* PRQA S 2844, 2814 # JV-01, JV-01 */
    RH850_SV_MODE_REG_READ_ONLY(16, LpDmaConfig->pICDma);                                                               /* PRQA S 2814 # JV-01 */
    EXECUTE_SYNCP();
  } /* else No action required */
}

/***********************************************************************************************************************
** Function Name      : Spi_DMADeInit
**
** Service ID         : Not Applicable
**
** Description        : This function de-initializes all configured DMA units
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Non-Reentrant
**
** Input Parameters   : None
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpConfigPtr, Spi_GpFirstDMAUnit
**
** Function invoked   : None
** 
** Registers Used     : DMAjCHCR_n, DMAjCHFCR_n, EIC(SDMACjCHn), DMAjSAR_n, DMAjDAR_n, DMAjTSR_n, DMAjTMR_n,
**                      DMAjRS_n, DMAjBUFCR_n, DMACSELj_m
**
** Reference ID       : SPI_DUD_ACT_081, SPI_DUD_ACT_081_REG001, SPI_DUD_ACT_081_REG002, SPI_DUD_ACT_081_REG003,
** Reference ID       : SPI_DUD_ACT_081_REG004, SPI_DUD_ACT_081_REG005, SPI_DUD_ACT_081_REG006, SPI_DUD_ACT_081_REG007,
** Reference ID       : SPI_DUD_ACT_081_REG008, SPI_DUD_ACT_081_REG009, SPI_DUD_ACT_081_REG010, SPI_DUD_ACT_081_REG011
** Reference ID       : SPI_DUD_ACT_081_REG012
***********************************************************************************************************************/
FUNC(void, SPI_PRIVATE_CODE) Spi_DMADeInit(void)                                                                        /* PRQA S 1532 # JV-01 */
{
  uint32 LulDmaIndex;
  uint32 LulCSEL;
  P2CONST(Spi_DmaConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpDmaConfig;

  for (LulDmaIndex = 0UL; LulDmaIndex < Spi_GpConfigPtr->ucNoOfDMAChannels; LulDmaIndex++)
  {
    LpDmaConfig = &Spi_GpFirstDMAUnit[LulDmaIndex];
    /* Stop DMA and clear all flags */
    LpDmaConfig->pDmaRegs->ulCHFCR =                                                                                    /* PRQA S 2844, 2814 # JV-01, JV-01 */
        (uint32)(SPI_DMA_OVF | SPI_DMA_DRQ | SPI_DMA_DPE | SPI_DMA_CAE | SPI_DMA_DSE | SPI_DMA_TE | SPI_DMA_DE);
    /* Restore all used registers as the reset default value */
    LpDmaConfig->pDmaRegs->ulSAR = 0UL;
    LpDmaConfig->pDmaRegs->ulDAR = 0UL;
    LpDmaConfig->pDmaRegs->ulTSR = 0UL;
    LpDmaConfig->pDmaRegs->ulTMR = SPI_DMA_TMR_DEFAULT;
    LpDmaConfig->pDmaRegs->usCHCR = SPI_DMA_CHCR_DEFAULT;
    LpDmaConfig->pDmaRegs->ulRS = SPI_DMA_RS_DEFAULT;
    LpDmaConfig->pDmaRegs->ulBUFCR = SPI_DMA_ULB_DEFAULT;
    LulCSEL = LpDmaConfig->pDMACSEL[SPI_DMA_SEL_INDEX(LpDmaConfig->ucTriggerNumber)];                                   /* PRQA S 2824, 3469 # JV-01, JV-01 */
    LulCSEL &= ~(1UL << SPI_DMA_SEL_SHIFT(LpDmaConfig->ucTriggerNumber));                                               /* PRQA S 3469 # JV-01 */
    LpDmaConfig->pDMACSEL[SPI_DMA_SEL_INDEX(LpDmaConfig->ucTriggerNumber)] = LulCSEL;                                   /* PRQA S 3469 # JV-01 */
    /* Set interrupt mask */
    RH850_SV_MODE_ICR_OR(8, LpDmaConfig->pICDma, (uint8)SPI_EIC_EIMK_MASK);                                             /* PRQA S 2814, 0751 # JV-01, JV-01 */
    /* Clear pending interrupt */
    RH850_SV_MODE_ICR_AND(16, LpDmaConfig->pICDma, (uint16)(~SPI_EIC_EIRF_MASK));
  }
  /* Dummy read & SYNCP */
  if (0U < Spi_GpConfigPtr->ucNoOfDMAChannels)
  {
    LpDmaConfig = &Spi_GpFirstDMAUnit[0];
    LpDmaConfig->pDmaRegs->usCHCR;                                                                                      /* PRQA S 2844, 2814 # JV-01, JV-01 */
    RH850_SV_MODE_REG_READ_ONLY(16, LpDmaConfig->pICDma);                                                               /* PRQA S 2814 # JV-01 */
    EXECUTE_SYNCP();
  } /* else No action required */
}

/***********************************************************************************************************************
** Function Name      : Spi_DMAStart
**
** Service ID         : Not Applicable
**
** Description        : This function starts DMA transfer
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW. Non-Reentrant for same HW
**
** Input Parameters   : LulDmaIndex   - Index of DMAUnit
**                      LpMemAddress  - Address of memory side
**                      LulCount      - Number of data elements
**                      LulAttributes - Transfer attributes
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : Spi_Init should have been invoked.
**
** Global Variable    : Spi_GpFirstDMAUnit, Spi_GenAsyncMode
**
** Function invoked   : None
**
** Registers Used     : DMAjTMR_n, DMAjTSR_n, DMAjSAR_n, DMAjDAR_n, DMAjCHFCR_n, DMAjCHCR_n, DMAjRS_n
**
** Reference ID       : SPI_DUD_ACT_082, SPI_DUD_ACT_082_REG001, SPI_DUD_ACT_082_REG002, SPI_DUD_ACT_082_REG003,
** Reference ID       : SPI_DUD_ACT_082_REG004, SPI_DUD_ACT_082_REG005, SPI_DUD_ACT_082_REG006, SPI_DUD_ACT_082_REG007,
** Reference ID       : SPI_DUD_ACT_082_REG008
***********************************************************************************************************************/
FUNC(void, SPI_PRIVATE_CODE)
Spi_DMAStart(const uint32 LulDmaIndex, volatile CONSTP2CONST(void, AUTOMATIC, SPI_APPL_DATA) LpMemAddress,              /* PRQA S 1532 # JV-01 */
             const uint32 LulCount, const uint32 LulAttributes)
{
  P2CONST(Spi_DmaConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpDmaConfig;
  uint32 LulTMR;
  uint32 LulTSR;

  LpDmaConfig = &Spi_GpFirstDMAUnit[LulDmaIndex];

  /* Setup size of transfer count per hardware request */
  LpDmaConfig->pDmaRegs->ulRS &= ~SPI_DMA_TC_MASK;                                                                      /* PRQA S 2844, 2814 # JV-01, JV-01 */
  LpDmaConfig->pDmaRegs->ulRS |= LulAttributes & SPI_DMA_TC_MASK;

  /* Keep priority setting by user */
  LulTMR = LpDmaConfig->pDmaRegs->ulTMR & SPI_DMA_PRI_MASK;
  /* Setup normal mode and hardware request source */
  LulTMR = LulTMR | SPI_DMA_SLM_NORMAL | SPI_DMA_TRS;                                                                   /* PRQA S 2985 # JV-01 */
  /* Setup transaction size in TMR register */
  switch (LulAttributes & SPI_DMA_DTS_STS_MASK)
  {
  case SPI_DMA_32BIT:
    LulTMR = LulTMR | SPI_DMA_DTS_4 | SPI_DMA_STS_4;
    LulTSR = LulCount * (uint32)(sizeof(uint32));                                                                       /* PRQA S 3383 # JV-01 */
    break;
  case SPI_DMA_16BIT:
    LulTMR = LulTMR | SPI_DMA_DTS_2 | SPI_DMA_STS_2;
    LulTSR = LulCount * (uint32)(sizeof(uint16));                                                                       /* PRQA S 3383 # JV-01 */
    break;
  default:
    LulTSR = LulCount;
    break;
  }

  if (SPI_TRUE == LpDmaConfig->blRxSide)
  {
    LpDmaConfig->pDmaRegs->ulDAR = (uint32)LpMemAddress;                                                                /* PRQA S 0326 # JV-01 */
    if (0UL != (LulAttributes & SPI_DMA_INCDST))
    {
      LulTMR = LulTMR | SPI_DMA_DM_INC | SPI_DMA_SM_FIXED;                                                              /* PRQA S 2985 # JV-01 */
    }
    else
    {
      LulTMR = LulTMR | SPI_DMA_DM_FIXED | SPI_DMA_SM_FIXED;                                                            /* PRQA S 2985 # JV-01 */
    }
  }
  else
  {
    LpDmaConfig->pDmaRegs->ulSAR = (uint32)LpMemAddress;                                                                /* PRQA S 0326 # JV-01 */
    if (0UL != (LulAttributes & SPI_DMA_INCSRC))
    {
      LulTMR = LulTMR | SPI_DMA_DM_FIXED | SPI_DMA_SM_INC;                                                              /* PRQA S 2985 # JV-01 */
    }
    else
    {
      LulTMR = LulTMR | SPI_DMA_DM_FIXED | SPI_DMA_SM_FIXED;                                                            /* PRQA S 2985 # JV-01 */
    }
  }
  LpDmaConfig->pDmaRegs->ulTMR = LulTMR;
  /* Setup transfer count for TSR register*/
  LpDmaConfig->pDmaRegs->ulTSR = LulTSR;
  /* Clear flags */
  LpDmaConfig->pDmaRegs->ulCHFCR =
      (uint32)(SPI_DMA_OVF | SPI_DMA_DRQ | SPI_DMA_DPE | SPI_DMA_CAE | SPI_DMA_DSE | SPI_DMA_TE);
  /* Start DMA */
  if (
      #if (SPI_LEVEL_DELIVERED == SPI_LEVEL_2)
      (SPI_INTERRUPT_MODE == Spi_GenAsyncMode) &&                                                                       /* PRQA S 3416 # JV-01 */
      #endif
      (0UL != (LulAttributes & SPI_DMA_INTERRUPT)))
  {
    LpDmaConfig->pDmaRegs->usCHCR = SPI_DMA_IE | SPI_DMA_DE;
  }
  else
  {
    LpDmaConfig->pDmaRegs->usCHCR = SPI_DMA_DE;
  }
}

/***********************************************************************************************************************
** Function Name      : Spi_DMAStop
**
** Service ID         : Not Applicable
**
** Description        : This function stops DMA unit unconditionally
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HW. Non-Reentrant for same HW
**
** Input Parameters   : LulDMAIndex - Index of DMAUnit
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : Assigned SPI unit must be stopped
**
** Global Variable    : Spi_GpFirstDMAUnit, Spi_GpConfigPtr
**
** Function invoked   : None
**
** Registers Used     : DMAjCHFCR_n, DMAjCHSTA_n
**
** Reference ID       : SPI_DUD_ACT_083, SPI_DUD_ACT_083_REG001, SPI_DUD_ACT_083_REG002
***********************************************************************************************************************/
#if (SPI_FORCE_CANCEL_API == STD_ON)
FUNC(void, SPI_PRIVATE_CODE) Spi_DMAStop(const uint32 LulDmaIndex)                                                      /* PRQA S 1532 # JV-01 */
{
  P2CONST(Spi_DmaConfigType, AUTOMATIC, SPI_CONFIG_DATA) LpDmaConfig;
  uint32 LulCount;

  LpDmaConfig = &Spi_GpFirstDMAUnit[LulDmaIndex];

  /* Stop DMA */
  LpDmaConfig->pDmaRegs->ulCHFCR = SPI_DMA_BUSY_DEC;                                                                    /* PRQA S 2814, 2844 # JV-01, JV-01 */

  /* Wait until DMAjCHSTA.BUSY bit is cleared.
     This loop will finish in a moment unless a DMA malfunctions. */
  LulCount = 0UL;
  while ((LulCount < Spi_GpConfigPtr->ulTimeoutCount) && (0UL != (LpDmaConfig->pDmaRegs->ulCHSTA & SPI_DMA_BUSY_DEC)))
  {
    LulCount++;
  }

  /* Clear all flags */
  LpDmaConfig->pDmaRegs->ulCHFCR =
      (uint32)(SPI_DMA_OVF | SPI_DMA_DRQ | SPI_DMA_DPE | SPI_DMA_CAE | SPI_DMA_DSE | SPI_DMA_TE);

  /* Do DummyRead & SYNCP */
  LpDmaConfig->pDmaRegs->ulCHSTA;
  EXECUTE_SYNCP();
}
#endif /* (SPI_FORCE_CANCEL_SPI == STD_ON) */

/***********************************************************************************************************************
** Function Name      : Spi_DMAMaskHWUnitInterrupts
**
** Service ID         : NA
**
** Description        : This function manipulates interrupt masks of a HWUnit.
**                      This function modifies EIMK bit only, EIRF bit is not affected.
**                      This function doesn't perform disabling interruption, dummy read & SYNCP. These should be done 
**                      in a caller.
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HWUnit. Non-Reentrant for same HWUnit
**
** Input Parameters   : LulDmaIndex - Index of HW
**                      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_GpFirstDMAUnit
**
** Function invoked   : None
**
** Registers Used     : EIC(SDMACjCHn)
**
** Reference ID       : SPI_DUD_ACT_084, SPI_DUD_ACT_084_REG001, SPI_DUD_ACT_084_REG002
***********************************************************************************************************************/
FUNC(void, SPI_PRIVATE_CODE) Spi_DMAMaskHWUnitInterrupts(const uint32 LulDmaIndex, const boolean LblMask)               /* PRQA S 1532 # JV-01 */
{
  /* Check if request to mask interrupt */
  if (SPI_TRUE == LblMask)
  {
    /* Write the lower byte of EIC registers to avoid modifying EIRF bit */
    RH850_SV_MODE_ICR_OR(8, Spi_GpFirstDMAUnit[LulDmaIndex].pICDma, (uint8)SPI_EIC_EIMK_MASK);                          /* PRQA S 2814, 0751, 3464 # JV-01, JV-01, JV-01 */
  }
  else
  {
    /* Write the lower byte of EIC registers to avoid modifying EIRF bit */
    RH850_SV_MODE_ICR_AND(8, Spi_GpFirstDMAUnit[LulDmaIndex].pICDma, (uint8)(~SPI_EIC_EIMK_MASK));                      /* PRQA S 0751, 3464 # JV-01, JV-01 */
  }

  /* DummyRead & SYNCP */
  RH850_SV_MODE_REG_READ_ONLY(16, Spi_GpFirstDMAUnit[LulDmaIndex].pICDma);
  EXECUTE_SYNCP();
}

/***********************************************************************************************************************
** Function Name      : Spi_DMAClearInterruptFlag
**
** Service ID         : NA
**
** Description        : This function clears interrupt flag.
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant for different HWUnit. Non-Reentrant for same HWUnit
**
** Input Parameters   : LulDmaIndex - Index of HW
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : None
**
** Preconditions      : Global variables must be initialized
**
** Global Variable    : Spi_GpFirstDMAUnit
**
** Function invoked   : None
**
** Registers Used     : DMAjCHFCR_n, DMAjCHSTA_n
**
** Reference ID       : SPI_DUD_ACT_085, SPI_DUD_ACT_085_REG001
***********************************************************************************************************************/
FUNC(void, SPI_PRIVATE_CODE) Spi_DMAClearInterruptFlag(const uint32 LulDmaIndex)
{
  /* Clear pending interrupt flag */
  Spi_GpFirstDMAUnit[LulDmaIndex].pDmaRegs->ulCHFCR = SPI_DMA_TE;                                                       /* PRQA S 2814 # JV-01 */

  /* Do DummyRead & SYNCP */
  Spi_GpFirstDMAUnit[LulDmaIndex].pDmaRegs->ulCHSTA;
  EXECUTE_SYNCP();
}

/***********************************************************************************************************************
** Function Name      : Spi_DMAGetInterruptFlag
**
** Service ID         : NA
**
** Description        : This function gets the transfer end flag.
**
** Sync/Async         : Synchronous
**
** Re-entrancy        : Reentrant
**
** Input Parameters   : LulDmaIndex - Index of HW
**
** InOut Parameters   : None
**
** Output Parameters  : None
**
** Return parameter   : uint32
**
** Preconditions      : Global variables must be initialized
**
** Global Variable    : Spi_GpFirstDMAUnit
**
** Function invoked   : None
**
** Registers Used     : DMAjCHSTA_n
**
** Reference ID       : SPI_DUD_ACT_086, SPI_DUD_ACT_086_GBL001
***********************************************************************************************************************/
FUNC(uint32, SPI_PRIVATE_CODE) Spi_DMAGetInterruptFlag(const uint32 LulDmaIndex)                                        /* PRQA S 1532 # JV-01 */
{
  uint32 LulReturnValue;

  LulReturnValue = (Spi_GpFirstDMAUnit[LulDmaIndex].pDmaRegs->ulCHSTA & SPI_DMA_TE);                                    /* PRQA S 2814 # JV-01 */

  return LulReturnValue;
}

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

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