rt-thread/bsp/synwit/swm320/libraries/CMSIS/DeviceSupport/system_SWM320.c

286 lines
8.8 KiB
C
Raw Normal View History

2021-09-13 21:04:42 +08:00
/******************************************************************************************************************************************
* : system_SWM320.c
* : SWM320单片机的时钟设置
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
2021-05-06 10:24:00 +08:00
* :
2021-09-13 21:04:42 +08:00
* : V1.1.0 20171025
* :
2021-02-18 13:29:12 +08:00
*
*
*******************************************************************************************************************************************
* @attention
*
2021-09-13 21:04:42 +08:00
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
2021-02-18 13:29:12 +08:00
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
2021-05-06 10:42:41 +08:00
*******************************************************************************************************************************************/
2021-02-18 13:29:12 +08:00
#include <stdint.h>
#include "SWM320.h"
2021-02-18 13:29:12 +08:00
/******************************************************************************************************************************************
2021-05-06 10:24:00 +08:00
*
2021-02-18 13:29:12 +08:00
*****************************************************************************************************************************************/
#define SYS_CLK_20MHz 0 //0 内部高频20MHz RC振荡器
#define SYS_CLK_40MHz 1 //1 内部高频40MHz RC振荡器
#define SYS_CLK_32KHz 2 //2 内部低频32KHz RC振荡器
#define SYS_CLK_XTAL 3 //3 外部晶体振荡器2-30MHz
#define SYS_CLK_PLL 4 //4 片内锁相环输出
#define SYS_CLK SYS_CLK_PLL
#define SYS_CLK_DIV_1 0
#define SYS_CLK_DIV_2 1
2021-02-18 13:29:12 +08:00
#define SYS_CLK_DIV SYS_CLK_DIV_1
2021-02-18 13:29:12 +08:00
#define __HSI (20000000UL) //高速内部时钟
#define __LSI ( 32000UL) //低速内部时钟
#define __HSE (20000000UL) //高速外部时钟
2021-02-18 13:29:12 +08:00
2021-05-06 10:24:00 +08:00
/********************************** PLL 设定 **********************************************
* VCO输出频率 = PLL输入时钟 / INDIV * 4 * FBDIV
2021-09-13 21:04:42 +08:00
* PLL输出频率 = PLL输入时钟 / INDIV * 4 * FBDIV / OUTDIV = VCO输出频率 / OUTDIV
2021-09-13 20:19:14 +08:00
* VCO输出频率需要在 [600MHz, 1200MHz]
2021-05-06 10:42:41 +08:00
*****************************************************************************************/
#define SYS_PLL_SRC SYS_CLK_20MHz //可取值SYS_CLK_20MHz、SYS_CLK_XTAL
#define PLL_IN_DIV 5
#define PLL_FB_DIV 60
#define PLL_OUT_DIV8 0
#define PLL_OUT_DIV4 1
#define PLL_OUT_DIV2 2
2021-02-18 13:29:12 +08:00
#define PLL_OUT_DIV PLL_OUT_DIV8
2021-02-18 13:29:12 +08:00
uint32_t SystemCoreClock = __HSI; //System Clock Frequency (Core Clock)
uint32_t CyclesPerUs = (__HSI / 1000000); //Cycles per micro second
2021-02-18 13:29:12 +08:00
2021-09-13 21:04:42 +08:00
/******************************************************************************************************************************************
* :
2021-05-06 10:24:00 +08:00
* : This function is used to update the variable SystemCoreClock and must be called whenever the core clock is changed
2021-09-13 21:04:42 +08:00
* :
* :
* :
2021-05-06 10:10:29 +08:00
******************************************************************************************************************************************/
2021-05-06 10:42:41 +08:00
void SystemCoreClockUpdate(void)
2021-05-06 10:10:29 +08:00
{
if(SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) //SYS_CLK <= HFCK
2021-05-06 10:42:41 +08:00
{
if(SYS->CLKSEL & SYS_CLKSEL_HFCK_Msk) //HFCK <= XTAL
2021-05-06 10:42:41 +08:00
{
SystemCoreClock = __HSE;
2021-05-06 10:42:41 +08:00
}
else //HFCK <= HRC
2021-05-06 10:42:41 +08:00
{
if(SYS->HRCCR & SYS_HRCCR_DBL_Msk) //HRC = 40MHz
2021-05-06 10:42:41 +08:00
{
SystemCoreClock = __HSI*2;
2021-05-06 10:42:41 +08:00
}
else //HRC = 20MHz
2021-05-06 10:42:41 +08:00
{
SystemCoreClock = __HSI;
}
}
}
else //SYS_CLK <= LFCK
2021-05-06 10:42:41 +08:00
{
if(SYS->CLKSEL & SYS_CLKSEL_LFCK_Msk) //LFCK <= PLL
2021-05-06 10:42:41 +08:00
{
if(SYS->PLLCR & SYS_PLLCR_INSEL_Msk) //PLL_SRC <= HRC
2021-05-06 10:42:41 +08:00
{
SystemCoreClock = __HSI;
}
else //PLL_SRC <= XTAL
2021-05-06 10:42:41 +08:00
{
SystemCoreClock = __HSE;
}
SystemCoreClock = SystemCoreClock / PLL_IN_DIV * PLL_FB_DIV * 4 / (2 << (2 - PLL_OUT_DIV));
}
else //LFCK <= LRC
2021-05-06 10:42:41 +08:00
{
SystemCoreClock = __LSI;
}
}
if(SYS->CLKDIV & SYS_CLKDIV_SYS_Msk) SystemCoreClock /= 2;
2021-05-06 10:42:41 +08:00
CyclesPerUs = SystemCoreClock / 1000000;
2021-05-06 10:10:29 +08:00
}
2021-02-18 13:29:12 +08:00
2021-09-13 21:04:42 +08:00
/******************************************************************************************************************************************
* :
2021-05-06 10:24:00 +08:00
* : The necessary initializaiton of systerm
2021-09-13 21:04:42 +08:00
* :
* :
* :
2021-05-06 10:10:29 +08:00
******************************************************************************************************************************************/
void SystemInit(void)
2021-05-06 10:42:41 +08:00
{
SYS->CLKEN |= (1 << SYS_CLKEN_ANAC_Pos);
Flash_Param_at_xMHz(120);
switch(SYS_CLK)
2021-05-06 10:42:41 +08:00
{
case SYS_CLK_20MHz: //0 内部高频20MHz RC振荡器
switchCLK_20MHz();
break;
2021-05-06 10:42:41 +08:00
case SYS_CLK_40MHz: //1 内部高频40MHz RC振荡器
switchCLK_40MHz();
break;
2021-05-06 10:42:41 +08:00
case SYS_CLK_32KHz: //2 内部低频32KHz RC振荡器
switchCLK_32KHz();
break;
2021-05-06 10:42:41 +08:00
case SYS_CLK_XTAL: //3 外部晶体振荡器2-30MHz
switchCLK_XTAL();
break;
2021-05-06 10:42:41 +08:00
case SYS_CLK_PLL: //4 片内锁相环输出
switchCLK_PLL();
break;
2021-05-06 10:42:41 +08:00
}
SYS->CLKDIV &= ~SYS_CLKDIV_SYS_Msk;
SYS->CLKDIV |= (SYS_CLK_DIV << SYS_CLKDIV_SYS_Pos);
SystemCoreClockUpdate();
if(SystemCoreClock > 80000000)
2021-05-06 10:42:41 +08:00
{
Flash_Param_at_xMHz(120);
}
else if(SystemCoreClock > 40000000)
2021-05-06 10:42:41 +08:00
{
Flash_Param_at_xMHz(80);
}
else if(SystemCoreClock > 30000000)
2021-05-06 10:42:41 +08:00
{
Flash_Param_at_xMHz(40);
}
else
{
Flash_Param_at_xMHz(30);
}
2021-02-18 13:29:12 +08:00
}
2021-09-13 20:19:14 +08:00
static void delay_3ms(void)
2021-02-18 13:29:12 +08:00
{
2021-05-06 10:42:41 +08:00
uint32_t i;
if(((SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) == 0) &&
((SYS->CLKSEL & SYS_CLKSEL_LFCK_Msk) == 0)) //32KHz
2021-09-13 20:19:14 +08:00
{
for(i = 0; i < 20; i++) __NOP();
2021-09-13 20:19:14 +08:00
}
else
{
for(i = 0; i < 20000; i++) __NOP();
2021-09-13 20:19:14 +08:00
}
}
void switchCLK_20MHz(void)
{
2021-05-06 10:42:41 +08:00
SYS->HRCCR = (0 << SYS_HRCCR_OFF_Pos) |
(0 << SYS_HRCCR_DBL_Pos); //HRC = 20MHz
2021-05-06 10:42:41 +08:00
2021-09-13 20:19:14 +08:00
delay_3ms();
2021-05-06 10:42:41 +08:00
SYS->CLKSEL &= ~SYS_CLKSEL_HFCK_Msk; //HFCK <= HRC
SYS->CLKSEL |= (1 << SYS_CLKSEL_SYS_Pos); //SYS_CLK <= HFCK
2021-02-18 13:29:12 +08:00
}
void switchCLK_40MHz(void)
{
2021-05-06 10:42:41 +08:00
SYS->HRCCR = (0 << SYS_HRCCR_OFF_Pos) |
(1 << SYS_HRCCR_DBL_Pos); //HRC = 40MHz
2021-05-06 10:42:41 +08:00
2021-09-13 20:19:14 +08:00
delay_3ms();
2021-05-06 10:42:41 +08:00
SYS->CLKSEL &= ~SYS_CLKSEL_HFCK_Msk; //HFCK <= HRC
SYS->CLKSEL |= (1 << SYS_CLKSEL_SYS_Pos); //SYS_CLK <= HFCK
2021-02-18 13:29:12 +08:00
}
void switchCLK_32KHz(void)
{
2021-05-06 10:42:41 +08:00
SYS->CLKEN |= (1 << SYS_CLKEN_RTCBKP_Pos);
SYS->LRCCR &= ~(1 << SYS_LRCCR_OFF_Pos);
2021-09-13 20:19:14 +08:00
delay_3ms();
2021-05-06 10:42:41 +08:00
SYS->CLKSEL &= ~SYS_CLKSEL_LFCK_Msk; //LFCK <= LRC
SYS->CLKSEL &= ~SYS_CLKSEL_SYS_Msk; //SYS_CLK <= LFCK
2021-02-18 13:29:12 +08:00
}
void switchCLK_XTAL(void)
{
2021-05-06 10:42:41 +08:00
SYS->XTALCR = (1 << SYS_XTALCR_EN_Pos);
2021-09-13 20:19:14 +08:00
delay_3ms();
delay_3ms();
2021-05-06 10:42:41 +08:00
SYS->CLKSEL |= (1 << SYS_CLKSEL_HFCK_Pos); //HFCK <= XTAL
SYS->CLKSEL |= (1 << SYS_CLKSEL_SYS_Pos); //SYS_CLK <= HFCK
2021-02-18 13:29:12 +08:00
}
void switchCLK_PLL(void)
{
2021-05-06 10:42:41 +08:00
PLLInit();
2021-09-13 20:19:14 +08:00
SYS->PLLCR |= (1 << SYS_PLLCR_OUTEN_Pos);
2021-05-06 10:42:41 +08:00
SYS->CLKSEL |= (1 << SYS_CLKSEL_LFCK_Pos); //LFCK <= PLL
SYS->CLKSEL &= ~SYS_CLKSEL_SYS_Msk; //SYS_CLK <= LFCK
2021-02-18 13:29:12 +08:00
}
void PLLInit(void)
{
if(SYS_PLL_SRC == SYS_CLK_20MHz)
2021-05-06 10:42:41 +08:00
{
SYS->HRCCR = (0 << SYS_HRCCR_OFF_Pos) |
(0 << SYS_HRCCR_DBL_Pos); //HRC = 20MHz
2021-05-06 10:42:41 +08:00
2021-09-13 20:19:14 +08:00
delay_3ms();
2021-05-06 10:42:41 +08:00
SYS->PLLCR |= (1 << SYS_PLLCR_INSEL_Pos); //PLL_SRC <= HRC
2021-05-06 10:42:41 +08:00
}
else if(SYS_PLL_SRC == SYS_CLK_XTAL)
2021-05-06 10:42:41 +08:00
{
SYS->XTALCR = (1 << SYS_XTALCR_EN_Pos);
2021-09-13 20:19:14 +08:00
delay_3ms();
delay_3ms();
2021-05-06 10:42:41 +08:00
SYS->PLLCR &= ~(1 << SYS_PLLCR_INSEL_Pos); //PLL_SRC <= XTAL
2021-05-06 10:42:41 +08:00
}
SYS->PLLDIV &= ~(SYS_PLLDIV_INDIV_Msk |
SYS_PLLDIV_FBDIV_Msk |
SYS_PLLDIV_OUTDIV_Msk);
SYS->PLLDIV |= (PLL_IN_DIV << SYS_PLLDIV_INDIV_Pos) |
(PLL_FB_DIV << SYS_PLLDIV_FBDIV_Pos) |
(PLL_OUT_DIV<< SYS_PLLDIV_OUTDIV_Pos);
2021-05-06 10:42:41 +08:00
SYS->PLLCR &= ~(1 << SYS_PLLCR_OFF_Pos);
while(SYS->PLLLOCK == 0); //等待PLL锁定
2021-02-18 13:29:12 +08:00
}