/*!
 * @file        system_apm32f10x.c
 *
 * @brief       CMSIS Cortex-M3 Device Peripheral Access Layer System Source File
 *
 * @version     V1.0.0
 *
 * @date        2022-11-15
 *
 * @attention
 *
 *  Copyright (C) 2022 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

/*Includes*/
#include "apm32f10x.h"

/** @addtogroup Examples
  @{
  */

/** @addtogroup I2C_EEPROM
  @{
  */

/** @defgroup I2C_EEPROM_System_Macros
  @{
*/

//#define SYSTEM_CLOCK_HSE    HSE_VALUE
//#define SYSTEM_CLOCK_24MHz  (24000000)
//#define SYSTEM_CLOCK_36MHz  (36000000)
//#define SYSTEM_CLOCK_48MHz  (48000000)
//#define SYSTEM_CLOCK_56MHz  (56000000)
#define SYSTEM_CLOCK_72MHz  (72000000)
//#define SYSTEM_CLOCK_96MHz  (96000000)

/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET     0x00

/**@} end of group I2C_EEPROM_System_Macros*/

/** @defgroup I2C_EEPROM_System_Variables
  @{
*/

#ifdef SYSTEM_CLOCK_HSE
    uint32_t SystemCoreClock         = SYSTEM_CLOCK_HSE;
#elif defined SYSTEM_CLOCK_24MHz
    uint32_t SystemCoreClock         = SYSTEM_CLOCK_24MHz;
#elif defined SYSTEM_CLOCK_36MHz
    uint32_t SystemCoreClock         = SYSTEM_CLOCK_36MHz;
#elif defined SYSTEM_CLOCK_48MHz
    uint32_t SystemCoreClock         = SYSTEM_CLOCK_48MHz;
#elif defined SYSTEM_CLOCK_56MHz
    uint32_t SystemCoreClock         = SYSTEM_CLOCK_56MHz;
#elif defined SYSTEM_CLOCK_72MHz
    uint32_t SystemCoreClock         = SYSTEM_CLOCK_72MHz;
#else
    uint32_t SystemCoreClock         = SYSTEM_CLOCK_96MHz;
#endif

/**@} end of group I2C_EEPROM_System_Variables*/

/** @defgroup I2C_EEPROM_System_Functions
  @{
*/

static void SystemClockConfig(void);

#ifdef SYSTEM_CLOCK_HSE
    static void SystemClockHSE(void);
#elif defined SYSTEM_CLOCK_24MHz
    static void SystemClock24M(void);
#elif defined SYSTEM_CLOCK_36MHz
    static void SystemClock36M(void);
#elif defined SYSTEM_CLOCK_48MHz
    static void SystemClock48M(void);
#elif defined SYSTEM_CLOCK_56MHz
    static void SystemClock56M(void);
#elif defined SYSTEM_CLOCK_72MHz
    static void SystemClock72M(void);
#elif defined SYSTEM_CLOCK_96MHz
    static void SystemClock96M(void);
#endif

/*!
 * @brief       Setup the microcontroller system
 *
 * @param       None
 *
 * @retval      None
 *
 */
void SystemInit(void)
{
    /* Set HSIEN bit */
    RCM->CTRL_B.HSIEN = BIT_SET;

#ifdef APM32F10X_CL
    RCM->CFG &= (uint32_t) 0xF0FF0000;
#else
    /* Reset SCLKSEL, AHBPSC, APB1PSC, APB2PSC, ADCPSC and MCOSEL bits */
    RCM->CFG &= (uint32_t) 0xF8FF0000;
#endif /* APM32F10X_CL */

    /* Reset HSEEN, CSSEN and PLLEN bits */
    RCM->CTRL &= (uint32_t) 0xFEF6FFFF;
    /* Reset HSEBCFG bit */
    RCM->CTRL_B.HSEBCFG = BIT_RESET;
    /* Reset PLLSRCSEL, PLLHSEPSC, PLLMULCFG and USBDIV bits */
    RCM->CFG &= (uint32_t) 0xFF80FFFF;

#ifdef APM32F10X_CL
    /* Reset PLL2ON and PLL3ON bits */
    RCM->CTRL &= (uint32_t) 0xEBFFFFFF;
    /* Disable all interrupts and clear pending bits  */
    RCM->INT = 0x00FF0000;
    /* Reset CFG2 register */
    RCM->CFG2 = 0x00000000;
#else
    /* Disable all interrupts and clear pending bits */
    RCM->INT = 0x009F0000;
#endif /* APM32F10X_CL */

    SystemClockConfig();

#ifdef VECT_TAB_SRAM
    SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
#else
    SCB->VTOR = FMC_BASE | VECT_TAB_OFFSET;
#endif
}

/*!
 * @brief       Update SystemCoreClock variable according to Clock Register Values
 *              The SystemCoreClock variable contains the core clock (HCLK)
 *
 * @param       None
 *
 * @retval      None
 *
 */
void SystemCoreClockUpdate(void)
{
#ifdef APM32F10X_CL
    uint32_t sysClock, pllMull, pllSource, pll2Mull, pllPsc1, pllPsc2;
#else
    uint32_t sysClock, pllMull, pllSource;
#endif

    /* get sys clock */
    sysClock = RCM->CFG_B.SCLKSEL;

    switch (sysClock)
    {
        /* sys clock is HSI */
        case 0:
            sysClock = HSI_VALUE;
            break;

        /* sys clock is HSE */
        case 1:
            sysClock = HSE_VALUE;
            break;

        /* sys clock is PLL */
        case 2:
#ifdef APM32F10X_CL
            /* NOTE : PLL is the same as PLL1 */
            pllSource = RCM->CFG_B.PLL1SRCSEL;
            
            /* PLL entry clock source is HSE */
            if (pllSource)
            {
                /* PLLPSC1 prescaler factor */
                pllPsc1 = (RCM->CFG2_B.PLLPSC1 + 1);

                /* PLL entry clock source is PLL2 */
                if (RCM->CFG2_B.PLLPSC1SRC)
                {
                    pll2Mull = (RCM->CFG2_B.PLL2MUL != 15) ? (RCM->CFG2_B.PLL2MUL + 2) : 20;
                    pllPsc2 = RCM->CFG2_B.PLLPSC2 + 1;
                    
                    pllSource = ((HSE_VALUE / pllPsc2) * pll2Mull) / pllPsc1;
                }
                /* PLL entry clock source is HSE */
                else
                {
                    pllSource = HSE_VALUE / pllPsc1;
                }
            }
            /* PLL entry clock source is HSI/2 */
            else
            {
                pllSource = HSI_VALUE >> 1;
            }

            pllMull = RCM->CFG_B.PLL1MULCFG;
            if (pllMull == 13)
            {
                /* For 6.5 multiplication factor */
                sysClock = pllSource * pllMull / 2;
            }
            else
            {
                sysClock = pllSource * (pllMull + 2);
            }
#else
            pllMull = RCM->CFG_B.PLL1MULCFG + 2;
            pllSource = RCM->CFG_B.PLL1SRCSEL;

            /* PLL entry clock source is HSE */
            if (pllSource == BIT_SET)
            {
                sysClock = HSE_VALUE * pllMull;

                /* HSE clock divided by 2 */
                if (pllSource == RCM->CFG_B.PLLHSEPSC)
                {
                    sysClock >>= 1;
                }
            }
            /* PLL entry clock source is HSI/2 */
            else
            {
                sysClock = (HSI_VALUE >> 1) * pllMull;
            }
#endif
            break;

        default:
            sysClock  = HSI_VALUE;
            break;
    }

    SystemCoreClock = sysClock;
}

/*!
 * @brief       Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers
 *
 * @param       None
 *
 * @retval      None
 *
 */
static void SystemClockConfig(void)
{
#ifdef SYSTEM_CLOCK_HSE
    SystemClockHSE();
#elif defined SYSTEM_CLOCK_24MHz
    SystemClock24M();
#elif defined SYSTEM_CLOCK_36MHz
    SystemClock36M();
#elif defined SYSTEM_CLOCK_48MHz
    SystemClock48M();
#elif defined SYSTEM_CLOCK_56MHz
    SystemClock56M();
#elif defined SYSTEM_CLOCK_72MHz
    SystemClock72M();
#elif defined SYSTEM_CLOCK_96MHz
    SystemClock96M();
#endif
}

#if defined SYSTEM_CLOCK_HSE
/*!
 * @brief       Selects HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers
 *
 * @param       None
 *
 * @retval      None
 *
 */
static void SystemClockHSE(void)
{
    __IO uint32_t i;

    RCM->CTRL_B.HSEEN = BIT_SET;

    for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
    {
        if (RCM->CTRL_B.HSERDYFLG)
        {
            break;
        }
    }

    if (RCM->CTRL_B.HSERDYFLG)
    {
        /* Enable Prefetch Buffer */
        FMC->CTRL1_B.PBEN = BIT_SET;

#ifdef APM32F10X_CL

        if (HSE_VALUE <= 24000000)
        {
            /* Flash 0 wait state */
            FMC->CTRL1_B.WS = 0;
        }
        else
        {
            /* Flash 1 wait state */
            FMC->CTRL1_B.WS = 1;
        }

#else
        /* Flash 0 wait state */
        FMC->CTRL1_B.WS = 0;
#endif /* APM32F10X_CL */

        /* HCLK = SYSCLK */
        RCM->CFG_B.AHBPSC = 0X00;
        /* PCLK2 = HCLK */
        RCM->CFG_B.APB2PSC = 0;
        /* PCLK1 = HCLK */
        RCM->CFG_B.APB1PSC = 0;

        /* Select HSE as system clock source */
        RCM->CFG_B.SCLKSEL = 1;

        /* Wait till HSE is used as system clock source */
        while (RCM->CFG_B.SCLKSELSTS != 0x01);
    }
}

#elif defined SYSTEM_CLOCK_24MHz
/*!
 * @brief       Sets System clock frequency to 24MHz and configure HCLK, PCLK2 and PCLK1 prescalers
 *
 * @param       None
 *
 * @retval      None
 *
 */
static void SystemClock24M(void)
{
    __IO uint32_t i;

    RCM->CTRL_B.HSEEN = BIT_SET;

    for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
    {
        if (RCM->CTRL_B.HSERDYFLG)
        {
            break;
        }
    }

    if (RCM->CTRL_B.HSERDYFLG)
    {
        /* Enable Prefetch Buffer */
        FMC->CTRL1_B.PBEN = BIT_SET;
        /* Flash 0 wait state */
        FMC->CTRL1_B.WS = 0;

        /* HCLK = SYSCLK */
        RCM->CFG_B.AHBPSC = 0X00;
        /* PCLK2 = HCLK */
        RCM->CFG_B.APB2PSC = 0;
        /* PCLK1 = HCLK */
        RCM->CFG_B.APB1PSC = 0;

#ifdef APM32F10X_CL
        /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz (HSE is 25MHz for APM32F10X_CL) */
        /* PLL configuration: PLLCLK = (PLL2 / 10) * 6 = 24 MHz */

        RCM->CFG2_B.PLLPSC2 = 4;
        RCM->CFG2_B.PLL2MUL = 0x06;

        RCM->CFG2_B.PLLPSC1SRC = 1;
        RCM->CFG2_B.PLLPSC1 = 9;

        /* Enable PLL2 */
        RCM->CTRL_B.PLL2EN = 1;
        /* Wait till PLL2 is ready */
        while (RCM->CTRL_B.PLL2RDYFLG == BIT_RESET);

        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 4;
#else
        /*  PLL configuration: PLLCLK = (HSE / 2) * 6 = 24 MHz */
        /* PLL: (HSE / 2) * 6 */
        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLLHSEPSC = 1;
        RCM->CFG_B.PLL1MULCFG = 4;
#endif /* APM32F10X_CL */

        /* Enable PLL */
        RCM->CTRL_B.PLL1EN = 1;

        /* Wait PLL Ready */
        while (RCM->CTRL_B.PLL1RDYFLG == BIT_RESET);

        /* Select PLL as system clock source */
        RCM->CFG_B.SCLKSEL = 2;

        /* Wait till PLL is used as system clock source */
        while (RCM->CFG_B.SCLKSELSTS != 0x02);
    }
}

#elif defined SYSTEM_CLOCK_36MHz
/*!
 * @brief       Sets System clock frequency to 36MHz and configure HCLK, PCLK2 and PCLK1 prescalers
 *
 * @param       None
 *
 * @retval      None
 *
 */
static void SystemClock36M(void)
{
    __IO uint32_t i;

    RCM->CTRL_B.HSEEN = BIT_SET;

    for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
    {
        if (RCM->CTRL_B.HSERDYFLG)
        {
            break;
        }
    }

    if (RCM->CTRL_B.HSERDYFLG)
    {
        /* Enable Prefetch Buffer */
        FMC->CTRL1_B.PBEN = BIT_SET;
        /* Flash 1 wait state */
        FMC->CTRL1_B.WS = 1;

        /* HCLK = SYSCLK */
        RCM->CFG_B.AHBPSC = 0X00;
        /* PCLK2 = HCLK */
        RCM->CFG_B.APB2PSC = 0;
        /* PCLK1 = HCLK */
        RCM->CFG_B.APB1PSC = 0;

#ifdef APM32F10X_CL
        /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz (HSE is 25MHz for APM32F10X_CL) */
        /* PLL configuration: PLLCLK = (PLL2 / 10) * 9 = 36 MHz */

        RCM->CFG2_B.PLLPSC2 = 4;
        RCM->CFG2_B.PLL2MUL = 0x06;

        RCM->CFG2_B.PLLPSC1SRC = 1;
        RCM->CFG2_B.PLLPSC1 = 9;

        /* Enable PLL2 */
        RCM->CTRL_B.PLL2EN = 1;
        /* Wait till PLL2 is ready */
        while (RCM->CTRL_B.PLL2RDYFLG == BIT_RESET);

        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 7;
#else
        /*  PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */
        /* PLL: (HSE / 2) * 9 */
        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLLHSEPSC = 1;
        RCM->CFG_B.PLL1MULCFG = 7;
#endif

        /* Enable PLL */
        RCM->CTRL_B.PLL1EN = 1;

        /* Wait PLL Ready */
        while (RCM->CTRL_B.PLL1RDYFLG == BIT_RESET);

        /* Select PLL as system clock source */
        RCM->CFG_B.SCLKSEL = 2;

        /* Wait till PLL is used as system clock source */
        while (RCM->CFG_B.SCLKSELSTS != 0x02);
    }
}

#elif defined SYSTEM_CLOCK_48MHz
/*!
 * @brief       Sets System clock frequency to 46MHz and configure HCLK, PCLK2 and PCLK1 prescalers
 *
 * @param       None
 *
 * @retval      None
 *
 */
static void SystemClock48M(void)
{
    __IO uint32_t i;

    RCM->CTRL_B.HSEEN = BIT_SET;

    for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
    {
        if (RCM->CTRL_B.HSERDYFLG)
        {
            break;
        }
    }

    if (RCM->CTRL_B.HSERDYFLG)
    {
        /* Enable Prefetch Buffer */
        FMC->CTRL1_B.PBEN = BIT_SET;
        /* Flash 1 wait state */
        FMC->CTRL1_B.WS = 1;

        /* HCLK = SYSCLK */
        RCM->CFG_B.AHBPSC = 0X00;
        /* PCLK2 = HCLK */
        RCM->CFG_B.APB2PSC = 0;
        /* PCLK1 = HCLK / 2 */
        RCM->CFG_B.APB1PSC = 4;

#ifdef APM32F10X_CL
        /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz (HSE is 25MHz for APM32F10X_CL) */
        /* PLL configuration: PLLCLK = (PLL2 / 5) * 6 = 48 MHz */

        RCM->CFG2_B.PLLPSC2 = 4;
        RCM->CFG2_B.PLL2MUL = 0x06;

        RCM->CFG2_B.PLLPSC1SRC = 1;
        RCM->CFG2_B.PLLPSC1 = 0x4;

        /* Enable PLL2 */
        RCM->CTRL_B.PLL2EN = 1;
        /* Wait till PLL2 is ready */
        while (RCM->CTRL_B.PLL2RDYFLG == BIT_RESET);

        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 4;
#else
        /* PLL: HSE * 6 */
        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 4;
#endif

        /* Enable PLL */
        RCM->CTRL_B.PLL1EN = 1;

        /* Wait PLL Ready */
        while (RCM->CTRL_B.PLL1RDYFLG == BIT_RESET);

        /* Select PLL as system clock source */
        RCM->CFG_B.SCLKSEL = 2;

        /* Wait till PLL is used as system clock source */
        while (RCM->CFG_B.SCLKSELSTS != 0x02);
    }
}

#elif defined SYSTEM_CLOCK_56MHz
/*!
 * @brief       Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers
 *
 * @param       None
 *
 * @retval      None
 *
 */
static void SystemClock56M(void)
{
    __IO uint32_t i;

    RCM->CTRL_B.HSEEN = BIT_SET;

    for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
    {
        if (RCM->CTRL_B.HSERDYFLG)
        {
            break;
        }
    }

    if (RCM->CTRL_B.HSERDYFLG)
    {
        /* Enable Prefetch Buffer */
        FMC->CTRL1_B.PBEN = BIT_SET;
        /* Flash 2 wait state */
        FMC->CTRL1_B.WS = 2;

        /* HCLK = SYSCLK */
        RCM->CFG_B.AHBPSC = 0X00;
        /* PCLK2 = HCLK */
        RCM->CFG_B.APB2PSC = 0;
        /* PCLK1 = HCLK / 2 */
        RCM->CFG_B.APB1PSC = 4;

#ifdef APM32F10X_CL
        /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz (HSE is 25MHz for APM32F10X_CL) */
        /* PLL configuration: PLLCLK = (PLL2 / 5) * 7 = 56 MHz */

        RCM->CFG2_B.PLLPSC2 = 4;
        RCM->CFG2_B.PLL2MUL = 0x06;

        RCM->CFG2_B.PLLPSC1SRC = 1;
        RCM->CFG2_B.PLLPSC1 = 0x4;

        /* Enable PLL2 */
        RCM->CTRL_B.PLL2EN = 1;
        /* Wait till PLL2 is ready */
        while (RCM->CTRL_B.PLL2RDYFLG == BIT_RESET);

        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 5;
#else
        /* PLL: HSE * 7 */
        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 5;
#endif

        /* Enable PLL */
        RCM->CTRL_B.PLL1EN = 1;

        /* Wait PLL Ready */
        while (RCM->CTRL_B.PLL1RDYFLG == BIT_RESET);

        /* Select PLL as system clock source */
        RCM->CFG_B.SCLKSEL = 2;

        /* Wait till PLL is used as system clock source */
        while (RCM->CFG_B.SCLKSELSTS != 0x02);
    }
}

#elif defined SYSTEM_CLOCK_72MHz
/*!
 * @brief       Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers
 *
 * @param       None
 *
 * @retval      None
 *
 */
static void SystemClock72M(void)
{
    __IO uint32_t i;

    RCM->CTRL_B.HSEEN = BIT_SET;

    for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
    {
        if (RCM->CTRL_B.HSERDYFLG)
        {
            break;
        }
    }

    if (RCM->CTRL_B.HSERDYFLG)
    {
        /* Enable Prefetch Buffer */
        FMC->CTRL1_B.PBEN = BIT_SET;
        /* Flash 2 wait state */
        FMC->CTRL1_B.WS = 2;

        /* HCLK = SYSCLK */
        RCM->CFG_B.AHBPSC = 0X00;
        /* PCLK2 = HCLK */
        RCM->CFG_B.APB2PSC = 0;
        /* PCLK1 = HCLK / 2 */
        RCM->CFG_B.APB1PSC = 4;

#ifdef APM32F10X_CL
        /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz (HSE is 25MHz for APM32F10X_CL) */
        /* PLL configuration: PLLCLK = (PLL2 / 5) * 9 = 72 MHz */

        RCM->CFG2_B.PLLPSC2 = 4;
        RCM->CFG2_B.PLL2MUL = 0x06;

        RCM->CFG2_B.PLLPSC1SRC = 1;
        RCM->CFG2_B.PLLPSC1 = 0x4;

        /* Enable PLL2 */
        RCM->CTRL_B.PLL2EN = 1;
        /* Wait till PLL2 is ready */
        while (RCM->CTRL_B.PLL2RDYFLG == BIT_RESET);

        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 7;
#else
        /* PLL: HSE * 9 */
        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 7;
#endif

        /* Enable PLL */
        RCM->CTRL_B.PLL1EN = 1;

        /* Wait PLL Ready */
        while (RCM->CTRL_B.PLL1RDYFLG == BIT_RESET);

        /* Select PLL as system clock source */
        RCM->CFG_B.SCLKSEL = 2;

        /* Wait till PLL is used as system clock source */
        while (RCM->CFG_B.SCLKSELSTS != 0x02);
    }

}

#elif defined SYSTEM_CLOCK_96MHz
/*!
 * @brief       Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers
 *
 * @param       None
 *
 * @retval      None
 *
 */
static void SystemClock96M(void)
{
    __IO uint32_t i;

    RCM->CTRL_B.HSEEN = BIT_SET;

    for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
    {
        if (RCM->CTRL_B.HSERDYFLG)
        {
            break;
        }
    }

    if (RCM->CTRL_B.HSERDYFLG)
    {
        /* Enable Prefetch Buffer */
        FMC->CTRL1_B.PBEN = BIT_SET;
        /* Flash 3 wait state */
        FMC->CTRL1_B.WS = 3;

        /* HCLK = SYSCLK */
        RCM->CFG_B.AHBPSC = 0X00;
        /* PCLK2 = HCLK */
        RCM->CFG_B.APB2PSC = 0;
        /* PCLK1 = HCLK / 2 */
        RCM->CFG_B.APB1PSC = 4;

#ifdef APM32F10X_CL
        /* PLL2 configuration: PLL2CLK = (HSE / 5) * 12 = 60 MHz (HSE is 25MHz for APM32F10X_CL) */
        /* PLL configuration: PLLCLK = (PLL2 / 5) * 8 = 96 MHz */

        RCM->CFG2_B.PLLPSC2 = 4;
        RCM->CFG2_B.PLL2MUL = 10;

        RCM->CFG2_B.PLLPSC1SRC = 1;
        RCM->CFG2_B.PLLPSC1 = 4;

        /* Enable PLL2 */
        RCM->CTRL_B.PLL2EN = 1;
        /* Wait till PLL2 is ready */
        while (RCM->CTRL_B.PLL2RDYFLG == BIT_RESET);

        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 6;
#else
        /* PLL: HSE * 12 */
        RCM->CFG_B.PLL1SRCSEL = 1;
        RCM->CFG_B.PLL1MULCFG = 10;
#endif

        /* Enable PLL */
        RCM->CTRL_B.PLL1EN = 1;

        /* Wait PLL Ready */
        while (RCM->CTRL_B.PLL1RDYFLG == BIT_RESET);

        /* Select PLL as system clock source */
        RCM->CFG_B.SCLKSEL = 2;

        /* Wait till PLL is used as system clock source */
        while (RCM->CFG_B.SCLKSELSTS != 0x02);
    }
}
#endif

/**@} end of group I2C_EEPROM_System_Functions */
/**@} end of group I2C_EEPROM */
/**@} end of group Examples */
