
#include "r_typedefs.h"
#include "dr7f701441.dvf.h"
#include "r_dev_clk_types.h"
#include "r_dev_api.h"
#include "Clock.h"
#include "GPIO.h"
#include "Watchdog.h"
#include "TYW_FLASH.h"
#include "RTC.h"
#include "rh850_macros.h"

extern uint32_t TestBackupRam;

#define CLOCK_PROTECTED_WRITE(preg, pstatus, reg, value) \
    do                                                   \
    {                                                    \
        (preg) = 0xA5U;                                  \
        (reg) = (value);                                 \
        (reg) = ~(value);                                \
        (reg) = (value);                                 \
    } while ((pstatus) == 1U)

static const r_dev_ClkGenConfig_t g_stClockGenCfg =
{
    /*mainosc*/
    {
        /* FrequencyHz */ R_DEV_MOSC_FRQ_HZ,
        /* StabiTimeNs */ 400000UL,
        /* Gain        */ 3U,
        /* Running     */ 1U,
        /* StpReqMsk   */ 1U,
    },

    /*subosc*/
    {
        /* FrequencyHz */ 32768UL,
        /* Running     */ 0U,
        /* StpReqMsk   */ 0U,
    },

    /* PLL */
    {
        /*PLL0*/
        {
            /* Mode        */ R_DEV_PLL_SSCG,
            /* DithMode    */ R_DEV_PLL_DITH_DOWN,
            /* DithRange   */ 3U,
            /* ModFreq     */ 50UL,
            /* FrequencyHz */ 480UL * 1000UL * 1000UL,
            /* StabiTimeNs */ 40000UL,
            /* StpReqMsk   */ 0U,
        },

        /*PLL1*/
        {
            /* Mode        */ R_DEV_PLL_ON,
            /* DithMode    */ R_DEV_PLL_DITH_FIXED,
            /* DithRange   */ 0U,
            /* ModFreq     */ 0UL,
            /* FrequencyHz */ 480UL * 1000UL * 1000UL,
            /* StabiTimeNs */ 40000UL,
            /* StpReqMsk   */ 0U,
        },

        /*PLL2*/
        {
            /* Mode        */ R_DEV_PLL_OFF,
            /* DithMode    */ R_DEV_PLL_DITH_FIXED,
            /* DithRange   */ 0U,
            /* ModFreq     */ 0UL,
            /* FrequencyHz */ 0UL,
            /* StabiTimeNs */ 0UL,
            /* StpReqMsk   */ 0U,
        },
    },

    /* ROSC */
    /* RoscStpReqMsk */ 1U,

    /* BusEnable */
    {
        /* R_DEV_CLK_PLL0    */ 1U,
        /* R_DEV_CLK_PLL1    */ 1U,
        /* R_DEV_CLK_PLL2    */ 0U,
        /* R_DEV_CLK_PLL0PIX */ 1U,
        /* R_DEV_CLK_SDRB    */ 1U,
        /* R_DEV_CLK_ETNBP   */ 1U,
        /* R_DEV_CLK_MLBP    */ 1U,
        /* R_DEV_CLK_RSCANP  */ 1U,
        /* R_DEV_CLK_XCC     */ 1U,
        /* R_DEV_CLK_ETNBXCC */ 1U,
        /* R_DEV_CLK_MLBXCC  */ 1U,
    },
};

static const r_dev_ClkSelConfig_t g_stClkSelectionCfg[] =
    /*   Cks                   SrcId                Div  StpReqMsk      */
{
    /* {R_DEV_CKS_RSCAN, R_DEV_CKS_SRC_PLLFIX, } */
    {R_DEV_CKS_RSCANXIN, R_DEV_CKS_SRC_MOSC, 1, 0u},
    {R_DEV_CKS_WDT0, R_DEV_CKS_SRC_LRNG, 256, 0u},
    {R_DEV_CKS_RTC, R_DEV_CKS_SRC_MOSC, 2, 0u},
    {R_DEV_CKS_OSTM, R_DEV_CKS_SRC_MOSC, 2, 0u},
    {R_DEV_CKS_CLKJIT, R_DEV_CKS_SRC_DIV, 6, 0u},
    {R_DEV_CKS_PLLFIX, R_DEV_CKS_SRC_PLL1, 1, 0u},
    {R_DEV_CKS_CLKFIX, R_DEV_CKS_SRC_DIV, 6, 0u},
    {R_DEV_CKS_CPU, R_DEV_CKS_SRC_PLL0, 2, 0u},
    {R_DEV_CKS_SFMA, R_DEV_CKS_SRC_PLL0, 3, 0u},
    {R_DEV_CKS_SSIF, R_DEV_CKS_SRC_PLLFIX, 156, 0u},
    {R_DEV_CKS_RLIN, R_DEV_CKS_SRC_PLLFIX_10, 0, 0u},

    /* delimiter - do not remove */
    {R_DEV_CKS_LAST, R_DEV_CKS_SRC_MOSC, 2, 0u},
};

void Clock_Pre_Init(void)
{
    /* use the config, call Clock Gen Init */
    R_DEV_ClkGenInit((r_dev_ClkGenConfig_t *)(&g_stClockGenCfg), g_stClkSelectionCfg);

    /* use the config, store settings (needs to be repeated after low init */
    R_DEV_ClkGenInitStore((r_dev_ClkGenConfig_t *)(&g_stClockGenCfg));
}

void Clock_Init(void)
{
    /* use the config, store settings */
    R_DEV_ClkGenInitStore((r_dev_ClkGenConfig_t *)(&g_stClockGenCfg));
}

/*Clock monitor initialization*/
static void Clock_Monitor_A_Init(void)
{
    /*only open monitor2 ，Monitor main clock*/
    CLMA2CMPH = 652U; /*+-10%*/

    CLMA2CMPL = 435U; /*+-10%*/

    CLOCK_PROTECTED_WRITE(CLMA2PCMD, CLMA2PS, CLMA2CTL0, 0x01U);
}

/*Stop all of the modules before Call the following function,except RTC*/
/*falling edge detection*/
void Clock_Enter_Sleep_Mode(void)
{
    /*Stop  modules*/
    /*port buffer  into hold state*/
    /*Disable  interrupt*/
    /*Clear the interrupt flag*/
    /*config interrupt , mask or unmask*/
    /*Clear  wake-up  flag*/
    /*Config wake-up factors*/
    /*You can choose more than one PIN*/
    /*(Except in D1M1A and D1M1-V2) ,Change CPU clock to EMCLK*/
    CLOCK_PROTECTED_WRITE(SYSPROTCMD1, SYSPROTS1, SYSCKSC_ICPUCLKS_CTL, 0x01U); /*select EMCLK*/

    /*Config clock domains . It's already set up in the initialization function  */
    /*MainOsc continues operation in DEEPSTOP mode*/
    SYSMOSCSTPM = 0x03U;
    /*High Speed IntOsc stops operation in DEEPSTOP mode.*/
    // SYSROSCSTPM = 0x02U;
    R_DEV_SetGenStopMask(R_DEV_HS_RING, 0U);
    /*Clock domain C_AWO_AWOT is stopped in DEEPSTOP mode*/
    SYSCKSC_AAWOTD_STPM = 0x02U;
    /*Clock domain C_AWO_RTCA is not stopped in DEEPSTOP mode*/
    SYSCKSC_ARTCAD_STPM = 0X03U;
    /*Clock domain C_AWO_FOUT is stopped in DEEPSTOP mode*/
    SYSCKSC_AFOUTS_STPM = 0X02U;

    /*Stop all active PLLs*/
    // CLOCK_PROTECTED_WRITE(SYSPROTCMD1, SYSPROTS1, SYSPLL0E, 0x02U); /*Stop the PLL0*/
    // CLOCK_PROTECTED_WRITE(SYSPROTCMD1, SYSPROTS1, SYSPLL1E, 0x02U); /*Stop the PLL1*/
    R_DEV_ClkGenStop(R_DEV_PLL0);
    R_DEV_ClkGenStop(R_DEV_PLL1);
    /*Clear the RESF register*/
    /*start DEEPSTOP mode*/
    /*wait for the transition to the DEEPSTOP mode by the unconditional loop*/
}
#pragma ghs section bss = ".absinitarea"

uint32_t u32ResetFlag;
uint32_t u32ResetSource;
#pragma ghs section bss = default

Clock_Startup_Mode_en_t Clock_Get_Startup_Mode(void)
{
    Clock_Startup_Mode_en_t enClockMode;

    uint32_t u32ResetRESFValue = 0U;
    uint32_t u32ResetRESFRValue = 0U;

    /* Read reset factor */
    u32ResetRESFValue = SYSRESF;
    u32ResetRESFRValue = SYSRESFR;

    u32ResetSource = SYSRESF;

    /* Clear reset factor */
    SYSRESFC = 0xC70FU;
    SYSRESFCR = 0xC70FU;

    if (u32ResetRESFValue & 0x0000C30FU)
    {
        enClockMode = CLOCK_STARTUP_PWR_ON;
    }
    else
    {
        enClockMode = CLOCK_STARTUP_WAKE_UP;
    }

    return enClockMode;
}

void Sys_Enter_Sleep_Mode(void)
{
    WDT_Clear();
    CLOCK_PROTECTED_WRITE(SYSPROTCMD0, SYSPROTS0, SYSCKSC_AWDTA0D_CTL, 0x06U); /*  看门狗时钟2048分频*/

    GPIO_Init(GPIO_SLEEP_MODE);

    __DI();
    SYSWUFC0 = 0x7FFFFU;
    /*---------------------------------------------*/
    GPIO_Wakeup_PIN_Set(GPIO_WAKEUP_PIN_P0_5, GPIO_WAKEUP_FALLING_EDGE); /*CAN唤醒*/
    GPIO_Wakeup_PIN_Set(GPIO_WAKEUP_PIN_P0_0, GPIO_WAKEUP_HIGH_LEVEL);   /*15电唤醒*/
    GPIO_Wakeup_PIN_Set(GPIO_WAKEUP_PIN_P0_7, GPIO_WAKEUP_HIGH_LEVEL);   /*硬线唤醒*/
    /*----------------------------------------------*/
    SYSWUFMSK0 &= 0x7FFFEU;

    Clock_Enter_Sleep_Mode();

    SYSRESFC = 0xC70FU;

    CLOCK_PROTECTED_WRITE(SYSPROTCMD0, SYSPROTS0, SYSSTBC0PSC, 0x02U);

    RTC_Backup_Time();
    TestBackupRam = 0xaabbccddu;
    hardware_reset();
}
