/*
 * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
 * All rights reserved.
 *
 * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
 * exclusively with CVA's microcontroller products. This file can be freely
 * distributed within development tools that are supporting such microcontroller
 * products.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 */

#ifndef _FHU_REG_H_
#define _FHU_REG_H_

/*! \brief Contains public interface to various functions related
 *         to the FHU Registers
 */

/*******************************************************************************
 * the includes
 ******************************************************************************/

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
 * the defines
 ******************************************************************************/

/* USER_KEY Bit Fields */
#define FHU_USER_KEY_USER_KEY_MASK    (0xFFFFFFFFu)
#define FHU_USER_KEY_USER_KEY_SHIFT   (0u)
#define FHU_USER_KEY_USER_KEY_WIDTH   (32u)

/* USER_LOCK Bit Fields */
#define FHU_USER_LOCK_USER_LOCK_MASK  (0x01u)
#define FHU_USER_LOCK_USER_LOCK_SHIFT (0u)
#define FHU_USER_LOCK_USER_LOCK_WIDTH (1u)

/* CHCTL Bit Fields */
#define FHU_CHCTL_CHEN_CTL_MASK       (0x1FFu)
#define FHU_CHCTL_CHEN_CTL_SHIFT      (0u)
#define FHU_CHCTL_CHEN_CTL_WIDTH      (9u)

/* RSTCTL Bit Fields */
#define FHU_RSTCTL_RST_CTL_MASK       (0x1FFu)
#define FHU_RSTCTL_RST_CTL_SHIFT      (0u)
#define FHU_RSTCTL_RST_CTL_WIDTH      (9u)

/* INTCTL Bit Fields */
#define FHU_INTCTL_INT_CTL_MASK       (0x1FFu)
#define FHU_INTCTL_INT_CTL_SHIFT      (0u)
#define FHU_INTCTL_INT_CTL_WIDTH      (9u)

/* NMICTL Bit Fields */
#define FHU_NMICTL_NMI_CTL_MASK       (0x1FFu)
#define FHU_NMICTL_NMI_CTL_SHIFT      (0u)
#define FHU_NMICTL_NMI_CTL_WIDTH      (9u)

/* CHNRCD Bit Fields */
#define FHU_CHNRCD_CHN_RCD_MASK       (0x3FFu)
#define FHU_CHNRCD_CHN_RCD_SHIFT      (0u)
#define FHU_CHNRCD_CHN_RCD_WIDTH      (10u)

/* ADRCD Bit Fields */
#define FHU_ADRCD_CHN_ADRCD_MASK      (0x1Fu)
#define FHU_ADRCD_CHN_ADRCD_SHIFT     (0u)
#define FHU_ADRCD_CHN_ADRCD_WIDTH     (5u)

/*******************************************************************************
 * the typedefs
 ******************************************************************************/

/*! \brief The definition of FHU registers
 */
typedef struct _FhuRegType_
{
    volatile uint32_t       USER_KEY;  /*!< secure key register, offset: 0x00 */
    const volatile uint32_t USER_LOCK; /*!< register lock, offset: 0x04 */
    volatile uint32_t       CHCTL;     /*!< channel enable control register, offset: 0x08 */
    volatile uint32_t       RSTCTL;    /*!< channel reset control register, offset: 0x0C */
    volatile uint32_t       INTCTL;    /*!< channel interrupt control register, offset: 0x10 */
    volatile uint32_t       NMICTL;    /*!< channel NMI control register, offset: 0x14 */
    volatile uint32_t       CHNRCD;    /*!< fault channel record register, offset: 0x18 */
    const volatile uint32_t ADRCD;     /*!< AD fault channel record register, offset: 0x1C */
} FhuRegType;

/*******************************************************************************
 * the globals
 ******************************************************************************/

/*******************************************************************************
 * the function prototypes
 ******************************************************************************/

/*! \brief Sets the configure secure key
 *
 * This function sets the configure secure key.
 *
 * \param[in] obj : pointer to FHU register instance
 * \param[in] value : the value of configure secure key
 *                    - 0x97D356BA : key match
 *                    - others : key mismatch
 */
__attribute__((always_inline)) static inline void FhuReg_SetUserKey(FhuRegType *obj, uint32_t value)
{
    uint32_t tmp = obj->USER_KEY;

    tmp &= ~FHU_USER_KEY_USER_KEY_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_USER_KEY_USER_KEY_SHIFT)) & FHU_USER_KEY_USER_KEY_MASK);
    obj->USER_KEY = tmp;
}

/*! \brief Gets the configure register lock flag
 *
 * This function gets the current configure register lock flag.
 * register lock flag;
 *
 * \param[in] obj : pointer to FHU register instance
 * \return configure register lock flag
 *         - 0b : unlock
 *         - 1b : lock
 */
__attribute__((always_inline)) static inline uint8_t FhuReg_GetUserLock(const FhuRegType *obj)
{
    return ((obj->USER_LOCK & FHU_USER_LOCK_USER_LOCK_MASK) >> FHU_USER_LOCK_USER_LOCK_SHIFT);
}

/*! \brief Gets the configure fault channel enable
 *
 * This function gets the current configure fault channel enable.
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * For each bit:
 * - 0b: disable
 * - 1b: enabl
 *
 * \param[in] obj : pointer to FHU register instance
 * \return configure fault channel enable
 */
__attribute__((always_inline)) static inline uint16_t FhuReg_GetChCtl(const FhuRegType *obj)
{
    return ((obj->CHCTL & FHU_CHCTL_CHEN_CTL_MASK) >> FHU_CHCTL_CHEN_CTL_SHIFT);
}

/*! \brief Sets the configure fault channel enable
 *
 * This function sets the configure fault channel enable.
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * For each bit:
 * - 0b: disable
 * - 1b: enabl
 *
 * \param[in] obj : pointer to FHU register instance
 * \param[in] value : the value of configure fault channel enable
 */
__attribute__((always_inline)) static inline void FhuReg_SetChCtl(FhuRegType *obj, uint16_t value)
{
    uint32_t tmp = obj->CHCTL;

    tmp &= ~FHU_CHCTL_CHEN_CTL_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_CHCTL_CHEN_CTL_SHIFT)) & FHU_CHCTL_CHEN_CTL_MASK);
    obj->CHCTL = tmp;
}

/*! \brief Gets the configure fault channel reset enable
 *
 * This function gets the current configure fault channel reset enable.
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * For each bit:
 * - 0b: disable system reset generation
 * - 1b: enable system reset generatio
 *
 * \param[in] obj : pointer to FHU register instance
 * \return configure fault channel reset enable
 */
__attribute__((always_inline)) static inline uint16_t FhuReg_GetRstCtl(const FhuRegType *obj)
{
    return ((obj->RSTCTL & FHU_RSTCTL_RST_CTL_MASK) >> FHU_RSTCTL_RST_CTL_SHIFT);
}

/*! \brief Sets the configure fault channel reset enable
 *
 * This function sets the configure fault channel reset enable.
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * For each bit:
 * - 0b: disable system reset generation
 * - 1b: enable system reset generatio
 *
 * \param[in] obj : pointer to FHU register instance
 * \param[in] value : the value of configure fault channel reset enable
 */
__attribute__((always_inline)) static inline void FhuReg_SetRstCtl(FhuRegType *obj, uint16_t value)
{
    uint32_t tmp = obj->RSTCTL;

    tmp &= ~FHU_RSTCTL_RST_CTL_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_RSTCTL_RST_CTL_SHIFT)) & FHU_RSTCTL_RST_CTL_MASK);
    obj->RSTCTL = tmp;
}

/*! \brief Gets the configure fault channel interrupt enable
 *
 * This function gets the current configure fault channel interrupt enable.
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * For each bit:
 * -0b: disable interrupt generation
 * -1b: enable interrupt generatio
 *
 * \param[in] obj : pointer to FHU register instance
 * \return configure fault channel interrupt enable
 */
__attribute__((always_inline)) static inline uint16_t FhuReg_GetIntCtl(const FhuRegType *obj)
{
    return ((obj->INTCTL & FHU_INTCTL_INT_CTL_MASK) >> FHU_INTCTL_INT_CTL_SHIFT);
}

/*! \brief Sets the configure fault channel interrupt enable
 *
 * This function sets the configure fault channel interrupt enable.
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * For each bit:
 * -0b: disable interrupt generation
 * -1b: enable interrupt generatio
 *
 * \param[in] obj : pointer to FHU register instance
 * \param[in] value : the value of configure fault channel interrupt enable
 */
__attribute__((always_inline)) static inline void FhuReg_SetIntCtl(FhuRegType *obj, uint16_t value)
{
    uint32_t tmp = obj->INTCTL;

    tmp &= ~FHU_INTCTL_INT_CTL_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_INTCTL_INT_CTL_SHIFT)) & FHU_INTCTL_INT_CTL_MASK);
    obj->INTCTL = tmp;
}

/*! \brief Gets the configure fault channel NMI enable
 *
 * This function gets the current configure fault channel NMI enable.
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * For each bit:
 * - 0b: disable NMI generation
 * - 1b: enable NMI generatio
 *
 * \param[in] obj : pointer to FHU register instance
 * \return configure fault channel NMI enable
 */
__attribute__((always_inline)) static inline uint16_t FhuReg_GetNmiCtl(const FhuRegType *obj)
{
    return ((obj->NMICTL & FHU_NMICTL_NMI_CTL_MASK) >> FHU_NMICTL_NMI_CTL_SHIFT);
}

/*! \brief Sets the configure fault channel NMI enable
 *
 * This function sets the configure fault channel NMI enable.
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * For each bit:
 * - 0b: disable NMI generation
 * - 1b: enable NMI generatio
 *
 * \param[in] obj : pointer to FHU register instance
 * \param[in] value : the value of configure fault channel NMI enable
 */
__attribute__((always_inline)) static inline void FhuReg_SetNmiCtl(FhuRegType *obj, uint16_t value)
{
    uint32_t tmp = obj->NMICTL;

    tmp &= ~FHU_NMICTL_NMI_CTL_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_NMICTL_NMI_CTL_SHIFT)) & FHU_NMICTL_NMI_CTL_MASK);
    obj->NMICTL = tmp;
}

/*! \brief Gets the fault channel record
 *
 * This function gets the current fault channel record.
 * record the fault channel number
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * [9]:CPU_RET_DED;
 * For each bit:
 * - 0b: not fault occurs
 * - 1b: fault has occurre
 *
 * \param[in] obj : pointer to FHU register instance
 * \return fault channel record
 */
__attribute__((always_inline)) static inline uint16_t FhuReg_GetChnRcd(const FhuRegType *obj)
{
    return ((obj->CHNRCD & FHU_CHNRCD_CHN_RCD_MASK) >> FHU_CHNRCD_CHN_RCD_SHIFT);
}

/*! \brief Sets the fault channel record
 *
 * This function sets the fault channel record.
 * record the fault channel number
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * [5]:SRAM_SEC;
 * [6]:SRAM_DED;
 * [7]:FLS_DEC;
 * [8]:FLS_DED;
 * [9]:CPU_RET_DED;
 * For each bit:
 * - 0b: not fault occurs
 * - 1b: fault has occurre
 *
 * \note Write 1 to clear for each bit.
 *
 * \param[in] obj : pointer to FHU register instance
 * \param[in] value : the value of fault channel record
 */
__attribute__((always_inline)) static inline void FhuReg_SetChnRcd(FhuRegType *obj, uint16_t value)
{
    uint32_t tmp = obj->CHNRCD;

    tmp &= ~FHU_CHNRCD_CHN_RCD_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_CHNRCD_CHN_RCD_SHIFT)) & FHU_CHNRCD_CHN_RCD_MASK);
    obj->CHNRCD = tmp;
}

/*! \brief Gets the AD fault channel record
 *
 * This function gets the current AD fault channel record.
 * record the fault channel number
 * Corresponing bit:
 * [0]:AD_LVD;
 * [1]:AD_LVW;
 * [2]:AD_FLDO_RDY;
 * [3]:AD_FLDO_LVD;
 * [4]:AD_OTP;
 * For each bit:
 * - 0b: not fault occurs
 * - 1b: fault has occurre
 *
 * \param[in] obj : pointer to FHU register instance
 * \return AD fault channel record
 */
__attribute__((always_inline)) static inline uint8_t FhuReg_GetAdRcd(const FhuRegType *obj)
{
    return ((obj->ADRCD & FHU_ADRCD_CHN_ADRCD_MASK) >> FHU_ADRCD_CHN_ADRCD_SHIFT);
}

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

#endif /* _FHU_REG_H_ */
