/**
  ******************************************************************************
 *
 * @file        Sample_CSC_Init.c
 *
 * @brief       CSC set CK_HS/ CK_LS/ Divider/ PLL/ ICKO/ Module Clock Enable sample code.
 *
 * @par         Project
 *              MG32
 * @version     V1.01
 * @date        2024/03/04
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2018 Megawin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************
 * @par         Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "MG32_DRV.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void Sample_CSC_Init(void);
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/

/**
 *******************************************************************************
 * @brief       Sample CSC_Init
 * @details     1.  CSC module protect disable
 *      \n      2.  Wait CK_LS clock mux changed complete
 *      \n      3.  CK_HS clock source select.
 *      \n      4.  IHRCO configurate
 *      \n      5.  Wait IHRCO ready check
 *      \n      6.  Select IHRCO clock source
 *      \n      7.  IHRCO configurate
 *      \n      8.  Wait IHRCO ready
 *      \n      9.  CK_HS clock source select
 *      \n      10. Wait CK_HS clock mux changed complete
 *      \n      11. CK_HS2 clock source select
 *      \n      12. Wait CK_HS2 clock mux changed complete
 *      \n      13. CK_LS clock source select
 *      \n      14. Wait CK_LS clock mux changed complete
 *      \n      15. CK_PLL module initial
 *      \n      16. PLL Module Enable
 *      \n      17. Wait PLL Ready
 *      \n      18. CK_MAIN clock source select
 *      \n      19. CK_MAIN clock mux changed complete check
 *      \n      20. CK_APB clock divider select
 *      \n      21. CK_AHB clock divider select
 *      \n      22. CK_UT clock divider select
 *      \n      23. CK_ST clock source select
 *      \n      24. Module "ON MODE" clock enable
 *      \n      25. Module "SLEEP MODE" clock enable
 *      \n      26. Module "STOP MODE" clock enable
 *      \n      27. ICKO Configure
 *      \n      28. PC0 output ICKO configure
 * @return	    None
 * @note        
 * @par         Example
 * @code
    Sample_CSC_Init();
 * @endcode
 *******************************************************************************
 */
void Sample_CSC_Init(void)
{
    PIN_InitTypeDef PINX_InitStruct;
    CSC_PLL_TypeDef CSC_PLL_Init;
    
    /* 1. CSC module protect disable */
    UnProtectModuleReg(CSCprotect);
    
    /* 2. Wait CK_LS clock mux changed complete. */
    #if defined(CSC_STA_LS_STA_mask_w)
        while(CSC_GetLsSwitchState(LS_MUX_ILRCO)==DRV_Busy);        // CK_LS_SEL param: LS_MUX_XOSC/ LS_MUX_ILRCO/ LS_MUX_CK_EXT
    #else
        while((CSC_GetAllFlagStatus()&CSC_STA_ILRCOF_mask_w)!=CSC_STA_ILRCOF_happened_w);
    #endif
    
    /* 3. CK_HS clock source select.(CK_HS can select clock source from IHRCO/ XOSC/ ILRCO/ EXTCK) */
    CSC_CK_HS_Select(HS_CK_ILRCO);                      // Select CK_HS clock from IHRCO.           \
                                                        // CK_HS_SEL param: HS_CK_IHRCO/ HS_CK_XOSC/ HS_CK_ILRCO/ HS_CK_EXT
                                                        // When CK_LS select to CK_XOSC please refer to Sample_XOSC_Init.c
                                                        // When CL_LS select to EXTCK please refer to Sample_EXTCK_Init.c
    
    /* 4. IHRCO configurate. */
    CSC_IHRCO_Cmd(DISABLE);
    /* 5. Wait IHRCO ready check */
    #if defined(CSC_STA_IHRCO_STA_mask_w)
        while(CSC_GetClockSourceState(CSC_IHRCO_STA)!=DRV_Unready);             // When IHRCO_STA = 1, IHRCO module is ready.
    #else
        do
        {
            CSC_ClearFlag(CSC_IHRCOF);
        }
        while((CSC_GetAllFlagStatus()&CSC_STA_IHRCOF_mask_w)==CSC_STA_IHRCOF_happened_w);
    #endif
    
    /* 6. Select IHRCO clock source.(11.0592MHz or 12MHz) */
    CSC_IHRCO_Select(IHRCO_12MHz);                      // IHRCO_11M0592Hz: Select IHRCO clock is 11.0592MHz.
    
    /* 7. IHRCO configurate. */
    CSC_IHRCO_Cmd(ENABLE);
    
    /* 8. Wait IHRCO ready */
    #if defined(CSC_STA_IHRCO_STA_mask_w)
        while(CSC_GetClockSourceState(CSC_IHRCO_STA)==DRV_Unready);             // When IHRCO_STA = 1, IHRCO module is ready.
    #else
        while((CSC_GetAllFlagStatus()&CSC_STA_IHRCOF_mask_w)!=CSC_STA_IHRCOF_happened_w);
    #endif
    
    /* 9. CK_HS clock source select.(CK_HS can select clock source from IHRCO/ XOSC/ ILRCO/ EXTCK) */
    CSC_CK_HS_Select(HS_CK_IHRCO);                      // Select CK_HS clock from IHRCO.           \
                                                        // CK_HS_SEL param: HS_CK_IHRCO/ HS_CK_XOSC/ HS_CK_ILRCO/ HS_CK_EXT
                                                        // When CK_LS select to CK_XOSC please refer to Sample_XOSC_Init.c
                                                        // When CL_LS select to EXTCK please refer to Sample_EXTCK_Init.c
    
    /* 10. Wait CK_HS clock mux changed complete. */
    #if defined(CSC_STA_HS_STA_mask_w)
        while(CSC_GetHsSwitchState(HS_MUX_IHRCO)==DRV_Busy);
    #endif
    
    #if defined(CSC_CR0_HS2_SEL_mask_w)
        /* 11. CK_HS2 clock source select.(CK_HS2 can select clock source from IHRCO/ XOSC/ EXTCK) */
        CSC_CK_HS2_Select(HS_CK_IHRCO);                             // CK_HS2 clock source select param: HS_CK_IHRCO/ HS_CK_XOSC/ HS_CK_EXT
        
        /* 12 Wait CK_HS2 clock mux changed complete. */
        while(CSC_GetHS2SwitchState(HS_MUX_IHRCO)==DRV_Busy);       // CK_HS2_SEL param: HS_MUX_IHRCO/ HS_MUX_XOSC/ HS_MUX_CK_EXT
        
    #endif
    
    /* 13. CK_LS clock source select.(CK_LS can select clock source from XOSC/ ILRCO/ EXTCK) */
    CSC_CK_LS_Select(LS_CK_ILRCO);                      // CK_LS_SEL param: LS_CK_XOSC/ LS_CK_ILRCO/ LS_CK_EXT
                                                        // When CK_LS select to CK_XOSC please refer to Sample_XOSC_Init.c
                                                        // When CL_LS select to EXTCK please refer to Sample_EXTCK_Init.c
    
    /* 14. Wait CK_LS clock mux changed complete. */
    #if defined(CSC_STA_LS_STA_mask_w)
        while(CSC_GetLsSwitchState(LS_MUX_ILRCO)==DRV_Busy);        // CK_LS_SEL param: LS_MUX_XOSC/ LS_MUX_ILRCO/ LS_MUX_CK_EXT
    #else
        while((CSC_GetAllFlagStatus()&CSC_STA_ILRCOF_mask_w)!=CSC_STA_ILRCOF_happened_w);
    #endif
    
    /* 15. CK_PLL module initial. */
    #if !defined(CSC_PLL_PLL_MULX_mask_w)
        // For MG32F02A132/A072/A032 and MA862
        CSC_PLL_Init.InputDivider = PLLI_DIV_2;                 // PLLI divider select.
        CSC_PLL_Init.Multiplication = PLLIx16;                  // PLL multiplication select.
        CSC_PLL_Init.OutputDivider = PLLO_DIV_4;                // PLLO divider select.
        CSC_PLL_Config(&CSC_PLL_Init);
    
    #elif defined(CSC_PLL_PLL_MULX_mask_w)
        // For MG32F02A128/A064/U128/U064
        CSC_PLL_Init.InputDivider = PLLI_DIV_2;                 // PLLI divider select.
        CSC_PLL_Init.Multiplication = PLLI_CLKx16;              // PLL multiplication configure.
        CSC_PLL_Init.OutputDivider = PLLO_DIV_4;                // PLLO divider select.
        CSC_PLL_Init.PLLInputClockSelect = PLLI_SEL_HS;         // PLLI clock source select.(CK_HS/ CK_HS2)
        CSC_PLL_Config(&CSC_PLL_Init);
    #endif
    /* 16. PLL Module Enable. */
    CSC_PLL_Cmd(ENABLE);                                    // CK_PLL enable.
    
    /* 17. Wait PLL Ready. */
    #if defined(CSC_STA_PLL_STA_mask_w)
        while(CSC_GetClockSourceState(CSC_PLL_STA)==DRV_Unready);                   // When PLL_STA = 1, PLL module is ready.
    #else
        while((CSC_GetAllFlagStatus()&CSC_STA_PLLF_mask_w)!=CSC_STA_PLLF_happened_w);
        CSC_ClearFlag(CSC_PLLF);
    #endif
    
    /* 18. CK_MAIN clock source select.(CK_MAIN can select clock source from CK_HS/ CK_PLLI/ CK_PLLO) */
    CSC_CK_MAIN_Select(MAIN_CK_PLLO);                       // CK_MAIN clock param: MAIN_CK_HS/ MAIN_CK_PLLI/ MAIN_CK_PLLO
    
    /* 19. CK_MAIN clock mux changed complete check. */
    #if defined(CSC_STA_MAIN_STA_mask_w)
        while(CSC_GetMainSwitchState(MAIN_MUX_PLLO)==DRV_Busy);     // CK_MAIN_SEL param: MAIN_CK_HS/ MAIN_CK_PLLI/ MAIN_CK_PLLO
    #endif
    
    /* 20. CK_APB clock divider select. */
    CSC_CK_APB_Divider_Select(APB_DIV_1);                   // CK_APB_DIV param: APB_DIV_1/ APB_DIV_2/ APB_DIV_4/ APB_DIV_8/ APB_DIV_16
    
    /* 21. CK_AHB clock divider select. */
    CSC_CK_AHB_Divider_Select(AHB_DIV_1);                   // CK_AHB_DIV param: AHB_DIV_1/ AHB_DIV_2/ AHB_DIV_4/ AHB_DIV_8/ AHB_DIV_16 \
                                                            // AHB_DIV_32/ AHB_DIV_64/ AHB_DIV_128/ AHB_DIV_256/ AHB_DIV_512
    
    /* 22. CK_UT clock divider select. */
    CSC_CK_UT_Divider_Select(UT_DIV_8);                     // CK_UT divider select param: UT_DIV_8/ UT_DIV_16/ UT_DIV_32/ UT_DIV_128
    
    /* 23. CK_ST clock source select */
    CSC_CK_ST_Select(ST_HCLK_DIV_8);                        // CK_ST clock source select param: ST_HCLK_DIV_8/ ST_CK_LS_DIV_2
                                                            // Want to change CK_ST please config CPU->SYST_CSR.W[2] = 0
    /* 24. Module "ON MODE" clock enable. */
    CSC_PeriphONModeClock_Config(CSC_ON_PortC, ENABLE);
    CSC_PeriphONModeClock_Config(CSC_ON_ADC0, ENABLE);
    CSC_PeriphONModeClock_Config(CSC_ON_UART0, ENABLE);
    
    /* 25. Module "SLEEP MODE" clock enable. */
    CSC_PeriphSLEEPModeClock_Config(CSC_SLP_ADC0, ENABLE);
    CSC_PeriphSLEEPModeClock_Config(CSC_SLP_UART0, ENABLE);
    
    /* 26. Module "STOP MODE" clock enable */
    CSC_PeriphSTOPModeClock_Config(CSC_STP_RTC, ENABLE);
    
    /* 27. ICKO Configure. (ICKO output config for debug, when not use can mask this config) */
    CSC_ICKO_ClockSource_Select(ICKO_CK_MAIN);              // ICKO clock source select.    \
                                                            // ICKO param: ICKO_CK_MAIN/ ICKO_CK_AHB /ICKO_CK_APB/ ICKO_CK_HS/ ICKO_CK_LS/ ICKO_CK_XOSC
    CSC_ICKO_Divider_Select(ICKO_DIV_4);                    // ICKO output divider select.  \
                                                            // ICKO_DIV param: ICKO_DIV_1/ ICKO_DIV_2/ ICKO_DIV_4/ ICKO_DIV_8
    CSC_ICKO_Cmd(ENABLE);                                   // ICKO function enable.
    
    /* 28. PC0 output ICKO configure. (ICKO pin config when not use ICKO can mask thisconfig) */
    PINX_InitStruct.PINX_Pin                = PX_Pin_0;
    PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;
    PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Disable;
    PINX_InitStruct.PINX_Speed              = PINX_Speed_High;
    PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;
    PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;
    PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;
    PINX_InitStruct.PINX_Alternate_Function = 1;
    GPIO_PortMode_Config(IOMC,&PINX_InitStruct);
    
    ProtectModuleReg(CSCprotect);
}




