Newer
Older
mbed-os / targets / TARGET_Cypress / TARGET_PSOC6 / mtb-pdl-cat1 / drivers / source / cy_pra.c
@Dustin Crossman Dustin Crossman on 4 Jun 2021 145 KB Fix file modes.
/***************************************************************************//**
* \file cy_pra.c
* \version 2.20
*
* \brief The source code file for the PRA driver. The API is not intended to
* be used directly by the user application.
*
********************************************************************************
* \copyright
* Copyright 2020 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include "cy_device.h"

#if defined (CY_IP_M4CPUSS) && defined (CY_IP_MXS40IOSS)

#include "cy_pra.h"
#include "cy_pra_cfg.h"
#include "cy_sysint.h"
#include "cy_ipc_drv.h"
#include "cy_device.h"
#include "cy_syspm.h"
#include "cy_ble_clk.h"
#include "cy_gpio.h"

#if defined (CY_DEVICE_SECURE) || defined (CY_DOXYGEN)

#define CY_PRA_REG_POLICY_WRITE_ALL   (0x00000000UL)
#define CY_PRA_REG_POLICY_WRITE_NONE  (0xFFFFFFFFUL)
#define CY_PRA_MS_NR                  (16U)

#define CY_PRA_GPIO_V2_PRT_REG_NR       (21U)   /* No of registers in GPIO PRT_V2 */
#define CY_PRA_HSIOM_PRT_REG_NR         (2U)    /* No of registers in GPIO PRT_V1 */

#define CY_PRA_CLK_EXT_PIN_INDEX        (0UL)
#define CY_PRA_CLK_ECO_INPIN_INDEX      (1UL)
#define CY_PRA_CLK_ECO_OUTPIN_INDEX     (2UL)
#define CY_PRA_CLK_WCO_INPIN_INDEX      (3UL)
#define CY_PRA_CLK_WCO_OUTPIN_INDEX     (4UL)


/* The table to get a register address based on its index */
cy_stc_pra_reg_policy_t regIndexToAddr[CY_PRA_REG_INDEX_COUNT];

#if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
/* SRAM power mode configurations */
cy_pra_sram_pwr_mode_config_t sramPwrModeConfig[CY_PRA_SRAM_MAX_NR];
#endif

#if (CY_CPU_CORTEX_M4)
    static IPC_STRUCT_Type *ipcPraBase = NULL;

    /* External clock secure pin list */
    cy_stc_pra_extclk_pin_t secExtclkPinList[CY_PRA_EXTCLK_PIN_NR];
#if defined(CY_DEVICE_PSOC6ABLE2)
    cy_stc_pra_extclk_hsiom_t secExtClkAdjHsiomList[CY_PRA_EXTCLK_PIN_NR];
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
#endif /* (CY_CPU_CORTEX_M0P) */


/*******************************************************************************
*        Internal Function Prototypes
*******************************************************************************/
#if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
    static void Cy_PRA_Handler(void);
    static void Cy_PRA_ProcessCmd(cy_stc_pra_msg_t *message);
    static void Cy_PRA_PmHibernate(uint32_t funcProc);
    static void Cy_PRA_PmCm4DpFlagSet(void);
    static cy_en_pra_status_t Cy_PRA_ClkDSBeforeTransition(void);
    static cy_en_pra_status_t Cy_PRA_ClkDSAfterTransition(void);
    static bool Cy_PRA_RegAccessRangeValid(uint16_t index);
    static cy_en_pra_status_t Cy_PRA_ClocksReset(void);
    static cy_en_pra_status_t Cy_PRA_BackupReset(bool iloHibernateON);
    static void Cy_PRA_InitGpioPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *port, uint32_t pinNum);
    static void Cy_PRA_InitHsiomPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *port, uint32_t pinNum);
#if defined(CY_DEVICE_PSOC6ABLE2)
    static void Cy_PRA_InitAdjHsiomPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *base);
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
    static cy_en_pra_status_t Cy_PRA_ValidateSramPowerMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode);
    static cy_en_pra_status_t Cy_PRA_ValidateEntireSramPowerMode(cy_en_syspm_sram_index_t sramNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode);
#endif /* (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN) */


/*******************************************************************************
* Function Name: Cy_PRA_Init
****************************************************************************//**
*
* Initializes the PRA driver:
* - Initializes the register access array with the register addresses (Cortex-M0+)
* - Sets up the IPC communication between CPU cores
* - Checks that the driver versions match on the Cortex-M0+ and Cortex-M4 sides.
*
* Call the function before accessing any protected registers.
* It is called during a device startup from \ref SystemInit().
*
*******************************************************************************/
void Cy_PRA_Init(void)
{

#if (CY_CPU_CORTEX_M0P)
    for (uint32_t i = 0UL; i < CY_PRA_REG_INDEX_COUNT; i++)
    {
        regIndexToAddr[i].writeMask = CY_PRA_REG_POLICY_WRITE_ALL;
    }
    regIndexToAddr[CY_PRA_INDX_SRSS_PWR_LVD_CTL].addr          = &SRSS_PWR_LVD_CTL;
    regIndexToAddr[CY_PRA_INDX_SRSS_SRSS_INTR].addr            = &SRSS_SRSS_INTR;
    regIndexToAddr[CY_PRA_INDX_SRSS_SRSS_INTR_SET].addr        = &SRSS_SRSS_INTR_SET;
    regIndexToAddr[CY_PRA_INDX_SRSS_SRSS_INTR_MASK].addr       = &SRSS_SRSS_INTR_MASK;
    regIndexToAddr[CY_PRA_INDX_SRSS_SRSS_INTR_CFG].addr        = &SRSS_SRSS_INTR_CFG;
    regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_1].addr    = &SRSS_CLK_ROOT_SELECT[1U];
    regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_2].addr    = &SRSS_CLK_ROOT_SELECT[2U];
    regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_3].addr    = &SRSS_CLK_ROOT_SELECT[3U];
    regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_4].addr    = &SRSS_CLK_ROOT_SELECT[4U];
    regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_5].addr    = (CY_SRSS_NUM_HFROOT > 4U) ? &SRSS_CLK_ROOT_SELECT[5U] : NULL;
    regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_6].addr    = (CY_SRSS_NUM_HFROOT > 5U) ? &SRSS_CLK_ROOT_SELECT[6U] : NULL;
    regIndexToAddr[CY_PRA_INDX_FLASHC_FLASH_CMD].addr          = &FLASHC_FLASH_CMD;
    regIndexToAddr[CY_PRA_INDX_SRSS_PWR_HIBERNATE].addr        = &SRSS_PWR_HIBERNATE;
    regIndexToAddr[CY_PRA_INDX_SRSS_PWR_HIBERNATE].writeMask   = (uint32_t) ~ (SRSS_PWR_HIBERNATE_TOKEN_Msk |
                                                                               SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |
                                                                               SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk |
                                                                               SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |
                                                                               SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk);
    regIndexToAddr[CY_PRA_INDX_SRSS_CLK_MFO_CONFIG].addr       = &SRSS_CLK_MFO_CONFIG;
    regIndexToAddr[CY_PRA_INDX_SRSS_CLK_MF_SELECT].addr        = &SRSS_CLK_MF_SELECT;
    regIndexToAddr[CY_PRA_INDX_FLASHC_FM_CTL_BOOKMARK].addr     = &FLASHC_FM_CTL_BOOKMARK;
    regIndexToAddr[CY_PRA_INDX_FLASHC_FM_CTL_BOOKMARK].writeMask= CY_PRA_REG_POLICY_WRITE_NONE;

    /* There are up to 16 bus masters */
    for (uint32_t i = 0UL; i < CY_PRA_MS_NR; i++)
    {
        #if defined(CY_DEVICE_PSOC6ABLE2)
            regIndexToAddr[CY_PRA_INDX_PROT_MPU_MS_CTL + i].addr = &PROT_MPU_MS_CTL(i);
        #else
            regIndexToAddr[CY_PRA_INDX_PROT_MPU_MS_CTL + i].addr = (volatile uint32_t *) 0UL;
        #endif /* (CY_DEVICE_PSOC6ABLE2) */

        regIndexToAddr[CY_PRA_INDX_PROT_MPU_MS_CTL + i].writeMask= CY_PRA_REG_POLICY_WRITE_NONE;
    }

    /* Initialize SRAM power modes */
    for (uint32_t i = 0UL; i < CY_PRA_SRAM_MAX_NR; i++)
    {
        sramPwrModeConfig[i].macroConfigCount = 0UL;
    }

    /* Configures the IPC interrupt handler. */
    Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(CY_IPC_INTR_PRA), CY_PRA_IPC_NONE_INTR, CY_PRA_IPC_CHAN_INTR);
    cy_stc_sysint_t intr = {
        .intrSrc = (IRQn_Type)CY_SYSINT_CM0P_MUX4,
        .cm0pSrc = (cy_en_intr_t)(int32_t) CY_IPC_INTR_NUM_TO_VECT((int32_t) CY_IPC_INTR_PRA),
        .intrPriority = 0UL
    };

    if (CY_SYSINT_SUCCESS != Cy_SysInt_Init(&intr, &Cy_PRA_Handler))
    {
        CY_HALT();
    }

    NVIC_EnableIRQ(intr.intrSrc);
#else
    /* Need to get this address in RAM, because there are use cases
    *  where this address is used but flash is not accessible
    */
    ipcPraBase = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_PRA);

    /* Check the version of the driver on the Cortex-M0+ side to match with this one */
    if (CY_PRA_STATUS_SUCCESS != Cy_PRA_SendCmd(CY_PRA_MSG_TYPE_VERSION_CHECK,
                                    (uint16_t) 0U,
                                    (uint32_t) CY_PRA_DRV_VERSION_MAJOR,
                                    (uint32_t) CY_PRA_DRV_VERSION_MINOR))
    {
        /* The PRA driver may not function as expected if different versions
        *  of the driver are on the Cortex-M0+ and Cortex-M4 sides, so halt device.
        */
        CY_HALT();
    }

    /* Fill the external clock ports */
    if (CY_PRA_STATUS_SUCCESS != Cy_PRA_SendCmd(CY_PRA_MSG_TYPE_EXTCLK_PIN_LIST,
                                    (uint16_t) 0U,
                                    (uint32_t) secExtclkPinList,
                                    (uint32_t) CY_PRA_EXTCLK_PIN_NR))
    {
        /* Initilize the List */
        for (uint32_t index = 0UL; index<CY_PRA_EXTCLK_PIN_NR; index++)
        {
            secExtclkPinList[index].port = NULL;
        }
    }

#if defined(CY_DEVICE_PSOC6ABLE2)
    /* Fill the external clock HSIOM ports */
    if (CY_PRA_STATUS_SUCCESS != Cy_PRA_SendCmd(CY_PRA_MSG_TYPE_EXTCLK_ADJHSIOM_LIST,
                                    (uint16_t) 0U,
                                    (uint32_t) secExtClkAdjHsiomList,
                                    (uint32_t) CY_PRA_EXTCLK_PIN_NR))
    {
        /* Initilize the List */
        for (uint32_t index = 0UL; index<CY_PRA_EXTCLK_PIN_NR; index++)
        {
            secExtClkAdjHsiomList[index].port = NULL;
        }
    }
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */

#endif /* (CY_CPU_CORTEX_M0P) */
}


#if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)

/*******************************************************************************
* Function Name: Cy_PRA_UpdateExtClockRegIndex
****************************************************************************//**
*
* Update Index-to-Addr Array with External clock addresses
*
*******************************************************************************/
void Cy_PRA_UpdateExtClockRegIndex(void)
{
    if (NULL != extClkPolicyPtr)
    {
        if (extClkPolicyPtr->extClkEnable)
        {
            Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_EXTCLK_PRT, extClkPolicyPtr->extClkPort, extClkPolicyPtr->extClkPinNum);
            Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_EXTCLK_PRT, extClkPolicyPtr->extClkPort, extClkPolicyPtr->extClkPinNum);
            #if defined(CY_DEVICE_PSOC6ABLE2)
                Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_EXTCLK_ADJ_PRT, extClkPolicyPtr->extClkPort);
            #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
        }

        if (extClkPolicyPtr->ecoEnable)
        {
            Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_ECO_IN_PRT, extClkPolicyPtr->ecoInPort, extClkPolicyPtr->ecoInPinNum);
            Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_ECO_OUT_PRT, extClkPolicyPtr->ecoOutPort, extClkPolicyPtr->ecoOutPinNum);
            Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_ECO_IN_PRT, extClkPolicyPtr->ecoInPort, extClkPolicyPtr->ecoInPinNum);
            Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_ECO_OUT_PRT, extClkPolicyPtr->ecoOutPort, extClkPolicyPtr->ecoOutPinNum);
            #if defined(CY_DEVICE_PSOC6ABLE2)
                Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_ECO_IN_ADJ_PRT, extClkPolicyPtr->ecoInPort);
                Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_ECO_OUT_ADJ_PRT, extClkPolicyPtr->ecoOutPort);
            #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
        }

        if (extClkPolicyPtr->wcoEnable)
        {
            Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_WCO_IN_PRT, extClkPolicyPtr->wcoInPort, extClkPolicyPtr->wcoInPinNum);
            Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_WCO_OUT_PRT, extClkPolicyPtr->wcoOutPort, extClkPolicyPtr->wcoOutPinNum);
            Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_WCO_IN_PRT, extClkPolicyPtr->wcoInPort, extClkPolicyPtr->wcoInPinNum);
            Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_WCO_OUT_PRT, extClkPolicyPtr->wcoOutPort, extClkPolicyPtr->wcoOutPinNum);
            #if defined(CY_DEVICE_PSOC6ABLE2)
                Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_WCO_IN_ADJ_PRT, extClkPolicyPtr->wcoInPort);
                Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_WCO_OUT_ADJ_PRT, extClkPolicyPtr->wcoOutPort);
            #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
        }
    }
}

/*******************************************************************************
* Function Name: Cy_PRA_InitGpioPort
****************************************************************************//**
*
* Initializes all port register address and write mask
*
*******************************************************************************/
static void Cy_PRA_InitGpioPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *port, uint32_t pinNum)
{
    uint32_t pinLoc;
    volatile uint32_t *portAddr;

    if ((NULL != regPolicy) && (NULL != port) && CY_GPIO_IS_PIN_VALID(pinNum))
    {
        portAddr = (volatile uint32_t *)((void *)(port));
        for (uint32_t i = 0UL; i < CY_PRA_GPIO_V2_PRT_REG_NR; i++)
        {
            regPolicy[index + i].addr = (portAddr + i);
        }

        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT), 4U)].writeMask = (CY_GPIO_OUT_MASK << pinNum); /* OUT */
        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_CLR), 4U)].writeMask = (CY_GPIO_OUT_MASK << pinNum); /* OUT_CLR */
        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_SET), 4U)].writeMask = (CY_GPIO_OUT_MASK << pinNum); /* OUT_SET */
        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_INV), 4U)].writeMask = (CY_GPIO_OUT_MASK << pinNum); /* OUT_INV */
        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, IN), 4U)].writeMask = (CY_GPIO_IN_MASK << pinNum); /* IN */
        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR), 4U)].writeMask = (CY_GPIO_INTR_STATUS_MASK << pinNum); /* INTR */
        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_MASK), 4U)].writeMask = (CY_GPIO_INTR_EN_MASK << pinNum); /* INTR_MASK */
        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_MASKED), 4U)].writeMask = (CY_GPIO_INTR_MASKED_MASK << pinNum); /* INTR_MASKED */
        regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_SET), 4U)].writeMask = (CY_GPIO_INTR_SET_MASK << pinNum); /* INTR_SET */

        pinLoc = pinNum << CY_GPIO_INTR_CFG_OFFSET;
        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtIntrCfgOffset), 4U)].writeMask = (CY_GPIO_INTR_EDGE_MASK << pinLoc); /* INTR_CFG */

        pinLoc = pinNum << CY_GPIO_DRIVE_MODE_OFFSET;
        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgOffset), 4U)].writeMask = (CY_GPIO_CFG_DM_MASK << pinLoc); /* CFG */

        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgInOffset), 4U)].writeMask = (CY_GPIO_CFG_IN_VTRIP_SEL_MASK << pinNum); /* CFG_IN */

        pinLoc = (uint32_t)(pinNum << 1u) + CY_GPIO_CFG_OUT_DRIVE_OFFSET;
        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgOutOffset), 4U)].writeMask = (CY_GPIO_CFG_OUT_DRIVE_SEL_MASK << pinLoc) |
                                                                                                            (CY_GPIO_CFG_OUT_SLOW_MASK << pinNum); /* CFG_OUT */

        pinLoc = (pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET;
        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask = (CY_GPIO_VREG_EN_MASK << pinLoc);
        pinLoc = ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET) + CY_GPIO_IBUF_SHIFT;
        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask |= (CY_GPIO_IBUF_MASK << pinLoc);
        pinLoc = ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET) + CY_GPIO_VTRIP_SEL_SHIFT;
        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask |= (CY_GPIO_VTRIP_SEL_MASK << pinLoc);
        pinLoc = ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET) + CY_GPIO_VREF_SEL_SHIFT;
        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask |= (CY_GPIO_VREF_SEL_MASK << pinLoc);
        pinLoc = ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET) + CY_GPIO_VOH_SEL_SHIFT;
        regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask |= (CY_GPIO_VOH_SEL_MASK << pinLoc);
    }
    else if (NULL != regPolicy)
    {
        /* regIndexToAddr Indexes are filled with NULL addresses. So don't allow to write in these indexes */
        for (uint32_t i = 0UL; i < CY_PRA_GPIO_V2_PRT_REG_NR; i++)
        {
            regPolicy[index + i].addr = NULL;
            regPolicy[index + i].writeMask = CY_PRA_REG_POLICY_WRITE_NONE;
        }
    }
    else
    {
        /* Invalid parameters */
    }
}

/*******************************************************************************
* Function Name: Cy_PRA_InitHsiomPort
****************************************************************************//**
*
* Initializes all HSIOM port register adrress and write mask
*
*******************************************************************************/
static void Cy_PRA_InitHsiomPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *port, uint32_t pinNum)
{
    uint32_t portNum;
    volatile uint32_t *portAddrHSIOM;

    if ((NULL != regPolicy) && (NULL != port) && CY_GPIO_IS_PIN_VALID(pinNum))
    {
        /* calculate hsiom port */
        portNum = ((uint32_t)(port) - CY_GPIO_BASE) / GPIO_PRT_SECTION_SIZE;
        portAddrHSIOM = (volatile uint32_t *)(CY_HSIOM_BASE + (HSIOM_PRT_SECTION_SIZE * portNum));

        for (uint32_t i = 0UL; i < CY_PRA_HSIOM_PRT_REG_NR; i++)
        {
            regPolicy[index + i].addr = (portAddrHSIOM + i);
        }

        if (pinNum < CY_GPIO_PRT_HALF)
        {
            regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL0), 4U)].writeMask = (CY_GPIO_HSIOM_MASK << (pinNum << CY_GPIO_HSIOM_OFFSET));
        }
        else
        {
            pinNum -= CY_GPIO_PRT_HALF;
            regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL1), 4U)].writeMask = (CY_GPIO_HSIOM_MASK << (pinNum << CY_GPIO_HSIOM_OFFSET));
        }
    }
    else if (NULL != regPolicy)
    {
        /* regIndexToAddr Indexes are filled with NULL addresses. So don't allow to write in these indexes */
        for (uint32_t i = 0UL; i < CY_PRA_HSIOM_PRT_REG_NR; i++)
        {
            regPolicy[index + i].addr = NULL;
            regPolicy[index + i].writeMask = CY_PRA_REG_POLICY_WRITE_NONE;
        }
    }
    else
    {
        /* Invalid parameters */
    }
}

#if defined(CY_DEVICE_PSOC6ABLE2)
/*******************************************************************************
* Function Name: Cy_PRA_InitAdjHsiomPort
****************************************************************************//**
*
* Initializes all adjacent HSIOM port register address and write mask
*
*******************************************************************************/
static void Cy_PRA_InitAdjHsiomPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *base)
{
    uint32_t portNum;
    volatile uint32_t *portAddrHSIOM;
    GPIO_PRT_Type *port;

    if ((NULL != regPolicy) && (NULL != base))
    {
        /* calculate next port address */
        port = base + 1UL;

        /* calculate hsiom port */
        portNum = ((uint32_t)(port) - CY_GPIO_BASE) / GPIO_PRT_SECTION_SIZE;
        portAddrHSIOM = (volatile uint32_t *)(CY_HSIOM_BASE + (HSIOM_PRT_SECTION_SIZE * portNum));

        for (uint32_t i = 0UL; i < CY_PRA_HSIOM_PRT_REG_NR; i++)
        {
            regPolicy[index + i].addr = (portAddrHSIOM + i);
            regPolicy[index + i].writeMask = CY_PRA_REG_POLICY_WRITE_ALL;
        }
    }
    else if (NULL != regPolicy)
    {
        /* regIndexToAddr Indexes are filled with NULL addresses. So don't allow to write in these indexes */
        for (uint32_t i = 0UL; i < CY_PRA_HSIOM_PRT_REG_NR; i++)
        {
            regPolicy[index + i].addr = NULL;
            regPolicy[index + i].writeMask = CY_PRA_REG_POLICY_WRITE_NONE;
        }
    }
    else
    {
        /* Invalid parameters */
    }
}
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */

/*******************************************************************************
* Function Name: Cy_PRA_Handler
****************************************************************************//**
*
* The IPC interrupt handler on Cortex-M0+ core is called after there is a
* request from the Cortex-M4 core.
*
*******************************************************************************/
static void Cy_PRA_Handler(void)
{
    cy_stc_pra_msg_t msgLocal;
    cy_stc_pra_msg_t* msgRemote;

    /* Processes an internal command copy and updates the original value */
    msgRemote = (cy_stc_pra_msg_t *)Cy_IPC_Drv_ReadDataValue(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_PRA));

    msgLocal = *msgRemote;
    Cy_PRA_ProcessCmd(&msgLocal);
    *msgRemote = msgLocal;

    /* Clears the interrupt logic to detect a next interrupt */
    Cy_IPC_Drv_ClearInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(CY_IPC_INTR_PRA), CY_PRA_IPC_NONE_INTR, CY_PRA_IPC_CHAN_INTR);

    (void) Cy_IPC_Drv_LockRelease(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_PRA), CY_PRA_IPC_NONE_INTR);
}


/*******************************************************************************
* Function Name: Cy_PRA_ProcessCmd
****************************************************************************//**
*
* Processes and executes the command on Cortex-M0+ which was received from
* the Cortex-M4 application.
*
* \param message cy_stc_pra_msg_t
*
*******************************************************************************/
static void Cy_PRA_ProcessCmd(cy_stc_pra_msg_t *message)
{
    static bool structInit = false;
    static cy_stc_pra_system_config_t structCpy = {0UL};

    CY_ASSERT_L1(NULL != message);


    switch (message->praCommand)
    {
        case CY_PRA_MSG_TYPE_REG32_CLR_SET:
            /* Reports an error if any of the following conditions is false:
            *  - A new value (message->praData2) has zeros in the write-protected fields
            *  - The register index is within the valid range.
            */
            if ((0U == (message->praData2 & regIndexToAddr[message->praIndex].writeMask)) &&
                (CY_PRA_REG_POLICY_WRITE_NONE != regIndexToAddr[message->praIndex].writeMask) &&
                (Cy_PRA_RegAccessRangeValid(message->praIndex)))
            {
                uint32_t tmp;

                tmp =  CY_GET_REG32(regIndexToAddr[message->praIndex].addr);

                tmp &= (message->praData1 | regIndexToAddr[message->praIndex].writeMask);
                tmp |= message->praData2;
                CY_SET_REG32(regIndexToAddr[message->praIndex].addr, tmp);
                message->praStatus = CY_PRA_STATUS_SUCCESS;
            }
            else
            {
                message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
            }
            break;

        case CY_PRA_MSG_TYPE_REG32_SET:
            /* Reports an error if any of the following conditions is false:
            *  - A new value (message->praData1) has zeros or same value in the write-protected fields
            *  - The register index is within the valid range.
            */
            if ((CY_PRA_REG_POLICY_WRITE_NONE != regIndexToAddr[message->praIndex].writeMask) &&
                (Cy_PRA_RegAccessRangeValid(message->praIndex)))
            {
                uint32_t tmp;

                tmp =  CY_GET_REG32(regIndexToAddr[message->praIndex].addr);

                if ((0U == (message->praData1 & regIndexToAddr[message->praIndex].writeMask)) ||
                    ((tmp & regIndexToAddr[message->praIndex].writeMask) ==
                    (message->praData1 & regIndexToAddr[message->praIndex].writeMask)))
                {
                    /* Clears the bits allowed to write */
                    tmp &= regIndexToAddr[message->praIndex].writeMask;

                    /* Sets the allowed bits based on the new value.
                    *  The write-protected fields have zeros in the new value, so no additional checks needed
                    */
                    tmp |= message->praData1;
                    CY_SET_REG32(regIndexToAddr[message->praIndex].addr, tmp);
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                }
                else
                {
                    message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                }
            }
            else
            {
                message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
            }
            break;

        case CY_PRA_MSG_TYPE_REG32_GET:
            if (Cy_PRA_RegAccessRangeValid(message->praIndex))
            {
                message->praData1 = CY_GET_REG32(regIndexToAddr[message->praIndex].addr);
                message->praStatus = CY_PRA_STATUS_SUCCESS;
            }
            else
            {
                message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
            }
            break;

        case CY_PRA_MSG_TYPE_CM0_WAKEUP:
            message->praStatus = CY_PRA_STATUS_SUCCESS;
            break;

        case CY_PRA_MSG_TYPE_VERSION_CHECK:
            /* The PRA driver may not function as expected if different versions
            *  of the driver are on the Cortex-M0+ and Cortex-M4 sides.
            */
            if (((uint32_t) CY_PRA_DRV_VERSION_MAJOR == (message->praData1)) &&
                ((uint32_t) CY_PRA_DRV_VERSION_MINOR == (message->praData2)))
            {
                message->praStatus = CY_PRA_STATUS_SUCCESS;
            }
            else
            {
                message->praStatus = CY_PRA_STATUS_ERROR_PRA_VERSION;
            }
            break;

        case CY_PRA_MSG_TYPE_EXTCLK_PIN_LIST:

            if ((NULL != (cy_stc_pra_extclk_pin_t *) (message->praData1)) && ((uint32_t) (message->praData2) <= CY_PRA_EXTCLK_PIN_NR))
            {
                cy_stc_pra_extclk_pin_t *pinList =  (cy_stc_pra_extclk_pin_t *) message->praData1;
                message->praStatus = CY_PRA_STATUS_SUCCESS;

                if (extClkPolicyPtr->extClkEnable)
                {
                    pinList[CY_PRA_CLK_EXT_PIN_INDEX].port = extClkPolicyPtr->extClkPort;
                    pinList[CY_PRA_CLK_EXT_PIN_INDEX].pinNum = extClkPolicyPtr->extClkPinNum;
                    pinList[CY_PRA_CLK_EXT_PIN_INDEX].index = CY_PRA_INDX_GPIO_EXTCLK_PRT;
                    pinList[CY_PRA_CLK_EXT_PIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_EXTCLK_PRT;
                }
                else
                {
                    pinList[CY_PRA_CLK_EXT_PIN_INDEX].port = NULL;
                }

                if (extClkPolicyPtr->ecoEnable)
                {
                    pinList[CY_PRA_CLK_ECO_INPIN_INDEX].port = extClkPolicyPtr->ecoInPort;
                    pinList[CY_PRA_CLK_ECO_INPIN_INDEX].pinNum = extClkPolicyPtr->ecoInPinNum;
                    pinList[CY_PRA_CLK_ECO_INPIN_INDEX].index = CY_PRA_INDX_GPIO_ECO_IN_PRT;
                    pinList[CY_PRA_CLK_ECO_INPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_ECO_IN_PRT;

                    pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = extClkPolicyPtr->ecoOutPort;
                    pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].pinNum = extClkPolicyPtr->ecoOutPinNum;
                    pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].index = CY_PRA_INDX_GPIO_ECO_OUT_PRT;
                    pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_ECO_OUT_PRT;
                }
                else
                {
                    pinList[CY_PRA_CLK_ECO_INPIN_INDEX].port = NULL;
                    pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = NULL;
                }

                if (extClkPolicyPtr->wcoEnable)
                {
                    pinList[CY_PRA_CLK_WCO_INPIN_INDEX].port = extClkPolicyPtr->wcoInPort;
                    pinList[CY_PRA_CLK_WCO_INPIN_INDEX].pinNum = extClkPolicyPtr->wcoInPinNum;
                    pinList[CY_PRA_CLK_WCO_INPIN_INDEX].index = CY_PRA_INDX_GPIO_WCO_IN_PRT;
                    pinList[CY_PRA_CLK_WCO_INPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_WCO_IN_PRT;

                    pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = extClkPolicyPtr->wcoOutPort;
                    pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].pinNum = extClkPolicyPtr->wcoOutPinNum;
                    pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].index = CY_PRA_INDX_GPIO_WCO_OUT_PRT;
                    pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_WCO_OUT_PRT;
                }
                else
                {
                    pinList[CY_PRA_CLK_WCO_INPIN_INDEX].port = NULL;
                    pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = NULL;
                }
            }
            else
            {
                message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
            }

            break;
#if defined(CY_DEVICE_PSOC6ABLE2)
        case CY_PRA_MSG_TYPE_EXTCLK_ADJHSIOM_LIST:
            if ((NULL != (cy_stc_pra_extclk_hsiom_t *) (message->praData1)) && ((uint32_t) (message->praData2) <= CY_PRA_EXTCLK_PIN_NR))
            {
                cy_stc_pra_extclk_hsiom_t *hsiomList =  (cy_stc_pra_extclk_hsiom_t *) message->praData1;
                if (extClkPolicyPtr->extClkEnable)
                {
                    hsiomList[CY_PRA_CLK_EXT_PIN_INDEX].port = extClkPolicyPtr->extClkPort + 1; /* Fill adjacent GPIO port */
                    hsiomList[CY_PRA_CLK_EXT_PIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_EXTCLK_ADJ_PRT;
                }
                else
                {
                    hsiomList[CY_PRA_CLK_EXT_PIN_INDEX].port = NULL;
                }

                if (extClkPolicyPtr->ecoEnable)
                {
                    hsiomList[CY_PRA_CLK_ECO_INPIN_INDEX].port = extClkPolicyPtr->ecoInPort + 1; /* Fill adjacent GPIO port */
                    hsiomList[CY_PRA_CLK_ECO_INPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_ECO_IN_ADJ_PRT;
                    hsiomList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = extClkPolicyPtr->ecoOutPort + 1; /* Fill adjacent GPIO port */
                    hsiomList[CY_PRA_CLK_ECO_OUTPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_ECO_OUT_ADJ_PRT;
                }
                else
                {
                    hsiomList[CY_PRA_CLK_ECO_INPIN_INDEX].port = NULL;
                    hsiomList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = NULL;
                }

                if (extClkPolicyPtr->wcoEnable)
                {
                    hsiomList[CY_PRA_CLK_WCO_INPIN_INDEX].port = extClkPolicyPtr->wcoInPort + 1; /* Fill adjacent GPIO port */
                    hsiomList[CY_PRA_CLK_WCO_INPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_WCO_IN_ADJ_PRT;
                    hsiomList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = extClkPolicyPtr->wcoOutPort + 1; /* Fill adjacent GPIO port */
                    hsiomList[CY_PRA_CLK_WCO_OUTPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_WCO_OUT_ADJ_PRT;
                }
                else
                {
                    hsiomList[CY_PRA_CLK_WCO_INPIN_INDEX].port = NULL;
                    hsiomList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = NULL;
                }

                message->praStatus = CY_PRA_STATUS_SUCCESS;
            }
            break;
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
        case CY_PRA_MSG_TYPE_SYS_CFG_FUNC:
            CY_ASSERT_L1((cy_stc_pra_system_config_t *)(message->praData1) != NULL);

            if( NULL != (cy_stc_pra_system_config_t *)(message->praData1))
            {
                cy_en_sysclk_status_t sysClkStatus = CY_SYSCLK_SUCCESS;
                message->praStatus = CY_PRA_STATUS_SUCCESS;

                structCpy = *((cy_stc_pra_system_config_t *)(message->praData1));

                /* Resets clocks configuration to the default state during system reset - DRIVERS-495 */
                if (0u != Cy_SysLib_GetResetReason())
                {
                    message->praStatus = Cy_PRA_ClocksReset();
                }
                /* Resets clocks configuration and backup domain to default
                 * state during hardware reset (POR, XRES, BOD)
                 */
                else if (!structInit)
                {
                    /* Resets the Backup domain on POR, XRES, BOD only if Backup domain is supplied by VDDD */
                    if ((structCpy.vBackupVDDDEnable) && (structCpy.iloEnable))
                    {
                        message->praStatus = Cy_PRA_BackupReset(structCpy.iloHibernateON);
                    }
                    message->praStatus = Cy_PRA_ClocksReset();
                }
                else
                {
                    /* Skip clock clocks configuration resetting */
                }

                CY_MISRA_FP_LINE('MISRA C-2012 Rule 14.3','Checked manually, condition evaluates true.');
                if (CY_SYSCLK_SUCCESS == sysClkStatus)
                {
                    message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                }

                if((!structInit) && (CY_PRA_STATUS_SUCCESS == message->praStatus))
                {
                    structInit = true;
                }
            }
            else
            {
                message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
            }
            break;

        case CY_PRA_MSG_TYPE_SECURE_ONLY:
            switch (message->praIndex)
            {
                case CY_PRA_PM_FUNC_HIBERNATE:
                    Cy_PRA_PmHibernate(message->praData1);
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;

                case CY_PRA_PM_FUNC_CM4_DP_FLAG_SET:
                    Cy_PRA_PmCm4DpFlagSet();
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;

                case CY_PRA_CLK_FUNC_DS_BEFORE_TRANSITION:
                    message->praStatus = Cy_PRA_ClkDSBeforeTransition();
                    break;

                case CY_PRA_CLK_FUNC_DS_AFTER_TRANSITION:
                    message->praStatus = Cy_PRA_ClkDSAfterTransition();
                    break;

                case CY_PRA_PM_FUNC_BUCK_ENABLE_VOLTAGE2:
                    Cy_SysPm_BuckEnableVoltage2();
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;

                case CY_PRA_PM_FUNC_BUCK_DISABLE_VOLTAGE2:
                    Cy_SysPm_BuckDisableVoltage2();
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;

                case CY_PRA_PM_FUNC_BUCK_VOLTAGE2_HW_CTRL:
                    Cy_SysPm_BuckSetVoltage2HwControl((bool) message->praData1);
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;

                case CY_PRA_PM_FUNC_BUCK_SET_VOLTAGE2:
                    if (CY_SYSPM_IS_BUCK_VOLTAGE2_VALID(((cy_stc_pra_voltage2_t *) message->praData1)->praVoltage))
                    {
                        Cy_SysPm_BuckSetVoltage2(((cy_stc_pra_voltage2_t *) message->praData1)->praVoltage,
                                                 ((cy_stc_pra_voltage2_t *) message->praData1)->praWaitToSettle);
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                    }
                    else
                    {
                        message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
                    }
                    break;

                case CY_PRA_PM_FUNC_SRAM_MACRO_PWR_MODE:
                {
                    cy_en_syspm_sram_index_t sramNum;
                    uint32_t sramMacroNum;
                    cy_en_syspm_sram_pwr_mode_t sramPwrMode;

                    sramNum = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramNum;
                    sramMacroNum = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramMacroNum;
                    sramPwrMode = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramPwrMode;

                    message->praStatus = Cy_PRA_ValidateSramPowerMode(sramNum, sramMacroNum, sramPwrMode);

                    if (message->praStatus == CY_PRA_STATUS_SUCCESS)
                    {
                        if (CY_SYSPM_SUCCESS != Cy_SysPm_SetSRAMMacroPwrMode(sramNum, sramMacroNum, sramPwrMode))
                        {
                            message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
                        }
                    }
                    else
                    {
                        /* Not allowed to modify sram power mode */
                    }
                }
                    break;

                case CY_PRA_PM_FUNC_SRAM_PWR_MODE:
                {
                    cy_en_syspm_sram_index_t sramNum;
                    cy_en_syspm_sram_pwr_mode_t sramPwrMode;

                    sramNum = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramNum;
                    sramPwrMode = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramPwrMode;

                    message->praStatus = Cy_PRA_ValidateEntireSramPowerMode(sramNum, sramPwrMode);

                    if (message->praStatus == CY_PRA_STATUS_SUCCESS)
                    {
                        if (CY_SYSPM_SUCCESS != Cy_SysPm_SetSRAMPwrMode(sramNum, sramPwrMode))
                        {
                            message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
                        }
                    }
                    else
                    {
                        /* Not allowed to modify sram power mode */
                    }
                }
                    break;

            #ifdef CY_IP_MXBLESS
                case CY_PRA_CLK_FUNC_PILO_INITIAL_TRIM:
                    Cy_SysClk_PiloInitialTrim();
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;

                case CY_PRA_CLK_FUNC_UPDATE_PILO_TRIM_STEP:
                    Cy_SysClk_PiloUpdateTrimStep();
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;
            #endif /* CY_IP_MXBLESS */

                case CY_PRA_CLK_FUNC_START_MEASUREMENT:
                {
                    cy_en_meas_clks_t clockVal1, clockVal2;
                    uint32_t countVal1;
                    clockVal1 = ((cy_stc_pra_start_clk_measurement_t *) message->praData1)->clock1;
                    clockVal2 = ((cy_stc_pra_start_clk_measurement_t *) message->praData1)->clock2;
                    countVal1 = ((cy_stc_pra_start_clk_measurement_t *) message->praData1)->count1;
                    message->praStatus = (cy_en_pra_status_t)Cy_SysClk_StartClkMeasurementCounters(clockVal1, countVal1, clockVal2);
                }
                    break;

                case CY_PRA_CLK_FUNC_ILO_TRIM:
                    message->praStatus = (cy_en_pra_status_t)Cy_SysClk_IloTrim(message->praData1);
                    break;

                case CY_PRA_CLK_FUNC_SET_PILO_TRIM:
                    Cy_SysClk_PiloSetTrim(message->praData1);
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;

            #if defined(CY_IP_MXBLESS)
                case CY_PRA_BLE_CLK_FUNC_ECO_CONFIGURE:
                    structCpy.altHFcLoad = ((cy_stc_pra_ble_eco_config_t *) message->praData1)->cLoad;
                    structCpy.altHFxtalStartUpTime = ((cy_stc_pra_ble_eco_config_t *) message->praData1)->xtalStartUpTime;
                    structCpy.altHFclkFreq = (uint32_t)((cy_stc_pra_ble_eco_config_t *) message->praData1)->freq;
                    structCpy.altHFsysClkDiv = (uint32_t)((cy_stc_pra_ble_eco_config_t *) message->praData1)->sysClkDiv;
                    structCpy.altHFvoltageReg = (uint32_t)((cy_stc_pra_ble_eco_config_t *) message->praData1)->voltageReg;
                    structCpy.clkAltHfEnable = true;

                    message->praStatus = (cy_en_pra_status_t)Cy_BLE_EcoConfigure(
                                                                (cy_en_ble_eco_freq_t)structCpy.altHFclkFreq,
                                                                (cy_en_ble_eco_sys_clk_div_t)structCpy.altHFsysClkDiv,
                                                                structCpy.altHFcLoad,
                                                                structCpy.altHFxtalStartUpTime,
                                                                (cy_en_ble_eco_voltage_reg_t)structCpy.altHFvoltageReg);
                    break;

                case CY_PRA_BLE_CLK_FUNC_ECO_RESET:
                    Cy_BLE_EcoReset();
                    message->praStatus = CY_PRA_STATUS_SUCCESS;
                    break;
            #endif /* CY_IP_MXBLESS */

                default:
                    message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                    break;
            }
            break;

        case CY_PRA_MSG_TYPE_FUNC_POLICY:
            if(structInit)
            {
                switch (message->praIndex)
                {
                    case CY_PRA_PM_FUNC_LDO_SET_VOLTAGE:
                    {
                        bool powerEnableTmp, ldoEnableTmp, ulpEnableTmp;
                        powerEnableTmp = structCpy.powerEnable; /* old value backup */
                        ldoEnableTmp = structCpy.ldoEnable; /* old value backup */
                        ulpEnableTmp = structCpy.ulpEnable; /* old value backup */
                        structCpy.powerEnable = true;
                        structCpy.ldoEnable = true;
                        structCpy.ldoVoltage = (cy_en_syspm_ldo_voltage_t)message->praData1;
                        if (structCpy.ldoVoltage == CY_SYSPM_LDO_VOLTAGE_0_9V)
                        {
                            structCpy.ulpEnable = true;
                        }
                        else
                        {
                            structCpy.ulpEnable = false;
                        }
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.powerEnable = powerEnableTmp;
                            structCpy.ldoEnable = ldoEnableTmp;
                            structCpy.ulpEnable = ulpEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_PM_FUNC_BUCK_ENABLE:
                    {
                        bool powerEnableTmp, ldoEnableTmp, ulpEnableTmp;
                        powerEnableTmp = structCpy.powerEnable; /* Old value backup */
                        ldoEnableTmp = structCpy.ldoEnable; /* Old value backup */
                        ulpEnableTmp = structCpy.ulpEnable; /* Old value backup */
                        structCpy.powerEnable = true;
                        structCpy.ldoEnable = false;
                        structCpy.buckVoltage = (cy_en_syspm_buck_voltage1_t)message->praData1;
                        if (structCpy.buckVoltage == CY_SYSPM_BUCK_OUT1_VOLTAGE_0_9V)
                        {
                            structCpy.ulpEnable = true;
                        }
                        else
                        {
                            structCpy.ulpEnable = false;
                        }
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.powerEnable = powerEnableTmp;
                            structCpy.ldoEnable = ldoEnableTmp;
                            structCpy.ulpEnable = ulpEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_PM_FUNC_SET_MIN_CURRENT:
                    {
                        bool powerEnableTmp, pwrCurrentModeMinTmp;
                        /* Backups old values */
                        powerEnableTmp = structCpy.powerEnable;
                        pwrCurrentModeMinTmp = structCpy.pwrCurrentModeMin;
                        structCpy.powerEnable = true;
                        structCpy.pwrCurrentModeMin = true;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.powerEnable = powerEnableTmp;
                            structCpy.pwrCurrentModeMin = pwrCurrentModeMinTmp;
                        }
                    }
                    break;

                    case CY_PRA_PM_FUNC_SET_NORMAL_CURRENT:
                    {
                        bool powerEnableTmp, pwrCurrentModeMinTmp;
                        /* Backups old values */
                        powerEnableTmp = structCpy.powerEnable;
                        pwrCurrentModeMinTmp = structCpy.pwrCurrentModeMin;
                        structCpy.powerEnable = true;
                        structCpy.pwrCurrentModeMin = false;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.powerEnable = powerEnableTmp;
                            structCpy.pwrCurrentModeMin = pwrCurrentModeMinTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_ECO_DISABLE:
                    {
                        bool ecoEnableTmp;
                        /* Backups old values */
                        ecoEnableTmp = structCpy.ecoEnable;
                        structCpy.ecoEnable = false;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.ecoEnable = ecoEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_FLL_DISABLE:
                    {
                        bool fllEnableTmp;
                        uint32_t fllOutFreqHzTmp;
                        /* Backups old values */
                        fllOutFreqHzTmp = structCpy.fllOutFreqHz;
                        fllEnableTmp = structCpy.fllEnable;
                        structCpy.fllEnable = false;
                        structCpy.fllOutFreqHz = CY_PRA_DEFAULT_ZERO;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.fllEnable = fllEnableTmp;
                            structCpy.fllOutFreqHz = fllOutFreqHzTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PLL_DISABLE:
                    {
                        bool pllEnable;
                        if (((message->praData1) > CY_PRA_CLKPATH_0) && ((message->praData1) <= CY_SRSS_NUM_PLL)) /* 0 is invalid pll number */
                        {
                            /* Backups old values */
                            ((message->praData1) == CY_PRA_CLKPLL_1) ? (pllEnable = structCpy.pll0Enable) : (pllEnable = structCpy.pll1Enable);

                            ((message->praData1) == CY_PRA_CLKPLL_1) ? (structCpy.pll0Enable = false) : (structCpy.pll1Enable = false);

                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);

                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored */
                                ((message->praData1) == CY_PRA_CLKPLL_1) ? (structCpy.pll0Enable = pllEnable) : (structCpy.pll1Enable = pllEnable);
                            }
                        }
                        else
                        {
                            message->praStatus = CY_PRA_STATUS_INVALID_PARAM_PLL_NUM;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_ILO_ENABLE:
                    {
                        bool iloEnableTmp;
                        /* Backups old values */
                        iloEnableTmp = structCpy.iloEnable;
                        structCpy.iloEnable = true;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored  */
                            structCpy.iloEnable = iloEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_ILO_DISABLE:
                    {
                        bool iloEnableTmp;
                        /* Backups old values */
                        iloEnableTmp = structCpy.iloEnable;
                        structCpy.iloEnable = false;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.iloEnable = iloEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_ILO_HIBERNATE_ON:
                    {
                        bool iloHibernateOnTmp;
                        /* Backups old values */
                        iloHibernateOnTmp = structCpy.iloHibernateON;
                        structCpy.iloHibernateON = (CY_PRA_DATA_DISABLE != message->praData1);
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.iloHibernateON = iloHibernateOnTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PILO_ENABLE:
                    {
                        bool piloEnableTmp;
                        /* Backups old values */
                        piloEnableTmp = structCpy.piloEnable;
                        structCpy.piloEnable = true;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.piloEnable = piloEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PILO_DISABLE:
                    {
                        bool piloEnableTmp;
                        /* Backups old values */
                        piloEnableTmp = structCpy.piloEnable;
                        structCpy.piloEnable = false;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.piloEnable = piloEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_WCO_ENABLE:
                    {
                        bool wcoEnableTmp;
                        /* Backups old values */
                        wcoEnableTmp = structCpy.wcoEnable;
                        structCpy.wcoEnable = true;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.wcoEnable = wcoEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_WCO_DISABLE:
                    {
                        bool wcoEnableTmp;
                        /* Backups old values */
                        wcoEnableTmp = structCpy.wcoEnable;
                        structCpy.wcoEnable = false;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.wcoEnable = wcoEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_WCO_BYPASS:
                    {
                        bool bypassEnableTmp;
                        /* Backups old values */
                        bypassEnableTmp = structCpy.bypassEnable;
                        structCpy.bypassEnable = ((cy_en_wco_bypass_modes_t) message->praData1 == CY_SYSCLK_WCO_BYPASSED) ? true : false;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* The bypass value will be written to the register only when WCO is enabled */
                        if (structCpy.wcoEnable)
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored */
                                structCpy.bypassEnable = bypassEnableTmp;
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_HF_ENABLE:
                    {
                        bool clkHFEnable;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* Backups old values */
                        switch (message->praData1)
                        {
                            case CY_PRA_CLKHF_0:
                            clkHFEnable = structCpy.clkHF0Enable;
                            structCpy.clkHF0Enable = true;
                            break;

                            case CY_PRA_CLKHF_1:
                            clkHFEnable = structCpy.clkHF1Enable;
                            structCpy.clkHF1Enable = true;
                            break;

                            case CY_PRA_CLKHF_2:
                            clkHFEnable = structCpy.clkHF2Enable;
                            structCpy.clkHF2Enable = true;
                            break;

                            case CY_PRA_CLKHF_3:
                            clkHFEnable = structCpy.clkHF3Enable;
                            structCpy.clkHF3Enable = true;
                            break;

                            case CY_PRA_CLKHF_4:
                            clkHFEnable = structCpy.clkHF4Enable;
                            structCpy.clkHF4Enable = true;
                            break;

                            case CY_PRA_CLKHF_5:
                            clkHFEnable = structCpy.clkHF5Enable;
                            structCpy.clkHF5Enable = true;
                            break;

                            default:
                            clkHFEnable = false;
                            message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                            break;

                        }
                        if (message->praStatus == CY_PRA_STATUS_SUCCESS)
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored */
                                switch (message->praData1)
                                {
                                    case CY_PRA_CLKHF_0:
                                    structCpy.clkHF0Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_1:
                                    structCpy.clkHF1Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_2:
                                    structCpy.clkHF2Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_3:
                                    structCpy.clkHF3Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_4:
                                    structCpy.clkHF4Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_5:
                                    structCpy.clkHF5Enable = clkHFEnable;
                                    break;

                                    default:
                                    /* Unknown Clock HF source */
                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_HF_DISABLE:
                    {
                        bool clkHFEnable;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* Backups old values */
                        switch (message->praData1)
                        {
                            case CY_PRA_CLKHF_0:
                            clkHFEnable = structCpy.clkHF0Enable;
                            structCpy.clkHF0Enable = false;
                            break;

                            case CY_PRA_CLKHF_1:
                            clkHFEnable = structCpy.clkHF1Enable;
                            structCpy.clkHF1Enable = false;
                            break;

                            case CY_PRA_CLKHF_2:
                            clkHFEnable = structCpy.clkHF2Enable;
                            structCpy.clkHF2Enable = false;
                            break;

                            case CY_PRA_CLKHF_3:
                            clkHFEnable = structCpy.clkHF3Enable;
                            structCpy.clkHF3Enable = false;
                            break;

                            case CY_PRA_CLKHF_4:
                            clkHFEnable = structCpy.clkHF4Enable;
                            structCpy.clkHF4Enable = false;
                            break;

                            case CY_PRA_CLKHF_5:
                            clkHFEnable = structCpy.clkHF5Enable;
                            structCpy.clkHF5Enable = false;
                            break;

                            default:
                            clkHFEnable = false;
                            message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                            break;

                        }
                        if (message->praStatus == CY_PRA_STATUS_SUCCESS)
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored */
                                switch (message->praData1)
                                {
                                    case CY_PRA_CLKHF_0:
                                    structCpy.clkHF0Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_1:
                                    structCpy.clkHF1Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_2:
                                    structCpy.clkHF2Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_3:
                                    structCpy.clkHF3Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_4:
                                    structCpy.clkHF4Enable = clkHFEnable;
                                    break;

                                    case CY_PRA_CLKHF_5:
                                    structCpy.clkHF5Enable = clkHFEnable;
                                    break;

                                    default:
                                    /* Unknown Clock HF source */
                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_HF_SET_SOURCE:
                    {
                        cy_en_clkhf_in_sources_t hfSource;
                        uint32_t hfOutFreqMHz;
                        bool hfEnabled;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* Backups old values */
                        switch (((cy_stc_pra_clkhfsetsource_t *) message->praData1)->clkHf)
                        {
                            case CY_PRA_CLKHF_0:
                            hfSource = structCpy.hf0Source;
                            structCpy.hf0Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
                            hfOutFreqMHz = structCpy.hf0OutFreqMHz;
                            hfEnabled = structCpy.clkHF0Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf0OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source)/(1UL << (uint32_t)structCpy.hf0Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_1:
                            hfSource = structCpy.hf1Source;
                            structCpy.hf1Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
                            hfOutFreqMHz = structCpy.hf1OutFreqMHz;
                            hfEnabled = structCpy.clkHF1Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with thecurrent HF output frequency value */
                            structCpy.hf1OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf1Source)/(1UL << (uint32_t)structCpy.hf1Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_2:
                            hfSource = structCpy.hf2Source;
                            structCpy.hf2Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
                            hfOutFreqMHz = structCpy.hf2OutFreqMHz;
                            hfEnabled = structCpy.clkHF2Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf2OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf2Source)/(1UL << (uint32_t)structCpy.hf2Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_3:
                            hfSource = structCpy.hf3Source;
                            structCpy.hf3Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
                            hfOutFreqMHz = structCpy.hf3OutFreqMHz;
                            hfEnabled = structCpy.clkHF3Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf3OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf3Source)/(1UL << (uint32_t)structCpy.hf3Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_4:
                            hfSource = structCpy.hf4Source;
                            structCpy.hf4Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
                            hfOutFreqMHz = structCpy.hf4OutFreqMHz;
                            hfEnabled = structCpy.clkHF4Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf4OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf4Source)/(1UL << (uint32_t)structCpy.hf4Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_5:
                            hfSource = structCpy.hf5Source;
                            structCpy.hf5Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
                            hfOutFreqMHz = structCpy.hf5OutFreqMHz;
                            hfEnabled = structCpy.clkHF5Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf5OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf5Source)/(1UL << (uint32_t)structCpy.hf5Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            default:
                            hfEnabled = false;
                            message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                            break;
                        }
                        /* The HF source value is updated in the register only when
                         * that particular HF is enabled. Otherwise, it is stored in
                         * the system config structure
                         */
                        if ((message->praStatus == CY_PRA_STATUS_SUCCESS) && (hfEnabled))
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored */
                                switch (((cy_stc_pra_clkhfsetsource_t *) message->praData1)->clkHf)
                                {
                                    case CY_PRA_CLKHF_0:
                                    structCpy.hf0Source = hfSource;
                                    structCpy.hf0OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_1:
                                    structCpy.hf1Source = hfSource;
                                    structCpy.hf1OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_2:
                                    structCpy.hf2Source = hfSource;
                                    structCpy.hf2OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_3:
                                    structCpy.hf3Source = hfSource;
                                    structCpy.hf3OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_4:
                                    structCpy.hf4Source = hfSource;
                                    structCpy.hf4OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_5:
                                    structCpy.hf5Source = hfSource;
                                    structCpy.hf5OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    default:
                                    /* Unknown Clock HF source */
                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_HF_SET_DIVIDER:
                    {
                        cy_en_clkhf_dividers_t hfDivider;
                        uint32_t hfOutFreqMHz;
                        bool hfEnabled;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* Backups old values */
                        switch (((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->clkHf)
                        {
                            case CY_PRA_CLKHF_0:
                            hfDivider = structCpy.hf0Divider;
                            structCpy.hf0Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
                            hfOutFreqMHz = structCpy.hf0OutFreqMHz;
                            hfEnabled = structCpy.clkHF0Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf0OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source)/(1UL << (uint32_t)structCpy.hf0Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_1:
                            hfDivider = structCpy.hf1Divider;
                            structCpy.hf1Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
                            hfOutFreqMHz = structCpy.hf1OutFreqMHz;
                            hfEnabled = structCpy.clkHF1Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf1OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf1Source)/(1UL << (uint32_t)structCpy.hf1Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_2:
                            hfDivider = structCpy.hf2Divider;
                            structCpy.hf2Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
                            hfOutFreqMHz = structCpy.hf2OutFreqMHz;
                            hfEnabled = structCpy.clkHF2Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf2OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf2Source)/(1UL << (uint32_t)structCpy.hf2Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_3:
                            hfDivider = structCpy.hf3Divider;
                            structCpy.hf3Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
                            hfOutFreqMHz = structCpy.hf3OutFreqMHz;
                            hfEnabled = structCpy.clkHF3Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf3OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf3Source)/(1UL << (uint32_t)structCpy.hf3Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_4:
                            hfDivider = structCpy.hf4Divider;
                            structCpy.hf4Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
                            hfOutFreqMHz = structCpy.hf4OutFreqMHz;
                            hfEnabled = structCpy.clkHF4Enable;
                            /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
                            structCpy.hf4OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf4Source)/(1UL << (uint32_t)structCpy.hf4Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            case CY_PRA_CLKHF_5:
                            hfDivider = structCpy.hf5Divider;
                            structCpy.hf5Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
                            hfOutFreqMHz = structCpy.hf5OutFreqMHz;
                            hfEnabled = structCpy.clkHF5Enable;
                            /* The HF output frequency is not present in PDL API argument. So updated the system config structure with current HF output frequency value */
                            structCpy.hf5OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf5Source)/(1UL << (uint32_t)structCpy.hf5Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
                            break;

                            default:
                            hfEnabled = false;
                            message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                            break;
                        }
                        /* The HF divider value is updated in the register only when
                         * that particular HF is enabled. Otherwise, it is stored in
                         * the system config structure
                         */
                        if ((message->praStatus == CY_PRA_STATUS_SUCCESS) && (hfEnabled))
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored  */
                                switch (((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->clkHf)
                                {
                                    case CY_PRA_CLKHF_0:
                                    structCpy.hf0Divider = hfDivider;
                                    structCpy.hf0OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_1:
                                    structCpy.hf1Divider = hfDivider;
                                    structCpy.hf1OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_2:
                                    structCpy.hf2Divider = hfDivider;
                                    structCpy.hf2OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_3:
                                    structCpy.hf3Divider = hfDivider;
                                    structCpy.hf3OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_4:
                                    structCpy.hf4Divider = hfDivider;
                                    structCpy.hf4OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    case CY_PRA_CLKHF_5:
                                    structCpy.hf5Divider = hfDivider;
                                    structCpy.hf5OutFreqMHz = hfOutFreqMHz;
                                    break;

                                    default:
                                    /* Invalid Clock HF Source */
                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_FAST_SET_DIVIDER:
                    {
                        uint8_t clkFastDivTmp;
                        bool clkFastEnableTmp;
                        /* Backups old values */
                        clkFastEnableTmp = structCpy.clkFastEnable;
                        clkFastDivTmp = structCpy.clkFastDiv;
                        structCpy.clkFastEnable = true;
                        structCpy.clkFastDiv =  (uint8_t)(message->praData1);
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored  */
                            structCpy.clkFastDiv = clkFastDivTmp;
                            structCpy.clkFastEnable = clkFastEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PERI_SET_DIVIDER:
                    {
                        uint8_t clkPeriDivTmp;
                        bool clkPeriEnableTmp;
                        /* Backups old values */
                        clkPeriDivTmp = structCpy.clkPeriDiv;
                        clkPeriEnableTmp = structCpy.clkPeriEnable;
                        structCpy.clkPeriEnable = true;
                        structCpy.clkPeriDiv =  (uint8_t)(message->praData1);
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored  */
                            structCpy.clkPeriDiv = clkPeriDivTmp;
                            structCpy.clkPeriEnable = clkPeriEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_LF_SET_SOURCE:
                    {
                        cy_en_clklf_in_sources_t clkLfSourceTmp;
                        bool clkLFEnableTmp;
                        /* Backups old values */
                        clkLFEnableTmp = structCpy.clkLFEnable;
                        clkLfSourceTmp = structCpy.clkLfSource;
                        structCpy.clkLFEnable = true;
                        structCpy.clkLfSource = (cy_en_clklf_in_sources_t)message->praData1;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.clkLfSource = clkLfSourceTmp;
                            structCpy.clkLFEnable = clkLFEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_TIMER_SET_SOURCE:
                    {
                        cy_en_clktimer_in_sources_t clkTimerSourceTmp;
                        /* Backups old values */
                        clkTimerSourceTmp = structCpy.clkTimerSource;
                        structCpy.clkTimerSource = (cy_en_clktimer_in_sources_t)message->praData1;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        if (structCpy.clkTimerEnable)
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored */
                                structCpy.clkTimerSource = clkTimerSourceTmp;
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_TIMER_SET_DIVIDER:
                    {
                        uint8_t clkTimerDividerTmp;
                        /* Backups old values */
                        clkTimerDividerTmp = structCpy.clkTimerDivider;
                        structCpy.clkTimerDivider = (uint8_t)(message->praData1);
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* The timer divider value is updated in the register only
                         * when CLK_TIMER is enabled. Otherwise, it is only
                         * stored in the system config structure
                         */
                        if (structCpy.clkTimerEnable)
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored */
                                structCpy.clkTimerDivider = clkTimerDividerTmp;
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_TIMER_ENABLE:
                    {
                        bool clkTimerEnableTmp;
                        /* Backups old values */
                        clkTimerEnableTmp = structCpy.clkTimerEnable;
                        structCpy.clkTimerEnable = true;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored  */
                            structCpy.clkTimerEnable = clkTimerEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_TIMER_DISABLE:
                    {
                        bool clkTimerEnableTmp;
                        /* Backups old values */
                        clkTimerEnableTmp = structCpy.clkTimerEnable;
                        structCpy.clkTimerEnable = false;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored  */
                            structCpy.clkTimerEnable = clkTimerEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PUMP_SET_SOURCE:
                    {
                        cy_en_clkpump_in_sources_t pumpSourceTmp;
                        /* Backups old values */
                        pumpSourceTmp = structCpy.pumpSource;
                        structCpy.pumpSource = (cy_en_clkpump_in_sources_t)message->praData1;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* The PUMP source value is updated in the register only
                         * when PUMP is enabled. Otherwise, it is only
                         * stored in the system config structure
                         */
                        if (structCpy.clkPumpEnable)
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored  */
                                structCpy.pumpSource = pumpSourceTmp;
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PUMP_SET_DIVIDER:
                    {
                        cy_en_clkpump_divide_t pumpDividerTmp;
                        /* Backups old values */
                        pumpDividerTmp = structCpy.pumpDivider;
                        structCpy.pumpDivider = (cy_en_clkpump_divide_t)message->praData1;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* The PUMP divider value is updated in the register only
                         * when PUMP is enabled. Otherwise, it is only
                         * stored in the system config structure
                         */
                        if (structCpy.clkPumpEnable)
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous values are restored  */
                                structCpy.pumpDivider = pumpDividerTmp;
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PUMP_ENABLE:
                    {
                        bool clkPumpEnableTmp;
                        /* Backups old values */
                        clkPumpEnableTmp = structCpy.clkPumpEnable;
                        structCpy.clkPumpEnable = true;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored  */
                            structCpy.clkPumpEnable = clkPumpEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PUMP_DISABLE:
                    {
                        bool clkPumpEnableTmp;
                        /* Backups old values */
                        clkPumpEnableTmp = structCpy.clkPumpEnable;
                        structCpy.clkPumpEnable = false;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored */
                            structCpy.clkPumpEnable = clkPumpEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_BAK_SET_SOURCE:
                    {
                        cy_en_clkbak_in_sources_t clkBakSourceTmp;
                        bool clkBakEnableTmp;
                        /* Backups old values */
                        clkBakEnableTmp = structCpy.clkBakEnable;
                        clkBakSourceTmp = structCpy.clkBakSource;
                        structCpy.clkBakEnable = true;
                        structCpy.clkBakSource = (cy_en_clkbak_in_sources_t)message->praData1;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored  */
                            structCpy.clkBakSource = clkBakSourceTmp;
                            structCpy.clkBakEnable = clkBakEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_ECO_CONFIGURE:
                    {
                        /* ECO configuration is not allowed if ECO is already enabled.
                         * The correct sequence is ECO_DISABLE -> ECO_CONFIGURE -> ECO_ENABLE
                         */
                        if (structCpy.ecoEnable)
                        {
                            message->praStatus = CY_PRA_STATUS_ERROR_PROCESSING_ECO_ENABLED;
                        }
                        else
                        {
                            /* Stored the ECO config values into the system config structure.
                             * These values are applied to the register after a call from ECO_ENABLE.
                             */
                            structCpy.ecoFreqHz = ((cy_stc_pra_clk_eco_configure_t *) message->praData1)->praClkEcofreq;
                            structCpy.ecoLoad = ((cy_stc_pra_clk_eco_configure_t *) message->praData1)->praCsum;
                            structCpy.ecoEsr = ((cy_stc_pra_clk_eco_configure_t *) message->praData1)->praEsr;
                            structCpy.ecoDriveLevel = ((cy_stc_pra_clk_eco_configure_t *) message->praData1)->praDriveLevel;
                            message->praStatus = CY_PRA_STATUS_SUCCESS;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_ECO_ENABLE:
                    {
                        bool ecoEnableTmp;
                        /* Backups old values */
                        ecoEnableTmp = structCpy.ecoEnable;
                        structCpy.ecoEnable = true;
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous values are restored  */
                            structCpy.ecoEnable = ecoEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PATH_SET_SOURCE:
                    {
                        bool pathEnable = false;
                        cy_en_clkpath_in_sources_t pathSrc = CY_SYSCLK_CLKPATH_IN_IMO;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                        /* Backups old values */
                        switch (((cy_stc_pra_clkpathsetsource_t *) message->praData1)->clk_path)
                        {
                            case CY_PRA_CLKPATH_0:
                            pathEnable = structCpy.path0Enable;
                            pathSrc = structCpy.path0Src;
                            structCpy.path0Enable = true;
                            structCpy.path0Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
                            break;

                            case CY_PRA_CLKPATH_1:
                            pathEnable = structCpy.path1Enable;
                            pathSrc = structCpy.path1Src;
                            structCpy.path1Enable = true;
                            structCpy.path1Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
                            break;

                            case CY_PRA_CLKPATH_2:
                            pathEnable = structCpy.path2Enable;
                            pathSrc = structCpy.path2Src;
                            structCpy.path2Enable = true;
                            structCpy.path2Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
                            break;

                            case CY_PRA_CLKPATH_3:
                            pathEnable = structCpy.path3Enable;
                            pathSrc = structCpy.path3Src;
                            structCpy.path3Enable = true;
                            structCpy.path3Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
                            break;

                            case CY_PRA_CLKPATH_4:
                            pathEnable = structCpy.path4Enable;
                            pathSrc = structCpy.path4Src;
                            structCpy.path4Enable = true;
                            structCpy.path4Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
                            break;

                            case CY_PRA_CLKPATH_5:
                            pathEnable = structCpy.path5Enable;
                            pathSrc = structCpy.path5Src;
                            structCpy.path5Enable = true;
                            structCpy.path5Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
                            break;

                            default:
                            message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                            break;
                        }
                        if (message->praStatus == CY_PRA_STATUS_SUCCESS)
                        {
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                /* On failure, previous path values are restored  */
                                switch (((cy_stc_pra_clkpathsetsource_t *) message->praData1)->clk_path)
                                {
                                    case CY_PRA_CLKPATH_0:
                                    structCpy.path0Enable = pathEnable;
                                    structCpy.path0Src = pathSrc;
                                    break;

                                    case CY_PRA_CLKPATH_1:
                                    structCpy.path1Enable = pathEnable;
                                    structCpy.path1Src = pathSrc;
                                    break;

                                    case CY_PRA_CLKPATH_2:
                                    structCpy.path2Enable = pathEnable;
                                    structCpy.path2Src = pathSrc;
                                    break;

                                    case CY_PRA_CLKPATH_3:
                                    structCpy.path3Enable = pathEnable;
                                    structCpy.path3Src = pathSrc;
                                    break;

                                    case CY_PRA_CLKPATH_4:
                                    structCpy.path4Enable = pathEnable;
                                    structCpy.path4Src = pathSrc;
                                    break;

                                    case CY_PRA_CLKPATH_5:
                                    structCpy.path5Enable = pathEnable;
                                    structCpy.path5Src = pathSrc;
                                    break;

                                    default:
                                    message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                                    break;
                                }
                            }
                            else
                            {
                                switch (((cy_stc_pra_clkpathsetsource_t *) message->praData1)->clk_path)
                                {
                                    case CY_PRA_CLKPATH_0:
                                    {
                                        if (structCpy.fllEnable)
                                        {
                                            /* Update FLL output frequency */
                                            structCpy.fllOutFreqHz = Cy_PRA_CalculateFLLOutFreq(&structCpy);
                                        }
                                        if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH0)
                                        {
                                            /* Update HF0 output frequency */
                                            structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
                                        }
                                    }
                                    break;

                                    case CY_PRA_CLKPATH_1:
                                    {
                                        if (structCpy.pll0Enable)
                                        {
                                            /* Update PLL0 output frequency */
                                            structCpy.pll0OutFreqHz = Cy_PRA_CalculatePLLOutFreq(CY_PRA_CLKPLL_1, &structCpy);
                                        }
                                        if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH1)
                                        {
                                            /* Update HF0 output frequency */
                                            structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
                                        }
                                    }
                                    break;

                                    case CY_PRA_CLKPATH_2:
                                    {
                                        if (structCpy.pll1Enable)
                                        {
                                            /* Update PLL1 output frequency */
                                            structCpy.pll1OutFreqHz = Cy_PRA_CalculatePLLOutFreq(CY_PRA_CLKPLL_2, &structCpy);
                                        }
                                        if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH2)
                                        {
                                            /* Update HF0 output frequency */
                                            structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
                                        }
                                    }
                                    break;

                                    case CY_PRA_CLKPATH_3:
                                    {
                                        if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH3)
                                        {
                                            /* Update HF0 output frequency */
                                            structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
                                        }
                                    }
                                    break;

                                    case CY_PRA_CLKPATH_4:
                                    {
                                        if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH4)
                                        {
                                            /* Update HF0 output frequency */
                                            structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
                                        }
                                    }
                                    break;

                                    case CY_PRA_CLKPATH_5:
                                    {
                                        if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH5)
                                        {
                                            /* Update HF0 output frequency */
                                            structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
                                        }
                                    }
                                    break;

                                    default:
                                    /* Unknown clock path */
                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_FLL_MANCONFIG:
                    {
                        /* FLL manual configuration values are not written to the
                         * register but stored in the system config structure.
                         * These values are applied to the register
                         * after a call from CY_PRA_CLK_FUNC_FLL_ENABLE */
                        structCpy.fllMult = ((cy_stc_fll_manual_config_t *) message->praData1)->fllMult;
                        structCpy.fllRefDiv = ((cy_stc_fll_manual_config_t *) message->praData1)->refDiv;
                        structCpy.fllCcoRange = ((cy_stc_fll_manual_config_t *) message->praData1)->ccoRange;
                        structCpy.enableOutputDiv = ((cy_stc_fll_manual_config_t *) message->praData1)->enableOutputDiv;
                        structCpy.lockTolerance = ((cy_stc_fll_manual_config_t *) message->praData1)->lockTolerance;
                        structCpy.igain = ((cy_stc_fll_manual_config_t *) message->praData1)->igain;
                        structCpy.pgain = ((cy_stc_fll_manual_config_t *) message->praData1)->pgain;
                        structCpy.settlingCount = ((cy_stc_fll_manual_config_t *) message->praData1)->settlingCount;
                        structCpy.outputMode = ((cy_stc_fll_manual_config_t *) message->praData1)->outputMode;
                        structCpy.ccoFreq = ((cy_stc_fll_manual_config_t *) message->praData1)->cco_Freq;
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                    }
                    break;

                    case CY_PRA_CLK_FUNC_FLL_ENABLE:
                    {
                        /* FLL Enable is not allowed if it is already enabled */
                        if (structCpy.fllEnable == true) /* FLL is already enabled */
                        {
                            message->praStatus = CY_PRA_STATUS_ERROR_PROCESSING_FLL0_ENABLED;
                        }
                        else
                        {
                            structCpy.fllEnable = true;
                            /* FLL Enable API does not contain the FLL output value
                             * as the argument. So, calculate and update the FLL output value */
                            structCpy.fllOutFreqHz = Cy_PRA_CalculateFLLOutFreq(&structCpy);
                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                structCpy.fllOutFreqHz = CY_PRA_DEFAULT_ZERO;
                                structCpy.fllEnable = false;
                            }
                            else
                            {
                                /* Check if FLL is source to HF0 */
                                if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH0)
                                {
                                    /* Update HF0 output frequency */
                                    structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
                                }
                            }
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PLL_MANCONFIG:
                    {
                        /* Checks for the valid PLL number */
                        if((((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->clkPath == CY_PRA_CLKPATH_0) ||
                           (((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->clkPath > CY_SRSS_NUM_PLL))
                        {
                            message->praStatus = CY_PRA_STATUS_INVALID_PARAM_PLL_NUM;
                        }
                        else
                        {
                            /* PLL manual configuration values are not written to
                             * the register but stored in the system config structure.
                             * These values are applied to the register
                             * after a call from CY_PRA_CLK_FUNC_PLL_ENABLE. */
                            if(((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->clkPath == CY_PRA_CLKPATH_1)
                            {
                                structCpy.pll0FeedbackDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->feedbackDiv;
                                structCpy.pll0ReferenceDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->referenceDiv;
                                structCpy.pll0OutputDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->outputDiv;
                                structCpy.pll0LfMode = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->lfMode;
                                structCpy.pll0OutputMode = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->outputMode;
                            }
                            else
                            {
                                structCpy.pll1FeedbackDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->feedbackDiv;
                                structCpy.pll1ReferenceDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->referenceDiv;
                                structCpy.pll1OutputDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->outputDiv;
                                structCpy.pll1LfMode = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->lfMode;
                                structCpy.pll1OutputMode = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->outputMode;
                            }
                            message->praStatus = CY_PRA_STATUS_SUCCESS;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_PLL_ENABLE:
                    {
                        if ((((message->praData1) == CY_PRA_CLKPLL_1) && (structCpy.pll0Enable == true))
                            || (((message->praData1) == CY_PRA_CLKPLL_2) && (structCpy.pll1Enable == true))
                            || (message->praData1 > CY_SRSS_NUM_PLL) || (message->praData1 == 0UL))
                        {
                            message->praStatus = CY_PRA_STATUS_ERROR_PROCESSING_PLL_ENABLED;
                        }
                        else
                        {
                            /* PLL Enable API does not contain the PLL output value
                             * as the argument. So, calculate and update the PLL output value */
                            if ((message->praData1) == CY_PRA_CLKPLL_1)
                            {
                                structCpy.pll0OutFreqHz = Cy_PRA_CalculatePLLOutFreq(CY_PRA_CLKPLL_1, &structCpy);
                                structCpy.pll0Enable = true;
                            }
                            else
                            {
                                structCpy.pll1OutFreqHz = Cy_PRA_CalculatePLLOutFreq(CY_PRA_CLKPLL_2, &structCpy);
                                structCpy.pll1Enable = true;
                            }

                            message->praStatus = Cy_PRA_SystemConfig(&structCpy);

                            if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                            {
                                if ((message->praData1) == CY_PRA_CLKPLL_1)
                                {
                                    structCpy.pll0OutFreqHz = CY_PRA_DEFAULT_ZERO;
                                    structCpy.pll0Enable = false;
                                }
                                else
                                {
                                    structCpy.pll1OutFreqHz = CY_PRA_DEFAULT_ZERO;
                                    structCpy.pll1Enable = false;
                                }
                            }
                            else /* PLL is enabled successfully */
                            {
                                /* Check if PLL0 or PLL1 is source to HF0 */
                                if ((structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH1) || (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH2))
                                {
                                    /* Update HF0 output frequency */
                                    structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
                                }
                            }

                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_SLOW_SET_DIVIDER:
                    {
                        uint8_t clkSlowDivTmp;
                        bool clkSlowEnableTmp;
                        /* Backups old values */
                        clkSlowEnableTmp = structCpy.clkSlowEnable;
                        clkSlowDivTmp = structCpy.clkSlowDiv;
                        structCpy.clkSlowEnable = true;
                        structCpy.clkSlowDiv = (uint8_t)(message->praData1);
                        message->praStatus = Cy_PRA_SystemConfig(&structCpy);
                        if (message->praStatus != CY_PRA_STATUS_SUCCESS)
                        {
                            /* On failure, previous path values are restored */
                            structCpy.clkSlowDiv = clkSlowDivTmp;
                            structCpy.clkSlowEnable = clkSlowEnableTmp;
                        }
                    }
                    break;

                    case CY_PRA_CLK_FUNC_EXT_CLK_SET_FREQUENCY:
                    {
                        structCpy.extClkEnable = true;
                        structCpy.extClkFreqHz = (uint32_t)(message->praData1);
                        message->praStatus = CY_PRA_STATUS_SUCCESS;
                    }
                    break;

                    default:
                        message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
                        break;
                }
            }
            else
            {
                message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
            }
            break;

        default:
            message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
           break;
    }

}
#endif /* (CY_CPU_CORTEX_M0P) */


#if (CY_CPU_CORTEX_M4) || defined (CY_DOXYGEN)

/*******************************************************************************
* Function Name: Cy_PRA_SendCmd
****************************************************************************//**
*
* Takes the parameters, passes them to the secure Cortex-M0+ via IPC, waits for
* Cortex-M0+ to finish and reports the status.
*
* \param cmd The command to execute on the secure side. The macros for this
* parameter are defined in the cy_pra.h file with the CY_PRA_MSG_TYPE_ prefix.
* \param regIndex The index of the function or register depending on the command
* parameter. The macros for this parameter are defined in the cy_pra.h file with
* the CY_PRA_INDX_ prefix.
* \param clearMask Data sent to secure the core.
* \param setMask Additional data send to secure the core.
*
* \return The command execution status. For the register read command, the read
* value is returned.
*
*******************************************************************************/
#if defined(CY_DEVICE_PSOC6ABLE2)

    CY_SECTION_RAMFUNC_BEGIN
    #if !defined (__ICCARM__)
        CY_NOINLINE
    #endif
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
    cy_en_pra_status_t Cy_PRA_SendCmd(uint16_t cmd, uint16_t regIndex, uint32_t clearMask, uint32_t setMask)
    {
        CY_ASSERT_L1(NULL != ipcPraBase);

        cy_en_pra_status_t status;
        CY_ALIGN(4UL) cy_stc_pra_msg_t ipcMsg;
        uint32_t interruptState;

        ipcMsg.praCommand = cmd;
        ipcMsg.praStatus  = CY_PRA_STATUS_REQUEST_SENT;
        ipcMsg.praIndex   = regIndex;
        ipcMsg.praData1   = clearMask;
        ipcMsg.praData2   = setMask;

        interruptState = Cy_SysLib_EnterCriticalSection();

        while (0U == _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(ipcPraBase)))
        {
            /* Waits until the PRA IPC structure is acquired */
        }

        /* Sends the message */
        REG_IPC_STRUCT_DATA(ipcPraBase) = (uint32_t) &ipcMsg;

        /* Generates an acquire notification event by the PRA IPC interrupt structure */
        REG_IPC_STRUCT_NOTIFY(ipcPraBase) = _VAL2FLD(IPC_STRUCT_NOTIFY_INTR_NOTIFY, CY_PRA_IPC_NOTIFY_INTR);

        while (0U != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_LOCK_STATUS(ipcPraBase)))
        {
            /* Waits until the PRA IPC structure is released */
        }

        Cy_SysLib_ExitCriticalSection(interruptState);

        /* Cortex-M0+ has an updated ipcMsg variable */

        status = (cy_en_pra_status_t) ipcMsg.praStatus;

        if (CY_PRA_STATUS_ACCESS_DENIED == status)
        {
            CY_HALT();
        }

        if (CY_PRA_MSG_TYPE_SYS_CFG_FUNC == ipcMsg.praCommand)
        {
        #if defined(CY_IP_MXBLESS)
            /* Update cy_BleEcoClockFreqHz for the proper Cy_SysLib_Delay functionality */
            if(((cy_stc_pra_system_config_t *) clearMask)->altHFclkFreq == CY_BLE_BLESS_ECO_FREQ_32MHZ)
            {
                cy_BleEcoClockFreqHz = CY_PRA_ALTHF_FREQ_32MHZ / (1UL << ((cy_stc_pra_system_config_t *) clearMask)->altHFsysClkDiv);
            }
            else
            {
                cy_BleEcoClockFreqHz = CY_PRA_ALTHF_FREQ_16MHZ / (1UL << ((cy_stc_pra_system_config_t *) clearMask)->altHFsysClkDiv);
            }

            if(((cy_stc_pra_system_config_t *) clearMask)->clkAltHfEnable == false)
            {
                cy_BleEcoClockFreqHz = 0UL;
            }
        #endif /* defined(CY_IP_MXBLESS) */

            cySysClkExtFreq = ((cy_stc_pra_system_config_t *) clearMask)->extClkFreqHz;

            SystemCoreClockUpdate();
        }

        if (CY_PRA_MSG_TYPE_REG32_GET == ipcMsg.praCommand)
        {
            status = (cy_en_pra_status_t)ipcMsg.praData1;
        }

        return status;
    }
#if defined(CY_DEVICE_PSOC6ABLE2)
    CY_SECTION_RAMFUNC_END
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */

/*******************************************************************************
* Function Name: Cy_PRA_GetPinProtType
****************************************************************************//**
*
* Find the matching PORT and PIN number from External clock secure PIN list and
* returns protection status of the PIN.
*
*******************************************************************************/
    cy_en_pra_pin_prot_type_t Cy_PRA_GetPinProtType(GPIO_PRT_Type *base, uint32_t pinNum)
    {
        uint32_t index;
        cy_en_pra_pin_prot_type_t pinType = CY_PRA_PIN_SECURE_NONE;

        if ((NULL != base) && (CY_GPIO_IS_PIN_VALID(pinNum)))
        {
            for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
            {
                if (secExtclkPinList[index].port == base)
                {
                    pinType = CY_PRA_PIN_SECURE_UNCONSTRAINED;

                    if (secExtclkPinList[index].pinNum == pinNum)
                    {
                        pinType = CY_PRA_PIN_SECURE;
                        break;
                    }
                }
            }
        }

        return pinType;
    }

/*******************************************************************************
* Function Name: Cy_PRA_IsPortSecure
****************************************************************************//**
*
* Find the matching PORT from External clock secure PIN list and returns
* protection status of the PORT.
*
*******************************************************************************/
    bool Cy_PRA_IsPortSecure(GPIO_PRT_Type *base)
    {
        uint32_t index;
        bool retPort = false;
        if (NULL != base)
        {
            for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
            {
                if (secExtclkPinList[index].port == base)
                {
                    retPort = true;
                    break;
                }
            }
        }

        return retPort;
    }

#if defined(CY_DEVICE_PSOC6ABLE2)
/*******************************************************************************
* Function Name: Cy_PRA_IsHsiomSecure
****************************************************************************//**
*
* Find the matching PORT from External clock adjacent HSIOM list and returns
* protection status of the PORT.
*
*******************************************************************************/
    bool Cy_PRA_IsHsiomSecure(GPIO_PRT_Type *base)
    {
        uint32_t index;
        bool retPort = false;
        if (NULL != base)
        {
            for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
            {
                if (secExtClkAdjHsiomList[index].port == base)
                {
                    retPort = true;
                    break;
                }
            }
        }

        return retPort;
    }

#endif /* defined(CY_DEVICE_PSOC6ABLE2) */

/*******************************************************************************
* Function Name: Cy_PRA_GetPortRegIndex
****************************************************************************//**
*
* Find the matching PORT and PIN number from External clock secure PIN list and
* returns port address index
*
*******************************************************************************/
    uint16_t Cy_PRA_GetPortRegIndex(GPIO_PRT_Type *base, uint16_t subIndex)
    {
        uint32_t index;
        uint16_t portIndex;
        uint16_t retIndex = CY_PRA_REG_INDEX_COUNT; /* assigned with invalid index */

        if (NULL != base)
        {
            for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
            {
                if (secExtclkPinList[index].port == base)
                {
                    portIndex = secExtclkPinList[index].index;

                    switch (subIndex)
                    {
                        case CY_PRA_SUB_INDEX_PORT_OUT:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_OUT_CLR:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_CLR), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_OUT_SET:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_SET), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_OUT_INV:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_INV), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_IN:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, IN), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_INTR:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_INTR_MASK:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_MASK), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_INTR_MASKED:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_MASKED), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_INTR_SET:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_SET), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_INTR_CFG:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtIntrCfgOffset), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_CFG:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgOffset), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_CFG_IN:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgInOffset), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_CFG_OUT:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgOutOffset), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_PORT_CFG_SIO:
                        retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U);
                        break;
                        default:
                        retIndex = CY_PRA_REG_INDEX_COUNT;
                        break;
                    }

                    break;
                }
            }
        }
        return retIndex;
    }

/*******************************************************************************
* Function Name: Cy_PRA_GetHsiomRegIndex
****************************************************************************//**
*
* Find the matching PORT address from External clock secure PIN list and
* returns HSIOM port address index
*
*******************************************************************************/
    uint16_t Cy_PRA_GetHsiomRegIndex(GPIO_PRT_Type *base, uint16_t subIndex)
    {
        uint32_t index;
        uint16_t hsiomIndex;
        uint16_t retIndex = CY_PRA_REG_INDEX_COUNT; /* assigned with invalid index */

        if (NULL != base)
        {
            for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
            {
                if (secExtclkPinList[index].port == base)
                {
                    hsiomIndex = secExtclkPinList[index].hsiomIndex;

                    switch (subIndex)
                    {
                        case CY_PRA_SUB_INDEX_HSIOM_PORT0:
                        retIndex = hsiomIndex + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL0), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_HSIOM_PORT1:
                        retIndex = hsiomIndex + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL1), 4U);
                        break;
                        default:
                        retIndex = CY_PRA_REG_INDEX_COUNT;
                        break;
                    }
                    break;
                }
            }
        }
        return retIndex;
    }

#if defined(CY_DEVICE_PSOC6ABLE2)
/*******************************************************************************
* Function Name: Cy_PRA_GetAdjHsiomRegIndex
****************************************************************************//**
*
* Find the matching PORT address from External clock adjacent hsiom list and
* returns HSIOM port address index
*
*******************************************************************************/
    uint16_t Cy_PRA_GetAdjHsiomRegIndex(GPIO_PRT_Type *base, uint16_t subIndex)
    {
        uint32_t index;
        uint16_t hsiomIndex;
        uint16_t retIndex = CY_PRA_REG_INDEX_COUNT; /* assigned with invalid index */

        if (NULL != base)
        {
            for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
            {
                if (secExtClkAdjHsiomList[index].port == base)
                {
                    hsiomIndex = secExtClkAdjHsiomList[index].hsiomIndex;

                    switch (subIndex)
                    {
                        case CY_PRA_SUB_INDEX_HSIOM_PORT0:
                        retIndex = hsiomIndex + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL0), 4U);
                        break;
                        case CY_PRA_SUB_INDEX_HSIOM_PORT1:
                        retIndex = hsiomIndex + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL1), 4U);
                        break;
                        default:
                        retIndex = CY_PRA_REG_INDEX_COUNT;
                        break;
                    }
                    break;
                }
            }
        }
        return retIndex;
    }
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */

#endif /* (CY_CPU_CORTEX_M4) */


#if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)

/* The mask to unlock Hibernate power mode */
#define HIBERNATE_UNLOCK_VAL                 ((uint32_t) 0x3Au << SRSS_PWR_HIBERNATE_UNLOCK_Pos)

/* The mask to set Hibernate power mode */
#define SET_HIBERNATE_MODE                   ((HIBERNATE_UNLOCK_VAL |\
                                               SRSS_PWR_HIBERNATE_FREEZE_Msk |\
                                               SRSS_PWR_HIBERNATE_HIBERNATE_Msk))

/* The mask to retain Hibernate power mode status */
#define HIBERNATE_RETAIN_STATUS_MASK         ((SRSS_PWR_HIBERNATE_TOKEN_Msk |\
                                               SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
                                               SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
                                               SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
                                               SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk))

/** The mask for Hibernate wakeup sources */
#define HIBERNATE_WAKEUP_MASK               ((SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
                                              SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
                                              SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
                                              SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk))

/** The define to update the token to indicate the transition into Hibernate */
#define HIBERNATE_TOKEN                    ((uint32_t) 0x1BU << SRSS_PWR_HIBERNATE_TOKEN_Pos)


/*******************************************************************************
* Function Name: Cy_PRA_PmHibernate
****************************************************************************//**
*
* Updates the SRSS_PWR_HIBERNATE register for the Cy_SysPm_SystemEnterHibernate and
* Cy_SysPm_IoUnfreeze functions.
*
*******************************************************************************/
static void Cy_PRA_PmHibernate(uint32_t funcProc)
{

    if(0UL == funcProc)
    {
        /* Saves the token to be retained through a wakeup sequence.
         * This could be used by Cy_SysLib_GetResetReason() to differentiate
         * Wakeup from a general reset event.
         * Saves the wakeup source(s) configuration.
         */
        SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & HIBERNATE_WAKEUP_MASK) | HIBERNATE_TOKEN;

        /* Disables the overriding the next pin-freeze command by the peripherals */
        SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;

        /* The second write causes freezing of I/O cells to save the I/O-cell state */
        SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;

        /* The third write cause system to enter Hibernate */
        SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
    }
    else
    {
        /* Saves the last reset reason and wakeup polarity. Then, unfreeze I/O:
         * writes PWR_HIBERNATE.FREEZE=0, .UNLOCK=0x3A, .HIBERANTE=0
         */
        SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & HIBERNATE_RETAIN_STATUS_MASK) | HIBERNATE_UNLOCK_VAL;

        /* Locks Hibernate mode:
        * write PWR_HIBERNATE.HIBERNATE=0, UNLOCK=0x00, HIBERANTE=0
        */
        SRSS_PWR_HIBERNATE &= HIBERNATE_RETAIN_STATUS_MASK;
    }
}


/*******************************************************************************
* Function Name: Cy_PRA_PmCm4DpFlagSet
****************************************************************************//**
*
* Sets Deep Sleep Flag for the CM4 core.
*
*******************************************************************************/
static void Cy_PRA_PmCm4DpFlagSet(void)
{
    uint32_t ddftStructData;

    /* Acquires the IPC to prevent the changing of the shared resources at the same time */
    while (0U == _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
    {
        /* Waits until the IPC structure is released by another CPU */
    }

    ddftStructData = REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT));

    /* Updates the CM4 core Deep Sleep mask */
    ddftStructData |= (0x01UL << 28u);

    /* Updates the pointer to the latest saved structure */
    REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = ddftStructData;

    /* Releases the IPC */
    REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;

    /* Reads the release value to make sure it is set */
    (void) REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT));
}

/* The timeout count for function Cy_PRA_ClkDeepSleepCallback() is sufficiently large for ~1 second */
#define CY_PRA_TIMEOUT (1000000UL)
/* These variables act as locks to prevent collisions between clock measurement and entry into
   Deep Sleep mode. See Cy_SysClk_DeepSleep(). */
static uint16_t changedSourcePaths = CY_PRA_DEFAULT_ZERO;
static uint16_t pllAutoModes = CY_PRA_DEFAULT_ZERO;


/*******************************************************************************
* Function Name: Cy_PRA_ClkDSBeforeTransition
****************************************************************************//**
*
* SysClock before deep sleep transition.
*
*******************************************************************************/
static cy_en_pra_status_t Cy_PRA_ClkDSBeforeTransition(void)
{
    uint32_t fllPll; /* 0 = FLL, all other values = a PLL */

    /* Initializes the storage of changed paths */
    changedSourcePaths = CY_PRA_DEFAULT_ZERO;
    pllAutoModes = CY_PRA_DEFAULT_ZERO;

    /* For FLL and each PLL */
    for (fllPll = 0UL; fllPll <= CY_SRSS_NUM_PLL; fllPll++)
    {
        /* If FLL or PLL is enabled */
        if ((0UL == fllPll) ? Cy_SysClk_FllIsEnabled() : Cy_SysClk_PllIsEnabled(fllPll))
        {
            /* And the FLL/PLL has ECO as a source */
            if (Cy_SysClk_ClkPathGetSource(fllPll) == CY_SYSCLK_CLKPATH_IN_ECO)
            {
                /* Bypasses the FLL/PLL */
                if (0UL == fllPll)
                {
                    CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
                }
                else
                {
                    if (((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_AUTO  == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[fllPll - 1UL])) ||
                        ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_AUTO1 == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[fllPll - 1UL])))
                    {
                        pllAutoModes |= (uint16_t)(1UL << fllPll);
                    }

                    CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllPll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
                }

                /* Changes this path source to IMO */
                (void)Cy_SysClk_ClkPathSetSource(fllPll, CY_SYSCLK_CLKPATH_IN_IMO);

                /* Stores a record that this path source was changed from ECO */
                changedSourcePaths |= (uint16_t)(1UL << fllPll);
            }
            else if (0UL == fllPll)
            {
                CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
            }
            else
            {
                /* Does nothing */
            }
        }
    }

    return CY_PRA_STATUS_SUCCESS;
}

/*******************************************************************************
* Function Name: Cy_PRA_ClkDSAfterTransition
****************************************************************************//**
*
* SysClock after Deep Sleep transition.
*
*******************************************************************************/
static cy_en_pra_status_t Cy_PRA_ClkDSAfterTransition(void)
{
    /* Bit-mapped paths with enabled FLL/PLL sourced by ECO */
    uint32_t timeout = CY_PRA_TIMEOUT;
    cy_en_pra_status_t retVal = CY_PRA_STATUS_ERROR_SYSPM_TIMEOUT;

    /* After return from Deep Sleep, for each FLL/PLL, if needed, restore the source to ECO.
     * And block until the FLL/PLL has regained its frequency lock.
     */
    if (0U != changedSourcePaths)
    {
        /* If any FLL/PLL was sourced by the ECO, the timeout waits for the ECO to become fully stabilized again */
        while ((CY_SYSCLK_ECOSTAT_STABLE != Cy_SysClk_EcoGetStatus()) && (0UL != timeout))
        {
            timeout--;
        }

        if (0UL != timeout)
        {
            uint32_t fllPll; /* 0 = FLL, all other values = PLL */

            for (fllPll = 0UL; fllPll <= CY_SRSS_NUM_PLL; fllPll++)
            {
                /* If there is a correspondent record about a changed clock source */
                if (0U != (changedSourcePaths & (uint16_t)(1UL << fllPll)))
                {
                    /* Changes this path source back to ECO */
                    (void)Cy_SysClk_ClkPathSetSource(fllPll, CY_SYSCLK_CLKPATH_IN_ECO);

                    /* The timeout waits for FLL/PLL to regain a lock.
                     * Split FLL and PLL lock polling loops into two separate threads to minimize one polling loop duration.
                     */
                    if (0UL == fllPll)
                    {
                        while ((!Cy_SysClk_FllLocked()) && (0UL != timeout))
                        {
                            timeout--;
                        }
                    }
                    else
                    {
                        while ((!Cy_SysClk_PllLocked(fllPll)) && (0UL != timeout))
                        {
                            timeout--;
                        }
                    }

                    if (0UL != timeout)
                    {
                        /* Undoes the bypass for FLL/PLL */
                        if (0UL == fllPll)
                        {
                            CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
                        }
                        else
                        {
                            if (0U != (pllAutoModes & (uint16_t)(1UL << fllPll)))
                            {
                                CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllPll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_AUTO);
                            }
                            else
                            {
                                CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllPll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
                            }
                        }

                        retVal = CY_PRA_STATUS_SUCCESS;
                    }
                }
            }
        }
    }
    else if (Cy_SysClk_FllIsEnabled())
    {
        /* The timeout waits for FLL to regain a lock */
        while ((!Cy_SysClk_FllLocked()) && (0UL != timeout))
        {
            timeout--;
        }

        if (0UL != timeout)
        {
            /* Undoes the bypass for FLL */
            CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
            retVal = CY_PRA_STATUS_SUCCESS;
        }
    }
    else
    {
        retVal = CY_PRA_STATUS_SUCCESS;
    }

    return (retVal);
}

/*******************************************************************************
* Function Name: Cy_PRA_RegAccessRangeValid
****************************************************************************//**
*
* Checks if the access is within the valid range and the access address is non-zero.
*
* \param index The index of the accessed register.
*
* \return Returns true for the valid access.
*
*******************************************************************************/
static bool Cy_PRA_RegAccessRangeValid(uint16_t index)
{
    bool accessValid = true;

    /* Checks if access is within the array range */
    if (index >= CY_PRA_REG_INDEX_COUNT)
    {
        accessValid = false;
    }
    else
    {
        /* Some registers do not exist for some families */
        if (regIndexToAddr[index].addr == (const volatile uint32_t *) 0U)
        {
            accessValid = false;
        }
    }

    return accessValid;
}


/*******************************************************************************
* Function Name: Cy_PRA_ClocksReset
****************************************************************************//**
*
* Initializes system clocks and dividers to the default state after reset.
*
*******************************************************************************/
static cy_en_pra_status_t Cy_PRA_ClocksReset(void)
{
    cy_en_pra_status_t returnStatus = CY_PRA_STATUS_SUCCESS;
    cy_en_sysclk_status_t sysClkStatus = CY_SYSCLK_SUCCESS;

    /* Sets the worst case memory wait states (! ultra low power, 150 MHz) */
    Cy_SysLib_SetWaitStates(false, CY_PRA_150MHZ_FREQUENCY);

    /* Resets the core clock path to default and disable all the FLLs/PLLs after Reset or Software reset */
    sysClkStatus = Cy_SysClk_ClkHfSetDivider(CY_PRA_CLKHF_0, CY_SYSCLK_CLKHF_NO_DIVIDE);
    if (CY_SYSCLK_SUCCESS != sysClkStatus)
    {
        returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_CLKHF0;
    }

    /* Sets the default divider for FAST, PERI and SLOW clocks */
    Cy_SysClk_ClkFastSetDivider(CY_PRA_DIVIDER_0);
    Cy_SysClk_ClkPeriSetDivider(CY_PRA_DIVIDER_1);
    Cy_SysClk_ClkSlowSetDivider(CY_PRA_DIVIDER_0);

    SystemCoreClockUpdate();

    /* Disables All PLLs */
    if (CY_SRSS_NUM_PLL >= CY_PRA_CLKPLL_1)
    {
        sysClkStatus = Cy_SysClk_PllDisable(CY_PRA_CLKPLL_1);
    }

    if (CY_SYSCLK_SUCCESS != sysClkStatus)
    {
        returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PLL0;
    }

    if (CY_SRSS_NUM_PLL >= CY_PRA_CLKPLL_2)
    {
        sysClkStatus = Cy_SysClk_PllDisable(CY_PRA_CLKPLL_2);
    }

    if (CY_SYSCLK_SUCCESS != sysClkStatus)
    {
        returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PLL1;
    }

    /* Sets the CLK_PATH1 source to IMO */
    sysClkStatus = Cy_SysClk_ClkPathSetSource((uint32_t) CY_SYSCLK_CLKHF_IN_CLKPATH1, CY_SYSCLK_CLKPATH_IN_IMO);
    if (CY_SYSCLK_SUCCESS != sysClkStatus)
    {
        returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PATHMUX1;
    }

    /* Set the HF0 source to IMO if it is sourced from WCO */
    if (CY_SYSCLK_CLKHF_IN_CLKPATH0 == Cy_SysClk_ClkHfGetSource(CY_PRA_CLKHF_0))
    {
            if (CY_SYSCLK_CLKPATH_IN_WCO == Cy_SysClk_ClkPathGetSource((uint32_t) CY_SYSCLK_CLKHF_IN_CLKPATH0))
            {
                sysClkStatus = Cy_SysClk_ClkHfSetSource(CY_PRA_CLKHF_0, CY_SYSCLK_CLKHF_IN_CLKPATH1);
                if (CY_SYSCLK_SUCCESS != sysClkStatus)
                {
                    returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_CLKHF0;
                }
                SystemCoreClockUpdate();
            }
    }

    sysClkStatus = Cy_SysClk_FllDisable();
    if (CY_SYSCLK_SUCCESS != sysClkStatus)
    {
        returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_FLL0;
    }

    /* Sets the CLK_PATH0 source to IMO */
    sysClkStatus = Cy_SysClk_ClkPathSetSource((uint32_t) CY_SYSCLK_CLKHF_IN_CLKPATH0, CY_SYSCLK_CLKPATH_IN_IMO);
    if (CY_SYSCLK_SUCCESS != sysClkStatus)
    {
        returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PATHMUX0;
    }

    /* Sets the HF0 source to IMO via CLK_PATH0 */
    sysClkStatus = Cy_SysClk_ClkHfSetSource(CY_PRA_CLKHF_0, CY_SYSCLK_CLKHF_IN_CLKPATH0);
    if (CY_SYSCLK_SUCCESS != sysClkStatus)
    {
        returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_CLKHF0;
    }

    #ifdef CY_IP_MXBLESS
        Cy_BLE_EcoReset();
    #endif

    return returnStatus;
}


/*******************************************************************************
* Function Name: Cy_PRA_BackupReset
****************************************************************************//**
*
* Resets the Backup domain and system clocks after System reset.
*
*******************************************************************************/
static cy_en_pra_status_t Cy_PRA_BackupReset(bool iloHibernateON)
{
    cy_en_pra_status_t returnStatus = CY_PRA_STATUS_SUCCESS;

    if (CY_SYSLIB_SUCCESS != Cy_SysLib_ResetBackupDomain())
    {
        returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PWR;
    }
    else
    {
        if (Cy_SysClk_IloIsEnabled())
        {
            if (CY_SYSCLK_SUCCESS != Cy_SysClk_IloDisable())
            {
                returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PWR;
            }
        }

        if (CY_PRA_STATUS_SUCCESS == returnStatus)
        {
            Cy_SysClk_IloEnable();
            Cy_SysClk_IloHibernateOn(iloHibernateON);
        }
    }

    return returnStatus;
}

/*******************************************************************************
* Function Name: Cy_PRA_ValidateSramPowerMode
****************************************************************************//**
*
* Validate SRAM power mode for a particular macro.
*
*******************************************************************************/
static cy_en_pra_status_t Cy_PRA_ValidateSramPowerMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
{
    uint32_t macroConfigIndex;
    cy_en_pra_status_t praStatus = CY_PRA_STATUS_SUCCESS;

    if (((uint8_t)sramNum < CY_PRA_SRAM_MAX_NR) && ((uint8_t)sramMacroNum < CY_PRA_SRAM_MACRO_MAX_NR))
    {
        /* find the sram macro */
        for (macroConfigIndex=0UL; macroConfigIndex<sramPwrModeConfig[sramNum].macroConfigCount; macroConfigIndex++)
        {
            if (0UL != (sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramMacros & (1UL<<sramMacroNum)))
            {
                switch(sramPwrMode)
                {
                    case CY_SYSPM_SRAM_PWR_MODE_OFF:
                    if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_OFF, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
                    {
                        praStatus = CY_PRA_STATUS_INVALID_PARAM;
                    }
                    break;
                    case CY_SYSPM_SRAM_PWR_MODE_RET:
                    if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_RETAIN, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
                    {
                        praStatus = CY_PRA_STATUS_INVALID_PARAM;
                    }
                    break;
                    case CY_SYSPM_SRAM_PWR_MODE_ON:
                    if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_ON, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
                    {
                        praStatus = CY_PRA_STATUS_INVALID_PARAM;
                    }
                    break;
                    default:
                    /* invalid power mode */
                    break;
                }
                break; /* found the macro number */
            }
        }

        /* if configuration is not present in policy, then all power modes are allowed */
    }
    else
    {
        praStatus = CY_PRA_STATUS_INVALID_PARAM;
    }

    return praStatus;
}

/*******************************************************************************
* Function Name: Cy_PRA_ValidateEntireSramPowerMode
****************************************************************************//**
*
* Validate SRAM power mode for all macros.
*
*******************************************************************************/
static cy_en_pra_status_t Cy_PRA_ValidateEntireSramPowerMode(cy_en_syspm_sram_index_t sramNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
{
    uint32_t macroConfigIndex;
    cy_en_pra_status_t praStatus = CY_PRA_STATUS_SUCCESS;

    if ((uint8_t)sramNum < CY_PRA_SRAM_MAX_NR)
    {
        /* find the sram macro */
        for (macroConfigIndex=0UL; macroConfigIndex<sramPwrModeConfig[sramNum].macroConfigCount; macroConfigIndex++)
        {
            switch(sramPwrMode)
            {
                case CY_SYSPM_SRAM_PWR_MODE_OFF:
                if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_OFF, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
                {
                    praStatus = CY_PRA_STATUS_INVALID_PARAM;
                }
                break;
                case CY_SYSPM_SRAM_PWR_MODE_RET:
                if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_RETAIN, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
                {
                    praStatus = CY_PRA_STATUS_INVALID_PARAM;
                }
                break;
                case CY_SYSPM_SRAM_PWR_MODE_ON:
                if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_ON, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
                {
                    praStatus = CY_PRA_STATUS_INVALID_PARAM;
                }
                break;
                default:
                /* invalid power mode */
                break;
            }
            if (praStatus == CY_PRA_STATUS_INVALID_PARAM)
            {
                break;
            }
        }

        /* if configuration is not present in policy, then all power modes are allowed */
    }
    else
    {
        praStatus = CY_PRA_STATUS_INVALID_PARAM;
    }

    return praStatus;
}

#endif /* (CY_CPU_CORTEX_M0P) */

#endif /* (CY_DEVICE_SECURE) */

#endif /* CY_IP_M4CPUSS */

/* [] END OF FILE */