/*********************************************************
 *Copyright (C), 2015, Shanghai Eastsoft Microelectronics Co., Ltd.
 * @文件名:  lib_scu.h
 * @作  者:  AE Team
 * @版  本:  V1.01
 * @日  期:  2022/07/25
 * @描  述:  SCU模块库函数头文件
 * @note
 *          Change Logs:
 *          Date            Author          Notes
 *          25 July 2022    AE Team         change license to Apache-2.0
 *
 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
 *
 * 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
 *
 * 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.
 *
 **********************************************************************************
 */
 
#ifndef __LIBSCU_H__
#define __LIBSCU_H__

#include "FS030.h"
#include "lib_gpio.h"
#include "type.h"

/* NMI不可屏蔽中断选择 */
typedef enum
{
    SCU_NMIIRQ_PINT0    = 0,
    SCU_NMIIRQ_PINT1    = 1,
    SCU_NMIIRQ_PINT2    = 2,
    SCU_NMIIRQ_PINT3    = 3,
    SCU_NMIIRQ_PINT4    = 4,
    SCU_NMIIRQ_PINT5    = 5,
    SCU_NMIIRQ_PINT6    = 6,
    SCU_NMIIRQ_PINT7    = 7,
    SCU_NMIIRQ_T16N0    = 8,
    SCU_NMIIRQ_T16N1    = 9,
    SCU_NMIIRQ_T16N2    = 10,
    SCU_NMIIRQ_T16N3    = 11,
    SCU_NMIIRQ_T32N0    = 12,
    SCU_NMIIRQ_WWDTINT  = 15,
    SCU_NMIIRQ_IWDTINT  = 16,
    SCU_NMIIRQ_KINT     = 18,
    SCU_NMIIRQ_ADCINT   = 19,
    SCU_NMIIRQ_LVDINT   = 21,
    SCU_NMIIRQ_UART0    = 23,
    SCU_NMIIRQ_UART1    = 24,
    SCU_NMIIRQ_UART2    = 25,
    SCU_NMIIRQ_SPI1INT  = 28,
    SCU_NMIIRQ_IIC0INT  = 29,
    SCU_NMIIRQ_CCMINT   = 31,
} SCU_TYPE_NMICS;

/* PWRC复位状态寄存器标志位 */
typedef enum
{
    SCU_PWRC_PORF     = (1 << 0),       /* POR总复位标志 */
    SCU_PWRC_PORRCF   = (1 << 1),       /* PORRC复位标志 */
    SCU_PWRC_PORRSTF  = (1 << 2),       /* PORRST复位标志 */
    SCU_PWRC_BORF     = (1 << 3),       /* BOR复位标志 */
    SCU_PWRC_WDTRSTF  = (1 << 4),       /* WDT复位标志 */
    SCU_PWRC_MRSTF    = (1 << 5),       /* MRSTn丢失标志位 */
    SCU_PWRC_SOFTRSTF = (1 << 6),       /* 软件丢失标志位 */
    SCU_PWRC_POR_LOST = (1 << 7),       /* POR丢失标志位 */
    SCU_PWRC_CFGRST   = (1 << 8),       /* 配置字读取 */
    SCU_PWRC_LKRSTF   = (1 << 9),       /* LOCKUP复位 */
} SCU_TYPE_PWRC;

/* LVD寄存器标志位 */
typedef enum
{
    SCU_LVDFlag_IF  = (1 << 8),  /* LVD中断标志 */
    SCU_LVDFlag_IE  = (1 << 9),  /* LVD中断使能标志 */
    SCU_LVDFlag_Out = (1 << 15), /* 输出状态位 */
} SCU_TYPE_LVDCON;

/* 时钟选择 */
typedef enum
{
    SCU_CLK_HRC  = 0x0,     /* HRC时钟 */
    SCU_CLK_LRC  = 0x1,     /* LRC时钟：32KHZ */
    SCU_CLK_XTAL = 0x2,     /* XTAL时钟 */
} SCU_TYPE_SYSCLK;

/* 外设时钟 */
typedef enum
{
    SCU_SUCCLK     = 0x00000001,
    SCU_GPIOCLK    = 0x00000002,
    SCU_IAPCLK     = 0x00000004,
    SCU_RESERVED0  = 0x00000008,
    SCU_ADCCLK     = 0x00000010,
    SCU_RESERVED1  = 0x00000020,
    SCU_WWDTCLK    = 0x00000040,
    SCU_IWDTCLK    = 0x00000080,
    SCU_T16N0CLK   = 0x00000100,
    SCU_T16N1CLK   = 0x00000200,
    SCU_T16N2CLK   = 0x00000400,
    SCU_T16N3CLK   = 0x00000800,
    SCU_T32N0CLK   = 0x00001000,
    SCU_RESERVED2  = 0x00002000,
    SCU_RESERVED3  = 0x00004000,
    SCU_RESERVED4  = 0x00008000,
    SCU_UART0CLK   = 0x00010000,
    SCU_UART1CLK   = 0x00020000,
    SCU_UART2CLK   = 0x00040000,
    SCU_RESERVED5  = 0x00080000,
    SCU_RESERVED6  = 0x00100000,
    SCU_RESERVED7  = 0x00200000,
    SCU_RESERVED8  = 0x00400000,
    SCU_RESERVED9  = 0x00800000,
    SCU_RESERVED10 = 0x01000000,
    SCU_SPI1CLK    = 0x02000000,
    SCU_RESERVED11 = 0x04000000,
    SCU_RESERVED12 = 0x08000000,
    SCU_I2C0CLK    = 0x10000000,
} SUC_TYPE_Periph;

/* HRC时钟输出频率旋择 */
typedef enum
{
    SCU_HRC_2M   = 0x0,    /* HRC时钟输出为2MHz */
    SCU_HRC_16M  = 0x1,    /* HRC时钟输出为16Mhz */
    SCU_HRC_32M  = 0x2,    /* HRC时钟输出为32Mhz */
    SCU_HRC_48M  = 0x3,    /* HRC时钟输出为48Mhz */
} SCU_HRC_FRE;


/************SCU模块宏定义***********/

/* SCU写保护控制 */
#define SCU_RegUnLock() (SCU->PROT.Word = 0x55AA6996)
#define SCU_RegLock()   (SCU->PROT.Word = 0x00000000)

/* NMI使能控制 */
#define SCU_NMI_Enable()    (SCU->NMICON.NMIEN = 0x1)
#define SCU_NMI_Disable()     (SCU->NMICON.NMIEN = 0x0)

/*-------LVD模块-------*/

/* LVD使能控制 */
#define SCU_LVD_Enable()    (SCU->LVDCON.EN = 0x1)
#define SCU_LVD_Disable()   (SCU->LVDCON.EN = 0x0)

/* LVD滤波使能控制 */
#define SCU_LVDFLT_Enable()     (SCU->LVDCON.FLTEN = 0x1)
#define SCU_LVDFLT_Disable()    (SCU->LVDCON.FLTEN = 0x0)

/* LVD触发电压选择 */
#define SCU_LVDVS_2V2()     (SCU->LVDCON.VS = 0x0)
#define SCU_LVDVS_2V4()     (SCU->LVDCON.VS = 0x1)
#define SCU_LVDVS_2V6()     (SCU->LVDCON.VS = 0x2)
#define SCU_LVDVS_2V8()     (SCU->LVDCON.VS = 0x3)
#define SCU_LVDVS_3V()      (SCU->LVDCON.VS = 0x4)
#define SCU_LVDVS_3V6()     (SCU->LVDCON.VS = 0x5)
#define SCU_LVDVS_4V1()     (SCU->LVDCON.VS = 0x6)
#define SCU_LVDVS_4V7()     (SCU->LVDCON.VS = 0x7)

/* LVD中断使能控制 */
#define SCU_LVDIT_Enable()  (SCU->LVDCON.IE = 0x1)
#define SCU_LVDIT_Disable() (SCU->LVDCON.IE = 0x0)

/* LVD中断标志位清除 */
#define SCU_LVDClearIFBit() (SCU->LVDCON.Word |= 0x01 << 8)

/* LVD中断产生模式选择 */
#define SCU_LVDIFS_Rise()   (SCU->LVDCON.IFS = 0x0) /* LVDO上升沿产生中断 */
#define SCU_LVDIFS_Fall()   (SCU->LVDCON.IFS = 0x1) /* LVDO下降沿产生中断 */
#define SCU_LVDIFS_High()   (SCU->LVDCON.IFS = 0x2) /* LVDO高电平产生中断 */
#define SCU_LVDIFS_Low()    (SCU->LVDCON.IFS = 0x3) /* LVDO低电平产生中断 */
#define SCU_LVDIFS_Change() (SCU->LVDCON.IFS = 0x4) /* LVDO电平变化产生中断 */
#define SCU_LVDIFS_Get()    (SCU->LVDCON.IFS)       /* 获取LVDO的值 */

/* LVD输出状态获取 */
#define SCU_LVDO_Get()      (SCU->LVDCON.LVDO)      /* 被监测电压高于电压阈值返回0 */

/* 系统唤醒时间控制 */
#define SCU_WAKEUPTIME(X)   (SCU->WAKEUPTIME.WAKEUPTIME = ((X) & 0xFFF))

/* 深度睡眠下系统时钟控制 */
#define SCU_MOSC_EN(X)      (SCU->WAKEUPTIME.MOSC_EN = ((X) & 0x1))

/* 系统时钟滤波器使能 */
#define SCU_CLKFLT_EN(X)    (SCU->WAKEUPTIME.CLKFLT_EN = ((X) & 0x1))

/* VR工作时钟控制 */
#define SCU_VROSCEN(X)      (SCU->WAKEUPTIME.VROSCEN = ((X) & 0x1))

/* 深度睡眠下SRAM低功耗使能 */
#define SCU_STPRTNEN(X)     (SCU->WAKEUPTIME.STPRTNEN = ((X) & 0x1))

/* 深度睡眠下LDO电压输出 */
#define SCU_LDOLP_VOSEL(X)  (SCU->WAKEUPTIME.LDOLP_VOSEL = ((X) & 0x11))

/* 深度睡眠下LDO低功耗使能 */
#define SCU_LP_STOP(X)      (SCU->WAKEUPTIME.LP_STOP = ((X) & 0x1))

/* 深度睡眠下BG低功耗使能 */
#define SCU_BG_STOP(X)      (SCU->WAKEUPTIME.BG_STOP = ((X) & 0x1))

/* 深度睡眠下FLASH STOP使能 */
#define SCU_FLS_STOP(X)     (SCU->WAKEUPTIME.FLS_STOP = ((X) & 0x1))

/* FLASH访问等待时间选择 */
#define SCU_FlashWait_1Tclk()   (SCU->FLASHWAIT.ACCT = 0x0)
#define SCU_FlashWait_2Tclk()   (SCU->FLASHWAIT.ACCT = 0x1)
#define SCU_FlashWait_3Tclk()   (SCU->FLASHWAIT.ACCT = 0x2)
#define SCU_FlashWait_4Tclk()   (SCU->FLASHWAIT.ACCT = 0x3)
#define SCU_FlashWait_5Tclk()   (SCU->FLASHWAIT.ACCT = 0x4)
#define SCU_FlashWait_6Tclk()   (SCU->FLASHWAIT.ACCT = 0x5)
#define SCU_FlashWait_7Tclk()   (SCU->FLASHWAIT.ACCT = 0x6)
#define SCU_FlashWait_8Tclk()   (SCU->FLASHWAIT.ACCT = 0x7)
#define SCU_FlashWait_9Tclk()   (SCU->FLASHWAIT.ACCT = 0x8)
#define SCU_FlashWait_10Tclk()  (SCU->FLASHWAIT.ACCT = 0x9)
#define SCU_FlashWait_11Tclk()  (SCU->FLASHWAIT.ACCT = 0xA)
#define SCU_FlashWait_12Tclk()  (SCU->FLASHWAIT.ACCT = 0xB)
#define SCU_FlashWait_13Tclk()  (SCU->FLASHWAIT.ACCT = 0xC)
#define SCU_FlashWait_14Tclk()  (SCU->FLASHWAIT.ACCT = 0xD)
#define SCU_FlashWait_15Tclk()  (SCU->FLASHWAIT.ACCT = 0xE)
#define SCU_FlashWait_16Tclk()  (SCU->FLASHWAIT.ACCT = 0xF)

/* 系统时钟后分频选择 */
#define SCU_SysClk_Div1()   (SCU->SCLKEN0.SYSCLK_DIV = 0)
#define SCU_SysClk_Div2()   (SCU->SCLKEN0.SYSCLK_DIV = 1)
#define SCU_SysClk_Div4()   (SCU->SCLKEN0.SYSCLK_DIV = 2)
#define SCU_SysClk_Div8()   (SCU->SCLKEN0.SYSCLK_DIV = 3)
#define SCU_SysClk_Div16()  (SCU->SCLKEN0.SYSCLK_DIV = 4)
#define SCU_SysClk_Div32()  (SCU->SCLKEN0.SYSCLK_DIV = 5)
#define SCU_SysClk_Div64()  (SCU->SCLKEN0.SYSCLK_DIV = 6)
#define SCU_SysClk_Div128() (SCU->SCLKEN0.SYSCLK_DIV = 7)

/* 外部时钟低功耗模式 */
#define SCU_XTAL_LP_Enable()    (SCU->SCLKEN0.XTAL_LP = 0)
#define SCU_XTAL_LP_Disable()   (SCU->SCLKEN0.XTAL_LP = 1)

/* 中断向量表重映射使能控制 */
#define SCU_TBLRemap_Enable()   (SCU->TBLREMAPEN.EN= 1)
#define SCU_TBLRemap_Disable()  (SCU->TBLREMAPEN.EN= 0)

/* 中断向量表偏移寄存器 x最大为2^24=16777216 */
#define SCU_TBL_Offset(x)   (SCU->TBLOFF.TBLOFF = (uint32_t)x)

/************SCU模块函数声明***********/
void SCU_NMISelect(SCU_TYPE_NMICS NMI_Type);
FlagStatus SCU_GetPWRCFlagStatus(SCU_TYPE_PWRC PWRC_Flag);
void SCU_ClearPWRCFlagBit(SCU_TYPE_PWRC PWRC_Flag);
void SCU_OpenXTAL(void);
FlagStatus SCU_GetLVDFlagStatus(SCU_TYPE_LVDCON LVD_Flag);
void SCU_SysClkSelect(SCU_TYPE_SYSCLK Sysclk);
SCU_TYPE_SYSCLK SCU_GetSysClk(void);
void DeviceClockAllEnable(void);
void DeviceClockAllDisable(void);
void DeviceClockAllEnableButIAP(void);
void DeviceClock_Config(SUC_TYPE_Periph tppe_periph, TYPE_FUNCEN NewState);
void HRC_Config(TYPE_FUNCEN hrc_en, SCU_HRC_FRE hrc_fre, TYPE_FUNCEN sys_hrc);
void SCU_MultTimerEnable(SCU_TIMEREN_Typedef SCU_TimerMask);
void SCU_MultTimerDisable(SCU_TIMERDIS_Typedef SCU_TimerMask);

#endif

/*************************END OF FILE**********************/
