/*
 * Copyright 2019-2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef _FSL_XRDC2_H_
#define _FSL_XRDC2_H_

#include "fsl_common.h"

/*!
 * @addtogroup xrdc2
 * @{
 */

/******************************************************************************
 * Definitions
 *****************************************************************************/
/*! @brief Driver version. */
#define FSL_XRDC2_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))

/* Definitions for XRDC2 Exclusive access lock. */
#define XRDC2_EAL_FORCE_RELEASE_MAGIC_0 0x02000046UL
#define XRDC2_EAL_FORCE_RELEASE_MAGIC_1 0x02000052UL

#define XRDC2_EAL_DISABLE             (0UL << XRDC2_MSC_MSAC_W1_EAL_SHIFT)
#define XRDC2_EAL_DISABLE_UNTIL_RESET (1UL << XRDC2_MSC_MSAC_W1_EAL_SHIFT)
#define XRDC2_EAL_UNLOCKED            (2UL << XRDC2_MSC_MSAC_W1_EAL_SHIFT)
#define XRDC2_EAL_LOCKED              (3UL << XRDC2_MSC_MSAC_W1_EAL_SHIFT)

#define XRDC2_EAL_MASK XRDC2_MSC_MSAC_W1_EAL_MASK

/*!
 * @brief Global configuration lock.
 */
typedef enum _xrdc2_global_config_lock
{
    kXRDC2_GlobalConfigLockDisabled,           /*!< Lock disabled, registers can be written by any domain. */
    kXRDC2_GlobalConfigLockDisabledUntilReset, /*!< Lock disabled until the next reset. */
    kXRDC2_GlobalConfigLockOwnerOnly,          /*!< Lock enabled, only the lock owner can write. */
    kXRDC2_GlobalConfigLockEnabledUntilReset   /*!< Lock enabled, all registers are read only until the next reset. */
} xrdc2_global_config_lock_t;

/*!
 * @brief XRDC2 secure attribute, the register bit MDACi_MDAj_W0[SA],
 * secure/nonsecure attribute output on a hit.
 */
typedef enum _xrdc2_secure_attr
{
    kXRDC2_MasterSecure   = 0, /*!< Use the bus master's secure/nonsecure attribute directly. */
    kXRDC2_ForceSecure    = 2, /*!< Force the bus attribute for this master to secure.        */
    kXRDC2_ForceNonSecure = 3, /*!< Force the bus attribute for this master to non-secure.    */
} xrdc2_secure_attr_t;

/*!
 * @brief XRDC2 privileged attribute, the register bit MDACi_MDAj_W0[PA],
 * defines the privileged/user attribute on a hit.
 */
typedef enum _xrdc2_privilege_attr
{
    kXRDC2_MasterPrivilege = 0, /*!< Use the bus master's attribute directly. */
    kXRDC2_ForceUser       = 2, /*!< Force the bus attribute for this master to user.       */
    kXRDC2_ForcePrivilege  = 3, /*!< Force the bus attribute for this master to privileged. */
} xrdc2_privilege_attr_t;

/*!
 * @brief Domain assignment for the bus master.
 *
 * XRDC2 compares the bus master @e match @e input with the parameter @ref mask
 * and @ref match in this structure. If hit, the domain ID, privilege attribute,
 * and secure attribute are used for the access.
 */
typedef struct _xrdc2_master_domain_assignment
{
    bool lock;                            /*!< Set true to lock the descriptor. */
    xrdc2_privilege_attr_t privilegeAttr; /*!< Privilege attribute. */
    xrdc2_secure_attr_t secureAttr;       /*!< Secure attribute. */
    uint8_t domainId;                     /*!< Domain ID used when this descriptor hit. */
    uint16_t mask;                        /*!< Mask used for descriptor hit. */
    uint16_t match;                       /*!< Match used for descriptor hit. */
} xrdc2_master_domain_assignment_t;

/*!
 * @brief XRDC2 domain access control policy.
 */
typedef enum _xrdc2_access_policy
{
    /*                               policy SecurePriv  SecureUser  NonSecurePriv  NonSecureUsr */
    kXRDC2_AccessPolicyNone = 0U, /*  000      none        none        none            none     */
    kXRDC2_AccessPolicyAlt1 = 1U, /*  001      r             r         none            none     */
    kXRDC2_AccessPolicyAlt2 = 2U, /*  010      r,w         none        none            none     */
    kXRDC2_AccessPolicyAlt3 = 3U, /*  011      r,w          r,w        none            none     */
    kXRDC2_AccessPolicyAlt4 = 4U, /*  100      r,w          r,w         r              none     */
    kXRDC2_AccessPolicyAlt5 = 5U, /*  101      r,w          r,w         r                r      */
    kXRDC2_AccessPolicyAlt6 = 6U, /*  110      r,w          r,w         r,w            none     */
    kXRDC2_AccessPolicyAll  = 7U  /*  111      r,w          r,w         r,w             r,w     */
} xrdc2_access_policy_t;

/*!
 * @brief Access configuration lock mode, the register field PDAC and MRGD LK2.
 */
typedef enum _xrdc2_access_config_lock
{
    kXRDC2_AccessConfigLockDisabled           = 0U, /*!< Entire PDACn/MRGDn/MSC can be written.       */
    kXRDC2_AccessConfigLockDisabledUntilReset = 1U, /*!< Entire PDACn/MRGDn/MSC can be written until next reset. */
    kXRDC2_AccessConfigLockDomainXOnly        = 2U, /*!< Domain x only write the DxACP field.     */
    kXRDC2_AccessConfigLockEnabledUntilReset  = 3U  /*!< PDACn/MRGDn/MSC is read-only until the next reset. */
} xrdc2_access_config_lock_t;

/*!
 * @brief XRDC2 peripheral domain access control configuration.
 */
typedef struct _xrdc2_periph_access_config
{
    xrdc2_access_config_lock_t lockMode;                          /*!< PDACn lock configuration.      */
    xrdc2_access_policy_t policy[FSL_FEATURE_XRDC2_DOMAIN_COUNT]; /*!< Access policy for each domain. */
} xrdc2_periph_access_config_t;

/*!
 * @brief XRDC2 memory region domain access control configuration.
 */
typedef struct _xrdc2_mem_access_config
{
    uint32_t startAddr;                  /*!< Memory region start address, should be 4k aligned. */
    uint32_t endAddr;                    /*!< Memory region end address, (endAddr + 1) should be 4k aligned. */
    xrdc2_access_config_lock_t lockMode; /*!< MRGDn lock configuration.      */
    xrdc2_access_policy_t policy[FSL_FEATURE_XRDC2_DOMAIN_COUNT]; /*!< Access policy for each domain. */
} xrdc2_mem_access_config_t;

/*!
 * @brief XRDC2 memory slot domain access control configuration.
 */
typedef struct _xrdc2_mem_slot_access_config
{
    xrdc2_access_config_lock_t lockMode;                          /*!< Descriptor lock configuration.      */
    xrdc2_access_policy_t policy[FSL_FEATURE_XRDC2_DOMAIN_COUNT]; /*!< Access policy for each domain. */
} xrdc2_mem_slot_access_config_t;

/*******************************************************************************
 * API
 ******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Initializes the XRDC2 module.
 *
 * @param base XRDC2 peripheral base address.
 */
void XRDC2_Init(XRDC2_Type *base);

/*!
 * @brief De-initializes the XRDC2 module.
 *
 * @param base XRDC2 peripheral base address.
 */
void XRDC2_Deinit(XRDC2_Type *base);

/*!
 * @name XRDC2 manager (XRDC2)
 * @{
 */

/*!
 * @brief Sets the XRDC2 global valid.
 *
 * This function sets the XRDC2 global valid or invalid. When the XRDC2 is global
 * invalid, all accesses from all bus masters to all slaves are allowed.
 *
 * @param base XRDC2 peripheral base address.
 * @param valid True to valid XRDC2.
 */
void XRDC2_SetGlobalValid(XRDC2_Type *base, bool valid);

/*!
 * @brief Gets the domain ID of the current bus master.
 *
 * This function returns the domain ID of the current bus master.
 *
 * @param base XRDC2 peripheral base address.
 * @return Domain ID of current bus master.
 */
static inline uint8_t XRDC2_GetCurrentMasterDomainId(XRDC2_Type *base)
{
#if defined(XRDC2_SR_DIN_MASK)
    return (uint8_t)((base->SR & XRDC2_SR_DIN_MASK) >> XRDC2_SR_DIN_SHIFT);
#else
    return (uint8_t)((base->SR & XRDC2_SR_DID_MASK) >> XRDC2_SR_DID_SHIFT);
#endif
}

/*!
 * @brief Set the global configuration lock mode.
 *
 * Once change the lock mode, it could not be changed until next reset.
 *
 * @param base XRDC2 peripheral base address.
 * @param lock The lock mode.
 */
static inline void XRDC2_SetGlobalConfigLock(XRDC2_Type *base, xrdc2_global_config_lock_t mode)
{
    base->MCR = (base->MCR & ~XRDC2_MCR_GCL_MASK) | XRDC2_MCR_GCL(mode);
}

/*!
 * @brief Gets the domain ID of global configuration lock owner.
 *
 * @param base XRDC2 peripheral base address.
 * @return Domain ID of the global configuration lock owner.
 */
static inline uint8_t XRDC2_GetCurrentGlobalConfigLockOwnerDomainId(XRDC2_Type *base)
{
    return (uint8_t)((base->SR & XRDC2_SR_GCLO_MASK) >> XRDC2_SR_GCLO_SHIFT);
}

/*@}*/

/*!
 * @name XRDC2 Master Domain Assignment Controller (XRDC2_MDAC).
 * @{
 */

/*!
 * @brief Gets the default master domain assignment.
 *
 * This function sets the assignment as follows:
 *
 * @code
 *  config->lock = false;
 *  config->privilegeAttr = kXRDC2_MasterPrivilege;
 *  config->secureAttr = kXRDC2_MasterSecure;
 *  config->domainId = 0U;
 *  config->mask = 0U;
 *  config->match = 0U;
 * @endcode
 *
 * @param assignment Pointer to the assignment structure.
 */
void XRDC2_GetDefaultMasterDomainAssignment(xrdc2_master_domain_assignment_t *assignment);

/*!
 * @brief Sets the processor bus master domain assignment.
 *
 * @param base XRDC2 peripheral base address.
 * @param master Which master to configure.
 * @param assignIndex Which assignment register to set.
 * @param assignment Pointer to the assignment structure.
 */
void XRDC2_SetMasterDomainAssignment(XRDC2_Type *base,
                                     xrdc2_master_t master,
                                     uint8_t assignIndex,
                                     const xrdc2_master_domain_assignment_t *assignment);

/*!
 * @brief Locks the bus master domain assignment register.
 *
 * This function locks the master domain assignment. One bus master might have
 * multiple domain assignment registers. The parameter \p assignIndex specifies
 * which assignment register to lock. After it is locked, the register can't be changed
 * until next reset.
 *
 * @param base XRDC2 peripheral base address.
 * @param master Which master to configure.
 * @param assignIndex Which assignment register to lock.
 */
static inline void XRDC2_LockMasterDomainAssignment(XRDC2_Type *base, xrdc2_master_t master, uint8_t assignIndex)
{
    base->MDACI_MDAJ[master][assignIndex].MDAC_MDA_W1 |= XRDC2_MDAC_MDA_W1_DL_MASK;
}

/*!
 * @brief Sets the master domain assignment as valid or invalid.
 *
 * This function sets the master domain assignment as valid or invalid. One bus master might have
 * multiple domain assignment registers. The parameter \p assignIndex specifies
 * which assignment register to configure.
 *
 * @param base XRDC2 peripheral base address.
 * @param master Which master to configure.
 * @param assignIndex Index for the domain assignment register.
 * @param valid True to set valid, false to set invalid.
 */
static inline void XRDC2_SetMasterDomainAssignmentValid(XRDC2_Type *base,
                                                        xrdc2_master_t master,
                                                        uint8_t assignIndex,
                                                        bool valid)
{
    if (valid)
    {
        base->MDACI_MDAJ[master][assignIndex].MDAC_MDA_W1 |= XRDC2_MDAC_MDA_W1_VLD_MASK;
    }
    else
    {
        base->MDACI_MDAJ[master][assignIndex].MDAC_MDA_W1 &= ~XRDC2_MDAC_MDA_W1_VLD_MASK;
    }
}

/*@}*/

/*!
 * @name XRDC2 Memory Slot Access Controller (XRDC2_MSC).
 * @{
 */

/*!
 * @brief Gets the default memory slot access configuration.
 *
 * This function sets the assignment as follows:
 *
 * @code
 *  config->lockMode = kXRDC2_AccessConfigLockDisabled;
 *  config->policy[0] = kXRDC2_AccessPolicyNone;
 *  config->policy[1] = kXRDC2_AccessPolicyNone;
 *  ...
 * @endcode
 *
 * @param config Pointer to the configuration.
 */
void XRDC2_GetMemSlotAccessDefaultConfig(xrdc2_mem_slot_access_config_t *config);

/*!
 * @brief Sets the memory slot access policy.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot Which memory slot descriptor to set.
 * @param config Pointer to the access policy configuration structure.
 */
void XRDC2_SetMemSlotAccessConfig(XRDC2_Type *base,
                                  xrdc2_mem_slot_t memSlot,
                                  const xrdc2_mem_slot_access_config_t *config);

/*!
 * @brief Sets the memory slot descriptor as valid or invalid.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot Which memory slot descriptor to set.
 * @param valid True to set valid, false to set invalid.
 */
void XRDC2_SetMemSlotAccessValid(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, bool valid);

/*!
 * @brief Sets the memory slot descriptor lock mode.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot Which memory slot descriptor to set.
 * @param lockMode The lock mode to set.
 */
void XRDC2_SetMemSlotAccessLockMode(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, xrdc2_access_config_lock_t lockMode);

/*!
 * @brief Sets the memory slot access policy for specific domain.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot The memory slot to operate.
 * @param domainId The ID of the domain whose policy will be changed.
 * @param policy The access policy to set.
 */
void XRDC2_SetMemSlotDomainAccessPolicy(XRDC2_Type *base,
                                        xrdc2_mem_slot_t memSlot,
                                        uint8_t domainId,
                                        xrdc2_access_policy_t policy);

/*!
 * @brief Enable or disable the memory slot exclusive access lock.
 *
 * The lock must be enabled first before use. Once disabled, it could not be
 * enabled until reset.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot The memory slot to operate.
 * @param enable True to enable, false to disable.
 */
void XRDC2_EnableMemSlotExclAccessLock(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, bool enable);

/*!
 * @brief Get current memory slot exclusive access lock owner.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot The memory slot to operate.
 * @return The domain ID of the lock owner.
 */
uint8_t XRDC2_GetMemSlotExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_mem_slot_t memSlot);

/*!
 * @brief Try to lock the memory slot exclusive access.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot The memory slot to operate.
 * @retval kStatus_Fail Failed to lock.
 * @retval kStatus_Success Locked succussfully.
 */
status_t XRDC2_TryLockMemSlotExclAccess(XRDC2_Type *base, xrdc2_mem_slot_t memSlot);

/*!
 * @brief Lock the memory slot exclusive access using blocking method.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot The memory slot to operate.
 *
 * @note This function must be called when the lock is not disabled.
 */
void XRDC2_LockMemSlotExclAccess(XRDC2_Type *base, xrdc2_mem_slot_t memSlot);

/*!
 * @brief Unlock the memory slot exclusive access.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot The memory slot to operate.
 *
 * @note This function must be called by the lock owner.
 */
static inline void XRDC2_UnlockMemSlotExclAccess(XRDC2_Type *base, xrdc2_mem_slot_t memSlot)
{
    base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = XRDC2_EAL_UNLOCKED;
}

/*!
 * @brief Force the memory slot exclusive access lock release.
 *
 * The master does not own the lock could call this function to force release the lock.
 *
 * @param base XRDC2 peripheral base address.
 * @param memSlot The memory slot to operate.
 */
static inline void XRDC2_ForceMemSlotExclAccessLockRelease(XRDC2_Type *base, xrdc2_mem_slot_t memSlot)
{
    base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = XRDC2_EAL_FORCE_RELEASE_MAGIC_0;
    base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = XRDC2_EAL_FORCE_RELEASE_MAGIC_1;
}

/*@}*/

/*!
 * @name XRDC2 Memory Region Controller (XRDC2_MRC)
 * @{
 */

/*!
 * @brief Gets the default memory access configuration.
 *
 * This function sets the assignment as follows:
 *
 * @code
 *  config->startAddr = 0U;
 *  config->endAddr = 0xFFFFFFFFU;
 *  config->lockMode = kXRDC2_AccessConfigLockDisabled;
 *  config->policy[0] = kXRDC2_AccessPolicyNone;
 *  config->policy[1] = kXRDC2_AccessPolicyNone;
 *  ...
 * @endcode
 *
 * @param config Pointer to the configuration.
 */
void XRDC2_GetMemAccessDefaultConfig(xrdc2_mem_access_config_t *config);

/*!
 * @brief Sets the memory region access policy.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem Which memory region descriptor to set.
 * @param config Pointer to the access policy configuration structure.
 */
void XRDC2_SetMemAccessConfig(XRDC2_Type *base, xrdc2_mem_t mem, const xrdc2_mem_access_config_t *config);

/*!
 * @brief Sets the memory region descriptor as valid or invalid.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem Which memory region descriptor to set.
 * @param valid True to set valid, false to set invalid.
 */
void XRDC2_SetMemAccessValid(XRDC2_Type *base, xrdc2_mem_t mem, bool valid);

/*!
 * @brief Sets the memory descriptor lock mode.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem Which memory descriptor to set.
 * @param lockMode The lock mode to set.
 */
void XRDC2_SetMemAccessLockMode(XRDC2_Type *base, xrdc2_mem_t mem, xrdc2_access_config_lock_t lockMode);

/*!
 * @brief Sets the memory region access policy for specific domain.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem The memory region to operate.
 * @param domainId The ID of the domain whose policy will be changed.
 * @param policy The access policy to set.
 */
void XRDC2_SetMemDomainAccessPolicy(XRDC2_Type *base, xrdc2_mem_t mem, uint8_t domainId, xrdc2_access_policy_t policy);

/*!
 * @brief Enable or disable the memory region exclusive access lock.
 *
 * Once disabled, it could not be enabled until reset.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem The memory region to operate.
 * @param enable True to enable, false to disable.
 */
void XRDC2_EnableMemExclAccessLock(XRDC2_Type *base, xrdc2_mem_t mem, bool enable);

/*!
 * @brief Get current memory region exclusive access lock owner.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem The memory region to operate.
 * @return The domain ID of the lock owner.
 */
uint8_t XRDC2_GetMemExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_mem_t mem);

/*!
 * @brief Try to lock the memory region exclusive access.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem The memory region to operate.
 * @retval kStatus_Fail Failed to lock.
 * @retval kStatus_Success Locked succussfully.
 */
status_t XRDC2_TryLockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem);

/*!
 * @brief Lock the memory region exclusive access using blocking method.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem The memory region to operate.
 *
 * @note This function must be called when the lock is not disabled.
 */
void XRDC2_LockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem);

/*!
 * @brief Unlock the memory region exclusive access.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem The memory region to operate.
 *
 * @note This function must be called by the lock owner.
 */
void XRDC2_UnlockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem);

/*!
 * @brief Force the memory region exclusive access lock release.
 *
 * The master does not own the lock could call this function to force release the lock.
 *
 * @param base XRDC2 peripheral base address.
 * @param mem The memory region to operate.
 */
void XRDC2_ForceMemExclAccessLockRelease(XRDC2_Type *base, xrdc2_mem_t mem);

/*@}*/

/*!
 * @name XRDC2 Peripheral Access Controller (XRDC2_PAC)
 * @{
 */

/*!
 * @brief Gets the default peripheral access configuration.
 *
 * The default configuration is set as follows:
 * @code
 * config->lockMode          = kXRDC2_AccessConfigLockWritable;
 * config->policy[0]         = kXRDC2_AccessPolicyNone;
 * config->policy[1]         = kXRDC2_AccessPolicyNone;
 * ...
 * config->policy[15]        = kXRDC2_AccessPolicyNone;
 * @endcode
 *
 * @param config Pointer to the configuration structure.
 */
void XRDC2_GetPeriphAccessDefaultConfig(xrdc2_periph_access_config_t *config);

/*!
 * @brief Sets the peripheral access policy.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph Which peripheral descriptor to set.
 * @param config Pointer to the access policy configuration structure.
 */
void XRDC2_SetPeriphAccessConfig(XRDC2_Type *base, xrdc2_periph_t periph, const xrdc2_periph_access_config_t *config);

/*!
 * @brief Sets the peripheral descriptor as valid or invalid.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph Which peripheral descriptor to set.
 * @param valid True to set valid, false to set invalid.
 */
void XRDC2_SetPeriphAccessValid(XRDC2_Type *base, xrdc2_periph_t periph, bool valid);

/*!
 * @brief Sets the peripheral descriptor lock mode.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph Which peripheral descriptor to set.
 * @param lockMode The lock mode to set.
 */
void XRDC2_SetPeriphAccessLockMode(XRDC2_Type *base, xrdc2_periph_t periph, xrdc2_access_config_lock_t lockMode);

/*!
 * @brief Sets the peripheral access policy for specific domain.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph The peripheral to operate.
 * @param domainId The ID of the domain whose policy will be changed.
 * @param policy The access policy to set.
 */
void XRDC2_SetPeriphDomainAccessPolicy(XRDC2_Type *base,
                                       xrdc2_periph_t periph,
                                       uint8_t domainId,
                                       xrdc2_access_policy_t policy);

/*!
 * @brief Disable the peripheral exclusive access lock.
 *
 * Once disabled, it could not be enabled until reset.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph The peripheral to operate.
 * @param enable True to enable, false to disable.
 */
void XRDC2_EnablePeriphExclAccessLock(XRDC2_Type *base, xrdc2_periph_t periph, bool enable);

/*!
 * @brief Get current peripheral exclusive access lock owner.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph The peripheral to operate.
 * @return The domain ID of the lock owner.
 */
uint8_t XRDC2_GetPeriphExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_periph_t periph);

/*!
 * @brief Try to lock the peripheral exclusive access.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph The peripheral to operate.
 * @retval kStatus_Fail Failed to lock.
 * @retval kStatus_Success Locked succussfully.
 */
status_t XRDC2_TryLockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph);

/*!
 * @brief Lock the peripheral exclusive access using blocking method.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph The peripheral to operate.
 *
 * @note This function must be called when the lock is not disabled.
 */
void XRDC2_LockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph);

/*!
 * @brief Unlock the peripheral exclusive access.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph The peripheral to operate.
 *
 * @note This function must be called by the lock owner.
 */
void XRDC2_UnlockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph);

/*!
 * @brief Force the peripheral exclusive access lock release.
 *
 * The master does not own the lock could call this function to force release the lock.
 *
 * @param base XRDC2 peripheral base address.
 * @param periph The peripheral to operate.
 */
void XRDC2_ForcePeriphExclAccessLockRelease(XRDC2_Type *base, xrdc2_periph_t periph);

/*@}*/

#if defined(__cplusplus)
}
#endif

/*!
 * @}
 */

#endif /* _FSL_XRDC2_H_ */
