/*!
* @file     Pdl_Dma.c
*
* @version  1.0.0
*
* @brief    The source file of the DMA driver.
*           This source file contains the API specification and other variables of the DMA driver.
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_01-Otc-25
*
* Copyright (C) 2026 Geehy Semiconductor
*
* You may not use this file except in compliance with the
* GEEHY COPYRIGHT NOTICE (Geehy Semiconductor Software License Agreement).
*
* The program is only for reference, which is distributed in the hope
* that it will be usefull and instructional for customers to develop
* their software. Unless required by applicable law or agreed to in
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
* See the Geehy Semiconductor Software License Agreement for the governing permissions
* and limitations under the License.
*/

#ifdef __cplusplus
extern "C"{
#endif   /* ifdef __cplusplus */ 

#include "Mcal.h"
#include "StdRegMacros.h"
#include "Pdl_Dma.h"
#include "CDD_Pdl.h"
/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup PDL_Driver
  * @brief PDL driver modules
  @{
*/

/** @defgroup PDL_Macros
  @{
*/
/***********************************************************************************************************************
                                    VENDOR ID & AUTOSAR VERSION INFO
***********************************************************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define PDL_DMA_VENDOR_ID                        0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PDL_DMA_AR_RELEASE_MAJOR_VERSION         0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PDL_DMA_AR_RELEASE_MINOR_VERSION         0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PDL_DMA_AR_RELEASE_REVISION_VERSION      0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */ 
#define PDL_DMA_SW_MAJOR_VERSION                 0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define PDL_DMA_SW_MINOR_VERSION                 0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define PDL_DMA_SW_PATCH_VERSION                 0x00U
/**@} end of group PDL_Macros */
/**********************************************************************************************************************
                                        VERSION INFOMATION VERIFICATION
***********************************************************************************************************************/
#ifdef ENABLE_INTERMODULE_MCAL_CHECK
    /* Make sure the AUTOSAR major version number is the same between Pdl_Dma.c and Mcal.h */
    #if (PDL_DMA_AR_RELEASE_MAJOR_VERSION != MCAL_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Numbers mismatch between Pdl_Dma.c and Mcal.h"
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Pdl_Dma.c and Mcal.h */
    #if (PDL_DMA_AR_RELEASE_MINOR_VERSION != MCAL_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Numbers mismatch between Pdl_Dma.c and Mcal.h"
    #endif
    
    /* Make sure the AUTOSAR major version number is the same between Pdl_Dma.c and StdRegMacros.h */
    #if (PDL_DMA_AR_RELEASE_MAJOR_VERSION != STD_REG_MACROS_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Numbers mismatch between Pdl_Dma.c and StdRegMacros.h"
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Pdl_Dma.c and StdRegMacros.h */
    #if (PDL_DMA_AR_RELEASE_MINOR_VERSION != STD_REG_MACROS_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Numbers mismatch between Pdl_Dma.c and StdRegMacros.h"
    #endif
#endif

/* Make sure the AUTOSAR major version number is the same between Pdl_Dma.c and Pdl_Dma.h */
#if (PDL_DMA_AR_RELEASE_MAJOR_VERSION != PDL_DMA_H_AR_RELEASE_MAJOR_VERSION)
#error "AUTOSAR Major Version Numbers mismatch between Pdl_Dma.c and Pdl_Dma.h"
#endif
/* Make sure the AUTOSAR minor version number is the same between Pdl_Dma.c and Pdl_Dma.h */
#if (PDL_DMA_AR_RELEASE_MINOR_VERSION != PDL_DMA_H_AR_RELEASE_MINOR_VERSION)
#error "AUTOSAR Minor Version Numbers mismatch between Pdl_Dma.c and Pdl_Dma.h"
#endif
/* Make sure the AUTOSAR revision version number is the same between Pdl_Dma.c and Pdl_Dma.h */
#if (PDL_DMA_AR_RELEASE_REVISION_VERSION != PDL_DMA_H_AR_RELEASE_REVISION_VERSION)
#error "AUTOSAR Revision Version Numbers mismatch between Pdl_Dma.c and Pdl_Dma.h"
#endif

#if (PDL_DMA_VENDOR_ID != PDL_DMA_H_VENDOR_ID)
    #error "Vendor ids mismatch between Pdl_Dma.c and Pdl_Dma.h"
#endif  /* {if (PDL_DMA_VENDOR_ID != PDL_DMA_H_VENDOR_ID)} */

/* Make sure the software major version number is the same between Pdl_Dma.c and Pdl_Dma.h */
#if (PDL_DMA_SW_MAJOR_VERSION != PDL_DMA_H_SW_MAJOR_VERSION)
#error "Software Major Version Numbers mismatch between Pdl_Dma.c and Pdl_Dma.h"
#endif
/* Make sure the software minor version number is the same between Pdl_Dma.c and Pdl_Dma.h */
#if (PDL_DMA_SW_MINOR_VERSION != PDL_DMA_H_SW_MINOR_VERSION)
#error "Software Minor Version Numbers mismatch between Pdl_Dma.c and Pdl_Dma.h"
#endif
/* Make sure the software patch version number is the same between Pdl_Dma.c and Pdl_Dma.h */
#if (PDL_DMA_SW_PATCH_VERSION != PDL_DMA_H_SW_PATCH_VERSION)
#error "Software Patch Version Numbers mismatch between Pdl_Dma.c and Pdl_Dma.h"
#endif

/**********************************************************************************************************************
                                                  LOCAL FUNCTION
***********************************************************************************************************************/
/** @defgroup PDL_Fuctions
  @{
*/
#if (STD_ON == CDD_PDL_DMA_SUPPORT)
#define PDL_START_SEC_CODE
#include "Pdl_MemMap.h"

#if (STD_ON == CDD_PDL_DMA_GET_CH_ERR_STAT_API)
#if (STD_OFF == CDD_PDL_DEM_ERR_REP_DISABLE)
LOCAL_INLINE FUNC(void, PDL_CODE) Pdl_Dma_RepDemErr(VAR(uint32,AUTOMATIC) GlobalErrStatus,
                                                   VAR(Pdl_DmaChErrStsType,AUTOMATIC) ChErrStatus)
{
    if((uint32)STD_ON == g_pdlDemConfigPtr->pdlDmaUnrecognizedError.state)
    {
        if (ChErrStatus == DMA_UNRECOG_ERR)
        {
            (void)Dem_SetEventStatus((Dem_EventIdType)g_pdlDemConfigPtr->pdlDmaUnrecognizedError.id, DEM_EVENT_STATUS_FAILED);
        }
        else if (ChErrStatus == DMA_CH_NO_ERR)
        {
            (void)Dem_SetEventStatus((Dem_EventIdType)g_pdlDemConfigPtr->pdlDmaUnrecognizedError.id, DEM_EVENT_STATUS_PASSED);
        }
        else
        {
            /* do nothing */
        }
    }
    else
    {
        /* do nothing */
    }

    (void)GlobalErrStatus;
}
#endif  /* {if (STD_OFF == CDD_PDL_DEM_ERR_REP_DISABLE)} */
#endif  /* {if (STD_ON == CDD_PDL_DMA_GET_CH_ERR_STAT_API)} */

#if (STD_ON == CDD_PDL_DEINIT_API)
/*!
* @brief     Set the DMA peripheral registers to their default reset values
*
* @param     ChId: The DMA channel id to be reset,this parameter can be one of the following values:
*                  DMA_HW_CH1
*                  DMA_HW_CH2
*                  DMA_HW_CH3
*                  DMA_HW_CH4
*                  DMA_HW_CH5
* @retval    None
*/
LOCAL_INLINE FUNC(void, PDL_CODE) Pdl_Dma_Reset(VAR(Pdl_DmaChType, AUTOMATIC) ChId)
{
    REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(ChId), DMA_CHCFG_CHEN_MASK);
    REG_WRITE32(DMA_CHCFG_REG_ADDR(ChId), 0);
    REG_WRITE32(DMA_CHNDATA_REG_ADDR(ChId), 0);
    REG_WRITE32(DMA_CHPADDR_REG_ADDR(ChId), 0);
    REG_WRITE32(DMA_CHMADDR_REG_ADDR(ChId), 0);

    if (ChId == DMA_HW_CH1)
    {
        REG_WRITE32(DMA_INTFCLR_REG_ADDR, (uint32_t)0x0000000F);
    }
    else if (ChId == DMA_HW_CH2)
    {
        REG_WRITE32(DMA_INTFCLR_REG_ADDR, (uint32_t)0x000000F0);
    }
    else if (ChId == DMA_HW_CH3)
    {
        REG_WRITE32(DMA_INTFCLR_REG_ADDR, (uint32_t)0x00000F00);
    }
    else if (ChId == DMA_HW_CH4)
    {
        REG_WRITE32(DMA_INTFCLR_REG_ADDR, (uint32_t)0x0000F000);
    }
    else if (ChId == DMA_HW_CH5)
    {
        REG_WRITE32(DMA_INTFCLR_REG_ADDR, (uint32_t)0x000F0000);
    }
    else
    {
        /* nothing */
    }
}
#endif  /* {if (STD_ON == CDD_PDL_DEINIT_API)} */
/**********************************************************************************************************************
                                                    GLOBAL FUNCTION
***********************************************************************************************************************/
/*!
* @brief       Config the DMA peripheral channel according to the specified parameters in the dmaConfig
*
* @param     ChId: The DMA channel id to be reset,this parameter can be one of the following values:
*                  DMA_HW_CH1
*                  DMA_HW_CH2
*                  DMA_HW_CH3
*                  DMA_HW_CH4
*                  DMA_HW_CH5
*
* @param       DmaChConfigPtr:  Pointer to a Pdl_DmaChConfigType structure that
*                          contains the configuration information for the DMA channel.
*
* @retval      None
*/
FUNC(void, PDL_CODE) Pdl_Dma_ChConfig(VAR(Pdl_DmaChType, AUTOMATIC) ChId, 
    P2CONST(Pdl_DmaChHwConfigType, AUTOMATIC, PDL_APPL_DATA) DmaChHwConfigPtr)
{
    /* First reset the CHCFG register */
    REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(ChId), DMA_CHCFG_CHEN_MASK);
    REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(ChId), DMA_CHCFG_DIRCFG_MASK | DMA_CHCFG_CIRMODE_MASK | DMA_CHCFG_PERIMODE_MASK |
    DMA_CHCFG_MIMODE_MASK | DMA_CHCFG_PERSIZE_MASK | DMA_CHCFG_MSIZE_MASK | DMA_CHCFG_CHPL_MASK | DMA_CHCFG_M2MMODE_MASK);

    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)(DmaChHwConfigPtr->dir) << DMA_CHCFG_DIRCFG_SHIFT);
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)(DmaChHwConfigPtr->circularMode) << DMA_CHCFG_CIRMODE_SHIFT);
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)(DmaChHwConfigPtr->mem2Mem) << DMA_CHCFG_M2MMODE_SHIFT);
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)(DmaChHwConfigPtr->priority) << DMA_CHCFG_CHPL_SHIFT);
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)(DmaChHwConfigPtr->memInc) << DMA_CHCFG_MIMODE_SHIFT);
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)(DmaChHwConfigPtr->periphInc) << DMA_CHCFG_PERIMODE_SHIFT);
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)(DmaChHwConfigPtr->periphDataWidth) << DMA_CHCFG_MSIZE_SHIFT);
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)(DmaChHwConfigPtr->memDataWidth) << DMA_CHCFG_PERSIZE_SHIFT);

    REG_WRITE32(DMA_CHNDATA_REG_ADDR(ChId), DmaChHwConfigPtr->bufSize);
    REG_WRITE32(DMA_CHMADDR_REG_ADDR(ChId), DmaChHwConfigPtr->memAddr);
    REG_WRITE32(DMA_CHPADDR_REG_ADDR(ChId), DmaChHwConfigPtr->periphAddr);
}

/*!
* @brief       Enable the DMA peripheral
*
* @param       ChId: The DMA channel id to be reset,this parameter can be one of the following values:
*                  DMA_HW_CH1
*                  DMA_HW_CH2
*                  DMA_HW_CH3
*                  DMA_HW_CH4
*                  DMA_HW_CH5
*
* @retval      None
*/
FUNC(void, PDL_CODE) Pdl_Dma_Enable(VAR(Pdl_DmaChType, AUTOMATIC) ChId)
{
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR(ChId), (uint32)PDL_BIT_SET << DMA_CHCFG_CHEN_SHIFT);
}

/*!
* @brief       Disable the DMA peripheral
*
* @param       ChId: The DMA channel id to be reset,this parameter can be one of the following values:
*                  DMA_HW_CH1
*                  DMA_HW_CH2
*                  DMA_HW_CH3
*                  DMA_HW_CH4
*                  DMA_HW_CH5
*
* @retval      None
*/
FUNC(void, PDL_CODE) Pdl_Dma_Disable(VAR(Pdl_DmaChType, AUTOMATIC) ChId)
{
    REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(ChId), DMA_CHCFG_CHEN_MASK << DMA_CHCFG_CHEN_SHIFT);
}

/*!
* @brief       Set the DMA Channelx transfer data of number
*
* @param       DmaCh: The DMA channel id to be reset(1-5)
*
* @param       DataNum:  The number of data units in the current DMA Channel transfer
*
* @retval      None
*/
FUNC(void, PDL_CODE) Pdl_Dma_SetDataNumber(VAR(Pdl_DmaChType, AUTOMATIC) DmaCh, VAR(uint32, AUTOMATIC) DataNum)
{
    REG_WRITE32(DMA_CHNDATA_REG_ADDR(DmaCh), DataNum);
}

/*!
* @brief       Read the DMA Channelx transfer data of number
*
* @param       DmaCh: The DMA channel id to be reset(1-5)
*
* @retval      The number of data units in the current DMA Channel transfer
*/
FUNC(uint32, PDL_CODE) Pdl_Dma_ReadDataNumber(VAR(Pdl_DmaChType, AUTOMATIC) DmaCh)
{
    return (REG_READ32(DMA_CHNDATA_REG_ADDR(DmaCh)));
}

/*!
* @brief       Checks whether the specified DMA flag is set or not
*
* @param       Flag:   Specifies the flag to check
*                      This parameter can be one of the following values:
*                       DMA1_FLAG_AL1:   DMA1 Channel 1 All flag
*                       DMA1_FLAG_TF1:   DMA1 Channel 1 Transfer Complete flag
*                       DMA1_FLAG_HT1:   DMA1 Channel 1 Half Transfer Complete flag
*                       DMA1_FLAG_TE1:   DMA1 Channel 1 Transfer Error flag
*                       DMA1_FLAG_AL2:   DMA1 Channel 2 All flag
*                       DMA1_FLAG_TF2:   DMA1 Channel 2 Transfer Complete flag
*                       DMA1_FLAG_HT2:   DMA1 Channel 2 Half Transfer Complete flag
*                       DMA1_FLAG_TE2:   DMA1 Channel 2 Transfer Error flag
*                       DMA1_FLAG_AL3:   DMA1 Channel 3 All flag
*                       DMA1_FLAG_TF3:   DMA1 Channel 3 Transfer Complete flag
*                       DMA1_FLAG_HT3:   DMA1 Channel 3 Half Transfer Complete flag
*                       DMA1_FLAG_TE3:   DMA1 Channel 3 Transfer Error flag
*                       DMA1_FLAG_AL4:   DMA1 Channel 4 All flag
*                       DMA1_FLAG_TF4:   DMA1 Channel 4 Transfer Complete flag
*                       DMA1_FLAG_HT4:   DMA1 Channel 4 Half Transfer Complete flag
*                       DMA1_FLAG_TE4:   DMA1 Channel 4 Transfer Error flag
*                       DMA1_FLAG_AL5:   DMA1 Channel 5 All flag
*                       DMA1_FLAG_TF5:   DMA1 Channel 5 Transfer Complete flag
*                       DMA1_FLAG_HT5:   DMA1 Channel 5 Half Transfer Complete flag
*                       DMA1_FLAG_TE5:   DMA1 Channel 5 Transfer Error flag
*
* @retval      The new state of flag (SET or RESET)
*/
FUNC(uint8, PDL_CODE) Pdl_Dma_ReadStatusFlag(VAR(Pdl_DmaChFlagType, AUTOMATIC) Flag)
{
    uint32 status = 0;
    uint8 tempRet = RESET;

    status = REG_READ32(DMA_INTSTS_REG_ADDR) & ((uint32)Flag & (uint32)0x0FFFFFFF);

    if (status == (uint32)Flag)
    {
        tempRet = SET;
    }
    else
    {
        /* nothing */
    }

    return tempRet;
}

/*!
* @brief       Clears the specified interrupt pending bits
*
* @param       Flag:   Specifies the DMA interrupt pending bit to clear
*                      The parameter can be combination of following values:
*                      DMA1_INT_FLAG_AL1:   DMA1_Channel 1 All interrupt flag
*                      DMA1_INT_FLAG_TF1:   DMA1_Channel 1 Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_HT1:   DMA1_Channel 1 Half Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_TE1:   DMA1_Channel 1 Transfer Error interrupt flag
*                      DMA1_INT_FLAG_AL2:   DMA1_Channel 2 All interrupt flag
*                      DMA1_INT_FLAG_TF2:   DMA1_Channel 2 Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_HT2:   DMA1_Channel 2 Half Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_TE2:   DMA1_Channel 2 Transfer Error interrupt flag
*                      DMA1_INT_FLAG_AL3:   DMA1_Channel 3 All interrupt flag
*                      DMA1_INT_FLAG_TF3:   DMA1_Channel 3 Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_HT3:   DMA1_Channel 3 Half Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_TE3:   DMA1_Channel 3 Transfer Error interrupt flag
*                      DMA1_INT_FLAG_AL4:   DMA1_Channel 4 All interrupt flag
*                      DMA1_INT_FLAG_TF4:   DMA1_Channel 4 Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_HT4:   DMA1_Channel 4 Half Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_TE4:   DMA1_Channel 4 Transfer Error interrupt flag
*                      DMA1_INT_FLAG_AL5:   DMA1_Channel 5 All interrupt flag
*                      DMA1_INT_FLAG_TF5:   DMA1_Channel 5 Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_HT5:   DMA1_Channel 5 Half Transfer Complete interrupt flag
*                      DMA1_INT_FLAG_TE5:   DMA1_Channel 5 Transfer Error interrupt flag
*
* @retval      None
*/
FUNC(void, PDL_CODE) Pdl_Dma_ClrStsFlag(VAR(uint32, AUTOMATIC) Flag)
{
    REG_BIT_SET32(DMA_INTFCLR_REG_ADDR, ((uint32)Flag & (uint32)0x0FFFFFFF));
}

/*!
* @brief         The function read the inttruppt enable status of a channel.
*
* @param         DmaCh: The DMA channel id to be reset(1-5)
* @param         IntType: The type of the interrupt
* 
* @retval        The interrupt enable status of the channel
*/ 
FUNC(uint8, PDL_CODE) Pdl_Dma_ReadInitEn(VAR(Pdl_DmaChType, AUTOMATIC) DmaCh, Pdl_DmaIntType IntType)
{
    return ((uint8)(REG_READ32(DMA_CHCFG_REG_ADDR(DmaCh)) & (uint32)IntType));
}

/*!
* @brief         The function error status of a channel.
*
* @param         DmaCh: The DMA channel id to be reset(1-5)
* 
* @retval        The error status of the channel
*/ 
#if (STD_ON == CDD_PDL_DMA_GET_CH_ERR_STAT_API)
FUNC(Pdl_DmaChErrStsType, PDL_CODE) Pdl_Dma_ChErrStsGet(VAR(Pdl_DmaChType, AUTOMATIC) DmaCh)
{
    VAR(uint32,AUTOMATIC) globalErrStatus = (uint32)DMA_CH_NO_ERR;
    VAR(Pdl_DmaChErrStsType,AUTOMATIC) errStatus =  DMA_CH_NO_ERR;

    globalErrStatus = REG_READ32(DMA_INTSTS_REG_ADDR);

    if((uint32)FALSE != (uint32)(globalErrStatus & (uint32)DMA_CH_TERRFLG_MASK(DmaCh)))
    {
        errStatus = DMA_UNRECOG_ERR;
    }
    else
    {
         errStatus = DMA_CH_NO_ERR;
    }

#if (STD_OFF == CDD_PDL_DEM_ERR_REP_DISABLE)
    Pdl_Dma_RepDemErr(globalErrStatus, errStatus);
#endif  /* {if (STD_OFF == CDD_PDL_DEM_ERR_REP_DISABLE)} */
    
    return errStatus;
}
#endif

/*!
* @brief         The function verify the Dma transfer is completed.
*
* @param         DmaCh: The DMA channel id to be reset(1-5)
* 
* @retval        true             The Dma transfer is completed
*                false            The Dma transfer is running
*/ 
FUNC(boolean, PDL_CODE) Pdl_Dma_TransDoneCheck(VAR(Pdl_ChType, AUTOMATIC) DmaCh)
{
    VAR(boolean, AUTOMATIC) completeStatus = (boolean)FALSE;

    /* Verify the TCFLG bit region in the DMA_INTSTS register */
    if((uint32)FALSE != ((uint32)REG_READ32(DMA_INTSTS_REG_ADDR) & (uint32)DMA_CH_TCFLG_MASK(DmaCh)))
    {
        /* The Dma transfer is completed */
        completeStatus = (boolean)TRUE;
    }
    else
    {
        /* The transfer is not completed  */
        completeStatus = (boolean)FALSE;
    }
   
    return completeStatus;
}

/*!
* @brief         The function error status of a channel.
*
* @param[in]      DmaCh: The DMA channel id to be reset(1-5)
* 
* @param[in]      ChPrio: The DMA channel priority to be set.
*
* @retval         None
*/ 
FUNC(void, PDL_CODE) Pdl_Dma_ChPrioSet(VAR(Pdl_DmaChType, AUTOMATIC) DmaCh, VAR(Pdl_DmaPrioType, AUTOMATIC) ChPrio)
{
    SchM_Enter_Pdl_PDL_CRITICAL_SECTION14();

    REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR((uint32)DmaCh), (uint32)DMA_CHCFG_CHPL_MASK);
    REG_BIT_SET32(DMA_CHCFG_REG_ADDR((uint32)DmaCh), (uint32)ChPrio << (uint32)DMA_CHCFG_CHPL_SHIFT);

    SchM_Exit_Pdl_PDL_CRITICAL_SECTION14();
}

#if ((STD_ON == CDD_PDL_DMA_NOTIFICATION_ENABLE)  || (STD_ON == CDD_PDL_DMA_ERR_NOTIFICATION_SUPPORT))
/*!
* @brief         The function enables the user notifications.
*
* @param[in]     DmaCh: The DMA channel id to be reset(1-5)
* 
* @param[in]     NotifiType:   The type of the notification
*
* @retval        void
*/ 
FUNC(void, PDL_CODE) Pdl_Dma_NotifEn(VAR(Pdl_ChType, AUTOMATIC) DmaCh, VAR(Pdl_DmaTranNotifType, AUTOMATIC) NotifiType)
{
     /* Clear the Dma interrupt request of all channels */
    REG_WRITE32(DMA_INTFCLR_REG_ADDR, 0xFFFFFFFFU);

    SchM_Enter_Pdl_PDL_CRITICAL_SECTION29();

    switch ((uint32)NotifiType)
    {
        case (uint32)PDL_DMA_TRAN_COMPLETED:
            REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_TCINTEN_MASK);
            REG_BIT_SET32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_TCINTEN_MASK);
            break;

        case (uint32)PDL_DMA_TRAN_HALF_COMPLETED:
            REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_HTINTEN_MASK);
            REG_BIT_SET32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_HTINTEN_MASK);
            break;

        case (uint32)PDL_DMA_TRAN_ERROR:
            REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_TERRINTEN_MASK);
            REG_BIT_SET32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_TERRINTEN_MASK);
            break;

        default:
            {
                /* do nothing */
            }
            break;
    }

    SchM_Exit_Pdl_PDL_CRITICAL_SECTION29();
}

/*!
* @brief         The function disables the user notifications.
*
* @param[in]     DmaCh: The DMA channel id to be reset(1-5)
* 
* @param[in]     NotifiType:   The type of the notification
*
* @retval        void
*/ 
FUNC(void, PDL_CODE) Pdl_Dma_NotifDis(VAR(Pdl_ChType, AUTOMATIC) DmaCh, VAR(Pdl_DmaTranNotifType, AUTOMATIC) NotifiType)
{
    /* Clear the Dma interrupt request of all channels */
    REG_WRITE32(DMA_INTFCLR_REG_ADDR, 0xFFFFFFFFU);

    SchM_Enter_Pdl_PDL_CRITICAL_SECTION28();

    switch ((uint32)NotifiType)
    {
        case (uint32)PDL_DMA_TRAN_COMPLETED:
            REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_TCINTEN_MASK);
            break;

        case (uint32)PDL_DMA_TRAN_HALF_COMPLETED:
            REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_HTINTEN_MASK);
            break;

        case (uint32)PDL_DMA_TRAN_ERROR:
            REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR(DmaCh), DMA_CHCFG_TERRINTEN_MASK);
            break;

        default:
            {
                /* do nothing */
            }
            break;
    }

    SchM_Exit_Pdl_PDL_CRITICAL_SECTION28();
}

/*!
* @brief         The function acknowledges the interrupt for the channel.
*
* @param[in]     DmaCh       The id of the Dma channel
*
* @retval        void
*/ 
FUNC(void, PDL_CODE) Pdl_Dma_IntAcknow(VAR(Pdl_ChType,AUTOMATIC) DmaCh)
{    
    REG_BIT_SET32(DMA_INTFCLR_REG_ADDR, DMA_CH_TCCLR_MASK(DmaCh));
    REG_BIT_SET32(DMA_INTFCLR_REG_ADDR, DMA_CH_HTCLR_MASK(DmaCh));
    REG_BIT_SET32(DMA_INTFCLR_REG_ADDR, DMA_CH_TERRCLR_MASK(DmaCh));
}

#endif

/*!
* @brief         The function initializes the DMA driver.
*
* @param[in]     HwIPConfigPtr                 The pointer of Dma configuration parameters
*
* @retval        None
*/ 
FUNC(void, PDL_CODE) Pdl_Dma_Init(P2CONST(Pdl_DmaConfigType, AUTOMATIC, PDL_APPL_CONST) DmaConfigPtr)
{
    VAR(uint8, AUTOMATIC)  cnter = 0;
    P2CONST(Pdl_DmaConfigType, AUTOMATIC, PDL_APPL_CONST) dmaConfigPtr = NULL_PTR;
    P2CONST(Pdl_DmaChConfigType, AUTOMATIC, PDL_APPL_CONST) dmaChConfigPtr = NULL_PTR;

    dmaConfigPtr = DmaConfigPtr;

    cnter = 0U;

     SchM_Enter_Pdl_PDL_CRITICAL_SECTION12();

    /* Initialize channels intrrupts */
    while(cnter < dmaConfigPtr->dmaChCnt)
    {
        dmaChConfigPtr = &((*(dmaConfigPtr->chConfigPtr))[cnter]);

        REG_BIT_CLEAR32(DMA_CHCFG_REG_ADDR((uint32)dmaChConfigPtr->dmaChannel), DMA_CHCFG_HTINTEN_MASK | DMA_CHCFG_TCINTEN_MASK | DMA_CHCFG_TERRINTEN_MASK);
        REG_BIT_SET32(DMA_CHCFG_REG_ADDR((uint32)dmaChConfigPtr->dmaChannel), dmaChConfigPtr->dmaChIntCtrl);

        cnter++;
    }

    SchM_Exit_Pdl_PDL_CRITICAL_SECTION12();
}

/*!
* @brief         The function updates the peripheral address of the channel.
*
* @param[in]     ChannelId          The channel id
* @param[in]     Paddr              The peripheral address of the channel
*
* @retval        void
*/ 
FUNC(void, PDL_CODE) Pdl_Dma_PAddrRefresh(VAR(Pdl_ChType, AUTOMATIC) ChannelId,
    VAR(uint32, AUTOMATIC) Paddr)
{

    SchM_Enter_Pdl_PDL_CRITICAL_SECTION15();

    REG_WRITE32(DMA_CHPADDR_REG_ADDR(ChannelId), Paddr);

    SchM_Exit_Pdl_PDL_CRITICAL_SECTION15();
}

/*!
* @brief         The function updates the memory address of the channel.
*
* @param[in]     ChannelId          The channel id
* @param[in]     Maddr              The memory address of the channel
*
* @retval        void
*/ 
FUNC(void, PDL_CODE) Pdl_Dma_MAddrRefresh(VAR(Pdl_ChType, AUTOMATIC) ChannelId,
    VAR(uint32, AUTOMATIC) Maddr)
{

    SchM_Enter_Pdl_PDL_CRITICAL_SECTION15();

    REG_WRITE32(DMA_CHMADDR_REG_ADDR(ChannelId), Maddr);

    SchM_Exit_Pdl_PDL_CRITICAL_SECTION15();
}

#if (STD_ON == CDD_PDL_DEINIT_API)
/*!
* @brief         The function deinitializes the DMA driver.
*
* @param[in]     DmaConfigPtr                 The pointer of Dma configuration parameters
* @param[in]     DmaInstanceId                The Dma instance id 
*
* @retval        void
*/ 
FUNC(void, PDL_CODE) Pdl_Dma_DeInit(P2CONST(Pdl_DmaConfigType, AUTOMATIC, PDL_APPL_CONST) DmaConfigPtr)
{
    P2CONST(Pdl_DmaChConfigType, AUTOMATIC, PDL_APPL_CONST) dmaChConfigPtr;
    VAR(uint8, AUTOMATIC) curAbsoluteCh = 0U;
    VAR(uint8, AUTOMATIC) logicalCh = 0U;

    SchM_Enter_Pdl_PDL_CRITICAL_SECTION13();

    while(logicalCh < DmaConfigPtr->dmaChCnt)
    {
        dmaChConfigPtr = &((*(DmaConfigPtr->chConfigPtr))[logicalCh]);
        curAbsoluteCh = dmaChConfigPtr->dmaChannel;
        
        Pdl_Dma_Reset((Pdl_DmaChType)curAbsoluteCh);
        
        logicalCh++;
    }

    SchM_Exit_Pdl_PDL_CRITICAL_SECTION13();
}
#endif  /* {if (STD_ON == CDD_PDL_DEINIT_API)} */

#define PDL_STOP_SEC_CODE
#include "Pdl_MemMap.h"

#endif

/**@} end of group PDL_Fuctions */
#ifdef __cplusplus
}
#endif  /* ifdef __cplusplus */
/**@} end of group PDL_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
