#include "r_typedefs.h"
#include "dr7f701401.dvf.h"
#include "GPIO.h"
#include "r_dev_clk_types.h"
#include "r_dev_api.h"
#include "Watchdog.h"
#include "rh850_macros.h"
#include "RTE_GPIO.h"
#include "Sys_Tick.h"
#include "TimerB.h"
#include "Analog_Signals.h"
#include "Rscan.h"


extern uint8_t TestBackupRam;
extern uint32_t TestBackupRam_Flag ;
#define GPIO_STB_PROTECTED_WRITE(preg, pstatus, reg, value) \
    do                                                      \
    {                                                       \
        (preg) = 0xA5U;                                     \
        (reg)  = (value);                                   \
        (reg)  = ~(value);                                  \
        (reg)  = (value);                                   \
    } while ( (pstatus) == 1U )

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

void GPIO_Init(GPIO_Config_Mode_en_t enGPIOConfigMode)
{
    if ( enGPIOConfigMode == GPIO_WAKEUP_MODE )
    {
        /*port buffer  exit hold state*/
        //  GPIO_PIN_Init(GPIO_WAKEUP_MODE);

        GPIO_STB_PROTECTED_WRITE(SYSPROTCMD0, SYSPROTS0, SYSIOHOLD, 0x00U);
    }
    else
    {
        //  GPIO_PIN_Init(GPIO_SLEEP_MODE);
		RTE_GPIO_Sleep_Init();
        /*All ports except P0 into hold state*/
        GPIO_STB_PROTECTED_WRITE(SYSPROTCMD0, SYSPROTS0, SYSIOHOLD, 0x7EU);
				//GPIO_PIN_Init(GPIO_SLEEP_MODE);
    }
}

void GPIO_Wakeup_PIN_Set(GPIO_Wakeup_PIN_en_t enGPIOWakeupPIN, GPIO_Wakeup_Trigger_Mode_en_t enGPIOTrigger)
{
    uint32_t u32GPIORegisterAddress = 0xFFC34000U + 0X4U * enGPIOWakeupPIN;
    uint32_t u32GPIORegisterValue   = ~(0x01U << enGPIOWakeupPIN);
    if ( enGPIOWakeupPIN >= GPIO_WAKEUP_PIN_P0_7 )
    {
        u32GPIORegisterAddress += 0xE0U;
    }
    else
    {
        u32GPIORegisterAddress += 0U;
    }
    /*trigger type*/
    *( uint8_t * )u32GPIORegisterAddress = enGPIOTrigger;

    /*trigger PIN*/
    SYSWUFMSK0 &= u32GPIORegisterValue;
}

/*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*/
    GPIO_STB_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 = 0x02U;
 
    R_DEV_SetGenStopMask(R_DEV_MOSC, 0U);
 
    /*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*/

    TestBackupRam_Flag=0xAABBCCDD;
}
void Sys_Enter_Sleep_Mode(void)
{    
    int i;
    WDT_Clear( );    
    GPIO_STB_PROTECTED_WRITE(SYSPROTCMD0, SYSPROTS0, SYSCKSC_AWDTA0D_CTL, 0x06U); /*  看门狗时钟2048分频*/
    Sys_Tick_Timer_Stop();
    TimerB_PWM_Channel_Sleep(1);
    TimerB_PWM_Channel_Sleep(3);
    TimerB_PWM_Channel_Sleep(5);   
    TimerB_PWM_Channel_Sleep(29);   

    Analog_Signal_Conv_Stop();    
    RSCAN0_Sleep_Init();
    GPIO_Init(GPIO_SLEEP_MODE);

    for (i = R_DEV_INT_FIRST; i < R_DEV_INT_LAST; i++)
    {  
        R_DEV_IntClearFlag(i) ;
        R_DEV_IntEnable(i, 0) ;
    }
    __DI( );
    SYSWUFC0 = 0x7FFFFU;
    /*---------------------------------------------*/
    GPIO_Wakeup_PIN_Set(GPIO_WAKEUP_PIN_P0_5, GPIO_WAKEUP_FALLING_EDGE);//BSI CAN
   // GPIO_Wakeup_PIN_Set(GPIO_WAKEUP_PIN_P0_9, GPIO_WAKEUP_FALLING_EDGE);//EV CAN
    GPIO_Wakeup_PIN_Set(GPIO_WAKEUP_PIN_P0_0, GPIO_WAKEUP_HIGH_LEVEL);//EV hardwire
    /*----------------------------------------------*/
    SYSWUFMSK0 &= 0x7FFFEU;

    Clock_Enter_Sleep_Mode( );
    

    SYSRESFC = 0xC70FU;

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

    // RTC_Backup_Time();

    hardware_reset();
}

void GPIO_Config(GPIO_Config_st_t *pstGPIOConfig)
{

    uint32_t u32GPIORegisterAddress = 0xFF610000U + 0X40U * pstGPIOConfig->enGPIOPort + 0X04U * pstGPIOConfig->enGPIOPIN;
    uint32_t u32GPIORegisterValue = 0U;
    if (pstGPIOConfig->enGPIOPort == 0U)
    {
        u32GPIORegisterAddress += 0xA000U; /*0x8000U+0X2000U*/
    }
    else
    {
        u32GPIORegisterAddress += 0X2000U;
    }

    if (pstGPIOConfig->enGPIODrive == GPIO_Drive_Fast)
    {
        u32GPIORegisterValue |= 0x1000000U; /*bit 24U PDSC*/
    }
    else
    {
        u32GPIORegisterValue &= (~0x1000000U);
    }
    if (pstGPIOConfig->enGPIOPort == GPIO_PORT_GROUP_JP0)
    {
        /*Temporary not support*/
    }
    else if (pstGPIOConfig->enGPIOPort == GPIO_PORT_GROUP_0)
    {
        if (pstGPIOConfig->enGPIOCharacter == GPIO_Char_TTL)
        {
            u32GPIORegisterValue |= 0x400000U; /*bit 22U PISA*/
        }
        else if (pstGPIOConfig->enGPIOCharacter == GPIO_Char_Schmitt4)
        {
            u32GPIORegisterValue |= 0x100000U; /*bit 20U PIS*/
        }
        else /*GPIO_Char_Schmitt1*/
        {
            u32GPIORegisterValue &= (~0x500000U);
        }
    }
    /*10 ,11,21,22*/
    else if ((pstGPIOConfig->enGPIOPort == GPIO_PORT_GROUP_21) || (pstGPIOConfig->enGPIOPort == GPIO_PORT_GROUP_22) ||
             (pstGPIOConfig->enGPIOPort == GPIO_PORT_GROUP_10) || (pstGPIOConfig->enGPIOPort == GPIO_PORT_GROUP_11))
    {
        u32GPIORegisterValue &= (~0x500000U); /*CMOS1*/
    }
    /*1,3,16,17,42,43,44,45*/
    else
    {
        if (pstGPIOConfig->enGPIOCharacter == GPIO_Char_CMOS1)
        {
            u32GPIORegisterValue |= 0x400000U; /*bit 22 PISA*/
        }
        else if (pstGPIOConfig->enGPIOCharacter == GPIO_Char_Schmitt4)
        {
            u32GPIORegisterValue |= 0x100000U; /*bit 20 PIS*/
        }
        else /*GPIO_Char_Schmitt1*/
        {
            u32GPIORegisterValue &= (~0x500000U);
        }
    }

    if (pstGPIOConfig->enGPIOPull == GPIO_PULL_UP)
    {
        u32GPIORegisterValue |= 0x80000U; /*bit 19*/
    }
    else if (pstGPIOConfig->enGPIOPull == GPIO_PULL_DOWN)
    {
        u32GPIORegisterValue |= 0x40000U; /*bit 18*/
    }
    else /*GPIO_PULL_NONE*/
    {
        u32GPIORegisterValue &= (~0xC0000U);
    }

    if (pstGPIOConfig->enGPIOOutputValue == GPIO_Level_High)
    {
        u32GPIORegisterValue |= 0x1000U; /*bit 12 Pn*/
    }
    else
    {
        u32GPIORegisterValue &= (~0x1000U);
    }

    if (pstGPIOConfig->enGPIOMode == GPIO_MODE_PORT)
    {
        u32GPIORegisterValue &= (~0x40U); /*bit 6 */
        u32GPIORegisterValue |= 0x10000U; /*bit 16 GPIO_Input_Buf_Open*/
    }
    else
    {
        /*u32GPIORegisterValue |= (0x40U);*/
        if (pstGPIOConfig->enGPIOMode == GPIO_MODE_ALTER_DIRECT)
        {
            u32GPIORegisterValue |= 0x60U; /*bit 6 5*/
        }
        else /*GPIO_MODE_ALTER_SOFTWARE*/
        {
            u32GPIORegisterValue |= 0x40U;       /*bit 6 5*/
            u32GPIORegisterValue &= (~0x10000U); /*bit 16 GPIO_Input_Buf_Close*/
        }
    }

    if (pstGPIOConfig->enGPIODir == GPIO_DIR_IN)
    {
        u32GPIORegisterValue |= 0x10U; /*bit 4 PMn*/
    }
    else
    {
        u32GPIORegisterValue &= (~0x10U);
    }
    if (pstGPIOConfig->enGPIOAltFun <= GPIO_ALTER_FUN_6)
    {
        u32GPIORegisterValue |= (pstGPIOConfig->enGPIOAltFun);
    }
    else
    {
        u32GPIORegisterValue &= (~0x07U); /*default*/
    }
    /*Port JP0 not support*/
    if (pstGPIOConfig->enGPIOPort < GPIO_PORT_GROUP_JP0)
    {
        *(uint32_t *)u32GPIORegisterAddress = u32GPIORegisterValue;
    }
    else
    {
        u32GPIORegisterValue = 0U; /*don't care*/
    }
}

