/*
 * 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 _SCG1_REG_H_
#define _SCG1_REG_H_

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

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

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

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

/* CKSRC Bit Fields */
#define SCG1_CKSRC_SYS_DIV_MASK  (0x0Fu)
#define SCG1_CKSRC_SYS_DIV_SHIFT (0u)
#define SCG1_CKSRC_SYS_DIV_WIDTH (4u)

/* CPU_MODE Bit Fields */
#define SCG1_CPU_MODE_RET_MASK   (0x01u)
#define SCG1_CPU_MODE_RET_SHIFT  (0u)
#define SCG1_CPU_MODE_RET_WIDTH  (1u)

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

/*! \brief The definition of SCG1 registers
 */
typedef struct _Scg1RegType_
{
    volatile uint32_t CKSRC;    /*!< clock source selection register, offset: 0x0 */
    volatile uint32_t CPU_MODE; /*!< CPU mode register, offset: 0x4 */
} Scg1RegType;

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

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

/*! \brief Gets the system clock divide control
 *
 * This function gets the current system clock divide control.
 * rstn_apor domain
 *
 * \param[in] obj : pointer to SCG1 register instance
 * \return system clock divide control
 *         - 0h : divide by 1
 *         - 1h : divide by 2
 *         - 2h : divide by 3
 *         - 3h : divide by 4
 *            .
 *            .
 *            .
 *         - Fh : divide by 16
 */
__attribute__((always_inline)) static inline uint8_t Scg1Reg_GetCkSrcSysDiv(const Scg1RegType *obj)
{
    return ((obj->CKSRC & SCG1_CKSRC_SYS_DIV_MASK) >> SCG1_CKSRC_SYS_DIV_SHIFT);
}

/*! \brief Sets the system clock divide control
 *
 * This function sets the system clock divide control.
 * rstn_apor domain
 *
 * \param[in] obj : pointer to SCG1 register instance
 * \param[in] value : the value of system clock divide control
 *                    - 0h : divide by 1
 *                    - 1h : divide by 2
 *                    - 2h : divide by 3
 *                    - 3h : divide by 4
 *                       .
 *                       .
 *                       .
 *                    - Fh : divide by 16
 */
__attribute__((always_inline)) static inline void Scg1Reg_SetCkSrcSysDiv(Scg1RegType *obj, uint8_t value)
{
    uint32_t tmp = obj->CKSRC;

    tmp &= ~SCG1_CKSRC_SYS_DIV_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << SCG1_CKSRC_SYS_DIV_SHIFT)) & SCG1_CKSRC_SYS_DIV_MASK);
    obj->CKSRC = tmp;
}

/*! \brief Gets the cpu core work clock selection
 *
 * This function gets the current cpu core work clock selection.
 * rstn_apor domain
 *
 * \param[in] obj : pointer to SCG1 register instance
 * \return cpu core work clock selection
 *         - 0b : cpu core clock always on, delay cpu reset release;
 *         - 1b : cpu core clock gate enable, cpu reset early;
 */
__attribute__((always_inline)) static inline uint8_t Scg1Reg_GetCpuModeRet(const Scg1RegType *obj)
{
    return ((obj->CPU_MODE & SCG1_CPU_MODE_RET_MASK) >> SCG1_CPU_MODE_RET_SHIFT);
}

/*! \brief Sets the cpu core work clock selection
 *
 * This function sets the cpu core work clock selection.
 * rstn_apor domain
 *
 * \param[in] obj : pointer to SCG1 register instance
 * \param[in] value : the value of cpu core work clock selection
 *                    - 0b : cpu core clock always on, delay cpu reset release;
 *                    - 1b : cpu core clock gate enable, cpu reset early;
 */
__attribute__((always_inline)) static inline void Scg1Reg_SetCpuModeRet(Scg1RegType *obj, uint8_t value)
{
    uint32_t tmp = obj->CPU_MODE;

    tmp &= ~SCG1_CPU_MODE_RET_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << SCG1_CPU_MODE_RET_SHIFT)) & SCG1_CPU_MODE_RET_MASK);
    obj->CPU_MODE = tmp;
}

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

#endif /* _SCG1_REG_H_ */
